]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/openswan-2.4.9.kernel-2.6-klips.patch
Pakfire laedt die Listen jetzt besser und hat eine veraenderte Oberflaeche bekommen.
[ipfire-2.x.git] / src / patches / openswan-2.4.9.kernel-2.6-klips.patch
CommitLineData
b4f8d26c
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,352 @@
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.11 2007/02/20 03:53:16 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+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3907+/* skb->nfmark changed to skb->mark in 2.6.20 */
3908+#define nfmark mark
3909+#endif
3910+
3911+#ifdef NET_21
3912+# include <linux/in6.h>
3913+#else
3914+ /* old kernel in.h has some IPv6 stuff, but not quite enough */
3915+# define s6_addr16 s6_addr
3916+# define AF_INET6 10
3917+# define uint8_t __u8
3918+# define uint16_t __u16
3919+# define uint32_t __u32
3920+# define uint64_t __u64
3921+#endif
3922+
3923+#ifdef NET_21
3924+# define ipsec_kfree_skb(a) kfree_skb(a)
3925+#else /* NET_21 */
3926+# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
3927+#endif /* NET_21 */
3928+
3929+#ifdef NETDEV_23
3930+#if 0
3931+#ifndef NETDEV_25
3932+#define device net_device
3933+#endif
3934+#endif
3935+# define ipsec_dev_get dev_get_by_name
3936+# define __ipsec_dev_get __dev_get_by_name
3937+# define ipsec_dev_put(x) dev_put(x)
3938+# define __ipsec_dev_put(x) __dev_put(x)
3939+# define ipsec_dev_hold(x) dev_hold(x)
3940+#else /* NETDEV_23 */
3941+# define ipsec_dev_get dev_get
3942+# define __ipsec_dev_put(x)
3943+# define ipsec_dev_put(x)
3944+# define ipsec_dev_hold(x)
3945+#endif /* NETDEV_23 */
3946+
3947+#ifndef SPINLOCK
3948+# include <linux/bios32.h>
3949+ /* simulate spin locks and read/write locks */
3950+ typedef struct {
3951+ volatile char lock;
3952+ } spinlock_t;
3953+
3954+ typedef struct {
3955+ volatile unsigned int lock;
3956+ } rwlock_t;
3957+
3958+# define spin_lock_init(x) { (x)->lock = 0;}
3959+# define rw_lock_init(x) { (x)->lock = 0; }
3960+
3961+# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
3962+# define spin_lock_irq(x) { cli(); spin_lock(x);}
3963+# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
3964+
3965+# define spin_unlock(x) { (x)->lock=0;}
3966+# define spin_unlock_irq(x) { spin_unlock(x); sti();}
3967+# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
3968+
3969+# define read_lock(x) spin_lock(x)
3970+# define read_lock_irq(x) spin_lock_irq(x)
3971+# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
3972+
3973+# define read_unlock(x) spin_unlock(x)
3974+# define read_unlock_irq(x) spin_unlock_irq(x)
3975+# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
3976+
3977+# define write_lock(x) spin_lock(x)
3978+# define write_lock_irq(x) spin_lock_irq(x)
3979+# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
3980+
3981+# define write_unlock(x) spin_unlock(x)
3982+# define write_unlock_irq(x) spin_unlock_irq(x)
3983+# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
3984+#endif /* !SPINLOCK */
3985+
3986+#ifndef SPINLOCK_23
3987+# define spin_lock_bh(x) spin_lock_irq(x)
3988+# define spin_unlock_bh(x) spin_unlock_irq(x)
3989+
3990+# define read_lock_bh(x) read_lock_irq(x)
3991+# define read_unlock_bh(x) read_unlock_irq(x)
3992+
3993+# define write_lock_bh(x) write_lock_irq(x)
3994+# define write_unlock_bh(x) write_unlock_irq(x)
3995+#endif /* !SPINLOCK_23 */
3996+
3997+#ifndef HAVE_NETDEV_PRINTK
3998+#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
3999+ printk(sevlevel "%s: " format , netdev->name , ## arg)
4000+#endif
4001+
4002+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0)
4003+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4004+#include "openswan/ipsec_kern24.h"
4005+#else
4006+#error "kernels before 2.4 are not supported at this time"
4007+#endif
4008+#endif
4009+
4010+
4011+#endif /* _OPENSWAN_KVERSIONS_H */
4012+
4013+/*
4014+ * $Log: ipsec_kversion.h,v $
4015+ * Revision 1.15.2.11 2007/02/20 03:53:16 paul
4016+ * Added comment, made layout consistent with other checks.
4017+ *
4018+ * Revision 1.15.2.10 2007/02/16 19:08:12 paul
4019+ * Fix for compiling on 2.6.20 (nfmark is now called mark in sk_buff)
4020+ *
4021+ * Revision 1.15.2.9 2006/07/29 05:00:40 paul
4022+ * Added HAVE_NEW_SKB_LINEARIZE for 2.6.18+ kernels where skb_linearize
4023+ * only takes 1 argument.
4024+ *
4025+ * Revision 1.15.2.8 2006/05/01 14:31:52 mcr
4026+ * FREESWAN->OPENSWAN in #ifdef.
4027+ *
4028+ * Revision 1.15.2.7 2006/01/11 02:02:59 mcr
4029+ * updated patches and DEFAULT_TTL code to work
4030+ *
4031+ * Revision 1.15.2.6 2006/01/03 19:25:02 ken
4032+ * Remove duplicated #ifdef for TTL fix - bad patch
4033+ *
4034+ * Revision 1.15.2.5 2006/01/03 18:06:33 ken
4035+ * Fix for missing sysctl default ttl
4036+ *
4037+ * Revision 1.15.2.4 2005/11/27 21:40:14 paul
4038+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
4039+ * in for klips as module.
4040+ *
4041+ * Revision 1.15.2.3 2005/11/22 04:11:52 ken
4042+ * Backport fixes for 2.6.14 kernels from HEAD
4043+ *
4044+ * Revision 1.15.2.2 2005/09/01 01:57:19 paul
4045+ * michael's fixes for 2.6.13 from head
4046+ *
4047+ * Revision 1.15.2.1 2005/08/27 23:13:48 paul
4048+ * Fix for:
4049+ * 7 weeks ago: [NET]: Remove unused security member in sk_buff
4050+ * changeset 4280: 328ea53f5fee
4051+ * parent 4279: beb0afb0e3f8
4052+ * author: Thomas Graf <tgraf@suug.ch>
4053+ * date: Tue Jul 5 21:12:44 2005
4054+ * 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
4055+ *
4056+ * This should fix compilation on 2.6.13(rc) kernels
4057+ *
4058+ * Revision 1.15 2005/07/19 20:02:15 mcr
4059+ * sk_alloc() interface change.
4060+ *
4061+ * Revision 1.14 2005/07/08 16:20:05 mcr
4062+ * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
4063+ *
4064+ * Revision 1.13 2005/05/20 03:19:18 mcr
4065+ * modifications for use on 2.4.30 kernel, with backported
4066+ * printk_ratelimit(). all warnings removed.
4067+ *
4068+ * Revision 1.12 2005/04/13 22:46:21 mcr
4069+ * note that KLIPS does not work on Linux 2.0.
4070+ *
4071+ * Revision 1.11 2004/09/13 02:22:26 mcr
4072+ * #define inet_protocol if necessary.
4073+ *
4074+ * Revision 1.10 2004/08/03 18:17:15 mcr
4075+ * in 2.6, use "net_device" instead of #define device->net_device.
4076+ * this probably breaks 2.0 compiles.
4077+ *
4078+ * Revision 1.9 2004/04/05 19:55:05 mcr
4079+ * Moved from linux/include/freeswan/ipsec_kversion.h,v
4080+ *
4081+ * Revision 1.8 2003/12/13 19:10:16 mcr
4082+ * refactored rcv and xmit code - same as FS 2.05.
4083+ *
4084+ * Revision 1.7 2003/07/31 22:48:08 mcr
4085+ * derive NET25-ness from presence of NETLINK_XFRM macro.
4086+ *
4087+ * Revision 1.6 2003/06/24 20:22:32 mcr
4088+ * added new global: ipsecdevices[] so that we can keep track of
4089+ * the ipsecX devices. They will be referenced with dev_hold(),
4090+ * so 2.2 may need this as well.
4091+ *
4092+ * Revision 1.5 2003/04/03 17:38:09 rgb
4093+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4094+ *
4095+ * Revision 1.4 2002/04/24 07:36:46 mcr
4096+ * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
4097+ *
4098+ * Revision 1.3 2002/04/12 03:21:17 mcr
4099+ * three parameter version of ip_select_ident appears first
4100+ * in 2.4.2 (RH7.1) not 2.4.4.
4101+ *
4102+ * Revision 1.2 2002/03/08 21:35:22 rgb
4103+ * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
4104+ * 2.4.9. (Andreas Piesk).
4105+ *
4106+ * Revision 1.1 2002/01/29 02:11:42 mcr
4107+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
4108+ * updating of IPv6 structures to match latest in6.h version.
4109+ * removed dead code from freeswan.h that also duplicated kversions.h
4110+ * code.
4111+ *
4112+ *
4113+ */
4114--- /dev/null Tue Mar 11 13:02:56 2003
4115+++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004
4116@@ -0,0 +1,112 @@
4117+/*
4118+ * Definitions relevant to IPSEC lifetimes
4119+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4120+ * and Michael Richardson <mcr@freeswan.org>
4121+ *
4122+ * This program is free software; you can redistribute it and/or modify it
4123+ * under the terms of the GNU General Public License as published by the
4124+ * Free Software Foundation; either version 2 of the License, or (at your
4125+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4126+ *
4127+ * This program is distributed in the hope that it will be useful, but
4128+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4129+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4130+ * for more details.
4131+ *
4132+ * RCSID $Id: ipsec_life.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
4133+ *
4134+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
4135+ *
4136+ */
4137+
4138+/*
4139+ * This file describes the book keeping fields for the
4140+ * IPsec Security Association Structure. ("ipsec_sa")
4141+ *
4142+ * This structure is never allocated directly by kernel code,
4143+ * (it is always a static/auto or is part of a structure)
4144+ * so it does not have a reference count.
4145+ *
4146+ */
4147+
4148+#ifndef _IPSEC_LIFE_H_
4149+
4150+/*
4151+ * _count is total count.
4152+ * _hard is hard limit (kill SA after this number)
4153+ * _soft is soft limit (try to renew SA after this number)
4154+ * _last is used in some special cases.
4155+ *
4156+ */
4157+
4158+struct ipsec_lifetime64
4159+{
4160+ __u64 ipl_count;
4161+ __u64 ipl_soft;
4162+ __u64 ipl_hard;
4163+ __u64 ipl_last;
4164+};
4165+
4166+struct ipsec_lifetimes
4167+{
4168+ /* number of bytes processed */
4169+ struct ipsec_lifetime64 ipl_bytes;
4170+
4171+ /* number of packets processed */
4172+ struct ipsec_lifetime64 ipl_packets;
4173+
4174+ /* time since SA was added */
4175+ struct ipsec_lifetime64 ipl_addtime;
4176+
4177+ /* time since SA was first used */
4178+ struct ipsec_lifetime64 ipl_usetime;
4179+
4180+ /* from rfc2367:
4181+ * For CURRENT, the number of different connections,
4182+ * endpoints, or flows that the association has been
4183+ * allocated towards. For HARD and SOFT, the number of
4184+ * these the association may be allocated towards
4185+ * before it expires. The concept of a connection,
4186+ * flow, or endpoint is system specific.
4187+ *
4188+ * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
4189+ * They are maintained for PF_KEY compatibility.
4190+ */
4191+ struct ipsec_lifetime64 ipl_allocations;
4192+};
4193+
4194+enum ipsec_life_alive {
4195+ ipsec_life_harddied = -1,
4196+ ipsec_life_softdied = 0,
4197+ ipsec_life_okay = 1
4198+};
4199+
4200+enum ipsec_life_type {
4201+ ipsec_life_timebased = 1,
4202+ ipsec_life_countbased= 0
4203+};
4204+
4205+#define _IPSEC_LIFE_H_
4206+#endif /* _IPSEC_LIFE_H_ */
4207+
4208+
4209+/*
4210+ * $Log: ipsec_life.h,v $
4211+ * Revision 1.4 2004/04/05 19:55:05 mcr
4212+ * Moved from linux/include/freeswan/ipsec_life.h,v
4213+ *
4214+ * Revision 1.3 2002/04/24 07:36:46 mcr
4215+ * Moved from ./klips/net/ipsec/ipsec_life.h,v
4216+ *
4217+ * Revision 1.2 2001/11/26 09:16:14 rgb
4218+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4219+ *
4220+ * Revision 1.1.2.1 2001/09/25 02:25:58 mcr
4221+ * lifetime structure created and common functions created.
4222+ *
4223+ *
4224+ * Local variables:
4225+ * c-file-style: "linux"
4226+ * End:
4227+ *
4228+ */
4229--- /dev/null Tue Mar 11 13:02:56 2003
4230+++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004
4231@@ -0,0 +1,143 @@
4232+/*
4233+ * RCSID $Id: ipsec_md5h.h,v 1.10 2004/09/08 17:21:35 ken Exp $
4234+ */
4235+
4236+/*
4237+ * The rest of this file is Copyright RSA DSI. See the following comments
4238+ * for the full Copyright notice.
4239+ */
4240+
4241+#ifndef _IPSEC_MD5H_H_
4242+#define _IPSEC_MD5H_H_
4243+
4244+/* GLOBAL.H - RSAREF types and constants
4245+ */
4246+
4247+/* PROTOTYPES should be set to one if and only if the compiler supports
4248+ function argument prototyping.
4249+ The following makes PROTOTYPES default to 0 if it has not already
4250+ been defined with C compiler flags.
4251+ */
4252+#ifndef PROTOTYPES
4253+#define PROTOTYPES 1
4254+#endif /* !PROTOTYPES */
4255+
4256+/* POINTER defines a generic pointer type */
4257+typedef __u8 *POINTER;
4258+
4259+/* UINT2 defines a two byte word */
4260+typedef __u16 UINT2;
4261+
4262+/* UINT4 defines a four byte word */
4263+typedef __u32 UINT4;
4264+
4265+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
4266+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
4267+ returns an empty list.
4268+ */
4269+
4270+#if PROTOTYPES
4271+#define PROTO_LIST(list) list
4272+#else /* PROTOTYPES */
4273+#define PROTO_LIST(list) ()
4274+#endif /* PROTOTYPES */
4275+
4276+
4277+/* MD5.H - header file for MD5C.C
4278+ */
4279+
4280+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
4281+rights reserved.
4282+
4283+License to copy and use this software is granted provided that it
4284+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
4285+Algorithm" in all material mentioning or referencing this software
4286+or this function.
4287+
4288+License is also granted to make and use derivative works provided
4289+that such works are identified as "derived from the RSA Data
4290+Security, Inc. MD5 Message-Digest Algorithm" in all material
4291+mentioning or referencing the derived work.
4292+
4293+RSA Data Security, Inc. makes no representations concerning either
4294+the merchantability of this software or the suitability of this
4295+software for any particular purpose. It is provided "as is"
4296+without express or implied warranty of any kind.
4297+
4298+These notices must be retained in any copies of any part of this
4299+documentation and/or software.
4300+ */
4301+
4302+/* MD5 context. */
4303+typedef struct {
4304+ UINT4 state[4]; /* state (ABCD) */
4305+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
4306+ unsigned char buffer[64]; /* input buffer */
4307+} MD5_CTX;
4308+
4309+void osMD5Init PROTO_LIST ((void *));
4310+void osMD5Update PROTO_LIST
4311+ ((void *, unsigned char *, __u32));
4312+void osMD5Final PROTO_LIST ((unsigned char [16], void *));
4313+
4314+#endif /* _IPSEC_MD5H_H_ */
4315+
4316+/*
4317+ * $Log: ipsec_md5h.h,v $
4318+ * Revision 1.10 2004/09/08 17:21:35 ken
4319+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
4320+ *
4321+ * Revision 1.9 2004/04/05 19:55:05 mcr
4322+ * Moved from linux/include/freeswan/ipsec_md5h.h,v
4323+ *
4324+ * Revision 1.8 2002/09/10 01:45:09 mcr
4325+ * changed type of MD5_CTX and SHA1_CTX to void * so that
4326+ * the function prototypes would match, and could be placed
4327+ * into a pointer to a function.
4328+ *
4329+ * Revision 1.7 2002/04/24 07:36:46 mcr
4330+ * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
4331+ *
4332+ * Revision 1.6 1999/12/13 13:59:13 rgb
4333+ * Quick fix to argument size to Update bugs.
4334+ *
4335+ * Revision 1.5 1999/12/07 18:16:23 rgb
4336+ * Fixed comments at end of #endif lines.
4337+ *
4338+ * Revision 1.4 1999/04/06 04:54:26 rgb
4339+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
4340+ * patch shell fixes.
4341+ *
4342+ * Revision 1.3 1999/01/22 06:19:58 rgb
4343+ * 64-bit clean-up.
4344+ *
4345+ * Revision 1.2 1998/11/30 13:22:54 rgb
4346+ * Rationalised all the klips kernel file headers. They are much shorter
4347+ * now and won't conflict under RH5.2.
4348+ *
4349+ * Revision 1.1 1998/06/18 21:27:48 henry
4350+ * move sources from klips/src to klips/net/ipsec, to keep stupid
4351+ * kernel-build scripts happier in the presence of symlinks
4352+ *
4353+ * Revision 1.2 1998/04/23 20:54:03 rgb
4354+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
4355+ * verified.
4356+ *
4357+ * Revision 1.1 1998/04/09 03:04:21 henry
4358+ * sources moved up from linux/net/ipsec
4359+ * these two include files modified not to include others except in kernel
4360+ *
4361+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
4362+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
4363+ *
4364+ * Revision 0.4 1997/01/15 01:28:15 ji
4365+ * No changes.
4366+ *
4367+ * Revision 0.3 1996/11/20 14:48:53 ji
4368+ * Release update only.
4369+ *
4370+ * Revision 0.2 1996/11/02 00:18:33 ji
4371+ * First limited release.
4372+ *
4373+ *
4374+ */
4375--- /dev/null Tue Mar 11 13:02:56 2003
4376+++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004
4377@@ -0,0 +1,387 @@
4378+/*
4379+ * @(#) Openswan tunable paramaters
4380+ *
4381+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4382+ * and Michael Richardson <mcr@freeswan.org>
4383+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
4384+ *
4385+ * This program is free software; you can redistribute it and/or modify it
4386+ * under the terms of the GNU General Public License as published by the
4387+ * Free Software Foundation; either version 2 of the License, or (at your
4388+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4389+ *
4390+ * This program is distributed in the hope that it will be useful, but
4391+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4392+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4393+ * for more details.
4394+ *
4395+ * RCSID $Id: ipsec_param.h,v 1.29.6.3 2006/05/01 14:32:31 mcr Exp $
4396+ *
4397+ */
4398+
4399+/*
4400+ * This file provides a set of #define's which may be tuned by various
4401+ * people/configurations. It keeps all compile-time tunables in one place.
4402+ *
4403+ * This file should be included before all other IPsec kernel-only files.
4404+ *
4405+ */
4406+
4407+#ifndef _IPSEC_PARAM_H_
4408+
4409+#ifdef __KERNEL__
4410+#include "ipsec_kversion.h"
4411+
4412+/* Set number of ipsecX virtual devices here. */
4413+/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
4414+/* It must also be reasonable so as not to overload the memory and CPU */
4415+/* constraints of the host. */
4416+#define IPSEC_NUM_IF 4
4417+/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
4418+/* With "ipsec" being 5 characters, that means 10 is the max field width */
4419+/* but machine memory and CPU constraints are not likely to tollerate */
4420+/* more than 3 digits. The default is one digit. */
4421+/* Update: userland scripts get upset if they can't find "ipsec0", so */
4422+/* for now, no "0"-padding should be used (which would have been helpful */
4423+/* to make text-searches work */
4424+#define IPSEC_DEV_FORMAT "ipsec%d"
4425+/* For, say, 500 virtual ipsec devices, I would recommend: */
4426+/* #define IPSEC_NUM_IF 500 */
4427+/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
4428+/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
4429+
4430+/* use dynamic ipsecX device allocation */
4431+#ifndef CONFIG_KLIPS_DYNDEV
4432+#define CONFIG_KLIPS_DYNDEV 1
4433+#endif /* CONFIG_KLIPS_DYNDEV */
4434+
4435+
4436+#ifdef CONFIG_KLIPS_BIGGATE
4437+# define SADB_HASHMOD 8069
4438+#else /* CONFIG_KLIPS_BIGGATE */
4439+# define SADB_HASHMOD 257
4440+#endif /* CONFIG_KLIPS_BIGGATE */
4441+#endif /* __KERNEL__ */
4442+
4443+/*
4444+ * This is for the SA reference table. This number is related to the
4445+ * maximum number of SAs that KLIPS can concurrently deal with, plus enough
4446+ * space for keeping expired SAs around.
4447+ *
4448+ * TABLE_MAX_WIDTH is the number of bits that we will use.
4449+ * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
4450+ *
4451+ */
4452+#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
4453+# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
4454+#endif
4455+
4456+#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
4457+# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
4458+#endif
4459+
4460+#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
4461+# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
4462+#endif
4463+
4464+#ifndef IPSEC_SA_REF_CODE
4465+# define IPSEC_SA_REF_CODE 1
4466+#endif
4467+
4468+#ifdef __KERNEL__
4469+/* This is defined for 2.4, but not 2.2.... */
4470+#ifndef ARPHRD_VOID
4471+# define ARPHRD_VOID 0xFFFF
4472+#endif
4473+
4474+/* always turn on IPIP mode */
4475+#ifndef CONFIG_KLIPS_IPIP
4476+#define CONFIG_KLIPS_IPIP 1
4477+#endif
4478+
4479+/*
4480+ * Worry about PROC_FS stuff
4481+ */
4482+#if defined(PROC_FS_2325)
4483+/* kernel 2.4 */
4484+# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
4485+# define IPSEC_PROCFS_DEBUG_NO_STATIC
4486+# define IPSEC_PROC_SUBDIRS
4487+#else
4488+/* kernel <2.4 */
4489+# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
4490+
4491+# ifndef PROC_NO_DUMMY
4492+# define IPSEC_PROC_LAST_ARG , int dummy
4493+# else
4494+# define IPSEC_PROC_LAST_ARG
4495+# endif /* !PROC_NO_DUMMY */
4496+#endif /* PROC_FS_2325 */
4497+
4498+#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
4499+/* GNU CPP specific! */
4500+# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
4501+#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
4502+
4503+#ifdef SPINLOCK
4504+# ifdef SPINLOCK_23
4505+# include <linux/spinlock.h> /* *lock* */
4506+# else /* SPINLOCK_23 */
4507+# include <asm/spinlock.h> /* *lock* */
4508+# endif /* SPINLOCK_23 */
4509+#endif /* SPINLOCK */
4510+
4511+#ifndef KLIPS_FIXES_DES_PARITY
4512+# define KLIPS_FIXES_DES_PARITY 1
4513+#endif /* !KLIPS_FIXES_DES_PARITY */
4514+
4515+/* we don't really want to print these unless there are really big problems */
4516+#ifndef KLIPS_DIVULGE_CYPHER_KEY
4517+# define KLIPS_DIVULGE_CYPHER_KEY 0
4518+#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
4519+
4520+#ifndef KLIPS_DIVULGE_HMAC_KEY
4521+# define KLIPS_DIVULGE_HMAC_KEY 0
4522+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4523+
4524+#ifndef IPSEC_DISALLOW_IPOPTIONS
4525+# define IPSEC_DISALLOW_IPOPTIONS 1
4526+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4527+
4528+/* extra toggles for regression testing */
4529+#ifdef CONFIG_KLIPS_REGRESS
4530+
4531+/*
4532+ * should pfkey_acquire() become 100% lossy?
4533+ *
4534+ */
4535+extern int sysctl_ipsec_regress_pfkey_lossage;
4536+#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
4537+# ifdef CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE
4538+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
4539+# endif /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4540+#else
4541+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4542+#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4543+
4544+#else /* CONFIG_KLIPS_REGRESS */
4545+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4546+
4547+#endif /* CONFIG_KLIPS_REGRESS */
4548+
4549+
4550+/*
4551+ * debugging routines.
4552+ */
4553+#define KLIPS_ERROR(flag, format, args...) if(printk_ratelimit() || flag) printk(KERN_ERR "KLIPS " format, ## args)
4554+#ifdef CONFIG_KLIPS_DEBUG
4555+extern void ipsec_print_ip(struct iphdr *ip);
4556+
4557+ #define KLIPS_PRINT(flag, format, args...) \
4558+ ((flag) ? printk(KERN_INFO format , ## args) : 0)
4559+ #define KLIPS_PRINTMORE(flag, format, args...) \
4560+ ((flag) ? printk(format , ## args) : 0)
4561+ #define KLIPS_IP_PRINT(flag, ip) \
4562+ ((flag) ? ipsec_print_ip(ip) : 0)
4563+#else /* CONFIG_KLIPS_DEBUG */
4564+ #define KLIPS_PRINT(flag, format, args...) do ; while(0)
4565+ #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
4566+ #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
4567+#endif /* CONFIG_KLIPS_DEBUG */
4568+
4569+
4570+/*
4571+ * Stupid kernel API differences in APIs. Not only do some
4572+ * kernels not have ip_select_ident, but some have differing APIs,
4573+ * and SuSE has one with one parameter, but no way of checking to
4574+ * see what is really what.
4575+ */
4576+
4577+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
4578+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
4579+#else
4580+
4581+/* simplest case, nothing */
4582+#if !defined(IP_SELECT_IDENT)
4583+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
4584+#endif
4585+
4586+/* kernels > 2.3.37-ish */
4587+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
4588+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
4589+#endif
4590+
4591+/* kernels > 2.4.2 */
4592+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
4593+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
4594+#endif
4595+
4596+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
4597+
4598+/*
4599+ * make klips fail test:east-espiv-01.
4600+ * exploit is at testing/attacks/espiv
4601+ *
4602+ */
4603+#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
4604+
4605+
4606+/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
4607+#ifndef IP_FRAGMENT_LINEARIZE
4608+# define IP_FRAGMENT_LINEARIZE 0
4609+#endif /* IP_FRAGMENT_LINEARIZE */
4610+#endif /* __KERNEL__ */
4611+
4612+#ifdef NEED_INET_PROTOCOL
4613+#define inet_protocol net_protocol
4614+#endif
4615+
4616+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && CONFIG_IPSEC_NAT_TRAVERSAL
4617+#define NAT_TRAVERSAL 1
4618+#else
4619+/* let people either #undef, or #define = 0 it */
4620+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
4621+#undef CONFIG_IPSEC_NAT_TRAVERSAL
4622+#endif
4623+#endif
4624+
4625+#ifndef IPSEC_DEFAULT_TTL
4626+#define IPSEC_DEFAULT_TTL 64
4627+#endif
4628+
4629+#define _IPSEC_PARAM_H_
4630+#endif /* _IPSEC_PARAM_H_ */
4631+
4632+/*
4633+ * $Log: ipsec_param.h,v $
4634+ * Revision 1.29.6.3 2006/05/01 14:32:31 mcr
4635+ * added KLIPS_ERROR and make sure that things work without CONFIG_KLIPS_REGRESS.
4636+ *
4637+ * Revision 1.29.6.2 2005/11/27 21:40:14 paul
4638+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
4639+ * in for klips as module.
4640+ *
4641+ * Revision 1.29.6.1 2005/08/12 16:24:18 ken
4642+ * Pull in NAT-T compile logic from HEAD
4643+ *
4644+ * Revision 1.29 2005/01/26 00:50:35 mcr
4645+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
4646+ * and make sure that NAT_TRAVERSAL is set as well to match
4647+ * userspace compiles of code.
4648+ *
4649+ * Revision 1.28 2004/09/13 15:50:15 mcr
4650+ * spell NEED_INET properly, not NET_INET.
4651+ *
4652+ * Revision 1.27 2004/09/13 02:21:45 mcr
4653+ * always turn on IPIP mode.
4654+ * #define inet_protocol if necessary.
4655+ *
4656+ * Revision 1.26 2004/08/17 03:25:43 mcr
4657+ * freeswan->openswan.
4658+ *
4659+ * Revision 1.25 2004/07/10 19:08:41 mcr
4660+ * CONFIG_IPSEC -> CONFIG_KLIPS.
4661+ *
4662+ * Revision 1.24 2004/04/05 19:55:06 mcr
4663+ * Moved from linux/include/freeswan/ipsec_param.h,v
4664+ *
4665+ * Revision 1.23 2003/12/13 19:10:16 mcr
4666+ * refactored rcv and xmit code - same as FS 2.05.
4667+ *
4668+ * Revision 1.22 2003/10/31 02:27:05 mcr
4669+ * pulled up port-selector patches and sa_id elimination.
4670+ *
4671+ * Revision 1.21.4.1 2003/10/29 01:10:19 mcr
4672+ * elimited "struct sa_id"
4673+ *
4674+ * Revision 1.21 2003/04/03 17:38:18 rgb
4675+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4676+ * Change indentation for readability.
4677+ *
4678+ * Revision 1.20 2003/03/14 08:09:26 rgb
4679+ * Fixed up CONFIG_IPSEC_DYNDEV definitions.
4680+ *
4681+ * Revision 1.19 2003/01/30 02:31:43 rgb
4682+ *
4683+ * Rename SAref table macro names for clarity.
4684+ *
4685+ * Revision 1.18 2002/09/30 19:06:26 rgb
4686+ * Reduce default table to 16 bits width.
4687+ *
4688+ * Revision 1.17 2002/09/20 15:40:29 rgb
4689+ * Define switch to activate new SAref code.
4690+ * Prefix macros with "IPSEC_".
4691+ * Rework saref freelist.
4692+ * Restrict some bits to kernel context for use to klips utils.
4693+ *
4694+ * Revision 1.16 2002/09/20 05:00:31 rgb
4695+ * Define switch to divulge hmac keys for debugging.
4696+ * Added IPOPTIONS switch.
4697+ *
4698+ * Revision 1.15 2002/09/19 02:34:24 mcr
4699+ * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
4700+ * to decide if we are to create /proc/net/ipsec/.
4701+ *
4702+ * Revision 1.14 2002/08/30 01:20:54 mcr
4703+ * reorganized 2.0/2.2/2.4 procfs support macro so match
4704+ * 2.4 values/typedefs.
4705+ *
4706+ * Revision 1.13 2002/07/28 22:03:28 mcr
4707+ * added some documentation to SA_REF_*
4708+ * turned on fix for ESPIV attack, now that we have the attack code.
4709+ *
4710+ * Revision 1.12 2002/07/26 08:48:31 rgb
4711+ * Added SA ref table code.
4712+ *
4713+ * Revision 1.11 2002/07/23 02:57:45 rgb
4714+ * Define ARPHRD_VOID for < 2.4 kernels.
4715+ *
4716+ * Revision 1.10 2002/05/27 21:37:28 rgb
4717+ * Set the defaults sanely for those adventurous enough to try more than 1
4718+ * digit of ipsec devices.
4719+ *
4720+ * Revision 1.9 2002/05/27 18:56:07 rgb
4721+ * Convert to dynamic ipsec device allocation.
4722+ *
4723+ * Revision 1.8 2002/04/24 07:36:47 mcr
4724+ * Moved from ./klips/net/ipsec/ipsec_param.h,v
4725+ *
4726+ * Revision 1.7 2002/04/20 00:12:25 rgb
4727+ * Added esp IV CBC attack fix, disabled.
4728+ *
4729+ * Revision 1.6 2002/01/29 02:11:42 mcr
4730+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
4731+ * updating of IPv6 structures to match latest in6.h version.
4732+ * removed dead code from freeswan.h that also duplicated kversions.h
4733+ * code.
4734+ *
4735+ * Revision 1.5 2002/01/28 19:22:01 mcr
4736+ * by default, turn off LINEARIZE option
4737+ * (let kversions.h turn it on)
4738+ *
4739+ * Revision 1.4 2002/01/20 20:19:36 mcr
4740+ * renamed option to IP_FRAGMENT_LINEARIZE.
4741+ *
4742+ * Revision 1.3 2002/01/12 02:57:25 mcr
4743+ * first regression test causes acquire messages to be lost
4744+ * 100% of the time. This is to help testing of pluto.
4745+ *
4746+ * Revision 1.2 2001/11/26 09:16:14 rgb
4747+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4748+ *
4749+ * Revision 1.1.2.3 2001/10/23 04:40:16 mcr
4750+ * added #define for DIVULGING session keys in debug output.
4751+ *
4752+ * Revision 1.1.2.2 2001/10/22 20:53:25 mcr
4753+ * added a define to control forcing of DES parity.
4754+ *
4755+ * Revision 1.1.2.1 2001/09/25 02:20:19 mcr
4756+ * many common kernel configuration questions centralized.
4757+ * more things remain that should be moved from freeswan.h.
4758+ *
4759+ *
4760+ * Local variables:
4761+ * c-file-style: "linux"
4762+ * End:
4763+ *
4764+ */
4765--- /dev/null Tue Mar 11 13:02:56 2003
4766+++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004
4767@@ -0,0 +1,217 @@
4768+#ifndef _IPSEC_POLICY_H
4769+/*
4770+ * policy interface file between pluto and applications
4771+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
4772+ *
4773+ * This library is free software; you can redistribute it and/or modify it
4774+ * under the terms of the GNU Library General Public License as published by
4775+ * the Free Software Foundation; either version 2 of the License, or (at your
4776+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
4777+ *
4778+ * This library is distributed in the hope that it will be useful, but
4779+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4780+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
4781+ * License for more details.
4782+ *
4783+ * RCSID $Id: ipsec_policy.h,v 1.7.6.1 2005/07/26 01:53:07 ken Exp $
4784+ */
4785+#define _IPSEC_POLICY_H /* seen it, no need to see it again */
4786+
4787+
4788+/*
4789+ * this file defines an interface between an application (or rather an
4790+ * application library) and a key/policy daemon. It provides for inquiries
4791+ * as to the current state of a connected socket, as well as for general
4792+ * questions.
4793+ *
4794+ * In general, the interface is defined as a series of functional interfaces,
4795+ * and the policy messages should be internal. However, because this is in
4796+ * fact an ABI between pieces of the system that may get compiled and revised
4797+ * seperately, this ABI must be public and revision controlled.
4798+ *
4799+ * It is expected that the daemon will always support previous versions.
4800+ */
4801+
4802+#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
4803+
4804+enum ipsec_policy_command {
4805+ IPSEC_CMD_QUERY_FD = 1,
4806+ IPSEC_CMD_QUERY_HOSTPAIR = 2,
4807+ IPSEC_CMD_QUERY_DSTONLY = 3,
4808+};
4809+
4810+struct ipsec_policy_msg_head {
4811+ u_int32_t ipm_version;
4812+ u_int32_t ipm_msg_len;
4813+ u_int32_t ipm_msg_type;
4814+ u_int32_t ipm_msg_seq;
4815+};
4816+
4817+enum ipsec_privacy_quality {
4818+ IPSEC_PRIVACY_NONE = 0,
4819+ IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
4820+ IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
4821+ IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
4822+ IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
4823+ IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
4824+ IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
4825+ IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
4826+ IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
4827+};
4828+
4829+enum ipsec_bandwidth_quality {
4830+ IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
4831+ IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
4832+ Good enough for telnet/ssh. */
4833+ IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
4834+ IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
4835+ offloaded, but latency/jitter may be bad */
4836+ IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
4837+};
4838+
4839+/* moved from programs/pluto/constants.h */
4840+/* IPsec AH transform values
4841+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
4842+ * and in http://www.iana.org/assignments/isakmp-registry
4843+ */
4844+enum ipsec_authentication_algo {
4845+ AH_MD5=2,
4846+ AH_SHA=3,
4847+ AH_DES=4,
4848+ AH_SHA2_256=5,
4849+ AH_SHA2_384=6,
4850+ AH_SHA2_512=7
4851+};
4852+
4853+/* IPsec ESP transform values
4854+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
4855+ * and from http://www.iana.org/assignments/isakmp-registry
4856+ */
4857+
4858+enum ipsec_cipher_algo {
4859+ ESP_reserved=0,
4860+ ESP_DES_IV64=1,
4861+ ESP_DES=2,
4862+ ESP_3DES=3,
4863+ ESP_RC5=4,
4864+ ESP_IDEA=5,
4865+ ESP_CAST=6,
4866+ ESP_BLOWFISH=7,
4867+ ESP_3IDEA=8,
4868+ ESP_DES_IV32=9,
4869+ ESP_RC4=10,
4870+ ESP_NULL=11,
4871+ ESP_AES=12, /* 128 bit AES */
4872+};
4873+
4874+/* IPCOMP transform values
4875+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
4876+ */
4877+
4878+enum ipsec_comp_algo {
4879+ IPCOMP_OUI= 1,
4880+ IPCOMP_DEFLATE= 2,
4881+ IPCOMP_LZS= 3,
4882+ IPCOMP_V42BIS= 4
4883+};
4884+
4885+/* Identification type values
4886+ * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
4887+ */
4888+
4889+enum ipsec_id_type {
4890+ ID_IMPOSSIBLE= (-2), /* private to Pluto */
4891+ ID_MYID= (-1), /* private to Pluto */
4892+ ID_NONE= 0, /* private to Pluto */
4893+ ID_IPV4_ADDR= 1,
4894+ ID_FQDN= 2,
4895+ ID_USER_FQDN= 3,
4896+ ID_IPV4_ADDR_SUBNET= 4,
4897+ ID_IPV6_ADDR= 5,
4898+ ID_IPV6_ADDR_SUBNET= 6,
4899+ ID_IPV4_ADDR_RANGE= 7,
4900+ ID_IPV6_ADDR_RANGE= 8,
4901+ ID_DER_ASN1_DN= 9,
4902+ ID_DER_ASN1_GN= 10,
4903+ ID_KEY_ID= 11
4904+};
4905+
4906+/* Certificate type values
4907+ * RFC 2408 ISAKMP, chapter 3.9
4908+ */
4909+enum ipsec_cert_type {
4910+ CERT_NONE= 0, /* none, or guess from file contents */
4911+ CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */
4912+ CERT_PGP= 2,
4913+ CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */
4914+ CERT_X509_SIGNATURE= 4,
4915+ CERT_X509_KEY_EXCHANGE= 5,
4916+ CERT_KERBEROS_TOKENS= 6,
4917+ CERT_CRL= 7,
4918+ CERT_ARL= 8,
4919+ CERT_SPKI= 9,
4920+ CERT_X509_ATTRIBUTE= 10,
4921+ CERT_RAW_RSA= 11, /* raw RSA from config file */
4922+};
4923+
4924+/* a SIG record in ASCII */
4925+struct ipsec_dns_sig {
4926+ char fqdn[256];
4927+ char dns_sig[768]; /* empty string if not signed */
4928+};
4929+
4930+struct ipsec_raw_key {
4931+ char id_name[256];
4932+ char fs_keyid[8];
4933+};
4934+
4935+struct ipsec_identity {
4936+ enum ipsec_id_type ii_type;
4937+ enum ipsec_cert_type ii_format;
4938+ union {
4939+ struct ipsec_dns_sig ipsec_dns_signed;
4940+ /* some thing for PGP */
4941+ /* some thing for PKIX */
4942+ struct ipsec_raw_key ipsec_raw_key;
4943+ } ii_credential;
4944+};
4945+
4946+#define IPSEC_MAX_CREDENTIALS 32
4947+
4948+struct ipsec_policy_cmd_query {
4949+ struct ipsec_policy_msg_head head;
4950+
4951+ /* Query section */
4952+ ip_address query_local; /* us */
4953+ ip_address query_remote; /* them */
4954+ u_int8_t proto; /* TCP, ICMP, etc. */
4955+ u_short src_port, dst_port;
4956+
4957+ /* Answer section */
4958+ enum ipsec_privacy_quality strength;
4959+ enum ipsec_bandwidth_quality bandwidth;
4960+ enum ipsec_authentication_algo auth_detail;
4961+ enum ipsec_cipher_algo esp_detail;
4962+ enum ipsec_comp_algo comp_detail;
4963+
4964+ int credential_count;
4965+
4966+ struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
4967+};
4968+
4969+#define IPSEC_POLICY_SOCKET "/var/run/pluto/pluto.info"
4970+
4971+/* prototypes */
4972+extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
4973+extern err_t ipsec_policy_init(void);
4974+extern err_t ipsec_policy_final(void);
4975+extern err_t ipsec_policy_readmsg(int policysock,
4976+ unsigned char *buf, size_t buflen);
4977+extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
4978+extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
4979+
4980+
4981+extern const char *ipsec_policy_version_code(void);
4982+extern const char *ipsec_policy_version_string(void);
4983+
4984+#endif /* _IPSEC_POLICY_H */
4985--- /dev/null Tue Mar 11 13:02:56 2003
4986+++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004
4987@@ -0,0 +1,199 @@
4988+/*
4989+ * @(#) prototypes for FreeSWAN functions
4990+ *
4991+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4992+ * and Michael Richardson <mcr@freeswan.org>
4993+ *
4994+ * This program is free software; you can redistribute it and/or modify it
4995+ * under the terms of the GNU General Public License as published by the
4996+ * Free Software Foundation; either version 2 of the License, or (at your
4997+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4998+ *
4999+ * This program is distributed in the hope that it will be useful, but
5000+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5001+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5002+ * for more details.
5003+ *
5004+ * RCSID $Id: ipsec_proto.h,v 1.14 2005/04/29 04:50:03 mcr Exp $
5005+ *
5006+ */
5007+
5008+#ifndef _IPSEC_PROTO_H_
5009+
5010+#include "ipsec_param.h"
5011+
5012+/*
5013+ * This file is a kernel only file that declares prototypes for
5014+ * all intra-module function calls and global data structures.
5015+ *
5016+ * Include this file last.
5017+ *
5018+ */
5019+
5020+/* forward references */
5021+enum ipsec_direction;
5022+enum ipsec_life_type;
5023+struct ipsec_lifetime64;
5024+struct ident;
5025+struct sockaddr_encap;
5026+struct ipsec_sa;
5027+
5028+/* ipsec_init.c */
5029+extern struct prng ipsec_prng;
5030+
5031+/* ipsec_sa.c */
5032+extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
5033+extern spinlock_t tdb_lock;
5034+extern int ipsec_sadb_init(void);
5035+extern int ipsec_sadb_cleanup(__u8);
5036+
5037+extern struct ipsec_sa *ipsec_sa_alloc(int*error);
5038+
5039+
5040+extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *);
5041+extern int ipsec_sa_put(struct ipsec_sa *);
5042+extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
5043+extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
5044+extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
5045+
5046+extern int ipsec_sa_init(struct ipsec_sa *ipsp);
5047+extern int ipsec_sa_wipe(struct ipsec_sa *ipsp);
5048+
5049+/* debug declarations */
5050+
5051+/* ipsec_proc.c */
5052+extern int ipsec_proc_init(void);
5053+extern void ipsec_proc_cleanup(void);
5054+
5055+/* ipsec_rcv.c */
5056+extern int ipsec_rcv(struct sk_buff *skb);
5057+extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5058+
5059+/* ipsec_xmit.c */
5060+struct ipsec_xmit_state;
5061+extern enum ipsec_xmit_value ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
5062+extern enum ipsec_xmit_value ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
5063+extern void ipsec_print_ip(struct iphdr *ip);
5064+
5065+
5066+
5067+/* ipsec_radij.c */
5068+extern int ipsec_makeroute(struct sockaddr_encap *ea,
5069+ struct sockaddr_encap *em,
5070+ ip_said said,
5071+ uint32_t pid,
5072+ struct sk_buff *skb,
5073+ struct ident *ident_s,
5074+ struct ident *ident_d);
5075+
5076+extern int ipsec_breakroute(struct sockaddr_encap *ea,
5077+ struct sockaddr_encap *em,
5078+ struct sk_buff **first,
5079+ struct sk_buff **last);
5080+
5081+int ipsec_radijinit(void);
5082+int ipsec_cleareroutes(void);
5083+int ipsec_radijcleanup(void);
5084+
5085+/* ipsec_life.c */
5086+extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
5087+ const char *lifename,
5088+ const char *saname,
5089+ enum ipsec_life_type ilt,
5090+ enum ipsec_direction idir,
5091+ struct ipsec_sa *ips);
5092+
5093+
5094+extern int ipsec_lifetime_format(char *buffer,
5095+ int buflen,
5096+ char *lifename,
5097+ enum ipsec_life_type timebaselife,
5098+ struct ipsec_lifetime64 *lifetime);
5099+
5100+extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
5101+ __u64 newvalue);
5102+
5103+extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
5104+ __u64 newvalue);
5105+
5106+/* ipsec_snprintf.c */
5107+extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
5108+extern void ipsec_dmp_block(char *s, caddr_t bb, int len);
5109+
5110+
5111+/* ipsec_alg.c */
5112+extern int ipsec_alg_init(void);
5113+
5114+
5115+#ifdef CONFIG_KLIPS_DEBUG
5116+
5117+extern int debug_xform;
5118+extern int debug_eroute;
5119+extern int debug_spi;
5120+extern int debug_netlink;
5121+
5122+#endif /* CONFIG_KLIPS_DEBUG */
5123+
5124+
5125+
5126+
5127+#define _IPSEC_PROTO_H
5128+#endif /* _IPSEC_PROTO_H_ */
5129+
5130+/*
5131+ * $Log: ipsec_proto.h,v $
5132+ * Revision 1.14 2005/04/29 04:50:03 mcr
5133+ * prototypes for xmit and alg code.
5134+ *
5135+ * Revision 1.13 2005/04/17 03:46:07 mcr
5136+ * added prototypes for ipsec_rcv() routines.
5137+ *
5138+ * Revision 1.12 2005/04/14 20:28:37 mcr
5139+ * added additional prototypes.
5140+ *
5141+ * Revision 1.11 2005/04/14 01:16:28 mcr
5142+ * add prototypes for snprintf.
5143+ *
5144+ * Revision 1.10 2005/04/13 22:47:28 mcr
5145+ * make sure that forward references are available.
5146+ *
5147+ * Revision 1.9 2004/07/10 19:08:41 mcr
5148+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5149+ *
5150+ * Revision 1.8 2004/04/05 19:55:06 mcr
5151+ * Moved from linux/include/freeswan/ipsec_proto.h,v
5152+ *
5153+ * Revision 1.7 2003/10/31 02:27:05 mcr
5154+ * pulled up port-selector patches and sa_id elimination.
5155+ *
5156+ * Revision 1.6.30.1 2003/10/29 01:10:19 mcr
5157+ * elimited "struct sa_id"
5158+ *
5159+ * Revision 1.6 2002/05/23 07:13:48 rgb
5160+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
5161+ *
5162+ * Revision 1.5 2002/05/14 02:36:40 rgb
5163+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
5164+ * with "put" usage in the kernel.
5165+ *
5166+ * Revision 1.4 2002/04/24 07:36:47 mcr
5167+ * Moved from ./klips/net/ipsec/ipsec_proto.h,v
5168+ *
5169+ * Revision 1.3 2002/04/20 00:12:25 rgb
5170+ * Added esp IV CBC attack fix, disabled.
5171+ *
5172+ * Revision 1.2 2001/11/26 09:16:15 rgb
5173+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5174+ *
5175+ * Revision 1.1.2.1 2001/09/25 02:21:01 mcr
5176+ * ipsec_proto.h created to keep prototypes rather than deal with
5177+ * cyclic dependancies of structures and prototypes in .h files.
5178+ *
5179+ *
5180+ *
5181+ * Local variables:
5182+ * c-file-style: "linux"
5183+ * End:
5184+ *
5185+ */
5186+
5187--- /dev/null Tue Mar 11 13:02:56 2003
5188+++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004
5189@@ -0,0 +1,179 @@
5190+/*
5191+ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
5192+ * Copyright (C) 1996, 1997 John Ioannidis.
5193+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5194+ *
5195+ * This program is free software; you can redistribute it and/or modify it
5196+ * under the terms of the GNU General Public License as published by the
5197+ * Free Software Foundation; either version 2 of the License, or (at your
5198+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5199+ *
5200+ * This program is distributed in the hope that it will be useful, but
5201+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5202+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5203+ * for more details.
5204+ *
5205+ * RCSID $Id: ipsec_radij.h,v 1.22 2004/07/10 19:08:41 mcr Exp $
5206+ */
5207+
5208+#ifndef _IPSEC_RADIJ_H
5209+
5210+#include <openswan.h>
5211+
5212+int ipsec_walk(char *);
5213+
5214+int ipsec_rj_walker_procprint(struct radij_node *, void *);
5215+int ipsec_rj_walker_delete(struct radij_node *, void *);
5216+
5217+/* This structure is used to pass information between
5218+ * ipsec_eroute_get_info and ipsec_rj_walker_procprint
5219+ * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
5220+ */
5221+struct wsbuf
5222+{
5223+ /* from caller of ipsec_eroute_get_info: */
5224+ char *const buffer; /* start of buffer provided */
5225+ const int length; /* length of buffer provided */
5226+ const off_t offset; /* file position of first character of interest */
5227+ /* accumulated by ipsec_rj_walker_procprint: */
5228+ int len; /* number of character filled into buffer */
5229+ off_t begin; /* file position contained in buffer[0] (<=offset) */
5230+};
5231+
5232+extern struct radij_node_head *rnh;
5233+extern spinlock_t eroute_lock;
5234+
5235+struct eroute * ipsec_findroute(struct sockaddr_encap *);
5236+
5237+#define O1(x) (int)(((x)>>24)&0xff)
5238+#define O2(x) (int)(((x)>>16)&0xff)
5239+#define O3(x) (int)(((x)>>8)&0xff)
5240+#define O4(x) (int)(((x))&0xff)
5241+
5242+#ifdef CONFIG_KLIPS_DEBUG
5243+extern int debug_radij;
5244+void rj_dumptrees(void);
5245+
5246+#define DB_RJ_DUMPTREES 0x0001
5247+#define DB_RJ_FINDROUTE 0x0002
5248+#endif /* CONFIG_KLIPS_DEBUG */
5249+
5250+#define _IPSEC_RADIJ_H
5251+#endif
5252+
5253+/*
5254+ * $Log: ipsec_radij.h,v $
5255+ * Revision 1.22 2004/07/10 19:08:41 mcr
5256+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5257+ *
5258+ * Revision 1.21 2004/04/29 11:06:42 ken
5259+ * Last bits from 2.06 procfs updates
5260+ *
5261+ * Revision 1.20 2004/04/06 02:49:08 mcr
5262+ * pullup of algo code from alg-branch.
5263+ *
5264+ * Revision 1.19 2004/04/05 19:55:06 mcr
5265+ * Moved from linux/include/freeswan/ipsec_radij.h,v
5266+ *
5267+ * Revision 1.18 2002/04/24 07:36:47 mcr
5268+ * Moved from ./klips/net/ipsec/ipsec_radij.h,v
5269+ *
5270+ * Revision 1.17 2001/11/26 09:23:49 rgb
5271+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5272+ *
5273+ * Revision 1.16.2.1 2001/09/25 02:21:17 mcr
5274+ * ipsec_proto.h created to keep prototypes rather than deal with
5275+ * cyclic dependancies of structures and prototypes in .h files.
5276+ *
5277+ * Revision 1.16 2001/09/15 16:24:04 rgb
5278+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
5279+ *
5280+ * Revision 1.15 2001/09/14 16:58:37 rgb
5281+ * Added support for storing the first and last packets through a HOLD.
5282+ *
5283+ * Revision 1.14 2001/09/08 21:13:32 rgb
5284+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
5285+ *
5286+ * Revision 1.13 2001/06/14 19:35:09 rgb
5287+ * Update copyright date.
5288+ *
5289+ * Revision 1.12 2001/05/27 06:12:11 rgb
5290+ * Added structures for pid, packet count and last access time to eroute.
5291+ * Added packet count to beginning of /proc/net/ipsec_eroute.
5292+ *
5293+ * Revision 1.11 2000/09/08 19:12:56 rgb
5294+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
5295+ *
5296+ * Revision 1.10 1999/11/17 15:53:39 rgb
5297+ * Changed all occurrences of #include "../../../lib/freeswan.h"
5298+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
5299+ * klips/net/ipsec/Makefile.
5300+ *
5301+ * Revision 1.9 1999/10/01 00:01:23 rgb
5302+ * Added eroute structure locking.
5303+ *
5304+ * Revision 1.8 1999/04/11 00:28:59 henry
5305+ * GPL boilerplate
5306+ *
5307+ * Revision 1.7 1999/04/06 04:54:26 rgb
5308+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5309+ * patch shell fixes.
5310+ *
5311+ * Revision 1.6 1999/01/22 06:23:26 rgb
5312+ * Cruft clean-out.
5313+ *
5314+ * Revision 1.5 1998/10/25 02:42:08 rgb
5315+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
5316+ * argument to be able to transmit more infomation about errors.
5317+ *
5318+ * Revision 1.4 1998/10/19 14:44:29 rgb
5319+ * Added inclusion of freeswan.h.
5320+ * sa_id structure implemented and used: now includes protocol.
5321+ *
5322+ * Revision 1.3 1998/07/28 00:03:31 rgb
5323+ * Comment out temporary inet_nto4u() kluge.
5324+ *
5325+ * Revision 1.2 1998/07/14 18:22:00 rgb
5326+ * Add function to clear the eroute table.
5327+ *
5328+ * Revision 1.1 1998/06/18 21:27:49 henry
5329+ * move sources from klips/src to klips/net/ipsec, to keep stupid
5330+ * kernel-build scripts happier in the presence of symlinks
5331+ *
5332+ * Revision 1.5 1998/05/25 20:30:38 rgb
5333+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
5334+ *
5335+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
5336+ * add ipsec_rj_walker_delete.
5337+ *
5338+ * Revision 1.4 1998/05/21 13:02:56 rgb
5339+ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
5340+ * limit fix.
5341+ *
5342+ * Revision 1.3 1998/04/21 21:29:09 rgb
5343+ * Rearrange debug switches to change on the fly debug output from user
5344+ * space. Only kernel changes checked in at this time. radij.c was also
5345+ * changed to temporarily remove buggy debugging code in rj_delete causing
5346+ * an OOPS and hence, netlink device open errors.
5347+ *
5348+ * Revision 1.2 1998/04/14 17:30:39 rgb
5349+ * Fix up compiling errors for radij tree memory reclamation.
5350+ *
5351+ * Revision 1.1 1998/04/09 03:06:10 henry
5352+ * sources moved up from linux/net/ipsec
5353+ *
5354+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
5355+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5356+ *
5357+ * Revision 0.4 1997/01/15 01:28:15 ji
5358+ * No changes.
5359+ *
5360+ * Revision 0.3 1996/11/20 14:39:04 ji
5361+ * Minor cleanups.
5362+ * Rationalized debugging code.
5363+ *
5364+ * Revision 0.2 1996/11/02 00:18:33 ji
5365+ * First limited release.
5366+ *
5367+ *
5368+ */
5369--- /dev/null Tue Mar 11 13:02:56 2003
5370+++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004
5371@@ -0,0 +1,199 @@
5372+/*
5373+ *
5374+ * Copyright (C) 1996, 1997 John Ioannidis.
5375+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5376+ *
5377+ * This program is free software; you can redistribute it and/or modify it
5378+ * under the terms of the GNU General Public License as published by the
5379+ * Free Software Foundation; either version 2 of the License, or (at your
5380+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5381+ *
5382+ * This program is distributed in the hope that it will be useful, but
5383+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5384+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5385+ * for more details.
5386+ *
5387+ * RCSID $Id: ipsec_rcv.h,v 1.28.2.2 2006/10/06 21:39:26 paul Exp $
5388+ */
5389+
5390+#ifndef IPSEC_RCV_H
5391+#define IPSEC_RCV_H
5392+
5393+#include "openswan/ipsec_auth.h"
5394+
5395+#define DB_RX_PKTRX 0x0001
5396+#define DB_RX_PKTRX2 0x0002
5397+#define DB_RX_DMP 0x0004
5398+#define DB_RX_IPSA 0x0010
5399+#define DB_RX_XF 0x0020
5400+#define DB_RX_IPAD 0x0040
5401+#define DB_RX_INAU 0x0080
5402+#define DB_RX_OINFO 0x0100
5403+#define DB_RX_OINFO2 0x0200
5404+#define DB_RX_OH 0x0400
5405+#define DB_RX_REPLAY 0x0800
5406+
5407+#ifdef __KERNEL__
5408+/* struct options; */
5409+
5410+#define __NO_VERSION__
5411+#ifndef AUTOCONF_INCLUDED
5412+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
5413+#endif
5414+#ifdef CONFIG_MODULES
5415+#include <linux/module.h>
5416+#endif
5417+#include <linux/version.h>
5418+#include <openswan.h>
5419+
5420+#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
5421+
5422+struct ipsec_birth_reply {
5423+ int packet_template_len;
5424+ unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
5425+};
5426+
5427+extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
5428+extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
5429+
5430+enum ipsec_rcv_value {
5431+ IPSEC_RCV_LASTPROTO=1,
5432+ IPSEC_RCV_OK=0,
5433+ IPSEC_RCV_BADPROTO=-1,
5434+ IPSEC_RCV_BADLEN=-2,
5435+ IPSEC_RCV_ESP_BADALG=-3,
5436+ IPSEC_RCV_3DES_BADBLOCKING=-4,
5437+ IPSEC_RCV_ESP_DECAPFAIL=-5,
5438+ IPSEC_RCV_DECAPFAIL=-6,
5439+ IPSEC_RCV_SAIDNOTFOUND=-7,
5440+ IPSEC_RCV_IPCOMPALONE=-8,
5441+ IPSEC_RCV_IPCOMPFAILED=-10,
5442+ IPSEC_RCV_SAIDNOTLIVE=-11,
5443+ IPSEC_RCV_FAILEDINBOUND=-12,
5444+ IPSEC_RCV_LIFETIMEFAILED=-13,
5445+ IPSEC_RCV_BADAUTH=-14,
5446+ IPSEC_RCV_REPLAYFAILED=-15,
5447+ IPSEC_RCV_AUTHFAILED=-16,
5448+ IPSEC_RCV_REPLAYROLLED=-17,
5449+ IPSEC_RCV_BAD_DECRYPT=-18
5450+};
5451+
5452+struct ipsec_rcv_state {
5453+ struct sk_buff *skb;
5454+ struct net_device_stats *stats;
5455+ struct iphdr *ipp; /* the IP header */
5456+ struct ipsec_sa *ipsp; /* current SA being processed */
5457+ int len; /* length of packet */
5458+ int ilen; /* length of inner payload (-authlen) */
5459+ int authlen; /* how big is the auth data at end */
5460+ int hard_header_len; /* layer 2 size */
5461+ int iphlen; /* how big is IP header */
5462+ struct auth_alg *authfuncs;
5463+ ip_said said;
5464+ char sa[SATOT_BUF];
5465+ size_t sa_len;
5466+ __u8 next_header;
5467+ __u8 hash[AH_AMAX];
5468+ char ipsaddr_txt[ADDRTOA_BUF];
5469+ char ipdaddr_txt[ADDRTOA_BUF];
5470+ __u8 *octx;
5471+ __u8 *ictx;
5472+ int ictx_len;
5473+ int octx_len;
5474+ union {
5475+ struct {
5476+ struct esphdr *espp;
5477+ } espstuff;
5478+ struct {
5479+ struct ahhdr *ahp;
5480+ } ahstuff;
5481+ struct {
5482+ struct ipcomphdr *compp;
5483+ } ipcompstuff;
5484+ } protostuff;
5485+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
5486+ __u8 natt_type;
5487+ __u16 natt_sport;
5488+ __u16 natt_dport;
5489+ int natt_len;
5490+#endif
5491+};
5492+
5493+extern int
5494+#ifdef PROTO_HANDLER_SINGLE_PARM
5495+ipsec_rcv(struct sk_buff *skb);
5496+#else /* PROTO_HANDLER_SINGLE_PARM */
5497+ipsec_rcv(struct sk_buff *skb,
5498+ unsigned short xlen);
5499+#endif /* PROTO_HANDLER_SINGLE_PARM */
5500+
5501+#ifdef CONFIG_KLIPS_DEBUG
5502+extern int debug_rcv;
5503+#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
5504+#else
5505+#define ipsec_rcv_dmp(_x,_y, _z) do {} while(0)
5506+#endif /* CONFIG_KLIPS_DEBUG */
5507+
5508+extern int sysctl_ipsec_inbound_policy_check;
5509+#endif /* __KERNEL__ */
5510+
5511+extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5512+
5513+
5514+#endif /* IPSEC_RCV_H */
5515+
5516+/*
5517+ * $Log: ipsec_rcv.h,v $
5518+ * Revision 1.28.2.2 2006/10/06 21:39:26 paul
5519+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
5520+ * set. This is defined through autoconf.h which is included through the
5521+ * linux kernel build macros.
5522+ *
5523+ * Revision 1.28.2.1 2006/07/10 15:52:20 paul
5524+ * Fix for bug #642 by Bart Trojanowski
5525+ *
5526+ * Revision 1.28 2005/05/11 00:59:45 mcr
5527+ * do not call debug routines if !defined KLIPS_DEBUG.
5528+ *
5529+ * Revision 1.27 2005/04/29 04:59:46 mcr
5530+ * use ipsec_dmp_block.
5531+ *
5532+ * Revision 1.26 2005/04/13 22:48:35 mcr
5533+ * added comments, and removed some log.
5534+ * removed Linux 2.0 support.
5535+ *
5536+ * Revision 1.25 2005/04/08 18:25:37 mcr
5537+ * prototype klips26 encap receive function
5538+ *
5539+ * Revision 1.24 2004/08/20 21:45:37 mcr
5540+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5541+ * be 26sec compatible. But, some defines where changed.
5542+ *
5543+ * Revision 1.23 2004/08/03 18:17:40 mcr
5544+ * in 2.6, use "net_device" instead of #define device->net_device.
5545+ * this probably breaks 2.0 compiles.
5546+ *
5547+ * Revision 1.22 2004/07/10 19:08:41 mcr
5548+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5549+ *
5550+ * Revision 1.21 2004/04/06 02:49:08 mcr
5551+ * pullup of algo code from alg-branch.
5552+ *
5553+ * Revision 1.20 2004/04/05 19:55:06 mcr
5554+ * Moved from linux/include/freeswan/ipsec_rcv.h,v
5555+ *
5556+ * Revision 1.19 2003/12/15 18:13:09 mcr
5557+ * when compiling with NAT traversal, don't assume that the
5558+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
5559+ * is set.
5560+ *
5561+ * history elided 2005-04-12.
5562+ *
5563+ * Local Variables:
5564+ * c-basic-offset:8
5565+ * c-style:linux
5566+ * End:
5567+ *
5568+ */
5569+
5570+
5571--- /dev/null Tue Mar 11 13:02:56 2003
5572+++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004
5573@@ -0,0 +1,355 @@
5574+/*
5575+ * @(#) Definitions of IPsec Security Association (ipsec_sa)
5576+ *
5577+ * Copyright (C) 2001, 2002, 2003
5578+ * Richard Guy Briggs <rgb@freeswan.org>
5579+ * and Michael Richardson <mcr@freeswan.org>
5580+ *
5581+ * This program is free software; you can redistribute it and/or modify it
5582+ * under the terms of the GNU General Public License as published by the
5583+ * Free Software Foundation; either version 2 of the License, or (at your
5584+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5585+ *
5586+ * This program is distributed in the hope that it will be useful, but
5587+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5588+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5589+ * for more details.
5590+ *
5591+ * RCSID $Id: ipsec_sa.h,v 1.23 2005/05/11 01:18:59 mcr Exp $
5592+ *
5593+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
5594+ *
5595+ */
5596+
5597+/*
5598+ * This file describes the IPsec Security Association Structure.
5599+ *
5600+ * This structure keeps track of a single transform that may be done
5601+ * to a set of packets. It can describe applying the transform or
5602+ * apply the reverse. (e.g. compression vs expansion). However, it
5603+ * only describes one at a time. To describe both, two structures would
5604+ * be used, but since the sides of the transform are performed
5605+ * on different machines typically it is usual to have only one side
5606+ * of each association.
5607+ *
5608+ */
5609+
5610+#ifndef _IPSEC_SA_H_
5611+
5612+#ifdef __KERNEL__
5613+#include "openswan/ipsec_stats.h"
5614+#include "openswan/ipsec_life.h"
5615+#include "openswan/ipsec_eroute.h"
5616+#endif /* __KERNEL__ */
5617+#include "openswan/ipsec_param.h"
5618+
5619+#include "pfkeyv2.h"
5620+
5621+
5622+/* SAs are held in a table.
5623+ * Entries in this table are referenced by IPsecSAref_t values.
5624+ * IPsecSAref_t values are conceptually subscripts. Because
5625+ * we want to allocate the table piece-meal, the subscripting
5626+ * is implemented with two levels, a bit like paged virtual memory.
5627+ * This representation mechanism is known as an Iliffe Vector.
5628+ *
5629+ * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
5630+ * pointers to subtables.
5631+ * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
5632+ * is a pointer to an SA.
5633+ *
5634+ * An IPsecSAref_t contains either an exceptional value (signified by the
5635+ * high-order bit being on) or a reference to a table entry. A table entry
5636+ * reference has the subtable subscript in the low-order
5637+ * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
5638+ * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
5639+ *
5640+ * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
5641+ * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
5642+ *
5643+ * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
5644+ * struct ipsec_sa*. The macro definition clearly shows the two-level
5645+ * access needed to find the SA pointer.
5646+ *
5647+ * The Maintable is allocated when IPsec is initialized.
5648+ * Each subtable is allocated when needed, but the first is allocated
5649+ * when IPsec is initialized.
5650+ *
5651+ * IPsecSAref_t is designed to be smaller than an NFmark so that
5652+ * they can be stored in NFmarks and still leave a few bits for other
5653+ * purposes. The spare bits are in the low order of the NFmark
5654+ * but in the high order of the IPsecSAref_t, so conversion is required.
5655+ * We pick the upper bits of NFmark on the theory that they are less likely to
5656+ * interfere with more pedestrian uses of nfmark.
5657+ */
5658+
5659+
5660+typedef unsigned short int IPsecRefTableUnusedCount;
5661+
5662+#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
5663+
5664+#ifdef __KERNEL__
5665+#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
5666+#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")"
5667+#endif
5668+
5669+#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5670+
5671+#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5672+#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5673+
5674+#ifdef CONFIG_NETFILTER
5675+#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
5676+#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
5677+#else /* CONFIG_NETFILTER */
5678+/* just make it work for now, it doesn't matter, since there is no nfmark */
5679+#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
5680+#endif /* CONFIG_NETFILTER */
5681+#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
5682+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
5683+
5684+#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
5685+#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)
5686+#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
5687+
5688+#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5689+#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
5690+#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
5691+
5692+#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
5693+#define IPsecSA2SAref(x) ((x)->ips_ref)
5694+
5695+#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
5696+
5697+/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
5698+struct ipsec_sa
5699+{
5700+ IPsecSAref_t ips_ref; /* reference table entry number */
5701+ atomic_t ips_refcount; /* reference count for this struct */
5702+ struct ipsec_sa *ips_hnext; /* next in hash chain */
5703+ struct ipsec_sa *ips_inext; /* pointer to next xform */
5704+ struct ipsec_sa *ips_onext; /* pointer to prev xform */
5705+
5706+ struct ifnet *ips_rcvif; /* related rcv encap interface */
5707+
5708+ ip_said ips_said; /* SA ID */
5709+
5710+ __u32 ips_seq; /* seq num of msg that initiated this SA */
5711+ __u32 ips_pid; /* PID of process that initiated this SA */
5712+ __u8 ips_authalg; /* auth algorithm for this SA */
5713+ __u8 ips_encalg; /* enc algorithm for this SA */
5714+
5715+ struct ipsec_stats ips_errs;
5716+
5717+ __u8 ips_replaywin; /* replay window size */
5718+ enum sadb_sastate ips_state; /* state of SA */
5719+ __u32 ips_replaywin_lastseq; /* last pkt sequence num */
5720+ __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
5721+ __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
5722+
5723+ __u32 ips_flags; /* generic xform flags */
5724+
5725+
5726+ struct ipsec_lifetimes ips_life; /* lifetime records */
5727+
5728+ /* selector information */
5729+ __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */
5730+ struct sockaddr*ips_addr_s; /* src sockaddr */
5731+ struct sockaddr*ips_addr_d; /* dst sockaddr */
5732+ struct sockaddr*ips_addr_p; /* proxy sockaddr */
5733+ __u16 ips_addr_s_size;
5734+ __u16 ips_addr_d_size;
5735+ __u16 ips_addr_p_size;
5736+ ip_address ips_flow_s;
5737+ ip_address ips_flow_d;
5738+ ip_address ips_mask_s;
5739+ ip_address ips_mask_d;
5740+
5741+ __u16 ips_key_bits_a; /* size of authkey in bits */
5742+ __u16 ips_auth_bits; /* size of authenticator in bits */
5743+ __u16 ips_key_bits_e; /* size of enckey in bits */
5744+ __u16 ips_iv_bits; /* size of IV in bits */
5745+ __u8 ips_iv_size;
5746+ __u16 ips_key_a_size;
5747+ __u16 ips_key_e_size;
5748+
5749+ caddr_t ips_key_a; /* authentication key */
5750+ caddr_t ips_key_e; /* encryption key */
5751+ caddr_t ips_iv; /* Initialisation Vector */
5752+
5753+ struct ident ips_ident_s; /* identity src */
5754+ struct ident ips_ident_d; /* identity dst */
5755+
5756+ /* these are included even if CONFIG_KLIPS_IPCOMP is off */
5757+ __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
5758+ __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
5759+ __u64 ips_comp_ratio_cbytes; /* compressed bytes */
5760+ __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
5761+
5762+ /* these are included even if CONFIG_IPSEC_NAT_TRAVERSAL is off */
5763+ __u8 ips_natt_type;
5764+ __u8 ips_natt_reserved[3];
5765+ __u16 ips_natt_sport;
5766+ __u16 ips_natt_dport;
5767+
5768+ struct sockaddr *ips_natt_oa;
5769+ __u16 ips_natt_oa_size;
5770+ __u16 ips_natt_reserved2;
5771+
5772+#if 0
5773+ __u32 ips_sens_dpd;
5774+ __u8 ips_sens_sens_level;
5775+ __u8 ips_sens_sens_len;
5776+ __u64* ips_sens_sens_bitmap;
5777+ __u8 ips_sens_integ_level;
5778+ __u8 ips_sens_integ_len;
5779+ __u64* ips_sens_integ_bitmap;
5780+#endif
5781+ struct ipsec_alg_enc *ips_alg_enc;
5782+ struct ipsec_alg_auth *ips_alg_auth;
5783+ IPsecSAref_t ips_ref_rel;
5784+};
5785+
5786+struct IPsecSArefSubTable
5787+{
5788+ struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
5789+};
5790+
5791+struct ipsec_sadb {
5792+ struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
5793+ IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
5794+ int refFreeListHead;
5795+ int refFreeListTail;
5796+ IPsecSAref_t refFreeListCont;
5797+ IPsecSAref_t said_hash[SADB_HASHMOD];
5798+ spinlock_t sadb_lock;
5799+};
5800+
5801+extern struct ipsec_sadb ipsec_sadb;
5802+
5803+extern int ipsec_SAref_recycle(void);
5804+extern int ipsec_SArefSubTable_alloc(unsigned table);
5805+extern int ipsec_saref_freelist_init(void);
5806+extern int ipsec_sadb_init(void);
5807+extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
5808+extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
5809+extern int ipsec_sa_free(struct ipsec_sa* ips);
5810+extern int ipsec_sa_put(struct ipsec_sa *ips);
5811+extern int ipsec_sa_add(struct ipsec_sa *ips);
5812+extern int ipsec_sa_del(struct ipsec_sa *ips);
5813+extern int ipsec_sa_delchain(struct ipsec_sa *ips);
5814+extern int ipsec_sadb_cleanup(__u8 proto);
5815+extern int ipsec_sadb_free(void);
5816+extern int ipsec_sa_wipe(struct ipsec_sa *ips);
5817+#endif /* __KERNEL__ */
5818+
5819+enum ipsec_direction {
5820+ ipsec_incoming = 1,
5821+ ipsec_outgoing = 2
5822+};
5823+
5824+#define _IPSEC_SA_H_
5825+#endif /* _IPSEC_SA_H_ */
5826+
5827+/*
5828+ * $Log: ipsec_sa.h,v $
5829+ * Revision 1.23 2005/05/11 01:18:59 mcr
5830+ * do not change structure based upon options, to avoid
5831+ * too many #ifdef.
5832+ *
5833+ * Revision 1.22 2005/04/14 01:17:09 mcr
5834+ * change sadb_state to an enum.
5835+ *
5836+ * Revision 1.21 2004/08/20 21:45:37 mcr
5837+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5838+ * be 26sec compatible. But, some defines where changed.
5839+ *
5840+ * Revision 1.20 2004/07/10 19:08:41 mcr
5841+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5842+ *
5843+ * Revision 1.19 2004/04/05 19:55:06 mcr
5844+ * Moved from linux/include/freeswan/ipsec_sa.h,v
5845+ *
5846+ * Revision 1.18 2004/04/05 19:41:05 mcr
5847+ * merged alg-branch code.
5848+ *
5849+ * Revision 1.17.2.1 2003/12/22 15:25:52 jjo
5850+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
5851+ *
5852+ * Revision 1.17 2003/12/10 01:20:06 mcr
5853+ * NAT-traversal patches to KLIPS.
5854+ *
5855+ * Revision 1.16 2003/10/31 02:27:05 mcr
5856+ * pulled up port-selector patches and sa_id elimination.
5857+ *
5858+ * Revision 1.15.4.1 2003/10/29 01:10:19 mcr
5859+ * elimited "struct sa_id"
5860+ *
5861+ * Revision 1.15 2003/05/11 00:53:09 mcr
5862+ * IPsecSAref_t and macros were moved to freeswan.h.
5863+ *
5864+ * Revision 1.14 2003/02/12 19:31:55 rgb
5865+ * Fixed bug in "file seen" machinery.
5866+ * Updated copyright year.
5867+ *
5868+ * Revision 1.13 2003/01/30 02:31:52 rgb
5869+ *
5870+ * Re-wrote comments describing SAref system for accuracy.
5871+ * Rename SAref table macro names for clarity.
5872+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
5873+ * Transmit error code through to caller from callee for better diagnosis of problems.
5874+ * Enclose all macro arguments in parens to avoid any possible obscrure bugs.
5875+ *
5876+ * Revision 1.12 2002/10/07 18:31:19 rgb
5877+ * Change comment to reflect the flexible nature of the main and sub-table widths.
5878+ * Added a counter for the number of unused entries in each subtable.
5879+ * Further break up host field type macro to host field.
5880+ * Move field width sanity checks to ipsec_sa.c
5881+ * Define a mask for an entire saref.
5882+ *
5883+ * Revision 1.11 2002/09/20 15:40:33 rgb
5884+ * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys.
5885+ * Fixed SAref/nfmark macros.
5886+ * Rework saref freeslist.
5887+ * Place all ipsec sadb globals into one struct.
5888+ * Restrict some bits to kernel context for use to klips utils.
5889+ *
5890+ * Revision 1.10 2002/09/20 05:00:34 rgb
5891+ * Update copyright date.
5892+ *
5893+ * Revision 1.9 2002/09/17 17:19:29 mcr
5894+ * make it compile even if there is no netfilter - we lost
5895+ * functionality, but it works, especially on 2.2.
5896+ *
5897+ * Revision 1.8 2002/07/28 22:59:53 mcr
5898+ * clarified/expanded one comment.
5899+ *
5900+ * Revision 1.7 2002/07/26 08:48:31 rgb
5901+ * Added SA ref table code.
5902+ *
5903+ * Revision 1.6 2002/05/31 17:27:48 rgb
5904+ * Comment fix.
5905+ *
5906+ * Revision 1.5 2002/05/27 18:55:03 rgb
5907+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
5908+ *
5909+ * Revision 1.4 2002/05/23 07:13:36 rgb
5910+ * Convert "usecount" to "refcount" to remove ambiguity.
5911+ *
5912+ * Revision 1.3 2002/04/24 07:36:47 mcr
5913+ * Moved from ./klips/net/ipsec/ipsec_sa.h,v
5914+ *
5915+ * Revision 1.2 2001/11/26 09:16:15 rgb
5916+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5917+ *
5918+ * Revision 1.1.2.1 2001/09/25 02:24:58 mcr
5919+ * struct tdb -> struct ipsec_sa.
5920+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
5921+ * ipsec_xform.c removed. header file still contains useful things.
5922+ *
5923+ *
5924+ * Local variables:
5925+ * c-file-style: "linux"
5926+ * End:
5927+ *
5928+ */
5929--- /dev/null Tue Mar 11 13:02:56 2003
5930+++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004
5931@@ -0,0 +1,79 @@
5932+/*
5933+ * RCSID $Id: ipsec_sha1.h,v 1.8 2004/04/05 19:55:07 mcr Exp $
5934+ */
5935+
5936+/*
5937+ * Here is the original comment from the distribution:
5938+
5939+SHA-1 in C
5940+By Steve Reid <steve@edmweb.com>
5941+100% Public Domain
5942+
5943+ * Adapted for use by the IPSEC code by John Ioannidis
5944+ */
5945+
5946+
5947+#ifndef _IPSEC_SHA1_H_
5948+#define _IPSEC_SHA1_H_
5949+
5950+typedef struct
5951+{
5952+ __u32 state[5];
5953+ __u32 count[2];
5954+ __u8 buffer[64];
5955+} SHA1_CTX;
5956+
5957+void SHA1Transform(__u32 state[5], __u8 buffer[64]);
5958+void SHA1Init(void *context);
5959+void SHA1Update(void *context, unsigned char *data, __u32 len);
5960+void SHA1Final(unsigned char digest[20], void *context);
5961+
5962+
5963+#endif /* _IPSEC_SHA1_H_ */
5964+
5965+/*
5966+ * $Log: ipsec_sha1.h,v $
5967+ * Revision 1.8 2004/04/05 19:55:07 mcr
5968+ * Moved from linux/include/freeswan/ipsec_sha1.h,v
5969+ *
5970+ * Revision 1.7 2002/09/10 01:45:09 mcr
5971+ * changed type of MD5_CTX and SHA1_CTX to void * so that
5972+ * the function prototypes would match, and could be placed
5973+ * into a pointer to a function.
5974+ *
5975+ * Revision 1.6 2002/04/24 07:36:47 mcr
5976+ * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
5977+ *
5978+ * Revision 1.5 1999/12/13 13:59:13 rgb
5979+ * Quick fix to argument size to Update bugs.
5980+ *
5981+ * Revision 1.4 1999/12/07 18:16:23 rgb
5982+ * Fixed comments at end of #endif lines.
5983+ *
5984+ * Revision 1.3 1999/04/06 04:54:27 rgb
5985+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5986+ * patch shell fixes.
5987+ *
5988+ * Revision 1.2 1998/11/30 13:22:54 rgb
5989+ * Rationalised all the klips kernel file headers. They are much shorter
5990+ * now and won't conflict under RH5.2.
5991+ *
5992+ * Revision 1.1 1998/06/18 21:27:50 henry
5993+ * move sources from klips/src to klips/net/ipsec, to keep stupid
5994+ * kernel-build scripts happier in the presence of symlinks
5995+ *
5996+ * Revision 1.2 1998/04/23 20:54:05 rgb
5997+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
5998+ * verified.
5999+ *
6000+ * Revision 1.1 1998/04/09 03:04:21 henry
6001+ * sources moved up from linux/net/ipsec
6002+ * these two include files modified not to include others except in kernel
6003+ *
6004+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
6005+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6006+ *
6007+ * Revision 0.4 1997/01/15 01:28:15 ji
6008+ * New transform
6009+ *
6010+ */
6011--- /dev/null Tue Mar 11 13:02:56 2003
6012+++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004
6013@@ -0,0 +1,76 @@
6014+/*
6015+ * @(#) definition of ipsec_stats structure
6016+ *
6017+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
6018+ * and Michael Richardson <mcr@freeswan.org>
6019+ *
6020+ * This program is free software; you can redistribute it and/or modify it
6021+ * under the terms of the GNU General Public License as published by the
6022+ * Free Software Foundation; either version 2 of the License, or (at your
6023+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6024+ *
6025+ * This program is distributed in the hope that it will be useful, but
6026+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6027+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6028+ * for more details.
6029+ *
6030+ * RCSID $Id: ipsec_stats.h,v 1.7 2005/04/14 01:17:45 mcr Exp $
6031+ *
6032+ */
6033+
6034+/*
6035+ * This file describes the errors/statistics that FreeSWAN collects.
6036+ */
6037+
6038+#ifndef _IPSEC_STATS_H_
6039+
6040+struct ipsec_stats {
6041+ __u32 ips_alg_errs; /* number of algorithm errors */
6042+ __u32 ips_auth_errs; /* # of authentication errors */
6043+ __u32 ips_encsize_errs; /* # of encryption size errors*/
6044+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
6045+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
6046+};
6047+
6048+#define _IPSEC_STATS_H_
6049+#endif /* _IPSEC_STATS_H_ */
6050+
6051+/*
6052+ * $Log: ipsec_stats.h,v $
6053+ * Revision 1.7 2005/04/14 01:17:45 mcr
6054+ * add prototypes for snprintf.
6055+ *
6056+ * Revision 1.6 2004/04/05 19:55:07 mcr
6057+ * Moved from linux/include/freeswan/ipsec_stats.h,v
6058+ *
6059+ * Revision 1.5 2004/04/05 19:41:05 mcr
6060+ * merged alg-branch code.
6061+ *
6062+ * Revision 1.4 2004/03/28 20:27:19 paul
6063+ * Included tested and confirmed fixes mcr made and dhr verified for
6064+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
6065+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
6066+ * dhr. (thanks dhr!)
6067+ *
6068+ * Revision 1.4 2004/03/24 01:58:31 mcr
6069+ * sprintf->snprintf for formatting into proc buffer.
6070+ *
6071+ * Revision 1.3.34.1 2004/04/05 04:30:46 mcr
6072+ * patches for alg-branch to compile/work with 2.x openswan
6073+ *
6074+ * Revision 1.3 2002/04/24 07:36:47 mcr
6075+ * Moved from ./klips/net/ipsec/ipsec_stats.h,v
6076+ *
6077+ * Revision 1.2 2001/11/26 09:16:16 rgb
6078+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6079+ *
6080+ * Revision 1.1.2.1 2001/09/25 02:27:00 mcr
6081+ * statistics moved to seperate structure.
6082+ *
6083+ *
6084+ *
6085+ * Local variables:
6086+ * c-file-style: "linux"
6087+ * End:
6088+ *
6089+ */
6090--- /dev/null Tue Mar 11 13:02:56 2003
6091+++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004
6092@@ -0,0 +1,280 @@
6093+/*
6094+ * IPSEC tunneling code
6095+ * Copyright (C) 1996, 1997 John Ioannidis.
6096+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6097+ *
6098+ * This program is free software; you can redistribute it and/or modify it
6099+ * under the terms of the GNU General Public License as published by the
6100+ * Free Software Foundation; either version 2 of the License, or (at your
6101+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6102+ *
6103+ * This program is distributed in the hope that it will be useful, but
6104+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6105+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6106+ * for more details.
6107+ *
6108+ * RCSID $Id: ipsec_tunnel.h,v 1.33 2005/06/04 16:06:05 mcr Exp $
6109+ */
6110+
6111+
6112+#ifdef NET_21
6113+# define DEV_QUEUE_XMIT(skb, device, pri) {\
6114+ skb->dev = device; \
6115+ neigh_compat_output(skb); \
6116+ /* skb->dst->output(skb); */ \
6117+ }
6118+# define ICMP_SEND(skb_in, type, code, info, dev) \
6119+ icmp_send(skb_in, type, code, htonl(info))
6120+# define IP_SEND(skb, dev) \
6121+ ip_send(skb);
6122+#else /* NET_21 */
6123+# define DEV_QUEUE_XMIT(skb, device, pri) {\
6124+ dev_queue_xmit(skb, device, pri); \
6125+ }
6126+# define ICMP_SEND(skb_in, type, code, info, dev) \
6127+ icmp_send(skb_in, type, code, info, dev)
6128+# define IP_SEND(skb, dev) \
6129+ if(ntohs(iph->tot_len) > physmtu) { \
6130+ ip_fragment(NULL, skb, dev, 0); \
6131+ ipsec_kfree_skb(skb); \
6132+ } else { \
6133+ dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
6134+ }
6135+#endif /* NET_21 */
6136+
6137+
6138+/*
6139+ * Heavily based on drivers/net/new_tunnel.c. Lots
6140+ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
6141+ */
6142+
6143+struct ipsectunnelconf
6144+{
6145+ __u32 cf_cmd;
6146+ union
6147+ {
6148+ char cfu_name[12];
6149+ } cf_u;
6150+#define cf_name cf_u.cfu_name
6151+};
6152+
6153+#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
6154+#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
6155+#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
6156+
6157+#ifdef __KERNEL__
6158+#include <linux/version.h>
6159+#ifndef KERNEL_VERSION
6160+# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
6161+#endif
6162+struct ipsecpriv
6163+{
6164+ struct sk_buff_head sendq;
6165+ struct net_device *dev;
6166+ struct wait_queue *wait_queue;
6167+ char locked;
6168+ int (*hard_start_xmit) (struct sk_buff *skb,
6169+ struct net_device *dev);
6170+ int (*hard_header) (struct sk_buff *skb,
6171+ struct net_device *dev,
6172+ unsigned short type,
6173+ void *daddr,
6174+ void *saddr,
6175+ unsigned len);
6176+#ifdef NET_21
6177+ int (*rebuild_header)(struct sk_buff *skb);
6178+#else /* NET_21 */
6179+ int (*rebuild_header)(void *buff, struct net_device *dev,
6180+ unsigned long raddr, struct sk_buff *skb);
6181+#endif /* NET_21 */
6182+ int (*set_mac_address)(struct net_device *dev, void *addr);
6183+#ifndef NET_21
6184+ void (*header_cache_bind)(struct hh_cache **hhp, struct net_device *dev,
6185+ unsigned short htype, __u32 daddr);
6186+#endif /* !NET_21 */
6187+ void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr);
6188+ struct net_device_stats *(*get_stats)(struct net_device *dev);
6189+ struct net_device_stats mystats;
6190+ int mtu; /* What is the desired MTU? */
6191+};
6192+
6193+extern char ipsec_tunnel_c_version[];
6194+
6195+extern struct net_device *ipsecdevices[IPSEC_NUM_IF];
6196+
6197+int ipsec_tunnel_init_devices(void);
6198+
6199+/* void */ int ipsec_tunnel_cleanup_devices(void);
6200+
6201+extern /* void */ int ipsec_init(void);
6202+
6203+extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev);
6204+extern struct net_device *ipsec_get_device(int inst);
6205+
6206+#ifdef CONFIG_KLIPS_DEBUG
6207+extern int debug_tunnel;
6208+extern int sysctl_ipsec_debug_verbose;
6209+#endif /* CONFIG_KLIPS_DEBUG */
6210+#endif /* __KERNEL__ */
6211+
6212+#ifdef CONFIG_KLIPS_DEBUG
6213+#define DB_TN_INIT 0x0001
6214+#define DB_TN_PROCFS 0x0002
6215+#define DB_TN_XMIT 0x0010
6216+#define DB_TN_OHDR 0x0020
6217+#define DB_TN_CROUT 0x0040
6218+#define DB_TN_OXFS 0x0080
6219+#define DB_TN_REVEC 0x0100
6220+#define DB_TN_ENCAP 0x0200
6221+#endif /* CONFIG_KLIPS_DEBUG */
6222+
6223+/*
6224+ * $Log: ipsec_tunnel.h,v $
6225+ * Revision 1.33 2005/06/04 16:06:05 mcr
6226+ * better patch for nat-t rcv-device code.
6227+ *
6228+ * Revision 1.32 2005/05/21 03:18:35 mcr
6229+ * added additional debug flag tunnelling.
6230+ *
6231+ * Revision 1.31 2004/08/03 18:18:02 mcr
6232+ * in 2.6, use "net_device" instead of #define device->net_device.
6233+ * this probably breaks 2.0 compiles.
6234+ *
6235+ * Revision 1.30 2004/07/10 19:08:41 mcr
6236+ * CONFIG_IPSEC -> CONFIG_KLIPS.
6237+ *
6238+ * Revision 1.29 2004/04/05 19:55:07 mcr
6239+ * Moved from linux/include/freeswan/ipsec_tunnel.h,v
6240+ *
6241+ * Revision 1.28 2003/06/24 20:22:32 mcr
6242+ * added new global: ipsecdevices[] so that we can keep track of
6243+ * the ipsecX devices. They will be referenced with dev_hold(),
6244+ * so 2.2 may need this as well.
6245+ *
6246+ * Revision 1.27 2003/04/03 17:38:09 rgb
6247+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
6248+ *
6249+ * Revision 1.26 2003/02/12 19:32:20 rgb
6250+ * Updated copyright year.
6251+ *
6252+ * Revision 1.25 2002/05/27 18:56:07 rgb
6253+ * Convert to dynamic ipsec device allocation.
6254+ *
6255+ * Revision 1.24 2002/04/24 07:36:48 mcr
6256+ * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
6257+ *
6258+ * Revision 1.23 2001/11/06 19:50:44 rgb
6259+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
6260+ * use also by pfkey_v2_parser.c
6261+ *
6262+ * Revision 1.22 2001/09/15 16:24:05 rgb
6263+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
6264+ *
6265+ * Revision 1.21 2001/06/14 19:35:10 rgb
6266+ * Update copyright date.
6267+ *
6268+ * Revision 1.20 2000/09/15 11:37:02 rgb
6269+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
6270+ * IPCOMP zlib deflate code.
6271+ *
6272+ * Revision 1.19 2000/09/08 19:12:56 rgb
6273+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6274+ *
6275+ * Revision 1.18 2000/07/28 13:50:54 rgb
6276+ * Changed enet_statistics to net_device_stats and added back compatibility
6277+ * for pre-2.1.19.
6278+ *
6279+ * Revision 1.17 1999/11/19 01:12:15 rgb
6280+ * Purge unneeded proc_info prototypes, now that static linking uses
6281+ * dynamic proc_info registration.
6282+ *
6283+ * Revision 1.16 1999/11/18 18:51:00 rgb
6284+ * Changed all device registrations for static linking to
6285+ * dynamic to reduce the number and size of patches.
6286+ *
6287+ * Revision 1.15 1999/11/18 04:14:21 rgb
6288+ * Replaced all kernel version macros to shorter, readable form.
6289+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
6290+ * Added Marc Boucher's 2.3.25 proc patches.
6291+ *
6292+ * Revision 1.14 1999/05/25 02:50:10 rgb
6293+ * Fix kernel version macros for 2.0.x static linking.
6294+ *
6295+ * Revision 1.13 1999/05/25 02:41:06 rgb
6296+ * Add ipsec_klipsdebug support for static linking.
6297+ *
6298+ * Revision 1.12 1999/05/05 22:02:32 rgb
6299+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
6300+ *
6301+ * Revision 1.11 1999/04/29 15:19:50 rgb
6302+ * Add return values to init and cleanup functions.
6303+ *
6304+ * Revision 1.10 1999/04/16 16:02:39 rgb
6305+ * Bump up macro to 4 ipsec I/Fs.
6306+ *
6307+ * Revision 1.9 1999/04/15 15:37:25 rgb
6308+ * Forward check changes from POST1_00 branch.
6309+ *
6310+ * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
6311+ * Backcheck from HEAD, pre1.0.
6312+ *
6313+ * Revision 1.8 1999/04/11 00:29:01 henry
6314+ * GPL boilerplate
6315+ *
6316+ * Revision 1.7 1999/04/06 04:54:28 rgb
6317+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
6318+ * patch shell fixes.
6319+ *
6320+ * Revision 1.6 1999/03/31 05:44:48 rgb
6321+ * Keep PMTU reduction private.
6322+ *
6323+ * Revision 1.5 1999/02/10 22:31:20 rgb
6324+ * Change rebuild_header member to reflect generality of link layer.
6325+ *
6326+ * Revision 1.4 1998/12/01 13:22:04 rgb
6327+ * Added support for debug printing of version info.
6328+ *
6329+ * Revision 1.3 1998/07/29 20:42:46 rgb
6330+ * Add a macro for clearing all tunnel devices.
6331+ * Rearrange structures and declarations for sharing with userspace.
6332+ *
6333+ * Revision 1.2 1998/06/25 20:01:45 rgb
6334+ * Make prototypes available for ipsec_init and ipsec proc_dir_entries
6335+ * for static linking.
6336+ *
6337+ * Revision 1.1 1998/06/18 21:27:50 henry
6338+ * move sources from klips/src to klips/net/ipsec, to keep stupid
6339+ * kernel-build scripts happier in the presence of symlinks
6340+ *
6341+ * Revision 1.3 1998/05/18 21:51:50 rgb
6342+ * Added macros for num of I/F's and a procfs debug switch.
6343+ *
6344+ * Revision 1.2 1998/04/21 21:29:09 rgb
6345+ * Rearrange debug switches to change on the fly debug output from user
6346+ * space. Only kernel changes checked in at this time. radij.c was also
6347+ * changed to temporarily remove buggy debugging code in rj_delete causing
6348+ * an OOPS and hence, netlink device open errors.
6349+ *
6350+ * Revision 1.1 1998/04/09 03:06:13 henry
6351+ * sources moved up from linux/net/ipsec
6352+ *
6353+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
6354+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6355+ *
6356+ * Revision 0.5 1997/06/03 04:24:48 ji
6357+ * Added transport mode.
6358+ * Changed the way routing is done.
6359+ * Lots of bug fixes.
6360+ *
6361+ * Revision 0.4 1997/01/15 01:28:15 ji
6362+ * No changes.
6363+ *
6364+ * Revision 0.3 1996/11/20 14:39:04 ji
6365+ * Minor cleanups.
6366+ * Rationalized debugging code.
6367+ *
6368+ * Revision 0.2 1996/11/02 00:18:33 ji
6369+ * First limited release.
6370+ *
6371+ *
6372+ */
6373--- /dev/null Tue Mar 11 13:02:56 2003
6374+++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004
6375@@ -0,0 +1,257 @@
6376+/*
6377+ * Definitions relevant to IPSEC transformations
6378+ * Copyright (C) 1996, 1997 John Ioannidis.
6379+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
6380+ * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
6381+ *
6382+ * This program is free software; you can redistribute it and/or modify it
6383+ * under the terms of the GNU General Public License as published by the
6384+ * Free Software Foundation; either version 2 of the License, or (at your
6385+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6386+ *
6387+ * This program is distributed in the hope that it will be useful, but
6388+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6389+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6390+ * for more details.
6391+ *
6392+ * RCSID $Id: ipsec_xform.h,v 1.41 2004/07/10 19:08:41 mcr Exp $
6393+ */
6394+
6395+#ifndef _IPSEC_XFORM_H_
6396+
6397+#include <openswan.h>
6398+
6399+#define XF_NONE 0 /* No transform set */
6400+#define XF_IP4 1 /* IPv4 inside IPv4 */
6401+#define XF_AHMD5 2 /* AH MD5 */
6402+#define XF_AHSHA 3 /* AH SHA */
6403+#define XF_ESP3DES 5 /* ESP DES3-CBC */
6404+#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
6405+#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
6406+#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
6407+#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
6408+#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
6409+#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
6410+#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
6411+#define XF_IP6 15 /* IPv6 inside IPv6 */
6412+#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
6413+
6414+#define XF_CLR 126 /* Clear SA table */
6415+#define XF_DEL 127 /* Delete SA */
6416+
6417+/* IPsec AH transform values
6418+ * RFC 2407
6419+ * draft-ietf-ipsec-doi-tc-mib-02.txt
6420+ */
6421+
6422+#define AH_NONE 0
6423+#define AH_MD5 2
6424+#define AH_SHA 3
6425+/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */
6426+#define AH_SHA2_256 5
6427+#define AH_SHA2_384 6
6428+#define AH_SHA2_512 7
6429+#define AH_RIPEMD 8
6430+#define AH_MAX 15
6431+
6432+/* IPsec ESP transform values */
6433+
6434+#define ESP_NONE 0
6435+#define ESP_DES 2
6436+#define ESP_3DES 3
6437+#define ESP_RC5 4
6438+#define ESP_IDEA 5
6439+#define ESP_CAST 6
6440+#define ESP_BLOWFISH 7
6441+#define ESP_3IDEA 8
6442+#define ESP_RC4 10
6443+#define ESP_NULL 11
6444+#define ESP_AES 12
6445+
6446+/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */
6447+#define ESP_MARS 249
6448+#define ESP_RC6 250
6449+#define ESP_SERPENT 252
6450+#define ESP_TWOFISH 253
6451+
6452+/* IPCOMP transform values */
6453+
6454+#define IPCOMP_NONE 0
6455+#define IPCOMP_OUI 1
6456+#define IPCOMP_DEFLAT 2
6457+#define IPCOMP_LZS 3
6458+#define IPCOMP_V42BIS 4
6459+
6460+#define XFT_AUTH 0x0001
6461+#define XFT_CONF 0x0100
6462+
6463+/* available if CONFIG_KLIPS_DEBUG is defined */
6464+#define DB_XF_INIT 0x0001
6465+
6466+#define PROTO2TXT(x) \
6467+ (x) == IPPROTO_AH ? "AH" : \
6468+ (x) == IPPROTO_ESP ? "ESP" : \
6469+ (x) == IPPROTO_IPIP ? "IPIP" : \
6470+ (x) == IPPROTO_COMP ? "COMP" : \
6471+ "UNKNOWN_proto"
6472+static inline const char *enc_name_id (unsigned id) {
6473+ static char buf[16];
6474+ snprintf(buf, sizeof(buf), "_ID%d", id);
6475+ return buf;
6476+}
6477+static inline const char *auth_name_id (unsigned id) {
6478+ static char buf[16];
6479+ snprintf(buf, sizeof(buf), "_ID%d", id);
6480+ return buf;
6481+}
6482+#define IPS_XFORM_NAME(x) \
6483+ PROTO2TXT((x)->ips_said.proto), \
6484+ (x)->ips_said.proto == IPPROTO_COMP ? \
6485+ ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
6486+ "_DEFLATE" : "_UNKNOWN_comp") : \
6487+ (x)->ips_encalg == ESP_NONE ? "" : \
6488+ (x)->ips_encalg == ESP_3DES ? "_3DES" : \
6489+ (x)->ips_encalg == ESP_AES ? "_AES" : \
6490+ (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
6491+ (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
6492+ enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
6493+ (x)->ips_authalg == AH_NONE ? "" : \
6494+ (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
6495+ (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
6496+ (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
6497+ (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
6498+ (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
6499+ auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
6500+
6501+#ifdef __KERNEL__
6502+struct ipsec_rcv_state;
6503+struct ipsec_xmit_state;
6504+
6505+struct xform_functions {
6506+ enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
6507+ struct sk_buff *skb);
6508+ enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
6509+
6510+ enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
6511+ struct sk_buff *skb,
6512+ __u32 *replay,
6513+ unsigned char **authenticator);
6514+ enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
6515+ struct sk_buff *skb);
6516+
6517+ enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
6518+ enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
6519+
6520+ enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
6521+ struct sk_buff *skb,
6522+ __u32 *replay,
6523+ unsigned char **authenticator);
6524+ enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
6525+ struct sk_buff *skb);
6526+ int xmit_headroom;
6527+ int xmit_needtailroom;
6528+};
6529+
6530+#endif /* __KERNEL__ */
6531+
6532+#ifdef CONFIG_KLIPS_DEBUG
6533+extern void ipsec_dmp(char *s, caddr_t bb, int len);
6534+#else /* CONFIG_KLIPS_DEBUG */
6535+#define ipsec_dmp(_x, _y, _z)
6536+#endif /* CONFIG_KLIPS_DEBUG */
6537+
6538+
6539+#define _IPSEC_XFORM_H_
6540+#endif /* _IPSEC_XFORM_H_ */
6541+
6542+/*
6543+ * $Log: ipsec_xform.h,v $
6544+ * Revision 1.41 2004/07/10 19:08:41 mcr
6545+ * CONFIG_IPSEC -> CONFIG_KLIPS.
6546+ *
6547+ * Revision 1.40 2004/04/06 02:49:08 mcr
6548+ * pullup of algo code from alg-branch.
6549+ *
6550+ * Revision 1.39 2004/04/05 19:55:07 mcr
6551+ * Moved from linux/include/freeswan/ipsec_xform.h,v
6552+ *
6553+ * Revision 1.38 2004/04/05 19:41:05 mcr
6554+ * merged alg-branch code.
6555+ *
6556+ * Revision 1.37 2003/12/13 19:10:16 mcr
6557+ * refactored rcv and xmit code - same as FS 2.05.
6558+ *
6559+ * Revision 1.36.34.1 2003/12/22 15:25:52 jjo
6560+ * Merged algo-0.8.1-rc11-test1 into alg-branch
6561+ *
6562+ * Revision 1.36 2002/04/24 07:36:48 mcr
6563+ * Moved from ./klips/net/ipsec/ipsec_xform.h,v
6564+ *
6565+ * Revision 1.35 2001/11/26 09:23:51 rgb
6566+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6567+ *
6568+ * Revision 1.33.2.1 2001/09/25 02:24:58 mcr
6569+ * struct tdb -> struct ipsec_sa.
6570+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
6571+ * ipsec_xform.c removed. header file still contains useful things.
6572+ *
6573+ * Revision 1.34 2001/11/06 19:47:17 rgb
6574+ * Changed lifetime_packets to uint32 from uint64.
6575+ *
6576+ * Revision 1.33 2001/09/08 21:13:34 rgb
6577+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
6578+ *
6579+ * Revision 1.32 2001/07/06 07:40:01 rgb
6580+ * Reformatted for readability.
6581+ * Added inbound policy checking fields for use with IPIP SAs.
6582+ *
6583+ * Revision 1.31 2001/06/14 19:35:11 rgb
6584+ * Update copyright date.
6585+ *
6586+ * Revision 1.30 2001/05/30 08:14:03 rgb
6587+ * Removed vestiges of esp-null transforms.
6588+ *
6589+ * Revision 1.29 2001/01/30 23:42:47 rgb
6590+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
6591+ * and subsequent ADD or UDATE.
6592+ *
6593+ * Revision 1.28 2000/11/06 04:30:40 rgb
6594+ * Add Svenning's adaptive content compression.
6595+ *
6596+ * Revision 1.27 2000/09/19 00:38:25 rgb
6597+ * Fixed algorithm name bugs introduced for ipcomp.
6598+ *
6599+ * Revision 1.26 2000/09/17 21:36:48 rgb
6600+ * Added proto2txt macro.
6601+ *
6602+ * Revision 1.25 2000/09/17 18:56:47 rgb
6603+ * Added IPCOMP support.
6604+ *
6605+ * Revision 1.24 2000/09/12 19:34:12 rgb
6606+ * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
6607+ *
6608+ * Revision 1.23 2000/09/12 03:23:14 rgb
6609+ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
6610+ *
6611+ * Revision 1.22 2000/09/08 19:12:56 rgb
6612+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6613+ *
6614+ * Revision 1.21 2000/09/01 18:32:43 rgb
6615+ * Added (disabled) sensitivity members to tdb struct.
6616+ *
6617+ * Revision 1.20 2000/08/30 05:31:01 rgb
6618+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
6619+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
6620+ *
6621+ * Revision 1.19 2000/08/01 14:51:52 rgb
6622+ * Removed _all_ remaining traces of DES.
6623+ *
6624+ * Revision 1.18 2000/01/21 06:17:45 rgb
6625+ * Tidied up spacing.
6626+ *
6627+ *
6628+ * Local variables:
6629+ * c-file-style: "linux"
6630+ * End:
6631+ *
6632+ */
6633--- /dev/null Tue Mar 11 13:02:56 2003
6634+++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004
6635@@ -0,0 +1,198 @@
6636+/*
6637+ * IPSEC tunneling code
6638+ * Copyright (C) 1996, 1997 John Ioannidis.
6639+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6640+ *
6641+ * This program is free software; you can redistribute it and/or modify it
6642+ * under the terms of the GNU General Public License as published by the
6643+ * Free Software Foundation; either version 2 of the License, or (at your
6644+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6645+ *
6646+ * This program is distributed in the hope that it will be useful, but
6647+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6648+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6649+ * for more details.
6650+ *
6651+ * RCSID $Id: ipsec_xmit.h,v 1.14 2005/05/11 01:00:26 mcr Exp $
6652+ */
6653+
6654+#include "openswan/ipsec_sa.h"
6655+
6656+enum ipsec_xmit_value
6657+{
6658+ IPSEC_XMIT_STOLEN=2,
6659+ IPSEC_XMIT_PASS=1,
6660+ IPSEC_XMIT_OK=0,
6661+ IPSEC_XMIT_ERRMEMALLOC=-1,
6662+ IPSEC_XMIT_ESP_BADALG=-2,
6663+ IPSEC_XMIT_BADPROTO=-3,
6664+ IPSEC_XMIT_ESP_PUSHPULLERR=-4,
6665+ IPSEC_XMIT_BADLEN=-5,
6666+ IPSEC_XMIT_AH_BADALG=-6,
6667+ IPSEC_XMIT_SAIDNOTFOUND=-7,
6668+ IPSEC_XMIT_SAIDNOTLIVE=-8,
6669+ IPSEC_XMIT_REPLAYROLLED=-9,
6670+ IPSEC_XMIT_LIFETIMEFAILED=-10,
6671+ IPSEC_XMIT_CANNOTFRAG=-11,
6672+ IPSEC_XMIT_MSSERR=-12,
6673+ IPSEC_XMIT_ERRSKBALLOC=-13,
6674+ IPSEC_XMIT_ENCAPFAIL=-14,
6675+ IPSEC_XMIT_NODEV=-15,
6676+ IPSEC_XMIT_NOPRIVDEV=-16,
6677+ IPSEC_XMIT_NOPHYSDEV=-17,
6678+ IPSEC_XMIT_NOSKB=-18,
6679+ IPSEC_XMIT_NOIPV6=-19,
6680+ IPSEC_XMIT_NOIPOPTIONS=-20,
6681+ IPSEC_XMIT_TTLEXPIRED=-21,
6682+ IPSEC_XMIT_BADHHLEN=-22,
6683+ IPSEC_XMIT_PUSHPULLERR=-23,
6684+ IPSEC_XMIT_ROUTEERR=-24,
6685+ IPSEC_XMIT_RECURSDETECT=-25,
6686+ IPSEC_XMIT_IPSENDFAILURE=-26,
6687+ IPSEC_XMIT_ESPUDP=-27,
6688+ IPSEC_XMIT_ESPUDP_BADTYPE=-28,
6689+};
6690+
6691+struct ipsec_xmit_state
6692+{
6693+ struct sk_buff *skb; /* working skb pointer */
6694+ struct net_device *dev; /* working dev pointer */
6695+ struct ipsecpriv *prv; /* Our device' private space */
6696+ struct sk_buff *oskb; /* Original skb pointer */
6697+ struct net_device_stats *stats; /* This device's statistics */
6698+ struct iphdr *iph; /* Our new IP header */
6699+ __u32 newdst; /* The other SG's IP address */
6700+ __u32 orgdst; /* Original IP destination address */
6701+ __u32 orgedst; /* 1st SG's IP address */
6702+ __u32 newsrc; /* The new source SG's IP address */
6703+ __u32 orgsrc; /* Original IP source address */
6704+ __u32 innersrc; /* Innermost IP source address */
6705+ int iphlen; /* IP header length */
6706+ int pyldsz; /* upper protocol payload size */
6707+ int headroom;
6708+ int tailroom;
6709+ int authlen;
6710+ int max_headroom; /* The extra header space needed */
6711+ int max_tailroom; /* The extra stuffing needed */
6712+ int ll_headroom; /* The extra link layer hard_header space needed */
6713+ int tot_headroom; /* The total header space needed */
6714+ int tot_tailroom; /* The totalstuffing needed */
6715+ __u8 *saved_header; /* saved copy of the hard header */
6716+ unsigned short sport, dport;
6717+
6718+ struct sockaddr_encap matcher; /* eroute search key */
6719+ struct eroute *eroute;
6720+ struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */
6721+ char sa_txt[SATOT_BUF];
6722+ size_t sa_len;
6723+ int hard_header_stripped; /* has the hard header been removed yet? */
6724+ int hard_header_len;
6725+ struct net_device *physdev;
6726+/* struct device *virtdev; */
6727+ short physmtu;
6728+ short cur_mtu; /* copy of prv->mtu, cause prv may == NULL */
6729+ short mtudiff;
6730+#ifdef NET_21
6731+ struct rtable *route;
6732+#endif /* NET_21 */
6733+ ip_said outgoing_said;
6734+#ifdef NET_21
6735+ int pass;
6736+#endif /* NET_21 */
6737+ int error;
6738+ uint32_t eroute_pid;
6739+ struct ipsec_sa ips;
6740+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
6741+ uint8_t natt_type;
6742+ uint8_t natt_head;
6743+ uint16_t natt_sport;
6744+ uint16_t natt_dport;
6745+#endif
6746+};
6747+
6748+enum ipsec_xmit_value
6749+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
6750+
6751+enum ipsec_xmit_value
6752+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
6753+
6754+enum ipsec_xmit_value
6755+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
6756+
6757+extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
6758+
6759+
6760+extern int ipsec_xmit_trap_count;
6761+extern int ipsec_xmit_trap_sendcount;
6762+
6763+#ifdef CONFIG_KLIPS_DEBUG
6764+extern int debug_tunnel;
6765+
6766+#define debug_xmit debug_tunnel
6767+
6768+#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
6769+#else
6770+#define ipsec_xmit_dmp(_x,_y, _z) do {} while(0)
6771+
6772+#endif /* CONFIG_KLIPS_DEBUG */
6773+
6774+extern int sysctl_ipsec_debug_verbose;
6775+extern int sysctl_ipsec_icmp;
6776+extern int sysctl_ipsec_tos;
6777+
6778+
6779+/*
6780+ * $Log: ipsec_xmit.h,v $
6781+ * Revision 1.14 2005/05/11 01:00:26 mcr
6782+ * do not call debug routines if !defined KLIPS_DEBUG.
6783+ *
6784+ * Revision 1.13 2005/04/29 05:01:38 mcr
6785+ * use ipsec_dmp_block.
6786+ * added cur_mtu to ixs instead of using ixs->dev.
6787+ *
6788+ * Revision 1.12 2004/08/20 21:45:37 mcr
6789+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
6790+ * be 26sec compatible. But, some defines where changed.
6791+ *
6792+ * Revision 1.11 2004/08/03 18:18:21 mcr
6793+ * in 2.6, use "net_device" instead of #define device->net_device.
6794+ * this probably breaks 2.0 compiles.
6795+ *
6796+ * Revision 1.10 2004/07/10 19:08:41 mcr
6797+ * CONFIG_IPSEC -> CONFIG_KLIPS.
6798+ *
6799+ * Revision 1.9 2004/04/06 02:49:08 mcr
6800+ * pullup of algo code from alg-branch.
6801+ *
6802+ * Revision 1.8 2004/04/05 19:55:07 mcr
6803+ * Moved from linux/include/freeswan/ipsec_xmit.h,v
6804+ *
6805+ * Revision 1.7 2004/02/03 03:11:40 mcr
6806+ * new xmit type if the UDP encapsulation is wrong.
6807+ *
6808+ * Revision 1.6 2003/12/13 19:10:16 mcr
6809+ * refactored rcv and xmit code - same as FS 2.05.
6810+ *
6811+ * Revision 1.5 2003/12/10 01:20:06 mcr
6812+ * NAT-traversal patches to KLIPS.
6813+ *
6814+ * Revision 1.4 2003/12/06 16:37:04 mcr
6815+ * 1.4.7a X.509 patch applied.
6816+ *
6817+ * Revision 1.3 2003/10/31 02:27:05 mcr
6818+ * pulled up port-selector patches and sa_id elimination.
6819+ *
6820+ * Revision 1.2.4.2 2003/10/29 01:10:19 mcr
6821+ * elimited "struct sa_id"
6822+ *
6823+ * Revision 1.2.4.1 2003/09/21 13:59:38 mcr
6824+ * pre-liminary X.509 patch - does not yet pass tests.
6825+ *
6826+ * Revision 1.2 2003/06/20 01:42:13 mcr
6827+ * added counters to measure how many ACQUIREs we send to pluto,
6828+ * and how many are successfully sent.
6829+ *
6830+ * Revision 1.1 2003/02/12 19:31:03 rgb
6831+ * Refactored from ipsec_tunnel.c
6832+ *
6833+ */
6834--- /dev/null Tue Mar 11 13:02:56 2003
6835+++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004
6836@@ -0,0 +1,75 @@
6837+/*
6838+ * sanitize a string into a printable format.
6839+ *
6840+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
6841+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
6842+ *
6843+ * This library is free software; you can redistribute it and/or modify it
6844+ * under the terms of the GNU Library General Public License as published by
6845+ * the Free Software Foundation; either version 2 of the License, or (at your
6846+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
6847+ *
6848+ * This library is distributed in the hope that it will be useful, but
6849+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6850+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
6851+ * License for more details.
6852+ *
6853+ * RCSID $Id: passert.h,v 1.7 2004/10/21 18:44:42 mcr Exp $
6854+ */
6855+
6856+#include "openswan.h"
6857+
6858+#ifndef _OPENSWAN_PASSERT_H
6859+#define _OPENSWAN_PASSERT_H
6860+/* our versions of assert: log result */
6861+
6862+#ifdef DEBUG
6863+
6864+typedef void (*openswan_passert_fail_t)(const char *pred_str,
6865+ const char *file_str,
6866+ unsigned long line_no) NEVER_RETURNS;
6867+
6868+openswan_passert_fail_t openswan_passert_fail;
6869+
6870+extern void pexpect_log(const char *pred_str
6871+ , const char *file_str, unsigned long line_no);
6872+
6873+# define impossible() do { \
6874+ if(openswan_passert_fail) { \
6875+ (*openswan_passert_fail)("impossible", __FILE__, __LINE__); \
6876+ }} while(0)
6877+
6878+extern void switch_fail(int n
6879+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
6880+
6881+# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
6882+
6883+# define passert(pred) do { \
6884+ if (!(pred)) \
6885+ if(openswan_passert_fail) { \
6886+ (*openswan_passert_fail)(#pred, __FILE__, __LINE__); \
6887+ } \
6888+ } while(0)
6889+
6890+# define pexpect(pred) do { \
6891+ if (!(pred)) \
6892+ pexpect_log(#pred, __FILE__, __LINE__); \
6893+ } while(0)
6894+
6895+/* assert that an err_t is NULL; evaluate exactly once */
6896+# define happy(x) { \
6897+ err_t ugh = x; \
6898+ if (ugh != NULL) \
6899+ if(openswan_passert_fail) { (*openswan_passert_fail)(ugh, __FILE__, __LINE__); } \
6900+ }
6901+
6902+#else /*!DEBUG*/
6903+
6904+# define impossible() abort()
6905+# define bad_case(n) abort()
6906+# define passert(pred) { } /* do nothing */
6907+# define happy(x) { (void) x; } /* evaluate non-judgementally */
6908+
6909+#endif /*!DEBUG*/
6910+
6911+#endif /* _OPENSWAN_PASSERT_H */
6912--- /dev/null Tue Mar 11 13:02:56 2003
6913+++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004
6914@@ -0,0 +1,54 @@
6915+/*
6916+ * sanitize a string into a printable format.
6917+ *
6918+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
6919+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
6920+ *
6921+ * This library is free software; you can redistribute it and/or modify it
6922+ * under the terms of the GNU Library General Public License as published by
6923+ * the Free Software Foundation; either version 2 of the License, or (at your
6924+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
6925+ *
6926+ * This library is distributed in the hope that it will be useful, but
6927+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6928+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
6929+ * License for more details.
6930+ *
6931+ * RCSID $Id: pfkey_debug.h,v 1.3 2004/04/05 19:55:07 mcr Exp $
6932+ */
6933+
6934+#ifndef _FREESWAN_PFKEY_DEBUG_H
6935+#define _FREESWAN_PFKEY_DEBUG_H
6936+
6937+#ifdef __KERNEL__
6938+
6939+/* note, kernel version ignores pfkey levels */
6940+# define DEBUGGING(level,args...) \
6941+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
6942+
6943+# define ERROR(args...) printk(KERN_ERR "klips:" args)
6944+
6945+#else
6946+
6947+extern unsigned int pfkey_lib_debug;
6948+
6949+extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
6950+extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
6951+
6952+#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \
6953+ if(pfkey_debug_func != NULL) { \
6954+ (*pfkey_debug_func)("pfkey_lib_debug:" args); \
6955+ } else { \
6956+ printf("pfkey_lib_debug:" args); \
6957+ } }
6958+
6959+#define ERROR(args...) if(pfkey_error_func != NULL) { \
6960+ (*pfkey_error_func)("pfkey_lib_debug:" args); \
6961+ }
6962+
6963+# define MALLOC(size) malloc(size)
6964+# define FREE(obj) free(obj)
6965+
6966+#endif
6967+
6968+#endif
6969--- /dev/null Tue Mar 11 13:02:56 2003
6970+++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004
6971@@ -0,0 +1,280 @@
6972+/*
6973+ * RCSID $Id: radij.h,v 1.13 2004/04/05 19:55:08 mcr Exp $
6974+ */
6975+
6976+/*
6977+ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
6978+ *
6979+ * Variable and procedure names have been modified so that they don't
6980+ * conflict with the original BSD code, as a small number of modifications
6981+ * have been introduced and we may want to reuse this code in BSD.
6982+ *
6983+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
6984+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
6985+ * spanish j as in Juan. It is not as far back in the throat like
6986+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
6987+ * It has nothing to do with the Dutch ij sound.
6988+ *
6989+ * Here is the appropriate copyright notice:
6990+ */
6991+
6992+/*
6993+ * Copyright (c) 1988, 1989, 1993
6994+ * The Regents of the University of California. All rights reserved.
6995+ *
6996+ * Redistribution and use in source and binary forms, with or without
6997+ * modification, are permitted provided that the following conditions
6998+ * are met:
6999+ * 1. Redistributions of source code must retain the above copyright
7000+ * notice, this list of conditions and the following disclaimer.
7001+ * 2. Redistributions in binary form must reproduce the above copyright
7002+ * notice, this list of conditions and the following disclaimer in the
7003+ * documentation and/or other materials provided with the distribution.
7004+ * 3. All advertising materials mentioning features or use of this software
7005+ * must display the following acknowledgement:
7006+ * This product includes software developed by the University of
7007+ * California, Berkeley and its contributors.
7008+ * 4. Neither the name of the University nor the names of its contributors
7009+ * may be used to endorse or promote products derived from this software
7010+ * without specific prior written permission.
7011+ *
7012+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
7013+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7014+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7015+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
7016+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7017+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
7018+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7019+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7020+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7021+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7022+ * SUCH DAMAGE.
7023+ *
7024+ * @(#)radix.h 8.1 (Berkeley) 6/10/93
7025+ */
7026+
7027+#ifndef _RADIJ_H_
7028+#define _RADIJ_H_
7029+
7030+/*
7031+#define RJ_DEBUG
7032+*/
7033+
7034+#ifdef __KERNEL__
7035+
7036+#ifndef __P
7037+#ifdef __STDC__
7038+#define __P(x) x
7039+#else
7040+#define __P(x) ()
7041+#endif
7042+#endif
7043+
7044+/*
7045+ * Radix search tree node layout.
7046+ */
7047+
7048+struct radij_node
7049+{
7050+ struct radij_mask *rj_mklist; /* list of masks contained in subtree */
7051+ struct radij_node *rj_p; /* parent */
7052+ short rj_b; /* bit offset; -1-index(netmask) */
7053+ char rj_bmask; /* node: mask for bit test*/
7054+ u_char rj_flags; /* enumerated next */
7055+#define RJF_NORMAL 1 /* leaf contains normal route */
7056+#define RJF_ROOT 2 /* leaf is root leaf for tree */
7057+#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
7058+ union {
7059+ struct { /* leaf only data: */
7060+ caddr_t rj_Key; /* object of search */
7061+ caddr_t rj_Mask; /* netmask, if present */
7062+ struct radij_node *rj_Dupedkey;
7063+ } rj_leaf;
7064+ struct { /* node only data: */
7065+ int rj_Off; /* where to start compare */
7066+ struct radij_node *rj_L;/* progeny */
7067+ struct radij_node *rj_R;/* progeny */
7068+ }rj_node;
7069+ } rj_u;
7070+#ifdef RJ_DEBUG
7071+ int rj_info;
7072+ struct radij_node *rj_twin;
7073+ struct radij_node *rj_ybro;
7074+#endif
7075+};
7076+
7077+#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
7078+#define rj_key rj_u.rj_leaf.rj_Key
7079+#define rj_mask rj_u.rj_leaf.rj_Mask
7080+#define rj_off rj_u.rj_node.rj_Off
7081+#define rj_l rj_u.rj_node.rj_L
7082+#define rj_r rj_u.rj_node.rj_R
7083+
7084+/*
7085+ * Annotations to tree concerning potential routes applying to subtrees.
7086+ */
7087+
7088+extern struct radij_mask {
7089+ short rm_b; /* bit offset; -1-index(netmask) */
7090+ char rm_unused; /* cf. rj_bmask */
7091+ u_char rm_flags; /* cf. rj_flags */
7092+ struct radij_mask *rm_mklist; /* more masks to try */
7093+ caddr_t rm_mask; /* the mask */
7094+ int rm_refs; /* # of references to this struct */
7095+} *rj_mkfreelist;
7096+
7097+#define MKGet(m) {\
7098+ if (rj_mkfreelist) {\
7099+ m = rj_mkfreelist; \
7100+ rj_mkfreelist = (m)->rm_mklist; \
7101+ } else \
7102+ R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
7103+
7104+#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
7105+
7106+struct radij_node_head {
7107+ struct radij_node *rnh_treetop;
7108+ int rnh_addrsize; /* permit, but not require fixed keys */
7109+ int rnh_pktsize; /* permit, but not require fixed keys */
7110+#if 0
7111+ struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
7112+ __P((void *v, void *mask,
7113+ struct radij_node_head *head, struct radij_node nodes[]));
7114+#endif
7115+ int (*rnh_addaddr) /* add based on sockaddr */
7116+ __P((void *v, void *mask,
7117+ struct radij_node_head *head, struct radij_node nodes[]));
7118+ struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
7119+ __P((void *v, void *mask,
7120+ struct radij_node_head *head, struct radij_node nodes[]));
7121+#if 0
7122+ struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
7123+ __P((void *v, void *mask, struct radij_node_head *head));
7124+#endif
7125+ int (*rnh_deladdr) /* remove based on sockaddr */
7126+ __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
7127+ struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
7128+ __P((void *v, void *mask, struct radij_node_head *head));
7129+ struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
7130+ __P((void *v, struct radij_node_head *head));
7131+ struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
7132+ __P((void *v, struct radij_node_head *head));
7133+ int (*rnh_walktree) /* traverse tree */
7134+ __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7135+ struct radij_node rnh_nodes[3]; /* empty tree for common case */
7136+};
7137+
7138+
7139+#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7140+#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7141+#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
7142+#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
7143+#define Free(p) kfree((caddr_t)p);
7144+
7145+void rj_init __P((void));
7146+int rj_inithead __P((void **, int));
7147+int rj_refines __P((void *, void *));
7148+int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7149+struct radij_node
7150+ *rj_addmask __P((void *, int, int)) /* , rgb */ ;
7151+int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
7152+ struct radij_node [2])) /* , rgb */ ;
7153+int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
7154+struct radij_node /* rgb */
7155+ *rj_insert __P((void *, struct radij_node_head *, int *,
7156+ struct radij_node [2])),
7157+ *rj_match __P((void *, struct radij_node_head *)),
7158+ *rj_newpair __P((void *, int, struct radij_node[2])),
7159+ *rj_search __P((void *, struct radij_node *)),
7160+ *rj_search_m __P((void *, struct radij_node *, void *));
7161+
7162+void rj_deltree(struct radij_node_head *);
7163+void rj_delnodes(struct radij_node *);
7164+void rj_free_mkfreelist(void);
7165+int radijcleartree(void);
7166+int radijcleanup(void);
7167+
7168+extern struct radij_node_head *mask_rjhead;
7169+extern int maj_keylen;
7170+#endif /* __KERNEL__ */
7171+
7172+#endif /* _RADIJ_H_ */
7173+
7174+
7175+/*
7176+ * $Log: radij.h,v $
7177+ * Revision 1.13 2004/04/05 19:55:08 mcr
7178+ * Moved from linux/include/freeswan/radij.h,v
7179+ *
7180+ * Revision 1.12 2002/04/24 07:36:48 mcr
7181+ * Moved from ./klips/net/ipsec/radij.h,v
7182+ *
7183+ * Revision 1.11 2001/09/20 15:33:00 rgb
7184+ * Min/max cleanup.
7185+ *
7186+ * Revision 1.10 1999/11/18 04:09:20 rgb
7187+ * Replaced all kernel version macros to shorter, readable form.
7188+ *
7189+ * Revision 1.9 1999/05/05 22:02:33 rgb
7190+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
7191+ *
7192+ * Revision 1.8 1999/04/29 15:24:58 rgb
7193+ * Add check for existence of macros min/max.
7194+ *
7195+ * Revision 1.7 1999/04/11 00:29:02 henry
7196+ * GPL boilerplate
7197+ *
7198+ * Revision 1.6 1999/04/06 04:54:29 rgb
7199+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
7200+ * patch shell fixes.
7201+ *
7202+ * Revision 1.5 1999/01/22 06:30:32 rgb
7203+ * 64-bit clean-up.
7204+ *
7205+ * Revision 1.4 1998/11/30 13:22:55 rgb
7206+ * Rationalised all the klips kernel file headers. They are much shorter
7207+ * now and won't conflict under RH5.2.
7208+ *
7209+ * Revision 1.3 1998/10/25 02:43:27 rgb
7210+ * Change return type on rj_addroute and rj_delete and add and argument
7211+ * to the latter to be able to transmit more infomation about errors.
7212+ *
7213+ * Revision 1.2 1998/07/14 18:09:51 rgb
7214+ * Add a routine to clear eroute table.
7215+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
7216+ *
7217+ * Revision 1.1 1998/06/18 21:30:22 henry
7218+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
7219+ * build scripts happier about symlinks
7220+ *
7221+ * Revision 1.4 1998/05/25 20:34:16 rgb
7222+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
7223+ *
7224+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
7225+ * add ipsec_rj_walker_delete.
7226+ *
7227+ * Recover memory for eroute table on unload of module.
7228+ *
7229+ * Revision 1.3 1998/04/22 16:51:37 rgb
7230+ * Tidy up radij debug code from recent rash of modifications to debug code.
7231+ *
7232+ * Revision 1.2 1998/04/14 17:30:38 rgb
7233+ * Fix up compiling errors for radij tree memory reclamation.
7234+ *
7235+ * Revision 1.1 1998/04/09 03:06:16 henry
7236+ * sources moved up from linux/net/ipsec
7237+ *
7238+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
7239+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
7240+ *
7241+ * Revision 0.4 1997/01/15 01:28:15 ji
7242+ * No changes.
7243+ *
7244+ * Revision 0.3 1996/11/20 14:44:45 ji
7245+ * Release update only.
7246+ *
7247+ * Revision 0.2 1996/11/02 00:18:33 ji
7248+ * First limited release.
7249+ *
7250+ *
7251+ */
7252--- /dev/null Tue Mar 11 13:02:56 2003
7253+++ linux/include/pfkey.h Mon Feb 9 13:51:03 2004
7254@@ -0,0 +1,529 @@
7255+/*
7256+ * FreeS/WAN specific PF_KEY headers
7257+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
7258+ *
7259+ * This program is free software; you can redistribute it and/or modify it
7260+ * under the terms of the GNU General Public License as published by the
7261+ * Free Software Foundation; either version 2 of the License, or (at your
7262+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
7263+ *
7264+ * This program is distributed in the hope that it will be useful, but
7265+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7266+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7267+ * for more details.
7268+ *
7269+ * RCSID $Id: pfkey.h,v 1.49 2005/05/11 00:57:29 mcr Exp $
7270+ */
7271+
7272+#ifndef __NET_IPSEC_PF_KEY_H
7273+#define __NET_IPSEC_PF_KEY_H
7274+#ifdef __KERNEL__
7275+extern struct proto_ops pfkey_proto_ops;
7276+typedef struct sock pfkey_sock;
7277+extern int debug_pfkey;
7278+
7279+extern /* void */ int pfkey_init(void);
7280+extern /* void */ int pfkey_cleanup(void);
7281+
7282+struct socket_list
7283+{
7284+ struct socket *socketp;
7285+ struct socket_list *next;
7286+};
7287+extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
7288+extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
7289+extern struct socket_list *pfkey_open_sockets;
7290+extern struct socket_list *pfkey_registered_sockets[];
7291+
7292+struct ipsec_alg_supported
7293+{
7294+ uint16_t ias_exttype;
7295+ uint8_t ias_id;
7296+ uint8_t ias_ivlen;
7297+ uint16_t ias_keyminbits;
7298+ uint16_t ias_keymaxbits;
7299+ char *ias_name;
7300+};
7301+
7302+extern struct supported_list *pfkey_supported_list[];
7303+struct supported_list
7304+{
7305+ struct ipsec_alg_supported *supportedp;
7306+ struct supported_list *next;
7307+};
7308+extern int pfkey_list_insert_supported(struct ipsec_alg_supported*, struct supported_list**);
7309+extern int pfkey_list_remove_supported(struct ipsec_alg_supported*, struct supported_list**);
7310+
7311+struct sockaddr_key
7312+{
7313+ uint16_t key_family; /* PF_KEY */
7314+ uint16_t key_pad; /* not used */
7315+ uint32_t key_pid; /* process ID */
7316+};
7317+
7318+struct pfkey_extracted_data
7319+{
7320+ struct ipsec_sa* ips;
7321+ struct ipsec_sa* ips2;
7322+ struct eroute *eroute;
7323+};
7324+
7325+/* forward reference */
7326+struct sadb_ext;
7327+struct sadb_msg;
7328+struct sockaddr;
7329+struct sadb_comb;
7330+struct sadb_sadb;
7331+struct sadb_alg;
7332+
7333+extern int
7334+pfkey_alloc_eroute(struct eroute** eroute);
7335+
7336+extern int
7337+pfkey_sa_process(struct sadb_ext *pfkey_ext,
7338+ struct pfkey_extracted_data* extr);
7339+
7340+extern int
7341+pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
7342+ struct pfkey_extracted_data* extr);
7343+
7344+extern int
7345+pfkey_address_process(struct sadb_ext *pfkey_ext,
7346+ struct pfkey_extracted_data* extr);
7347+
7348+extern int
7349+pfkey_key_process(struct sadb_ext *pfkey_ext,
7350+ struct pfkey_extracted_data* extr);
7351+
7352+extern int
7353+pfkey_ident_process(struct sadb_ext *pfkey_ext,
7354+ struct pfkey_extracted_data* extr);
7355+
7356+extern int
7357+pfkey_sens_process(struct sadb_ext *pfkey_ext,
7358+ struct pfkey_extracted_data* extr);
7359+
7360+extern int
7361+pfkey_prop_process(struct sadb_ext *pfkey_ext,
7362+ struct pfkey_extracted_data* extr);
7363+
7364+extern int
7365+pfkey_supported_process(struct sadb_ext *pfkey_ext,
7366+ struct pfkey_extracted_data* extr);
7367+
7368+extern int
7369+pfkey_spirange_process(struct sadb_ext *pfkey_ext,
7370+ struct pfkey_extracted_data* extr);
7371+
7372+extern int
7373+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
7374+ struct pfkey_extracted_data* extr);
7375+
7376+extern int
7377+pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
7378+ struct pfkey_extracted_data* extr);
7379+
7380+extern int
7381+pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
7382+ struct pfkey_extracted_data* extr);
7383+
7384+extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
7385+extern int pfkey_expire(struct ipsec_sa *, int);
7386+extern int pfkey_acquire(struct ipsec_sa *);
7387+#else /* ! __KERNEL__ */
7388+
7389+extern void (*pfkey_debug_func)(const char *message, ...);
7390+extern void (*pfkey_error_func)(const char *message, ...);
7391+extern void pfkey_print(struct sadb_msg *msg, FILE *out);
7392+
7393+
7394+#endif /* __KERNEL__ */
7395+
7396+extern uint8_t satype2proto(uint8_t satype);
7397+extern uint8_t proto2satype(uint8_t proto);
7398+extern char* satype2name(uint8_t satype);
7399+extern char* proto2name(uint8_t proto);
7400+
7401+struct key_opt
7402+{
7403+ uint32_t key_pid; /* process ID */
7404+ struct sock *sk;
7405+};
7406+
7407+#define key_pid(sk) ((struct key_opt*)&((sk)->sk_protinfo))->key_pid
7408+
7409+/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
7410+ * words.
7411+ */
7412+#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
7413+#define BITS_PER_OCTET 8
7414+#define OCTETBITS 8
7415+#define PFKEYBITS 64
7416+#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
7417+#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
7418+
7419+#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN)
7420+#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN)
7421+
7422+
7423+#define PFKEYv2_MAX_MSGSIZE 4096
7424+
7425+/*
7426+ * PF_KEYv2 permitted and required extensions in and out bitmaps
7427+ */
7428+struct pf_key_ext_parsers_def {
7429+ int (*parser)(struct sadb_ext*);
7430+ char *parser_name;
7431+};
7432+
7433+
7434+#define SADB_EXTENSIONS_MAX 31
7435+extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX];
7436+#define EXT_BITS_IN 0
7437+#define EXT_BITS_OUT 1
7438+#define EXT_BITS_PERM 0
7439+#define EXT_BITS_REQ 1
7440+
7441+extern void pfkey_extensions_init(struct sadb_ext *extensions[]);
7442+extern void pfkey_extensions_free(struct sadb_ext *extensions[]);
7443+extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
7444+
7445+extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
7446+ struct pf_key_ext_parsers_def *ext_parsers[],
7447+ struct sadb_ext **extensions,
7448+ int dir);
7449+
7450+extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg);
7451+
7452+/*
7453+ * PF_KEYv2 build function prototypes
7454+ */
7455+
7456+int
7457+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
7458+ uint8_t msg_type,
7459+ uint8_t satype,
7460+ uint8_t msg_errno,
7461+ uint32_t seq,
7462+ uint32_t pid);
7463+
7464+int
7465+pfkey_sa_ref_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+ uint32_t/*IPsecSAref_t*/ ref);
7474+
7475+int
7476+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
7477+ uint16_t exttype,
7478+ uint32_t spi, /* in network order */
7479+ uint8_t replay_window,
7480+ uint8_t sa_state,
7481+ uint8_t auth,
7482+ uint8_t encrypt,
7483+ uint32_t flags);
7484+
7485+int
7486+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
7487+ uint16_t exttype,
7488+ uint32_t allocations,
7489+ uint64_t bytes,
7490+ uint64_t addtime,
7491+ uint64_t usetime,
7492+ uint32_t packets);
7493+
7494+int
7495+pfkey_address_build(struct sadb_ext** pfkey_ext,
7496+ uint16_t exttype,
7497+ uint8_t proto,
7498+ uint8_t prefixlen,
7499+ struct sockaddr* address);
7500+
7501+int
7502+pfkey_key_build(struct sadb_ext** pfkey_ext,
7503+ uint16_t exttype,
7504+ uint16_t key_bits,
7505+ char* key);
7506+
7507+int
7508+pfkey_ident_build(struct sadb_ext** pfkey_ext,
7509+ uint16_t exttype,
7510+ uint16_t ident_type,
7511+ uint64_t ident_id,
7512+ uint8_t ident_len,
7513+ char* ident_string);
7514+
7515+#ifdef __KERNEL__
7516+extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
7517+extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7518+extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7519+#endif /* __KERNEL__ */
7520+int
7521+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
7522+ uint8_t type);
7523+int
7524+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
7525+ uint16_t exttype,
7526+ uint16_t port);
7527+
7528+int
7529+pfkey_sens_build(struct sadb_ext** pfkey_ext,
7530+ uint32_t dpd,
7531+ uint8_t sens_level,
7532+ uint8_t sens_len,
7533+ uint64_t* sens_bitmap,
7534+ uint8_t integ_level,
7535+ uint8_t integ_len,
7536+ uint64_t* integ_bitmap);
7537+
7538+int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
7539+
7540+
7541+int
7542+pfkey_prop_build(struct sadb_ext** pfkey_ext,
7543+ uint8_t replay,
7544+ unsigned int comb_num,
7545+ struct sadb_comb* comb);
7546+
7547+int
7548+pfkey_supported_build(struct sadb_ext** pfkey_ext,
7549+ uint16_t exttype,
7550+ unsigned int alg_num,
7551+ struct sadb_alg* alg);
7552+
7553+int
7554+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
7555+ uint16_t exttype,
7556+ uint32_t min,
7557+ uint32_t max);
7558+
7559+int
7560+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
7561+
7562+int
7563+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
7564+ uint8_t satype);
7565+
7566+int
7567+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
7568+ uint32_t tunnel,
7569+ uint32_t netlink,
7570+ uint32_t xform,
7571+ uint32_t eroute,
7572+ uint32_t spi,
7573+ uint32_t radij,
7574+ uint32_t esp,
7575+ uint32_t ah,
7576+ uint32_t rcv,
7577+ uint32_t pfkey,
7578+ uint32_t ipcomp,
7579+ uint32_t verbose);
7580+
7581+int
7582+pfkey_msg_build(struct sadb_msg** pfkey_msg,
7583+ struct sadb_ext* extensions[],
7584+ int dir);
7585+
7586+/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
7587+const char *
7588+pfkey_v2_sadb_ext_string(int extnum);
7589+
7590+const char *
7591+pfkey_v2_sadb_type_string(int sadb_type);
7592+
7593+
7594+#endif /* __NET_IPSEC_PF_KEY_H */
7595+
7596+/*
7597+ * $Log: pfkey.h,v $
7598+ * Revision 1.49 2005/05/11 00:57:29 mcr
7599+ * rename struct supported -> struct ipsec_alg_supported.
7600+ * make pfkey.h more standalone.
7601+ *
7602+ * Revision 1.48 2005/05/01 03:12:50 mcr
7603+ * include name of algorithm in datastructure.
7604+ *
7605+ * Revision 1.47 2004/08/21 00:44:14 mcr
7606+ * simplify definition of nat_t related prototypes.
7607+ *
7608+ * Revision 1.46 2004/08/04 16:27:22 mcr
7609+ * 2.6 sk_ options.
7610+ *
7611+ * Revision 1.45 2004/04/06 02:49:00 mcr
7612+ * pullup of algo code from alg-branch.
7613+ *
7614+ * Revision 1.44 2003/12/10 01:20:01 mcr
7615+ * NAT-traversal patches to KLIPS.
7616+ *
7617+ * Revision 1.43 2003/10/31 02:26:44 mcr
7618+ * pulled up port-selector patches.
7619+ *
7620+ * Revision 1.42.2.2 2003/10/29 01:09:32 mcr
7621+ * added debugging for pfkey library.
7622+ *
7623+ * Revision 1.42.2.1 2003/09/21 13:59:34 mcr
7624+ * pre-liminary X.509 patch - does not yet pass tests.
7625+ *
7626+ * Revision 1.42 2003/08/25 22:08:19 mcr
7627+ * removed pfkey_proto_init() from pfkey.h for 2.6 support.
7628+ *
7629+ * Revision 1.41 2003/05/07 17:28:57 mcr
7630+ * new function pfkey_debug_func added for us in debugging from
7631+
7632+ * pfkey library.
7633+ *
7634+ * Revision 1.40 2003/01/30 02:31:34 rgb
7635+ *
7636+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
7637+ *
7638+ * Revision 1.39 2002/09/20 15:40:21 rgb
7639+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
7640+ * Added ref parameter to pfkey_sa_build().
7641+ * Cleaned out unused cruft.
7642+ *
7643+ * Revision 1.38 2002/05/14 02:37:24 rgb
7644+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
7645+ * ipsec_sa or ipsec_sa.
7646+ * Added function prototypes for the functions moved to
7647+ * pfkey_v2_ext_process.c.
7648+ *
7649+ * Revision 1.37 2002/04/24 07:36:49 mcr
7650+ * Moved from ./lib/pfkey.h,v
7651+ *
7652+ * Revision 1.36 2002/01/20 20:34:49 mcr
7653+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
7654+ *
7655+ * Revision 1.35 2001/11/27 05:27:47 mcr
7656+ * pfkey parses are now maintained by a structure
7657+ * that includes their name for debug purposes.
7658+ *
7659+ * Revision 1.34 2001/11/26 09:23:53 rgb
7660+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
7661+ *
7662+ * Revision 1.33 2001/11/06 19:47:47 rgb
7663+ * Added packet parameter to lifetime and comb structures.
7664+ *
7665+ * Revision 1.32 2001/09/08 21:13:34 rgb
7666+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
7667+ *
7668+ * Revision 1.31 2001/06/14 19:35:16 rgb
7669+ * Update copyright date.
7670+ *
7671+ * Revision 1.30 2001/02/27 07:04:52 rgb
7672+ * Added satype2name prototype.
7673+ *
7674+ * Revision 1.29 2001/02/26 19:59:33 rgb
7675+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
7676+ *
7677+ * Revision 1.28 2000/10/10 20:10:19 rgb
7678+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
7679+ *
7680+ * Revision 1.27 2000/09/21 04:20:45 rgb
7681+ * Fixed array size off-by-one error. (Thanks Svenning!)
7682+ *
7683+ * Revision 1.26 2000/09/12 03:26:05 rgb
7684+ * Added pfkey_acquire prototype.
7685+ *
7686+ * Revision 1.25 2000/09/08 19:21:28 rgb
7687+ * Fix pfkey_prop_build() parameter to be only single indirection.
7688+ *
7689+ * Revision 1.24 2000/09/01 18:46:42 rgb
7690+ * Added a supported algorithms array lists, one per satype and registered
7691+ * existing algorithms.
7692+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
7693+ * list.
7694+ *
7695+ * Revision 1.23 2000/08/27 01:55:26 rgb
7696+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
7697+ *
7698+ * Revision 1.22 2000/08/20 21:39:23 rgb
7699+ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
7700+ * pfkey_expire().
7701+ *
7702+ * Revision 1.21 2000/08/15 17:29:23 rgb
7703+ * Fixes from SZI to untested pfkey_prop_build().
7704+ *
7705+ * Revision 1.20 2000/05/10 20:14:19 rgb
7706+ * Fleshed out sensitivity, proposal and supported extensions.
7707+ *
7708+ * Revision 1.19 2000/03/16 14:07:23 rgb
7709+ * Renamed ALIGN macro to avoid fighting with others in kernel.
7710+ *
7711+ * Revision 1.18 2000/01/22 23:24:06 rgb
7712+ * Added prototypes for proto2satype(), satype2proto() and proto2name().
7713+ *
7714+ * Revision 1.17 2000/01/21 06:26:59 rgb
7715+ * Converted from double tdb arguments to one structure (extr)
7716+ * containing pointers to all temporary information structures.
7717+ * Added klipsdebug switching capability.
7718+ * Dropped unused argument to pfkey_x_satype_build().
7719+ *
7720+ * Revision 1.16 1999/12/29 21:17:41 rgb
7721+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
7722+ * parameter for cleaner manipulation of extensions[] and to guard
7723+ * against potential memory leaks.
7724+ * Changed the I/F to pfkey_msg_free() for the same reason.
7725+ *
7726+ * Revision 1.15 1999/12/09 23:12:54 rgb
7727+ * Added macro for BITS_PER_OCTET.
7728+ * Added argument to pfkey_sa_build() to do eroutes.
7729+ *
7730+ * Revision 1.14 1999/12/08 20:33:25 rgb
7731+ * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
7732+ *
7733+ * Revision 1.13 1999/12/07 19:53:40 rgb
7734+ * Removed unused first argument from extension parsers.
7735+ * Changed __u* types to uint* to avoid use of asm/types.h and
7736+ * sys/types.h in userspace code.
7737+ * Added function prototypes for pfkey message and extensions
7738+ * initialisation and cleanup.
7739+ *
7740+ * Revision 1.12 1999/12/01 22:19:38 rgb
7741+ * Change pfkey_sa_build to accept an SPI in network byte order.
7742+ *
7743+ * Revision 1.11 1999/11/27 11:55:26 rgb
7744+ * Added extern sadb_satype2proto to enable moving protocol lookup table
7745+ * to lib/pfkey_v2_parse.c.
7746+ * Delete unused, moved typedefs.
7747+ * Add argument to pfkey_msg_parse() for direction.
7748+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
7749+ *
7750+ * Revision 1.10 1999/11/23 22:29:21 rgb
7751+ * This file has been moved in the distribution from klips/net/ipsec to
7752+ * lib.
7753+ * Add macros for dealing with alignment and rounding up more opaquely.
7754+ * The uint<n>_t type defines have been moved to freeswan.h to avoid
7755+ * chicken-and-egg problems.
7756+ * Add macros for dealing with alignment and rounding up more opaque.
7757+ * Added prototypes for using extention header bitmaps.
7758+ * Added prototypes of all the build functions.
7759+ *
7760+ * Revision 1.9 1999/11/20 21:59:48 rgb
7761+ * Moved socketlist type declarations and prototypes for shared use.
7762+ * Slightly modified scope of sockaddr_key declaration.
7763+ *
7764+ * Revision 1.8 1999/11/17 14:34:25 rgb
7765+ * Protect sa_family_t from being used in userspace with GLIBC<2.
7766+ *
7767+ * Revision 1.7 1999/10/27 19:40:35 rgb
7768+ * Add a maximum PFKEY packet size macro.
7769+ *
7770+ * Revision 1.6 1999/10/26 16:58:58 rgb
7771+ * Created a sockaddr_key and key_opt socket extension structures.
7772+ *
7773+ * Revision 1.5 1999/06/10 05:24:41 rgb
7774+ * Renamed variables to reduce confusion.
7775+ *
7776+ * Revision 1.4 1999/04/29 15:21:11 rgb
7777+ * Add pfkey support to debugging.
7778+ * Add return values to init and cleanup functions.
7779+ *
7780+ * Revision 1.3 1999/04/15 17:58:07 rgb
7781+ * Add RCSID labels.
7782+ *
7783+ */
7784--- /dev/null Tue Mar 11 13:02:56 2003
7785+++ linux/include/pfkeyv2.h Mon Feb 9 13:51:03 2004
7786@@ -0,0 +1,472 @@
7787+/*
7788+ * RCSID $Id: pfkeyv2.h,v 1.31 2005/04/14 01:14:54 mcr Exp $
7789+ */
7790+
7791+/*
7792+RFC 2367 PF_KEY Key Management API July 1998
7793+
7794+
7795+Appendix D: Sample Header File
7796+
7797+This file defines structures and symbols for the PF_KEY Version 2
7798+key management interface. It was written at the U.S. Naval Research
7799+Laboratory. This file is in the public domain. The authors ask that
7800+you leave this credit intact on any copies of this file.
7801+*/
7802+#ifndef __PFKEY_V2_H
7803+#define __PFKEY_V2_H 1
7804+
7805+#define PF_KEY_V2 2
7806+#define PFKEYV2_REVISION 199806L
7807+
7808+#define SADB_RESERVED 0
7809+#define SADB_GETSPI 1
7810+#define SADB_UPDATE 2
7811+#define SADB_ADD 3
7812+#define SADB_DELETE 4
7813+#define SADB_GET 5
7814+#define SADB_ACQUIRE 6
7815+#define SADB_REGISTER 7
7816+#define SADB_EXPIRE 8
7817+#define SADB_FLUSH 9
7818+#define SADB_DUMP 10
7819+#define SADB_X_PROMISC 11
7820+#define SADB_X_PCHANGE 12
7821+#define SADB_X_GRPSA 13
7822+#define SADB_X_ADDFLOW 14
7823+#define SADB_X_DELFLOW 15
7824+#define SADB_X_DEBUG 16
7825+#define SADB_X_NAT_T_NEW_MAPPING 17
7826+#define SADB_MAX 17
7827+
7828+struct sadb_msg {
7829+ uint8_t sadb_msg_version;
7830+ uint8_t sadb_msg_type;
7831+ uint8_t sadb_msg_errno;
7832+ uint8_t sadb_msg_satype;
7833+ uint16_t sadb_msg_len;
7834+ uint16_t sadb_msg_reserved;
7835+ uint32_t sadb_msg_seq;
7836+ uint32_t sadb_msg_pid;
7837+};
7838+
7839+struct sadb_ext {
7840+ uint16_t sadb_ext_len;
7841+ uint16_t sadb_ext_type;
7842+};
7843+
7844+struct sadb_sa {
7845+ uint16_t sadb_sa_len;
7846+ uint16_t sadb_sa_exttype;
7847+ uint32_t sadb_sa_spi;
7848+ uint8_t sadb_sa_replay;
7849+ uint8_t sadb_sa_state;
7850+ uint8_t sadb_sa_auth;
7851+ uint8_t sadb_sa_encrypt;
7852+ uint32_t sadb_sa_flags;
7853+ uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
7854+ uint8_t sadb_x_reserved[4];
7855+};
7856+
7857+struct sadb_sa_v1 {
7858+ uint16_t sadb_sa_len;
7859+ uint16_t sadb_sa_exttype;
7860+ uint32_t sadb_sa_spi;
7861+ uint8_t sadb_sa_replay;
7862+ uint8_t sadb_sa_state;
7863+ uint8_t sadb_sa_auth;
7864+ uint8_t sadb_sa_encrypt;
7865+ uint32_t sadb_sa_flags;
7866+};
7867+
7868+struct sadb_lifetime {
7869+ uint16_t sadb_lifetime_len;
7870+ uint16_t sadb_lifetime_exttype;
7871+ uint32_t sadb_lifetime_allocations;
7872+ uint64_t sadb_lifetime_bytes;
7873+ uint64_t sadb_lifetime_addtime;
7874+ uint64_t sadb_lifetime_usetime;
7875+ uint32_t sadb_x_lifetime_packets;
7876+ uint32_t sadb_x_lifetime_reserved;
7877+};
7878+
7879+struct sadb_address {
7880+ uint16_t sadb_address_len;
7881+ uint16_t sadb_address_exttype;
7882+ uint8_t sadb_address_proto;
7883+ uint8_t sadb_address_prefixlen;
7884+ uint16_t sadb_address_reserved;
7885+};
7886+
7887+struct sadb_key {
7888+ uint16_t sadb_key_len;
7889+ uint16_t sadb_key_exttype;
7890+ uint16_t sadb_key_bits;
7891+ uint16_t sadb_key_reserved;
7892+};
7893+
7894+struct sadb_ident {
7895+ uint16_t sadb_ident_len;
7896+ uint16_t sadb_ident_exttype;
7897+ uint16_t sadb_ident_type;
7898+ uint16_t sadb_ident_reserved;
7899+ uint64_t sadb_ident_id;
7900+};
7901+
7902+struct sadb_sens {
7903+ uint16_t sadb_sens_len;
7904+ uint16_t sadb_sens_exttype;
7905+ uint32_t sadb_sens_dpd;
7906+ uint8_t sadb_sens_sens_level;
7907+ uint8_t sadb_sens_sens_len;
7908+ uint8_t sadb_sens_integ_level;
7909+ uint8_t sadb_sens_integ_len;
7910+ uint32_t sadb_sens_reserved;
7911+};
7912+
7913+struct sadb_prop {
7914+ uint16_t sadb_prop_len;
7915+ uint16_t sadb_prop_exttype;
7916+ uint8_t sadb_prop_replay;
7917+ uint8_t sadb_prop_reserved[3];
7918+};
7919+
7920+struct sadb_comb {
7921+ uint8_t sadb_comb_auth;
7922+ uint8_t sadb_comb_encrypt;
7923+ uint16_t sadb_comb_flags;
7924+ uint16_t sadb_comb_auth_minbits;
7925+ uint16_t sadb_comb_auth_maxbits;
7926+ uint16_t sadb_comb_encrypt_minbits;
7927+ uint16_t sadb_comb_encrypt_maxbits;
7928+ uint32_t sadb_comb_reserved;
7929+ uint32_t sadb_comb_soft_allocations;
7930+ uint32_t sadb_comb_hard_allocations;
7931+ uint64_t sadb_comb_soft_bytes;
7932+ uint64_t sadb_comb_hard_bytes;
7933+ uint64_t sadb_comb_soft_addtime;
7934+ uint64_t sadb_comb_hard_addtime;
7935+ uint64_t sadb_comb_soft_usetime;
7936+ uint64_t sadb_comb_hard_usetime;
7937+ uint32_t sadb_x_comb_soft_packets;
7938+ uint32_t sadb_x_comb_hard_packets;
7939+};
7940+
7941+struct sadb_supported {
7942+ uint16_t sadb_supported_len;
7943+ uint16_t sadb_supported_exttype;
7944+ uint32_t sadb_supported_reserved;
7945+};
7946+
7947+struct sadb_alg {
7948+ uint8_t sadb_alg_id;
7949+ uint8_t sadb_alg_ivlen;
7950+ uint16_t sadb_alg_minbits;
7951+ uint16_t sadb_alg_maxbits;
7952+ uint16_t sadb_alg_reserved;
7953+};
7954+
7955+struct sadb_spirange {
7956+ uint16_t sadb_spirange_len;
7957+ uint16_t sadb_spirange_exttype;
7958+ uint32_t sadb_spirange_min;
7959+ uint32_t sadb_spirange_max;
7960+ uint32_t sadb_spirange_reserved;
7961+};
7962+
7963+struct sadb_x_kmprivate {
7964+ uint16_t sadb_x_kmprivate_len;
7965+ uint16_t sadb_x_kmprivate_exttype;
7966+ uint32_t sadb_x_kmprivate_reserved;
7967+};
7968+
7969+struct sadb_x_satype {
7970+ uint16_t sadb_x_satype_len;
7971+ uint16_t sadb_x_satype_exttype;
7972+ uint8_t sadb_x_satype_satype;
7973+ uint8_t sadb_x_satype_reserved[3];
7974+};
7975+
7976+struct sadb_x_policy {
7977+ uint16_t sadb_x_policy_len;
7978+ uint16_t sadb_x_policy_exttype;
7979+ uint16_t sadb_x_policy_type;
7980+ uint8_t sadb_x_policy_dir;
7981+ uint8_t sadb_x_policy_reserved;
7982+ uint32_t sadb_x_policy_id;
7983+ uint32_t sadb_x_policy_reserved2;
7984+};
7985+
7986+struct sadb_x_debug {
7987+ uint16_t sadb_x_debug_len;
7988+ uint16_t sadb_x_debug_exttype;
7989+ uint32_t sadb_x_debug_tunnel;
7990+ uint32_t sadb_x_debug_netlink;
7991+ uint32_t sadb_x_debug_xform;
7992+ uint32_t sadb_x_debug_eroute;
7993+ uint32_t sadb_x_debug_spi;
7994+ uint32_t sadb_x_debug_radij;
7995+ uint32_t sadb_x_debug_esp;
7996+ uint32_t sadb_x_debug_ah;
7997+ uint32_t sadb_x_debug_rcv;
7998+ uint32_t sadb_x_debug_pfkey;
7999+ uint32_t sadb_x_debug_ipcomp;
8000+ uint32_t sadb_x_debug_verbose;
8001+ uint8_t sadb_x_debug_reserved[4];
8002+};
8003+
8004+struct sadb_x_nat_t_type {
8005+ uint16_t sadb_x_nat_t_type_len;
8006+ uint16_t sadb_x_nat_t_type_exttype;
8007+ uint8_t sadb_x_nat_t_type_type;
8008+ uint8_t sadb_x_nat_t_type_reserved[3];
8009+};
8010+struct sadb_x_nat_t_port {
8011+ uint16_t sadb_x_nat_t_port_len;
8012+ uint16_t sadb_x_nat_t_port_exttype;
8013+ uint16_t sadb_x_nat_t_port_port;
8014+ uint16_t sadb_x_nat_t_port_reserved;
8015+};
8016+
8017+/*
8018+ * A protocol structure for passing through the transport level
8019+ * protocol. It contains more fields than are actually used/needed
8020+ * but it is this way to be compatible with the structure used in
8021+ * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
8022+ */
8023+struct sadb_protocol {
8024+ uint16_t sadb_protocol_len;
8025+ uint16_t sadb_protocol_exttype;
8026+ uint8_t sadb_protocol_proto;
8027+ uint8_t sadb_protocol_direction;
8028+ uint8_t sadb_protocol_flags;
8029+ uint8_t sadb_protocol_reserved2;
8030+};
8031+
8032+#define SADB_EXT_RESERVED 0
8033+#define SADB_EXT_SA 1
8034+#define SADB_EXT_LIFETIME_CURRENT 2
8035+#define SADB_EXT_LIFETIME_HARD 3
8036+#define SADB_EXT_LIFETIME_SOFT 4
8037+#define SADB_EXT_ADDRESS_SRC 5
8038+#define SADB_EXT_ADDRESS_DST 6
8039+#define SADB_EXT_ADDRESS_PROXY 7
8040+#define SADB_EXT_KEY_AUTH 8
8041+#define SADB_EXT_KEY_ENCRYPT 9
8042+#define SADB_EXT_IDENTITY_SRC 10
8043+#define SADB_EXT_IDENTITY_DST 11
8044+#define SADB_EXT_SENSITIVITY 12
8045+#define SADB_EXT_PROPOSAL 13
8046+#define SADB_EXT_SUPPORTED_AUTH 14
8047+#define SADB_EXT_SUPPORTED_ENCRYPT 15
8048+#define SADB_EXT_SPIRANGE 16
8049+#define SADB_X_EXT_KMPRIVATE 17
8050+#define SADB_X_EXT_SATYPE2 18
8051+#ifdef KERNEL26_HAS_KAME_DUPLICATES
8052+#define SADB_X_EXT_POLICY 18
8053+#endif
8054+#define SADB_X_EXT_SA2 19
8055+#define SADB_X_EXT_ADDRESS_DST2 20
8056+#define SADB_X_EXT_ADDRESS_SRC_FLOW 21
8057+#define SADB_X_EXT_ADDRESS_DST_FLOW 22
8058+#define SADB_X_EXT_ADDRESS_SRC_MASK 23
8059+#define SADB_X_EXT_ADDRESS_DST_MASK 24
8060+#define SADB_X_EXT_DEBUG 25
8061+#define SADB_X_EXT_PROTOCOL 26
8062+#define SADB_X_EXT_NAT_T_TYPE 27
8063+#define SADB_X_EXT_NAT_T_SPORT 28
8064+#define SADB_X_EXT_NAT_T_DPORT 29
8065+#define SADB_X_EXT_NAT_T_OA 30
8066+#define SADB_EXT_MAX 30
8067+
8068+/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
8069+#define SADB_X_EXT_ADDRESS_DELFLOW \
8070+ ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
8071+ | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
8072+ | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
8073+ | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
8074+
8075+#define SADB_SATYPE_UNSPEC 0
8076+#define SADB_SATYPE_AH 2
8077+#define SADB_SATYPE_ESP 3
8078+#define SADB_SATYPE_RSVP 5
8079+#define SADB_SATYPE_OSPFV2 6
8080+#define SADB_SATYPE_RIPV2 7
8081+#define SADB_SATYPE_MIP 8
8082+#define SADB_X_SATYPE_IPIP 9
8083+#ifdef KERNEL26_HAS_KAME_DUPLICATES
8084+#define SADB_X_SATYPE_IPCOMP 9 /* ICK! */
8085+#endif
8086+#define SADB_X_SATYPE_COMP 10
8087+#define SADB_X_SATYPE_INT 11
8088+#define SADB_SATYPE_MAX 11
8089+
8090+enum sadb_sastate {
8091+ SADB_SASTATE_LARVAL=0,
8092+ SADB_SASTATE_MATURE=1,
8093+ SADB_SASTATE_DYING=2,
8094+ SADB_SASTATE_DEAD=3
8095+};
8096+#define SADB_SASTATE_MAX 3
8097+
8098+#define SADB_SAFLAGS_PFS 1
8099+#define SADB_X_SAFLAGS_REPLACEFLOW 2
8100+#define SADB_X_SAFLAGS_CLEARFLOW 4
8101+#define SADB_X_SAFLAGS_INFLOW 8
8102+
8103+/* not obvious, but these are the same values as used in isakmp,
8104+ * and in freeswan/ipsec_policy.h. If you need to add any, they
8105+ * should be added as according to
8106+ * http://www.iana.org/assignments/isakmp-registry
8107+ *
8108+ * and if not, then please try to use a private-use value, and
8109+ * consider asking IANA to assign a value.
8110+ */
8111+#define SADB_AALG_NONE 0
8112+#define SADB_AALG_MD5HMAC 2
8113+#define SADB_AALG_SHA1HMAC 3
8114+#define SADB_X_AALG_SHA2_256HMAC 5
8115+#define SADB_X_AALG_SHA2_384HMAC 6
8116+#define SADB_X_AALG_SHA2_512HMAC 7
8117+#define SADB_X_AALG_RIPEMD160HMAC 8
8118+#define SADB_X_AALG_NULL 251 /* kame */
8119+#define SADB_AALG_MAX 251
8120+
8121+#define SADB_EALG_NONE 0
8122+#define SADB_EALG_DESCBC 2
8123+#define SADB_EALG_3DESCBC 3
8124+#define SADB_X_EALG_CASTCBC 6
8125+#define SADB_X_EALG_BLOWFISHCBC 7
8126+#define SADB_EALG_NULL 11
8127+#define SADB_X_EALG_AESCBC 12
8128+#define SADB_EALG_MAX 255
8129+
8130+#define SADB_X_CALG_NONE 0
8131+#define SADB_X_CALG_OUI 1
8132+#define SADB_X_CALG_DEFLATE 2
8133+#define SADB_X_CALG_LZS 3
8134+#define SADB_X_CALG_V42BIS 4
8135+#ifdef KERNEL26_HAS_KAME_DUPLICATES
8136+#define SADB_X_CALG_LZJH 4
8137+#endif
8138+#define SADB_X_CALG_MAX 4
8139+
8140+#define SADB_X_TALG_NONE 0
8141+#define SADB_X_TALG_IPv4_in_IPv4 1
8142+#define SADB_X_TALG_IPv6_in_IPv4 2
8143+#define SADB_X_TALG_IPv4_in_IPv6 3
8144+#define SADB_X_TALG_IPv6_in_IPv6 4
8145+#define SADB_X_TALG_MAX 4
8146+
8147+
8148+#define SADB_IDENTTYPE_RESERVED 0
8149+#define SADB_IDENTTYPE_PREFIX 1
8150+#define SADB_IDENTTYPE_FQDN 2
8151+#define SADB_IDENTTYPE_USERFQDN 3
8152+#define SADB_X_IDENTTYPE_CONNECTION 4
8153+#define SADB_IDENTTYPE_MAX 4
8154+
8155+#define SADB_KEY_FLAGS_MAX 0
8156+#endif /* __PFKEY_V2_H */
8157+
8158+/*
8159+ * $Log: pfkeyv2.h,v $
8160+ * Revision 1.31 2005/04/14 01:14:54 mcr
8161+ * change sadb_state to an enum.
8162+ *
8163+ * Revision 1.30 2004/04/06 02:49:00 mcr
8164+ * pullup of algo code from alg-branch.
8165+ *
8166+ * Revision 1.29 2003/12/22 21:35:58 mcr
8167+ * new patches from Dr{Who}.
8168+ *
8169+ * Revision 1.28 2003/12/22 19:33:15 mcr
8170+ * added 0.6c NAT-T patch.
8171+ *
8172+ * Revision 1.27 2003/12/10 01:20:01 mcr
8173+ * NAT-traversal patches to KLIPS.
8174+ *
8175+ * Revision 1.26 2003/10/31 02:26:44 mcr
8176+ * pulled up port-selector patches.
8177+ *
8178+ * Revision 1.25.4.1 2003/09/21 13:59:34 mcr
8179+ * pre-liminary X.509 patch - does not yet pass tests.
8180+ *
8181+ * Revision 1.25 2003/07/31 23:59:17 mcr
8182+ * re-introduce kernel 2.6 duplicate values for now.
8183+ * hope to get them changed!
8184+ *
8185+ * Revision 1.24 2003/07/31 22:55:27 mcr
8186+ * added some definitions to keep pfkeyv2.h files in sync.
8187+ *
8188+ * Revision 1.23 2003/05/11 00:43:48 mcr
8189+ * added comment about origin of values used
8190+ *
8191+ * Revision 1.22 2003/01/30 02:31:34 rgb
8192+ *
8193+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
8194+ *
8195+ * Revision 1.21 2002/12/16 19:26:49 mcr
8196+ * added definition of FS 1.xx sadb structure
8197+ *
8198+ * Revision 1.20 2002/09/20 15:40:25 rgb
8199+ * Added sadb_x_sa_ref to struct sadb_sa.
8200+ *
8201+ * Revision 1.19 2002/04/24 07:36:49 mcr
8202+ * Moved from ./lib/pfkeyv2.h,v
8203+ *
8204+ * Revision 1.18 2001/11/06 19:47:47 rgb
8205+ * Added packet parameter to lifetime and comb structures.
8206+ *
8207+ * Revision 1.17 2001/09/08 21:13:35 rgb
8208+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
8209+ *
8210+ * Revision 1.16 2001/07/06 19:49:46 rgb
8211+ * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks.
8212+ *
8213+ * Revision 1.15 2001/02/26 20:00:43 rgb
8214+ * Added internal IP protocol 61 for magic SAs.
8215+ *
8216+ * Revision 1.14 2001/02/08 18:51:05 rgb
8217+ * Include RFC document title and appendix subsection title.
8218+ *
8219+ * Revision 1.13 2000/10/10 20:10:20 rgb
8220+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
8221+ *
8222+ * Revision 1.12 2000/09/15 06:41:50 rgb
8223+ * Added V42BIS constant.
8224+ *
8225+ * Revision 1.11 2000/09/12 22:35:37 rgb
8226+ * Restructured to remove unused extensions from CLEARFLOW messages.
8227+ *
8228+ * Revision 1.10 2000/09/12 18:50:09 rgb
8229+ * Added IPIP tunnel types as algo support.
8230+ *
8231+ * Revision 1.9 2000/08/21 16:47:19 rgb
8232+ * Added SADB_X_CALG_* macros for IPCOMP.
8233+ *
8234+ * Revision 1.8 2000/08/09 20:43:34 rgb
8235+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
8236+ *
8237+ * Revision 1.7 2000/01/21 06:28:37 rgb
8238+ * Added flow add/delete message type macros.
8239+ * Added flow address extension type macros.
8240+ * Tidied up spacing.
8241+ * Added klipsdebug switching capability.
8242+ *
8243+ * Revision 1.6 1999/11/27 11:56:08 rgb
8244+ * Add SADB_X_SATYPE_COMP for compression, eventually.
8245+ *
8246+ * Revision 1.5 1999/11/23 22:23:16 rgb
8247+ * This file has been moved in the distribution from klips/net/ipsec to
8248+ * lib.
8249+ *
8250+ * Revision 1.4 1999/04/29 15:23:29 rgb
8251+ * Add GRPSA support.
8252+ * Add support for a second SATYPE, SA and DST_ADDRESS.
8253+ * Add IPPROTO_IPIP support.
8254+ *
8255+ * Revision 1.3 1999/04/15 17:58:08 rgb
8256+ * Add RCSID labels.
8257+ *
8258+ */
8259--- /dev/null Tue Mar 11 13:02:56 2003
8260+++ linux/include/zlib/zconf.h Mon Feb 9 13:51:03 2004
8261@@ -0,0 +1,309 @@
8262+/* zconf.h -- configuration of the zlib compression library
8263+ * Copyright (C) 1995-2002 Jean-loup Gailly.
8264+ * For conditions of distribution and use, see copyright notice in zlib.h
8265+ */
8266+
8267+/* @(#) $Id: zconf.h,v 1.4 2004/07/10 07:48:40 mcr Exp $ */
8268+
8269+#ifndef _ZCONF_H
8270+#define _ZCONF_H
8271+
8272+/*
8273+ * If you *really* need a unique prefix for all types and library functions,
8274+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
8275+ */
8276+#ifdef IPCOMP_PREFIX
8277+# define deflateInit_ ipcomp_deflateInit_
8278+# define deflate ipcomp_deflate
8279+# define deflateEnd ipcomp_deflateEnd
8280+# define inflateInit_ ipcomp_inflateInit_
8281+# define inflate ipcomp_inflate
8282+# define inflateEnd ipcomp_inflateEnd
8283+# define deflateInit2_ ipcomp_deflateInit2_
8284+# define deflateSetDictionary ipcomp_deflateSetDictionary
8285+# define deflateCopy ipcomp_deflateCopy
8286+# define deflateReset ipcomp_deflateReset
8287+# define deflateParams ipcomp_deflateParams
8288+# define inflateInit2_ ipcomp_inflateInit2_
8289+# define inflateSetDictionary ipcomp_inflateSetDictionary
8290+# define inflateSync ipcomp_inflateSync
8291+# define inflateSyncPoint ipcomp_inflateSyncPoint
8292+# define inflateReset ipcomp_inflateReset
8293+# define compress ipcomp_compress
8294+# define compress2 ipcomp_compress2
8295+# define uncompress ipcomp_uncompress
8296+# define adler32 ipcomp_adler32
8297+# define crc32 ipcomp_crc32
8298+# define get_crc_table ipcomp_get_crc_table
8299+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
8300+# define inflate_blocks ipcomp_deflate_blocks
8301+# define inflate_blocks_free ipcomp_deflate_blocks_free
8302+# define inflate_blocks_new ipcomp_inflate_blocks_new
8303+# define inflate_blocks_reset ipcomp_inflate_blocks_reset
8304+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
8305+# define inflate_set_dictionary ipcomp_inflate_set_dictionary
8306+# define inflate_codes ipcomp_inflate_codes
8307+# define inflate_codes_free ipcomp_inflate_codes_free
8308+# define inflate_codes_new ipcomp_inflate_codes_new
8309+# define inflate_fast ipcomp_inflate_fast
8310+# define inflate_trees_bits ipcomp_inflate_trees_bits
8311+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
8312+# define inflate_trees_fixed ipcomp_inflate_trees_fixed
8313+# define inflate_flush ipcomp_inflate_flush
8314+# define inflate_mask ipcomp_inflate_mask
8315+# define _dist_code _ipcomp_dist_code
8316+# define _length_code _ipcomp_length_code
8317+# define _tr_align _ipcomp_tr_align
8318+# define _tr_flush_block _ipcomp_tr_flush_block
8319+# define _tr_init _ipcomp_tr_init
8320+# define _tr_stored_block _ipcomp_tr_stored_block
8321+# define _tr_tally _ipcomp_tr_tally
8322+# define zError ipcomp_zError
8323+# define z_errmsg ipcomp_z_errmsg
8324+# define zlibVersion ipcomp_zlibVersion
8325+# define match_init ipcomp_match_init
8326+# define longest_match ipcomp_longest_match
8327+#endif
8328+
8329+#ifdef Z_PREFIX
8330+# define Byte z_Byte
8331+# define uInt z_uInt
8332+# define uLong z_uLong
8333+# define Bytef z_Bytef
8334+# define charf z_charf
8335+# define intf z_intf
8336+# define uIntf z_uIntf
8337+# define uLongf z_uLongf
8338+# define voidpf z_voidpf
8339+# define voidp z_voidp
8340+#endif
8341+
8342+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
8343+# define WIN32
8344+#endif
8345+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
8346+# ifndef __32BIT__
8347+# define __32BIT__
8348+# endif
8349+#endif
8350+#if defined(__MSDOS__) && !defined(MSDOS)
8351+# define MSDOS
8352+#endif
8353+
8354+/*
8355+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
8356+ * than 64k bytes at a time (needed on systems with 16-bit int).
8357+ */
8358+#if defined(MSDOS) && !defined(__32BIT__)
8359+# define MAXSEG_64K
8360+#endif
8361+#ifdef MSDOS
8362+# define UNALIGNED_OK
8363+#endif
8364+
8365+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
8366+# define STDC
8367+#endif
8368+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
8369+# ifndef STDC
8370+# define STDC
8371+# endif
8372+#endif
8373+
8374+#ifndef STDC
8375+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
8376+# define const
8377+# endif
8378+#endif
8379+
8380+/* Some Mac compilers merge all .h files incorrectly: */
8381+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
8382+# define NO_DUMMY_DECL
8383+#endif
8384+
8385+/* Old Borland C incorrectly complains about missing returns: */
8386+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
8387+# define NEED_DUMMY_RETURN
8388+#endif
8389+
8390+
8391+/* Maximum value for memLevel in deflateInit2 */
8392+#ifndef MAX_MEM_LEVEL
8393+# ifdef MAXSEG_64K
8394+# define MAX_MEM_LEVEL 8
8395+# else
8396+# define MAX_MEM_LEVEL 9
8397+# endif
8398+#endif
8399+
8400+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
8401+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
8402+ * created by gzip. (Files created by minigzip can still be extracted by
8403+ * gzip.)
8404+ */
8405+#ifndef MAX_WBITS
8406+# define MAX_WBITS 15 /* 32K LZ77 window */
8407+#endif
8408+
8409+/* The memory requirements for deflate are (in bytes):
8410+ (1 << (windowBits+2)) + (1 << (memLevel+9))
8411+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
8412+ plus a few kilobytes for small objects. For example, if you want to reduce
8413+ the default memory requirements from 256K to 128K, compile with
8414+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
8415+ Of course this will generally degrade compression (there's no free lunch).
8416+
8417+ The memory requirements for inflate are (in bytes) 1 << windowBits
8418+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
8419+ for small objects.
8420+*/
8421+
8422+ /* Type declarations */
8423+
8424+#ifndef OF /* function prototypes */
8425+# ifdef STDC
8426+# define OF(args) args
8427+# else
8428+# define OF(args) ()
8429+# endif
8430+#endif
8431+
8432+/* The following definitions for FAR are needed only for MSDOS mixed
8433+ * model programming (small or medium model with some far allocations).
8434+ * This was tested only with MSC; for other MSDOS compilers you may have
8435+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
8436+ * just define FAR to be empty.
8437+ */
8438+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
8439+ /* MSC small or medium model */
8440+# define SMALL_MEDIUM
8441+# ifdef _MSC_VER
8442+# define FAR _far
8443+# else
8444+# define FAR far
8445+# endif
8446+#endif
8447+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
8448+# ifndef __32BIT__
8449+# define SMALL_MEDIUM
8450+# define FAR _far
8451+# endif
8452+#endif
8453+
8454+/* Compile with -DZLIB_DLL for Windows DLL support */
8455+#if defined(ZLIB_DLL)
8456+# if defined(_WINDOWS) || defined(WINDOWS)
8457+# ifdef FAR
8458+# undef FAR
8459+# endif
8460+# include <windows.h>
8461+# define ZEXPORT WINAPI
8462+# ifdef WIN32
8463+# define ZEXPORTVA WINAPIV
8464+# else
8465+# define ZEXPORTVA FAR _cdecl _export
8466+# endif
8467+# endif
8468+# if defined (__BORLANDC__)
8469+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
8470+# include <windows.h>
8471+# define ZEXPORT __declspec(dllexport) WINAPI
8472+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
8473+# else
8474+# if defined (_Windows) && defined (__DLL__)
8475+# define ZEXPORT _export
8476+# define ZEXPORTVA _export
8477+# endif
8478+# endif
8479+# endif
8480+#endif
8481+
8482+#if defined (__BEOS__)
8483+# if defined (ZLIB_DLL)
8484+# define ZEXTERN extern __declspec(dllexport)
8485+# else
8486+# define ZEXTERN extern __declspec(dllimport)
8487+# endif
8488+#endif
8489+
8490+#ifndef ZEXPORT
8491+# define ZEXPORT
8492+#endif
8493+#ifndef ZEXPORTVA
8494+# define ZEXPORTVA
8495+#endif
8496+#ifndef ZEXTERN
8497+# define ZEXTERN extern
8498+#endif
8499+
8500+#ifndef FAR
8501+# define FAR
8502+#endif
8503+
8504+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
8505+typedef unsigned char Byte; /* 8 bits */
8506+#endif
8507+typedef unsigned int uInt; /* 16 bits or more */
8508+typedef unsigned long uLong; /* 32 bits or more */
8509+
8510+#ifdef SMALL_MEDIUM
8511+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
8512+# define Bytef Byte FAR
8513+#else
8514+ typedef Byte FAR Bytef;
8515+#endif
8516+typedef char FAR charf;
8517+typedef int FAR intf;
8518+typedef uInt FAR uIntf;
8519+typedef uLong FAR uLongf;
8520+
8521+#ifdef STDC
8522+ typedef void FAR *voidpf;
8523+ typedef void *voidp;
8524+#else
8525+ typedef Byte FAR *voidpf;
8526+ typedef Byte *voidp;
8527+#endif
8528+
8529+#ifdef HAVE_UNISTD_H
8530+# include <sys/types.h> /* for off_t */
8531+# include <unistd.h> /* for SEEK_* and off_t */
8532+# define z_off_t off_t
8533+#endif
8534+#ifndef SEEK_SET
8535+# define SEEK_SET 0 /* Seek from beginning of file. */
8536+# define SEEK_CUR 1 /* Seek from current position. */
8537+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
8538+#endif
8539+#ifndef z_off_t
8540+# define z_off_t long
8541+#endif
8542+
8543+/* MVS linker does not support external names larger than 8 bytes */
8544+#if defined(__MVS__)
8545+# pragma map(deflateInit_,"DEIN")
8546+# pragma map(deflateInit2_,"DEIN2")
8547+# pragma map(deflateEnd,"DEEND")
8548+# pragma map(inflateInit_,"ININ")
8549+# pragma map(inflateInit2_,"ININ2")
8550+# pragma map(inflateEnd,"INEND")
8551+# pragma map(inflateSync,"INSY")
8552+# pragma map(inflateSetDictionary,"INSEDI")
8553+# pragma map(inflate_blocks,"INBL")
8554+# pragma map(inflate_blocks_new,"INBLNE")
8555+# pragma map(inflate_blocks_free,"INBLFR")
8556+# pragma map(inflate_blocks_reset,"INBLRE")
8557+# pragma map(inflate_codes_free,"INCOFR")
8558+# pragma map(inflate_codes,"INCO")
8559+# pragma map(inflate_fast,"INFA")
8560+# pragma map(inflate_flush,"INFLU")
8561+# pragma map(inflate_mask,"INMA")
8562+# pragma map(inflate_set_dictionary,"INSEDI2")
8563+# pragma map(ipcomp_inflate_copyright,"INCOPY")
8564+# pragma map(inflate_trees_bits,"INTRBI")
8565+# pragma map(inflate_trees_dynamic,"INTRDY")
8566+# pragma map(inflate_trees_fixed,"INTRFI")
8567+# pragma map(inflate_trees_free,"INTRFR")
8568+#endif
8569+
8570+#endif /* _ZCONF_H */
8571--- /dev/null Tue Mar 11 13:02:56 2003
8572+++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004
8573@@ -0,0 +1,893 @@
8574+/* zlib.h -- interface of the 'zlib' general purpose compression library
8575+ version 1.1.4, March 11th, 2002
8576+
8577+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
8578+
8579+ This software is provided 'as-is', without any express or implied
8580+ warranty. In no event will the authors be held liable for any damages
8581+ arising from the use of this software.
8582+
8583+ Permission is granted to anyone to use this software for any purpose,
8584+ including commercial applications, and to alter it and redistribute it
8585+ freely, subject to the following restrictions:
8586+
8587+ 1. The origin of this software must not be misrepresented; you must not
8588+ claim that you wrote the original software. If you use this software
8589+ in a product, an acknowledgment in the product documentation would be
8590+ appreciated but is not required.
8591+ 2. Altered source versions must be plainly marked as such, and must not be
8592+ misrepresented as being the original software.
8593+ 3. This notice may not be removed or altered from any source distribution.
8594+
8595+ Jean-loup Gailly Mark Adler
8596+ jloup@gzip.org madler@alumni.caltech.edu
8597+
8598+
8599+ The data format used by the zlib library is described by RFCs (Request for
8600+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
8601+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
8602+*/
8603+
8604+#ifndef _ZLIB_H
8605+#define _ZLIB_H
8606+
8607+#include "zconf.h"
8608+
8609+#ifdef __cplusplus
8610+extern "C" {
8611+#endif
8612+
8613+#define ZLIB_VERSION "1.1.4"
8614+
8615+/*
8616+ The 'zlib' compression library provides in-memory compression and
8617+ decompression functions, including integrity checks of the uncompressed
8618+ data. This version of the library supports only one compression method
8619+ (deflation) but other algorithms will be added later and will have the same
8620+ stream interface.
8621+
8622+ Compression can be done in a single step if the buffers are large
8623+ enough (for example if an input file is mmap'ed), or can be done by
8624+ repeated calls of the compression function. In the latter case, the
8625+ application must provide more input and/or consume the output
8626+ (providing more output space) before each call.
8627+
8628+ The library also supports reading and writing files in gzip (.gz) format
8629+ with an interface similar to that of stdio.
8630+
8631+ The library does not install any signal handler. The decoder checks
8632+ the consistency of the compressed data, so the library should never
8633+ crash even in case of corrupted input.
8634+*/
8635+
8636+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
8637+typedef void (*free_func) OF((voidpf opaque, voidpf address));
8638+
8639+struct internal_state;
8640+
8641+typedef struct z_stream_s {
8642+ Bytef *next_in; /* next input byte */
8643+ uInt avail_in; /* number of bytes available at next_in */
8644+ uLong total_in; /* total nb of input bytes read so far */
8645+
8646+ Bytef *next_out; /* next output byte should be put there */
8647+ uInt avail_out; /* remaining free space at next_out */
8648+ uLong total_out; /* total nb of bytes output so far */
8649+
8650+ const char *msg; /* last error message, NULL if no error */
8651+ struct internal_state FAR *state; /* not visible by applications */
8652+
8653+ alloc_func zalloc; /* used to allocate the internal state */
8654+ free_func zfree; /* used to free the internal state */
8655+ voidpf opaque; /* private data object passed to zalloc and zfree */
8656+
8657+ int data_type; /* best guess about the data type: ascii or binary */
8658+ uLong adler; /* adler32 value of the uncompressed data */
8659+ uLong reserved; /* reserved for future use */
8660+} z_stream;
8661+
8662+typedef z_stream FAR *z_streamp;
8663+
8664+/*
8665+ The application must update next_in and avail_in when avail_in has
8666+ dropped to zero. It must update next_out and avail_out when avail_out
8667+ has dropped to zero. The application must initialize zalloc, zfree and
8668+ opaque before calling the init function. All other fields are set by the
8669+ compression library and must not be updated by the application.
8670+
8671+ The opaque value provided by the application will be passed as the first
8672+ parameter for calls of zalloc and zfree. This can be useful for custom
8673+ memory management. The compression library attaches no meaning to the
8674+ opaque value.
8675+
8676+ zalloc must return Z_NULL if there is not enough memory for the object.
8677+ If zlib is used in a multi-threaded application, zalloc and zfree must be
8678+ thread safe.
8679+
8680+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
8681+ exactly 65536 bytes, but will not be required to allocate more than this
8682+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
8683+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
8684+ have their offset normalized to zero. The default allocation function
8685+ provided by this library ensures this (see zutil.c). To reduce memory
8686+ requirements and avoid any allocation of 64K objects, at the expense of
8687+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
8688+
8689+ The fields total_in and total_out can be used for statistics or
8690+ progress reports. After compression, total_in holds the total size of
8691+ the uncompressed data and may be saved for use in the decompressor
8692+ (particularly if the decompressor wants to decompress everything in
8693+ a single step).
8694+*/
8695+
8696+ /* constants */
8697+
8698+#define Z_NO_FLUSH 0
8699+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
8700+#define Z_SYNC_FLUSH 2
8701+#define Z_FULL_FLUSH 3
8702+#define Z_FINISH 4
8703+/* Allowed flush values; see deflate() below for details */
8704+
8705+#define Z_OK 0
8706+#define Z_STREAM_END 1
8707+#define Z_NEED_DICT 2
8708+#define Z_ERRNO (-1)
8709+#define Z_STREAM_ERROR (-2)
8710+#define Z_DATA_ERROR (-3)
8711+#define Z_MEM_ERROR (-4)
8712+#define Z_BUF_ERROR (-5)
8713+#define Z_VERSION_ERROR (-6)
8714+/* Return codes for the compression/decompression functions. Negative
8715+ * values are errors, positive values are used for special but normal events.
8716+ */
8717+
8718+#define Z_NO_COMPRESSION 0
8719+#define Z_BEST_SPEED 1
8720+#define Z_BEST_COMPRESSION 9
8721+#define Z_DEFAULT_COMPRESSION (-1)
8722+/* compression levels */
8723+
8724+#define Z_FILTERED 1
8725+#define Z_HUFFMAN_ONLY 2
8726+#define Z_DEFAULT_STRATEGY 0
8727+/* compression strategy; see deflateInit2() below for details */
8728+
8729+#define Z_BINARY 0
8730+#define Z_ASCII 1
8731+#define Z_UNKNOWN 2
8732+/* Possible values of the data_type field */
8733+
8734+#define Z_DEFLATED 8
8735+/* The deflate compression method (the only one supported in this version) */
8736+
8737+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
8738+
8739+#define zlib_version zlibVersion()
8740+/* for compatibility with versions < 1.0.2 */
8741+
8742+ /* basic functions */
8743+
8744+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
8745+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
8746+ If the first character differs, the library code actually used is
8747+ not compatible with the zlib.h header file used by the application.
8748+ This check is automatically made by deflateInit and inflateInit.
8749+ */
8750+
8751+/*
8752+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
8753+
8754+ Initializes the internal stream state for compression. The fields
8755+ zalloc, zfree and opaque must be initialized before by the caller.
8756+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
8757+ use default allocation functions.
8758+
8759+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
8760+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
8761+ all (the input data is simply copied a block at a time).
8762+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
8763+ compression (currently equivalent to level 6).
8764+
8765+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
8766+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
8767+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
8768+ with the version assumed by the caller (ZLIB_VERSION).
8769+ msg is set to null if there is no error message. deflateInit does not
8770+ perform any compression: this will be done by deflate().
8771+*/
8772+
8773+
8774+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
8775+/*
8776+ deflate compresses as much data as possible, and stops when the input
8777+ buffer becomes empty or the output buffer becomes full. It may introduce some
8778+ output latency (reading input without producing any output) except when
8779+ forced to flush.
8780+
8781+ The detailed semantics are as follows. deflate performs one or both of the
8782+ following actions:
8783+
8784+ - Compress more input starting at next_in and update next_in and avail_in
8785+ accordingly. If not all input can be processed (because there is not
8786+ enough room in the output buffer), next_in and avail_in are updated and
8787+ processing will resume at this point for the next call of deflate().
8788+
8789+ - Provide more output starting at next_out and update next_out and avail_out
8790+ accordingly. This action is forced if the parameter flush is non zero.
8791+ Forcing flush frequently degrades the compression ratio, so this parameter
8792+ should be set only when necessary (in interactive applications).
8793+ Some output may be provided even if flush is not set.
8794+
8795+ Before the call of deflate(), the application should ensure that at least
8796+ one of the actions is possible, by providing more input and/or consuming
8797+ more output, and updating avail_in or avail_out accordingly; avail_out
8798+ should never be zero before the call. The application can consume the
8799+ compressed output when it wants, for example when the output buffer is full
8800+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
8801+ and with zero avail_out, it must be called again after making room in the
8802+ output buffer because there might be more output pending.
8803+
8804+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
8805+ flushed to the output buffer and the output is aligned on a byte boundary, so
8806+ that the decompressor can get all input data available so far. (In particular
8807+ avail_in is zero after the call if enough output space has been provided
8808+ before the call.) Flushing may degrade compression for some compression
8809+ algorithms and so it should be used only when necessary.
8810+
8811+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
8812+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
8813+ restart from this point if previous compressed data has been damaged or if
8814+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
8815+ the compression.
8816+
8817+ If deflate returns with avail_out == 0, this function must be called again
8818+ with the same value of the flush parameter and more output space (updated
8819+ avail_out), until the flush is complete (deflate returns with non-zero
8820+ avail_out).
8821+
8822+ If the parameter flush is set to Z_FINISH, pending input is processed,
8823+ pending output is flushed and deflate returns with Z_STREAM_END if there
8824+ was enough output space; if deflate returns with Z_OK, this function must be
8825+ called again with Z_FINISH and more output space (updated avail_out) but no
8826+ more input data, until it returns with Z_STREAM_END or an error. After
8827+ deflate has returned Z_STREAM_END, the only possible operations on the
8828+ stream are deflateReset or deflateEnd.
8829+
8830+ Z_FINISH can be used immediately after deflateInit if all the compression
8831+ is to be done in a single step. In this case, avail_out must be at least
8832+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
8833+ Z_STREAM_END, then it must be called again as described above.
8834+
8835+ deflate() sets strm->adler to the adler32 checksum of all input read
8836+ so far (that is, total_in bytes).
8837+
8838+ deflate() may update data_type if it can make a good guess about
8839+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
8840+ binary. This field is only for information purposes and does not affect
8841+ the compression algorithm in any manner.
8842+
8843+ deflate() returns Z_OK if some progress has been made (more input
8844+ processed or more output produced), Z_STREAM_END if all input has been
8845+ consumed and all output has been produced (only when flush is set to
8846+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
8847+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
8848+ (for example avail_in or avail_out was zero).
8849+*/
8850+
8851+
8852+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
8853+/*
8854+ All dynamically allocated data structures for this stream are freed.
8855+ This function discards any unprocessed input and does not flush any
8856+ pending output.
8857+
8858+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
8859+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
8860+ prematurely (some input or output was discarded). In the error case,
8861+ msg may be set but then points to a static string (which must not be
8862+ deallocated).
8863+*/
8864+
8865+
8866+/*
8867+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
8868+
8869+ Initializes the internal stream state for decompression. The fields
8870+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
8871+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
8872+ value depends on the compression method), inflateInit determines the
8873+ compression method from the zlib header and allocates all data structures
8874+ accordingly; otherwise the allocation will be deferred to the first call of
8875+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
8876+ use default allocation functions.
8877+
8878+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
8879+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
8880+ version assumed by the caller. msg is set to null if there is no error
8881+ message. inflateInit does not perform any decompression apart from reading
8882+ the zlib header if present: this will be done by inflate(). (So next_in and
8883+ avail_in may be modified, but next_out and avail_out are unchanged.)
8884+*/
8885+
8886+
8887+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
8888+/*
8889+ inflate decompresses as much data as possible, and stops when the input
8890+ buffer becomes empty or the output buffer becomes full. It may some
8891+ introduce some output latency (reading input without producing any output)
8892+ except when forced to flush.
8893+
8894+ The detailed semantics are as follows. inflate performs one or both of the
8895+ following actions:
8896+
8897+ - Decompress more input starting at next_in and update next_in and avail_in
8898+ accordingly. If not all input can be processed (because there is not
8899+ enough room in the output buffer), next_in is updated and processing
8900+ will resume at this point for the next call of inflate().
8901+
8902+ - Provide more output starting at next_out and update next_out and avail_out
8903+ accordingly. inflate() provides as much output as possible, until there
8904+ is no more input data or no more space in the output buffer (see below
8905+ about the flush parameter).
8906+
8907+ Before the call of inflate(), the application should ensure that at least
8908+ one of the actions is possible, by providing more input and/or consuming
8909+ more output, and updating the next_* and avail_* values accordingly.
8910+ The application can consume the uncompressed output when it wants, for
8911+ example when the output buffer is full (avail_out == 0), or after each
8912+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
8913+ must be called again after making room in the output buffer because there
8914+ might be more output pending.
8915+
8916+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
8917+ output as possible to the output buffer. The flushing behavior of inflate is
8918+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
8919+ and Z_FINISH, but the current implementation actually flushes as much output
8920+ as possible anyway.
8921+
8922+ inflate() should normally be called until it returns Z_STREAM_END or an
8923+ error. However if all decompression is to be performed in a single step
8924+ (a single call of inflate), the parameter flush should be set to
8925+ Z_FINISH. In this case all pending input is processed and all pending
8926+ output is flushed; avail_out must be large enough to hold all the
8927+ uncompressed data. (The size of the uncompressed data may have been saved
8928+ by the compressor for this purpose.) The next operation on this stream must
8929+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
8930+ is never required, but can be used to inform inflate that a faster routine
8931+ may be used for the single inflate() call.
8932+
8933+ If a preset dictionary is needed at this point (see inflateSetDictionary
8934+ below), inflate sets strm-adler to the adler32 checksum of the
8935+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
8936+ it sets strm->adler to the adler32 checksum of all output produced
8937+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
8938+ an error code as described below. At the end of the stream, inflate()
8939+ checks that its computed adler32 checksum is equal to that saved by the
8940+ compressor and returns Z_STREAM_END only if the checksum is correct.
8941+
8942+ inflate() returns Z_OK if some progress has been made (more input processed
8943+ or more output produced), Z_STREAM_END if the end of the compressed data has
8944+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
8945+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
8946+ corrupted (input stream not conforming to the zlib format or incorrect
8947+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
8948+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
8949+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
8950+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
8951+ case, the application may then call inflateSync to look for a good
8952+ compression block.
8953+*/
8954+
8955+
8956+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
8957+/*
8958+ All dynamically allocated data structures for this stream are freed.
8959+ This function discards any unprocessed input and does not flush any
8960+ pending output.
8961+
8962+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
8963+ was inconsistent. In the error case, msg may be set but then points to a
8964+ static string (which must not be deallocated).
8965+*/
8966+
8967+ /* Advanced functions */
8968+
8969+/*
8970+ The following functions are needed only in some special applications.
8971+*/
8972+
8973+/*
8974+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
8975+ int level,
8976+ int method,
8977+ int windowBits,
8978+ int memLevel,
8979+ int strategy));
8980+
8981+ This is another version of deflateInit with more compression options. The
8982+ fields next_in, zalloc, zfree and opaque must be initialized before by
8983+ the caller.
8984+
8985+ The method parameter is the compression method. It must be Z_DEFLATED in
8986+ this version of the library.
8987+
8988+ The windowBits parameter is the base two logarithm of the window size
8989+ (the size of the history buffer). It should be in the range 8..15 for this
8990+ version of the library. Larger values of this parameter result in better
8991+ compression at the expense of memory usage. The default value is 15 if
8992+ deflateInit is used instead.
8993+
8994+ The memLevel parameter specifies how much memory should be allocated
8995+ for the internal compression state. memLevel=1 uses minimum memory but
8996+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
8997+ for optimal speed. The default value is 8. See zconf.h for total memory
8998+ usage as a function of windowBits and memLevel.
8999+
9000+ The strategy parameter is used to tune the compression algorithm. Use the
9001+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
9002+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
9003+ string match). Filtered data consists mostly of small values with a
9004+ somewhat random distribution. In this case, the compression algorithm is
9005+ tuned to compress them better. The effect of Z_FILTERED is to force more
9006+ Huffman coding and less string matching; it is somewhat intermediate
9007+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
9008+ the compression ratio but not the correctness of the compressed output even
9009+ if it is not set appropriately.
9010+
9011+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9012+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
9013+ method). msg is set to null if there is no error message. deflateInit2 does
9014+ not perform any compression: this will be done by deflate().
9015+*/
9016+
9017+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
9018+ const Bytef *dictionary,
9019+ uInt dictLength));
9020+/*
9021+ Initializes the compression dictionary from the given byte sequence
9022+ without producing any compressed output. This function must be called
9023+ immediately after deflateInit, deflateInit2 or deflateReset, before any
9024+ call of deflate. The compressor and decompressor must use exactly the same
9025+ dictionary (see inflateSetDictionary).
9026+
9027+ The dictionary should consist of strings (byte sequences) that are likely
9028+ to be encountered later in the data to be compressed, with the most commonly
9029+ used strings preferably put towards the end of the dictionary. Using a
9030+ dictionary is most useful when the data to be compressed is short and can be
9031+ predicted with good accuracy; the data can then be compressed better than
9032+ with the default empty dictionary.
9033+
9034+ Depending on the size of the compression data structures selected by
9035+ deflateInit or deflateInit2, a part of the dictionary may in effect be
9036+ discarded, for example if the dictionary is larger than the window size in
9037+ deflate or deflate2. Thus the strings most likely to be useful should be
9038+ put at the end of the dictionary, not at the front.
9039+
9040+ Upon return of this function, strm->adler is set to the Adler32 value
9041+ of the dictionary; the decompressor may later use this value to determine
9042+ which dictionary has been used by the compressor. (The Adler32 value
9043+ applies to the whole dictionary even if only a subset of the dictionary is
9044+ actually used by the compressor.)
9045+
9046+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
9047+ parameter is invalid (such as NULL dictionary) or the stream state is
9048+ inconsistent (for example if deflate has already been called for this stream
9049+ or if the compression method is bsort). deflateSetDictionary does not
9050+ perform any compression: this will be done by deflate().
9051+*/
9052+
9053+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
9054+ z_streamp source));
9055+/*
9056+ Sets the destination stream as a complete copy of the source stream.
9057+
9058+ This function can be useful when several compression strategies will be
9059+ tried, for example when there are several ways of pre-processing the input
9060+ data with a filter. The streams that will be discarded should then be freed
9061+ by calling deflateEnd. Note that deflateCopy duplicates the internal
9062+ compression state which can be quite large, so this strategy is slow and
9063+ can consume lots of memory.
9064+
9065+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
9066+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
9067+ (such as zalloc being NULL). msg is left unchanged in both source and
9068+ destination.
9069+*/
9070+
9071+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
9072+/*
9073+ This function is equivalent to deflateEnd followed by deflateInit,
9074+ but does not free and reallocate all the internal compression state.
9075+ The stream will keep the same compression level and any other attributes
9076+ that may have been set by deflateInit2.
9077+
9078+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9079+ stream state was inconsistent (such as zalloc or state being NULL).
9080+*/
9081+
9082+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
9083+ int level,
9084+ int strategy));
9085+/*
9086+ Dynamically update the compression level and compression strategy. The
9087+ interpretation of level and strategy is as in deflateInit2. This can be
9088+ used to switch between compression and straight copy of the input data, or
9089+ to switch to a different kind of input data requiring a different
9090+ strategy. If the compression level is changed, the input available so far
9091+ is compressed with the old level (and may be flushed); the new level will
9092+ take effect only at the next call of deflate().
9093+
9094+ Before the call of deflateParams, the stream state must be set as for
9095+ a call of deflate(), since the currently available input may have to
9096+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
9097+
9098+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
9099+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
9100+ if strm->avail_out was zero.
9101+*/
9102+
9103+/*
9104+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
9105+ int windowBits));
9106+
9107+ This is another version of inflateInit with an extra parameter. The
9108+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
9109+ before by the caller.
9110+
9111+ The windowBits parameter is the base two logarithm of the maximum window
9112+ size (the size of the history buffer). It should be in the range 8..15 for
9113+ this version of the library. The default value is 15 if inflateInit is used
9114+ instead. If a compressed stream with a larger window size is given as
9115+ input, inflate() will return with the error code Z_DATA_ERROR instead of
9116+ trying to allocate a larger window.
9117+
9118+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9119+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
9120+ memLevel). msg is set to null if there is no error message. inflateInit2
9121+ does not perform any decompression apart from reading the zlib header if
9122+ present: this will be done by inflate(). (So next_in and avail_in may be
9123+ modified, but next_out and avail_out are unchanged.)
9124+*/
9125+
9126+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
9127+ const Bytef *dictionary,
9128+ uInt dictLength));
9129+/*
9130+ Initializes the decompression dictionary from the given uncompressed byte
9131+ sequence. This function must be called immediately after a call of inflate
9132+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
9133+ can be determined from the Adler32 value returned by this call of
9134+ inflate. The compressor and decompressor must use exactly the same
9135+ dictionary (see deflateSetDictionary).
9136+
9137+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
9138+ parameter is invalid (such as NULL dictionary) or the stream state is
9139+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
9140+ expected one (incorrect Adler32 value). inflateSetDictionary does not
9141+ perform any decompression: this will be done by subsequent calls of
9142+ inflate().
9143+*/
9144+
9145+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
9146+/*
9147+ Skips invalid compressed data until a full flush point (see above the
9148+ description of deflate with Z_FULL_FLUSH) can be found, or until all
9149+ available input is skipped. No output is provided.
9150+
9151+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
9152+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
9153+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
9154+ case, the application may save the current current value of total_in which
9155+ indicates where valid compressed data was found. In the error case, the
9156+ application may repeatedly call inflateSync, providing more input each time,
9157+ until success or end of the input data.
9158+*/
9159+
9160+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
9161+/*
9162+ This function is equivalent to inflateEnd followed by inflateInit,
9163+ but does not free and reallocate all the internal decompression state.
9164+ The stream will keep attributes that may have been set by inflateInit2.
9165+
9166+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9167+ stream state was inconsistent (such as zalloc or state being NULL).
9168+*/
9169+
9170+
9171+ /* utility functions */
9172+
9173+/*
9174+ The following utility functions are implemented on top of the
9175+ basic stream-oriented functions. To simplify the interface, some
9176+ default options are assumed (compression level and memory usage,
9177+ standard memory allocation functions). The source code of these
9178+ utility functions can easily be modified if you need special options.
9179+*/
9180+
9181+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
9182+ const Bytef *source, uLong sourceLen));
9183+/*
9184+ Compresses the source buffer into the destination buffer. sourceLen is
9185+ the byte length of the source buffer. Upon entry, destLen is the total
9186+ size of the destination buffer, which must be at least 0.1% larger than
9187+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
9188+ compressed buffer.
9189+ This function can be used to compress a whole file at once if the
9190+ input file is mmap'ed.
9191+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
9192+ enough memory, Z_BUF_ERROR if there was not enough room in the output
9193+ buffer.
9194+*/
9195+
9196+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
9197+ const Bytef *source, uLong sourceLen,
9198+ int level));
9199+/*
9200+ Compresses the source buffer into the destination buffer. The level
9201+ parameter has the same meaning as in deflateInit. sourceLen is the byte
9202+ length of the source buffer. Upon entry, destLen is the total size of the
9203+ destination buffer, which must be at least 0.1% larger than sourceLen plus
9204+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
9205+
9206+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9207+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
9208+ Z_STREAM_ERROR if the level parameter is invalid.
9209+*/
9210+
9211+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
9212+ const Bytef *source, uLong sourceLen));
9213+/*
9214+ Decompresses the source buffer into the destination buffer. sourceLen is
9215+ the byte length of the source buffer. Upon entry, destLen is the total
9216+ size of the destination buffer, which must be large enough to hold the
9217+ entire uncompressed data. (The size of the uncompressed data must have
9218+ been saved previously by the compressor and transmitted to the decompressor
9219+ by some mechanism outside the scope of this compression library.)
9220+ Upon exit, destLen is the actual size of the compressed buffer.
9221+ This function can be used to decompress a whole file at once if the
9222+ input file is mmap'ed.
9223+
9224+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
9225+ enough memory, Z_BUF_ERROR if there was not enough room in the output
9226+ buffer, or Z_DATA_ERROR if the input data was corrupted.
9227+*/
9228+
9229+
9230+typedef voidp gzFile;
9231+
9232+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
9233+/*
9234+ Opens a gzip (.gz) file for reading or writing. The mode parameter
9235+ is as in fopen ("rb" or "wb") but can also include a compression level
9236+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
9237+ Huffman only compression as in "wb1h". (See the description
9238+ of deflateInit2 for more information about the strategy parameter.)
9239+
9240+ gzopen can be used to read a file which is not in gzip format; in this
9241+ case gzread will directly read from the file without decompression.
9242+
9243+ gzopen returns NULL if the file could not be opened or if there was
9244+ insufficient memory to allocate the (de)compression state; errno
9245+ can be checked to distinguish the two cases (if errno is zero, the
9246+ zlib error is Z_MEM_ERROR). */
9247+
9248+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
9249+/*
9250+ gzdopen() associates a gzFile with the file descriptor fd. File
9251+ descriptors are obtained from calls like open, dup, creat, pipe or
9252+ fileno (in the file has been previously opened with fopen).
9253+ The mode parameter is as in gzopen.
9254+ The next call of gzclose on the returned gzFile will also close the
9255+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
9256+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
9257+ gzdopen returns NULL if there was insufficient memory to allocate
9258+ the (de)compression state.
9259+*/
9260+
9261+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
9262+/*
9263+ Dynamically update the compression level or strategy. See the description
9264+ of deflateInit2 for the meaning of these parameters.
9265+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
9266+ opened for writing.
9267+*/
9268+
9269+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
9270+/*
9271+ Reads the given number of uncompressed bytes from the compressed file.
9272+ If the input file was not in gzip format, gzread copies the given number
9273+ of bytes into the buffer.
9274+ gzread returns the number of uncompressed bytes actually read (0 for
9275+ end of file, -1 for error). */
9276+
9277+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
9278+ const voidp buf, unsigned len));
9279+/*
9280+ Writes the given number of uncompressed bytes into the compressed file.
9281+ gzwrite returns the number of uncompressed bytes actually written
9282+ (0 in case of error).
9283+*/
9284+
9285+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
9286+/*
9287+ Converts, formats, and writes the args to the compressed file under
9288+ control of the format string, as in fprintf. gzprintf returns the number of
9289+ uncompressed bytes actually written (0 in case of error).
9290+*/
9291+
9292+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
9293+/*
9294+ Writes the given null-terminated string to the compressed file, excluding
9295+ the terminating null character.
9296+ gzputs returns the number of characters written, or -1 in case of error.
9297+*/
9298+
9299+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
9300+/*
9301+ Reads bytes from the compressed file until len-1 characters are read, or
9302+ a newline character is read and transferred to buf, or an end-of-file
9303+ condition is encountered. The string is then terminated with a null
9304+ character.
9305+ gzgets returns buf, or Z_NULL in case of error.
9306+*/
9307+
9308+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
9309+/*
9310+ Writes c, converted to an unsigned char, into the compressed file.
9311+ gzputc returns the value that was written, or -1 in case of error.
9312+*/
9313+
9314+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
9315+/*
9316+ Reads one byte from the compressed file. gzgetc returns this byte
9317+ or -1 in case of end of file or error.
9318+*/
9319+
9320+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
9321+/*
9322+ Flushes all pending output into the compressed file. The parameter
9323+ flush is as in the deflate() function. The return value is the zlib
9324+ error number (see function gzerror below). gzflush returns Z_OK if
9325+ the flush parameter is Z_FINISH and all output could be flushed.
9326+ gzflush should be called only when strictly necessary because it can
9327+ degrade compression.
9328+*/
9329+
9330+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
9331+ z_off_t offset, int whence));
9332+/*
9333+ Sets the starting position for the next gzread or gzwrite on the
9334+ given compressed file. The offset represents a number of bytes in the
9335+ uncompressed data stream. The whence parameter is defined as in lseek(2);
9336+ the value SEEK_END is not supported.
9337+ If the file is opened for reading, this function is emulated but can be
9338+ extremely slow. If the file is opened for writing, only forward seeks are
9339+ supported; gzseek then compresses a sequence of zeroes up to the new
9340+ starting position.
9341+
9342+ gzseek returns the resulting offset location as measured in bytes from
9343+ the beginning of the uncompressed stream, or -1 in case of error, in
9344+ particular if the file is opened for writing and the new starting position
9345+ would be before the current position.
9346+*/
9347+
9348+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
9349+/*
9350+ Rewinds the given file. This function is supported only for reading.
9351+
9352+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
9353+*/
9354+
9355+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
9356+/*
9357+ Returns the starting position for the next gzread or gzwrite on the
9358+ given compressed file. This position represents a number of bytes in the
9359+ uncompressed data stream.
9360+
9361+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
9362+*/
9363+
9364+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
9365+/*
9366+ Returns 1 when EOF has previously been detected reading the given
9367+ input stream, otherwise zero.
9368+*/
9369+
9370+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
9371+/*
9372+ Flushes all pending output if necessary, closes the compressed file
9373+ and deallocates all the (de)compression state. The return value is the zlib
9374+ error number (see function gzerror below).
9375+*/
9376+
9377+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
9378+/*
9379+ Returns the error message for the last error which occurred on the
9380+ given compressed file. errnum is set to zlib error number. If an
9381+ error occurred in the file system and not in the compression library,
9382+ errnum is set to Z_ERRNO and the application may consult errno
9383+ to get the exact error code.
9384+*/
9385+
9386+ /* checksum functions */
9387+
9388+/*
9389+ These functions are not related to compression but are exported
9390+ anyway because they might be useful in applications using the
9391+ compression library.
9392+*/
9393+
9394+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
9395+
9396+/*
9397+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
9398+ return the updated checksum. If buf is NULL, this function returns
9399+ the required initial value for the checksum.
9400+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
9401+ much faster. Usage example:
9402+
9403+ uLong adler = adler32(0L, Z_NULL, 0);
9404+
9405+ while (read_buffer(buffer, length) != EOF) {
9406+ adler = adler32(adler, buffer, length);
9407+ }
9408+ if (adler != original_adler) error();
9409+*/
9410+
9411+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
9412+/*
9413+ Update a running crc with the bytes buf[0..len-1] and return the updated
9414+ crc. If buf is NULL, this function returns the required initial value
9415+ for the crc. Pre- and post-conditioning (one's complement) is performed
9416+ within this function so it shouldn't be done by the application.
9417+ Usage example:
9418+
9419+ uLong crc = crc32(0L, Z_NULL, 0);
9420+
9421+ while (read_buffer(buffer, length) != EOF) {
9422+ crc = crc32(crc, buffer, length);
9423+ }
9424+ if (crc != original_crc) error();
9425+*/
9426+
9427+
9428+ /* various hacks, don't look :) */
9429+
9430+/* deflateInit and inflateInit are macros to allow checking the zlib version
9431+ * and the compiler's view of z_stream:
9432+ */
9433+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
9434+ const char *version, int stream_size));
9435+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
9436+ const char *version, int stream_size));
9437+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
9438+ int windowBits, int memLevel,
9439+ int strategy, const char *version,
9440+ int stream_size));
9441+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
9442+ const char *version, int stream_size));
9443+#define deflateInit(strm, level) \
9444+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
9445+#define inflateInit(strm) \
9446+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
9447+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
9448+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
9449+ (strategy), ZLIB_VERSION, sizeof(z_stream))
9450+#define inflateInit2(strm, windowBits) \
9451+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
9452+
9453+
9454+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
9455+ struct internal_state {int dummy;}; /* hack for buggy compilers */
9456+#endif
9457+
9458+ZEXTERN const char * ZEXPORT zError OF((int err));
9459+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
9460+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
9461+
9462+#ifdef __cplusplus
9463+}
9464+#endif
9465+
9466+#endif /* _ZLIB_H */
9467--- /dev/null Tue Mar 11 13:02:56 2003
9468+++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004
9469@@ -0,0 +1,225 @@
9470+/* zutil.h -- internal interface and configuration of the compression library
9471+ * Copyright (C) 1995-2002 Jean-loup Gailly.
9472+ * For conditions of distribution and use, see copyright notice in zlib.h
9473+ */
9474+
9475+/* WARNING: this file should *not* be used by applications. It is
9476+ part of the implementation of the compression library and is
9477+ subject to change. Applications should only use zlib.h.
9478+ */
9479+
9480+/* @(#) $Id: zutil.h,v 1.4 2002/04/24 07:36:48 mcr Exp $ */
9481+
9482+#ifndef _Z_UTIL_H
9483+#define _Z_UTIL_H
9484+
9485+#include "zlib.h"
9486+
9487+#include <linux/string.h>
9488+#define HAVE_MEMCPY
9489+
9490+#if 0 // #ifdef STDC
9491+# include <stddef.h>
9492+# include <string.h>
9493+# include <stdlib.h>
9494+#endif
9495+#ifndef __KERNEL__
9496+#ifdef NO_ERRNO_H
9497+ extern int errno;
9498+#else
9499+# include <errno.h>
9500+#endif
9501+#endif
9502+
9503+#ifndef local
9504+# define local static
9505+#endif
9506+/* compile with -Dlocal if your debugger can't find static symbols */
9507+
9508+typedef unsigned char uch;
9509+typedef uch FAR uchf;
9510+typedef unsigned short ush;
9511+typedef ush FAR ushf;
9512+typedef unsigned long ulg;
9513+
9514+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
9515+/* (size given to avoid silly warnings with Visual C++) */
9516+
9517+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
9518+
9519+#define ERR_RETURN(strm,err) \
9520+ return (strm->msg = ERR_MSG(err), (err))
9521+/* To be used only when the state is known to be valid */
9522+
9523+ /* common constants */
9524+
9525+#ifndef DEF_WBITS
9526+# define DEF_WBITS MAX_WBITS
9527+#endif
9528+/* default windowBits for decompression. MAX_WBITS is for compression only */
9529+
9530+#if MAX_MEM_LEVEL >= 8
9531+# define DEF_MEM_LEVEL 8
9532+#else
9533+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
9534+#endif
9535+/* default memLevel */
9536+
9537+#define STORED_BLOCK 0
9538+#define STATIC_TREES 1
9539+#define DYN_TREES 2
9540+/* The three kinds of block type */
9541+
9542+#define MIN_MATCH 3
9543+#define MAX_MATCH 258
9544+/* The minimum and maximum match lengths */
9545+
9546+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
9547+
9548+ /* target dependencies */
9549+
9550+#ifdef MSDOS
9551+# define OS_CODE 0x00
9552+# if defined(__TURBOC__) || defined(__BORLANDC__)
9553+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
9554+ /* Allow compilation with ANSI keywords only enabled */
9555+ void _Cdecl farfree( void *block );
9556+ void *_Cdecl farmalloc( unsigned long nbytes );
9557+# else
9558+# include <alloc.h>
9559+# endif
9560+# else /* MSC or DJGPP */
9561+# include <malloc.h>
9562+# endif
9563+#endif
9564+
9565+#ifdef OS2
9566+# define OS_CODE 0x06
9567+#endif
9568+
9569+#ifdef WIN32 /* Window 95 & Windows NT */
9570+# define OS_CODE 0x0b
9571+#endif
9572+
9573+#if defined(VAXC) || defined(VMS)
9574+# define OS_CODE 0x02
9575+# define F_OPEN(name, mode) \
9576+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
9577+#endif
9578+
9579+#ifdef AMIGA
9580+# define OS_CODE 0x01
9581+#endif
9582+
9583+#if defined(ATARI) || defined(atarist)
9584+# define OS_CODE 0x05
9585+#endif
9586+
9587+#if defined(MACOS) || defined(TARGET_OS_MAC)
9588+# define OS_CODE 0x07
9589+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
9590+# include <unix.h> /* for fdopen */
9591+# else
9592+# ifndef fdopen
9593+# define fdopen(fd,mode) NULL /* No fdopen() */
9594+# endif
9595+# endif
9596+#endif
9597+
9598+#ifdef __50SERIES /* Prime/PRIMOS */
9599+# define OS_CODE 0x0F
9600+#endif
9601+
9602+#ifdef TOPS20
9603+# define OS_CODE 0x0a
9604+#endif
9605+
9606+#if defined(_BEOS_) || defined(RISCOS)
9607+# define fdopen(fd,mode) NULL /* No fdopen() */
9608+#endif
9609+
9610+#if (defined(_MSC_VER) && (_MSC_VER > 600))
9611+# define fdopen(fd,type) _fdopen(fd,type)
9612+#endif
9613+
9614+
9615+ /* Common defaults */
9616+
9617+#ifndef OS_CODE
9618+# define OS_CODE 0x03 /* assume Unix */
9619+#endif
9620+
9621+#ifndef F_OPEN
9622+# define F_OPEN(name, mode) fopen((name), (mode))
9623+#endif
9624+
9625+ /* functions */
9626+
9627+#ifdef HAVE_STRERROR
9628+ extern char *strerror OF((int));
9629+# define zstrerror(errnum) strerror(errnum)
9630+#else
9631+# define zstrerror(errnum) ""
9632+#endif
9633+
9634+#if defined(pyr)
9635+# define NO_MEMCPY
9636+#endif
9637+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
9638+ /* Use our own functions for small and medium model with MSC <= 5.0.
9639+ * You may have to use the same strategy for Borland C (untested).
9640+ * The __SC__ check is for Symantec.
9641+ */
9642+# define NO_MEMCPY
9643+#endif
9644+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
9645+# define HAVE_MEMCPY
9646+#endif
9647+#ifdef HAVE_MEMCPY
9648+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
9649+# define zmemcpy _fmemcpy
9650+# define zmemcmp _fmemcmp
9651+# define zmemzero(dest, len) _fmemset(dest, 0, len)
9652+# else
9653+# define zmemcpy memcpy
9654+# define zmemcmp memcmp
9655+# define zmemzero(dest, len) memset(dest, 0, len)
9656+# endif
9657+#else
9658+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
9659+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
9660+ extern void zmemzero OF((Bytef* dest, uInt len));
9661+#endif
9662+
9663+/* Diagnostic functions */
9664+#ifdef DEBUG
9665+# include <stdio.h>
9666+ extern int z_verbose;
9667+ extern void z_error OF((char *m));
9668+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
9669+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
9670+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
9671+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
9672+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
9673+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
9674+#else
9675+# define Assert(cond,msg)
9676+# define Trace(x)
9677+# define Tracev(x)
9678+# define Tracevv(x)
9679+# define Tracec(c,x)
9680+# define Tracecv(c,x)
9681+#endif
9682+
9683+
9684+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
9685+ uInt len));
9686+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
9687+void zcfree OF((voidpf opaque, voidpf ptr));
9688+
9689+#define ZALLOC(strm, items, size) \
9690+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
9691+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
9692+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
9693+
9694+#endif /* _Z_UTIL_H */
9695--- /dev/null Tue Mar 11 13:02:56 2003
9696+++ linux/lib/libfreeswan/Makefile.objs Mon Feb 9 13:51:03 2004
9697@@ -0,0 +1,21 @@
9698+obj-y += satot.o
9699+obj-y += addrtot.o
9700+obj-y += ultot.o
9701+obj-y += addrtypeof.o
9702+obj-y += anyaddr.o
9703+obj-y += initaddr.o
9704+obj-y += ultoa.o
9705+obj-y += addrtoa.o
9706+obj-y += subnettoa.o
9707+obj-y += subnetof.o
9708+obj-y += goodmask.o
9709+obj-y += datatot.o
9710+obj-y += rangetoa.o
9711+obj-y += prng.o
9712+obj-y += pfkey_v2_parse.o
9713+obj-y += pfkey_v2_build.o
9714+obj-y += pfkey_v2_debug.o
9715+obj-y += pfkey_v2_ext_bits.o
9716+
9717+#version.c: ${LIBFREESWANDIR}/version.in.c ${OPENSWANSRCDIR}/Makefile.ver
9718+# sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@
9719--- /dev/null Tue Mar 11 13:02:56 2003
9720+++ linux/lib/zlib/Makefile Mon Feb 9 13:51:03 2004
9721@@ -0,0 +1,118 @@
9722+# (kernel) Makefile for IPCOMP zlib deflate code
9723+# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
9724+# Copyright (C) 2000 Svenning Soerensen
9725+#
9726+# This program is free software; you can redistribute it and/or modify it
9727+# under the terms of the GNU General Public License as published by the
9728+# Free Software Foundation; either version 2 of the License, or (at your
9729+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9730+#
9731+# This program is distributed in the hope that it will be useful, but
9732+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9733+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9734+# for more details.
9735+#
9736+# RCSID $Id: Makefile,v 1.9 2002/04/24 07:55:32 mcr Exp $
9737+#
9738+
9739+
9740+
9741+include ../Makefile.inc
9742+
9743+
9744+
9745+ifndef TOPDIR
9746+TOPDIR := /usr/src/linux
9747+endif
9748+
9749+
9750+L_TARGET := zlib.a
9751+
9752+obj-y :=
9753+
9754+include Makefile.objs
9755+
9756+EXTRA_CFLAGS += $(KLIPSCOMPILE)
9757+
9758+EXTRA_CFLAGS += -Wall
9759+#EXTRA_CFLAGS += -Wconversion
9760+#EXTRA_CFLAGS += -Wmissing-prototypes
9761+EXTRA_CFLAGS += -Wpointer-arith
9762+#EXTRA_CFLAGS += -Wcast-qual
9763+#EXTRA_CFLAGS += -Wmissing-declarations
9764+EXTRA_CFLAGS += -Wstrict-prototypes
9765+#EXTRA_CFLAGS += -pedantic
9766+#EXTRA_CFLAGS += -W
9767+#EXTRA_CFLAGS += -Wwrite-strings
9768+EXTRA_CFLAGS += -Wbad-function-cast
9769+EXTRA_CFLAGS += -DIPCOMP_PREFIX
9770+
9771+.S.o:
9772+ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o
9773+
9774+asm-obj-$(CONFIG_M586) += match586.o
9775+asm-obj-$(CONFIG_M586TSC) += match586.o
9776+asm-obj-$(CONFIG_M586MMX) += match586.o
9777+asm-obj-$(CONFIG_M686) += match686.o
9778+asm-obj-$(CONFIG_MPENTIUMIII) += match686.o
9779+asm-obj-$(CONFIG_MPENTIUM4) += match686.o
9780+asm-obj-$(CONFIG_MK6) += match586.o
9781+asm-obj-$(CONFIG_MK7) += match686.o
9782+asm-obj-$(CONFIG_MCRUSOE) += match586.o
9783+asm-obj-$(CONFIG_MWINCHIPC6) += match586.o
9784+asm-obj-$(CONFIG_MWINCHIP2) += match686.o
9785+asm-obj-$(CONFIG_MWINCHIP3D) += match686.o
9786+
9787+obj-y += $(asm-obj-y)
9788+ifneq ($(strip $(asm-obj-y)),)
9789+ EXTRA_CFLAGS += -DASMV
9790+endif
9791+
9792+active-objs := $(sort $(obj-y) $(obj-m))
9793+L_OBJS := $(obj-y)
9794+M_OBJS := $(obj-m)
9795+MIX_OBJS := $(filter $(export-objs), $(active-objs))
9796+
9797+include $(TOPDIR)/Rules.make
9798+
9799+$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
9800+
9801+
9802+clean:
9803+ -rm -f *.o *.a
9804+
9805+checkprograms:
9806+programs: $(L_TARGET)
9807+
9808+#
9809+# $Log: Makefile,v $
9810+# Revision 1.9 2002/04/24 07:55:32 mcr
9811+# #include patches and Makefiles for post-reorg compilation.
9812+#
9813+# Revision 1.8 2002/04/24 07:36:44 mcr
9814+# Moved from ./zlib/Makefile,v
9815+#
9816+# Revision 1.7 2002/03/27 23:34:35 mcr
9817+# added programs: target
9818+#
9819+# Revision 1.6 2001/12/05 20:19:08 henry
9820+# use new compile-control variable
9821+#
9822+# Revision 1.5 2001/11/27 16:38:08 mcr
9823+# added new "checkprograms" target to deal with programs that
9824+# are required for "make check", but that may not be ready to
9825+# build for every user due to external dependancies.
9826+#
9827+# Revision 1.4 2001/10/24 14:46:24 henry
9828+# Makefile.inc
9829+#
9830+# Revision 1.3 2001/04/21 23:05:24 rgb
9831+# Update asm directives for 2.4 style makefiles.
9832+#
9833+# Revision 1.2 2001/01/29 22:22:00 rgb
9834+# Convert to 2.4 new style with back compat.
9835+#
9836+# Revision 1.1.1.1 2000/09/29 18:51:33 rgb
9837+# zlib_beginnings
9838+#
9839+#
9840--- /dev/null Tue Mar 11 13:02:56 2003
9841+++ linux/lib/zlib/Makefile.objs Mon Feb 9 13:51:03 2004
9842@@ -0,0 +1,27 @@
9843+obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o
9844+obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o
9845+obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o
9846+obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o
9847+obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o
9848+obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o
9849+obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o
9850+obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o
9851+obj-$(CONFIG_IPSEC_IPCOMP) += trees.o
9852+obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o
9853+
9854+asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o
9855+asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o
9856+asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o
9857+asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o
9858+asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o
9859+asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o
9860+asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o
9861+asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o
9862+asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o
9863+asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o
9864+asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o
9865+asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o
9866+
9867+EXTRA_CFLAGS += -DIPCOMP_PREFIX
9868+
9869+
9870--- swan26/net/Kconfig.preipsec 2005-09-01 18:15:19.000000000 -0400
9871+++ swan26/net/Kconfig 2005-09-03 16:51:17.000000000 -0400
9872@@ -215,2 +215,6 @@
9873
9874+if INET
9875+source "net/ipsec/Kconfig"
9876+endif # if INET
9877+
9878 endif # if NET
9879--- /distros/kernel/linux-2.6.3-rc4/net/Makefile Mon Feb 16 21:22:12 2004
9880+++ ref26/net/Makefile Thu Feb 19 21:02:25 2004
9881@@ -42,3 +42,6 @@
9882 ifeq ($(CONFIG_NET),y)
9883 obj-$(CONFIG_SYSCTL) += sysctl_net.o
9884 endif
9885+
9886+obj-$(CONFIG_KLIPS) += ipsec/
9887+
9888--- /dev/null Tue Mar 11 13:02:56 2003
9889+++ linux/net/ipsec/Kconfig Mon Feb 9 13:51:03 2004
9890@@ -0,0 +1,161 @@
9891+#
9892+# IPSEC configuration
9893+# Copyright (C) 2004 Michael Richardson <mcr@freeswan.org>
9894+#
9895+# This program is free software; you can redistribute it and/or modify it
9896+# under the terms of the GNU General Public License as published by the
9897+# Free Software Foundation; either version 2 of the License, or (at your
9898+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9899+#
9900+# This program is distributed in the hope that it will be useful, but
9901+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9902+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9903+# for more details.
9904+#
9905+# RCSID $Id: Kconfig,v 1.6.2.2 2006/10/11 18:14:33 paul Exp $
9906+
9907+config KLIPS
9908+ tristate "Openswan IPsec (KLIPS26)"
9909+ default n
9910+ help
9911+ KLIPS is the Openswan (www.openswan.org) Kernel Level IP Security
9912+ system. It is extensively tested, and has interoperated with
9913+ many other systems.
9914+ It provides "ipsecX" devices on which one can do firewalling.
9915+ The userland, is compatible with both KLIPS and 26sec.
9916+
9917+menu "KLIPS options"
9918+ depends on KLIPS
9919+
9920+config KLIPS_ESP
9921+ bool 'Encapsulating Security Payload - ESP ("VPN")'
9922+ default y
9923+ help
9924+ This option provides support for the IPSEC Encapsulation Security
9925+ Payload (IP protocol 50) which provides packet layer content
9926+ hiding, and content authentication.
9927+ It is recommended to enable this. RFC2406
9928+
9929+config KLIPS_AH
9930+ bool 'Authentication Header - AH'
9931+ default n
9932+ help
9933+ This option provides support for the IPSEC Authentication Header
9934+ (IP protocol 51) which provides packet layer sender and content
9935+ authentication. It does not provide for confidentiality.
9936+ It is not recommended to enable this. RFC2402
9937+
9938+config KLIPS_AUTH_HMAC_MD5
9939+ bool 'HMAC-MD5 authentication algorithm'
9940+ default y
9941+ help
9942+ The HMAC-MD5 algorithm is used by ESP (and AH) to guarantee packet
9943+ integrity. There is little reason not to include it.
9944+
9945+config KLIPS_AUTH_HMAC_SHA1
9946+ bool 'HMAC-SHA1 authentication algorithm'
9947+ default y
9948+ help
9949+ The HMAC-SHA1 algorithm is used by ESP (and AH) to guarantee packet
9950+ integrity. SHA1 is a little slower than MD5, but is said to be
9951+ a bit more secure. There is little reason not to include it.
9952+
9953+config KLIPS_ENC_CRYPTOAPI
9954+ bool 'CryptoAPI algorithm interface'
9955+ default n
9956+ help
9957+ Enable the algorithm interface to make all CryptoAPI 1.0 algorithms
9958+ available to KLIPS.
9959+
9960+config KLIPS_ENC_1DES
9961+ bool 'Include 1DES with CryptoAPI'
9962+ default n
9963+ depends on KLIPS_ENC_CRYPTOAPI
9964+ help
9965+ The CryptoAPI interface does not include support for every algorithm
9966+ yet, and one that it doesn't support by default is the VERY WEAK
9967+ 1DES. Select this if you are terminally stupid.
9968+
9969+config KLIPS_ENC_3DES
9970+ bool '3DES encryption algorithm'
9971+ default y
9972+ help
9973+ The 3DES algorithm is used by ESP to provide for packet privacy.
9974+ 3DES is 3-repeats of the DES algorithm. 3DES is widely supported,
9975+ and analyzed and is considered very secure. 1DES is not supported.
9976+
9977+config KLIPS_ENC_AES
9978+ bool 'AES encryption algorithm'
9979+ default y
9980+ help
9981+ The AES algorithm is used by ESP to provide for packet privacy.
9982+ AES the NIST replacement for DES. AES is being widely analyzed,
9983+ and is very fast.
9984+
9985+config KLIPS_ENC_NULL
9986+ bool 'NULL NON-encryption algorithm'
9987+ default n
9988+ help
9989+ NON encryption algo , maybe useful for ESP auth only scenarios
9990+ (eg: with NAT-T), see RFC 2410.
9991+
9992+config KLIPS_IPCOMP
9993+ bool 'IP compression'
9994+ default y
9995+ help
9996+ The IPcomp protocol is used prior to ESP to make the packet
9997+ smaller. Once encrypted, compression will fail, so any link
9998+ layer efforts (e.g. PPP) will not work.
9999+
10000+config KLIPS_DEBUG
10001+ bool 'IPsec debugging'
10002+ default y
10003+ help
10004+ KLIPS includes a lot of debugging code. Unless there is a real
10005+ tangible benefit to removing this code, it should be left in place.
10006+ Debugging connections without access to kernel level debugging is
10007+ essentially impossible. Leave this on.
10008+
10009+endmenu
10010+
10011+#
10012+#
10013+# $Log: Kconfig,v $
10014+# Revision 1.6.2.2 2006/10/11 18:14:33 paul
10015+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
10016+# per default.
10017+#
10018+# Revision 1.6.2.1 2006/04/20 16:33:06 mcr
10019+# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
10020+# Fix in-kernel module compilation. Sub-makefiles do not work.
10021+#
10022+# Revision 1.6 2005/05/18 20:55:27 mcr
10023+# default cryptoapi to n.
10024+#
10025+# Revision 1.5 2005/05/11 01:23:25 mcr
10026+# added 1DES option to cryptoapi.
10027+#
10028+# Revision 1.4 2005/04/29 05:29:54 mcr
10029+# add option to include cryptoapi algorithms.
10030+#
10031+# Revision 1.3 2004/08/17 03:27:23 mcr
10032+# klips 2.6 edits.
10033+#
10034+# Revision 1.2 2004/08/14 03:27:39 mcr
10035+# 2.6 kernel build/configuration files.
10036+#
10037+# Revision 1.1 2004/08/14 02:47:55 mcr
10038+# kernel build/config patches
10039+#
10040+# Revision 1.3 2004/02/24 17:17:04 mcr
10041+# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
10042+# turn it on/off as well.
10043+#
10044+# Revision 1.2 2004/02/22 06:50:42 mcr
10045+# kernel 2.6 port - merged with 2.4 code.
10046+#
10047+# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
10048+# module configuration for KLIPS 2.6
10049+#
10050+#
10051+
10052--- /dev/null Tue Mar 11 13:02:56 2003
10053+++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004
10054@@ -0,0 +1,195 @@
10055+# Makefile for KLIPS kernel code as a module for 2.6 kernels
10056+#
10057+# Makefile for KLIPS kernel code as a module
10058+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
10059+# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
10060+#
10061+# This program is free software; you can redistribute it and/or modify it
10062+# under the terms of the GNU General Public License as published by the
10063+# Free Software Foundation; either version 2 of the License, or (at your
10064+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10065+#
10066+# This program is distributed in the hope that it will be useful, but
10067+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10068+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10069+# for more details.
10070+#
10071+# RCSID $Id: Makefile.fs2_6,v 1.8.2.2 2006/10/11 18:14:33 paul Exp $
10072+#
10073+# Note! Dependencies are done automagically by 'make dep', which also
10074+# removes any old dependencies. DON'T put your own dependencies here
10075+# unless it's something special (ie not a .c file).
10076+#
10077+
10078+OPENSWANSRCDIR?=.
10079+KLIPS_TOP?=.
10080+
10081+-include ${OPENSWANSRCDIR}/Makefile.ver
10082+
10083+base-klips-objs :=
10084+
10085+base-klips-objs+= ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
10086+base-klips-objs+= ipsec_life.o ipsec_proc.o
10087+base-klips-objs+= ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
10088+base-klips-objs+= ipsec_snprintf.o
10089+base-klips-objs+= sysctl_net_ipsec.o
10090+base-klips-objs+= pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
10091+base-klips-objs+= version.o
10092+
10093+base-klips-objs+= satot.o
10094+base-klips-objs+= addrtot.o
10095+base-klips-objs+= ultot.o
10096+base-klips-objs+= addrtypeof.o
10097+base-klips-objs+= anyaddr.o
10098+base-klips-objs+= initaddr.o
10099+base-klips-objs+= ultoa.o
10100+base-klips-objs+= addrtoa.o
10101+base-klips-objs+= subnettoa.o
10102+base-klips-objs+= subnetof.o
10103+base-klips-objs+= goodmask.o
10104+base-klips-objs+= datatot.o
10105+base-klips-objs+= rangetoa.o
10106+base-klips-objs+= prng.o
10107+base-klips-objs+= pfkey_v2_parse.o
10108+base-klips-objs+= pfkey_v2_build.o
10109+base-klips-objs+= pfkey_v2_debug.o
10110+base-klips-objs+= pfkey_v2_ext_bits.o
10111+base-klips-objs+= version.o
10112+
10113+obj-${CONFIG_KLIPS} += ipsec.o
10114+
10115+ipsec-objs += ${base-klips-objs}
10116+
10117+ipsec-$(CONFIG_KLIPS_ESP) += ipsec_esp.o
10118+ipsec-$(CONFIG_KLIPS_IPCOMP) += ipsec_ipcomp.o
10119+ipsec-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
10120+ipsec-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
10121+
10122+# AH, if you really think you need it.
10123+ipsec-$(CONFIG_KLIPS_AH) += ipsec_ah.o
10124+
10125+ipsec-y += ipsec_alg.o
10126+
10127+# include code from DES subdir
10128+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ipsec_alg_3des.o
10129+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/cbc_enc.o
10130+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ecb_enc.o
10131+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/set_key.o
10132+
10133+ifeq ($(strip ${SUBARCH}),)
10134+SUBARCH:=${ARCH}
10135+endif
10136+
10137+# the assembly version expects frame pointers, which are
10138+# optional in many kernel builds. If you want speed, you should
10139+# probably use cryptoapi code instead.
10140+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10141+ifeq (${USEASSEMBLY},i386y)
10142+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/dx86unix.o
10143+else
10144+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/des_enc.o
10145+endif
10146+
10147+# include code from AES subdir
10148+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/ipsec_alg_aes.o
10149+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_xcbc_mac.o
10150+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_cbc.o
10151+
10152+ifeq ($(strip ${SUBARCH}),)
10153+SUBARCH:=${ARCH}
10154+endif
10155+
10156+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10157+ifeq (${USEASSEMBLY},i386y)
10158+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes-i586.o
10159+else
10160+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes.o
10161+endif
10162+
10163+crypto-$(CONFIG_KLIPS_ENC_NULL) += null/ipsec_alg_null.o
10164+
10165+ipsec-y += ${crypto-y}
10166+
10167+ipsec-$(CONFIG_KLIPS_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o
10168+
10169+# IPcomp stuff
10170+base-ipcomp-objs := ipcomp.o
10171+base-ipcomp-objs += adler32.o
10172+base-ipcomp-objs += deflate.o
10173+base-ipcomp-objs += infblock.o
10174+base-ipcomp-objs += infcodes.o
10175+base-ipcomp-objs += inffast.o
10176+base-ipcomp-objs += inflate.o
10177+base-ipcomp-objs += inftrees.o
10178+base-ipcomp-objs += infutil.o
10179+base-ipcomp-objs += trees.o
10180+base-ipcomp-objs += zutil.o
10181+asm-ipcomp-obj-$(CONFIG_M586) += match586.o
10182+asm-ipcomp-obj-$(CONFIG_M586TSC) += match586.o
10183+asm-ipcomp-obj-$(CONFIG_M586MMX) += match586.o
10184+asm-ipcomp-obj-$(CONFIG_M686) += match686.o
10185+asm-ipcomp-obj-$(CONFIG_MPENTIUMIII) += match686.o
10186+asm-ipcomp-obj-$(CONFIG_MPENTIUM4) += match686.o
10187+asm-ipcomp-obj-$(CONFIG_MK6) += match586.o
10188+asm-ipcomp-obj-$(CONFIG_MK7) += match686.o
10189+asm-ipcomp-obj-$(CONFIG_MCRUSOE) += match586.o
10190+asm-ipcomp-obj-$(CONFIG_MWINCHIPC6) += match586.o
10191+asm-ipcomp-obj-$(CONFIG_MWINCHIP2) += match686.o
10192+asm-ipcomp-obj-$(CONFIG_MWINCHIP3D) += match686.o
10193+base-ipcomp-objs += ${asm-ipcomp-obj-y}
10194+
10195+ipsec-$(CONFIG_KLIPS_IPCOMP) += ${base-ipcomp-objs}
10196+
10197+EXTRA_CFLAGS += -DIPCOMP_PREFIX
10198+
10199+#
10200+# $Log: Makefile.fs2_6,v $
10201+# Revision 1.8.2.2 2006/10/11 18:14:33 paul
10202+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
10203+# per default.
10204+#
10205+# Revision 1.8.2.1 2006/04/20 16:33:06 mcr
10206+# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
10207+# Fix in-kernel module compilation. Sub-makefiles do not work.
10208+#
10209+# Revision 1.8 2005/05/11 03:15:42 mcr
10210+# adjusted makefiles to sanely build modules properly.
10211+#
10212+# Revision 1.7 2005/04/13 22:52:12 mcr
10213+# moved KLIPS specific snprintf() wrapper to seperate file.
10214+#
10215+# Revision 1.6 2004/08/22 05:02:03 mcr
10216+# organized symbols such that it is easier to build modules.
10217+#
10218+# Revision 1.5 2004/08/18 01:43:56 mcr
10219+# adjusted makefile enumation so that it can be used by module
10220+# wrapper.
10221+#
10222+# Revision 1.4 2004/08/17 03:27:23 mcr
10223+# klips 2.6 edits.
10224+#
10225+# Revision 1.3 2004/08/04 16:50:13 mcr
10226+# removed duplicate definition of dx86unix.o
10227+#
10228+# Revision 1.2 2004/08/03 18:21:09 mcr
10229+# only set KLIPS_TOP and OPENSWANSRCDIR if not already set.
10230+#
10231+# Revision 1.1 2004/07/26 15:02:22 mcr
10232+# makefile for KLIPS module for 2.6.
10233+#
10234+# Revision 1.3 2004/02/24 17:17:04 mcr
10235+# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
10236+# turn it on/off as well.
10237+#
10238+# Revision 1.2 2004/02/22 06:50:42 mcr
10239+# kernel 2.6 port - merged with 2.4 code.
10240+#
10241+# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
10242+# module configuration for KLIPS 2.6
10243+#
10244+#
10245+# Local Variables:
10246+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
10247+# End Variables:
10248+#
10249+
10250--- /dev/null Tue Mar 11 13:02:56 2003
10251+++ linux/net/ipsec/README-zlib Mon Feb 9 13:51:03 2004
10252@@ -0,0 +1,147 @@
10253+zlib 1.1.4 is a general purpose data compression library. All the code
10254+is thread safe. The data format used by the zlib library
10255+is described by RFCs (Request for Comments) 1950 to 1952 in the files
10256+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
10257+format) and rfc1952.txt (gzip format). These documents are also available in
10258+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
10259+
10260+All functions of the compression library are documented in the file zlib.h
10261+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
10262+example of the library is given in the file example.c which also tests that
10263+the library is working correctly. Another example is given in the file
10264+minigzip.c. The compression library itself is composed of all source files
10265+except example.c and minigzip.c.
10266+
10267+To compile all files and run the test program, follow the instructions
10268+given at the top of Makefile. In short "make test; make install"
10269+should work for most machines. For Unix: "./configure; make test; make install"
10270+For MSDOS, use one of the special makefiles such as Makefile.msc.
10271+For VMS, use Make_vms.com or descrip.mms.
10272+
10273+Questions about zlib should be sent to <zlib@gzip.org>, or to
10274+Gilles Vollant <info@winimage.com> for the Windows DLL version.
10275+The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
10276+Before reporting a problem, please check this site to verify that
10277+you have the latest version of zlib; otherwise get the latest version and
10278+check whether the problem still exists or not.
10279+
10280+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
10281+before asking for help.
10282+
10283+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
10284+issue of Dr. Dobb's Journal; a copy of the article is available in
10285+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
10286+
10287+The changes made in version 1.1.4 are documented in the file ChangeLog.
10288+The only changes made since 1.1.3 are bug corrections:
10289+
10290+- ZFREE was repeated on same allocation on some error conditions.
10291+ This creates a security problem described in
10292+ http://www.zlib.org/advisory-2002-03-11.txt
10293+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
10294+- Avoid accesses before window for invalid distances with inflate window
10295+ less than 32K.
10296+- force windowBits > 8 to avoid a bug in the encoder for a window size
10297+ of 256 bytes. (A complete fix will be available in 1.1.5).
10298+
10299+The beta version 1.1.5beta includes many more changes. A new official
10300+version 1.1.5 will be released as soon as extensive testing has been
10301+completed on it.
10302+
10303+
10304+Unsupported third party contributions are provided in directory "contrib".
10305+
10306+A Java implementation of zlib is available in the Java Development Kit
10307+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
10308+See the zlib home page http://www.zlib.org for details.
10309+
10310+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
10311+is in the CPAN (Comprehensive Perl Archive Network) sites
10312+http://www.cpan.org/modules/by-module/Compress/
10313+
10314+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
10315+is available in Python 1.5 and later versions, see
10316+http://www.python.org/doc/lib/module-zlib.html
10317+
10318+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
10319+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
10320+
10321+An experimental package to read and write files in .zip format,
10322+written on top of zlib by Gilles Vollant <info@winimage.com>, is
10323+available at http://www.winimage.com/zLibDll/unzip.html
10324+and also in the contrib/minizip directory of zlib.
10325+
10326+
10327+Notes for some targets:
10328+
10329+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
10330+ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
10331+ The zlib DLL support was initially done by Alessandro Iacopetti and is
10332+ now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
10333+ home page at http://www.winimage.com/zLibDll
10334+
10335+ From Visual Basic, you can call the DLL functions which do not take
10336+ a structure as argument: compress, uncompress and all gz* functions.
10337+ See contrib/visual-basic.txt for more information, or get
10338+ http://www.tcfb.com/dowseware/cmp-z-it.zip
10339+
10340+- For 64-bit Irix, deflate.c must be compiled without any optimization.
10341+ With -O, one libpng test fails. The test works in 32 bit mode (with
10342+ the -n32 compiler flag). The compiler bug has been reported to SGI.
10343+
10344+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
10345+ it works when compiled with cc.
10346+
10347+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
10348+ is necessary to get gzprintf working correctly. This is done by configure.
10349+
10350+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
10351+ with other compilers. Use "make test" to check your compiler.
10352+
10353+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
10354+
10355+- For Turbo C the small model is supported only with reduced performance to
10356+ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
10357+
10358+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
10359+ Per Harald Myrvang <perm@stud.cs.uit.no>
10360+
10361+
10362+Acknowledgments:
10363+
10364+ The deflate format used by zlib was defined by Phil Katz. The deflate
10365+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
10366+ people who reported problems and suggested various improvements in zlib;
10367+ they are too numerous to cite here.
10368+
10369+Copyright notice:
10370+
10371+ (C) 1995-2002 Jean-loup Gailly and Mark Adler
10372+
10373+ This software is provided 'as-is', without any express or implied
10374+ warranty. In no event will the authors be held liable for any damages
10375+ arising from the use of this software.
10376+
10377+ Permission is granted to anyone to use this software for any purpose,
10378+ including commercial applications, and to alter it and redistribute it
10379+ freely, subject to the following restrictions:
10380+
10381+ 1. The origin of this software must not be misrepresented; you must not
10382+ claim that you wrote the original software. If you use this software
10383+ in a product, an acknowledgment in the product documentation would be
10384+ appreciated but is not required.
10385+ 2. Altered source versions must be plainly marked as such, and must not be
10386+ misrepresented as being the original software.
10387+ 3. This notice may not be removed or altered from any source distribution.
10388+
10389+ Jean-loup Gailly Mark Adler
10390+ jloup@gzip.org madler@alumni.caltech.edu
10391+
10392+If you use the zlib library in a product, we would appreciate *not*
10393+receiving lengthy legal documents to sign. The sources are provided
10394+for free but without warranty of any kind. The library has been
10395+entirely written by Jean-loup Gailly and Mark Adler; it does not
10396+include third-party code.
10397+
10398+If you redistribute modified sources, we would appreciate that you include
10399+in the file ChangeLog history information documenting your changes.
10400--- /dev/null Tue Mar 11 13:02:56 2003
10401+++ linux/net/ipsec/README-zlib.freeswan Mon Feb 9 13:51:03 2004
10402@@ -0,0 +1,13 @@
10403+The only changes made to these files for use in FreeS/WAN are:
10404+
10405+ - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
10406+ (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
10407+ - The copyright strings are defined local (static)
10408+
10409+ The above changes are made to avoid name collisions with ppp_deflate
10410+ and ext2compr.
10411+
10412+ - Files not needed for FreeS/WAN have been removed
10413+
10414+ See the "README" file for information about where to obtain the complete
10415+ zlib package.
10416--- /dev/null Tue Mar 11 13:02:56 2003
10417+++ linux/net/ipsec/addrtoa.c Mon Feb 9 13:51:03 2004
10418@@ -0,0 +1,67 @@
10419+/*
10420+ * addresses to ASCII
10421+ * Copyright (C) 1998, 1999 Henry Spencer.
10422+ *
10423+ * This library is free software; you can redistribute it and/or modify it
10424+ * under the terms of the GNU Library General Public License as published by
10425+ * the Free Software Foundation; either version 2 of the License, or (at your
10426+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10427+ *
10428+ * This library is distributed in the hope that it will be useful, but
10429+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10430+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10431+ * License for more details.
10432+ *
10433+ * RCSID $Id: addrtoa.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10434+ */
10435+#include "openswan.h"
10436+
10437+#define NBYTES 4 /* bytes in an address */
10438+#define PERBYTE 4 /* three digits plus a dot or NUL */
10439+#define BUFLEN (NBYTES*PERBYTE)
10440+
10441+#if BUFLEN != ADDRTOA_BUF
10442+#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code"
10443+#endif
10444+
10445+/*
10446+ - addrtoa - convert binary address to ASCII dotted decimal
10447+ */
10448+size_t /* space needed for full conversion */
10449+addrtoa(addr, format, dst, dstlen)
10450+struct in_addr addr;
10451+int format; /* character */
10452+char *dst; /* need not be valid if dstlen is 0 */
10453+size_t dstlen;
10454+{
10455+ unsigned long a = ntohl(addr.s_addr);
10456+ int i;
10457+ size_t n;
10458+ unsigned long byte;
10459+ char buf[BUFLEN];
10460+ char *p;
10461+
10462+ switch (format) {
10463+ case 0:
10464+ break;
10465+ default:
10466+ return 0;
10467+ break;
10468+ }
10469+
10470+ p = buf;
10471+ for (i = NBYTES-1; i >= 0; i--) {
10472+ byte = (a >> (i*8)) & 0xff;
10473+ p += ultoa(byte, 10, p, PERBYTE);
10474+ if (i != 0)
10475+ *(p-1) = '.';
10476+ }
10477+ n = p - buf;
10478+
10479+ if (dstlen > 0) {
10480+ if (n > dstlen)
10481+ buf[dstlen - 1] = '\0';
10482+ strcpy(dst, buf);
10483+ }
10484+ return n;
10485+}
10486--- /dev/null Tue Mar 11 13:02:56 2003
10487+++ linux/net/ipsec/addrtot.c Mon Feb 9 13:51:03 2004
10488@@ -0,0 +1,423 @@
10489+/*
10490+ * addresses to text
10491+ * Copyright (C) 2000 Henry Spencer.
10492+ *
10493+ * This library is free software; you can redistribute it and/or modify it
10494+ * under the terms of the GNU Library General Public License as published by
10495+ * the Free Software Foundation; either version 2 of the License, or (at your
10496+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10497+ *
10498+ * This library is distributed in the hope that it will be useful, but
10499+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10500+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10501+ * License for more details.
10502+ *
10503+ * RCSID $Id: addrtot.c,v 1.22.2.1 2005/11/17 22:30:49 paul Exp $
10504+ */
10505+
10506+#if defined(__KERNEL__) && defined(__HAVE_ARCH_STRSTR)
10507+#include <linux/string.h>
10508+#endif
10509+
10510+#include "openswan.h"
10511+
10512+#define IP4BYTES 4 /* bytes in an IPv4 address */
10513+#define PERBYTE 4 /* three digits plus a dot or NUL */
10514+#define IP6BYTES 16 /* bytes in an IPv6 address */
10515+
10516+/* forwards */
10517+static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
10518+static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
10519+static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
10520+static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
10521+
10522+#if defined(__KERNEL__) && !defined(__HAVE_ARCH_STRSTR)
10523+#define strstr ipsec_strstr
10524+/*
10525+ * Find the first occurrence of find in s.
10526+ * (from NetBSD 1.6's /src/lib/libc/string/strstr.c)
10527+ */
10528+static char *
10529+strstr(s, find)
10530+ const char *s, *find;
10531+{
10532+ char c, sc;
10533+ size_t len;
10534+
10535+ if ((c = *find++) != 0) {
10536+ len = strlen(find);
10537+ do {
10538+ do {
10539+ if ((sc = *s++) == 0)
10540+ return (NULL);
10541+ } while (sc != c);
10542+ } while (strncmp(s, find, len) != 0);
10543+ s--;
10544+ }
10545+ /* LINTED interface specification */
10546+ return ((char *)s);
10547+}
10548+#endif
10549+
10550+/*
10551+ - addrtot - convert binary address to text (dotted decimal or IPv6 string)
10552+ */
10553+size_t /* space needed for full conversion */
10554+addrtot(src, format, dst, dstlen)
10555+const ip_address *src;
10556+int format; /* character */
10557+char *dst; /* need not be valid if dstlen is 0 */
10558+size_t dstlen;
10559+{
10560+ const unsigned char *b;
10561+ size_t n;
10562+ char buf[1+ADDRTOT_BUF+1]; /* :address: */
10563+ char *p;
10564+ int t = addrtypeof(src);
10565+# define TF(t, f) (((t)<<8) | (f))
10566+
10567+ n = addrbytesptr(src, &b);
10568+ if (n == 0) {
10569+ bad:
10570+ dst[0]='\0';
10571+ strncat(dst, "<invalid>", dstlen);
10572+ return sizeof("<invalid>");
10573+ }
10574+
10575+ switch (TF(t, format)) {
10576+ case TF(AF_INET, 0):
10577+ n = normal4(b, n, buf, &p);
10578+ break;
10579+ case TF(AF_INET6, 0):
10580+ n = normal6(b, n, buf, &p, 1);
10581+ break;
10582+ case TF(AF_INET, 'Q'):
10583+ n = normal4(b, n, buf, &p);
10584+ break;
10585+ case TF(AF_INET6, 'Q'):
10586+ n = normal6(b, n, buf, &p, 0);
10587+ break;
10588+ case TF(AF_INET, 'r'):
10589+ n = reverse4(b, n, buf, &p);
10590+ break;
10591+ case TF(AF_INET6, 'r'):
10592+ n = reverse6(b, n, buf, &p);
10593+ break;
10594+ default: /* including (AF_INET, 'R') */
10595+ goto bad;
10596+ break;
10597+ }
10598+
10599+ if (dstlen > 0) {
10600+ if (dstlen < n)
10601+ p[dstlen - 1] = '\0';
10602+ strcpy(dst, p);
10603+ }
10604+ return n;
10605+}
10606+
10607+/*
10608+ - normal4 - normal IPv4 address-text conversion
10609+ */
10610+static size_t /* size of text, including NUL */
10611+normal4(srcp, srclen, buf, dstp)
10612+const unsigned char *srcp;
10613+size_t srclen;
10614+char *buf; /* guaranteed large enough */
10615+char **dstp; /* where to put result pointer */
10616+{
10617+ int i;
10618+ char *p;
10619+
10620+ if (srclen != IP4BYTES) /* "can't happen" */
10621+ return 0;
10622+ p = buf;
10623+ for (i = 0; i < IP4BYTES; i++) {
10624+ p += ultot(srcp[i], 10, p, PERBYTE);
10625+ if (i != IP4BYTES - 1)
10626+ *(p-1) = '.'; /* overwrites the NUL */
10627+ }
10628+ *dstp = buf;
10629+ return p - buf;
10630+}
10631+
10632+/*
10633+ - normal6 - normal IPv6 address-text conversion
10634+ */
10635+static size_t /* size of text, including NUL */
10636+normal6(srcp, srclen, buf, dstp, squish)
10637+const unsigned char *srcp;
10638+size_t srclen;
10639+char *buf; /* guaranteed large enough, plus 2 */
10640+char **dstp; /* where to put result pointer */
10641+int squish; /* whether to squish out 0:0 */
10642+{
10643+ int i;
10644+ unsigned long piece;
10645+ char *p;
10646+ char *q;
10647+
10648+ if (srclen != IP6BYTES) /* "can't happen" */
10649+ return 0;
10650+ p = buf;
10651+ *p++ = ':';
10652+ for (i = 0; i < IP6BYTES/2; i++) {
10653+ piece = (srcp[2*i] << 8) + srcp[2*i + 1];
10654+ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
10655+ *(p-1) = ':'; /* overwrites the NUL */
10656+ }
10657+ *p = '\0';
10658+ q = strstr(buf, ":0:0:");
10659+ if (squish && q != NULL) { /* zero squishing is possible */
10660+ p = q + 1;
10661+ while (*p == '0' && *(p+1) == ':')
10662+ p += 2;
10663+ q++;
10664+ *q++ = ':'; /* overwrite first 0 */
10665+ while (*p != '\0')
10666+ *q++ = *p++;
10667+ *q = '\0';
10668+ if (!(*(q-1) == ':' && *(q-2) == ':'))
10669+ *--q = '\0'; /* strip final : unless :: */
10670+ p = buf;
10671+ if (!(*p == ':' && *(p+1) == ':'))
10672+ p++; /* skip initial : unless :: */
10673+ } else {
10674+ q = p;
10675+ *--q = '\0'; /* strip final : */
10676+ p = buf + 1; /* skip initial : */
10677+ }
10678+ *dstp = p;
10679+ return q - p + 1;
10680+}
10681+
10682+/*
10683+ - reverse4 - IPv4 reverse-lookup conversion
10684+ */
10685+static size_t /* size of text, including NUL */
10686+reverse4(srcp, srclen, buf, dstp)
10687+const unsigned char *srcp;
10688+size_t srclen;
10689+char *buf; /* guaranteed large enough */
10690+char **dstp; /* where to put result pointer */
10691+{
10692+ int i;
10693+ char *p;
10694+
10695+ if (srclen != IP4BYTES) /* "can't happen" */
10696+ return 0;
10697+ p = buf;
10698+ for (i = IP4BYTES-1; i >= 0; i--) {
10699+ p += ultot(srcp[i], 10, p, PERBYTE);
10700+ *(p-1) = '.'; /* overwrites the NUL */
10701+ }
10702+ strcpy(p, "IN-ADDR.ARPA.");
10703+ *dstp = buf;
10704+ return strlen(buf) + 1;
10705+}
10706+
10707+/*
10708+ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
10709+ * A trifle inefficient, really shouldn't use ultot...
10710+ */
10711+static size_t /* size of text, including NUL */
10712+reverse6(srcp, srclen, buf, dstp)
10713+const unsigned char *srcp;
10714+size_t srclen;
10715+char *buf; /* guaranteed large enough */
10716+char **dstp; /* where to put result pointer */
10717+{
10718+ int i;
10719+ unsigned long piece;
10720+ char *p;
10721+
10722+ if (srclen != IP6BYTES) /* "can't happen" */
10723+ return 0;
10724+ p = buf;
10725+ for (i = IP6BYTES-1; i >= 0; i--) {
10726+ piece = srcp[i];
10727+ p += ultot(piece&0xf, 16, p, 2);
10728+ *(p-1) = '.';
10729+ p += ultot(piece>>4, 16, p, 2);
10730+ *(p-1) = '.';
10731+ }
10732+ strcpy(p, "IP6.ARPA.");
10733+ *dstp = buf;
10734+ return strlen(buf) + 1;
10735+}
10736+
10737+/*
10738+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
10739+ * this version removed as it was obsoleted in the end.
10740+ */
10741+
10742+#ifdef ADDRTOT_MAIN
10743+
10744+#include <stdio.h>
10745+#include <sys/socket.h>
10746+#include <netinet/in.h>
10747+#include <arpa/inet.h>
10748+
10749+void regress(void);
10750+
10751+int
10752+main(int argc, char *argv[])
10753+{
10754+ if (argc < 2) {
10755+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
10756+ argv[0]);
10757+ exit(2);
10758+ }
10759+
10760+ if (strcmp(argv[1], "-r") == 0) {
10761+ regress();
10762+ fprintf(stderr, "regress() returned?!?\n");
10763+ exit(1);
10764+ }
10765+ exit(0);
10766+}
10767+
10768+struct rtab {
10769+ char *input;
10770+ char format;
10771+ char *output; /* NULL means error expected */
10772+} rtab[] = {
10773+ {"1.2.3.0", 0, "1.2.3.0"},
10774+ {"1:2::3:4", 0, "1:2::3:4"},
10775+ {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
10776+ {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
10777+ {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
10778+ /* 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 */
10779+ {"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."},
10780+ {NULL, 0, NULL}
10781+};
10782+
10783+void
10784+regress()
10785+{
10786+ struct rtab *r;
10787+ int status = 0;
10788+ ip_address a;
10789+ char in[100];
10790+ char buf[100];
10791+ const char *oops;
10792+ size_t n;
10793+
10794+ for (r = rtab; r->input != NULL; r++) {
10795+ strcpy(in, r->input);
10796+
10797+ /* convert it *to* internal format */
10798+ oops = ttoaddr(in, strlen(in), 0, &a);
10799+
10800+ /* now convert it back */
10801+
10802+ n = addrtot(&a, r->format, buf, sizeof(buf));
10803+
10804+ if (n == 0 && r->output == NULL)
10805+ {} /* okay, error expected */
10806+
10807+ else if (n == 0) {
10808+ printf("`%s' atoasr failed\n", r->input);
10809+ status = 1;
10810+
10811+ } else if (r->output == NULL) {
10812+ printf("`%s' atoasr succeeded unexpectedly '%c'\n",
10813+ r->input, r->format);
10814+ status = 1;
10815+ } else {
10816+ if (strcasecmp(r->output, buf) != 0) {
10817+ printf("`%s' '%c' gave `%s', expected `%s'\n",
10818+ r->input, r->format, buf, r->output);
10819+ status = 1;
10820+ }
10821+ }
10822+ }
10823+ exit(status);
10824+}
10825+
10826+#endif /* ADDRTOT_MAIN */
10827+
10828+/*
10829+ * $Log: addrtot.c,v $
10830+ * Revision 1.22.2.1 2005/11/17 22:30:49 paul
10831+ * pull up strstr fix from head.
10832+ *
10833+ * Revision 1.22 2005/05/20 16:47:40 mcr
10834+ * make strstr static if we need it.
10835+ *
10836+ * Revision 1.21 2005/03/21 00:35:12 mcr
10837+ * test for strstr properly
10838+ *
10839+ * Revision 1.20 2004/11/09 22:52:20 mcr
10840+ * until we figure out which kernels have strsep and which
10841+ * do not (UML does not under certain circumstances), then
10842+ * let's just provide our own.
10843+ *
10844+ * Revision 1.19 2004/10/08 16:30:33 mcr
10845+ * pull-up of initial crypto-offload work.
10846+ *
10847+ * Revision 1.18 2004/09/18 19:33:08 mcr
10848+ * use an appropriate kernel happy ifdef for strstr.
10849+ *
10850+ * Revision 1.17 2004/09/15 21:49:02 mcr
10851+ * use local copy of strstr() if this is going in the kernel.
10852+ * Not clear why this worked before, or why this shows up
10853+ * for modules only.
10854+ *
10855+ * Revision 1.16 2004/07/10 07:43:47 mcr
10856+ * Moved from linux/lib/libfreeswan/addrtot.c,v
10857+ *
10858+ * Revision 1.15 2004/04/11 17:39:25 mcr
10859+ * removed internal.h requirements.
10860+ *
10861+ * Revision 1.14 2004/03/08 01:59:08 ken
10862+ * freeswan.h -> openswan.h
10863+ *
10864+ * Revision 1.13 2004/01/05 23:21:05 mcr
10865+ * if the address type is invalid, then return length of <invalid>
10866+ * string!
10867+ *
10868+ * Revision 1.12 2003/12/30 06:42:48 mcr
10869+ * added $Log: addrtot.c,v $
10870+ * added Revision 1.22.2.1 2005/11/17 22:30:49 paul
10871+ * added pull up strstr fix from head.
10872+ * added
10873+ * added Revision 1.22 2005/05/20 16:47:40 mcr
10874+ * added make strstr static if we need it.
10875+ * added
10876+ * added Revision 1.21 2005/03/21 00:35:12 mcr
10877+ * added test for strstr properly
10878+ * added
10879+ * added Revision 1.20 2004/11/09 22:52:20 mcr
10880+ * added until we figure out which kernels have strsep and which
10881+ * added do not (UML does not under certain circumstances), then
10882+ * added let's just provide our own.
10883+ * added
10884+ * added Revision 1.19 2004/10/08 16:30:33 mcr
10885+ * added pull-up of initial crypto-offload work.
10886+ * added
10887+ * added Revision 1.18 2004/09/18 19:33:08 mcr
10888+ * added use an appropriate kernel happy ifdef for strstr.
10889+ * added
10890+ * added Revision 1.17 2004/09/15 21:49:02 mcr
10891+ * added use local copy of strstr() if this is going in the kernel.
10892+ * added Not clear why this worked before, or why this shows up
10893+ * added for modules only.
10894+ * added
10895+ * added Revision 1.16 2004/07/10 07:43:47 mcr
10896+ * added Moved from linux/lib/libfreeswan/addrtot.c,v
10897+ * added
10898+ * added Revision 1.15 2004/04/11 17:39:25 mcr
10899+ * added removed internal.h requirements.
10900+ * added
10901+ * added Revision 1.14 2004/03/08 01:59:08 ken
10902+ * added freeswan.h -> openswan.h
10903+ * added
10904+ * added Revision 1.13 2004/01/05 23:21:05 mcr
10905+ * added if the address type is invalid, then return length of <invalid>
10906+ * added string!
10907+ * added
10908+ *
10909+ *
10910+ */
10911+
10912--- /dev/null Tue Mar 11 13:02:56 2003
10913+++ linux/net/ipsec/addrtypeof.c Mon Feb 9 13:51:03 2004
10914@@ -0,0 +1,93 @@
10915+/*
10916+ * extract parts of an ip_address
10917+ * Copyright (C) 2000 Henry Spencer.
10918+ *
10919+ * This library is free software; you can redistribute it and/or modify it
10920+ * under the terms of the GNU Library General Public License as published by
10921+ * the Free Software Foundation; either version 2 of the License, or (at your
10922+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10923+ *
10924+ * This library is distributed in the hope that it will be useful, but
10925+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10926+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10927+ * License for more details.
10928+ *
10929+ * RCSID $Id: addrtypeof.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10930+ */
10931+#include "openswan.h"
10932+
10933+/*
10934+ - addrtypeof - get the type of an ip_address
10935+ */
10936+int
10937+addrtypeof(src)
10938+const ip_address *src;
10939+{
10940+ return src->u.v4.sin_family;
10941+}
10942+
10943+/*
10944+ - addrbytesptr - get pointer to the address bytes of an ip_address
10945+ */
10946+size_t /* 0 for error */
10947+addrbytesptr(src, dstp)
10948+const ip_address *src;
10949+const unsigned char **dstp; /* NULL means just a size query */
10950+{
10951+ const unsigned char *p;
10952+ size_t n;
10953+
10954+ switch (src->u.v4.sin_family) {
10955+ case AF_INET:
10956+ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
10957+ n = 4;
10958+ break;
10959+ case AF_INET6:
10960+ p = (const unsigned char *)&src->u.v6.sin6_addr;
10961+ n = 16;
10962+ break;
10963+ default:
10964+ return 0;
10965+ break;
10966+ }
10967+
10968+ if (dstp != NULL)
10969+ *dstp = p;
10970+ return n;
10971+}
10972+
10973+/*
10974+ - addrlenof - get length of the address bytes of an ip_address
10975+ */
10976+size_t /* 0 for error */
10977+addrlenof(src)
10978+const ip_address *src;
10979+{
10980+ return addrbytesptr(src, NULL);
10981+}
10982+
10983+/*
10984+ - addrbytesof - get the address bytes of an ip_address
10985+ */
10986+size_t /* 0 for error */
10987+addrbytesof(src, dst, dstlen)
10988+const ip_address *src;
10989+unsigned char *dst;
10990+size_t dstlen;
10991+{
10992+ const unsigned char *p;
10993+ size_t n;
10994+ size_t ncopy;
10995+
10996+ n = addrbytesptr(src, &p);
10997+ if (n == 0)
10998+ return 0;
10999+
11000+ if (dstlen > 0) {
11001+ ncopy = n;
11002+ if (ncopy > dstlen)
11003+ ncopy = dstlen;
11004+ memcpy(dst, p, ncopy);
11005+ }
11006+ return n;
11007+}
11008--- /dev/null Tue Mar 11 13:02:56 2003
11009+++ linux/net/ipsec/adler32.c Mon Feb 9 13:51:03 2004
11010@@ -0,0 +1,49 @@
11011+/* adler32.c -- compute the Adler-32 checksum of a data stream
11012+ * Copyright (C) 1995-2002 Mark Adler
11013+ * For conditions of distribution and use, see copyright notice in zlib.h
11014+ */
11015+
11016+/* @(#) $Id: adler32.c,v 1.6 2004/07/10 19:11:18 mcr Exp $ */
11017+
11018+#include <zlib/zlib.h>
11019+#include <zlib/zconf.h>
11020+
11021+#define BASE 65521L /* largest prime smaller than 65536 */
11022+#define NMAX 5552
11023+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
11024+
11025+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
11026+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
11027+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
11028+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
11029+#define DO16(buf) DO8(buf,0); DO8(buf,8);
11030+
11031+/* ========================================================================= */
11032+uLong ZEXPORT adler32(adler, buf, len)
11033+ uLong adler;
11034+ const Bytef *buf;
11035+ uInt len;
11036+{
11037+ unsigned long s1 = adler & 0xffff;
11038+ unsigned long s2 = (adler >> 16) & 0xffff;
11039+ int k;
11040+
11041+ if (buf == Z_NULL) return 1L;
11042+
11043+ while (len > 0) {
11044+ k = len < NMAX ? len : NMAX;
11045+ len -= k;
11046+ while (k >= 16) {
11047+ DO16(buf);
11048+ buf += 16;
11049+ k -= 16;
11050+ }
11051+ if (k != 0) do {
11052+ s1 += *buf++;
11053+ s2 += s1;
11054+ } while (--k);
11055+ s1 %= BASE;
11056+ s2 %= BASE;
11057+ }
11058+ return (s2 << 16) | s1;
11059+}
11060--- /dev/null Tue Mar 11 13:02:56 2003
11061+++ linux/net/ipsec/aes/Makefile Mon Feb 9 13:51:03 2004
11062@@ -0,0 +1,59 @@
11063+# Makefile for KLIPS 3DES kernel code as a module for 2.6 kernels
11064+#
11065+# Makefile for KLIPS kernel code as a module
11066+# Copyright (C) 2002-2004 Michael Richardson <mcr@xelerance.com>
11067+#
11068+# This program is free software; you can redistribute it and/or modify it
11069+# under the terms of the GNU General Public License as published by the
11070+# Free Software Foundation; either version 2 of the License, or (at your
11071+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11072+#
11073+# This program is distributed in the hope that it will be useful, but
11074+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11075+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11076+# for more details.
11077+#
11078+# RCSID $Id: Makefile.fs2_6,v 1.1.10.1 2005/08/12 16:10:05 ken Exp $
11079+#
11080+# Note! Dependencies are done automagically by 'make dep', which also
11081+# removes any old dependencies. DON'T put your own dependencies here
11082+# unless it's something special (ie not a .c file).
11083+#
11084+
11085+obj-$(CONFIG_KLIPS_ENC_AES) += ipsec_alg_aes.o
11086+obj-$(CONFIG_KLIPS_ENC_AES) += aes_xcbc_mac.o
11087+obj-$(CONFIG_KLIPS_ENC_AES) += aes_cbc.o
11088+
11089+ifeq ($(strip ${SUBARCH}),)
11090+SUBARCH:=${ARCH}
11091+endif
11092+
11093+# the assembly version expects frame pointers, which are
11094+# optional in many kernel builds. If you want speed, you should
11095+# probably use cryptoapi code instead.
11096+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
11097+ifeq (${USEASSEMBLY},i386y)
11098+obj-$(CONFIG_KLIPS_ENC_AES) += aes-i586.o
11099+else
11100+obj-$(CONFIG_KLIPS_ENC_AES) += aes.o
11101+endif
11102+
11103+
11104+#
11105+# $Log: Makefile.fs2_6,v $
11106+# Revision 1.1.10.1 2005/08/12 16:10:05 ken
11107+# do not use assembly code with there are no frame pointers
11108+#
11109+# Revision 1.2 2005/08/12 14:13:58 mcr
11110+# do not use assembly code with there are no frame pointers,
11111+# as it does not have the right linkages.
11112+#
11113+# Revision 1.1 2004/08/17 03:31:34 mcr
11114+# klips 2.6 edits.
11115+#
11116+#
11117+# Local Variables:
11118+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
11119+# End Variables:
11120+#
11121+
11122--- /dev/null Tue Mar 11 13:02:56 2003
11123+++ linux/net/ipsec/aes/aes-i586.S Mon Feb 9 13:51:03 2004
11124@@ -0,0 +1,892 @@
11125+//
11126+// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
11127+// All rights reserved.
11128+//
11129+// TERMS
11130+//
11131+// Redistribution and use in source and binary forms, with or without
11132+// modification, are permitted subject to the following conditions:
11133+//
11134+// 1. Redistributions of source code must retain the above copyright
11135+// notice, this list of conditions and the following disclaimer.
11136+//
11137+// 2. Redistributions in binary form must reproduce the above copyright
11138+// notice, this list of conditions and the following disclaimer in the
11139+// documentation and/or other materials provided with the distribution.
11140+//
11141+// 3. The copyright holder's name must not be used to endorse or promote
11142+// any products derived from this software without his specific prior
11143+// written permission.
11144+//
11145+// This software is provided 'as is' with no express or implied warranties
11146+// of correctness or fitness for purpose.
11147+
11148+// Modified by Jari Ruusu, December 24 2001
11149+// - Converted syntax to GNU CPP/assembler syntax
11150+// - C programming interface converted back to "old" API
11151+// - Minor portability cleanups and speed optimizations
11152+
11153+// An AES (Rijndael) implementation for the Pentium. This version only
11154+// implements the standard AES block length (128 bits, 16 bytes). This code
11155+// does not preserve the eax, ecx or edx registers or the artihmetic status
11156+// flags. However, the ebx, esi, edi, and ebp registers are preserved across
11157+// calls.
11158+
11159+// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
11160+// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
11161+// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
11162+
11163+#if defined(USE_UNDERLINE)
11164+# define aes_set_key _aes_set_key
11165+# define aes_encrypt _aes_encrypt
11166+# define aes_decrypt _aes_decrypt
11167+#endif
11168+#if !defined(ALIGN32BYTES)
11169+# define ALIGN32BYTES 32
11170+#endif
11171+
11172+ .file "aes-i586.S"
11173+ .globl aes_set_key
11174+ .globl aes_encrypt
11175+ .globl aes_decrypt
11176+
11177+#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
11178+
11179+// offsets to parameters with one register pushed onto stack
11180+
11181+#define ctx 8 // AES context structure
11182+#define in_blk 12 // input byte array address parameter
11183+#define out_blk 16 // output byte array address parameter
11184+
11185+// offsets in context structure
11186+
11187+#define nkey 0 // key length, size 4
11188+#define nrnd 4 // number of rounds, size 4
11189+#define ekey 8 // encryption key schedule base address, size 256
11190+#define dkey 264 // decryption key schedule base address, size 256
11191+
11192+// This macro performs a forward encryption cycle. It is entered with
11193+// the first previous round column values in %eax, %ebx, %esi and %edi and
11194+// exits with the final values in the same registers.
11195+
11196+#define fwd_rnd(p1,p2) \
11197+ mov %ebx,(%esp) ;\
11198+ movzbl %al,%edx ;\
11199+ mov %eax,%ecx ;\
11200+ mov p2(%ebp),%eax ;\
11201+ mov %edi,4(%esp) ;\
11202+ mov p2+12(%ebp),%edi ;\
11203+ xor p1(,%edx,4),%eax ;\
11204+ movzbl %ch,%edx ;\
11205+ shr $16,%ecx ;\
11206+ mov p2+4(%ebp),%ebx ;\
11207+ xor p1+tlen(,%edx,4),%edi ;\
11208+ movzbl %cl,%edx ;\
11209+ movzbl %ch,%ecx ;\
11210+ xor p1+3*tlen(,%ecx,4),%ebx ;\
11211+ mov %esi,%ecx ;\
11212+ mov p1+2*tlen(,%edx,4),%esi ;\
11213+ movzbl %cl,%edx ;\
11214+ xor p1(,%edx,4),%esi ;\
11215+ movzbl %ch,%edx ;\
11216+ shr $16,%ecx ;\
11217+ xor p1+tlen(,%edx,4),%ebx ;\
11218+ movzbl %cl,%edx ;\
11219+ movzbl %ch,%ecx ;\
11220+ xor p1+2*tlen(,%edx,4),%eax ;\
11221+ mov (%esp),%edx ;\
11222+ xor p1+3*tlen(,%ecx,4),%edi ;\
11223+ movzbl %dl,%ecx ;\
11224+ xor p2+8(%ebp),%esi ;\
11225+ xor p1(,%ecx,4),%ebx ;\
11226+ movzbl %dh,%ecx ;\
11227+ shr $16,%edx ;\
11228+ xor p1+tlen(,%ecx,4),%eax ;\
11229+ movzbl %dl,%ecx ;\
11230+ movzbl %dh,%edx ;\
11231+ xor p1+2*tlen(,%ecx,4),%edi ;\
11232+ mov 4(%esp),%ecx ;\
11233+ xor p1+3*tlen(,%edx,4),%esi ;\
11234+ movzbl %cl,%edx ;\
11235+ xor p1(,%edx,4),%edi ;\
11236+ movzbl %ch,%edx ;\
11237+ shr $16,%ecx ;\
11238+ xor p1+tlen(,%edx,4),%esi ;\
11239+ movzbl %cl,%edx ;\
11240+ movzbl %ch,%ecx ;\
11241+ xor p1+2*tlen(,%edx,4),%ebx ;\
11242+ xor p1+3*tlen(,%ecx,4),%eax
11243+
11244+// This macro performs an inverse encryption cycle. It is entered with
11245+// the first previous round column values in %eax, %ebx, %esi and %edi and
11246+// exits with the final values in the same registers.
11247+
11248+#define inv_rnd(p1,p2) \
11249+ movzbl %al,%edx ;\
11250+ mov %ebx,(%esp) ;\
11251+ mov %eax,%ecx ;\
11252+ mov p2(%ebp),%eax ;\
11253+ mov %edi,4(%esp) ;\
11254+ mov p2+4(%ebp),%ebx ;\
11255+ xor p1(,%edx,4),%eax ;\
11256+ movzbl %ch,%edx ;\
11257+ shr $16,%ecx ;\
11258+ mov p2+12(%ebp),%edi ;\
11259+ xor p1+tlen(,%edx,4),%ebx ;\
11260+ movzbl %cl,%edx ;\
11261+ movzbl %ch,%ecx ;\
11262+ xor p1+3*tlen(,%ecx,4),%edi ;\
11263+ mov %esi,%ecx ;\
11264+ mov p1+2*tlen(,%edx,4),%esi ;\
11265+ movzbl %cl,%edx ;\
11266+ xor p1(,%edx,4),%esi ;\
11267+ movzbl %ch,%edx ;\
11268+ shr $16,%ecx ;\
11269+ xor p1+tlen(,%edx,4),%edi ;\
11270+ movzbl %cl,%edx ;\
11271+ movzbl %ch,%ecx ;\
11272+ xor p1+2*tlen(,%edx,4),%eax ;\
11273+ mov (%esp),%edx ;\
11274+ xor p1+3*tlen(,%ecx,4),%ebx ;\
11275+ movzbl %dl,%ecx ;\
11276+ xor p2+8(%ebp),%esi ;\
11277+ xor p1(,%ecx,4),%ebx ;\
11278+ movzbl %dh,%ecx ;\
11279+ shr $16,%edx ;\
11280+ xor p1+tlen(,%ecx,4),%esi ;\
11281+ movzbl %dl,%ecx ;\
11282+ movzbl %dh,%edx ;\
11283+ xor p1+2*tlen(,%ecx,4),%edi ;\
11284+ mov 4(%esp),%ecx ;\
11285+ xor p1+3*tlen(,%edx,4),%eax ;\
11286+ movzbl %cl,%edx ;\
11287+ xor p1(,%edx,4),%edi ;\
11288+ movzbl %ch,%edx ;\
11289+ shr $16,%ecx ;\
11290+ xor p1+tlen(,%edx,4),%eax ;\
11291+ movzbl %cl,%edx ;\
11292+ movzbl %ch,%ecx ;\
11293+ xor p1+2*tlen(,%edx,4),%ebx ;\
11294+ xor p1+3*tlen(,%ecx,4),%esi
11295+
11296+// AES (Rijndael) Encryption Subroutine
11297+
11298+ .text
11299+ .align ALIGN32BYTES
11300+aes_encrypt:
11301+ push %ebp
11302+ mov ctx(%esp),%ebp // pointer to context
11303+ mov in_blk(%esp),%ecx
11304+ push %ebx
11305+ push %esi
11306+ push %edi
11307+ mov nrnd(%ebp),%edx // number of rounds
11308+ lea ekey+16(%ebp),%ebp // key pointer
11309+
11310+// input four columns and xor in first round key
11311+
11312+ mov (%ecx),%eax
11313+ mov 4(%ecx),%ebx
11314+ mov 8(%ecx),%esi
11315+ mov 12(%ecx),%edi
11316+ xor -16(%ebp),%eax
11317+ xor -12(%ebp),%ebx
11318+ xor -8(%ebp),%esi
11319+ xor -4(%ebp),%edi
11320+
11321+ sub $8,%esp // space for register saves on stack
11322+
11323+ sub $10,%edx
11324+ je aes_15
11325+ add $32,%ebp
11326+ sub $2,%edx
11327+ je aes_13
11328+ add $32,%ebp
11329+
11330+ fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
11331+ fwd_rnd(aes_ft_tab,-48)
11332+aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
11333+ fwd_rnd(aes_ft_tab,-16)
11334+aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
11335+ fwd_rnd(aes_ft_tab,16)
11336+ fwd_rnd(aes_ft_tab,32)
11337+ fwd_rnd(aes_ft_tab,48)
11338+ fwd_rnd(aes_ft_tab,64)
11339+ fwd_rnd(aes_ft_tab,80)
11340+ fwd_rnd(aes_ft_tab,96)
11341+ fwd_rnd(aes_ft_tab,112)
11342+ fwd_rnd(aes_ft_tab,128)
11343+ fwd_rnd(aes_fl_tab,144) // last round uses a different table
11344+
11345+// move final values to the output array.
11346+
11347+ mov out_blk+20(%esp),%ebp
11348+ add $8,%esp
11349+ mov %eax,(%ebp)
11350+ mov %ebx,4(%ebp)
11351+ mov %esi,8(%ebp)
11352+ mov %edi,12(%ebp)
11353+ pop %edi
11354+ pop %esi
11355+ pop %ebx
11356+ pop %ebp
11357+ ret
11358+
11359+
11360+// AES (Rijndael) Decryption Subroutine
11361+
11362+ .align ALIGN32BYTES
11363+aes_decrypt:
11364+ push %ebp
11365+ mov ctx(%esp),%ebp // pointer to context
11366+ mov in_blk(%esp),%ecx
11367+ push %ebx
11368+ push %esi
11369+ push %edi
11370+ mov nrnd(%ebp),%edx // number of rounds
11371+ lea dkey+16(%ebp),%ebp // key pointer
11372+
11373+// input four columns and xor in first round key
11374+
11375+ mov (%ecx),%eax
11376+ mov 4(%ecx),%ebx
11377+ mov 8(%ecx),%esi
11378+ mov 12(%ecx),%edi
11379+ xor -16(%ebp),%eax
11380+ xor -12(%ebp),%ebx
11381+ xor -8(%ebp),%esi
11382+ xor -4(%ebp),%edi
11383+
11384+ sub $8,%esp // space for register saves on stack
11385+
11386+ sub $10,%edx
11387+ je aes_25
11388+ add $32,%ebp
11389+ sub $2,%edx
11390+ je aes_23
11391+ add $32,%ebp
11392+
11393+ inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
11394+ inv_rnd(aes_it_tab,-48)
11395+aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
11396+ inv_rnd(aes_it_tab,-16)
11397+aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
11398+ inv_rnd(aes_it_tab,16)
11399+ inv_rnd(aes_it_tab,32)
11400+ inv_rnd(aes_it_tab,48)
11401+ inv_rnd(aes_it_tab,64)
11402+ inv_rnd(aes_it_tab,80)
11403+ inv_rnd(aes_it_tab,96)
11404+ inv_rnd(aes_it_tab,112)
11405+ inv_rnd(aes_it_tab,128)
11406+ inv_rnd(aes_il_tab,144) // last round uses a different table
11407+
11408+// move final values to the output array.
11409+
11410+ mov out_blk+20(%esp),%ebp
11411+ add $8,%esp
11412+ mov %eax,(%ebp)
11413+ mov %ebx,4(%ebp)
11414+ mov %esi,8(%ebp)
11415+ mov %edi,12(%ebp)
11416+ pop %edi
11417+ pop %esi
11418+ pop %ebx
11419+ pop %ebp
11420+ ret
11421+
11422+// AES (Rijndael) Key Schedule Subroutine
11423+
11424+// input/output parameters
11425+
11426+#define aes_cx 12 // AES context
11427+#define in_key 16 // key input array address
11428+#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
11429+#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
11430+
11431+// offsets for locals
11432+
11433+#define cnt -4
11434+#define kpf -8
11435+#define slen 8
11436+
11437+// This macro performs a column mixing operation on an input 32-bit
11438+// word to give a 32-bit result. It uses each of the 4 bytes in the
11439+// the input column to index 4 different tables of 256 32-bit words
11440+// that are xored together to form the output value.
11441+
11442+#define mix_col(p1) \
11443+ movzbl %bl,%ecx ;\
11444+ mov p1(,%ecx,4),%eax ;\
11445+ movzbl %bh,%ecx ;\
11446+ ror $16,%ebx ;\
11447+ xor p1+tlen(,%ecx,4),%eax ;\
11448+ movzbl %bl,%ecx ;\
11449+ xor p1+2*tlen(,%ecx,4),%eax ;\
11450+ movzbl %bh,%ecx ;\
11451+ xor p1+3*tlen(,%ecx,4),%eax
11452+
11453+// Key Schedule Macros
11454+
11455+#define ksc4(p1) \
11456+ rol $24,%ebx ;\
11457+ mix_col(aes_fl_tab) ;\
11458+ ror $8,%ebx ;\
11459+ xor 4*p1+aes_rcon_tab,%eax ;\
11460+ xor %eax,%esi ;\
11461+ xor %esi,%ebp ;\
11462+ mov %esi,16*p1(%edi) ;\
11463+ mov %ebp,16*p1+4(%edi) ;\
11464+ xor %ebp,%edx ;\
11465+ xor %edx,%ebx ;\
11466+ mov %edx,16*p1+8(%edi) ;\
11467+ mov %ebx,16*p1+12(%edi)
11468+
11469+#define ksc6(p1) \
11470+ rol $24,%ebx ;\
11471+ mix_col(aes_fl_tab) ;\
11472+ ror $8,%ebx ;\
11473+ xor 4*p1+aes_rcon_tab,%eax ;\
11474+ xor 24*p1-24(%edi),%eax ;\
11475+ mov %eax,24*p1(%edi) ;\
11476+ xor 24*p1-20(%edi),%eax ;\
11477+ mov %eax,24*p1+4(%edi) ;\
11478+ xor %eax,%esi ;\
11479+ xor %esi,%ebp ;\
11480+ mov %esi,24*p1+8(%edi) ;\
11481+ mov %ebp,24*p1+12(%edi) ;\
11482+ xor %ebp,%edx ;\
11483+ xor %edx,%ebx ;\
11484+ mov %edx,24*p1+16(%edi) ;\
11485+ mov %ebx,24*p1+20(%edi)
11486+
11487+#define ksc8(p1) \
11488+ rol $24,%ebx ;\
11489+ mix_col(aes_fl_tab) ;\
11490+ ror $8,%ebx ;\
11491+ xor 4*p1+aes_rcon_tab,%eax ;\
11492+ xor 32*p1-32(%edi),%eax ;\
11493+ mov %eax,32*p1(%edi) ;\
11494+ xor 32*p1-28(%edi),%eax ;\
11495+ mov %eax,32*p1+4(%edi) ;\
11496+ xor 32*p1-24(%edi),%eax ;\
11497+ mov %eax,32*p1+8(%edi) ;\
11498+ xor 32*p1-20(%edi),%eax ;\
11499+ mov %eax,32*p1+12(%edi) ;\
11500+ push %ebx ;\
11501+ mov %eax,%ebx ;\
11502+ mix_col(aes_fl_tab) ;\
11503+ pop %ebx ;\
11504+ xor %eax,%esi ;\
11505+ xor %esi,%ebp ;\
11506+ mov %esi,32*p1+16(%edi) ;\
11507+ mov %ebp,32*p1+20(%edi) ;\
11508+ xor %ebp,%edx ;\
11509+ xor %edx,%ebx ;\
11510+ mov %edx,32*p1+24(%edi) ;\
11511+ mov %ebx,32*p1+28(%edi)
11512+
11513+ .align ALIGN32BYTES
11514+aes_set_key:
11515+ pushfl
11516+ push %ebp
11517+ mov %esp,%ebp
11518+ sub $slen,%esp
11519+ push %ebx
11520+ push %esi
11521+ push %edi
11522+
11523+ mov aes_cx(%ebp),%edx // edx -> AES context
11524+
11525+ mov key_ln(%ebp),%ecx // key length
11526+ cmpl $128,%ecx
11527+ jb aes_30
11528+ shr $3,%ecx
11529+aes_30: cmpl $32,%ecx
11530+ je aes_32
11531+ cmpl $24,%ecx
11532+ je aes_32
11533+ mov $16,%ecx
11534+aes_32: shr $2,%ecx
11535+ mov %ecx,nkey(%edx)
11536+
11537+ lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
11538+ mov %eax,nrnd(%edx)
11539+
11540+ mov in_key(%ebp),%esi // key input array
11541+ lea ekey(%edx),%edi // key position in AES context
11542+ cld
11543+ push %ebp
11544+ mov %ecx,%eax // save key length in eax
11545+ rep ; movsl // words in the key schedule
11546+ mov -4(%esi),%ebx // put some values in registers
11547+ mov -8(%esi),%edx // to allow faster code
11548+ mov -12(%esi),%ebp
11549+ mov -16(%esi),%esi
11550+
11551+ cmpl $4,%eax // jump on key size
11552+ je aes_36
11553+ cmpl $6,%eax
11554+ je aes_35
11555+
11556+ ksc8(0)
11557+ ksc8(1)
11558+ ksc8(2)
11559+ ksc8(3)
11560+ ksc8(4)
11561+ ksc8(5)
11562+ ksc8(6)
11563+ jmp aes_37
11564+aes_35: ksc6(0)
11565+ ksc6(1)
11566+ ksc6(2)
11567+ ksc6(3)
11568+ ksc6(4)
11569+ ksc6(5)
11570+ ksc6(6)
11571+ ksc6(7)
11572+ jmp aes_37
11573+aes_36: ksc4(0)
11574+ ksc4(1)
11575+ ksc4(2)
11576+ ksc4(3)
11577+ ksc4(4)
11578+ ksc4(5)
11579+ ksc4(6)
11580+ ksc4(7)
11581+ ksc4(8)
11582+ ksc4(9)
11583+aes_37: pop %ebp
11584+ mov aes_cx(%ebp),%edx // edx -> AES context
11585+ cmpl $0,ed_flg(%ebp)
11586+ jne aes_39
11587+
11588+// compile decryption key schedule from encryption schedule - reverse
11589+// order and do mix_column operation on round keys except first and last
11590+
11591+ mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
11592+ shl $2,%eax
11593+ lea dkey(%edx,%eax,4),%edi
11594+ lea ekey(%edx),%esi // kf = cx->e_key
11595+
11596+ movsl // copy first round key (unmodified)
11597+ movsl
11598+ movsl
11599+ movsl
11600+ sub $32,%edi
11601+ movl $1,cnt(%ebp)
11602+aes_38: // do mix column on each column of
11603+ lodsl // each round key
11604+ mov %eax,%ebx
11605+ mix_col(aes_im_tab)
11606+ stosl
11607+ lodsl
11608+ mov %eax,%ebx
11609+ mix_col(aes_im_tab)
11610+ stosl
11611+ lodsl
11612+ mov %eax,%ebx
11613+ mix_col(aes_im_tab)
11614+ stosl
11615+ lodsl
11616+ mov %eax,%ebx
11617+ mix_col(aes_im_tab)
11618+ stosl
11619+ sub $32,%edi
11620+
11621+ incl cnt(%ebp)
11622+ mov cnt(%ebp),%eax
11623+ cmp nrnd(%edx),%eax
11624+ jb aes_38
11625+
11626+ movsl // copy last round key (unmodified)
11627+ movsl
11628+ movsl
11629+ movsl
11630+aes_39: pop %edi
11631+ pop %esi
11632+ pop %ebx
11633+ mov %ebp,%esp
11634+ pop %ebp
11635+ popfl
11636+ ret
11637+
11638+
11639+// finite field multiplies by {02}, {04} and {08}
11640+
11641+#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
11642+#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
11643+#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
11644+
11645+// finite field multiplies required in table generation
11646+
11647+#define f3(x) (f2(x) ^ x)
11648+#define f9(x) (f8(x) ^ x)
11649+#define fb(x) (f8(x) ^ f2(x) ^ x)
11650+#define fd(x) (f8(x) ^ f4(x) ^ x)
11651+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
11652+
11653+// These defines generate the forward table entries
11654+
11655+#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
11656+#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
11657+#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
11658+#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
11659+
11660+// These defines generate the inverse table entries
11661+
11662+#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
11663+#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
11664+#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
11665+#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
11666+
11667+// These defines generate entries for the last round tables
11668+
11669+#define w0(x) (x)
11670+#define w1(x) (x << 8)
11671+#define w2(x) (x << 16)
11672+#define w3(x) (x << 24)
11673+
11674+// macro to generate inverse mix column tables (needed for the key schedule)
11675+
11676+#define im_data0(p1) \
11677+ .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
11678+ .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
11679+ .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
11680+ .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
11681+#define im_data1(p1) \
11682+ .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
11683+ .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
11684+ .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
11685+ .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
11686+#define im_data2(p1) \
11687+ .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
11688+ .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
11689+ .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
11690+ .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
11691+#define im_data3(p1) \
11692+ .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
11693+ .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
11694+ .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
11695+ .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
11696+#define im_data4(p1) \
11697+ .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
11698+ .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
11699+ .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
11700+ .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
11701+#define im_data5(p1) \
11702+ .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
11703+ .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
11704+ .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
11705+ .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
11706+#define im_data6(p1) \
11707+ .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
11708+ .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
11709+ .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
11710+ .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
11711+#define im_data7(p1) \
11712+ .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
11713+ .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
11714+ .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
11715+ .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
11716+
11717+// S-box data - 256 entries
11718+
11719+#define sb_data0(p1) \
11720+ .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
11721+ .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
11722+ .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
11723+ .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
11724+#define sb_data1(p1) \
11725+ .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
11726+ .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
11727+ .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
11728+ .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
11729+#define sb_data2(p1) \
11730+ .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
11731+ .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
11732+ .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
11733+ .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
11734+#define sb_data3(p1) \
11735+ .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
11736+ .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
11737+ .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
11738+ .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
11739+#define sb_data4(p1) \
11740+ .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
11741+ .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
11742+ .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
11743+ .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
11744+#define sb_data5(p1) \
11745+ .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
11746+ .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
11747+ .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
11748+ .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
11749+#define sb_data6(p1) \
11750+ .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
11751+ .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
11752+ .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
11753+ .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
11754+#define sb_data7(p1) \
11755+ .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
11756+ .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
11757+ .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
11758+ .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
11759+
11760+// Inverse S-box data - 256 entries
11761+
11762+#define ib_data0(p1) \
11763+ .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
11764+ .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
11765+ .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
11766+ .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
11767+#define ib_data1(p1) \
11768+ .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
11769+ .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
11770+ .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
11771+ .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
11772+#define ib_data2(p1) \
11773+ .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
11774+ .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
11775+ .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
11776+ .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
11777+#define ib_data3(p1) \
11778+ .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
11779+ .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
11780+ .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
11781+ .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
11782+#define ib_data4(p1) \
11783+ .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
11784+ .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
11785+ .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
11786+ .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
11787+#define ib_data5(p1) \
11788+ .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
11789+ .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
11790+ .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
11791+ .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
11792+#define ib_data6(p1) \
11793+ .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
11794+ .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
11795+ .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
11796+ .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
11797+#define ib_data7(p1) \
11798+ .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
11799+ .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
11800+ .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
11801+ .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
11802+
11803+// The rcon_table (needed for the key schedule)
11804+//
11805+// Here is original Dr Brian Gladman's source code:
11806+// _rcon_tab:
11807+// %assign x 1
11808+// %rep 29
11809+// dd x
11810+// %assign x f2(x)
11811+// %endrep
11812+//
11813+// Here is precomputed output (it's more portable this way):
11814+
11815+ .align ALIGN32BYTES
11816+aes_rcon_tab:
11817+ .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
11818+ .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
11819+ .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
11820+ .long 0xb3,0x7d,0xfa,0xef,0xc5
11821+
11822+// The forward xor tables
11823+
11824+ .align ALIGN32BYTES
11825+aes_ft_tab:
11826+ sb_data0(u0)
11827+ sb_data1(u0)
11828+ sb_data2(u0)
11829+ sb_data3(u0)
11830+ sb_data4(u0)
11831+ sb_data5(u0)
11832+ sb_data6(u0)
11833+ sb_data7(u0)
11834+
11835+ sb_data0(u1)
11836+ sb_data1(u1)
11837+ sb_data2(u1)
11838+ sb_data3(u1)
11839+ sb_data4(u1)
11840+ sb_data5(u1)
11841+ sb_data6(u1)
11842+ sb_data7(u1)
11843+
11844+ sb_data0(u2)
11845+ sb_data1(u2)
11846+ sb_data2(u2)
11847+ sb_data3(u2)
11848+ sb_data4(u2)
11849+ sb_data5(u2)
11850+ sb_data6(u2)
11851+ sb_data7(u2)
11852+
11853+ sb_data0(u3)
11854+ sb_data1(u3)
11855+ sb_data2(u3)
11856+ sb_data3(u3)
11857+ sb_data4(u3)
11858+ sb_data5(u3)
11859+ sb_data6(u3)
11860+ sb_data7(u3)
11861+
11862+ .align ALIGN32BYTES
11863+aes_fl_tab:
11864+ sb_data0(w0)
11865+ sb_data1(w0)
11866+ sb_data2(w0)
11867+ sb_data3(w0)
11868+ sb_data4(w0)
11869+ sb_data5(w0)
11870+ sb_data6(w0)
11871+ sb_data7(w0)
11872+
11873+ sb_data0(w1)
11874+ sb_data1(w1)
11875+ sb_data2(w1)
11876+ sb_data3(w1)
11877+ sb_data4(w1)
11878+ sb_data5(w1)
11879+ sb_data6(w1)
11880+ sb_data7(w1)
11881+
11882+ sb_data0(w2)
11883+ sb_data1(w2)
11884+ sb_data2(w2)
11885+ sb_data3(w2)
11886+ sb_data4(w2)
11887+ sb_data5(w2)
11888+ sb_data6(w2)
11889+ sb_data7(w2)
11890+
11891+ sb_data0(w3)
11892+ sb_data1(w3)
11893+ sb_data2(w3)
11894+ sb_data3(w3)
11895+ sb_data4(w3)
11896+ sb_data5(w3)
11897+ sb_data6(w3)
11898+ sb_data7(w3)
11899+
11900+// The inverse xor tables
11901+
11902+ .align ALIGN32BYTES
11903+aes_it_tab:
11904+ ib_data0(v0)
11905+ ib_data1(v0)
11906+ ib_data2(v0)
11907+ ib_data3(v0)
11908+ ib_data4(v0)
11909+ ib_data5(v0)
11910+ ib_data6(v0)
11911+ ib_data7(v0)
11912+
11913+ ib_data0(v1)
11914+ ib_data1(v1)
11915+ ib_data2(v1)
11916+ ib_data3(v1)
11917+ ib_data4(v1)
11918+ ib_data5(v1)
11919+ ib_data6(v1)
11920+ ib_data7(v1)
11921+
11922+ ib_data0(v2)
11923+ ib_data1(v2)
11924+ ib_data2(v2)
11925+ ib_data3(v2)
11926+ ib_data4(v2)
11927+ ib_data5(v2)
11928+ ib_data6(v2)
11929+ ib_data7(v2)
11930+
11931+ ib_data0(v3)
11932+ ib_data1(v3)
11933+ ib_data2(v3)
11934+ ib_data3(v3)
11935+ ib_data4(v3)
11936+ ib_data5(v3)
11937+ ib_data6(v3)
11938+ ib_data7(v3)
11939+
11940+ .align ALIGN32BYTES
11941+aes_il_tab:
11942+ ib_data0(w0)
11943+ ib_data1(w0)
11944+ ib_data2(w0)
11945+ ib_data3(w0)
11946+ ib_data4(w0)
11947+ ib_data5(w0)
11948+ ib_data6(w0)
11949+ ib_data7(w0)
11950+
11951+ ib_data0(w1)
11952+ ib_data1(w1)
11953+ ib_data2(w1)
11954+ ib_data3(w1)
11955+ ib_data4(w1)
11956+ ib_data5(w1)
11957+ ib_data6(w1)
11958+ ib_data7(w1)
11959+
11960+ ib_data0(w2)
11961+ ib_data1(w2)
11962+ ib_data2(w2)
11963+ ib_data3(w2)
11964+ ib_data4(w2)
11965+ ib_data5(w2)
11966+ ib_data6(w2)
11967+ ib_data7(w2)
11968+
11969+ ib_data0(w3)
11970+ ib_data1(w3)
11971+ ib_data2(w3)
11972+ ib_data3(w3)
11973+ ib_data4(w3)
11974+ ib_data5(w3)
11975+ ib_data6(w3)
11976+ ib_data7(w3)
11977+
11978+// The inverse mix column tables
11979+
11980+ .align ALIGN32BYTES
11981+aes_im_tab:
11982+ im_data0(v0)
11983+ im_data1(v0)
11984+ im_data2(v0)
11985+ im_data3(v0)
11986+ im_data4(v0)
11987+ im_data5(v0)
11988+ im_data6(v0)
11989+ im_data7(v0)
11990+
11991+ im_data0(v1)
11992+ im_data1(v1)
11993+ im_data2(v1)
11994+ im_data3(v1)
11995+ im_data4(v1)
11996+ im_data5(v1)
11997+ im_data6(v1)
11998+ im_data7(v1)
11999+
12000+ im_data0(v2)
12001+ im_data1(v2)
12002+ im_data2(v2)
12003+ im_data3(v2)
12004+ im_data4(v2)
12005+ im_data5(v2)
12006+ im_data6(v2)
12007+ im_data7(v2)
12008+
12009+ im_data0(v3)
12010+ im_data1(v3)
12011+ im_data2(v3)
12012+ im_data3(v3)
12013+ im_data4(v3)
12014+ im_data5(v3)
12015+ im_data6(v3)
12016+ im_data7(v3)
12017--- /dev/null Tue Mar 11 13:02:56 2003
12018+++ linux/net/ipsec/aes/aes.c Mon Feb 9 13:51:03 2004
12019@@ -0,0 +1,1415 @@
12020+// I retain copyright in this code but I encourage its free use provided
12021+// that I don't carry any responsibility for the results. I am especially
12022+// happy to see it used in free and open source software. If you do use
12023+// it I would appreciate an acknowledgement of its origin in the code or
12024+// the product that results and I would also appreciate knowing a little
12025+// about the use to which it is being put. I am grateful to Frank Yellin
12026+// for some ideas that are used in this implementation.
12027+//
12028+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
12029+//
12030+// This is an implementation of the AES encryption algorithm (Rijndael)
12031+// designed by Joan Daemen and Vincent Rijmen. This version is designed
12032+// to provide both fixed and dynamic block and key lengths and can also
12033+// run with either big or little endian internal byte order (see aes.h).
12034+// It inputs block and key lengths in bytes with the legal values being
12035+// 16, 24 and 32.
12036+
12037+/*
12038+ * Modified by Jari Ruusu, May 1 2001
12039+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
12040+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
12041+ * - Major name space cleanup: Names visible to outside now begin
12042+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
12043+ * - Removed C++ and DLL support as part of name space cleanup.
12044+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
12045+ * - Merged precomputed constant tables to aes.c file.
12046+ * - Removed data alignment restrictions for portability reasons.
12047+ * - Made block and key lengths accept bit count (128/192/256)
12048+ * as well byte count (16/24/32).
12049+ * - Removed all error checks. This change also eliminated the need
12050+ * to preinitialize the context struct to zero.
12051+ * - Removed some totally unused constants.
12052+ */
12053+
12054+#include "crypto/aes.h"
12055+
12056+// CONFIGURATION OPTIONS (see also aes.h)
12057+//
12058+// 1. Define UNROLL for full loop unrolling in encryption and decryption.
12059+// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
12060+// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
12061+// 4. Define FF_TABLES to use tables for field multiplies and inverses.
12062+// Do not enable this without understanding stack space requirements.
12063+// 5. Define ARRAYS to use arrays to hold the local state block. If this
12064+// is not defined, individually declared 32-bit words are used.
12065+// 6. Define FAST_VARIABLE if a high speed variable block implementation
12066+// is needed (essentially three separate fixed block size code sequences)
12067+// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
12068+// version using 1 table (2 kbytes of table space) or 4 tables (8
12069+// kbytes of table space) for higher speed.
12070+// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
12071+// increase by using tables for the last rounds but with more table
12072+// space (2 or 8 kbytes extra).
12073+// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
12074+// slower version is provided.
12075+// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
12076+// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
12077+
12078+#define UNROLL
12079+//#define PARTIAL_UNROLL
12080+
12081+#define FIXED_TABLES
12082+//#define FF_TABLES
12083+//#define ARRAYS
12084+#define FAST_VARIABLE
12085+
12086+//#define ONE_TABLE
12087+#define FOUR_TABLES
12088+
12089+//#define ONE_LR_TABLE
12090+#define FOUR_LR_TABLES
12091+
12092+//#define ONE_IM_TABLE
12093+#define FOUR_IM_TABLES
12094+
12095+#if defined(UNROLL) && defined (PARTIAL_UNROLL)
12096+#error both UNROLL and PARTIAL_UNROLL are defined
12097+#endif
12098+
12099+#if defined(ONE_TABLE) && defined (FOUR_TABLES)
12100+#error both ONE_TABLE and FOUR_TABLES are defined
12101+#endif
12102+
12103+#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
12104+#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
12105+#endif
12106+
12107+#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
12108+#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
12109+#endif
12110+
12111+#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
12112+#error an illegal block size has been specified
12113+#endif
12114+
12115+// upr(x,n): rotates bytes within words by n positions, moving bytes
12116+// to higher index positions with wrap around into low positions
12117+// ups(x,n): moves bytes by n positions to higher index positions in
12118+// words but without wrap around
12119+// bval(x,n): extracts a byte from a word
12120+
12121+#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
12122+#define ups(x,n) ((x) << 8 * (n))
12123+#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
12124+#define bytes2word(b0, b1, b2, b3) \
12125+ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
12126+
12127+
12128+/* little endian processor without data alignment restrictions: AES_LE_OK */
12129+/* original code: i386 */
12130+#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
12131+#define AES_LE_OK 1
12132+/* added (tested): alpha --jjo */
12133+#elif defined(__alpha__)|| defined (__alpha)
12134+#define AES_LE_OK 1
12135+/* added (tested): ia64 --jjo */
12136+#elif defined(__ia64__)|| defined (__ia64)
12137+#define AES_LE_OK 1
12138+#endif
12139+
12140+#ifdef AES_LE_OK
12141+/* little endian processor without data alignment restrictions */
12142+#define word_in(x) *(u_int32_t*)(x)
12143+#define const_word_in(x) *(const u_int32_t*)(x)
12144+#define word_out(x,v) *(u_int32_t*)(x) = (v)
12145+#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
12146+#else
12147+/* slower but generic big endian or with data alignment restrictions */
12148+/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
12149+#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))
12150+#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))
12151+#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)
12152+#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)
12153+#endif
12154+
12155+// Disable at least some poor combinations of options
12156+
12157+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
12158+#define FIXED_TABLES
12159+#undef UNROLL
12160+#undef ONE_LR_TABLE
12161+#undef FOUR_LR_TABLES
12162+#undef ONE_IM_TABLE
12163+#undef FOUR_IM_TABLES
12164+#elif !defined(FOUR_TABLES)
12165+#ifdef FOUR_LR_TABLES
12166+#undef FOUR_LR_TABLES
12167+#define ONE_LR_TABLE
12168+#endif
12169+#ifdef FOUR_IM_TABLES
12170+#undef FOUR_IM_TABLES
12171+#define ONE_IM_TABLE
12172+#endif
12173+#elif !defined(AES_BLOCK_SIZE)
12174+#if defined(UNROLL)
12175+#define PARTIAL_UNROLL
12176+#undef UNROLL
12177+#endif
12178+#endif
12179+
12180+// the finite field modular polynomial and elements
12181+
12182+#define ff_poly 0x011b
12183+#define ff_hi 0x80
12184+
12185+// multiply four bytes in GF(2^8) by 'x' {02} in parallel
12186+
12187+#define m1 0x80808080
12188+#define m2 0x7f7f7f7f
12189+#define m3 0x0000001b
12190+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
12191+
12192+// The following defines provide alternative definitions of FFmulX that might
12193+// give improved performance if a fast 32-bit multiply is not available. Note
12194+// that a temporary variable u needs to be defined where FFmulX is used.
12195+
12196+// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
12197+// #define m4 0x1b1b1b1b
12198+// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
12199+
12200+// perform column mix operation on four bytes in parallel
12201+
12202+#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
12203+
12204+#if defined(FIXED_TABLES)
12205+
12206+// the S-Box table
12207+
12208+static const unsigned char s_box[256] =
12209+{
12210+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
12211+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
12212+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
12213+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
12214+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
12215+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
12216+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
12217+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
12218+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
12219+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
12220+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
12221+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
12222+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
12223+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
12224+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
12225+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
12226+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
12227+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
12228+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
12229+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
12230+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
12231+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
12232+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
12233+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
12234+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
12235+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
12236+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
12237+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
12238+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
12239+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
12240+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
12241+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
12242+};
12243+
12244+// the inverse S-Box table
12245+
12246+static const unsigned char inv_s_box[256] =
12247+{
12248+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
12249+ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
12250+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
12251+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
12252+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
12253+ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
12254+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
12255+ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
12256+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
12257+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
12258+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
12259+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
12260+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
12261+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
12262+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
12263+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
12264+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
12265+ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
12266+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
12267+ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
12268+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
12269+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
12270+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
12271+ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
12272+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
12273+ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
12274+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
12275+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
12276+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
12277+ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
12278+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
12279+ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
12280+};
12281+
12282+#define w0(p) 0x000000##p
12283+
12284+// Number of elements required in this table for different
12285+// block and key lengths is:
12286+//
12287+// Nk = 4 6 8
12288+// ----------
12289+// Nb = 4 | 10 8 7
12290+// 6 | 19 12 11
12291+// 8 | 29 19 14
12292+//
12293+// this table can be a table of bytes if the key schedule
12294+// code is adjusted accordingly
12295+
12296+static const u_int32_t rcon_tab[29] =
12297+{
12298+ w0(01), w0(02), w0(04), w0(08),
12299+ w0(10), w0(20), w0(40), w0(80),
12300+ w0(1b), w0(36), w0(6c), w0(d8),
12301+ w0(ab), w0(4d), w0(9a), w0(2f),
12302+ w0(5e), w0(bc), w0(63), w0(c6),
12303+ w0(97), w0(35), w0(6a), w0(d4),
12304+ w0(b3), w0(7d), w0(fa), w0(ef),
12305+ w0(c5)
12306+};
12307+
12308+#undef w0
12309+
12310+#define r0(p,q,r,s) 0x##p##q##r##s
12311+#define r1(p,q,r,s) 0x##q##r##s##p
12312+#define r2(p,q,r,s) 0x##r##s##p##q
12313+#define r3(p,q,r,s) 0x##s##p##q##r
12314+#define w0(p) 0x000000##p
12315+#define w1(p) 0x0000##p##00
12316+#define w2(p) 0x00##p##0000
12317+#define w3(p) 0x##p##000000
12318+
12319+#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
12320+
12321+// data for forward tables (other than last round)
12322+
12323+#define f_table \
12324+ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
12325+ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
12326+ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
12327+ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
12328+ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
12329+ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
12330+ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
12331+ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
12332+ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
12333+ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
12334+ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
12335+ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
12336+ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
12337+ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
12338+ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
12339+ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
12340+ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
12341+ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
12342+ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
12343+ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
12344+ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
12345+ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
12346+ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
12347+ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
12348+ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
12349+ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
12350+ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
12351+ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
12352+ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
12353+ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
12354+ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
12355+ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
12356+ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
12357+ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
12358+ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
12359+ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
12360+ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
12361+ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
12362+ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
12363+ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
12364+ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
12365+ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
12366+ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
12367+ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
12368+ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
12369+ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
12370+ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
12371+ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
12372+ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
12373+ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
12374+ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
12375+ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
12376+ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
12377+ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
12378+ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
12379+ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
12380+ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
12381+ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
12382+ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
12383+ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
12384+ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
12385+ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
12386+ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
12387+ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
12388+
12389+// data for inverse tables (other than last round)
12390+
12391+#define i_table \
12392+ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
12393+ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
12394+ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
12395+ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
12396+ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
12397+ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
12398+ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
12399+ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
12400+ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
12401+ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
12402+ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
12403+ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
12404+ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
12405+ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
12406+ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
12407+ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
12408+ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
12409+ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
12410+ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
12411+ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
12412+ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
12413+ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
12414+ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
12415+ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
12416+ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
12417+ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
12418+ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
12419+ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
12420+ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
12421+ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
12422+ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
12423+ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
12424+ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
12425+ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
12426+ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
12427+ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
12428+ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
12429+ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
12430+ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
12431+ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
12432+ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
12433+ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
12434+ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
12435+ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
12436+ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
12437+ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
12438+ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
12439+ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
12440+ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
12441+ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
12442+ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
12443+ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
12444+ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
12445+ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
12446+ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
12447+ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
12448+ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
12449+ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
12450+ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
12451+ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
12452+ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
12453+ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
12454+ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
12455+ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
12456+
12457+// generate the required tables in the desired endian format
12458+
12459+#undef r
12460+#define r r0
12461+
12462+#if defined(ONE_TABLE)
12463+static const u_int32_t ft_tab[256] =
12464+ { f_table };
12465+#elif defined(FOUR_TABLES)
12466+static const u_int32_t ft_tab[4][256] =
12467+{ { f_table },
12468+#undef r
12469+#define r r1
12470+ { f_table },
12471+#undef r
12472+#define r r2
12473+ { f_table },
12474+#undef r
12475+#define r r3
12476+ { f_table }
12477+};
12478+#endif
12479+
12480+#undef r
12481+#define r r0
12482+#if defined(ONE_TABLE)
12483+static const u_int32_t it_tab[256] =
12484+ { i_table };
12485+#elif defined(FOUR_TABLES)
12486+static const u_int32_t it_tab[4][256] =
12487+{ { i_table },
12488+#undef r
12489+#define r r1
12490+ { i_table },
12491+#undef r
12492+#define r r2
12493+ { i_table },
12494+#undef r
12495+#define r r3
12496+ { i_table }
12497+};
12498+#endif
12499+
12500+#endif
12501+
12502+#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
12503+
12504+// data for inverse tables (last round)
12505+
12506+#define li_table \
12507+ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
12508+ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
12509+ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
12510+ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
12511+ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
12512+ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
12513+ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
12514+ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
12515+ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
12516+ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
12517+ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
12518+ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
12519+ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
12520+ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
12521+ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
12522+ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
12523+ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
12524+ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
12525+ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
12526+ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
12527+ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
12528+ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
12529+ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
12530+ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
12531+ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
12532+ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
12533+ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
12534+ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
12535+ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
12536+ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
12537+ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
12538+ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
12539+
12540+// generate the required tables in the desired endian format
12541+
12542+#undef r
12543+#define r(p,q,r,s) w0(q)
12544+#if defined(ONE_LR_TABLE)
12545+static const u_int32_t fl_tab[256] =
12546+ { f_table };
12547+#elif defined(FOUR_LR_TABLES)
12548+static const u_int32_t fl_tab[4][256] =
12549+{ { f_table },
12550+#undef r
12551+#define r(p,q,r,s) w1(q)
12552+ { f_table },
12553+#undef r
12554+#define r(p,q,r,s) w2(q)
12555+ { f_table },
12556+#undef r
12557+#define r(p,q,r,s) w3(q)
12558+ { f_table }
12559+};
12560+#endif
12561+
12562+#undef w
12563+#define w w0
12564+#if defined(ONE_LR_TABLE)
12565+static const u_int32_t il_tab[256] =
12566+ { li_table };
12567+#elif defined(FOUR_LR_TABLES)
12568+static const u_int32_t il_tab[4][256] =
12569+{ { li_table },
12570+#undef w
12571+#define w w1
12572+ { li_table },
12573+#undef w
12574+#define w w2
12575+ { li_table },
12576+#undef w
12577+#define w w3
12578+ { li_table }
12579+};
12580+#endif
12581+
12582+#endif
12583+
12584+#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
12585+
12586+#define m_table \
12587+ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
12588+ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
12589+ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
12590+ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
12591+ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
12592+ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
12593+ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
12594+ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
12595+ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
12596+ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
12597+ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
12598+ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
12599+ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
12600+ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
12601+ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
12602+ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
12603+ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
12604+ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
12605+ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
12606+ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
12607+ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
12608+ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
12609+ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
12610+ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
12611+ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
12612+ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
12613+ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
12614+ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
12615+ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
12616+ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
12617+ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
12618+ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
12619+ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
12620+ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
12621+ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
12622+ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
12623+ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
12624+ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
12625+ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
12626+ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
12627+ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
12628+ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
12629+ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
12630+ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
12631+ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
12632+ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
12633+ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
12634+ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
12635+ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
12636+ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
12637+ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
12638+ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
12639+ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
12640+ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
12641+ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
12642+ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
12643+ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
12644+ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
12645+ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
12646+ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
12647+ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
12648+ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
12649+ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
12650+ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
12651+
12652+#undef r
12653+#define r r0
12654+
12655+#if defined(ONE_IM_TABLE)
12656+static const u_int32_t im_tab[256] =
12657+ { m_table };
12658+#elif defined(FOUR_IM_TABLES)
12659+static const u_int32_t im_tab[4][256] =
12660+{ { m_table },
12661+#undef r
12662+#define r r1
12663+ { m_table },
12664+#undef r
12665+#define r r2
12666+ { m_table },
12667+#undef r
12668+#define r r3
12669+ { m_table }
12670+};
12671+#endif
12672+
12673+#endif
12674+
12675+#else
12676+
12677+static int tab_gen = 0;
12678+
12679+static unsigned char s_box[256]; // the S box
12680+static unsigned char inv_s_box[256]; // the inverse S box
12681+static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
12682+
12683+#if defined(ONE_TABLE)
12684+static u_int32_t ft_tab[256];
12685+static u_int32_t it_tab[256];
12686+#elif defined(FOUR_TABLES)
12687+static u_int32_t ft_tab[4][256];
12688+static u_int32_t it_tab[4][256];
12689+#endif
12690+
12691+#if defined(ONE_LR_TABLE)
12692+static u_int32_t fl_tab[256];
12693+static u_int32_t il_tab[256];
12694+#elif defined(FOUR_LR_TABLES)
12695+static u_int32_t fl_tab[4][256];
12696+static u_int32_t il_tab[4][256];
12697+#endif
12698+
12699+#if defined(ONE_IM_TABLE)
12700+static u_int32_t im_tab[256];
12701+#elif defined(FOUR_IM_TABLES)
12702+static u_int32_t im_tab[4][256];
12703+#endif
12704+
12705+// Generate the tables for the dynamic table option
12706+
12707+#if !defined(FF_TABLES)
12708+
12709+// It will generally be sensible to use tables to compute finite
12710+// field multiplies and inverses but where memory is scarse this
12711+// code might sometimes be better.
12712+
12713+// return 2 ^ (n - 1) where n is the bit number of the highest bit
12714+// set in x with x in the range 1 < x < 0x00000200. This form is
12715+// used so that locals within FFinv can be bytes rather than words
12716+
12717+static unsigned char hibit(const u_int32_t x)
12718+{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
12719+
12720+ r |= (r >> 2);
12721+ r |= (r >> 4);
12722+ return (r + 1) >> 1;
12723+}
12724+
12725+// return the inverse of the finite field element x
12726+
12727+static unsigned char FFinv(const unsigned char x)
12728+{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
12729+
12730+ if(x < 2) return x;
12731+
12732+ for(;;)
12733+ {
12734+ if(!n1) return v1;
12735+
12736+ while(n2 >= n1)
12737+ {
12738+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
12739+ }
12740+
12741+ if(!n2) return v2;
12742+
12743+ while(n1 >= n2)
12744+ {
12745+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
12746+ }
12747+ }
12748+}
12749+
12750+// define the finite field multiplies required for Rijndael
12751+
12752+#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
12753+#define FFmul03(x) ((x) ^ FFmul02(x))
12754+#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
12755+#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
12756+#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
12757+#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
12758+
12759+#else
12760+
12761+#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
12762+
12763+#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
12764+#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
12765+#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
12766+#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
12767+#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
12768+#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
12769+
12770+#endif
12771+
12772+// The forward and inverse affine transformations used in the S-box
12773+
12774+#define fwd_affine(x) \
12775+ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
12776+
12777+#define inv_affine(x) \
12778+ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
12779+
12780+static void gen_tabs(void)
12781+{ u_int32_t i, w;
12782+
12783+#if defined(FF_TABLES)
12784+
12785+ unsigned char pow[512], log[256];
12786+
12787+ // log and power tables for GF(2^8) finite field with
12788+ // 0x011b as modular polynomial - the simplest primitive
12789+ // root is 0x03, used here to generate the tables
12790+
12791+ i = 0; w = 1;
12792+ do
12793+ {
12794+ pow[i] = (unsigned char)w;
12795+ pow[i + 255] = (unsigned char)w;
12796+ log[w] = (unsigned char)i++;
12797+ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12798+ }
12799+ while (w != 1);
12800+
12801+#endif
12802+
12803+ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
12804+ {
12805+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
12806+ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12807+ }
12808+
12809+ for(i = 0; i < 256; ++i)
12810+ { unsigned char b;
12811+
12812+ s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
12813+
12814+ w = bytes2word(b, 0, 0, 0);
12815+#if defined(ONE_LR_TABLE)
12816+ fl_tab[i] = w;
12817+#elif defined(FOUR_LR_TABLES)
12818+ fl_tab[0][i] = w;
12819+ fl_tab[1][i] = upr(w,1);
12820+ fl_tab[2][i] = upr(w,2);
12821+ fl_tab[3][i] = upr(w,3);
12822+#endif
12823+ w = bytes2word(FFmul02(b), b, b, FFmul03(b));
12824+#if defined(ONE_TABLE)
12825+ ft_tab[i] = w;
12826+#elif defined(FOUR_TABLES)
12827+ ft_tab[0][i] = w;
12828+ ft_tab[1][i] = upr(w,1);
12829+ ft_tab[2][i] = upr(w,2);
12830+ ft_tab[3][i] = upr(w,3);
12831+#endif
12832+ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
12833+
12834+ w = bytes2word(b, 0, 0, 0);
12835+#if defined(ONE_LR_TABLE)
12836+ il_tab[i] = w;
12837+#elif defined(FOUR_LR_TABLES)
12838+ il_tab[0][i] = w;
12839+ il_tab[1][i] = upr(w,1);
12840+ il_tab[2][i] = upr(w,2);
12841+ il_tab[3][i] = upr(w,3);
12842+#endif
12843+ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
12844+#if defined(ONE_TABLE)
12845+ it_tab[i] = w;
12846+#elif defined(FOUR_TABLES)
12847+ it_tab[0][i] = w;
12848+ it_tab[1][i] = upr(w,1);
12849+ it_tab[2][i] = upr(w,2);
12850+ it_tab[3][i] = upr(w,3);
12851+#endif
12852+#if defined(ONE_IM_TABLE)
12853+ im_tab[b] = w;
12854+#elif defined(FOUR_IM_TABLES)
12855+ im_tab[0][b] = w;
12856+ im_tab[1][b] = upr(w,1);
12857+ im_tab[2][b] = upr(w,2);
12858+ im_tab[3][b] = upr(w,3);
12859+#endif
12860+
12861+ }
12862+}
12863+
12864+#endif
12865+
12866+#define no_table(x,box,vf,rf,c) bytes2word( \
12867+ box[bval(vf(x,0,c),rf(0,c))], \
12868+ box[bval(vf(x,1,c),rf(1,c))], \
12869+ box[bval(vf(x,2,c),rf(2,c))], \
12870+ box[bval(vf(x,3,c),rf(3,c))])
12871+
12872+#define one_table(x,op,tab,vf,rf,c) \
12873+ ( tab[bval(vf(x,0,c),rf(0,c))] \
12874+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
12875+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
12876+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
12877+
12878+#define four_tables(x,tab,vf,rf,c) \
12879+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
12880+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
12881+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
12882+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
12883+
12884+#define vf1(x,r,c) (x)
12885+#define rf1(r,c) (r)
12886+#define rf2(r,c) ((r-c)&3)
12887+
12888+#if defined(FOUR_LR_TABLES)
12889+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
12890+#elif defined(ONE_LR_TABLE)
12891+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
12892+#else
12893+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
12894+#endif
12895+
12896+#if defined(FOUR_IM_TABLES)
12897+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
12898+#elif defined(ONE_IM_TABLE)
12899+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
12900+#else
12901+#define inv_mcol(x) \
12902+ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
12903+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
12904+#endif
12905+
12906+// Subroutine to set the block size (if variable) in bytes, legal
12907+// values being 16, 24 and 32.
12908+
12909+#if defined(AES_BLOCK_SIZE)
12910+#define nc (AES_BLOCK_SIZE / 4)
12911+#else
12912+#define nc (cx->aes_Ncol)
12913+
12914+void aes_set_blk(aes_context *cx, int n_bytes)
12915+{
12916+#if !defined(FIXED_TABLES)
12917+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12918+#endif
12919+
12920+ switch(n_bytes) {
12921+ case 32: /* bytes */
12922+ case 256: /* bits */
12923+ nc = 8;
12924+ break;
12925+ case 24: /* bytes */
12926+ case 192: /* bits */
12927+ nc = 6;
12928+ break;
12929+ case 16: /* bytes */
12930+ case 128: /* bits */
12931+ default:
12932+ nc = 4;
12933+ break;
12934+ }
12935+}
12936+
12937+#endif
12938+
12939+// Initialise the key schedule from the user supplied key. The key
12940+// length is now specified in bytes - 16, 24 or 32 as appropriate.
12941+// This corresponds to bit lengths of 128, 192 and 256 bits, and
12942+// to Nk values of 4, 6 and 8 respectively.
12943+
12944+#define mx(t,f) (*t++ = inv_mcol(*f),f++)
12945+#define cp(t,f) *t++ = *f++
12946+
12947+#if AES_BLOCK_SIZE == 16
12948+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12949+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12950+#elif AES_BLOCK_SIZE == 24
12951+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12952+ cp(d,s); cp(d,s)
12953+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12954+ mx(d,s); mx(d,s)
12955+#elif AES_BLOCK_SIZE == 32
12956+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12957+ cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12958+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12959+ mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12960+#else
12961+
12962+#define cpy(d,s) \
12963+switch(nc) \
12964+{ case 8: cp(d,s); cp(d,s); \
12965+ case 6: cp(d,s); cp(d,s); \
12966+ case 4: cp(d,s); cp(d,s); \
12967+ cp(d,s); cp(d,s); \
12968+}
12969+
12970+#define mix(d,s) \
12971+switch(nc) \
12972+{ case 8: mx(d,s); mx(d,s); \
12973+ case 6: mx(d,s); mx(d,s); \
12974+ case 4: mx(d,s); mx(d,s); \
12975+ mx(d,s); mx(d,s); \
12976+}
12977+
12978+#endif
12979+
12980+void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
12981+{ u_int32_t *kf, *kt, rci;
12982+
12983+#if !defined(FIXED_TABLES)
12984+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12985+#endif
12986+
12987+ switch(n_bytes) {
12988+ case 32: /* bytes */
12989+ case 256: /* bits */
12990+ cx->aes_Nkey = 8;
12991+ break;
12992+ case 24: /* bytes */
12993+ case 192: /* bits */
12994+ cx->aes_Nkey = 6;
12995+ break;
12996+ case 16: /* bytes */
12997+ case 128: /* bits */
12998+ default:
12999+ cx->aes_Nkey = 4;
13000+ break;
13001+ }
13002+
13003+ cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
13004+
13005+ cx->aes_e_key[0] = const_word_in(in_key );
13006+ cx->aes_e_key[1] = const_word_in(in_key + 4);
13007+ cx->aes_e_key[2] = const_word_in(in_key + 8);
13008+ cx->aes_e_key[3] = const_word_in(in_key + 12);
13009+
13010+ kf = cx->aes_e_key;
13011+ kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
13012+ rci = 0;
13013+
13014+ switch(cx->aes_Nkey)
13015+ {
13016+ case 4: do
13017+ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
13018+ kf[5] = kf[1] ^ kf[4];
13019+ kf[6] = kf[2] ^ kf[5];
13020+ kf[7] = kf[3] ^ kf[6];
13021+ kf += 4;
13022+ }
13023+ while(kf < kt);
13024+ break;
13025+
13026+ case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
13027+ cx->aes_e_key[5] = const_word_in(in_key + 20);
13028+ do
13029+ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
13030+ kf[ 7] = kf[1] ^ kf[ 6];
13031+ kf[ 8] = kf[2] ^ kf[ 7];
13032+ kf[ 9] = kf[3] ^ kf[ 8];
13033+ kf[10] = kf[4] ^ kf[ 9];
13034+ kf[11] = kf[5] ^ kf[10];
13035+ kf += 6;
13036+ }
13037+ while(kf < kt);
13038+ break;
13039+
13040+ case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
13041+ cx->aes_e_key[5] = const_word_in(in_key + 20);
13042+ cx->aes_e_key[6] = const_word_in(in_key + 24);
13043+ cx->aes_e_key[7] = const_word_in(in_key + 28);
13044+ do
13045+ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
13046+ kf[ 9] = kf[1] ^ kf[ 8];
13047+ kf[10] = kf[2] ^ kf[ 9];
13048+ kf[11] = kf[3] ^ kf[10];
13049+ kf[12] = kf[4] ^ ls_box(kf[11],0);
13050+ kf[13] = kf[5] ^ kf[12];
13051+ kf[14] = kf[6] ^ kf[13];
13052+ kf[15] = kf[7] ^ kf[14];
13053+ kf += 8;
13054+ }
13055+ while (kf < kt);
13056+ break;
13057+ }
13058+
13059+ if(!f)
13060+ { u_int32_t i;
13061+
13062+ kt = cx->aes_d_key + nc * cx->aes_Nrnd;
13063+ kf = cx->aes_e_key;
13064+
13065+ cpy(kt, kf); kt -= 2 * nc;
13066+
13067+ for(i = 1; i < cx->aes_Nrnd; ++i)
13068+ {
13069+#if defined(ONE_TABLE) || defined(FOUR_TABLES)
13070+#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
13071+ u_int32_t f2, f4, f8, f9;
13072+#endif
13073+ mix(kt, kf);
13074+#else
13075+ cpy(kt, kf);
13076+#endif
13077+ kt -= 2 * nc;
13078+ }
13079+
13080+ cpy(kt, kf);
13081+ }
13082+}
13083+
13084+// y = output word, x = input word, r = row, c = column
13085+// for r = 0, 1, 2 and 3 = column accessed for row r
13086+
13087+#if defined(ARRAYS)
13088+#define s(x,c) x[c]
13089+#else
13090+#define s(x,c) x##c
13091+#endif
13092+
13093+// I am grateful to Frank Yellin for the following constructions
13094+// which, given the column (c) of the output state variable that
13095+// is being computed, return the input state variables which are
13096+// needed for each row (r) of the state
13097+
13098+// For the fixed block size options, compilers reduce these two
13099+// expressions to fixed variable references. For variable block
13100+// size code conditional clauses will sometimes be returned
13101+
13102+#define unused 77 // Sunset Strip
13103+
13104+#define fwd_var(x,r,c) \
13105+ ( r==0 ? \
13106+ ( c==0 ? s(x,0) \
13107+ : c==1 ? s(x,1) \
13108+ : c==2 ? s(x,2) \
13109+ : c==3 ? s(x,3) \
13110+ : c==4 ? s(x,4) \
13111+ : c==5 ? s(x,5) \
13112+ : c==6 ? s(x,6) \
13113+ : s(x,7)) \
13114+ : r==1 ? \
13115+ ( c==0 ? s(x,1) \
13116+ : c==1 ? s(x,2) \
13117+ : c==2 ? s(x,3) \
13118+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
13119+ : c==4 ? s(x,5) \
13120+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \
13121+ : c==6 ? s(x,7) \
13122+ : s(x,0)) \
13123+ : r==2 ? \
13124+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
13125+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
13126+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
13127+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
13128+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \
13129+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \
13130+ : c==6 ? s(x,1) \
13131+ : s(x,2)) \
13132+ : \
13133+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
13134+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
13135+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
13136+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
13137+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
13138+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
13139+ : c==6 ? s(x,2) \
13140+ : s(x,3)))
13141+
13142+#define inv_var(x,r,c) \
13143+ ( r==0 ? \
13144+ ( c==0 ? s(x,0) \
13145+ : c==1 ? s(x,1) \
13146+ : c==2 ? s(x,2) \
13147+ : c==3 ? s(x,3) \
13148+ : c==4 ? s(x,4) \
13149+ : c==5 ? s(x,5) \
13150+ : c==6 ? s(x,6) \
13151+ : s(x,7)) \
13152+ : r==1 ? \
13153+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
13154+ : c==1 ? s(x,0) \
13155+ : c==2 ? s(x,1) \
13156+ : c==3 ? s(x,2) \
13157+ : c==4 ? s(x,3) \
13158+ : c==5 ? s(x,4) \
13159+ : c==6 ? s(x,5) \
13160+ : s(x,6)) \
13161+ : r==2 ? \
13162+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
13163+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
13164+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
13165+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
13166+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
13167+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
13168+ : c==6 ? s(x,3) \
13169+ : s(x,4)) \
13170+ : \
13171+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
13172+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
13173+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
13174+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \
13175+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
13176+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
13177+ : c==6 ? s(x,2) \
13178+ : s(x,3)))
13179+
13180+#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
13181+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
13182+
13183+#if defined(FOUR_TABLES)
13184+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
13185+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
13186+#elif defined(ONE_TABLE)
13187+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
13188+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
13189+#else
13190+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
13191+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
13192+#endif
13193+
13194+#if defined(FOUR_LR_TABLES)
13195+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
13196+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
13197+#elif defined(ONE_LR_TABLE)
13198+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
13199+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
13200+#else
13201+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
13202+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
13203+#endif
13204+
13205+#if AES_BLOCK_SIZE == 16
13206+
13207+#if defined(ARRAYS)
13208+#define locals(y,x) x[4],y[4]
13209+#else
13210+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
13211+// the following defines prevent the compiler requiring the declaration
13212+// of generated but unused variables in the fwd_var and inv_var macros
13213+#define b04 unused
13214+#define b05 unused
13215+#define b06 unused
13216+#define b07 unused
13217+#define b14 unused
13218+#define b15 unused
13219+#define b16 unused
13220+#define b17 unused
13221+#endif
13222+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13223+ s(y,2) = s(x,2); s(y,3) = s(x,3);
13224+#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)
13225+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
13226+#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)
13227+
13228+#elif AES_BLOCK_SIZE == 24
13229+
13230+#if defined(ARRAYS)
13231+#define locals(y,x) x[6],y[6]
13232+#else
13233+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
13234+ y##0,y##1,y##2,y##3,y##4,y##5
13235+#define b06 unused
13236+#define b07 unused
13237+#define b16 unused
13238+#define b17 unused
13239+#endif
13240+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13241+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
13242+ s(y,4) = s(x,4); s(y,5) = s(x,5);
13243+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
13244+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
13245+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
13246+ so(y,x,3); so(y,x,4); so(y,x,5)
13247+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
13248+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
13249+#else
13250+
13251+#if defined(ARRAYS)
13252+#define locals(y,x) x[8],y[8]
13253+#else
13254+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
13255+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
13256+#endif
13257+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13258+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
13259+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
13260+ s(y,6) = s(x,6); s(y,7) = s(x,7);
13261+
13262+#if AES_BLOCK_SIZE == 32
13263+
13264+#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); \
13265+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
13266+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
13267+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
13268+#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); \
13269+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
13270+#else
13271+
13272+#define state_in(y,x,k) \
13273+switch(nc) \
13274+{ case 8: si(y,x,k,7); si(y,x,k,6); \
13275+ case 6: si(y,x,k,5); si(y,x,k,4); \
13276+ case 4: si(y,x,k,3); si(y,x,k,2); \
13277+ si(y,x,k,1); si(y,x,k,0); \
13278+}
13279+
13280+#define state_out(y,x) \
13281+switch(nc) \
13282+{ case 8: so(y,x,7); so(y,x,6); \
13283+ case 6: so(y,x,5); so(y,x,4); \
13284+ case 4: so(y,x,3); so(y,x,2); \
13285+ so(y,x,1); so(y,x,0); \
13286+}
13287+
13288+#if defined(FAST_VARIABLE)
13289+
13290+#define round(rm,y,x,k) \
13291+switch(nc) \
13292+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13293+ rm(y,x,k,5); rm(y,x,k,4); \
13294+ rm(y,x,k,3); rm(y,x,k,2); \
13295+ rm(y,x,k,1); rm(y,x,k,0); \
13296+ break; \
13297+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
13298+ rm(y,x,k,3); rm(y,x,k,2); \
13299+ rm(y,x,k,1); rm(y,x,k,0); \
13300+ break; \
13301+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
13302+ rm(y,x,k,1); rm(y,x,k,0); \
13303+ break; \
13304+}
13305+#else
13306+
13307+#define round(rm,y,x,k) \
13308+switch(nc) \
13309+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13310+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
13311+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
13312+ rm(y,x,k,1); rm(y,x,k,0); \
13313+}
13314+
13315+#endif
13316+
13317+#endif
13318+#endif
13319+
13320+void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13321+{ u_int32_t locals(b0, b1);
13322+ const u_int32_t *kp = cx->aes_e_key;
13323+
13324+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13325+ u_int32_t f2;
13326+#endif
13327+
13328+ state_in(b0, in_blk, kp); kp += nc;
13329+
13330+#if defined(UNROLL)
13331+
13332+ switch(cx->aes_Nrnd)
13333+ {
13334+ case 14: round(fwd_rnd, b1, b0, kp );
13335+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13336+ case 12: round(fwd_rnd, b1, b0, kp );
13337+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13338+ case 10: round(fwd_rnd, b1, b0, kp );
13339+ round(fwd_rnd, b0, b1, kp + nc);
13340+ round(fwd_rnd, b1, b0, kp + 2 * nc);
13341+ round(fwd_rnd, b0, b1, kp + 3 * nc);
13342+ round(fwd_rnd, b1, b0, kp + 4 * nc);
13343+ round(fwd_rnd, b0, b1, kp + 5 * nc);
13344+ round(fwd_rnd, b1, b0, kp + 6 * nc);
13345+ round(fwd_rnd, b0, b1, kp + 7 * nc);
13346+ round(fwd_rnd, b1, b0, kp + 8 * nc);
13347+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
13348+ }
13349+
13350+#elif defined(PARTIAL_UNROLL)
13351+ { u_int32_t rnd;
13352+
13353+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13354+ {
13355+ round(fwd_rnd, b1, b0, kp);
13356+ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
13357+ }
13358+
13359+ round(fwd_rnd, b1, b0, kp);
13360+ round(fwd_lrnd, b0, b1, kp + nc);
13361+ }
13362+#else
13363+ { u_int32_t rnd;
13364+
13365+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13366+ {
13367+ round(fwd_rnd, b1, b0, kp);
13368+ l_copy(b0, b1); kp += nc;
13369+ }
13370+
13371+ round(fwd_lrnd, b0, b1, kp);
13372+ }
13373+#endif
13374+
13375+ state_out(out_blk, b0);
13376+}
13377+
13378+void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13379+{ u_int32_t locals(b0, b1);
13380+ const u_int32_t *kp = cx->aes_d_key;
13381+
13382+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13383+ u_int32_t f2, f4, f8, f9;
13384+#endif
13385+
13386+ state_in(b0, in_blk, kp); kp += nc;
13387+
13388+#if defined(UNROLL)
13389+
13390+ switch(cx->aes_Nrnd)
13391+ {
13392+ case 14: round(inv_rnd, b1, b0, kp );
13393+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13394+ case 12: round(inv_rnd, b1, b0, kp );
13395+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13396+ case 10: round(inv_rnd, b1, b0, kp );
13397+ round(inv_rnd, b0, b1, kp + nc);
13398+ round(inv_rnd, b1, b0, kp + 2 * nc);
13399+ round(inv_rnd, b0, b1, kp + 3 * nc);
13400+ round(inv_rnd, b1, b0, kp + 4 * nc);
13401+ round(inv_rnd, b0, b1, kp + 5 * nc);
13402+ round(inv_rnd, b1, b0, kp + 6 * nc);
13403+ round(inv_rnd, b0, b1, kp + 7 * nc);
13404+ round(inv_rnd, b1, b0, kp + 8 * nc);
13405+ round(inv_lrnd, b0, b1, kp + 9 * nc);
13406+ }
13407+
13408+#elif defined(PARTIAL_UNROLL)
13409+ { u_int32_t rnd;
13410+
13411+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13412+ {
13413+ round(inv_rnd, b1, b0, kp);
13414+ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
13415+ }
13416+
13417+ round(inv_rnd, b1, b0, kp);
13418+ round(inv_lrnd, b0, b1, kp + nc);
13419+ }
13420+#else
13421+ { u_int32_t rnd;
13422+
13423+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13424+ {
13425+ round(inv_rnd, b1, b0, kp);
13426+ l_copy(b0, b1); kp += nc;
13427+ }
13428+
13429+ round(inv_lrnd, b0, b1, kp);
13430+ }
13431+#endif
13432+
13433+ state_out(out_blk, b0);
13434+}
13435--- /dev/null Tue Mar 11 13:02:56 2003
13436+++ linux/net/ipsec/aes/aes_cbc.c Mon Feb 9 13:51:03 2004
13437@@ -0,0 +1,46 @@
13438+/*
13439+// I retain copyright in this code but I encourage its free use provided
13440+// that I don't carry any responsibility for the results. I am especially
13441+// happy to see it used in free and open source software. If you do use
13442+// it I would appreciate an acknowledgement of its origin in the code or
13443+// the product that results and I would also appreciate knowing a little
13444+// about the use to which it is being put. I am grateful to Frank Yellin
13445+// for some ideas that are used in this implementation.
13446+//
13447+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
13448+//
13449+// This is an implementation of the AES encryption algorithm (Rijndael)
13450+// designed by Joan Daemen and Vincent Rijmen. This version is designed
13451+// to provide both fixed and dynamic block and key lengths and can also
13452+// run with either big or little endian internal byte order (see aes.h).
13453+// It inputs block and key lengths in bytes with the legal values being
13454+// 16, 24 and 32.
13455+*
13456+*/
13457+
13458+#ifdef __KERNEL__
13459+#include <linux/types.h>
13460+#else
13461+#include <sys/types.h>
13462+#endif
13463+#include "crypto/aes_cbc.h"
13464+#include "crypto/cbc_generic.h"
13465+
13466+/* returns bool success */
13467+int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
13468+ aes_set_key(aes_ctx, key, keysize, 0);
13469+ return 1;
13470+}
13471+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
13472+
13473+
13474+/*
13475+ * $Log: aes_cbc.c,v $
13476+ * Revision 1.2 2004/07/10 07:48:40 mcr
13477+ * Moved from linux/crypto/ciphers/aes/aes_cbc.c,v
13478+ *
13479+ * Revision 1.1 2004/04/06 02:48:12 mcr
13480+ * pullup of AES cipher from alg-branch.
13481+ *
13482+ *
13483+ */
13484--- /dev/null Tue Mar 11 13:02:56 2003
13485+++ linux/net/ipsec/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004
13486@@ -0,0 +1,67 @@
13487+#ifdef __KERNEL__
13488+#include <linux/types.h>
13489+#include <linux/kernel.h>
13490+#define DEBUG(x)
13491+#else
13492+#include <stdio.h>
13493+#include <sys/types.h>
13494+#define DEBUG(x) x
13495+#endif
13496+
13497+#include "crypto/aes.h"
13498+#include "crypto/aes_xcbc_mac.h"
13499+
13500+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
13501+{
13502+ int ret=1;
13503+ aes_block kn[3] = {
13504+ { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
13505+ { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
13506+ { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
13507+ };
13508+ aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
13509+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
13510+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
13511+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
13512+ aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
13513+ return ret;
13514+}
13515+static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
13516+ int pos=0;
13517+ for (pos=1; pos <= 16; pos++, in++, out++) {
13518+ if (pos <= len)
13519+ *out ^= *in;
13520+ if (pos > len) {
13521+ DEBUG(printf("put 0x80 at pos=%d\n", pos));
13522+ *out ^= 0x80;
13523+ break;
13524+ }
13525+ }
13526+}
13527+static void xor_block(aes_block res, const aes_block op) {
13528+ res[0] ^= op[0];
13529+ res[1] ^= op[1];
13530+ res[2] ^= op[2];
13531+ res[3] ^= op[3];
13532+}
13533+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
13534+ int ret=ilen;
13535+ u_int32_t out[4] = { 0, 0, 0, 0 };
13536+ for (; ilen > 16 ; ilen-=16) {
13537+ xor_block(out, (const u_int32_t*) &in[0]);
13538+ aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
13539+ in+=16;
13540+ }
13541+ do_pad_xor((u_int8_t *)&out, in, ilen);
13542+ if (ilen==16) {
13543+ DEBUG(printf("using k3\n"));
13544+ xor_block(out, ctxm->k3);
13545+ }
13546+ else
13547+ {
13548+ DEBUG(printf("using k2\n"));
13549+ xor_block(out, ctxm->k2);
13550+ }
13551+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
13552+ return ret;
13553+}
13554--- /dev/null Tue Mar 11 13:02:56 2003
13555+++ linux/net/ipsec/aes/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
13556@@ -0,0 +1,296 @@
13557+/*
13558+ * ipsec_alg AES cipher stubs
13559+ *
13560+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
13561+ *
13562+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13563+ *
13564+ * This program is free software; you can redistribute it and/or modify it
13565+ * under the terms of the GNU General Public License as published by the
13566+ * Free Software Foundation; either version 2 of the License, or (at your
13567+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13568+ *
13569+ * This program is distributed in the hope that it will be useful, but
13570+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13571+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13572+ * for more details.
13573+ *
13574+ * Fixes by:
13575+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
13576+ * Fixes list:
13577+ * PK: make XCBC comply with latest draft (keylength)
13578+ *
13579+ */
13580+#ifndef AUTOCONF_INCLUDED
13581+#include <linux/config.h>
13582+#endif
13583+#include <linux/version.h>
13584+
13585+/*
13586+ * special case: ipsec core modular with this static algo inside:
13587+ * must avoid MODULE magic for this file
13588+ */
13589+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_AES)
13590+#undef MODULE
13591+#endif
13592+
13593+#include <linux/module.h>
13594+#include <linux/init.h>
13595+
13596+#include <linux/kernel.h> /* printk() */
13597+#include <linux/errno.h> /* error codes */
13598+#include <linux/types.h> /* size_t */
13599+#include <linux/string.h>
13600+
13601+/* Check if __exit is defined, if not null it */
13602+#ifndef __exit
13603+#define __exit
13604+#endif
13605+
13606+/* Low freeswan header coupling */
13607+#include "openswan/ipsec_alg.h"
13608+#include "crypto/aes_cbc.h"
13609+
13610+#define CONFIG_KLIPS_ENC_AES_MAC 1
13611+
13612+#define AES_CONTEXT_T aes_context
13613+static int debug_aes=0;
13614+static int test_aes=0;
13615+static int excl_aes=0;
13616+static int keyminbits=0;
13617+static int keymaxbits=0;
13618+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13619+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
13620+#ifdef module_param
13621+module_param(debug_aes,int,0600)
13622+module_param(test_aes,int,0600)
13623+module_param(excl_aes,int,0600)
13624+module_param(keyminbits,int,0600)
13625+module_param(keymaxbits,int,0600)
13626+#else
13627+MODULE_PARM(debug_aes, "i");
13628+MODULE_PARM(test_aes, "i");
13629+MODULE_PARM(excl_aes, "i");
13630+MODULE_PARM(keyminbits, "i");
13631+MODULE_PARM(keymaxbits, "i");
13632+#endif
13633+#endif
13634+
13635+#if CONFIG_KLIPS_ENC_AES_MAC
13636+#include "crypto/aes_xcbc_mac.h"
13637+
13638+/*
13639+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
13640+ * We use 9 for non-modular algorithm and none for modular, thus
13641+ * forcing user to specify one on module load. -kravietz
13642+ */
13643+#ifdef MODULE
13644+static int auth_id=0;
13645+#else
13646+static int auth_id=9;
13647+#endif
13648+#ifdef module_param
13649+module_param(auth_id, int, 0600);
13650+#else
13651+MODULE_PARM(auth_id, "i");
13652+#endif
13653+#endif
13654+
13655+#define ESP_AES 12 /* truely _constant_ :) */
13656+
13657+/* 128, 192 or 256 */
13658+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
13659+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
13660+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
13661+
13662+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
13663+ * -kravietz
13664+ */
13665+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
13666+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
13667+
13668+static int _aes_set_key(struct ipsec_alg_enc *alg,
13669+ __u8 * key_e, const __u8 * key,
13670+ size_t keysize)
13671+{
13672+ int ret;
13673+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13674+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
13675+ if (debug_aes > 0)
13676+ printk(KERN_DEBUG "klips_debug:_aes_set_key:"
13677+ "ret=%d key_e=%p key=%p keysize=%ld\n",
13678+ ret, key_e, key, (unsigned long int) keysize);
13679+ return ret;
13680+}
13681+
13682+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e,
13683+ __u8 * in, int ilen, const __u8 * iv,
13684+ int encrypt)
13685+{
13686+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13687+ if (debug_aes > 0)
13688+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
13689+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
13690+ key_e, in, ilen, iv, encrypt);
13691+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
13692+}
13693+#if CONFIG_KLIPS_ENC_AES_MAC
13694+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
13695+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
13696+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
13697+}
13698+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
13699+ int ret;
13700+ char hash_buf[16];
13701+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
13702+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
13703+ memcpy(hash, hash_buf, hashlen);
13704+ return ret;
13705+}
13706+static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
13707+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13708+ ixt_refcnt: ATOMIC_INIT(0),
13709+ ixt_name: "aes_mac",
13710+ ixt_blocksize: ESP_AES_MAC_BLK_LEN,
13711+ ixt_support: {
13712+ ias_exttype: IPSEC_ALG_TYPE_AUTH,
13713+ ias_id: 0,
13714+ ias_keyminbits: ESP_AES_MAC_KEY_SZ*8,
13715+ ias_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
13716+ },
13717+ },
13718+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13719+ ixt_module: THIS_MODULE,
13720+#endif
13721+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
13722+ ixt_a_ctx_size: sizeof(aes_context_mac),
13723+ ixt_a_hmac_set_key: _aes_mac_set_key,
13724+ ixt_a_hmac_hash:_aes_mac_hash,
13725+};
13726+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13727+static struct ipsec_alg_enc ipsec_alg_AES = {
13728+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13729+ ixt_refcnt: ATOMIC_INIT(0),
13730+ ixt_name: "aes",
13731+ ixt_blocksize: ESP_AES_CBC_BLK_LEN,
13732+ ixt_support: {
13733+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
13734+ ias_id: ESP_AES,
13735+ ias_keyminbits: ESP_AES_KEY_SZ_MIN*8,
13736+ ias_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
13737+ },
13738+ },
13739+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13740+ ixt_module: THIS_MODULE,
13741+#endif
13742+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
13743+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
13744+ ixt_e_set_key: _aes_set_key,
13745+ ixt_e_cbc_encrypt:_aes_cbc_encrypt,
13746+};
13747+
13748+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13749+IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
13750+#else
13751+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
13752+#endif
13753+{
13754+ int ret, test_ret;
13755+
13756+ if (keyminbits)
13757+ ipsec_alg_AES.ixt_common.ixt_support.ias_keyminbits=keyminbits;
13758+ if (keymaxbits) {
13759+ ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits=keymaxbits;
13760+ if (keymaxbits*8>ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits)
13761+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
13762+ }
13763+ if (excl_aes) ipsec_alg_AES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
13764+ ret=register_ipsec_alg_enc(&ipsec_alg_AES);
13765+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13766+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype,
13767+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13768+ ipsec_alg_AES.ixt_common.ixt_name,
13769+ ret);
13770+ if (ret==0 && test_aes) {
13771+ test_ret=ipsec_alg_test(
13772+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13773+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13774+ test_aes);
13775+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13776+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13777+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13778+ test_ret);
13779+ }
13780+#if CONFIG_KLIPS_ENC_AES_MAC
13781+ if (auth_id!=0){
13782+ int ret;
13783+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id=auth_id;
13784+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13785+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13786+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13787+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13788+ ipsec_alg_AES_MAC.ixt_common.ixt_name,
13789+ ret);
13790+ if (ret==0 && test_aes) {
13791+ test_ret=ipsec_alg_test(
13792+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13793+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13794+ test_aes);
13795+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13796+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13797+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13798+ test_ret);
13799+ }
13800+ } else {
13801+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
13802+ }
13803+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13804+ return ret;
13805+}
13806+
13807+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13808+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
13809+#else
13810+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
13811+#endif
13812+{
13813+#if CONFIG_KLIPS_ENC_AES_MAC
13814+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13815+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13816+ unregister_ipsec_alg_enc(&ipsec_alg_AES);
13817+ return;
13818+}
13819+#ifdef MODULE_LICENSE
13820+MODULE_LICENSE("GPL");
13821+#endif
13822+
13823+#if 0 /* +NOT_YET */
13824+#ifndef MODULE
13825+/*
13826+ * This is intended for static module setups, currently
13827+ * doesn't work for modular ipsec.o with static algos inside
13828+ */
13829+static int setup_keybits(const char *str)
13830+{
13831+ unsigned aux;
13832+ char *end;
13833+
13834+ aux = simple_strtoul(str,&end,0);
13835+ if (aux != 128 && aux != 192 && aux != 256)
13836+ return 0;
13837+ keyminbits = aux;
13838+
13839+ if (*end == 0 || *end != ',')
13840+ return 1;
13841+ str=end+1;
13842+ aux = simple_strtoul(str, NULL, 0);
13843+ if (aux != 128 && aux != 192 && aux != 256)
13844+ return 0;
13845+ if (aux >= keyminbits)
13846+ keymaxbits = aux;
13847+ return 1;
13848+}
13849+__setup("ipsec_aes_keybits=", setup_keybits);
13850+#endif
13851+#endif
13852+
13853--- /dev/null Tue Mar 11 13:02:56 2003
13854+++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004
13855@@ -0,0 +1,3 @@
13856+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13857+ tristate ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES
13858+fi
13859--- /dev/null Tue Mar 11 13:02:56 2003
13860+++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004
13861@@ -0,0 +1,6 @@
13862+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13863+ dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
13864+ if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
13865+ bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
13866+ fi
13867+fi
13868--- /dev/null Tue Mar 11 13:02:56 2003
13869+++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004
13870@@ -0,0 +1,3 @@
13871+#Placeholder
13872+source net/ipsec/alg/Config.alg_aes.in
13873+source net/ipsec/alg/Config.alg_cryptoapi.in
13874--- /dev/null Tue Mar 11 13:02:56 2003
13875+++ linux/net/ipsec/alg/Makefile Mon Feb 9 13:51:03 2004
13876@@ -0,0 +1,112 @@
13877+# Makefile,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13878+ifeq ($(strip $(KLIPSMODULE)),)
13879+FREESWANSRCDIR=.
13880+else
13881+FREESWANSRCDIR=../../../..
13882+endif
13883+ifeq ($(strip $(KLIPS_TOP)),)
13884+KLIPS_TOP=../../..
13885+override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include
13886+endif
13887+
13888+ifeq ($(CONFIG_IPSEC_DEBUG),y)
13889+override EXTRA_CFLAGS += -g
13890+endif
13891+
13892+# LIBCRYPTO normally comes as an argument from "parent" Makefile
13893+# (this applies both to FS' "make module" and eg. Linux' "make modules"
13894+# But make dep doest follow same evaluations, so we need this default:
13895+LIBCRYPTO=$(TOPDIR)/lib/libcrypto
13896+
13897+override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include
13898+override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes
13899+
13900+MOD_LIST_NAME := NET_MISC_MODULES
13901+
13902+#O_TARGET := static_init.o
13903+
13904+subdir- :=
13905+subdir-n :=
13906+subdir-y :=
13907+subdir-m :=
13908+
13909+obj-y := static_init.o
13910+
13911+ARCH_ASM-y :=
13912+ARCH_ASM-$(CONFIG_M586) := i586
13913+ARCH_ASM-$(CONFIG_M586TSC) := i586
13914+ARCH_ASM-$(CONFIG_M586MMX) := i586
13915+ARCH_ASM-$(CONFIG_MK6) := i586
13916+ARCH_ASM-$(CONFIG_M686) := i686
13917+ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686
13918+ARCH_ASM-$(CONFIG_MPENTIUM4) := i686
13919+ARCH_ASM-$(CONFIG_MK7) := i686
13920+ARCH_ASM-$(CONFIG_MCRUSOE) := i586
13921+ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586
13922+ARCH_ASM-$(CONFIG_MWINCHIP2) := i586
13923+ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586
13924+ARCH_ASM-$(CONFIG_USERMODE) := i586
13925+
13926+ARCH_ASM :=$(ARCH_ASM-y)
13927+ifdef NO_ASM
13928+ARCH_ASM :=
13929+endif
13930+
13931+# The algorithm makefiles may put dependences, short-circuit them
13932+null:
13933+
13934+makefiles=$(filter-out %.preipsec, $(wildcard Makefile.alg_*))
13935+ifneq ($(makefiles),)
13936+#include Makefile.alg_aes
13937+#include Makefile.alg_aes-opt
13938+include $(makefiles)
13939+endif
13940+
13941+# These rules translate from new to old makefile rules
13942+# Translate to Rules.make lists.
13943+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m))
13944+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs))
13945+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m))
13946+O_OBJS := $(obj-y)
13947+M_OBJS := $(obj-m)
13948+MIX_OBJS := $(filter $(export-objs), $(active-objs))
13949+#OX_OBJS := $(export-objs)
13950+SUB_DIRS := $(subdir-y)
13951+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
13952+MOD_SUB_DIRS := $(subdir-m)
13953+
13954+
13955+static_init_mod.o: $(obj-y)
13956+ rm -f $@
13957+ $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@
13958+
13959+perlasm: ../../../crypto/ciphers/des/asm/perlasm
13960+ ln -sf $? $@
13961+
13962+$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
13963+$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
13964+
13965+
13966+all_alg_modules: perlasm $(ALG_MODULES)
13967+ @echo "ALG_MODULES=$(ALG_MODULES)"
13968+
13969+
13970+#
13971+# Construct alg. init. function: call ipsec_ALGO_init() for every static algo
13972+# Needed when there are static algos (with static or modular ipsec.o)
13973+#
13974+static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh
13975+ @echo "Re-creating $@"
13976+ $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@
13977+
13978+clean:
13979+ @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0
13980+ @find . -type l -exec rm -f {} \;
13981+ -rm -f perlasm
13982+ -rm -rf $(ALG_SUBDIRS)
13983+ -rm -f *.o static_init.c
13984+
13985+ifdef TOPDIR
13986+include $(TOPDIR)/Rules.make
13987+endif
13988+
13989--- /dev/null Tue Mar 11 13:02:56 2003
13990+++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004
13991@@ -0,0 +1,18 @@
13992+MOD_AES := ipsec_aes.o
13993+
13994+ALG_MODULES += $(MOD_AES)
13995+ALG_SUBDIRS += libaes
13996+
13997+obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
13998+static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
13999+alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
14000+
14001+AES_OBJS := ipsec_alg_aes.o $(LIBCRYPTO)/libaes/libaes.a
14002+
14003+
14004+$(MOD_AES): $(AES_OBJS)
14005+ $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
14006+
14007+$(LIBCRYPTO)/libaes/libaes.a:
14008+ $(MAKE) -C $(LIBCRYPTO)/libaes CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a
14009+
14010--- /dev/null Tue Mar 11 13:02:56 2003
14011+++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004
14012@@ -0,0 +1,14 @@
14013+MOD_CRYPTOAPI := ipsec_cryptoapi.o
14014+
14015+ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
14016+ALG_MODULES += $(MOD_CRYPTOAPI)
14017+obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
14018+static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
14019+alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
14020+else
14021+$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
14022+endif
14023+
14024+CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
14025+$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
14026+ $(LD) -r $(CRYPTOAPI_OBJS) -o $@
14027--- /dev/null Tue Mar 11 13:02:56 2003
14028+++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
14029@@ -0,0 +1,442 @@
14030+/*
14031+ * ipsec_alg to linux cryptoapi GLUE
14032+ *
14033+ * Authors: CODE.ar TEAM
14034+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
14035+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
14036+ * Luciano Ruete <docemeses@softhome.net>
14037+ *
14038+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
14039+ *
14040+ * This program is free software; you can redistribute it and/or modify it
14041+ * under the terms of the GNU General Public License as published by the
14042+ * Free Software Foundation; either version 2 of the License, or (at your
14043+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
14044+ *
14045+ * This program is distributed in the hope that it will be useful, but
14046+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14047+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14048+ * for more details.
14049+ *
14050+ * Example usage:
14051+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
14052+ * modprobe ipsec_cryptoapi
14053+ * modprobe ipsec_cryptoapi test=1
14054+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
14055+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
14056+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
14057+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
14058+ */
14059+#ifndef AUTOCONF_INCLUDED
14060+#include <linux/config.h>
14061+#endif
14062+#include <linux/version.h>
14063+
14064+/*
14065+ * special case: ipsec core modular with this static algo inside:
14066+ * must avoid MODULE magic for this file
14067+ */
14068+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
14069+#undef MODULE
14070+#endif
14071+
14072+#include <linux/module.h>
14073+#include <linux/init.h>
14074+
14075+#include <linux/kernel.h> /* printk() */
14076+#include <linux/errno.h> /* error codes */
14077+#include <linux/types.h> /* size_t */
14078+#include <linux/string.h>
14079+
14080+/* Check if __exit is defined, if not null it */
14081+#ifndef __exit
14082+#define __exit
14083+#endif
14084+
14085+/* warn the innocent */
14086+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
14087+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
14088+#define NO_CRYPTOAPI_SUPPORT
14089+#endif
14090+/* Low freeswan header coupling */
14091+#include "openswan/ipsec_alg.h"
14092+
14093+#include <linux/crypto.h>
14094+#ifdef CRYPTO_API_VERSION_CODE
14095+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
14096+#define NO_CRYPTOAPI_SUPPORT
14097+#endif
14098+
14099+#ifdef NO_CRYPTOAPI_SUPPORT
14100+#warning "Building an unusable module :P"
14101+/* Catch old CryptoAPI by not allowing module to load */
14102+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
14103+{
14104+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
14105+ return -EINVAL;
14106+}
14107+#else
14108+#include <asm/scatterlist.h>
14109+#include <asm/pgtable.h>
14110+#include <linux/mm.h>
14111+
14112+#define CIPHERNAME_AES "aes"
14113+#define CIPHERNAME_3DES "des3_ede"
14114+#define CIPHERNAME_BLOWFISH "blowfish"
14115+#define CIPHERNAME_CAST "cast5"
14116+#define CIPHERNAME_SERPENT "serpent"
14117+#define CIPHERNAME_TWOFISH "twofish"
14118+
14119+#define ESP_3DES 3
14120+#define ESP_AES 12
14121+#define ESP_BLOWFISH 7 /* truely _constant_ :) */
14122+#define ESP_CAST 6 /* quite constant :) */
14123+#define ESP_SERPENT 252 /* from ipsec drafts */
14124+#define ESP_TWOFISH 253 /* from ipsec drafts */
14125+
14126+#define AH_MD5 2
14127+#define AH_SHA 3
14128+#define DIGESTNAME_MD5 "md5"
14129+#define DIGESTNAME_SHA1 "sha1"
14130+
14131+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
14132+static int debug=0;
14133+static int test=0;
14134+static int excl=0;
14135+static int noauto = 0;
14136+
14137+static int des_ede3[] = {-1, -1};
14138+static int aes[] = {-1, -1};
14139+static int blowfish[] = {-1, -1};
14140+static int cast[] = {-1, -1};
14141+static int serpent[] = {-1, -1};
14142+static int twofish[] = {-1, -1};
14143+
14144+#ifdef module_param
14145+module_param(debug,int,0600);
14146+module_param(test,int,0600);
14147+module_param(ebug,int,0600);
14148+
14149+module_param(noauto,int,0600);
14150+module_param(ebug,int,0600);
14151+
14152+module_param_array(des_ede3,int,NULL,0);
14153+module_param(aes,int,NULL,0);
14154+module_param(blowfish,int,NULL,0);
14155+module_param(cast,int,NULL,0);
14156+module_param(serpent,int,NULL,0);
14157+module_param(twofish,int,NULL,0);
14158+#else
14159+MODULE_PARM(debug, "i");
14160+MODULE_PARM(test, "i");
14161+MODULE_PARM(excl, "i");
14162+
14163+MODULE_PARM(noauto,"i");
14164+
14165+MODULE_PARM(des_ede3,"1-2i");
14166+MODULE_PARM(aes,"1-2i");
14167+MODULE_PARM(blowfish,"1-2i");
14168+MODULE_PARM(cast,"1-2i");
14169+MODULE_PARM(serpent,"1-2i");
14170+MODULE_PARM(twofish,"1-2i");
14171+#endif
14172+
14173+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
14174+
14175+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
14176+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
14177+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
14178+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
14179+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
14180+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
14181+
14182+struct ipsec_alg_capi_cipher {
14183+ const char *ciphername; /* cryptoapi's ciphername */
14184+ unsigned blocksize;
14185+ unsigned short minbits;
14186+ unsigned short maxbits;
14187+ int *parm; /* lkm param for this cipher */
14188+ struct ipsec_alg_enc alg; /* note it's not a pointer */
14189+};
14190+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
14191+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
14192+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
14193+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
14194+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
14195+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
14196+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
14197+ { NULL, 0, 0, 0, NULL, {} }
14198+};
14199+#ifdef NOT_YET
14200+struct ipsec_alg_capi_digest {
14201+ const char *digestname; /* cryptoapi's digestname */
14202+ struct digest_implementation *di;
14203+ struct ipsec_alg_auth alg; /* note it's not a pointer */
14204+};
14205+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
14206+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
14207+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
14208+ { NULL, NULL, {} }
14209+};
14210+#endif
14211+/*
14212+ * "generic" linux cryptoapi setup_cipher() function
14213+ */
14214+int setup_cipher(const char *ciphername)
14215+{
14216+ return crypto_alg_available(ciphername, 0);
14217+}
14218+
14219+/*
14220+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
14221+ * register_ipsec_alg for cointaned ipsec_alg object
14222+ */
14223+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
14224+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
14225+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
14226+
14227+static int
14228+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
14229+{
14230+ int ret;
14231+ cptr->alg.ixt_version = IPSEC_ALG_VERSION;
14232+ cptr->alg.ixt_module = THIS_MODULE;
14233+ atomic_set (& cptr->alg.ixt_refcnt, 0);
14234+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
14235+
14236+ cptr->alg.ixt_blocksize=cptr->blocksize;
14237+ cptr->alg.ixt_keyminbits=cptr->minbits;
14238+ cptr->alg.ixt_keymaxbits=cptr->maxbits;
14239+ cptr->alg.ixt_state = 0;
14240+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
14241+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
14242+ cptr->alg.ixt_e_ctx_size = 0;
14243+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
14244+ cptr->alg.ixt_e_new_key = _capi_new_key;
14245+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
14246+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
14247+ cptr->alg.ixt_data = cptr;
14248+
14249+ ret=register_ipsec_alg_enc(&cptr->alg);
14250+ printk("setup_ipsec_alg_capi_cipher(): "
14251+ "alg_type=%d alg_id=%d name=%s "
14252+ "keyminbits=%d keymaxbits=%d, ret=%d\n",
14253+ cptr->alg.ixt_alg_type,
14254+ cptr->alg.ixt_alg_id,
14255+ cptr->alg.ixt_name,
14256+ cptr->alg.ixt_keyminbits,
14257+ cptr->alg.ixt_keymaxbits,
14258+ ret);
14259+ return ret;
14260+}
14261+/*
14262+ * called in ipsec_sa_wipe() time, will destroy key contexts
14263+ * and do 1 unbind()
14264+ */
14265+static void
14266+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
14267+{
14268+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
14269+
14270+ if (debug > 0)
14271+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
14272+ "name=%s key_e=%p \n",
14273+ alg->ixt_name, key_e);
14274+ if (!key_e) {
14275+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
14276+ "name=%s NULL key_e!\n",
14277+ alg->ixt_name);
14278+ return;
14279+ }
14280+ crypto_free_tfm(tfm);
14281+}
14282+
14283+/*
14284+ * create new key context, need alg->ixt_data to know which
14285+ * (of many) cipher inside this module is the target
14286+ */
14287+static __u8 *
14288+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
14289+{
14290+ struct ipsec_alg_capi_cipher *cptr;
14291+ struct crypto_tfm *tfm=NULL;
14292+
14293+ cptr = alg->ixt_data;
14294+ if (!cptr) {
14295+ printk(KERN_ERR "_capi_new_key(): "
14296+ "NULL ixt_data (?!) for \"%s\" algo\n"
14297+ , alg->ixt_name);
14298+ goto err;
14299+ }
14300+ if (debug > 0)
14301+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
14302+ "name=%s cptr=%p key=%p keysize=%d\n",
14303+ alg->ixt_name, cptr, key, keylen);
14304+
14305+ /*
14306+ * alloc tfm
14307+ */
14308+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
14309+ if (!tfm) {
14310+ printk(KERN_ERR "_capi_new_key(): "
14311+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
14312+ , alg->ixt_name, cptr->ciphername);
14313+ goto err;
14314+ }
14315+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
14316+ printk(KERN_ERR "_capi_new_key(): "
14317+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
14318+ , alg->ixt_name, keylen);
14319+ crypto_free_tfm(tfm);
14320+ tfm=NULL;
14321+ }
14322+err:
14323+ if (debug > 0)
14324+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
14325+ "name=%s key=%p keylen=%d tfm=%p\n",
14326+ alg->ixt_name, key, keylen, tfm);
14327+ return (__u8 *) tfm;
14328+}
14329+/*
14330+ * core encryption function: will use cx->ci to call actual cipher's
14331+ * cbc function
14332+ */
14333+static int
14334+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
14335+ int error =0;
14336+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
14337+ struct scatterlist sg = {
14338+ .page = virt_to_page(in),
14339+ .offset = (unsigned long)(in) % PAGE_SIZE,
14340+ .length=ilen,
14341+ };
14342+ if (debug > 1)
14343+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
14344+ "key_e=%p "
14345+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
14346+ , key_e
14347+ , in, in, ilen, iv, encrypt);
14348+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
14349+ if (encrypt)
14350+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
14351+ else
14352+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
14353+ if (debug > 1)
14354+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
14355+ "error=%d\n"
14356+ , error);
14357+ return (error<0)? error : ilen;
14358+}
14359+/*
14360+ * main initialization loop: for each cipher in list, do
14361+ * 1) setup cryptoapi cipher else continue
14362+ * 2) register ipsec_alg object
14363+ */
14364+static int
14365+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
14366+{
14367+ struct ipsec_alg_capi_cipher *cptr;
14368+ /* foreach cipher in list ... */
14369+ for (cptr=clist;cptr->ciphername;cptr++) {
14370+ /*
14371+ * see if cipher has been disabled (0) or
14372+ * if noauto set and not enabled (1)
14373+ */
14374+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
14375+ if (debug>0)
14376+ printk(KERN_INFO "setup_cipher_list(): "
14377+ "ciphername=%s skipped at user request: "
14378+ "noauto=%d parm[0]=%d parm[1]=%d\n"
14379+ , cptr->ciphername
14380+ , noauto
14381+ , cptr->parm[0]
14382+ , cptr->parm[1]);
14383+ continue;
14384+ }
14385+ /*
14386+ * use a local ci to avoid touching cptr->ci,
14387+ * if register ipsec_alg success then bind cipher
14388+ */
14389+ if( setup_cipher(cptr->ciphername) ) {
14390+ if (debug > 0)
14391+ printk(KERN_DEBUG "klips_debug:"
14392+ "setup_cipher_list():"
14393+ "ciphername=%s found\n"
14394+ , cptr->ciphername);
14395+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
14396+
14397+
14398+ } else {
14399+ printk(KERN_ERR "klips_debug:"
14400+ "setup_cipher_list():"
14401+ "ciphername=%s failed ipsec_alg_register\n"
14402+ , cptr->ciphername);
14403+ }
14404+ } else {
14405+ if (debug>0)
14406+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
14407+ cptr->ciphername);
14408+ }
14409+ }
14410+ return 0;
14411+}
14412+/*
14413+ * deregister ipsec_alg objects and unbind ciphers
14414+ */
14415+static int
14416+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
14417+{
14418+ struct ipsec_alg_capi_cipher *cptr;
14419+ /* foreach cipher in list ... */
14420+ for (cptr=clist;cptr->ciphername;cptr++) {
14421+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14422+ unregister_ipsec_alg_enc(&cptr->alg);
14423+ }
14424+ }
14425+ return 0;
14426+}
14427+/*
14428+ * test loop for registered algos
14429+ */
14430+static int
14431+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
14432+{
14433+ int test_ret;
14434+ struct ipsec_alg_capi_cipher *cptr;
14435+ /* foreach cipher in list ... */
14436+ for (cptr=clist;cptr->ciphername;cptr++) {
14437+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14438+ test_ret=ipsec_alg_test(
14439+ cptr->alg.ixt_alg_type,
14440+ cptr->alg.ixt_alg_id,
14441+ test);
14442+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
14443+ cptr->alg.ixt_alg_type,
14444+ cptr->alg.ixt_alg_id,
14445+ test_ret);
14446+ }
14447+ }
14448+ return 0;
14449+}
14450+
14451+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
14452+{
14453+ int ret, test_ret;
14454+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
14455+ return -EPROTONOSUPPORT;
14456+ if (ret==0 && test) {
14457+ test_ret=test_cipher_list(alg_capi_carray);
14458+ }
14459+ return ret;
14460+}
14461+IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
14462+{
14463+ unsetup_cipher_list(alg_capi_carray);
14464+ return;
14465+}
14466+#ifdef MODULE_LICENSE
14467+MODULE_LICENSE("GPL");
14468+#endif
14469+
14470+EXPORT_NO_SYMBOLS;
14471+#endif /* NO_CRYPTOAPI_SUPPORT */
14472--- /dev/null Tue Mar 11 13:02:56 2003
14473+++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004
14474@@ -0,0 +1,18 @@
14475+#!/bin/sh
14476+cat << EOF
14477+#include <linux/kernel.h>
14478+#include <linux/list.h>
14479+#include "freeswan/ipsec_alg.h"
14480+$(for i in $*; do
14481+ test -z "$i" && continue
14482+ echo "extern int $i(void);"
14483+done)
14484+void ipsec_alg_static_init(void){
14485+ int __attribute__ ((unused)) err=0;
14486+$(for i in $*; do
14487+ test -z "$i" && continue
14488+ echo " if ((err=$i()) < 0)"
14489+ echo " printk(KERN_WARNING \"$i() returned %d\", err);"
14490+done)
14491+}
14492+EOF
14493--- /dev/null Tue Mar 11 13:02:56 2003
14494+++ linux/net/ipsec/anyaddr.c Mon Feb 9 13:51:03 2004
14495@@ -0,0 +1,148 @@
14496+/*
14497+ * special addresses
14498+ * Copyright (C) 2000 Henry Spencer.
14499+ *
14500+ * This library is free software; you can redistribute it and/or modify it
14501+ * under the terms of the GNU Library General Public License as published by
14502+ * the Free Software Foundation; either version 2 of the License, or (at your
14503+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14504+ *
14505+ * This library is distributed in the hope that it will be useful, but
14506+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14507+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14508+ * License for more details.
14509+ *
14510+ * RCSID $Id: anyaddr.c,v 1.10.10.1 2006/11/24 05:55:46 paul Exp $
14511+ */
14512+#include "openswan.h"
14513+
14514+/* these are mostly fallbacks for the no-IPv6-support-in-library case */
14515+#ifndef IN6ADDR_ANY_INIT
14516+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
14517+#endif
14518+#ifndef IN6ADDR_LOOPBACK_INIT
14519+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
14520+#endif
14521+
14522+static struct in6_addr v6any = IN6ADDR_ANY_INIT;
14523+static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
14524+
14525+/*
14526+ - anyaddr - initialize to the any-address value
14527+ */
14528+err_t /* NULL for success, else string literal */
14529+anyaddr(af, dst)
14530+int af; /* address family */
14531+ip_address *dst;
14532+{
14533+ uint32_t v4any = htonl(INADDR_ANY);
14534+
14535+ switch (af) {
14536+ case AF_INET:
14537+ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
14538+ break;
14539+ case AF_INET6:
14540+ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
14541+ break;
14542+ default:
14543+ return "unknown address family in anyaddr/unspecaddr";
14544+ break;
14545+ }
14546+}
14547+
14548+/*
14549+ - unspecaddr - initialize to the unspecified-address value
14550+ */
14551+err_t /* NULL for success, else string literal */
14552+unspecaddr(af, dst)
14553+int af; /* address family */
14554+ip_address *dst;
14555+{
14556+ return anyaddr(af, dst);
14557+}
14558+
14559+/*
14560+ - loopbackaddr - initialize to the loopback-address value
14561+ */
14562+err_t /* NULL for success, else string literal */
14563+loopbackaddr(af, dst)
14564+int af; /* address family */
14565+ip_address *dst;
14566+{
14567+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
14568+
14569+ switch (af) {
14570+ case AF_INET:
14571+ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
14572+ break;
14573+ case AF_INET6:
14574+ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
14575+ break;
14576+ default:
14577+ return "unknown address family in loopbackaddr";
14578+ break;
14579+ }
14580+}
14581+
14582+/*
14583+ - isanyaddr - test for the any-address value
14584+ */
14585+int
14586+isanyaddr(src)
14587+const ip_address *src;
14588+{
14589+ uint32_t v4any = htonl(INADDR_ANY);
14590+ int cmp;
14591+
14592+ switch (src->u.v4.sin_family) {
14593+ case AF_INET:
14594+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
14595+ break;
14596+ case AF_INET6:
14597+ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
14598+ break;
14599+ case 0:
14600+ /* a zeroed structure is considered any address */
14601+ return 1;
14602+ default:
14603+ return 0;
14604+ break;
14605+ }
14606+
14607+ return (cmp == 0) ? 1 : 0;
14608+}
14609+
14610+/*
14611+ - isunspecaddr - test for the unspecified-address value
14612+ */
14613+int
14614+isunspecaddr(src)
14615+const ip_address *src;
14616+{
14617+ return isanyaddr(src);
14618+}
14619+
14620+/*
14621+ - isloopbackaddr - test for the loopback-address value
14622+ */
14623+int
14624+isloopbackaddr(src)
14625+const ip_address *src;
14626+{
14627+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
14628+ int cmp;
14629+
14630+ switch (src->u.v4.sin_family) {
14631+ case AF_INET:
14632+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
14633+ break;
14634+ case AF_INET6:
14635+ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
14636+ break;
14637+ default:
14638+ return 0;
14639+ break;
14640+ }
14641+
14642+ return (cmp == 0) ? 1 : 0;
14643+}
14644--- /dev/null Tue Mar 11 13:02:56 2003
14645+++ linux/net/ipsec/datatot.c Mon Feb 9 13:51:03 2004
14646@@ -0,0 +1,234 @@
14647+/*
14648+ * convert from binary data (e.g. key) to text form
14649+ * Copyright (C) 2000 Henry Spencer.
14650+ *
14651+ * This library is free software; you can redistribute it and/or modify it
14652+ * under the terms of the GNU Library General Public License as published by
14653+ * the Free Software Foundation; either version 2 of the License, or (at your
14654+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14655+ *
14656+ * This library is distributed in the hope that it will be useful, but
14657+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14658+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14659+ * License for more details.
14660+ *
14661+ * RCSID $Id: datatot.c,v 1.7 2005/04/14 20:48:43 mcr Exp $
14662+ */
14663+#include "openswan.h"
14664+
14665+static void convert(const char *src, size_t nreal, int format, char *out);
14666+
14667+/*
14668+ - datatot - convert data bytes to text
14669+ */
14670+size_t /* true length (with NUL) for success */
14671+datatot(src, srclen, format, dst, dstlen)
14672+const char *src;
14673+size_t srclen;
14674+int format; /* character indicating what format */
14675+char *dst; /* need not be valid if dstlen is 0 */
14676+size_t dstlen;
14677+{
14678+ size_t inblocksize; /* process this many bytes at a time */
14679+ size_t outblocksize; /* producing this many */
14680+ size_t breakevery; /* add a _ every this many (0 means don't) */
14681+ size_t sincebreak; /* output bytes since last _ */
14682+ char breakchar; /* character used to break between groups */
14683+ char inblock[10]; /* enough for any format */
14684+ char outblock[10]; /* enough for any format */
14685+ char fake[1]; /* fake output area for dstlen == 0 */
14686+ size_t needed; /* return value */
14687+ char *stop; /* where the terminating NUL will go */
14688+ size_t ntodo; /* remaining input */
14689+ size_t nreal;
14690+ char *out;
14691+ char *prefix;
14692+
14693+ breakevery = 0;
14694+ breakchar = '_';
14695+
14696+ switch (format) {
14697+ case 0:
14698+ case 'h':
14699+ format = 'x';
14700+ breakevery = 8;
14701+ /* FALLTHROUGH */
14702+ case 'x':
14703+ inblocksize = 1;
14704+ outblocksize = 2;
14705+ prefix = "0x";
14706+ break;
14707+ case ':':
14708+ format = 'x';
14709+ breakevery = 2;
14710+ breakchar = ':';
14711+ /* FALLTHROUGH */
14712+ case 16:
14713+ inblocksize = 1;
14714+ outblocksize = 2;
14715+ prefix = "";
14716+ format = 'x';
14717+ break;
14718+ case 's':
14719+ inblocksize = 3;
14720+ outblocksize = 4;
14721+ prefix = "0s";
14722+ break;
14723+ case 64: /* beware, equals ' ' */
14724+ inblocksize = 3;
14725+ outblocksize = 4;
14726+ prefix = "";
14727+ format = 's';
14728+ break;
14729+ default:
14730+ return 0;
14731+ break;
14732+ }
14733+
14734+ user_assert(inblocksize < sizeof(inblock));
14735+ user_assert(outblocksize < sizeof(outblock));
14736+ user_assert(breakevery % outblocksize == 0);
14737+
14738+ if (srclen == 0)
14739+ return 0;
14740+ ntodo = srclen;
14741+
14742+ if (dstlen == 0) { /* dispose of awkward special case */
14743+ dst = fake;
14744+ dstlen = 1;
14745+ }
14746+ stop = dst + dstlen - 1;
14747+
14748+ nreal = strlen(prefix);
14749+ needed = nreal; /* for starters */
14750+ if (dstlen <= nreal) { /* prefix won't fit */
14751+ strncpy(dst, prefix, dstlen - 1);
14752+ dst += dstlen - 1;
14753+ } else {
14754+ strcpy(dst, prefix);
14755+ dst += nreal;
14756+ }
14757+
14758+ user_assert(dst <= stop);
14759+ sincebreak = 0;
14760+
14761+ while (ntodo > 0) {
14762+ if (ntodo < inblocksize) { /* incomplete input */
14763+ memset(inblock, 0, sizeof(inblock));
14764+ memcpy(inblock, src, ntodo);
14765+ src = inblock;
14766+ nreal = ntodo;
14767+ ntodo = inblocksize;
14768+ } else
14769+ nreal = inblocksize;
14770+ out = (outblocksize > stop - dst) ? outblock : dst;
14771+
14772+ convert(src, nreal, format, out);
14773+ needed += outblocksize;
14774+ sincebreak += outblocksize;
14775+ if (dst < stop) {
14776+ if (out != dst) {
14777+ user_assert(outblocksize > stop - dst);
14778+ memcpy(dst, out, stop - dst);
14779+ dst = stop;
14780+ } else
14781+ dst += outblocksize;
14782+ }
14783+
14784+ src += inblocksize;
14785+ ntodo -= inblocksize;
14786+ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
14787+ if (dst < stop)
14788+ *dst++ = breakchar;
14789+ needed++;
14790+ sincebreak = 0;
14791+ }
14792+ }
14793+
14794+ user_assert(dst <= stop);
14795+ *dst++ = '\0';
14796+ needed++;
14797+
14798+ return needed;
14799+}
14800+
14801+/*
14802+ - convert - convert one input block to one output block
14803+ */
14804+static void
14805+convert(src, nreal, format, out)
14806+const char *src;
14807+size_t nreal; /* how much of the input block is real */
14808+int format;
14809+char *out;
14810+{
14811+ static char hex[] = "0123456789abcdef";
14812+ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
14813+ "abcdefghijklmnopqrstuvwxyz"
14814+ "0123456789+/";
14815+ unsigned char c;
14816+ unsigned char c1, c2, c3;
14817+
14818+ user_assert(nreal > 0);
14819+ switch (format) {
14820+ case 'x':
14821+ user_assert(nreal == 1);
14822+ c = (unsigned char)*src;
14823+ *out++ = hex[c >> 4];
14824+ *out++ = hex[c & 0xf];
14825+ break;
14826+ case 's':
14827+ c1 = (unsigned char)*src++;
14828+ c2 = (unsigned char)*src++;
14829+ c3 = (unsigned char)*src++;
14830+ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
14831+ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
14832+ c |= c2 >> 4; /* ...top 4 of c2 */
14833+ *out++ = base64[c];
14834+ if (nreal == 1)
14835+ *out++ = '=';
14836+ else {
14837+ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
14838+ c |= c3 >> 6; /* ...top 2 of c3 */
14839+ *out++ = base64[c];
14840+ }
14841+ if (nreal <= 2)
14842+ *out++ = '=';
14843+ else
14844+ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
14845+ break;
14846+ default:
14847+ user_assert(nreal == 0); /* unknown format */
14848+ break;
14849+ }
14850+}
14851+
14852+/*
14853+ - datatoa - convert data to ASCII
14854+ * backward-compatibility synonym for datatot
14855+ */
14856+size_t /* true length (with NUL) for success */
14857+datatoa(src, srclen, format, dst, dstlen)
14858+const char *src;
14859+size_t srclen;
14860+int format; /* character indicating what format */
14861+char *dst; /* need not be valid if dstlen is 0 */
14862+size_t dstlen;
14863+{
14864+ return datatot(src, srclen, format, dst, dstlen);
14865+}
14866+
14867+/*
14868+ - bytestoa - convert data bytes to ASCII
14869+ * backward-compatibility synonym for datatot
14870+ */
14871+size_t /* true length (with NUL) for success */
14872+bytestoa(src, srclen, format, dst, dstlen)
14873+const char *src;
14874+size_t srclen;
14875+int format; /* character indicating what format */
14876+char *dst; /* need not be valid if dstlen is 0 */
14877+size_t dstlen;
14878+{
14879+ return datatot(src, srclen, format, dst, dstlen);
14880+}
14881--- /dev/null Tue Mar 11 13:02:56 2003
14882+++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004
14883@@ -0,0 +1,148 @@
14884+
14885+#
14886+# RCSID $Id: defconfig,v 1.28.2.1 2006/10/11 18:14:33 paul Exp $
14887+#
14888+
14889+#
14890+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
14891+#
14892+
14893+#
14894+# First, lets override stuff already set or not in the kernel config.
14895+#
14896+# We can't even think about leaving this off...
14897+CONFIG_INET=y
14898+
14899+#
14900+# This must be on for subnet protection.
14901+CONFIG_IP_FORWARD=y
14902+
14903+# Shut off IPSEC masquerading if it has been enabled, since it will
14904+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
14905+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
14906+CONFIG_IP_MASQUERADE_IPSEC=n
14907+
14908+#
14909+# Next, lets set the recommended FreeS/WAN configuration.
14910+#
14911+
14912+# To config as static (preferred), 'y'. To config as module, 'm'.
14913+CONFIG_KLIPS=m
14914+
14915+# To do tunnel mode IPSec, this must be enabled.
14916+CONFIG_KLIPS_IPIP=y
14917+
14918+# To enable authentication, say 'y'. (Highly recommended)
14919+CONFIG_KLIPS_AH=y
14920+
14921+# Authentication algorithm(s):
14922+CONFIG_KLIPS_AUTH_HMAC_MD5=y
14923+CONFIG_KLIPS_AUTH_HMAC_SHA1=y
14924+
14925+# To enable encryption, say 'y'. (Highly recommended)
14926+CONFIG_KLIPS_ESP=y
14927+
14928+# modular algo extensions (and new ALGOs)
14929+CONFIG_KLIPS_ALG=y
14930+
14931+# Encryption algorithm(s):
14932+CONFIG_KLIPS_ENC_3DES=y
14933+CONFIG_KLIPS_ENC_AES=y
14934+# CONFIG_KLIPS_ENC_NULL=y
14935+
14936+# Use CryptoAPI for ALG? - by default, no.
14937+CONFIG_KLIPS_ENC_CRYPTOAPI=n
14938+
14939+# IP Compression: new, probably still has minor bugs.
14940+CONFIG_KLIPS_IPCOMP=y
14941+
14942+# To enable userspace-switchable KLIPS debugging, say 'y'.
14943+CONFIG_KLIPS_DEBUG=y
14944+
14945+# NAT Traversal
14946+CONFIG_IPSEC_NAT_TRAVERSAL=y
14947+
14948+#
14949+#
14950+# $Log: defconfig,v $
14951+# Revision 1.28.2.1 2006/10/11 18:14:33 paul
14952+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
14953+# per default.
14954+#
14955+# Revision 1.28 2005/05/11 03:15:42 mcr
14956+# adjusted makefiles to sanely build modules properly.
14957+#
14958+# Revision 1.27 2005/03/20 03:00:05 mcr
14959+# default configuration should enable NAT_TRAVERSAL.
14960+#
14961+# Revision 1.26 2004/07/10 19:11:18 mcr
14962+# CONFIG_IPSEC -> CONFIG_KLIPS.
14963+#
14964+# Revision 1.25 2004/07/05 01:03:53 mcr
14965+# fix for adding cryptoapi code.
14966+# keep it off for now, since UMLs do not have it yet.
14967+#
14968+# Revision 1.24 2004/04/06 02:49:25 mcr
14969+# pullup of algo code from alg-branch.
14970+#
14971+# Revision 1.23.2.2 2004/04/05 04:30:46 mcr
14972+# patches for alg-branch to compile/work with 2.x openswan
14973+#
14974+# Revision 1.23.2.1 2003/12/22 15:25:52 jjo
14975+# . Merged algo-0.8.1-rc11-test1 into alg-branch
14976+#
14977+# Revision 1.23 2003/12/10 01:14:27 mcr
14978+# NAT-traversal patches to KLIPS.
14979+#
14980+# Revision 1.22 2003/02/24 19:37:27 mcr
14981+# changed default compilation mode to static.
14982+#
14983+# Revision 1.21 2002/04/24 07:36:27 mcr
14984+# Moved from ./klips/net/ipsec/defconfig,v
14985+#
14986+# Revision 1.20 2002/04/02 04:07:40 mcr
14987+# default build is now 'm'odule for KLIPS
14988+#
14989+# Revision 1.19 2002/03/08 18:57:17 rgb
14990+# Added a blank line at the beginning of the file to make it easier for
14991+# other projects to patch ./arch/i386/defconfig, for example
14992+# LIDS+grSecurity requested by Jason Pattie.
14993+#
14994+# Revision 1.18 2000/11/30 17:26:56 rgb
14995+# Cleaned out unused options and enabled ipcomp by default.
14996+#
14997+# Revision 1.17 2000/09/15 11:37:01 rgb
14998+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
14999+# IPCOMP zlib deflate code.
15000+#
15001+# Revision 1.16 2000/09/08 19:12:55 rgb
15002+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
15003+#
15004+# Revision 1.15 2000/05/24 19:37:13 rgb
15005+# *** empty log message ***
15006+#
15007+# Revision 1.14 2000/05/11 21:14:57 henry
15008+# just commenting the FOOBAR=y lines out is not enough
15009+#
15010+# Revision 1.13 2000/05/10 20:17:58 rgb
15011+# Comment out netlink defaults, which are no longer needed.
15012+#
15013+# Revision 1.12 2000/05/10 19:13:38 rgb
15014+# Added configure option to shut off no eroute passthrough.
15015+#
15016+# Revision 1.11 2000/03/16 07:09:46 rgb
15017+# Hardcode PF_KEYv2 support.
15018+# Disable IPSEC_ICMP by default.
15019+# Remove DES config option from defaults file.
15020+#
15021+# Revision 1.10 2000/01/11 03:09:42 rgb
15022+# Added a default of 'y' to PF_KEYv2 keying I/F.
15023+#
15024+# Revision 1.9 1999/05/08 21:23:12 rgb
15025+# Added support for 2.2.x kernels.
15026+#
15027+# Revision 1.8 1999/04/06 04:54:25 rgb
15028+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
15029+# patch shell fixes.
15030+#
15031+#
15032--- /dev/null Tue Mar 11 13:02:56 2003
15033+++ linux/net/ipsec/deflate.c Mon Feb 9 13:51:03 2004
15034@@ -0,0 +1,1351 @@
15035+/* deflate.c -- compress data using the deflation algorithm
15036+ * Copyright (C) 1995-2002 Jean-loup Gailly.
15037+ * For conditions of distribution and use, see copyright notice in zlib.h
15038+ */
15039+
15040+/*
15041+ * ALGORITHM
15042+ *
15043+ * The "deflation" process depends on being able to identify portions
15044+ * of the input text which are identical to earlier input (within a
15045+ * sliding window trailing behind the input currently being processed).
15046+ *
15047+ * The most straightforward technique turns out to be the fastest for
15048+ * most input files: try all possible matches and select the longest.
15049+ * The key feature of this algorithm is that insertions into the string
15050+ * dictionary are very simple and thus fast, and deletions are avoided
15051+ * completely. Insertions are performed at each input character, whereas
15052+ * string matches are performed only when the previous match ends. So it
15053+ * is preferable to spend more time in matches to allow very fast string
15054+ * insertions and avoid deletions. The matching algorithm for small
15055+ * strings is inspired from that of Rabin & Karp. A brute force approach
15056+ * is used to find longer strings when a small match has been found.
15057+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
15058+ * (by Leonid Broukhis).
15059+ * A previous version of this file used a more sophisticated algorithm
15060+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
15061+ * time, but has a larger average cost, uses more memory and is patented.
15062+ * However the F&G algorithm may be faster for some highly redundant
15063+ * files if the parameter max_chain_length (described below) is too large.
15064+ *
15065+ * ACKNOWLEDGEMENTS
15066+ *
15067+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
15068+ * I found it in 'freeze' written by Leonid Broukhis.
15069+ * Thanks to many people for bug reports and testing.
15070+ *
15071+ * REFERENCES
15072+ *
15073+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
15074+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt
15075+ *
15076+ * A description of the Rabin and Karp algorithm is given in the book
15077+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
15078+ *
15079+ * Fiala,E.R., and Greene,D.H.
15080+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
15081+ *
15082+ */
15083+
15084+/* @(#) $Id: deflate.c,v 1.4 2004/07/10 07:48:37 mcr Exp $ */
15085+
15086+#include "deflate.h"
15087+
15088+local const char deflate_copyright[] =
15089+ " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
15090+/*
15091+ If you use the zlib library in a product, an acknowledgment is welcome
15092+ in the documentation of your product. If for some reason you cannot
15093+ include such an acknowledgment, I would appreciate that you keep this
15094+ copyright string in the executable of your product.
15095+ */
15096+
15097+/* ===========================================================================
15098+ * Function prototypes.
15099+ */
15100+typedef enum {
15101+ need_more, /* block not completed, need more input or more output */
15102+ block_done, /* block flush performed */
15103+ finish_started, /* finish started, need only more output at next deflate */
15104+ finish_done /* finish done, accept no more input or output */
15105+} block_state;
15106+
15107+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
15108+/* Compression function. Returns the block state after the call. */
15109+
15110+local void fill_window OF((deflate_state *s));
15111+local block_state deflate_stored OF((deflate_state *s, int flush));
15112+local block_state deflate_fast OF((deflate_state *s, int flush));
15113+local block_state deflate_slow OF((deflate_state *s, int flush));
15114+local void lm_init OF((deflate_state *s));
15115+local void putShortMSB OF((deflate_state *s, uInt b));
15116+local void flush_pending OF((z_streamp strm));
15117+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
15118+#ifdef ASMV
15119+ void match_init OF((void)); /* asm code initialization */
15120+ uInt longest_match OF((deflate_state *s, IPos cur_match));
15121+#else
15122+local uInt longest_match OF((deflate_state *s, IPos cur_match));
15123+#endif
15124+
15125+#ifdef DEBUG
15126+local void check_match OF((deflate_state *s, IPos start, IPos match,
15127+ int length));
15128+#endif
15129+
15130+/* ===========================================================================
15131+ * Local data
15132+ */
15133+
15134+#define NIL 0
15135+/* Tail of hash chains */
15136+
15137+#ifndef TOO_FAR
15138+# define TOO_FAR 4096
15139+#endif
15140+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
15141+
15142+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
15143+/* Minimum amount of lookahead, except at the end of the input file.
15144+ * See deflate.c for comments about the MIN_MATCH+1.
15145+ */
15146+
15147+/* Values for max_lazy_match, good_match and max_chain_length, depending on
15148+ * the desired pack level (0..9). The values given below have been tuned to
15149+ * exclude worst case performance for pathological files. Better values may be
15150+ * found for specific files.
15151+ */
15152+typedef struct config_s {
15153+ ush good_length; /* reduce lazy search above this match length */
15154+ ush max_lazy; /* do not perform lazy search above this match length */
15155+ ush nice_length; /* quit search above this match length */
15156+ ush max_chain;
15157+ compress_func func;
15158+} config;
15159+
15160+local const config configuration_table[10] = {
15161+/* good lazy nice chain */
15162+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
15163+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
15164+/* 2 */ {4, 5, 16, 8, deflate_fast},
15165+/* 3 */ {4, 6, 32, 32, deflate_fast},
15166+
15167+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
15168+/* 5 */ {8, 16, 32, 32, deflate_slow},
15169+/* 6 */ {8, 16, 128, 128, deflate_slow},
15170+/* 7 */ {8, 32, 128, 256, deflate_slow},
15171+/* 8 */ {32, 128, 258, 1024, deflate_slow},
15172+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
15173+
15174+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
15175+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
15176+ * meaning.
15177+ */
15178+
15179+#define EQUAL 0
15180+/* result of memcmp for equal strings */
15181+
15182+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
15183+
15184+/* ===========================================================================
15185+ * Update a hash value with the given input byte
15186+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
15187+ * input characters, so that a running hash key can be computed from the
15188+ * previous key instead of complete recalculation each time.
15189+ */
15190+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
15191+
15192+
15193+/* ===========================================================================
15194+ * Insert string str in the dictionary and set match_head to the previous head
15195+ * of the hash chain (the most recent string with same hash key). Return
15196+ * the previous length of the hash chain.
15197+ * If this file is compiled with -DFASTEST, the compression level is forced
15198+ * to 1, and no hash chains are maintained.
15199+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
15200+ * input characters and the first MIN_MATCH bytes of str are valid
15201+ * (except for the last MIN_MATCH-1 bytes of the input file).
15202+ */
15203+#ifdef FASTEST
15204+#define INSERT_STRING(s, str, match_head) \
15205+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
15206+ match_head = s->head[s->ins_h], \
15207+ s->head[s->ins_h] = (Pos)(str))
15208+#else
15209+#define INSERT_STRING(s, str, match_head) \
15210+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
15211+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
15212+ s->head[s->ins_h] = (Pos)(str))
15213+#endif
15214+
15215+/* ===========================================================================
15216+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
15217+ * prev[] will be initialized on the fly.
15218+ */
15219+#define CLEAR_HASH(s) \
15220+ s->head[s->hash_size-1] = NIL; \
15221+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
15222+
15223+/* ========================================================================= */
15224+int ZEXPORT deflateInit_(strm, level, version, stream_size)
15225+ z_streamp strm;
15226+ int level;
15227+ const char *version;
15228+ int stream_size;
15229+{
15230+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
15231+ Z_DEFAULT_STRATEGY, version, stream_size);
15232+ /* To do: ignore strm->next_in if we use it as window */
15233+}
15234+
15235+/* ========================================================================= */
15236+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
15237+ version, stream_size)
15238+ z_streamp strm;
15239+ int level;
15240+ int method;
15241+ int windowBits;
15242+ int memLevel;
15243+ int strategy;
15244+ const char *version;
15245+ int stream_size;
15246+{
15247+ deflate_state *s;
15248+ int noheader = 0;
15249+ static const char* my_version = ZLIB_VERSION;
15250+
15251+ ushf *overlay;
15252+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
15253+ * output size for (length,distance) codes is <= 24 bits.
15254+ */
15255+
15256+ if (version == Z_NULL || version[0] != my_version[0] ||
15257+ stream_size != sizeof(z_stream)) {
15258+ return Z_VERSION_ERROR;
15259+ }
15260+ if (strm == Z_NULL) return Z_STREAM_ERROR;
15261+
15262+ strm->msg = Z_NULL;
15263+ if (strm->zalloc == Z_NULL) {
15264+ return Z_STREAM_ERROR;
15265+/* strm->zalloc = zcalloc;
15266+ strm->opaque = (voidpf)0;*/
15267+ }
15268+ if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
15269+
15270+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
15271+#ifdef FASTEST
15272+ level = 1;
15273+#endif
15274+
15275+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
15276+ noheader = 1;
15277+ windowBits = -windowBits;
15278+ }
15279+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
15280+ windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
15281+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
15282+ return Z_STREAM_ERROR;
15283+ }
15284+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
15285+ if (s == Z_NULL) return Z_MEM_ERROR;
15286+ strm->state = (struct internal_state FAR *)s;
15287+ s->strm = strm;
15288+
15289+ s->noheader = noheader;
15290+ s->w_bits = windowBits;
15291+ s->w_size = 1 << s->w_bits;
15292+ s->w_mask = s->w_size - 1;
15293+
15294+ s->hash_bits = memLevel + 7;
15295+ s->hash_size = 1 << s->hash_bits;
15296+ s->hash_mask = s->hash_size - 1;
15297+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
15298+
15299+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
15300+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
15301+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
15302+
15303+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
15304+
15305+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
15306+ s->pending_buf = (uchf *) overlay;
15307+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
15308+
15309+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
15310+ s->pending_buf == Z_NULL) {
15311+ strm->msg = ERR_MSG(Z_MEM_ERROR);
15312+ deflateEnd (strm);
15313+ return Z_MEM_ERROR;
15314+ }
15315+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
15316+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
15317+
15318+ s->level = level;
15319+ s->strategy = strategy;
15320+ s->method = (Byte)method;
15321+
15322+ return deflateReset(strm);
15323+}
15324+
15325+/* ========================================================================= */
15326+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
15327+ z_streamp strm;
15328+ const Bytef *dictionary;
15329+ uInt dictLength;
15330+{
15331+ deflate_state *s;
15332+ uInt length = dictLength;
15333+ uInt n;
15334+ IPos hash_head = 0;
15335+
15336+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
15337+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
15338+
15339+ s = strm->state;
15340+ strm->adler = adler32(strm->adler, dictionary, dictLength);
15341+
15342+ if (length < MIN_MATCH) return Z_OK;
15343+ if (length > MAX_DIST(s)) {
15344+ length = MAX_DIST(s);
15345+#ifndef USE_DICT_HEAD
15346+ dictionary += dictLength - length; /* use the tail of the dictionary */
15347+#endif
15348+ }
15349+ zmemcpy(s->window, dictionary, length);
15350+ s->strstart = length;
15351+ s->block_start = (long)length;
15352+
15353+ /* Insert all strings in the hash table (except for the last two bytes).
15354+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
15355+ * call of fill_window.
15356+ */
15357+ s->ins_h = s->window[0];
15358+ UPDATE_HASH(s, s->ins_h, s->window[1]);
15359+ for (n = 0; n <= length - MIN_MATCH; n++) {
15360+ INSERT_STRING(s, n, hash_head);
15361+ }
15362+ if (hash_head) hash_head = 0; /* to make compiler happy */
15363+ return Z_OK;
15364+}
15365+
15366+/* ========================================================================= */
15367+int ZEXPORT deflateReset (strm)
15368+ z_streamp strm;
15369+{
15370+ deflate_state *s;
15371+
15372+ if (strm == Z_NULL || strm->state == Z_NULL ||
15373+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
15374+
15375+ strm->total_in = strm->total_out = 0;
15376+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
15377+ strm->data_type = Z_UNKNOWN;
15378+
15379+ s = (deflate_state *)strm->state;
15380+ s->pending = 0;
15381+ s->pending_out = s->pending_buf;
15382+
15383+ if (s->noheader < 0) {
15384+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
15385+ }
15386+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
15387+ strm->adler = 1;
15388+ s->last_flush = Z_NO_FLUSH;
15389+
15390+ _tr_init(s);
15391+ lm_init(s);
15392+
15393+ return Z_OK;
15394+}
15395+
15396+/* ========================================================================= */
15397+int ZEXPORT deflateParams(strm, level, strategy)
15398+ z_streamp strm;
15399+ int level;
15400+ int strategy;
15401+{
15402+ deflate_state *s;
15403+ compress_func func;
15404+ int err = Z_OK;
15405+
15406+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15407+ s = strm->state;
15408+
15409+ if (level == Z_DEFAULT_COMPRESSION) {
15410+ level = 6;
15411+ }
15412+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
15413+ return Z_STREAM_ERROR;
15414+ }
15415+ func = configuration_table[s->level].func;
15416+
15417+ if (func != configuration_table[level].func && strm->total_in != 0) {
15418+ /* Flush the last buffer: */
15419+ err = deflate(strm, Z_PARTIAL_FLUSH);
15420+ }
15421+ if (s->level != level) {
15422+ s->level = level;
15423+ s->max_lazy_match = configuration_table[level].max_lazy;
15424+ s->good_match = configuration_table[level].good_length;
15425+ s->nice_match = configuration_table[level].nice_length;
15426+ s->max_chain_length = configuration_table[level].max_chain;
15427+ }
15428+ s->strategy = strategy;
15429+ return err;
15430+}
15431+
15432+/* =========================================================================
15433+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
15434+ * IN assertion: the stream state is correct and there is enough room in
15435+ * pending_buf.
15436+ */
15437+local void putShortMSB (s, b)
15438+ deflate_state *s;
15439+ uInt b;
15440+{
15441+ put_byte(s, (Byte)(b >> 8));
15442+ put_byte(s, (Byte)(b & 0xff));
15443+}
15444+
15445+/* =========================================================================
15446+ * Flush as much pending output as possible. All deflate() output goes
15447+ * through this function so some applications may wish to modify it
15448+ * to avoid allocating a large strm->next_out buffer and copying into it.
15449+ * (See also read_buf()).
15450+ */
15451+local void flush_pending(strm)
15452+ z_streamp strm;
15453+{
15454+ unsigned len = strm->state->pending;
15455+
15456+ if (len > strm->avail_out) len = strm->avail_out;
15457+ if (len == 0) return;
15458+
15459+ zmemcpy(strm->next_out, strm->state->pending_out, len);
15460+ strm->next_out += len;
15461+ strm->state->pending_out += len;
15462+ strm->total_out += len;
15463+ strm->avail_out -= len;
15464+ strm->state->pending -= len;
15465+ if (strm->state->pending == 0) {
15466+ strm->state->pending_out = strm->state->pending_buf;
15467+ }
15468+}
15469+
15470+/* ========================================================================= */
15471+int ZEXPORT deflate (strm, flush)
15472+ z_streamp strm;
15473+ int flush;
15474+{
15475+ int old_flush; /* value of flush param for previous deflate call */
15476+ deflate_state *s;
15477+
15478+ if (strm == Z_NULL || strm->state == Z_NULL ||
15479+ flush > Z_FINISH || flush < 0) {
15480+ return Z_STREAM_ERROR;
15481+ }
15482+ s = strm->state;
15483+
15484+ if (strm->next_out == Z_NULL ||
15485+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
15486+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
15487+ ERR_RETURN(strm, Z_STREAM_ERROR);
15488+ }
15489+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
15490+
15491+ s->strm = strm; /* just in case */
15492+ old_flush = s->last_flush;
15493+ s->last_flush = flush;
15494+
15495+ /* Write the zlib header */
15496+ if (s->status == INIT_STATE) {
15497+
15498+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
15499+ uInt level_flags = (s->level-1) >> 1;
15500+
15501+ if (level_flags > 3) level_flags = 3;
15502+ header |= (level_flags << 6);
15503+ if (s->strstart != 0) header |= PRESET_DICT;
15504+ header += 31 - (header % 31);
15505+
15506+ s->status = BUSY_STATE;
15507+ putShortMSB(s, header);
15508+
15509+ /* Save the adler32 of the preset dictionary: */
15510+ if (s->strstart != 0) {
15511+ putShortMSB(s, (uInt)(strm->adler >> 16));
15512+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
15513+ }
15514+ strm->adler = 1L;
15515+ }
15516+
15517+ /* Flush as much pending output as possible */
15518+ if (s->pending != 0) {
15519+ flush_pending(strm);
15520+ if (strm->avail_out == 0) {
15521+ /* Since avail_out is 0, deflate will be called again with
15522+ * more output space, but possibly with both pending and
15523+ * avail_in equal to zero. There won't be anything to do,
15524+ * but this is not an error situation so make sure we
15525+ * return OK instead of BUF_ERROR at next call of deflate:
15526+ */
15527+ s->last_flush = -1;
15528+ return Z_OK;
15529+ }
15530+
15531+ /* Make sure there is something to do and avoid duplicate consecutive
15532+ * flushes. For repeated and useless calls with Z_FINISH, we keep
15533+ * returning Z_STREAM_END instead of Z_BUFF_ERROR.
15534+ */
15535+ } else if (strm->avail_in == 0 && flush <= old_flush &&
15536+ flush != Z_FINISH) {
15537+ ERR_RETURN(strm, Z_BUF_ERROR);
15538+ }
15539+
15540+ /* User must not provide more input after the first FINISH: */
15541+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
15542+ ERR_RETURN(strm, Z_BUF_ERROR);
15543+ }
15544+
15545+ /* Start a new block or continue the current one.
15546+ */
15547+ if (strm->avail_in != 0 || s->lookahead != 0 ||
15548+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
15549+ block_state bstate;
15550+
15551+ bstate = (*(configuration_table[s->level].func))(s, flush);
15552+
15553+ if (bstate == finish_started || bstate == finish_done) {
15554+ s->status = FINISH_STATE;
15555+ }
15556+ if (bstate == need_more || bstate == finish_started) {
15557+ if (strm->avail_out == 0) {
15558+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
15559+ }
15560+ return Z_OK;
15561+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
15562+ * of deflate should use the same flush parameter to make sure
15563+ * that the flush is complete. So we don't have to output an
15564+ * empty block here, this will be done at next call. This also
15565+ * ensures that for a very small output buffer, we emit at most
15566+ * one empty block.
15567+ */
15568+ }
15569+ if (bstate == block_done) {
15570+ if (flush == Z_PARTIAL_FLUSH) {
15571+ _tr_align(s);
15572+ } else { /* FULL_FLUSH or SYNC_FLUSH */
15573+ _tr_stored_block(s, (char*)0, 0L, 0);
15574+ /* For a full flush, this empty block will be recognized
15575+ * as a special marker by inflate_sync().
15576+ */
15577+ if (flush == Z_FULL_FLUSH) {
15578+ CLEAR_HASH(s); /* forget history */
15579+ }
15580+ }
15581+ flush_pending(strm);
15582+ if (strm->avail_out == 0) {
15583+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
15584+ return Z_OK;
15585+ }
15586+ }
15587+ }
15588+ Assert(strm->avail_out > 0, "bug2");
15589+
15590+ if (flush != Z_FINISH) return Z_OK;
15591+ if (s->noheader) return Z_STREAM_END;
15592+
15593+ /* Write the zlib trailer (adler32) */
15594+ putShortMSB(s, (uInt)(strm->adler >> 16));
15595+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
15596+ flush_pending(strm);
15597+ /* If avail_out is zero, the application will call deflate again
15598+ * to flush the rest.
15599+ */
15600+ s->noheader = -1; /* write the trailer only once! */
15601+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
15602+}
15603+
15604+/* ========================================================================= */
15605+int ZEXPORT deflateEnd (strm)
15606+ z_streamp strm;
15607+{
15608+ int status;
15609+
15610+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15611+
15612+ status = strm->state->status;
15613+ if (status != INIT_STATE && status != BUSY_STATE &&
15614+ status != FINISH_STATE) {
15615+ return Z_STREAM_ERROR;
15616+ }
15617+
15618+ /* Deallocate in reverse order of allocations: */
15619+ TRY_FREE(strm, strm->state->pending_buf);
15620+ TRY_FREE(strm, strm->state->head);
15621+ TRY_FREE(strm, strm->state->prev);
15622+ TRY_FREE(strm, strm->state->window);
15623+
15624+ ZFREE(strm, strm->state);
15625+ strm->state = Z_NULL;
15626+
15627+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
15628+}
15629+
15630+/* =========================================================================
15631+ * Copy the source state to the destination state.
15632+ * To simplify the source, this is not supported for 16-bit MSDOS (which
15633+ * doesn't have enough memory anyway to duplicate compression states).
15634+ */
15635+int ZEXPORT deflateCopy (dest, source)
15636+ z_streamp dest;
15637+ z_streamp source;
15638+{
15639+#ifdef MAXSEG_64K
15640+ return Z_STREAM_ERROR;
15641+#else
15642+ deflate_state *ds;
15643+ deflate_state *ss;
15644+ ushf *overlay;
15645+
15646+
15647+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
15648+ return Z_STREAM_ERROR;
15649+ }
15650+
15651+ ss = source->state;
15652+
15653+ *dest = *source;
15654+
15655+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
15656+ if (ds == Z_NULL) return Z_MEM_ERROR;
15657+ dest->state = (struct internal_state FAR *) ds;
15658+ *ds = *ss;
15659+ ds->strm = dest;
15660+
15661+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
15662+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
15663+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
15664+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
15665+ ds->pending_buf = (uchf *) overlay;
15666+
15667+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
15668+ ds->pending_buf == Z_NULL) {
15669+ deflateEnd (dest);
15670+ return Z_MEM_ERROR;
15671+ }
15672+ /* following zmemcpy do not work for 16-bit MSDOS */
15673+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
15674+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
15675+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
15676+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
15677+
15678+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
15679+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
15680+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
15681+
15682+ ds->l_desc.dyn_tree = ds->dyn_ltree;
15683+ ds->d_desc.dyn_tree = ds->dyn_dtree;
15684+ ds->bl_desc.dyn_tree = ds->bl_tree;
15685+
15686+ return Z_OK;
15687+#endif
15688+}
15689+
15690+/* ===========================================================================
15691+ * Read a new buffer from the current input stream, update the adler32
15692+ * and total number of bytes read. All deflate() input goes through
15693+ * this function so some applications may wish to modify it to avoid
15694+ * allocating a large strm->next_in buffer and copying from it.
15695+ * (See also flush_pending()).
15696+ */
15697+local int read_buf(strm, buf, size)
15698+ z_streamp strm;
15699+ Bytef *buf;
15700+ unsigned size;
15701+{
15702+ unsigned len = strm->avail_in;
15703+
15704+ if (len > size) len = size;
15705+ if (len == 0) return 0;
15706+
15707+ strm->avail_in -= len;
15708+
15709+ if (!strm->state->noheader) {
15710+ strm->adler = adler32(strm->adler, strm->next_in, len);
15711+ }
15712+ zmemcpy(buf, strm->next_in, len);
15713+ strm->next_in += len;
15714+ strm->total_in += len;
15715+
15716+ return (int)len;
15717+}
15718+
15719+/* ===========================================================================
15720+ * Initialize the "longest match" routines for a new zlib stream
15721+ */
15722+local void lm_init (s)
15723+ deflate_state *s;
15724+{
15725+ s->window_size = (ulg)2L*s->w_size;
15726+
15727+ CLEAR_HASH(s);
15728+
15729+ /* Set the default configuration parameters:
15730+ */
15731+ s->max_lazy_match = configuration_table[s->level].max_lazy;
15732+ s->good_match = configuration_table[s->level].good_length;
15733+ s->nice_match = configuration_table[s->level].nice_length;
15734+ s->max_chain_length = configuration_table[s->level].max_chain;
15735+
15736+ s->strstart = 0;
15737+ s->block_start = 0L;
15738+ s->lookahead = 0;
15739+ s->match_length = s->prev_length = MIN_MATCH-1;
15740+ s->match_available = 0;
15741+ s->ins_h = 0;
15742+#ifdef ASMV
15743+ match_init(); /* initialize the asm code */
15744+#endif
15745+}
15746+
15747+/* ===========================================================================
15748+ * Set match_start to the longest match starting at the given string and
15749+ * return its length. Matches shorter or equal to prev_length are discarded,
15750+ * in which case the result is equal to prev_length and match_start is
15751+ * garbage.
15752+ * IN assertions: cur_match is the head of the hash chain for the current
15753+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
15754+ * OUT assertion: the match length is not greater than s->lookahead.
15755+ */
15756+#ifndef ASMV
15757+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
15758+ * match.S. The code will be functionally equivalent.
15759+ */
15760+#ifndef FASTEST
15761+local uInt longest_match(s, cur_match)
15762+ deflate_state *s;
15763+ IPos cur_match; /* current match */
15764+{
15765+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
15766+ register Bytef *scan = s->window + s->strstart; /* current string */
15767+ register Bytef *match; /* matched string */
15768+ register int len; /* length of current match */
15769+ int best_len = s->prev_length; /* best match length so far */
15770+ int nice_match = s->nice_match; /* stop if match long enough */
15771+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
15772+ s->strstart - (IPos)MAX_DIST(s) : NIL;
15773+ /* Stop when cur_match becomes <= limit. To simplify the code,
15774+ * we prevent matches with the string of window index 0.
15775+ */
15776+ Posf *prev = s->prev;
15777+ uInt wmask = s->w_mask;
15778+
15779+#ifdef UNALIGNED_OK
15780+ /* Compare two bytes at a time. Note: this is not always beneficial.
15781+ * Try with and without -DUNALIGNED_OK to check.
15782+ */
15783+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
15784+ register ush scan_start = *(ushf*)scan;
15785+ register ush scan_end = *(ushf*)(scan+best_len-1);
15786+#else
15787+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15788+ register Byte scan_end1 = scan[best_len-1];
15789+ register Byte scan_end = scan[best_len];
15790+#endif
15791+
15792+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15793+ * It is easy to get rid of this optimization if necessary.
15794+ */
15795+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15796+
15797+ /* Do not waste too much time if we already have a good match: */
15798+ if (s->prev_length >= s->good_match) {
15799+ chain_length >>= 2;
15800+ }
15801+ /* Do not look for matches beyond the end of the input. This is necessary
15802+ * to make deflate deterministic.
15803+ */
15804+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
15805+
15806+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15807+
15808+ do {
15809+ Assert(cur_match < s->strstart, "no future");
15810+ match = s->window + cur_match;
15811+
15812+ /* Skip to next match if the match length cannot increase
15813+ * or if the match length is less than 2:
15814+ */
15815+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
15816+ /* This code assumes sizeof(unsigned short) == 2. Do not use
15817+ * UNALIGNED_OK if your compiler uses a different size.
15818+ */
15819+ if (*(ushf*)(match+best_len-1) != scan_end ||
15820+ *(ushf*)match != scan_start) continue;
15821+
15822+ /* It is not necessary to compare scan[2] and match[2] since they are
15823+ * always equal when the other bytes match, given that the hash keys
15824+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
15825+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
15826+ * lookahead only every 4th comparison; the 128th check will be made
15827+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
15828+ * necessary to put more guard bytes at the end of the window, or
15829+ * to check more often for insufficient lookahead.
15830+ */
15831+ Assert(scan[2] == match[2], "scan[2]?");
15832+ scan++, match++;
15833+ do {
15834+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15835+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15836+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15837+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15838+ scan < strend);
15839+ /* The funny "do {}" generates better code on most compilers */
15840+
15841+ /* Here, scan <= window+strstart+257 */
15842+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15843+ if (*scan == *match) scan++;
15844+
15845+ len = (MAX_MATCH - 1) - (int)(strend-scan);
15846+ scan = strend - (MAX_MATCH-1);
15847+
15848+#else /* UNALIGNED_OK */
15849+
15850+ if (match[best_len] != scan_end ||
15851+ match[best_len-1] != scan_end1 ||
15852+ *match != *scan ||
15853+ *++match != scan[1]) continue;
15854+
15855+ /* The check at best_len-1 can be removed because it will be made
15856+ * again later. (This heuristic is not always a win.)
15857+ * It is not necessary to compare scan[2] and match[2] since they
15858+ * are always equal when the other bytes match, given that
15859+ * the hash keys are equal and that HASH_BITS >= 8.
15860+ */
15861+ scan += 2, match++;
15862+ Assert(*scan == *match, "match[2]?");
15863+
15864+ /* We check for insufficient lookahead only every 8th comparison;
15865+ * the 256th check will be made at strstart+258.
15866+ */
15867+ do {
15868+ } while (*++scan == *++match && *++scan == *++match &&
15869+ *++scan == *++match && *++scan == *++match &&
15870+ *++scan == *++match && *++scan == *++match &&
15871+ *++scan == *++match && *++scan == *++match &&
15872+ scan < strend);
15873+
15874+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15875+
15876+ len = MAX_MATCH - (int)(strend - scan);
15877+ scan = strend - MAX_MATCH;
15878+
15879+#endif /* UNALIGNED_OK */
15880+
15881+ if (len > best_len) {
15882+ s->match_start = cur_match;
15883+ best_len = len;
15884+ if (len >= nice_match) break;
15885+#ifdef UNALIGNED_OK
15886+ scan_end = *(ushf*)(scan+best_len-1);
15887+#else
15888+ scan_end1 = scan[best_len-1];
15889+ scan_end = scan[best_len];
15890+#endif
15891+ }
15892+ } while ((cur_match = prev[cur_match & wmask]) > limit
15893+ && --chain_length != 0);
15894+
15895+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
15896+ return s->lookahead;
15897+}
15898+
15899+#else /* FASTEST */
15900+/* ---------------------------------------------------------------------------
15901+ * Optimized version for level == 1 only
15902+ */
15903+local uInt longest_match(s, cur_match)
15904+ deflate_state *s;
15905+ IPos cur_match; /* current match */
15906+{
15907+ register Bytef *scan = s->window + s->strstart; /* current string */
15908+ register Bytef *match; /* matched string */
15909+ register int len; /* length of current match */
15910+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15911+
15912+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15913+ * It is easy to get rid of this optimization if necessary.
15914+ */
15915+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15916+
15917+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15918+
15919+ Assert(cur_match < s->strstart, "no future");
15920+
15921+ match = s->window + cur_match;
15922+
15923+ /* Return failure if the match length is less than 2:
15924+ */
15925+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
15926+
15927+ /* The check at best_len-1 can be removed because it will be made
15928+ * again later. (This heuristic is not always a win.)
15929+ * It is not necessary to compare scan[2] and match[2] since they
15930+ * are always equal when the other bytes match, given that
15931+ * the hash keys are equal and that HASH_BITS >= 8.
15932+ */
15933+ scan += 2, match += 2;
15934+ Assert(*scan == *match, "match[2]?");
15935+
15936+ /* We check for insufficient lookahead only every 8th comparison;
15937+ * the 256th check will be made at strstart+258.
15938+ */
15939+ do {
15940+ } while (*++scan == *++match && *++scan == *++match &&
15941+ *++scan == *++match && *++scan == *++match &&
15942+ *++scan == *++match && *++scan == *++match &&
15943+ *++scan == *++match && *++scan == *++match &&
15944+ scan < strend);
15945+
15946+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15947+
15948+ len = MAX_MATCH - (int)(strend - scan);
15949+
15950+ if (len < MIN_MATCH) return MIN_MATCH - 1;
15951+
15952+ s->match_start = cur_match;
15953+ return len <= s->lookahead ? len : s->lookahead;
15954+}
15955+#endif /* FASTEST */
15956+#endif /* ASMV */
15957+
15958+#ifdef DEBUG
15959+/* ===========================================================================
15960+ * Check that the match at match_start is indeed a match.
15961+ */
15962+local void check_match(s, start, match, length)
15963+ deflate_state *s;
15964+ IPos start, match;
15965+ int length;
15966+{
15967+ /* check that the match is indeed a match */
15968+ if (zmemcmp(s->window + match,
15969+ s->window + start, length) != EQUAL) {
15970+ fprintf(stderr, " start %u, match %u, length %d\n",
15971+ start, match, length);
15972+ do {
15973+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
15974+ } while (--length != 0);
15975+ z_error("invalid match");
15976+ }
15977+ if (z_verbose > 1) {
15978+ fprintf(stderr,"\\[%d,%d]", start-match, length);
15979+ do { putc(s->window[start++], stderr); } while (--length != 0);
15980+ }
15981+}
15982+#else
15983+# define check_match(s, start, match, length)
15984+#endif
15985+
15986+/* ===========================================================================
15987+ * Fill the window when the lookahead becomes insufficient.
15988+ * Updates strstart and lookahead.
15989+ *
15990+ * IN assertion: lookahead < MIN_LOOKAHEAD
15991+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
15992+ * At least one byte has been read, or avail_in == 0; reads are
15993+ * performed for at least two bytes (required for the zip translate_eol
15994+ * option -- not supported here).
15995+ */
15996+local void fill_window(s)
15997+ deflate_state *s;
15998+{
15999+ register unsigned n, m;
16000+ register Posf *p;
16001+ unsigned more; /* Amount of free space at the end of the window. */
16002+ uInt wsize = s->w_size;
16003+
16004+ do {
16005+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
16006+
16007+ /* Deal with !@#$% 64K limit: */
16008+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
16009+ more = wsize;
16010+
16011+ } else if (more == (unsigned)(-1)) {
16012+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
16013+ * and lookahead == 1 (input done one byte at time)
16014+ */
16015+ more--;
16016+
16017+ /* If the window is almost full and there is insufficient lookahead,
16018+ * move the upper half to the lower one to make room in the upper half.
16019+ */
16020+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
16021+
16022+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
16023+ s->match_start -= wsize;
16024+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
16025+ s->block_start -= (long) wsize;
16026+
16027+ /* Slide the hash table (could be avoided with 32 bit values
16028+ at the expense of memory usage). We slide even when level == 0
16029+ to keep the hash table consistent if we switch back to level > 0
16030+ later. (Using level 0 permanently is not an optimal usage of
16031+ zlib, so we don't care about this pathological case.)
16032+ */
16033+ n = s->hash_size;
16034+ p = &s->head[n];
16035+ do {
16036+ m = *--p;
16037+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
16038+ } while (--n);
16039+
16040+ n = wsize;
16041+#ifndef FASTEST
16042+ p = &s->prev[n];
16043+ do {
16044+ m = *--p;
16045+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
16046+ /* If n is not on any hash chain, prev[n] is garbage but
16047+ * its value will never be used.
16048+ */
16049+ } while (--n);
16050+#endif
16051+ more += wsize;
16052+ }
16053+ if (s->strm->avail_in == 0) return;
16054+
16055+ /* If there was no sliding:
16056+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
16057+ * more == window_size - lookahead - strstart
16058+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
16059+ * => more >= window_size - 2*WSIZE + 2
16060+ * In the BIG_MEM or MMAP case (not yet supported),
16061+ * window_size == input_size + MIN_LOOKAHEAD &&
16062+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
16063+ * Otherwise, window_size == 2*WSIZE so more >= 2.
16064+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
16065+ */
16066+ Assert(more >= 2, "more < 2");
16067+
16068+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
16069+ s->lookahead += n;
16070+
16071+ /* Initialize the hash value now that we have some input: */
16072+ if (s->lookahead >= MIN_MATCH) {
16073+ s->ins_h = s->window[s->strstart];
16074+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
16075+#if MIN_MATCH != 3
16076+ Call UPDATE_HASH() MIN_MATCH-3 more times
16077+#endif
16078+ }
16079+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
16080+ * but this is not important since only literal bytes will be emitted.
16081+ */
16082+
16083+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
16084+}
16085+
16086+/* ===========================================================================
16087+ * Flush the current block, with given end-of-file flag.
16088+ * IN assertion: strstart is set to the end of the current match.
16089+ */
16090+#define FLUSH_BLOCK_ONLY(s, eof) { \
16091+ _tr_flush_block(s, (s->block_start >= 0L ? \
16092+ (charf *)&s->window[(unsigned)s->block_start] : \
16093+ (charf *)Z_NULL), \
16094+ (ulg)((long)s->strstart - s->block_start), \
16095+ (eof)); \
16096+ s->block_start = s->strstart; \
16097+ flush_pending(s->strm); \
16098+ Tracev((stderr,"[FLUSH]")); \
16099+}
16100+
16101+/* Same but force premature exit if necessary. */
16102+#define FLUSH_BLOCK(s, eof) { \
16103+ FLUSH_BLOCK_ONLY(s, eof); \
16104+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
16105+}
16106+
16107+/* ===========================================================================
16108+ * Copy without compression as much as possible from the input stream, return
16109+ * the current block state.
16110+ * This function does not insert new strings in the dictionary since
16111+ * uncompressible data is probably not useful. This function is used
16112+ * only for the level=0 compression option.
16113+ * NOTE: this function should be optimized to avoid extra copying from
16114+ * window to pending_buf.
16115+ */
16116+local block_state deflate_stored(s, flush)
16117+ deflate_state *s;
16118+ int flush;
16119+{
16120+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
16121+ * to pending_buf_size, and each stored block has a 5 byte header:
16122+ */
16123+ ulg max_block_size = 0xffff;
16124+ ulg max_start;
16125+
16126+ if (max_block_size > s->pending_buf_size - 5) {
16127+ max_block_size = s->pending_buf_size - 5;
16128+ }
16129+
16130+ /* Copy as much as possible from input to output: */
16131+ for (;;) {
16132+ /* Fill the window as much as possible: */
16133+ if (s->lookahead <= 1) {
16134+
16135+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
16136+ s->block_start >= (long)s->w_size, "slide too late");
16137+
16138+ fill_window(s);
16139+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
16140+
16141+ if (s->lookahead == 0) break; /* flush the current block */
16142+ }
16143+ Assert(s->block_start >= 0L, "block gone");
16144+
16145+ s->strstart += s->lookahead;
16146+ s->lookahead = 0;
16147+
16148+ /* Emit a stored block if pending_buf will be full: */
16149+ max_start = s->block_start + max_block_size;
16150+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
16151+ /* strstart == 0 is possible when wraparound on 16-bit machine */
16152+ s->lookahead = (uInt)(s->strstart - max_start);
16153+ s->strstart = (uInt)max_start;
16154+ FLUSH_BLOCK(s, 0);
16155+ }
16156+ /* Flush if we may have to slide, otherwise block_start may become
16157+ * negative and the data will be gone:
16158+ */
16159+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
16160+ FLUSH_BLOCK(s, 0);
16161+ }
16162+ }
16163+ FLUSH_BLOCK(s, flush == Z_FINISH);
16164+ return flush == Z_FINISH ? finish_done : block_done;
16165+}
16166+
16167+/* ===========================================================================
16168+ * Compress as much as possible from the input stream, return the current
16169+ * block state.
16170+ * This function does not perform lazy evaluation of matches and inserts
16171+ * new strings in the dictionary only for unmatched strings or for short
16172+ * matches. It is used only for the fast compression options.
16173+ */
16174+local block_state deflate_fast(s, flush)
16175+ deflate_state *s;
16176+ int flush;
16177+{
16178+ IPos hash_head = NIL; /* head of the hash chain */
16179+ int bflush; /* set if current block must be flushed */
16180+
16181+ for (;;) {
16182+ /* Make sure that we always have enough lookahead, except
16183+ * at the end of the input file. We need MAX_MATCH bytes
16184+ * for the next match, plus MIN_MATCH bytes to insert the
16185+ * string following the next match.
16186+ */
16187+ if (s->lookahead < MIN_LOOKAHEAD) {
16188+ fill_window(s);
16189+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
16190+ return need_more;
16191+ }
16192+ if (s->lookahead == 0) break; /* flush the current block */
16193+ }
16194+
16195+ /* Insert the string window[strstart .. strstart+2] in the
16196+ * dictionary, and set hash_head to the head of the hash chain:
16197+ */
16198+ if (s->lookahead >= MIN_MATCH) {
16199+ INSERT_STRING(s, s->strstart, hash_head);
16200+ }
16201+
16202+ /* Find the longest match, discarding those <= prev_length.
16203+ * At this point we have always match_length < MIN_MATCH
16204+ */
16205+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
16206+ /* To simplify the code, we prevent matches with the string
16207+ * of window index 0 (in particular we have to avoid a match
16208+ * of the string with itself at the start of the input file).
16209+ */
16210+ if (s->strategy != Z_HUFFMAN_ONLY) {
16211+ s->match_length = longest_match (s, hash_head);
16212+ }
16213+ /* longest_match() sets match_start */
16214+ }
16215+ if (s->match_length >= MIN_MATCH) {
16216+ check_match(s, s->strstart, s->match_start, s->match_length);
16217+
16218+ _tr_tally_dist(s, s->strstart - s->match_start,
16219+ s->match_length - MIN_MATCH, bflush);
16220+
16221+ s->lookahead -= s->match_length;
16222+
16223+ /* Insert new strings in the hash table only if the match length
16224+ * is not too large. This saves time but degrades compression.
16225+ */
16226+#ifndef FASTEST
16227+ if (s->match_length <= s->max_insert_length &&
16228+ s->lookahead >= MIN_MATCH) {
16229+ s->match_length--; /* string at strstart already in hash table */
16230+ do {
16231+ s->strstart++;
16232+ INSERT_STRING(s, s->strstart, hash_head);
16233+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
16234+ * always MIN_MATCH bytes ahead.
16235+ */
16236+ } while (--s->match_length != 0);
16237+ s->strstart++;
16238+ } else
16239+#endif
16240+ {
16241+ s->strstart += s->match_length;
16242+ s->match_length = 0;
16243+ s->ins_h = s->window[s->strstart];
16244+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
16245+#if MIN_MATCH != 3
16246+ Call UPDATE_HASH() MIN_MATCH-3 more times
16247+#endif
16248+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
16249+ * matter since it will be recomputed at next deflate call.
16250+ */
16251+ }
16252+ } else {
16253+ /* No match, output a literal byte */
16254+ Tracevv((stderr,"%c", s->window[s->strstart]));
16255+ _tr_tally_lit (s, s->window[s->strstart], bflush);
16256+ s->lookahead--;
16257+ s->strstart++;
16258+ }
16259+ if (bflush) FLUSH_BLOCK(s, 0);
16260+ }
16261+ FLUSH_BLOCK(s, flush == Z_FINISH);
16262+ return flush == Z_FINISH ? finish_done : block_done;
16263+}
16264+
16265+/* ===========================================================================
16266+ * Same as above, but achieves better compression. We use a lazy
16267+ * evaluation for matches: a match is finally adopted only if there is
16268+ * no better match at the next window position.
16269+ */
16270+local block_state deflate_slow(s, flush)
16271+ deflate_state *s;
16272+ int flush;
16273+{
16274+ IPos hash_head = NIL; /* head of hash chain */
16275+ int bflush; /* set if current block must be flushed */
16276+
16277+ /* Process the input block. */
16278+ for (;;) {
16279+ /* Make sure that we always have enough lookahead, except
16280+ * at the end of the input file. We need MAX_MATCH bytes
16281+ * for the next match, plus MIN_MATCH bytes to insert the
16282+ * string following the next match.
16283+ */
16284+ if (s->lookahead < MIN_LOOKAHEAD) {
16285+ fill_window(s);
16286+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
16287+ return need_more;
16288+ }
16289+ if (s->lookahead == 0) break; /* flush the current block */
16290+ }
16291+
16292+ /* Insert the string window[strstart .. strstart+2] in the
16293+ * dictionary, and set hash_head to the head of the hash chain:
16294+ */
16295+ if (s->lookahead >= MIN_MATCH) {
16296+ INSERT_STRING(s, s->strstart, hash_head);
16297+ }
16298+
16299+ /* Find the longest match, discarding those <= prev_length.
16300+ */
16301+ s->prev_length = s->match_length, s->prev_match = s->match_start;
16302+ s->match_length = MIN_MATCH-1;
16303+
16304+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
16305+ s->strstart - hash_head <= MAX_DIST(s)) {
16306+ /* To simplify the code, we prevent matches with the string
16307+ * of window index 0 (in particular we have to avoid a match
16308+ * of the string with itself at the start of the input file).
16309+ */
16310+ if (s->strategy != Z_HUFFMAN_ONLY) {
16311+ s->match_length = longest_match (s, hash_head);
16312+ }
16313+ /* longest_match() sets match_start */
16314+
16315+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
16316+ (s->match_length == MIN_MATCH &&
16317+ s->strstart - s->match_start > TOO_FAR))) {
16318+
16319+ /* If prev_match is also MIN_MATCH, match_start is garbage
16320+ * but we will ignore the current match anyway.
16321+ */
16322+ s->match_length = MIN_MATCH-1;
16323+ }
16324+ }
16325+ /* If there was a match at the previous step and the current
16326+ * match is not better, output the previous match:
16327+ */
16328+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
16329+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
16330+ /* Do not insert strings in hash table beyond this. */
16331+
16332+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
16333+
16334+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
16335+ s->prev_length - MIN_MATCH, bflush);
16336+
16337+ /* Insert in hash table all strings up to the end of the match.
16338+ * strstart-1 and strstart are already inserted. If there is not
16339+ * enough lookahead, the last two strings are not inserted in
16340+ * the hash table.
16341+ */
16342+ s->lookahead -= s->prev_length-1;
16343+ s->prev_length -= 2;
16344+ do {
16345+ if (++s->strstart <= max_insert) {
16346+ INSERT_STRING(s, s->strstart, hash_head);
16347+ }
16348+ } while (--s->prev_length != 0);
16349+ s->match_available = 0;
16350+ s->match_length = MIN_MATCH-1;
16351+ s->strstart++;
16352+
16353+ if (bflush) FLUSH_BLOCK(s, 0);
16354+
16355+ } else if (s->match_available) {
16356+ /* If there was no match at the previous position, output a
16357+ * single literal. If there was a match but the current match
16358+ * is longer, truncate the previous match to a single literal.
16359+ */
16360+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
16361+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
16362+ if (bflush) {
16363+ FLUSH_BLOCK_ONLY(s, 0);
16364+ }
16365+ s->strstart++;
16366+ s->lookahead--;
16367+ if (s->strm->avail_out == 0) return need_more;
16368+ } else {
16369+ /* There is no previous match to compare with, wait for
16370+ * the next step to decide.
16371+ */
16372+ s->match_available = 1;
16373+ s->strstart++;
16374+ s->lookahead--;
16375+ }
16376+ }
16377+ Assert (flush != Z_NO_FLUSH, "no flush?");
16378+ if (s->match_available) {
16379+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
16380+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
16381+ s->match_available = 0;
16382+ }
16383+ FLUSH_BLOCK(s, flush == Z_FINISH);
16384+ return flush == Z_FINISH ? finish_done : block_done;
16385+}
16386--- /dev/null Tue Mar 11 13:02:56 2003
16387+++ linux/net/ipsec/deflate.h Mon Feb 9 13:51:03 2004
16388@@ -0,0 +1,318 @@
16389+/* deflate.h -- internal compression state
16390+ * Copyright (C) 1995-2002 Jean-loup Gailly
16391+ * For conditions of distribution and use, see copyright notice in zlib.h
16392+ */
16393+
16394+/* WARNING: this file should *not* be used by applications. It is
16395+ part of the implementation of the compression library and is
16396+ subject to change. Applications should only use zlib.h.
16397+ */
16398+
16399+/* @(#) $Id: deflate.h,v 1.5 2004/07/10 07:48:38 mcr Exp $ */
16400+
16401+#ifndef _DEFLATE_H
16402+#define _DEFLATE_H
16403+
16404+#include "zlib/zutil.h"
16405+
16406+/* ===========================================================================
16407+ * Internal compression state.
16408+ */
16409+
16410+#define LENGTH_CODES 29
16411+/* number of length codes, not counting the special END_BLOCK code */
16412+
16413+#define LITERALS 256
16414+/* number of literal bytes 0..255 */
16415+
16416+#define L_CODES (LITERALS+1+LENGTH_CODES)
16417+/* number of Literal or Length codes, including the END_BLOCK code */
16418+
16419+#define D_CODES 30
16420+/* number of distance codes */
16421+
16422+#define BL_CODES 19
16423+/* number of codes used to transfer the bit lengths */
16424+
16425+#define HEAP_SIZE (2*L_CODES+1)
16426+/* maximum heap size */
16427+
16428+#define MAX_BITS 15
16429+/* All codes must not exceed MAX_BITS bits */
16430+
16431+#define INIT_STATE 42
16432+#define BUSY_STATE 113
16433+#define FINISH_STATE 666
16434+/* Stream status */
16435+
16436+
16437+/* Data structure describing a single value and its code string. */
16438+typedef struct ct_data_s {
16439+ union {
16440+ ush freq; /* frequency count */
16441+ ush code; /* bit string */
16442+ } fc;
16443+ union {
16444+ ush dad; /* father node in Huffman tree */
16445+ ush len; /* length of bit string */
16446+ } dl;
16447+} FAR ct_data;
16448+
16449+#define Freq fc.freq
16450+#define Code fc.code
16451+#define Dad dl.dad
16452+#define Len dl.len
16453+
16454+typedef struct static_tree_desc_s static_tree_desc;
16455+
16456+typedef struct tree_desc_s {
16457+ ct_data *dyn_tree; /* the dynamic tree */
16458+ int max_code; /* largest code with non zero frequency */
16459+ static_tree_desc *stat_desc; /* the corresponding static tree */
16460+} FAR tree_desc;
16461+
16462+typedef ush Pos;
16463+typedef Pos FAR Posf;
16464+typedef unsigned IPos;
16465+
16466+/* A Pos is an index in the character window. We use short instead of int to
16467+ * save space in the various tables. IPos is used only for parameter passing.
16468+ */
16469+
16470+typedef struct internal_state {
16471+ z_streamp strm; /* pointer back to this zlib stream */
16472+ int status; /* as the name implies */
16473+ Bytef *pending_buf; /* output still pending */
16474+ ulg pending_buf_size; /* size of pending_buf */
16475+ Bytef *pending_out; /* next pending byte to output to the stream */
16476+ int pending; /* nb of bytes in the pending buffer */
16477+ int noheader; /* suppress zlib header and adler32 */
16478+ Byte data_type; /* UNKNOWN, BINARY or ASCII */
16479+ Byte method; /* STORED (for zip only) or DEFLATED */
16480+ int last_flush; /* value of flush param for previous deflate call */
16481+
16482+ /* used by deflate.c: */
16483+
16484+ uInt w_size; /* LZ77 window size (32K by default) */
16485+ uInt w_bits; /* log2(w_size) (8..16) */
16486+ uInt w_mask; /* w_size - 1 */
16487+
16488+ Bytef *window;
16489+ /* Sliding window. Input bytes are read into the second half of the window,
16490+ * and move to the first half later to keep a dictionary of at least wSize
16491+ * bytes. With this organization, matches are limited to a distance of
16492+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
16493+ * performed with a length multiple of the block size. Also, it limits
16494+ * the window size to 64K, which is quite useful on MSDOS.
16495+ * To do: use the user input buffer as sliding window.
16496+ */
16497+
16498+ ulg window_size;
16499+ /* Actual size of window: 2*wSize, except when the user input buffer
16500+ * is directly used as sliding window.
16501+ */
16502+
16503+ Posf *prev;
16504+ /* Link to older string with same hash index. To limit the size of this
16505+ * array to 64K, this link is maintained only for the last 32K strings.
16506+ * An index in this array is thus a window index modulo 32K.
16507+ */
16508+
16509+ Posf *head; /* Heads of the hash chains or NIL. */
16510+
16511+ uInt ins_h; /* hash index of string to be inserted */
16512+ uInt hash_size; /* number of elements in hash table */
16513+ uInt hash_bits; /* log2(hash_size) */
16514+ uInt hash_mask; /* hash_size-1 */
16515+
16516+ uInt hash_shift;
16517+ /* Number of bits by which ins_h must be shifted at each input
16518+ * step. It must be such that after MIN_MATCH steps, the oldest
16519+ * byte no longer takes part in the hash key, that is:
16520+ * hash_shift * MIN_MATCH >= hash_bits
16521+ */
16522+
16523+ long block_start;
16524+ /* Window position at the beginning of the current output block. Gets
16525+ * negative when the window is moved backwards.
16526+ */
16527+
16528+ uInt match_length; /* length of best match */
16529+ IPos prev_match; /* previous match */
16530+ int match_available; /* set if previous match exists */
16531+ uInt strstart; /* start of string to insert */
16532+ uInt match_start; /* start of matching string */
16533+ uInt lookahead; /* number of valid bytes ahead in window */
16534+
16535+ uInt prev_length;
16536+ /* Length of the best match at previous step. Matches not greater than this
16537+ * are discarded. This is used in the lazy match evaluation.
16538+ */
16539+
16540+ uInt max_chain_length;
16541+ /* To speed up deflation, hash chains are never searched beyond this
16542+ * length. A higher limit improves compression ratio but degrades the
16543+ * speed.
16544+ */
16545+
16546+ uInt max_lazy_match;
16547+ /* Attempt to find a better match only when the current match is strictly
16548+ * smaller than this value. This mechanism is used only for compression
16549+ * levels >= 4.
16550+ */
16551+# define max_insert_length max_lazy_match
16552+ /* Insert new strings in the hash table only if the match length is not
16553+ * greater than this length. This saves time but degrades compression.
16554+ * max_insert_length is used only for compression levels <= 3.
16555+ */
16556+
16557+ int level; /* compression level (1..9) */
16558+ int strategy; /* favor or force Huffman coding*/
16559+
16560+ uInt good_match;
16561+ /* Use a faster search when the previous match is longer than this */
16562+
16563+ int nice_match; /* Stop searching when current match exceeds this */
16564+
16565+ /* used by trees.c: */
16566+ /* Didn't use ct_data typedef below to supress compiler warning */
16567+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
16568+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
16569+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
16570+
16571+ struct tree_desc_s l_desc; /* desc. for literal tree */
16572+ struct tree_desc_s d_desc; /* desc. for distance tree */
16573+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
16574+
16575+ ush bl_count[MAX_BITS+1];
16576+ /* number of codes at each bit length for an optimal tree */
16577+
16578+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
16579+ int heap_len; /* number of elements in the heap */
16580+ int heap_max; /* element of largest frequency */
16581+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
16582+ * The same heap array is used to build all trees.
16583+ */
16584+
16585+ uch depth[2*L_CODES+1];
16586+ /* Depth of each subtree used as tie breaker for trees of equal frequency
16587+ */
16588+
16589+ uchf *l_buf; /* buffer for literals or lengths */
16590+
16591+ uInt lit_bufsize;
16592+ /* Size of match buffer for literals/lengths. There are 4 reasons for
16593+ * limiting lit_bufsize to 64K:
16594+ * - frequencies can be kept in 16 bit counters
16595+ * - if compression is not successful for the first block, all input
16596+ * data is still in the window so we can still emit a stored block even
16597+ * when input comes from standard input. (This can also be done for
16598+ * all blocks if lit_bufsize is not greater than 32K.)
16599+ * - if compression is not successful for a file smaller than 64K, we can
16600+ * even emit a stored file instead of a stored block (saving 5 bytes).
16601+ * This is applicable only for zip (not gzip or zlib).
16602+ * - creating new Huffman trees less frequently may not provide fast
16603+ * adaptation to changes in the input data statistics. (Take for
16604+ * example a binary file with poorly compressible code followed by
16605+ * a highly compressible string table.) Smaller buffer sizes give
16606+ * fast adaptation but have of course the overhead of transmitting
16607+ * trees more frequently.
16608+ * - I can't count above 4
16609+ */
16610+
16611+ uInt last_lit; /* running index in l_buf */
16612+
16613+ ushf *d_buf;
16614+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
16615+ * the same number of elements. To use different lengths, an extra flag
16616+ * array would be necessary.
16617+ */
16618+
16619+ ulg opt_len; /* bit length of current block with optimal trees */
16620+ ulg static_len; /* bit length of current block with static trees */
16621+ uInt matches; /* number of string matches in current block */
16622+ int last_eob_len; /* bit length of EOB code for last block */
16623+
16624+#ifdef DEBUG
16625+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
16626+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
16627+#endif
16628+
16629+ ush bi_buf;
16630+ /* Output buffer. bits are inserted starting at the bottom (least
16631+ * significant bits).
16632+ */
16633+ int bi_valid;
16634+ /* Number of valid bits in bi_buf. All bits above the last valid bit
16635+ * are always zero.
16636+ */
16637+
16638+} FAR deflate_state;
16639+
16640+/* Output a byte on the stream.
16641+ * IN assertion: there is enough room in pending_buf.
16642+ */
16643+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
16644+
16645+
16646+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
16647+/* Minimum amount of lookahead, except at the end of the input file.
16648+ * See deflate.c for comments about the MIN_MATCH+1.
16649+ */
16650+
16651+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
16652+/* In order to simplify the code, particularly on 16 bit machines, match
16653+ * distances are limited to MAX_DIST instead of WSIZE.
16654+ */
16655+
16656+ /* in trees.c */
16657+void _tr_init OF((deflate_state *s));
16658+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
16659+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
16660+ int eof));
16661+void _tr_align OF((deflate_state *s));
16662+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
16663+ int eof));
16664+
16665+#define d_code(dist) \
16666+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
16667+/* Mapping from a distance to a distance code. dist is the distance - 1 and
16668+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
16669+ * used.
16670+ */
16671+
16672+#ifndef DEBUG
16673+/* Inline versions of _tr_tally for speed: */
16674+
16675+#if defined(GEN_TREES_H) || !defined(STDC)
16676+ extern uch _length_code[];
16677+ extern uch _dist_code[];
16678+#else
16679+ extern const uch _length_code[];
16680+ extern const uch _dist_code[];
16681+#endif
16682+
16683+# define _tr_tally_lit(s, c, flush) \
16684+ { uch cc = (c); \
16685+ s->d_buf[s->last_lit] = 0; \
16686+ s->l_buf[s->last_lit++] = cc; \
16687+ s->dyn_ltree[cc].Freq++; \
16688+ flush = (s->last_lit == s->lit_bufsize-1); \
16689+ }
16690+# define _tr_tally_dist(s, distance, length, flush) \
16691+ { uch len = (length); \
16692+ ush dist = (distance); \
16693+ s->d_buf[s->last_lit] = dist; \
16694+ s->l_buf[s->last_lit++] = len; \
16695+ dist--; \
16696+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
16697+ s->dyn_dtree[d_code(dist)].Freq++; \
16698+ flush = (s->last_lit == s->lit_bufsize-1); \
16699+ }
16700+#else
16701+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
16702+# define _tr_tally_dist(s, distance, length, flush) \
16703+ flush = _tr_tally(s, distance, length)
16704+#endif
16705+
16706+#endif /* _DEFLATE_H */
16707--- /dev/null Tue Mar 11 13:02:56 2003
16708+++ linux/net/ipsec/des/COPYRIGHT Mon Feb 9 13:51:03 2004
16709@@ -0,0 +1,50 @@
16710+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
16711+All rights reserved.
16712+
16713+This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
16714+The implementation was written so as to conform with MIT's libdes.
16715+
16716+This library is free for commercial and non-commercial use as long as
16717+the following conditions are aheared to. The following conditions
16718+apply to all code found in this distribution.
16719+
16720+Copyright remains Eric Young's, and as such any Copyright notices in
16721+the code are not to be removed.
16722+If this package is used in a product, Eric Young should be given attribution
16723+as the author of that the SSL library. This can be in the form of a textual
16724+message at program startup or in documentation (online or textual) provided
16725+with the package.
16726+
16727+Redistribution and use in source and binary forms, with or without
16728+modification, are permitted provided that the following conditions
16729+are met:
16730+1. Redistributions of source code must retain the copyright
16731+ notice, this list of conditions and the following disclaimer.
16732+2. Redistributions in binary form must reproduce the above copyright
16733+ notice, this list of conditions and the following disclaimer in the
16734+ documentation and/or other materials provided with the distribution.
16735+3. All advertising materials mentioning features or use of this software
16736+ must display the following acknowledgement:
16737+ This product includes software developed by Eric Young (eay@cryptsoft.com)
16738+
16739+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
16740+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16741+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16742+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16743+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16744+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16745+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16746+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16747+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16748+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16749+SUCH DAMAGE.
16750+
16751+The license and distribution terms for any publically available version or
16752+derivative of this code cannot be changed. i.e. this code cannot simply be
16753+copied and put under another distrubution license
16754+[including the GNU Public License.]
16755+
16756+The reason behind this being stated in this direct manner is past
16757+experience in code simply being copied and the attribution removed
16758+from it and then being distributed as part of other packages. This
16759+implementation was a non-trivial and unpaid effort.
16760--- /dev/null Tue Mar 11 13:02:56 2003
16761+++ linux/net/ipsec/des/INSTALL Mon Feb 9 13:51:03 2004
16762@@ -0,0 +1,69 @@
16763+Check the CC and CFLAGS lines in the makefile
16764+
16765+If your C library does not support the times(3) function, change the
16766+#define TIMES to
16767+#undef TIMES in speed.c
16768+If it does, check the HZ value for the times(3) function.
16769+If your system does not define CLK_TCK it will be assumed to
16770+be 100.0.
16771+
16772+If possible use gcc v 2.7.?
16773+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
16774+In recent times, some system compilers give better performace.
16775+
16776+type 'make'
16777+
16778+run './destest' to check things are ok.
16779+run './rpw' to check the tty code for reading passwords works.
16780+run './speed' to see how fast those optimisations make the library run :-)
16781+run './des_opts' to determin the best compile time options.
16782+
16783+The output from des_opts should be put in the makefile options and des_enc.c
16784+should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
16785+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
16786+and then you can use the 'DES_PTR' option.
16787+
16788+The file options.txt has the options listed for best speed on quite a
16789+few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
16790+turn on the relevent option in the Makefile
16791+
16792+There are some special Makefile targets that make life easier.
16793+make cc - standard cc build
16794+make gcc - standard gcc build
16795+make x86-elf - x86 assembler (elf), linux-elf.
16796+make x86-out - x86 assembler (a.out), FreeBSD
16797+make x86-solaris- x86 assembler
16798+make x86-bsdi - x86 assembler (a.out with primative assembler).
16799+
16800+If at all possible use the assembler (for Windows NT/95, use
16801+asm/win32.obj to link with). The x86 assembler is very very fast.
16802+
16803+A make install will by default install
16804+libdes.a in /usr/local/lib/libdes.a
16805+des in /usr/local/bin/des
16806+des_crypt.man in /usr/local/man/man3/des_crypt.3
16807+des.man in /usr/local/man/man1/des.1
16808+des.h in /usr/include/des.h
16809+
16810+des(1) should be compatible with sunOS's but I have been unable to
16811+test it.
16812+
16813+These routines should compile on MSDOS, most 32bit and 64bit version
16814+of Unix (BSD and SYSV) and VMS, without modification.
16815+The only problems should be #include files that are in the wrong places.
16816+
16817+These routines can be compiled under MSDOS.
16818+I have successfully encrypted files using des(1) under MSDOS and then
16819+decrypted the files on a SparcStation.
16820+I have been able to compile and test the routines with
16821+Microsoft C v 5.1 and Turbo C v 2.0.
16822+The code in this library is in no way optimised for the 16bit
16823+operation of MSDOS.
16824+
16825+When building for glibc, ignore all of the above and just unpack into
16826+glibc-1.??/des and then gmake as per normal.
16827+
16828+As a final note on performace. Certain CPUs like sparcs and Alpha often give
16829+a %10 speed difference depending on the link order. It is rather anoying
16830+when one program reports 'x' DES encrypts a second and another reports
16831+'x*0.9' the speed.
16832--- /dev/null Tue Mar 11 13:02:56 2003
16833+++ linux/net/ipsec/des/Makefile Mon Feb 9 13:51:03 2004
16834@@ -0,0 +1,63 @@
16835+# Makefile for KLIPS kernel code as a module for 2.6 kernels
16836+#
16837+# Makefile for KLIPS kernel code as a module
16838+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
16839+# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
16840+#
16841+# This program is free software; you can redistribute it and/or modify it
16842+# under the terms of the GNU General Public License as published by the
16843+# Free Software Foundation; either version 2 of the License, or (at your
16844+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16845+#
16846+# This program is distributed in the hope that it will be useful, but
16847+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16848+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16849+# for more details.
16850+#
16851+# RCSID $Id: Makefile.fs2_6,v 1.2.2.1 2005/08/12 16:10:57 ken Exp $
16852+#
16853+# Note! Dependencies are done automagically by 'make dep', which also
16854+# removes any old dependencies. DON'T put your own dependencies here
16855+# unless it's something special (ie not a .c file).
16856+#
16857+
16858+obj-$(CONFIG_KLIPS_ENC_3DES) += ipsec_alg_3des.o
16859+obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
16860+obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
16861+obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
16862+
16863+ifeq ($(strip ${SUBARCH}),)
16864+SUBARCH:=${ARCH}
16865+endif
16866+
16867+# the assembly version expects frame pointers, which are
16868+# optional in many kernel builds. If you want speed, you should
16869+# probably use cryptoapi code instead.
16870+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
16871+ifeq (${USEASSEMBLY},i386y)
16872+obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
16873+else
16874+obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
16875+endif
16876+
16877+#
16878+# $Log: Makefile.fs2_6,v $
16879+# Revision 1.2.2.1 2005/08/12 16:10:57 ken
16880+# do not use assembly code with there are no frame pointers
16881+#
16882+# Revision 1.3 2005/08/12 14:13:59 mcr
16883+# do not use assembly code with there are no frame pointers,
16884+# as it does not have the right linkages.
16885+#
16886+# Revision 1.2 2005/04/29 05:13:07 mcr
16887+# 3DES algorithm code.
16888+#
16889+# Revision 1.1 2004/08/17 03:27:30 mcr
16890+# klips 2.6 edits.
16891+#
16892+#
16893+# Local Variables:
16894+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
16895+# End Variables:
16896+#
16897+
16898--- /dev/null Tue Mar 11 13:02:56 2003
16899+++ linux/net/ipsec/des/README Mon Feb 9 13:51:03 2004
16900@@ -0,0 +1,54 @@
16901+
16902+ libdes, Version 4.01 10-Jan-97
16903+
16904+ Copyright (c) 1997, Eric Young
16905+ All rights reserved.
16906+
16907+ This program is free software; you can redistribute it and/or modify
16908+ it under the terms specified in COPYRIGHT.
16909+
16910+--
16911+The primary ftp site for this library is
16912+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
16913+libdes is now also shipped with SSLeay. Primary ftp site of
16914+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
16915+
16916+The best way to build this library is to build it as part of SSLeay.
16917+
16918+This kit builds a DES encryption library and a DES encryption program.
16919+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
16920+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
16921+implementation of crypt(3).
16922+It contains support routines to read keys from a terminal,
16923+generate a random key, generate a key from an arbitrary length string,
16924+read/write encrypted data from/to a file descriptor.
16925+
16926+The implementation was written so as to conform with the manual entry
16927+for the des_crypt(3) library routines from MIT's project Athena.
16928+
16929+destest should be run after compilation to test the des routines.
16930+rpw should be run after compilation to test the read password routines.
16931+The des program is a replacement for the sun des command. I believe it
16932+conforms to the sun version.
16933+
16934+The Imakefile is setup for use in the kerberos distribution.
16935+
16936+These routines are best compiled with gcc or any other good
16937+optimising compiler.
16938+Just turn you optimiser up to the highest settings and run destest
16939+after the build to make sure everything works.
16940+
16941+I believe these routines are close to the fastest and most portable DES
16942+routines that use small lookup tables (4.5k) that are publicly available.
16943+The fcrypt routine is faster than ufc's fcrypt (when compiling with
16944+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
16945+(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
16946+[ 10-Jan-97 and a function of an incorrect speed testing program in
16947+ ufc which gave much better test figures that reality ].
16948+
16949+It is worth noting that on sparc and Alpha CPUs, performance of the DES
16950+library can vary by upto %10 due to the positioning of files after application
16951+linkage.
16952+
16953+Eric Young (eay@cryptsoft.com)
16954+
16955--- /dev/null Tue Mar 11 13:02:56 2003
16956+++ linux/net/ipsec/des/README.freeswan Mon Feb 9 13:51:03 2004
16957@@ -0,0 +1,33 @@
16958+The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
16959+
16960+We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
16961+on the Alpha, instead of just noting the issue in a comment.
16962+
16963+We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
16964+use it, and its call to sprintf() can cause subtle difficulties when KLIPS
16965+is built as a module (depending on details of Linux configuration options).
16966+
16967+We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
16968+it cope better with Linux kernel Makefile stupidities, and took out an
16969+explicit CC=gcc (unwise on systems with strange compilers).
16970+
16971+We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
16972+of one function found only in the full libdes (not in libdes-lite), to
16973+avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
16974+Schultz for spotting this and pointing out the fixes.)
16975+
16976+We deleted a couple of .obj files in the asm subdirectory, which appear to
16977+have been included in the original library by accident.
16978+
16979+We have added an include of our Makefile.inc file, to permit overriding
16980+things like choice of compiler (although the libdes Makefile would
16981+probably need some work to make this effective).
16982+
16983+
16984+
16985+Note that Eric Young is no longer at the email address listed in these
16986+files, and is (alas) no longer working on free crypto software.
16987+
16988+
16989+
16990+This file is RCSID $Id: README.freeswan,v 1.12 2004/07/10 08:06:51 mcr Exp $
16991--- /dev/null Tue Mar 11 13:02:56 2003
16992+++ linux/net/ipsec/des/VERSION Mon Feb 9 13:51:03 2004
16993@@ -0,0 +1,406 @@
16994+Version 4.04
16995+ Fixed a few tests in destest. Also added x86 assember for
16996+ des_ncbc_encrypt() which is the standard cbc mode function.
16997+ This makes a very very large performace difference.
16998+ Ariel Glenn ariel@columbia.edu reports that the terminal
16999+ 'turn echo off' can return (errno == EINVAL) under solaris
17000+ when redirection is used. So I now catch that as well as ENOTTY.
17001+
17002+
17003+Version 4.03
17004+ Left a static out of enc_write.c, which caused to buffer to be
17005+ continiously malloc()ed. Does anyone use these functions? I keep
17006+ on feeling like removing them since I only had these in there
17007+ for a version of kerberised login. Anyway, this was pointed out
17008+ by Theo de Raadt <deraadt@cvs.openbsd.org>
17009+ The 'n' bit ofb code was wrong, it was not shifting the shift
17010+ register. It worked correctly for n == 64. Thanks to
17011+ Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
17012+
17013+Version 4.02
17014+ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
17015+ when checking for weak keys which is wrong :-(, pointed out by
17016+ Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
17017+
17018+Version 4.01
17019+ Even faster inner loop in the DES assembler for x86 and a modification
17020+ for IP/FP which is faster on x86. Both of these changes are
17021+ from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
17022+ changes make the assembler run %40 faster on a pentium. This is just
17023+ a case of getting the instruction sequence 'just right'.
17024+ All credit to 'Svend' :-)
17025+ Quite a few special x86 'make' targets.
17026+ A libdes-l (lite) distribution.
17027+
17028+Version 4.00
17029+ After a bit of a pause, I'll up the major version number since this
17030+ is mostly a performace release. I've added x86 assembler and
17031+ added more options for performance. A %28 speedup for gcc
17032+ on a pentium and the assembler is a %50 speedup.
17033+ MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
17034+ Run des_opts to work out which options should be used.
17035+ DES_RISC1/DES_RISC2 use alternative inner loops which use
17036+ more registers but should give speedups on any CPU that does
17037+ dual issue (pentium). DES_UNROLL unrolls the inner loop,
17038+ which costs in code size.
17039+
17040+Version 3.26
17041+ I've finally removed one of the shifts in D_ENCRYPT. This
17042+ meant I've changed the des_SPtrans table (spr.h), the set_key()
17043+ function and some things in des_enc.c. This has definitly
17044+ made things faster :-). I've known about this one for some
17045+ time but I've been too lazy to follow it up :-).
17046+ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
17047+ instead of L^=((..)|(..)|(..).. This should save a register at
17048+ least.
17049+ Assember for x86. The file to replace is des_enc.c, which is replaced
17050+ by one of the assembler files found in asm. Look at des/asm/readme
17051+ for more info.
17052+
17053+ /* Modification to fcrypt so it can be compiled to support
17054+ HPUX 10.x's long password format, define -DLONGCRYPT to use this.
17055+ Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
17056+
17057+ SIGWINCH case put in des_read_passwd() so the function does not
17058+ 'exit' if this function is recieved.
17059+
17060+Version 3.25 17/07/96
17061+ Modified read_pwd.c so that stdin can be read if not a tty.
17062+ Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
17063+ des_init_random_number_generator() shortened due to VMS linker
17064+ limits.
17065+ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
17066+ 8 byte quantites xored before and after encryption.
17067+ des_xcbc_encryption() - the name is funny to preserve the des_
17068+ prefix on all functions.
17069+
17070+Version 3.24 20/04/96
17071+ The DES_PTR macro option checked and used by SSLeay configuration
17072+
17073+Version 3.23 11/04/96
17074+ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
17075+ it gives a %20 speedup :-)
17076+ Fixed the problem with des.pl under perl5. The patches were
17077+ sent by Ed Kubaitis (ejk@uiuc.edu).
17078+ if fcrypt.c, changed values to handle illegal salt values the way
17079+ normal crypt() implementations do. Some programs apparently use
17080+ them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
17081+
17082+Version 3.22 29/11/95
17083+ Bug in des(1), an error with the uuencoding stuff when the
17084+ 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
17085+ for the patch.
17086+
17087+Version 3.21 22/11/95
17088+ After some emailing back and forth with
17089+ Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
17090+ and in a future version I will probably put in some of the
17091+ optimisation he suggested for use with the DES_USE_PTR option.
17092+ Extra routines from Mark Murray <mark@grondar.za> for use in
17093+ freeBSD. They mostly involve random number generation for use
17094+ with kerberos. They involve evil machine specific system calls
17095+ etc so I would normally suggest pushing this stuff into the
17096+ application and/or using RAND_seed()/RAND_bytes() if you are
17097+ using this DES library as part of SSLeay.
17098+ Redone the read_pw() function so that it is cleaner and
17099+ supports termios, thanks to Sameer Parekh <sameer@c2.org>
17100+ for the initial patches for this.
17101+ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
17102+ done just to make things more consistent.
17103+ I have also now added triple DES versions of cfb and ofb.
17104+
17105+Version 3.20
17106+ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
17107+ my des_random_seed() function was only copying 4 bytes of the
17108+ passed seed into the init structure. It is now fixed to copy 8.
17109+ My own suggestion is to used something like MD5 :-)
17110+
17111+Version 3.19
17112+ While looking at my code one day, I though, why do I keep on
17113+ calling des_encrypt(in,out,ks,enc) when every function that
17114+ calls it has in and out the same. So I dropped the 'out'
17115+ parameter, people should not be using this function.
17116+
17117+Version 3.18 30/08/95
17118+ Fixed a few bit with the distribution and the filenames.
17119+ 3.17 had been munged via a move to DOS and back again.
17120+ NO CODE CHANGES
17121+
17122+Version 3.17 14/07/95
17123+ Fixed ede3 cbc which I had broken in 3.16. I have also
17124+ removed some unneeded variables in 7-8 of the routines.
17125+
17126+Version 3.16 26/06/95
17127+ Added des_encrypt2() which does not use IP/FP, used by triple
17128+ des routines. Tweaked things a bit elsewhere. %13 speedup on
17129+ sparc and %6 on a R4400 for ede3 cbc mode.
17130+
17131+Version 3.15 06/06/95
17132+ Added des_ncbc_encrypt(), it is des_cbc mode except that it is
17133+ 'normal' and copies the new iv value back over the top of the
17134+ passed parameter.
17135+ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
17136+ the iv. THIS WILL BREAK EXISTING CODE, but since this function
17137+ only new, I feel I can change it, not so with des_cbc_encrypt :-(.
17138+ I need to update the documentation.
17139+
17140+Version 3.14 31/05/95
17141+ New release upon the world, as part of my SSL implementation.
17142+ New copyright and usage stuff. Basically free for all to use
17143+ as long as you say it came from me :-)
17144+
17145+Version 3.13 31/05/95
17146+ A fix in speed.c, if HZ is not defined, I set it to 100.0
17147+ which is reasonable for most unixes except SunOS 4.x.
17148+ I now have a #ifdef sun but timing for SunOS 4.x looked very
17149+ good :-(. At my last job where I used SunOS 4.x, it was
17150+ defined to be 60.0 (look at the old INSTALL documentation), at
17151+ the last release had it changed to 100.0 since I now work with
17152+ Solaris2 and SVR4 boxes.
17153+ Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
17154+ one out.
17155+
17156+Version 3.12 08/05/95
17157+ As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
17158+ my D_ENCRYPT macro in crypt() had an un-necessary variable.
17159+ It has been removed.
17160+
17161+Version 3.11 03/05/95
17162+ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
17163+ and one iv. It is a standard and I needed it for my SSL code.
17164+ It makes more sense to use this for triple DES than
17165+ 3cbc_encrypt(). I have also added (or should I say tested :-)
17166+ cfb64_encrypt() which is cfb64 but it will encrypt a partial
17167+ number of bytes - 3 bytes in 3 bytes out. Again this is for
17168+ my SSL library, as a form of encryption to use with SSL
17169+ telnet.
17170+
17171+Version 3.10 22/03/95
17172+ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
17173+ to cbc3_encrypt, the 2 iv values that were being returned to
17174+ be used in the next call were reversed :-(.
17175+ Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
17176+ this error.
17177+
17178+Version 3.09 01/02/95
17179+ Fixed des_random_key to far more random, it was rather feeble
17180+ with regards to picking the initial seed. The problem was
17181+ pointed out by Olaf Kirch <okir@monad.swb.de>.
17182+
17183+Version 3.08 14/12/94
17184+ Added Makefile.PL so libdes can be built into perl5.
17185+ Changed des_locl.h so RAND is always defined.
17186+
17187+Version 3.07 05/12/94
17188+ Added GNUmake and stuff so the library can be build with
17189+ glibc.
17190+
17191+Version 3.06 30/08/94
17192+ Added rpc_enc.c which contains _des_crypt. This is for use in
17193+ secure_rpc v 4.0
17194+ Finally fixed the cfb_enc problems.
17195+ Fixed a few parameter parsing bugs in des (-3 and -b), thanks
17196+ to Rob McMillan <R.McMillan@its.gu.edu.au>
17197+
17198+Version 3.05 21/04/94
17199+ for unsigned long l; gcc does not produce ((l>>34) == 0)
17200+ This causes bugs in cfb_enc.
17201+ Thanks to Hadmut Danisch <danisch@ira.uka.de>
17202+
17203+Version 3.04 20/04/94
17204+ Added a version number to des.c and libdes.a
17205+
17206+Version 3.03 12/01/94
17207+ Fixed a bug in non zero iv in 3cbc_enc.
17208+
17209+Version 3.02 29/10/93
17210+ I now work in a place where there are 6+ architectures and 14+
17211+ OS versions :-).
17212+ Fixed TERMIO definition so the most sys V boxes will work :-)
17213+
17214+Release upon comp.sources.misc
17215+Version 3.01 08/10/93
17216+ Added des_3cbc_encrypt()
17217+
17218+Version 3.00 07/10/93
17219+ Fixed up documentation.
17220+ quad_cksum definitely compatible with MIT's now.
17221+
17222+Version 2.30 24/08/93
17223+ Triple DES now defaults to triple cbc but can do triple ecb
17224+ with the -b flag.
17225+ Fixed some MSDOS uuen/uudecoding problems, thanks to
17226+ Added prototypes.
17227+
17228+Version 2.22 29/06/93
17229+ Fixed a bug in des_is_weak_key() which stopped it working :-(
17230+ thanks to engineering@MorningStar.Com.
17231+
17232+Version 2.21 03/06/93
17233+ des(1) with no arguments gives quite a bit of help.
17234+ Added -c (generate ckecksum) flag to des(1).
17235+ Added -3 (triple DES) flag to des(1).
17236+ Added cfb and ofb routines to the library.
17237+
17238+Version 2.20 11/03/93
17239+ Added -u (uuencode) flag to des(1).
17240+ I have been playing with byte order in quad_cksum to make it
17241+ compatible with MIT's version. All I can say is avid this
17242+ function if possible since MIT's output is endian dependent.
17243+
17244+Version 2.12 14/10/92
17245+ Added MSDOS specific macro in ecb_encrypt which gives a %70
17246+ speed up when the code is compiled with turbo C.
17247+
17248+Version 2.11 12/10/92
17249+ Speedup in set_key (recoding of PC-1)
17250+ I now do it in 47 simple operations, down from 60.
17251+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
17252+ for motivating me to look for a faster system :-)
17253+ The speedup is probably less that 1% but it is still 13
17254+ instructions less :-).
17255+
17256+Version 2.10 06/10/92
17257+ The code now works on the 64bit ETA10 and CRAY without modifications or
17258+ #defines. I believe the code should work on any machine that
17259+ defines long, int or short to be 8 bytes long.
17260+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
17261+ for helping me fix the code to run on 64bit machines (he had
17262+ access to an ETA10).
17263+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
17264+ for testing the routines on a CRAY.
17265+ read_password.c has been renamed to read_passwd.c
17266+ string_to_key.c has been renamed to string2key.c
17267+
17268+Version 2.00 14/09/92
17269+ Made mods so that the library should work on 64bit CPU's.
17270+ Removed all my uchar and ulong defs. To many different
17271+ versions of unix define them in their header files in too many
17272+ different combinations :-)
17273+ IRIX - Sillicon Graphics mods (mostly in read_password.c).
17274+ Thanks to Andrew Daviel (advax@erich.triumf.ca)
17275+
17276+Version 1.99 26/08/92
17277+ Fixed a bug or 2 in enc_read.c
17278+ Fixed a bug in enc_write.c
17279+ Fixed a pseudo bug in fcrypt.c (very obscure).
17280+
17281+Version 1.98 31/07/92
17282+ Support for the ETA10. This is a strange machine that defines
17283+ longs and ints as 8 bytes and shorts as 4 bytes.
17284+ Since I do evil things with long * that assume that they are 4
17285+ bytes. Look in the Makefile for the option to compile for
17286+ this machine. quad_cksum appears to have problems but I
17287+ will don't have the time to fix it right now, and this is not
17288+ a function that uses DES and so will not effect the main uses
17289+ of the library.
17290+
17291+Version 1.97 20/05/92 eay
17292+ Fixed the Imakefile and made some changes to des.h to fix some
17293+ problems when building this package with Kerberos v 4.
17294+
17295+Version 1.96 18/05/92 eay
17296+ Fixed a small bug in string_to_key() where problems could
17297+ occur if des_check_key was set to true and the string
17298+ generated a weak key.
17299+
17300+Patch2 posted to comp.sources.misc
17301+Version 1.95 13/05/92 eay
17302+ Added an alternative version of the D_ENCRYPT macro in
17303+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the
17304+ other will be faster. This was inspired by
17305+ Dana How <how@isl.stanford.edu>, and her pointers about doing the
17306+ *(ulong *)((uchar *)ptr+(value&0xfc))
17307+ vs
17308+ ptr[value&0x3f]
17309+ to stop the C compiler doing a <<2 to convert the long array index.
17310+
17311+Version 1.94 05/05/92 eay
17312+ Fixed an incompatibility between my string_to_key and the MIT
17313+ version. When the key is longer than 8 chars, I was wrapping
17314+ with a different method. To use the old version, define
17315+ OLD_STR_TO_KEY in the makefile. Thanks to
17316+ viktor@newsu.shearson.com (Viktor Dukhovni).
17317+
17318+Version 1.93 28/04/92 eay
17319+ Fixed the VMS mods so that echo is now turned off in
17320+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
17321+ MSDOS support added. The routines can be compiled with
17322+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
17323+
17324+Patch1 posted to comp.sources.misc
17325+Version 1.92 13/04/92 eay
17326+ Changed D_ENCRYPT so that the rotation of R occurs outside of
17327+ the loop. This required rotating all the longs in sp.h (now
17328+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
17329+ speed.c has been changed so it will work without SIGALRM. If
17330+ times(3) is not present it will try to use ftime() instead.
17331+
17332+Version 1.91 08/04/92 eay
17333+ Added -E/-D options to des(1) so it can use string_to_key.
17334+ Added SVR4 mods suggested by witr@rwwa.COM
17335+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
17336+ anyone knows how to turn of tty echo in VMS please tell me or
17337+ implement it yourself :-).
17338+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
17339+ does not like IN/OUT being used.
17340+
17341+Libdes posted to comp.sources.misc
17342+Version 1.9 24/03/92 eay
17343+ Now contains a fast small crypt replacement.
17344+ Added des(1) command.
17345+ Added des_rw_mode so people can use cbc encryption with
17346+ enc_read and enc_write.
17347+
17348+Version 1.8 15/10/91 eay
17349+ Bug in cbc_cksum.
17350+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
17351+ one out.
17352+
17353+Version 1.7 24/09/91 eay
17354+ Fixed set_key :-)
17355+ set_key is 4 times faster and takes less space.
17356+ There are a few minor changes that could be made.
17357+
17358+Version 1.6 19/09/1991 eay
17359+ Finally go IP and FP finished.
17360+ Now I need to fix set_key.
17361+ This version is quite a bit faster that 1.51
17362+
17363+Version 1.52 15/06/1991 eay
17364+ 20% speedup in ecb_encrypt by changing the E bit selection
17365+ to use 2 32bit words. This also required modification of the
17366+ sp table. There is still a way to speedup the IP and IP-1
17367+ (hints from outer@sq.com) still working on this one :-(.
17368+
17369+Version 1.51 07/06/1991 eay
17370+ Faster des_encrypt by loop unrolling
17371+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
17372+
17373+Version 1.50 28/05/1991 eay
17374+ Optimised the code a bit more for the sparc. I have improved the
17375+ speed of the inner des_encrypt by speeding up the initial and
17376+ final permutations.
17377+
17378+Version 1.40 23/10/1990 eay
17379+ Fixed des_random_key, it did not produce a random key :-(
17380+
17381+Version 1.30 2/10/1990 eay
17382+ Have made des_quad_cksum the same as MIT's, the full package
17383+ should be compatible with MIT's
17384+ Have tested on a DECstation 3100
17385+ Still need to fix des_set_key (make it faster).
17386+ Does des_cbc_encrypts at 70.5k/sec on a 3100.
17387+
17388+Version 1.20 18/09/1990 eay
17389+ Fixed byte order dependencies.
17390+ Fixed (I hope) all the word alignment problems.
17391+ Speedup in des_ecb_encrypt.
17392+
17393+Version 1.10 11/09/1990 eay
17394+ Added des_enc_read and des_enc_write.
17395+ Still need to fix des_quad_cksum.
17396+ Still need to document des_enc_read and des_enc_write.
17397+
17398+Version 1.00 27/08/1990 eay
17399+
17400--- /dev/null Tue Mar 11 13:02:56 2003
17401+++ linux/net/ipsec/des/asm/des-586.pl Mon Feb 9 13:51:03 2004
17402@@ -0,0 +1,251 @@
17403+#!/usr/local/bin/perl
17404+#
17405+# The inner loop instruction sequence and the IP/FP modifications are from
17406+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
17407+#
17408+
17409+push(@INC,"perlasm","../../perlasm");
17410+require "x86asm.pl";
17411+require "cbc.pl";
17412+require "desboth.pl";
17413+
17414+# base code is in microsft
17415+# op dest, source
17416+# format.
17417+#
17418+
17419+&asm_init($ARGV[0],"des-586.pl");
17420+
17421+$L="edi";
17422+$R="esi";
17423+
17424+&external_label("des_SPtrans");
17425+&des_encrypt("des_encrypt",1);
17426+&des_encrypt("des_encrypt2",0);
17427+&des_encrypt3("des_encrypt3",1);
17428+&des_encrypt3("des_decrypt3",0);
17429+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
17430+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
17431+
17432+&asm_finish();
17433+
17434+sub des_encrypt
17435+ {
17436+ local($name,$do_ip)=@_;
17437+
17438+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
17439+
17440+ &push("esi");
17441+ &push("edi");
17442+
17443+ &comment("");
17444+ &comment("Load the 2 words");
17445+ $ks="ebp";
17446+
17447+ if ($do_ip)
17448+ {
17449+ &mov($R,&wparam(0));
17450+ &xor( "ecx", "ecx" );
17451+
17452+ &push("ebx");
17453+ &push("ebp");
17454+
17455+ &mov("eax",&DWP(0,$R,"",0));
17456+ &mov("ebx",&wparam(2)); # get encrypt flag
17457+ &mov($L,&DWP(4,$R,"",0));
17458+ &comment("");
17459+ &comment("IP");
17460+ &IP_new("eax",$L,$R,3);
17461+ }
17462+ else
17463+ {
17464+ &mov("eax",&wparam(0));
17465+ &xor( "ecx", "ecx" );
17466+
17467+ &push("ebx");
17468+ &push("ebp");
17469+
17470+ &mov($R,&DWP(0,"eax","",0));
17471+ &mov("ebx",&wparam(2)); # get encrypt flag
17472+ &rotl($R,3);
17473+ &mov($L,&DWP(4,"eax","",0));
17474+ &rotl($L,3);
17475+ }
17476+
17477+ &mov( $ks, &wparam(1) );
17478+ &cmp("ebx","0");
17479+ &je(&label("start_decrypt"));
17480+
17481+ for ($i=0; $i<16; $i+=2)
17482+ {
17483+ &comment("");
17484+ &comment("Round $i");
17485+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17486+
17487+ &comment("");
17488+ &comment("Round ".sprintf("%d",$i+1));
17489+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17490+ }
17491+ &jmp(&label("end"));
17492+
17493+ &set_label("start_decrypt");
17494+
17495+ for ($i=15; $i>0; $i-=2)
17496+ {
17497+ &comment("");
17498+ &comment("Round $i");
17499+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17500+ &comment("");
17501+ &comment("Round ".sprintf("%d",$i-1));
17502+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17503+ }
17504+
17505+ &set_label("end");
17506+
17507+ if ($do_ip)
17508+ {
17509+ &comment("");
17510+ &comment("FP");
17511+ &mov("edx",&wparam(0));
17512+ &FP_new($L,$R,"eax",3);
17513+
17514+ &mov(&DWP(0,"edx","",0),"eax");
17515+ &mov(&DWP(4,"edx","",0),$R);
17516+ }
17517+ else
17518+ {
17519+ &comment("");
17520+ &comment("Fixup");
17521+ &rotr($L,3); # r
17522+ &mov("eax",&wparam(0));
17523+ &rotr($R,3); # l
17524+ &mov(&DWP(0,"eax","",0),$L);
17525+ &mov(&DWP(4,"eax","",0),$R);
17526+ }
17527+
17528+ &pop("ebp");
17529+ &pop("ebx");
17530+ &pop("edi");
17531+ &pop("esi");
17532+ &ret();
17533+
17534+ &function_end_B($name);
17535+ }
17536+
17537+sub D_ENCRYPT
17538+ {
17539+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
17540+
17541+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17542+ &xor( $tmp1, $tmp1);
17543+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17544+ &xor( $u, $R);
17545+ &xor( $t, $R);
17546+ &and( $u, "0xfcfcfcfc" );
17547+ &and( $t, "0xcfcfcfcf" );
17548+ &movb( &LB($tmp1), &LB($u) );
17549+ &movb( &LB($tmp2), &HB($u) );
17550+ &rotr( $t, 4 );
17551+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
17552+ &movb( &LB($tmp1), &LB($t) );
17553+ &xor( $L, $ks);
17554+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
17555+ &xor( $L, $ks); ######
17556+ &movb( &LB($tmp2), &HB($t) );
17557+ &shr( $u, 16);
17558+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
17559+ &xor( $L, $ks); ######
17560+ &movb( &LB($tmp1), &HB($u) );
17561+ &shr( $t, 16);
17562+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
17563+ &xor( $L, $ks);
17564+ &mov( $ks, &wparam(1) );
17565+ &movb( &LB($tmp2), &HB($t) );
17566+ &and( $u, "0xff" );
17567+ &and( $t, "0xff" );
17568+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
17569+ &xor( $L, $tmp1);
17570+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
17571+ &xor( $L, $tmp1);
17572+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
17573+ &xor( $L, $tmp1);
17574+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
17575+ &xor( $L, $tmp1);
17576+ }
17577+
17578+sub n2a
17579+ {
17580+ sprintf("%d",$_[0]);
17581+ }
17582+
17583+# now has a side affect of rotating $a by $shift
17584+sub R_PERM_OP
17585+ {
17586+ local($a,$b,$tt,$shift,$mask,$last)=@_;
17587+
17588+ &rotl( $a, $shift ) if ($shift != 0);
17589+ &mov( $tt, $a );
17590+ &xor( $a, $b );
17591+ &and( $a, $mask );
17592+ if (!$last eq $b)
17593+ {
17594+ &xor( $b, $a );
17595+ &xor( $tt, $a );
17596+ }
17597+ else
17598+ {
17599+ &xor( $tt, $a );
17600+ &xor( $b, $a );
17601+ }
17602+ &comment("");
17603+ }
17604+
17605+sub IP_new
17606+ {
17607+ local($l,$r,$tt,$lr)=@_;
17608+
17609+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
17610+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
17611+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
17612+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
17613+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
17614+
17615+ if ($lr != 3)
17616+ {
17617+ if (($lr-3) < 0)
17618+ { &rotr($tt, 3-$lr); }
17619+ else { &rotl($tt, $lr-3); }
17620+ }
17621+ if ($lr != 2)
17622+ {
17623+ if (($lr-2) < 0)
17624+ { &rotr($r, 2-$lr); }
17625+ else { &rotl($r, $lr-2); }
17626+ }
17627+ }
17628+
17629+sub FP_new
17630+ {
17631+ local($l,$r,$tt,$lr)=@_;
17632+
17633+ if ($lr != 2)
17634+ {
17635+ if (($lr-2) < 0)
17636+ { &rotl($r, 2-$lr); }
17637+ else { &rotr($r, $lr-2); }
17638+ }
17639+ if ($lr != 3)
17640+ {
17641+ if (($lr-3) < 0)
17642+ { &rotl($l, 3-$lr); }
17643+ else { &rotr($l, $lr-3); }
17644+ }
17645+
17646+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
17647+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
17648+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
17649+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
17650+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
17651+ &rotr($tt , 4);
17652+ }
17653+
17654--- /dev/null Tue Mar 11 13:02:56 2003
17655+++ linux/net/ipsec/des/asm/des686.pl Mon Feb 9 13:51:03 2004
17656@@ -0,0 +1,230 @@
17657+#!/usr/local/bin/perl
17658+
17659+$prog="des686.pl";
17660+
17661+# base code is in microsft
17662+# op dest, source
17663+# format.
17664+#
17665+
17666+# WILL NOT WORK ANYMORE WITH desboth.pl
17667+require "desboth.pl";
17668+
17669+if ( ($ARGV[0] eq "elf"))
17670+ { require "x86unix.pl"; }
17671+elsif ( ($ARGV[0] eq "a.out"))
17672+ { $aout=1; require "x86unix.pl"; }
17673+elsif ( ($ARGV[0] eq "sol"))
17674+ { $sol=1; require "x86unix.pl"; }
17675+elsif ( ($ARGV[0] eq "cpp"))
17676+ { $cpp=1; require "x86unix.pl"; }
17677+elsif ( ($ARGV[0] eq "win32"))
17678+ { require "x86ms.pl"; }
17679+else
17680+ {
17681+ print STDERR <<"EOF";
17682+Pick one target type from
17683+ elf - linux, FreeBSD etc
17684+ a.out - old linux
17685+ sol - x86 solaris
17686+ cpp - format so x86unix.cpp can be used
17687+ win32 - Windows 95/Windows NT
17688+EOF
17689+ exit(1);
17690+ }
17691+
17692+&comment("Don't even think of reading this code");
17693+&comment("It was automatically generated by $prog");
17694+&comment("Which is a perl program used to generate the x86 assember for");
17695+&comment("any of elf, a.out, Win32, or Solaris");
17696+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
17697+&comment("eric <eay\@cryptsoft.com>");
17698+&comment("");
17699+
17700+&file("dx86xxxx");
17701+
17702+$L="edi";
17703+$R="esi";
17704+
17705+&des_encrypt("des_encrypt",1);
17706+&des_encrypt("des_encrypt2",0);
17707+
17708+&des_encrypt3("des_encrypt3",1);
17709+&des_encrypt3("des_decrypt3",0);
17710+
17711+&file_end();
17712+
17713+sub des_encrypt
17714+ {
17715+ local($name,$do_ip)=@_;
17716+
17717+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
17718+
17719+ &comment("");
17720+ &comment("Load the 2 words");
17721+ &mov("eax",&wparam(0));
17722+ &mov($L,&DWP(0,"eax","",0));
17723+ &mov($R,&DWP(4,"eax","",0));
17724+
17725+ $ksp=&wparam(1);
17726+
17727+ if ($do_ip)
17728+ {
17729+ &comment("");
17730+ &comment("IP");
17731+ &IP_new($L,$R,"eax");
17732+ }
17733+
17734+ &comment("");
17735+ &comment("fixup rotate");
17736+ &rotl($R,3);
17737+ &rotl($L,3);
17738+ &exch($L,$R);
17739+
17740+ &comment("");
17741+ &comment("load counter, key_schedule and enc flag");
17742+ &mov("eax",&wparam(2)); # get encrypt flag
17743+ &mov("ebp",&wparam(1)); # get ks
17744+ &cmp("eax","0");
17745+ &je(&label("start_decrypt"));
17746+
17747+ # encrypting part
17748+
17749+ for ($i=0; $i<16; $i+=2)
17750+ {
17751+ &comment("");
17752+ &comment("Round $i");
17753+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17754+
17755+ &comment("");
17756+ &comment("Round ".sprintf("%d",$i+1));
17757+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17758+ }
17759+ &jmp(&label("end"));
17760+
17761+ &set_label("start_decrypt");
17762+
17763+ for ($i=15; $i>0; $i-=2)
17764+ {
17765+ &comment("");
17766+ &comment("Round $i");
17767+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17768+ &comment("");
17769+ &comment("Round ".sprintf("%d",$i-1));
17770+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17771+ }
17772+
17773+ &set_label("end");
17774+
17775+ &comment("");
17776+ &comment("Fixup");
17777+ &rotr($L,3); # r
17778+ &rotr($R,3); # l
17779+
17780+ if ($do_ip)
17781+ {
17782+ &comment("");
17783+ &comment("FP");
17784+ &FP_new($R,$L,"eax");
17785+ }
17786+
17787+ &mov("eax",&wparam(0));
17788+ &mov(&DWP(0,"eax","",0),$L);
17789+ &mov(&DWP(4,"eax","",0),$R);
17790+
17791+ &function_end($name);
17792+ }
17793+
17794+
17795+# The logic is to load R into 2 registers and operate on both at the same time.
17796+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
17797+# while also masking the other copy and doing a lookup. We then also accumulate the
17798+# L value in 2 registers then combine them at the end.
17799+sub D_ENCRYPT
17800+ {
17801+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
17802+
17803+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17804+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17805+ &xor( $u, $R );
17806+ &xor( $t, $R );
17807+ &rotr( $t, 4 );
17808+
17809+ # the numbers at the end of the line are origional instruction order
17810+ &mov( $tmp2, $u ); # 1 2
17811+ &mov( $tmp1, $t ); # 1 1
17812+ &and( $tmp2, "0xfc" ); # 1 4
17813+ &and( $tmp1, "0xfc" ); # 1 3
17814+ &shr( $t, 8 ); # 1 5
17815+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
17816+ &shr( $u, 8 ); # 1 6
17817+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
17818+
17819+ &mov( $tmp2, $u ); # 2 2
17820+ &xor( $L, $tmp1 ); # 1 9
17821+ &and( $tmp2, "0xfc" ); # 2 4
17822+ &mov( $tmp1, $t ); # 2 1
17823+ &and( $tmp1, "0xfc" ); # 2 3
17824+ &shr( $t, 8 ); # 2 5
17825+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
17826+ &shr( $u, 8 ); # 2 6
17827+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
17828+ &mov( $tmp2, $u ); # 3 2
17829+
17830+ &xor( $L, $tmp1 ); # 2 9
17831+ &and( $tmp2, "0xfc" ); # 3 4
17832+
17833+ &mov( $tmp1, $t ); # 3 1
17834+ &shr( $u, 8 ); # 3 6
17835+ &and( $tmp1, "0xfc" ); # 3 3
17836+ &shr( $t, 8 ); # 3 5
17837+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
17838+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
17839+
17840+ &and( $t, "0xfc" ); # 4 1
17841+ &xor( $L, $tmp1 ); # 3 9
17842+
17843+ &and( $u, "0xfc" ); # 4 2
17844+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
17845+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
17846+ }
17847+
17848+sub PERM_OP
17849+ {
17850+ local($a,$b,$tt,$shift,$mask)=@_;
17851+
17852+ &mov( $tt, $a );
17853+ &shr( $tt, $shift );
17854+ &xor( $tt, $b );
17855+ &and( $tt, $mask );
17856+ &xor( $b, $tt );
17857+ &shl( $tt, $shift );
17858+ &xor( $a, $tt );
17859+ }
17860+
17861+sub IP_new
17862+ {
17863+ local($l,$r,$tt)=@_;
17864+
17865+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
17866+ &PERM_OP($l,$r,$tt,16,"0x0000ffff");
17867+ &PERM_OP($r,$l,$tt, 2,"0x33333333");
17868+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
17869+ &PERM_OP($r,$l,$tt, 1,"0x55555555");
17870+ }
17871+
17872+sub FP_new
17873+ {
17874+ local($l,$r,$tt)=@_;
17875+
17876+ &PERM_OP($l,$r,$tt, 1,"0x55555555");
17877+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
17878+ &PERM_OP($l,$r,$tt, 2,"0x33333333");
17879+ &PERM_OP($r,$l,$tt,16,"0x0000ffff");
17880+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
17881+ }
17882+
17883+sub n2a
17884+ {
17885+ sprintf("%d",$_[0]);
17886+ }
17887--- /dev/null Tue Mar 11 13:02:56 2003
17888+++ linux/net/ipsec/des/asm/desboth.pl Mon Feb 9 13:51:03 2004
17889@@ -0,0 +1,79 @@
17890+#!/usr/local/bin/perl
17891+
17892+$L="edi";
17893+$R="esi";
17894+
17895+sub des_encrypt3
17896+ {
17897+ local($name,$enc)=@_;
17898+
17899+ &function_begin_B($name,"");
17900+ &push("ebx");
17901+ &mov("ebx",&wparam(0));
17902+
17903+ &push("ebp");
17904+ &push("esi");
17905+
17906+ &push("edi");
17907+
17908+ &comment("");
17909+ &comment("Load the data words");
17910+ &mov($L,&DWP(0,"ebx","",0));
17911+ &mov($R,&DWP(4,"ebx","",0));
17912+ &stack_push(3);
17913+
17914+ &comment("");
17915+ &comment("IP");
17916+ &IP_new($L,$R,"edx",0);
17917+
17918+ # put them back
17919+
17920+ if ($enc)
17921+ {
17922+ &mov(&DWP(4,"ebx","",0),$R);
17923+ &mov("eax",&wparam(1));
17924+ &mov(&DWP(0,"ebx","",0),"edx");
17925+ &mov("edi",&wparam(2));
17926+ &mov("esi",&wparam(3));
17927+ }
17928+ else
17929+ {
17930+ &mov(&DWP(4,"ebx","",0),$R);
17931+ &mov("esi",&wparam(1));
17932+ &mov(&DWP(0,"ebx","",0),"edx");
17933+ &mov("edi",&wparam(2));
17934+ &mov("eax",&wparam(3));
17935+ }
17936+ &mov(&swtmp(2), (($enc)?"1":"0"));
17937+ &mov(&swtmp(1), "eax");
17938+ &mov(&swtmp(0), "ebx");
17939+ &call("des_encrypt2");
17940+ &mov(&swtmp(2), (($enc)?"0":"1"));
17941+ &mov(&swtmp(1), "edi");
17942+ &mov(&swtmp(0), "ebx");
17943+ &call("des_encrypt2");
17944+ &mov(&swtmp(2), (($enc)?"1":"0"));
17945+ &mov(&swtmp(1), "esi");
17946+ &mov(&swtmp(0), "ebx");
17947+ &call("des_encrypt2");
17948+
17949+ &stack_pop(3);
17950+ &mov($L,&DWP(0,"ebx","",0));
17951+ &mov($R,&DWP(4,"ebx","",0));
17952+
17953+ &comment("");
17954+ &comment("FP");
17955+ &FP_new($L,$R,"eax",0);
17956+
17957+ &mov(&DWP(0,"ebx","",0),"eax");
17958+ &mov(&DWP(4,"ebx","",0),$R);
17959+
17960+ &pop("edi");
17961+ &pop("esi");
17962+ &pop("ebp");
17963+ &pop("ebx");
17964+ &ret();
17965+ &function_end_B($name);
17966+ }
17967+
17968+
17969--- /dev/null Tue Mar 11 13:02:56 2003
17970+++ linux/net/ipsec/des/asm/readme Mon Feb 9 13:51:03 2004
17971@@ -0,0 +1,131 @@
17972+First up, let me say I don't like writing in assembler. It is not portable,
17973+dependant on the particular CPU architecture release and is generally a pig
17974+to debug and get right. Having said that, the x86 architecture is probably
17975+the most important for speed due to number of boxes and since
17976+it appears to be the worst architecture to to get
17977+good C compilers for. So due to this, I have lowered myself to do
17978+assembler for the inner DES routines in libdes :-).
17979+
17980+The file to implement in assembler is des_enc.c. Replace the following
17981+4 functions
17982+des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
17983+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
17984+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17985+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17986+
17987+They encrypt/decrypt the 64 bits held in 'data' using
17988+the 'ks' key schedules. The only difference between the 4 functions is that
17989+des_encrypt2() does not perform IP() or FP() on the data (this is an
17990+optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
17991+perform triple des. The triple DES routines are in here because it does
17992+make a big difference to have them located near the des_encrypt2 function
17993+at link time..
17994+
17995+Now as we all know, there are lots of different operating systems running on
17996+x86 boxes, and unfortunately they normally try to make sure their assembler
17997+formating is not the same as the other peoples.
17998+The 4 main formats I know of are
17999+Microsoft Windows 95/Windows NT
18000+Elf Includes Linux and FreeBSD(?).
18001+a.out The older Linux.
18002+Solaris Same as Elf but different comments :-(.
18003+
18004+Now I was not overly keen to write 4 different copies of the same code,
18005+so I wrote a few perl routines to output the correct assembler, given
18006+a target assembler type. This code is ugly and is just a hack.
18007+The libraries are x86unix.pl and x86ms.pl.
18008+des586.pl, des686.pl and des-som[23].pl are the programs to actually
18009+generate the assembler.
18010+
18011+So to generate elf assembler
18012+perl des-som3.pl elf >dx86-elf.s
18013+For Windows 95/NT
18014+perl des-som2.pl win32 >win32.asm
18015+
18016+[ update 4 Jan 1996 ]
18017+I have added another way to do things.
18018+perl des-som3.pl cpp >dx86-cpp.s
18019+generates a file that will be included by dx86unix.cpp when it is compiled.
18020+To build for elf, a.out, solaris, bsdi etc,
18021+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
18022+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
18023+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
18024+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
18025+This was done to cut down the number of files in the distribution.
18026+
18027+Now the ugly part. I acquired my copy of Intels
18028+"Optimization's For Intel's 32-Bit Processors" and found a few interesting
18029+things. First, the aim of the exersize is to 'extract' one byte at a time
18030+from a word and do an array lookup. This involves getting the byte from
18031+the 4 locations in the word and moving it to a new word and doing the lookup.
18032+The most obvious way to do this is
18033+xor eax, eax # clear word
18034+movb al, cl # get low byte
18035+xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
18036+movb al, ch # get next byte
18037+xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
18038+shr ecx 16
18039+which seems ok. For the pentium, this system appears to be the best.
18040+One has to do instruction interleaving to keep both functional units
18041+operating, but it is basically very efficient.
18042+
18043+Now the crunch. When a full register is used after a partial write, eg.
18044+mov al, cl
18045+xor edi, DWORD PTR 0x100+des_SP[eax]
18046+386 - 1 cycle stall
18047+486 - 1 cycle stall
18048+586 - 0 cycle stall
18049+686 - at least 7 cycle stall (page 22 of the above mentioned document).
18050+
18051+So the technique that produces the best results on a pentium, according to
18052+the documentation, will produce hideous results on a pentium pro.
18053+
18054+To get around this, des686.pl will generate code that is not as fast on
18055+a pentium, should be very good on a pentium pro.
18056+mov eax, ecx # copy word
18057+shr ecx, 8 # line up next byte
18058+and eax, 0fch # mask byte
18059+xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
18060+mov eax, ecx # get word
18061+shr ecx 8 # line up next byte
18062+and eax, 0fch # mask byte
18063+xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
18064+
18065+Due to the execution units in the pentium, this actually works quite well.
18066+For a pentium pro it should be very good. This is the type of output
18067+Visual C++ generates.
18068+
18069+There is a third option. instead of using
18070+mov al, ch
18071+which is bad on the pentium pro, one may be able to use
18072+movzx eax, ch
18073+which may not incur the partial write penalty. On the pentium,
18074+this instruction takes 4 cycles so is not worth using but on the
18075+pentium pro it appears it may be worth while. I need access to one to
18076+experiment :-).
18077+
18078+eric (20 Oct 1996)
18079+
18080+22 Nov 1996 - I have asked people to run the 2 different version on pentium
18081+pros and it appears that the intel documentation is wrong. The
18082+mov al,bh is still faster on a pentium pro, so just use the des586.pl
18083+install des686.pl
18084+
18085+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
18086+functions into des_enc.c because it does make a massive performance
18087+difference on some boxes to have the functions code located close to
18088+the des_encrypt2() function.
18089+
18090+9 Jan 1997 - des-som2.pl is now the correct perl script to use for
18091+pentiums. It contains an inner loop from
18092+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
18093+273,000 per second. He had a previous version at 250,000 and the best
18094+I was able to get was 203,000. The content has not changed, this is all
18095+due to instruction sequencing (and actual instructions choice) which is able
18096+to keep both functional units of the pentium going.
18097+We may have lost the ugly register usage restrictions when x86 went 32 bit
18098+but for the pentium it has been replaced by evil instruction ordering tricks.
18099+
18100+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
18101+raw DES at 281,000 per second on a pentium 100.
18102+
18103--- /dev/null Tue Mar 11 13:02:56 2003
18104+++ linux/net/ipsec/des/cbc_enc.c Mon Feb 9 13:51:03 2004
18105@@ -0,0 +1,135 @@
18106+/* crypto/des/cbc_enc.c */
18107+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18108+ * All rights reserved.
18109+ *
18110+ * This package is an SSL implementation written
18111+ * by Eric Young (eay@cryptsoft.com).
18112+ * The implementation was written so as to conform with Netscapes SSL.
18113+ *
18114+ * This library is free for commercial and non-commercial use as long as
18115+ * the following conditions are aheared to. The following conditions
18116+ * apply to all code found in this distribution, be it the RC4, RSA,
18117+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18118+ * included with this distribution is covered by the same copyright terms
18119+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18120+ *
18121+ * Copyright remains Eric Young's, and as such any Copyright notices in
18122+ * the code are not to be removed.
18123+ * If this package is used in a product, Eric Young should be given attribution
18124+ * as the author of the parts of the library used.
18125+ * This can be in the form of a textual message at program startup or
18126+ * in documentation (online or textual) provided with the package.
18127+ *
18128+ * Redistribution and use in source and binary forms, with or without
18129+ * modification, are permitted provided that the following conditions
18130+ * are met:
18131+ * 1. Redistributions of source code must retain the copyright
18132+ * notice, this list of conditions and the following disclaimer.
18133+ * 2. Redistributions in binary form must reproduce the above copyright
18134+ * notice, this list of conditions and the following disclaimer in the
18135+ * documentation and/or other materials provided with the distribution.
18136+ * 3. All advertising materials mentioning features or use of this software
18137+ * must display the following acknowledgement:
18138+ * "This product includes cryptographic software written by
18139+ * Eric Young (eay@cryptsoft.com)"
18140+ * The word 'cryptographic' can be left out if the rouines from the library
18141+ * being used are not cryptographic related :-).
18142+ * 4. If you include any Windows specific code (or a derivative thereof) from
18143+ * the apps directory (application code) you must include an acknowledgement:
18144+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18145+ *
18146+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18147+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18148+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18149+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18150+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18151+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18152+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18153+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18154+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18155+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18156+ * SUCH DAMAGE.
18157+ *
18158+ * The licence and distribution terms for any publically available version or
18159+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18160+ * copied and put under another distribution licence
18161+ * [including the GNU Public Licence.]
18162+ */
18163+
18164+#include "des/des_locl.h"
18165+
18166+void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
18167+des_cblock (*input);
18168+des_cblock (*output);
18169+long length;
18170+des_key_schedule schedule;
18171+des_cblock (*ivec);
18172+int enc;
18173+ {
18174+ register DES_LONG tin0,tin1;
18175+ register DES_LONG tout0,tout1,xor0,xor1;
18176+ register unsigned char *in,*out;
18177+ register long l=length;
18178+ DES_LONG tin[2];
18179+ unsigned char *iv;
18180+
18181+ in=(unsigned char *)input;
18182+ out=(unsigned char *)output;
18183+ iv=(unsigned char *)ivec;
18184+
18185+ if (enc)
18186+ {
18187+ c2l(iv,tout0);
18188+ c2l(iv,tout1);
18189+ for (l-=8; l>=0; l-=8)
18190+ {
18191+ c2l(in,tin0);
18192+ c2l(in,tin1);
18193+ tin0^=tout0; tin[0]=tin0;
18194+ tin1^=tout1; tin[1]=tin1;
18195+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18196+ tout0=tin[0]; l2c(tout0,out);
18197+ tout1=tin[1]; l2c(tout1,out);
18198+ }
18199+ if (l != -8)
18200+ {
18201+ c2ln(in,tin0,tin1,l+8);
18202+ tin0^=tout0; tin[0]=tin0;
18203+ tin1^=tout1; tin[1]=tin1;
18204+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18205+ tout0=tin[0]; l2c(tout0,out);
18206+ tout1=tin[1]; l2c(tout1,out);
18207+ }
18208+ }
18209+ else
18210+ {
18211+ c2l(iv,xor0);
18212+ c2l(iv,xor1);
18213+ for (l-=8; l>=0; l-=8)
18214+ {
18215+ c2l(in,tin0); tin[0]=tin0;
18216+ c2l(in,tin1); tin[1]=tin1;
18217+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18218+ tout0=tin[0]^xor0;
18219+ tout1=tin[1]^xor1;
18220+ l2c(tout0,out);
18221+ l2c(tout1,out);
18222+ xor0=tin0;
18223+ xor1=tin1;
18224+ }
18225+ if (l != -8)
18226+ {
18227+ c2l(in,tin0); tin[0]=tin0;
18228+ c2l(in,tin1); tin[1]=tin1;
18229+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18230+ tout0=tin[0]^xor0;
18231+ tout1=tin[1]^xor1;
18232+ l2cn(tout0,tout1,out,l+8);
18233+ /* xor0=tin0;
18234+ xor1=tin1; */
18235+ }
18236+ }
18237+ tin0=tin1=tout0=tout1=xor0=xor1=0;
18238+ tin[0]=tin[1]=0;
18239+ }
18240+
18241--- /dev/null Tue Mar 11 13:02:56 2003
18242+++ linux/net/ipsec/des/des.doc Mon Feb 9 13:51:03 2004
18243@@ -0,0 +1,505 @@
18244+The DES library.
18245+
18246+Please note that this library was originally written to operate with
18247+eBones, a version of Kerberos that had had encryption removed when it left
18248+the USA and then put back in. As such there are some routines that I will
18249+advise not using but they are still in the library for historical reasons.
18250+For all calls that have an 'input' and 'output' variables, they can be the
18251+same.
18252+
18253+This library requires the inclusion of 'des.h'.
18254+
18255+All of the encryption functions take what is called a des_key_schedule as an
18256+argument. A des_key_schedule is an expanded form of the des key.
18257+A des_key is 8 bytes of odd parity, the type used to hold the key is a
18258+des_cblock. A des_cblock is an array of 8 bytes, often in this library
18259+description I will refer to input bytes when the function specifies
18260+des_cblock's as input or output, this just means that the variable should
18261+be a multiple of 8 bytes.
18262+
18263+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
18264+specify decryption. The functions and global variable are as follows:
18265+
18266+int des_check_key;
18267+ DES keys are supposed to be odd parity. If this variable is set to
18268+ a non-zero value, des_set_key() will check that the key has odd
18269+ parity and is not one of the known weak DES keys. By default this
18270+ variable is turned off;
18271+
18272+void des_set_odd_parity(
18273+des_cblock *key );
18274+ This function takes a DES key (8 bytes) and sets the parity to odd.
18275+
18276+int des_is_weak_key(
18277+des_cblock *key );
18278+ This function returns a non-zero value if the DES key passed is a
18279+ weak, DES key. If it is a weak key, don't use it, try a different
18280+ one. If you are using 'random' keys, the chances of hitting a weak
18281+ key are 1/2^52 so it is probably not worth checking for them.
18282+
18283+int des_set_key(
18284+des_cblock *key,
18285+des_key_schedule schedule);
18286+ Des_set_key converts an 8 byte DES key into a des_key_schedule.
18287+ A des_key_schedule is an expanded form of the key which is used to
18288+ perform actual encryption. It can be regenerated from the DES key
18289+ so it only needs to be kept when encryption or decryption is about
18290+ to occur. Don't save or pass around des_key_schedule's since they
18291+ are CPU architecture dependent, DES keys are not. If des_check_key
18292+ is non zero, zero is returned if the key has the wrong parity or
18293+ the key is a weak key, else 1 is returned.
18294+
18295+int des_key_sched(
18296+des_cblock *key,
18297+des_key_schedule schedule);
18298+ An alternative name for des_set_key().
18299+
18300+int des_rw_mode; /* defaults to DES_PCBC_MODE */
18301+ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
18302+ This specifies the function to use in the enc_read() and enc_write()
18303+ functions.
18304+
18305+void des_encrypt(
18306+unsigned long *data,
18307+des_key_schedule ks,
18308+int enc);
18309+ This is the DES encryption function that gets called by just about
18310+ every other DES routine in the library. You should not use this
18311+ function except to implement 'modes' of DES. I say this because the
18312+ functions that call this routine do the conversion from 'char *' to
18313+ long, and this needs to be done to make sure 'non-aligned' memory
18314+ access do not occur. The characters are loaded 'little endian',
18315+ have a look at my source code for more details on how I use this
18316+ function.
18317+ Data is a pointer to 2 unsigned long's and ks is the
18318+ des_key_schedule to use. enc, is non zero specifies encryption,
18319+ zero if decryption.
18320+
18321+void des_encrypt2(
18322+unsigned long *data,
18323+des_key_schedule ks,
18324+int enc);
18325+ This functions is the same as des_encrypt() except that the DES
18326+ initial permutation (IP) and final permutation (FP) have been left
18327+ out. As for des_encrypt(), you should not use this function.
18328+ It is used by the routines in my library that implement triple DES.
18329+ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
18330+ as des_encrypt() des_encrypt() des_encrypt() except faster :-).
18331+
18332+void des_ecb_encrypt(
18333+des_cblock *input,
18334+des_cblock *output,
18335+des_key_schedule ks,
18336+int enc);
18337+ This is the basic Electronic Code Book form of DES, the most basic
18338+ form. Input is encrypted into output using the key represented by
18339+ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
18340+ decryption occurs. Input is 8 bytes long and output is 8 bytes.
18341+ (the des_cblock structure is 8 chars).
18342+
18343+void des_ecb3_encrypt(
18344+des_cblock *input,
18345+des_cblock *output,
18346+des_key_schedule ks1,
18347+des_key_schedule ks2,
18348+des_key_schedule ks3,
18349+int enc);
18350+ This is the 3 key EDE mode of ECB DES. What this means is that
18351+ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
18352+ then encrypted again with ks3, before being put into output;
18353+ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
18354+ that only takes 2 des_key_schedules that implements,
18355+ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
18356+
18357+void des_cbc_encrypt(
18358+des_cblock *input,
18359+des_cblock *output,
18360+long length,
18361+des_key_schedule ks,
18362+des_cblock *ivec,
18363+int enc);
18364+ This routine implements DES in Cipher Block Chaining mode.
18365+ Input, which should be a multiple of 8 bytes is encrypted
18366+ (or decrypted) to output which will also be a multiple of 8 bytes.
18367+ The number of bytes is in length (and from what I've said above,
18368+ should be a multiple of 8). If length is not a multiple of 8, I'm
18369+ not being held responsible :-). ivec is the initialisation vector.
18370+ This function does not modify this variable. To correctly implement
18371+ cbc mode, you need to do one of 2 things; copy the last 8 bytes of
18372+ cipher text for use as the next ivec in your application,
18373+ or use des_ncbc_encrypt().
18374+ Only this routine has this problem with updating the ivec, all
18375+ other routines that are implementing cbc mode update ivec.
18376+
18377+void des_ncbc_encrypt(
18378+des_cblock *input,
18379+des_cblock *output,
18380+long length,
18381+des_key_schedule sk,
18382+des_cblock *ivec,
18383+int enc);
18384+ For historical reasons, des_cbc_encrypt() did not update the
18385+ ivec with the value requires so that subsequent calls to
18386+ des_cbc_encrypt() would 'chain'. This was needed so that the same
18387+ 'length' values would not need to be used when decrypting.
18388+ des_ncbc_encrypt() does the right thing. It is the same as
18389+ des_cbc_encrypt accept that ivec is updates with the correct value
18390+ to pass in subsequent calls to des_ncbc_encrypt(). I advise using
18391+ des_ncbc_encrypt() instead of des_cbc_encrypt();
18392+
18393+void des_xcbc_encrypt(
18394+des_cblock *input,
18395+des_cblock *output,
18396+long length,
18397+des_key_schedule sk,
18398+des_cblock *ivec,
18399+des_cblock *inw,
18400+des_cblock *outw,
18401+int enc);
18402+ This is RSA's DESX mode of DES. It uses inw and outw to
18403+ 'whiten' the encryption. inw and outw are secret (unlike the iv)
18404+ and are as such, part of the key. So the key is sort of 24 bytes.
18405+ This is much better than cbc des.
18406+
18407+void des_3cbc_encrypt(
18408+des_cblock *input,
18409+des_cblock *output,
18410+long length,
18411+des_key_schedule sk1,
18412+des_key_schedule sk2,
18413+des_cblock *ivec1,
18414+des_cblock *ivec2,
18415+int enc);
18416+ This function is flawed, do not use it. I have left it in the
18417+ library because it is used in my des(1) program and will function
18418+ correctly when used by des(1). If I removed the function, people
18419+ could end up unable to decrypt files.
18420+ This routine implements outer triple cbc encryption using 2 ks and
18421+ 2 ivec's. Use des_ede2_cbc_encrypt() instead.
18422+
18423+void des_ede3_cbc_encrypt(
18424+des_cblock *input,
18425+des_cblock *output,
18426+long length,
18427+des_key_schedule ks1,
18428+des_key_schedule ks2,
18429+des_key_schedule ks3,
18430+des_cblock *ivec,
18431+int enc);
18432+ This function implements inner triple CBC DES encryption with 3
18433+ keys. What this means is that each 'DES' operation
18434+ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
18435+ Again, this is cbc mode so an ivec is requires.
18436+ This mode is used by SSL.
18437+ There is also a des_ede2_cbc_encrypt() that only uses 2
18438+ des_key_schedule's, the first being reused for the final
18439+ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
18440+ is used by the RSAref library.
18441+
18442+void des_pcbc_encrypt(
18443+des_cblock *input,
18444+des_cblock *output,
18445+long length,
18446+des_key_schedule ks,
18447+des_cblock *ivec,
18448+int enc);
18449+ This is Propagating Cipher Block Chaining mode of DES. It is used
18450+ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
18451+
18452+void des_cfb_encrypt(
18453+unsigned char *in,
18454+unsigned char *out,
18455+int numbits,
18456+long length,
18457+des_key_schedule ks,
18458+des_cblock *ivec,
18459+int enc);
18460+ Cipher Feedback Back mode of DES. This implementation 'feeds back'
18461+ in numbit blocks. The input (and output) is in multiples of numbits
18462+ bits. numbits should to be a multiple of 8 bits. Length is the
18463+ number of bytes input. If numbits is not a multiple of 8 bits,
18464+ the extra bits in the bytes will be considered padding. So if
18465+ numbits is 12, for each 2 input bytes, the 4 high bits of the
18466+ second byte will be ignored. So to encode 72 bits when using
18467+ a numbits of 12 take 12 bytes. To encode 72 bits when using
18468+ numbits of 9 will take 16 bytes. To encode 80 bits when using
18469+ numbits of 16 will take 10 bytes. etc, etc. This padding will
18470+ apply to both input and output.
18471+
18472+
18473+void des_cfb64_encrypt(
18474+unsigned char *in,
18475+unsigned char *out,
18476+long length,
18477+des_key_schedule ks,
18478+des_cblock *ivec,
18479+int *num,
18480+int enc);
18481+ This is one of the more useful functions in this DES library, it
18482+ implements CFB mode of DES with 64bit feedback. Why is this
18483+ useful you ask? Because this routine will allow you to encrypt an
18484+ arbitrary number of bytes, no 8 byte padding. Each call to this
18485+ routine will encrypt the input bytes to output and then update ivec
18486+ and num. num contains 'how far' we are though ivec. If this does
18487+ not make much sense, read more about cfb mode of DES :-).
18488+
18489+void des_ede3_cfb64_encrypt(
18490+unsigned char *in,
18491+unsigned char *out,
18492+long length,
18493+des_key_schedule ks1,
18494+des_key_schedule ks2,
18495+des_key_schedule ks3,
18496+des_cblock *ivec,
18497+int *num,
18498+int enc);
18499+ Same as des_cfb64_encrypt() accept that the DES operation is
18500+ triple DES. As usual, there is a macro for
18501+ des_ede2_cfb64_encrypt() which reuses ks1.
18502+
18503+void des_ofb_encrypt(
18504+unsigned char *in,
18505+unsigned char *out,
18506+int numbits,
18507+long length,
18508+des_key_schedule ks,
18509+des_cblock *ivec);
18510+ This is a implementation of Output Feed Back mode of DES. It is
18511+ the same as des_cfb_encrypt() in that numbits is the size of the
18512+ units dealt with during input and output (in bits).
18513+
18514+void des_ofb64_encrypt(
18515+unsigned char *in,
18516+unsigned char *out,
18517+long length,
18518+des_key_schedule ks,
18519+des_cblock *ivec,
18520+int *num);
18521+ The same as des_cfb64_encrypt() except that it is Output Feed Back
18522+ mode.
18523+
18524+void des_ede3_ofb64_encrypt(
18525+unsigned char *in,
18526+unsigned char *out,
18527+long length,
18528+des_key_schedule ks1,
18529+des_key_schedule ks2,
18530+des_key_schedule ks3,
18531+des_cblock *ivec,
18532+int *num);
18533+ Same as des_ofb64_encrypt() accept that the DES operation is
18534+ triple DES. As usual, there is a macro for
18535+ des_ede2_ofb64_encrypt() which reuses ks1.
18536+
18537+int des_read_pw_string(
18538+char *buf,
18539+int length,
18540+char *prompt,
18541+int verify);
18542+ This routine is used to get a password from the terminal with echo
18543+ turned off. Buf is where the string will end up and length is the
18544+ size of buf. Prompt is a string presented to the 'user' and if
18545+ verify is set, the key is asked for twice and unless the 2 copies
18546+ match, an error is returned. A return code of -1 indicates a
18547+ system error, 1 failure due to use interaction, and 0 is success.
18548+
18549+unsigned long des_cbc_cksum(
18550+des_cblock *input,
18551+des_cblock *output,
18552+long length,
18553+des_key_schedule ks,
18554+des_cblock *ivec);
18555+ This function produces an 8 byte checksum from input that it puts in
18556+ output and returns the last 4 bytes as a long. The checksum is
18557+ generated via cbc mode of DES in which only the last 8 byes are
18558+ kept. I would recommend not using this function but instead using
18559+ the EVP_Digest routines, or at least using MD5 or SHA. This
18560+ function is used by Kerberos v4 so that is why it stays in the
18561+ library.
18562+
18563+char *des_fcrypt(
18564+const char *buf,
18565+const char *salt
18566+char *ret);
18567+ This is my fast version of the unix crypt(3) function. This version
18568+ takes only a small amount of space relative to other fast
18569+ crypt() implementations. This is different to the normal crypt
18570+ in that the third parameter is the buffer that the return value
18571+ is written into. It needs to be at least 14 bytes long. This
18572+ function is thread safe, unlike the normal crypt.
18573+
18574+char *crypt(
18575+const char *buf,
18576+const char *salt);
18577+ This function calls des_fcrypt() with a static array passed as the
18578+ third parameter. This emulates the normal non-thread safe semantics
18579+ of crypt(3).
18580+
18581+void des_string_to_key(
18582+char *str,
18583+des_cblock *key);
18584+ This function takes str and converts it into a DES key. I would
18585+ recommend using MD5 instead and use the first 8 bytes of output.
18586+ When I wrote the first version of these routines back in 1990, MD5
18587+ did not exist but I feel these routines are still sound. This
18588+ routines is compatible with the one in MIT's libdes.
18589+
18590+void des_string_to_2keys(
18591+char *str,
18592+des_cblock *key1,
18593+des_cblock *key2);
18594+ This function takes str and converts it into 2 DES keys.
18595+ I would recommend using MD5 and using the 16 bytes as the 2 keys.
18596+ I have nothing against these 2 'string_to_key' routines, it's just
18597+ that if you say that your encryption key is generated by using the
18598+ 16 bytes of an MD5 hash, every-one knows how you generated your
18599+ keys.
18600+
18601+int des_read_password(
18602+des_cblock *key,
18603+char *prompt,
18604+int verify);
18605+ This routine combines des_read_pw_string() with des_string_to_key().
18606+
18607+int des_read_2passwords(
18608+des_cblock *key1,
18609+des_cblock *key2,
18610+char *prompt,
18611+int verify);
18612+ This routine combines des_read_pw_string() with des_string_to_2key().
18613+
18614+void des_random_seed(
18615+des_cblock key);
18616+ This routine sets a starting point for des_random_key().
18617+
18618+void des_random_key(
18619+des_cblock ret);
18620+ This function return a random key. Make sure to 'seed' the random
18621+ number generator (with des_random_seed()) before using this function.
18622+ I personally now use a MD5 based random number system.
18623+
18624+int des_enc_read(
18625+int fd,
18626+char *buf,
18627+int len,
18628+des_key_schedule ks,
18629+des_cblock *iv);
18630+ This function will write to a file descriptor the encrypted data
18631+ from buf. This data will be preceded by a 4 byte 'byte count' and
18632+ will be padded out to 8 bytes. The encryption is either CBC of
18633+ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
18634+ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
18635+ DES_PCBC_MODE.
18636+
18637+int des_enc_write(
18638+int fd,
18639+char *buf,
18640+int len,
18641+des_key_schedule ks,
18642+des_cblock *iv);
18643+ This routines read stuff written by des_enc_read() and decrypts it.
18644+ I have used these routines quite a lot but I don't believe they are
18645+ suitable for non-blocking io. If you are after a full
18646+ authentication/encryption over networks, have a look at SSL instead.
18647+
18648+unsigned long des_quad_cksum(
18649+des_cblock *input,
18650+des_cblock *output,
18651+long length,
18652+int out_count,
18653+des_cblock *seed);
18654+ This is a function from Kerberos v4 that is not anything to do with
18655+ DES but was needed. It is a cksum that is quicker to generate than
18656+ des_cbc_cksum(); I personally would use MD5 routines now.
18657+=====
18658+Modes of DES
18659+Quite a bit of the following information has been taken from
18660+ AS 2805.5.2
18661+ Australian Standard
18662+ Electronic funds transfer - Requirements for interfaces,
18663+ Part 5.2: Modes of operation for an n-bit block cipher algorithm
18664+ Appendix A
18665+
18666+There are several different modes in which DES can be used, they are
18667+as follows.
18668+
18669+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
18670+- 64 bits are enciphered at a time.
18671+- The order of the blocks can be rearranged without detection.
18672+- The same plaintext block always produces the same ciphertext block
18673+ (for the same key) making it vulnerable to a 'dictionary attack'.
18674+- An error will only affect one ciphertext block.
18675+
18676+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
18677+- a multiple of 64 bits are enciphered at a time.
18678+- The CBC mode produces the same ciphertext whenever the same
18679+ plaintext is encrypted using the same key and starting variable.
18680+- The chaining operation makes the ciphertext blocks dependent on the
18681+ current and all preceding plaintext blocks and therefore blocks can not
18682+ be rearranged.
18683+- The use of different starting variables prevents the same plaintext
18684+ enciphering to the same ciphertext.
18685+- An error will affect the current and the following ciphertext blocks.
18686+
18687+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
18688+- a number of bits (j) <= 64 are enciphered at a time.
18689+- The CFB mode produces the same ciphertext whenever the same
18690+ plaintext is encrypted using the same key and starting variable.
18691+- The chaining operation makes the ciphertext variables dependent on the
18692+ current and all preceding variables and therefore j-bit variables are
18693+ chained together and can not be rearranged.
18694+- The use of different starting variables prevents the same plaintext
18695+ enciphering to the same ciphertext.
18696+- The strength of the CFB mode depends on the size of k (maximal if
18697+ j == k). In my implementation this is always the case.
18698+- Selection of a small value for j will require more cycles through
18699+ the encipherment algorithm per unit of plaintext and thus cause
18700+ greater processing overheads.
18701+- Only multiples of j bits can be enciphered.
18702+- An error will affect the current and the following ciphertext variables.
18703+
18704+Output Feedback Mode (OFB) (des_ofb_encrypt())
18705+- a number of bits (j) <= 64 are enciphered at a time.
18706+- The OFB mode produces the same ciphertext whenever the same
18707+ plaintext enciphered using the same key and starting variable. More
18708+ over, in the OFB mode the same key stream is produced when the same
18709+ key and start variable are used. Consequently, for security reasons
18710+ a specific start variable should be used only once for a given key.
18711+- The absence of chaining makes the OFB more vulnerable to specific attacks.
18712+- The use of different start variables values prevents the same
18713+ plaintext enciphering to the same ciphertext, by producing different
18714+ key streams.
18715+- Selection of a small value for j will require more cycles through
18716+ the encipherment algorithm per unit of plaintext and thus cause
18717+ greater processing overheads.
18718+- Only multiples of j bits can be enciphered.
18719+- OFB mode of operation does not extend ciphertext errors in the
18720+ resultant plaintext output. Every bit error in the ciphertext causes
18721+ only one bit to be in error in the deciphered plaintext.
18722+- OFB mode is not self-synchronising. If the two operation of
18723+ encipherment and decipherment get out of synchronism, the system needs
18724+ to be re-initialised.
18725+- Each re-initialisation should use a value of the start variable
18726+ different from the start variable values used before with the same
18727+ key. The reason for this is that an identical bit stream would be
18728+ produced each time from the same parameters. This would be
18729+ susceptible to a ' known plaintext' attack.
18730+
18731+Triple ECB Mode (des_ecb3_encrypt())
18732+- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
18733+- As for ECB encryption but increases the key length to 168 bits.
18734+ There are theoretic attacks that can be used that make the effective
18735+ key length 112 bits, but this attack also requires 2^56 blocks of
18736+ memory, not very likely, even for the NSA.
18737+- If both keys are the same it is equivalent to encrypting once with
18738+ just one key.
18739+- If the first and last key are the same, the key length is 112 bits.
18740+ There are attacks that could reduce the key space to 55 bit's but it
18741+ requires 2^56 blocks of memory.
18742+- If all 3 keys are the same, this is effectively the same as normal
18743+ ecb mode.
18744+
18745+Triple CBC Mode (des_ede3_cbc_encrypt())
18746+- Encrypt with key1, decrypt with key2 and then encrypt with key3.
18747+- As for CBC encryption but increases the key length to 168 bits with
18748+ the same restrictions as for triple ecb mode.
18749--- /dev/null Tue Mar 11 13:02:56 2003
18750+++ linux/net/ipsec/des/des_enc.c Mon Feb 9 13:51:03 2004
18751@@ -0,0 +1,502 @@
18752+/* crypto/des/des_enc.c */
18753+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18754+ * All rights reserved.
18755+ *
18756+ * This package is an SSL implementation written
18757+ * by Eric Young (eay@cryptsoft.com).
18758+ * The implementation was written so as to conform with Netscapes SSL.
18759+ *
18760+ * This library is free for commercial and non-commercial use as long as
18761+ * the following conditions are aheared to. The following conditions
18762+ * apply to all code found in this distribution, be it the RC4, RSA,
18763+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18764+ * included with this distribution is covered by the same copyright terms
18765+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18766+ *
18767+ * Copyright remains Eric Young's, and as such any Copyright notices in
18768+ * the code are not to be removed.
18769+ * If this package is used in a product, Eric Young should be given attribution
18770+ * as the author of the parts of the library used.
18771+ * This can be in the form of a textual message at program startup or
18772+ * in documentation (online or textual) provided with the package.
18773+ *
18774+ * Redistribution and use in source and binary forms, with or without
18775+ * modification, are permitted provided that the following conditions
18776+ * are met:
18777+ * 1. Redistributions of source code must retain the copyright
18778+ * notice, this list of conditions and the following disclaimer.
18779+ * 2. Redistributions in binary form must reproduce the above copyright
18780+ * notice, this list of conditions and the following disclaimer in the
18781+ * documentation and/or other materials provided with the distribution.
18782+ * 3. All advertising materials mentioning features or use of this software
18783+ * must display the following acknowledgement:
18784+ * "This product includes cryptographic software written by
18785+ * Eric Young (eay@cryptsoft.com)"
18786+ * The word 'cryptographic' can be left out if the rouines from the library
18787+ * being used are not cryptographic related :-).
18788+ * 4. If you include any Windows specific code (or a derivative thereof) from
18789+ * the apps directory (application code) you must include an acknowledgement:
18790+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18791+ *
18792+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18793+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18794+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18795+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18796+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18797+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18798+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18799+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18800+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18801+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18802+ * SUCH DAMAGE.
18803+ *
18804+ * The licence and distribution terms for any publically available version or
18805+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18806+ * copied and put under another distribution licence
18807+ * [including the GNU Public Licence.]
18808+ */
18809+
18810+#include "des/des_locl.h"
18811+
18812+void des_encrypt(data, ks, enc)
18813+DES_LONG *data;
18814+des_key_schedule ks;
18815+int enc;
18816+ {
18817+ register DES_LONG l,r,t,u;
18818+#ifdef DES_PTR
18819+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18820+#endif
18821+#ifndef DES_UNROLL
18822+ register int i;
18823+#endif
18824+ register DES_LONG *s;
18825+
18826+ r=data[0];
18827+ l=data[1];
18828+
18829+ IP(r,l);
18830+ /* Things have been modified so that the initial rotate is
18831+ * done outside the loop. This required the
18832+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18833+ * One perl script later and things have a 5% speed up on a sparc2.
18834+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18835+ * for pointing this out. */
18836+ /* clear the top bits on machines with 8byte longs */
18837+ /* shift left by 2 */
18838+ r=ROTATE(r,29)&0xffffffffL;
18839+ l=ROTATE(l,29)&0xffffffffL;
18840+
18841+ s=(DES_LONG *)ks;
18842+ /* I don't know if it is worth the effort of loop unrolling the
18843+ * inner loop */
18844+ if (enc)
18845+ {
18846+#ifdef DES_UNROLL
18847+ D_ENCRYPT(l,r, 0); /* 1 */
18848+ D_ENCRYPT(r,l, 2); /* 2 */
18849+ D_ENCRYPT(l,r, 4); /* 3 */
18850+ D_ENCRYPT(r,l, 6); /* 4 */
18851+ D_ENCRYPT(l,r, 8); /* 5 */
18852+ D_ENCRYPT(r,l,10); /* 6 */
18853+ D_ENCRYPT(l,r,12); /* 7 */
18854+ D_ENCRYPT(r,l,14); /* 8 */
18855+ D_ENCRYPT(l,r,16); /* 9 */
18856+ D_ENCRYPT(r,l,18); /* 10 */
18857+ D_ENCRYPT(l,r,20); /* 11 */
18858+ D_ENCRYPT(r,l,22); /* 12 */
18859+ D_ENCRYPT(l,r,24); /* 13 */
18860+ D_ENCRYPT(r,l,26); /* 14 */
18861+ D_ENCRYPT(l,r,28); /* 15 */
18862+ D_ENCRYPT(r,l,30); /* 16 */
18863+#else
18864+ for (i=0; i<32; i+=8)
18865+ {
18866+ D_ENCRYPT(l,r,i+0); /* 1 */
18867+ D_ENCRYPT(r,l,i+2); /* 2 */
18868+ D_ENCRYPT(l,r,i+4); /* 3 */
18869+ D_ENCRYPT(r,l,i+6); /* 4 */
18870+ }
18871+#endif
18872+ }
18873+ else
18874+ {
18875+#ifdef DES_UNROLL
18876+ D_ENCRYPT(l,r,30); /* 16 */
18877+ D_ENCRYPT(r,l,28); /* 15 */
18878+ D_ENCRYPT(l,r,26); /* 14 */
18879+ D_ENCRYPT(r,l,24); /* 13 */
18880+ D_ENCRYPT(l,r,22); /* 12 */
18881+ D_ENCRYPT(r,l,20); /* 11 */
18882+ D_ENCRYPT(l,r,18); /* 10 */
18883+ D_ENCRYPT(r,l,16); /* 9 */
18884+ D_ENCRYPT(l,r,14); /* 8 */
18885+ D_ENCRYPT(r,l,12); /* 7 */
18886+ D_ENCRYPT(l,r,10); /* 6 */
18887+ D_ENCRYPT(r,l, 8); /* 5 */
18888+ D_ENCRYPT(l,r, 6); /* 4 */
18889+ D_ENCRYPT(r,l, 4); /* 3 */
18890+ D_ENCRYPT(l,r, 2); /* 2 */
18891+ D_ENCRYPT(r,l, 0); /* 1 */
18892+#else
18893+ for (i=30; i>0; i-=8)
18894+ {
18895+ D_ENCRYPT(l,r,i-0); /* 16 */
18896+ D_ENCRYPT(r,l,i-2); /* 15 */
18897+ D_ENCRYPT(l,r,i-4); /* 14 */
18898+ D_ENCRYPT(r,l,i-6); /* 13 */
18899+ }
18900+#endif
18901+ }
18902+
18903+ /* rotate and clear the top bits on machines with 8byte longs */
18904+ l=ROTATE(l,3)&0xffffffffL;
18905+ r=ROTATE(r,3)&0xffffffffL;
18906+
18907+ FP(r,l);
18908+ data[0]=l;
18909+ data[1]=r;
18910+ l=r=t=u=0;
18911+ }
18912+
18913+void des_encrypt2(data, ks, enc)
18914+DES_LONG *data;
18915+des_key_schedule ks;
18916+int enc;
18917+ {
18918+ register DES_LONG l,r,t,u;
18919+#ifdef DES_PTR
18920+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18921+#endif
18922+#ifndef DES_UNROLL
18923+ register int i;
18924+#endif
18925+ register DES_LONG *s;
18926+
18927+ r=data[0];
18928+ l=data[1];
18929+
18930+ /* Things have been modified so that the initial rotate is
18931+ * done outside the loop. This required the
18932+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18933+ * One perl script later and things have a 5% speed up on a sparc2.
18934+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18935+ * for pointing this out. */
18936+ /* clear the top bits on machines with 8byte longs */
18937+ r=ROTATE(r,29)&0xffffffffL;
18938+ l=ROTATE(l,29)&0xffffffffL;
18939+
18940+ s=(DES_LONG *)ks;
18941+ /* I don't know if it is worth the effort of loop unrolling the
18942+ * inner loop */
18943+ if (enc)
18944+ {
18945+#ifdef DES_UNROLL
18946+ D_ENCRYPT(l,r, 0); /* 1 */
18947+ D_ENCRYPT(r,l, 2); /* 2 */
18948+ D_ENCRYPT(l,r, 4); /* 3 */
18949+ D_ENCRYPT(r,l, 6); /* 4 */
18950+ D_ENCRYPT(l,r, 8); /* 5 */
18951+ D_ENCRYPT(r,l,10); /* 6 */
18952+ D_ENCRYPT(l,r,12); /* 7 */
18953+ D_ENCRYPT(r,l,14); /* 8 */
18954+ D_ENCRYPT(l,r,16); /* 9 */
18955+ D_ENCRYPT(r,l,18); /* 10 */
18956+ D_ENCRYPT(l,r,20); /* 11 */
18957+ D_ENCRYPT(r,l,22); /* 12 */
18958+ D_ENCRYPT(l,r,24); /* 13 */
18959+ D_ENCRYPT(r,l,26); /* 14 */
18960+ D_ENCRYPT(l,r,28); /* 15 */
18961+ D_ENCRYPT(r,l,30); /* 16 */
18962+#else
18963+ for (i=0; i<32; i+=8)
18964+ {
18965+ D_ENCRYPT(l,r,i+0); /* 1 */
18966+ D_ENCRYPT(r,l,i+2); /* 2 */
18967+ D_ENCRYPT(l,r,i+4); /* 3 */
18968+ D_ENCRYPT(r,l,i+6); /* 4 */
18969+ }
18970+#endif
18971+ }
18972+ else
18973+ {
18974+#ifdef DES_UNROLL
18975+ D_ENCRYPT(l,r,30); /* 16 */
18976+ D_ENCRYPT(r,l,28); /* 15 */
18977+ D_ENCRYPT(l,r,26); /* 14 */
18978+ D_ENCRYPT(r,l,24); /* 13 */
18979+ D_ENCRYPT(l,r,22); /* 12 */
18980+ D_ENCRYPT(r,l,20); /* 11 */
18981+ D_ENCRYPT(l,r,18); /* 10 */
18982+ D_ENCRYPT(r,l,16); /* 9 */
18983+ D_ENCRYPT(l,r,14); /* 8 */
18984+ D_ENCRYPT(r,l,12); /* 7 */
18985+ D_ENCRYPT(l,r,10); /* 6 */
18986+ D_ENCRYPT(r,l, 8); /* 5 */
18987+ D_ENCRYPT(l,r, 6); /* 4 */
18988+ D_ENCRYPT(r,l, 4); /* 3 */
18989+ D_ENCRYPT(l,r, 2); /* 2 */
18990+ D_ENCRYPT(r,l, 0); /* 1 */
18991+#else
18992+ for (i=30; i>0; i-=8)
18993+ {
18994+ D_ENCRYPT(l,r,i-0); /* 16 */
18995+ D_ENCRYPT(r,l,i-2); /* 15 */
18996+ D_ENCRYPT(l,r,i-4); /* 14 */
18997+ D_ENCRYPT(r,l,i-6); /* 13 */
18998+ }
18999+#endif
19000+ }
19001+ /* rotate and clear the top bits on machines with 8byte longs */
19002+ data[0]=ROTATE(l,3)&0xffffffffL;
19003+ data[1]=ROTATE(r,3)&0xffffffffL;
19004+ l=r=t=u=0;
19005+ }
19006+
19007+void des_encrypt3(data,ks1,ks2,ks3)
19008+DES_LONG *data;
19009+des_key_schedule ks1;
19010+des_key_schedule ks2;
19011+des_key_schedule ks3;
19012+ {
19013+ register DES_LONG l,r;
19014+
19015+ l=data[0];
19016+ r=data[1];
19017+ IP(l,r);
19018+ data[0]=l;
19019+ data[1]=r;
19020+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
19021+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
19022+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
19023+ l=data[0];
19024+ r=data[1];
19025+ FP(r,l);
19026+ data[0]=l;
19027+ data[1]=r;
19028+ }
19029+
19030+void des_decrypt3(data,ks1,ks2,ks3)
19031+DES_LONG *data;
19032+des_key_schedule ks1;
19033+des_key_schedule ks2;
19034+des_key_schedule ks3;
19035+ {
19036+ register DES_LONG l,r;
19037+
19038+ l=data[0];
19039+ r=data[1];
19040+ IP(l,r);
19041+ data[0]=l;
19042+ data[1]=r;
19043+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
19044+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
19045+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
19046+ l=data[0];
19047+ r=data[1];
19048+ FP(r,l);
19049+ data[0]=l;
19050+ data[1]=r;
19051+ }
19052+
19053+#ifndef DES_DEFAULT_OPTIONS
19054+
19055+void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
19056+des_cblock (*input);
19057+des_cblock (*output);
19058+long length;
19059+des_key_schedule schedule;
19060+des_cblock (*ivec);
19061+int enc;
19062+ {
19063+ register DES_LONG tin0,tin1;
19064+ register DES_LONG tout0,tout1,xor0,xor1;
19065+ register unsigned char *in,*out;
19066+ register long l=length;
19067+ DES_LONG tin[2];
19068+ unsigned char *iv;
19069+
19070+ in=(unsigned char *)input;
19071+ out=(unsigned char *)output;
19072+ iv=(unsigned char *)ivec;
19073+
19074+ if (enc)
19075+ {
19076+ c2l(iv,tout0);
19077+ c2l(iv,tout1);
19078+ for (l-=8; l>=0; l-=8)
19079+ {
19080+ c2l(in,tin0);
19081+ c2l(in,tin1);
19082+ tin0^=tout0; tin[0]=tin0;
19083+ tin1^=tout1; tin[1]=tin1;
19084+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
19085+ tout0=tin[0]; l2c(tout0,out);
19086+ tout1=tin[1]; l2c(tout1,out);
19087+ }
19088+ if (l != -8)
19089+ {
19090+ c2ln(in,tin0,tin1,l+8);
19091+ tin0^=tout0; tin[0]=tin0;
19092+ tin1^=tout1; tin[1]=tin1;
19093+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
19094+ tout0=tin[0]; l2c(tout0,out);
19095+ tout1=tin[1]; l2c(tout1,out);
19096+ }
19097+ iv=(unsigned char *)ivec;
19098+ l2c(tout0,iv);
19099+ l2c(tout1,iv);
19100+ }
19101+ else
19102+ {
19103+ c2l(iv,xor0);
19104+ c2l(iv,xor1);
19105+ for (l-=8; l>=0; l-=8)
19106+ {
19107+ c2l(in,tin0); tin[0]=tin0;
19108+ c2l(in,tin1); tin[1]=tin1;
19109+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
19110+ tout0=tin[0]^xor0;
19111+ tout1=tin[1]^xor1;
19112+ l2c(tout0,out);
19113+ l2c(tout1,out);
19114+ xor0=tin0;
19115+ xor1=tin1;
19116+ }
19117+ if (l != -8)
19118+ {
19119+ c2l(in,tin0); tin[0]=tin0;
19120+ c2l(in,tin1); tin[1]=tin1;
19121+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
19122+ tout0=tin[0]^xor0;
19123+ tout1=tin[1]^xor1;
19124+ l2cn(tout0,tout1,out,l+8);
19125+ xor0=tin0;
19126+ xor1=tin1;
19127+ }
19128+
19129+ iv=(unsigned char *)ivec;
19130+ l2c(xor0,iv);
19131+ l2c(xor1,iv);
19132+ }
19133+ tin0=tin1=tout0=tout1=xor0=xor1=0;
19134+ tin[0]=tin[1]=0;
19135+ }
19136+
19137+void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
19138+des_cblock (*input);
19139+des_cblock (*output);
19140+long length;
19141+des_key_schedule ks1;
19142+des_key_schedule ks2;
19143+des_key_schedule ks3;
19144+des_cblock (*ivec);
19145+int enc;
19146+ {
19147+ register DES_LONG tin0,tin1;
19148+ register DES_LONG tout0,tout1,xor0,xor1;
19149+ register unsigned char *in,*out;
19150+ register long l=length;
19151+ DES_LONG tin[2];
19152+ unsigned char *iv;
19153+
19154+ in=(unsigned char *)input;
19155+ out=(unsigned char *)output;
19156+ iv=(unsigned char *)ivec;
19157+
19158+ if (enc)
19159+ {
19160+ c2l(iv,tout0);
19161+ c2l(iv,tout1);
19162+ for (l-=8; l>=0; l-=8)
19163+ {
19164+ c2l(in,tin0);
19165+ c2l(in,tin1);
19166+ tin0^=tout0;
19167+ tin1^=tout1;
19168+
19169+ tin[0]=tin0;
19170+ tin[1]=tin1;
19171+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19172+ tout0=tin[0];
19173+ tout1=tin[1];
19174+
19175+ l2c(tout0,out);
19176+ l2c(tout1,out);
19177+ }
19178+ if (l != -8)
19179+ {
19180+ c2ln(in,tin0,tin1,l+8);
19181+ tin0^=tout0;
19182+ tin1^=tout1;
19183+
19184+ tin[0]=tin0;
19185+ tin[1]=tin1;
19186+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19187+ tout0=tin[0];
19188+ tout1=tin[1];
19189+
19190+ l2c(tout0,out);
19191+ l2c(tout1,out);
19192+ }
19193+ iv=(unsigned char *)ivec;
19194+ l2c(tout0,iv);
19195+ l2c(tout1,iv);
19196+ }
19197+ else
19198+ {
19199+ register DES_LONG t0,t1;
19200+
19201+ c2l(iv,xor0);
19202+ c2l(iv,xor1);
19203+ for (l-=8; l>=0; l-=8)
19204+ {
19205+ c2l(in,tin0);
19206+ c2l(in,tin1);
19207+
19208+ t0=tin0;
19209+ t1=tin1;
19210+
19211+ tin[0]=tin0;
19212+ tin[1]=tin1;
19213+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19214+ tout0=tin[0];
19215+ tout1=tin[1];
19216+
19217+ tout0^=xor0;
19218+ tout1^=xor1;
19219+ l2c(tout0,out);
19220+ l2c(tout1,out);
19221+ xor0=t0;
19222+ xor1=t1;
19223+ }
19224+ if (l != -8)
19225+ {
19226+ c2l(in,tin0);
19227+ c2l(in,tin1);
19228+
19229+ t0=tin0;
19230+ t1=tin1;
19231+
19232+ tin[0]=tin0;
19233+ tin[1]=tin1;
19234+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19235+ tout0=tin[0];
19236+ tout1=tin[1];
19237+
19238+ tout0^=xor0;
19239+ tout1^=xor1;
19240+ l2cn(tout0,tout1,out,l+8);
19241+ xor0=t0;
19242+ xor1=t1;
19243+ }
19244+
19245+ iv=(unsigned char *)ivec;
19246+ l2c(xor0,iv);
19247+ l2c(xor1,iv);
19248+ }
19249+ tin0=tin1=tout0=tout1=xor0=xor1=0;
19250+ tin[0]=tin[1]=0;
19251+ }
19252+
19253+#endif /* DES_DEFAULT_OPTIONS */
19254--- /dev/null Tue Mar 11 13:02:56 2003
19255+++ linux/net/ipsec/des/des_opts.c Mon Feb 9 13:51:03 2004
19256@@ -0,0 +1,620 @@
19257+/* crypto/des/des_opts.c */
19258+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
19259+ * All rights reserved.
19260+ *
19261+ * This package is an SSL implementation written
19262+ * by Eric Young (eay@cryptsoft.com).
19263+ * The implementation was written so as to conform with Netscapes SSL.
19264+ *
19265+ * This library is free for commercial and non-commercial use as long as
19266+ * the following conditions are aheared to. The following conditions
19267+ * apply to all code found in this distribution, be it the RC4, RSA,
19268+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
19269+ * included with this distribution is covered by the same copyright terms
19270+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
19271+ *
19272+ * Copyright remains Eric Young's, and as such any Copyright notices in
19273+ * the code are not to be removed.
19274+ * If this package is used in a product, Eric Young should be given attribution
19275+ * as the author of the parts of the library used.
19276+ * This can be in the form of a textual message at program startup or
19277+ * in documentation (online or textual) provided with the package.
19278+ *
19279+ * Redistribution and use in source and binary forms, with or without
19280+ * modification, are permitted provided that the following conditions
19281+ * are met:
19282+ * 1. Redistributions of source code must retain the copyright
19283+ * notice, this list of conditions and the following disclaimer.
19284+ * 2. Redistributions in binary form must reproduce the above copyright
19285+ * notice, this list of conditions and the following disclaimer in the
19286+ * documentation and/or other materials provided with the distribution.
19287+ * 3. All advertising materials mentioning features or use of this software
19288+ * must display the following acknowledgement:
19289+ * "This product includes cryptographic software written by
19290+ * Eric Young (eay@cryptsoft.com)"
19291+ * The word 'cryptographic' can be left out if the rouines from the library
19292+ * being used are not cryptographic related :-).
19293+ * 4. If you include any Windows specific code (or a derivative thereof) from
19294+ * the apps directory (application code) you must include an acknowledgement:
19295+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
19296+ *
19297+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
19298+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19299+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19300+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19301+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19302+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19303+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19304+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19305+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19306+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
19307+ * SUCH DAMAGE.
19308+ *
19309+ * The licence and distribution terms for any publically available version or
19310+ * derivative of this code cannot be changed. i.e. this code cannot simply be
19311+ * copied and put under another distribution licence
19312+ * [including the GNU Public Licence.]
19313+ */
19314+
19315+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
19316+ * This is for machines with 64k code segment size restrictions. */
19317+
19318+#ifndef MSDOS
19319+#define TIMES
19320+#endif
19321+
19322+#include <stdio.h>
19323+#ifndef MSDOS
19324+#include <unistd.h>
19325+#else
19326+#include <io.h>
19327+extern void exit();
19328+#endif
19329+#include <signal.h>
19330+#ifndef VMS
19331+#ifndef _IRIX
19332+#include <time.h>
19333+#endif
19334+#ifdef TIMES
19335+#include <sys/types.h>
19336+#include <sys/times.h>
19337+#endif
19338+#else /* VMS */
19339+#include <types.h>
19340+struct tms {
19341+ time_t tms_utime;
19342+ time_t tms_stime;
19343+ time_t tms_uchild; /* I dunno... */
19344+ time_t tms_uchildsys; /* so these names are a guess :-) */
19345+ }
19346+#endif
19347+#ifndef TIMES
19348+#include <sys/timeb.h>
19349+#endif
19350+
19351+#ifdef sun
19352+#include <limits.h>
19353+#include <sys/param.h>
19354+#endif
19355+
19356+#include "des/des_locl.h"
19357+#include "des/spr.h"
19358+
19359+#define DES_DEFAULT_OPTIONS
19360+
19361+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
19362+#define PART1
19363+#define PART2
19364+#define PART3
19365+#define PART4
19366+#endif
19367+
19368+#ifdef PART1
19369+
19370+#undef DES_UNROLL
19371+#undef DES_RISC1
19372+#undef DES_RISC2
19373+#undef DES_PTR
19374+#undef D_ENCRYPT
19375+#define des_encrypt des_encrypt_u4_cisc_idx
19376+#define des_encrypt2 des_encrypt2_u4_cisc_idx
19377+#define des_encrypt3 des_encrypt3_u4_cisc_idx
19378+#define des_decrypt3 des_decrypt3_u4_cisc_idx
19379+#undef HEADER_DES_LOCL_H
19380+#include "des_enc.c"
19381+
19382+#define DES_UNROLL
19383+#undef DES_RISC1
19384+#undef DES_RISC2
19385+#undef DES_PTR
19386+#undef D_ENCRYPT
19387+#undef des_encrypt
19388+#undef des_encrypt2
19389+#undef des_encrypt3
19390+#undef des_decrypt3
19391+#define des_encrypt des_encrypt_u16_cisc_idx
19392+#define des_encrypt2 des_encrypt2_u16_cisc_idx
19393+#define des_encrypt3 des_encrypt3_u16_cisc_idx
19394+#define des_decrypt3 des_decrypt3_u16_cisc_idx
19395+#undef HEADER_DES_LOCL_H
19396+#include "des_enc.c"
19397+
19398+#undef DES_UNROLL
19399+#define DES_RISC1
19400+#undef DES_RISC2
19401+#undef DES_PTR
19402+#undef D_ENCRYPT
19403+#undef des_encrypt
19404+#undef des_encrypt2
19405+#undef des_encrypt3
19406+#undef des_decrypt3
19407+#define des_encrypt des_encrypt_u4_risc1_idx
19408+#define des_encrypt2 des_encrypt2_u4_risc1_idx
19409+#define des_encrypt3 des_encrypt3_u4_risc1_idx
19410+#define des_decrypt3 des_decrypt3_u4_risc1_idx
19411+#undef HEADER_DES_LOCL_H
19412+#include "des_enc.c"
19413+
19414+#endif
19415+
19416+#ifdef PART2
19417+
19418+#undef DES_UNROLL
19419+#undef DES_RISC1
19420+#define DES_RISC2
19421+#undef DES_PTR
19422+#undef D_ENCRYPT
19423+#undef des_encrypt
19424+#undef des_encrypt2
19425+#undef des_encrypt3
19426+#undef des_decrypt3
19427+#define des_encrypt des_encrypt_u4_risc2_idx
19428+#define des_encrypt2 des_encrypt2_u4_risc2_idx
19429+#define des_encrypt3 des_encrypt3_u4_risc2_idx
19430+#define des_decrypt3 des_decrypt3_u4_risc2_idx
19431+#undef HEADER_DES_LOCL_H
19432+#include "des_enc.c"
19433+
19434+#define DES_UNROLL
19435+#define DES_RISC1
19436+#undef DES_RISC2
19437+#undef DES_PTR
19438+#undef D_ENCRYPT
19439+#undef des_encrypt
19440+#undef des_encrypt2
19441+#undef des_encrypt3
19442+#undef des_decrypt3
19443+#define des_encrypt des_encrypt_u16_risc1_idx
19444+#define des_encrypt2 des_encrypt2_u16_risc1_idx
19445+#define des_encrypt3 des_encrypt3_u16_risc1_idx
19446+#define des_decrypt3 des_decrypt3_u16_risc1_idx
19447+#undef HEADER_DES_LOCL_H
19448+#include "des_enc.c"
19449+
19450+#define DES_UNROLL
19451+#undef DES_RISC1
19452+#define DES_RISC2
19453+#undef DES_PTR
19454+#undef D_ENCRYPT
19455+#undef des_encrypt
19456+#undef des_encrypt2
19457+#undef des_encrypt3
19458+#undef des_decrypt3
19459+#define des_encrypt des_encrypt_u16_risc2_idx
19460+#define des_encrypt2 des_encrypt2_u16_risc2_idx
19461+#define des_encrypt3 des_encrypt3_u16_risc2_idx
19462+#define des_decrypt3 des_decrypt3_u16_risc2_idx
19463+#undef HEADER_DES_LOCL_H
19464+#include "des_enc.c"
19465+
19466+#endif
19467+
19468+#ifdef PART3
19469+
19470+#undef DES_UNROLL
19471+#undef DES_RISC1
19472+#undef DES_RISC2
19473+#define DES_PTR
19474+#undef D_ENCRYPT
19475+#undef des_encrypt
19476+#undef des_encrypt2
19477+#undef des_encrypt3
19478+#undef des_decrypt3
19479+#define des_encrypt des_encrypt_u4_cisc_ptr
19480+#define des_encrypt2 des_encrypt2_u4_cisc_ptr
19481+#define des_encrypt3 des_encrypt3_u4_cisc_ptr
19482+#define des_decrypt3 des_decrypt3_u4_cisc_ptr
19483+#undef HEADER_DES_LOCL_H
19484+#include "des_enc.c"
19485+
19486+#define DES_UNROLL
19487+#undef DES_RISC1
19488+#undef DES_RISC2
19489+#define DES_PTR
19490+#undef D_ENCRYPT
19491+#undef des_encrypt
19492+#undef des_encrypt2
19493+#undef des_encrypt3
19494+#undef des_decrypt3
19495+#define des_encrypt des_encrypt_u16_cisc_ptr
19496+#define des_encrypt2 des_encrypt2_u16_cisc_ptr
19497+#define des_encrypt3 des_encrypt3_u16_cisc_ptr
19498+#define des_decrypt3 des_decrypt3_u16_cisc_ptr
19499+#undef HEADER_DES_LOCL_H
19500+#include "des_enc.c"
19501+
19502+#undef DES_UNROLL
19503+#define DES_RISC1
19504+#undef DES_RISC2
19505+#define DES_PTR
19506+#undef D_ENCRYPT
19507+#undef des_encrypt
19508+#undef des_encrypt2
19509+#undef des_encrypt3
19510+#undef des_decrypt3
19511+#define des_encrypt des_encrypt_u4_risc1_ptr
19512+#define des_encrypt2 des_encrypt2_u4_risc1_ptr
19513+#define des_encrypt3 des_encrypt3_u4_risc1_ptr
19514+#define des_decrypt3 des_decrypt3_u4_risc1_ptr
19515+#undef HEADER_DES_LOCL_H
19516+#include "des_enc.c"
19517+
19518+#endif
19519+
19520+#ifdef PART4
19521+
19522+#undef DES_UNROLL
19523+#undef DES_RISC1
19524+#define DES_RISC2
19525+#define DES_PTR
19526+#undef D_ENCRYPT
19527+#undef des_encrypt
19528+#undef des_encrypt2
19529+#undef des_encrypt3
19530+#undef des_decrypt3
19531+#define des_encrypt des_encrypt_u4_risc2_ptr
19532+#define des_encrypt2 des_encrypt2_u4_risc2_ptr
19533+#define des_encrypt3 des_encrypt3_u4_risc2_ptr
19534+#define des_decrypt3 des_decrypt3_u4_risc2_ptr
19535+#undef HEADER_DES_LOCL_H
19536+#include "des_enc.c"
19537+
19538+#define DES_UNROLL
19539+#define DES_RISC1
19540+#undef DES_RISC2
19541+#define DES_PTR
19542+#undef D_ENCRYPT
19543+#undef des_encrypt
19544+#undef des_encrypt2
19545+#undef des_encrypt3
19546+#undef des_decrypt3
19547+#define des_encrypt des_encrypt_u16_risc1_ptr
19548+#define des_encrypt2 des_encrypt2_u16_risc1_ptr
19549+#define des_encrypt3 des_encrypt3_u16_risc1_ptr
19550+#define des_decrypt3 des_decrypt3_u16_risc1_ptr
19551+#undef HEADER_DES_LOCL_H
19552+#include "des_enc.c"
19553+
19554+#define DES_UNROLL
19555+#undef DES_RISC1
19556+#define DES_RISC2
19557+#define DES_PTR
19558+#undef D_ENCRYPT
19559+#undef des_encrypt
19560+#undef des_encrypt2
19561+#undef des_encrypt3
19562+#undef des_decrypt3
19563+#define des_encrypt des_encrypt_u16_risc2_ptr
19564+#define des_encrypt2 des_encrypt2_u16_risc2_ptr
19565+#define des_encrypt3 des_encrypt3_u16_risc2_ptr
19566+#define des_decrypt3 des_decrypt3_u16_risc2_ptr
19567+#undef HEADER_DES_LOCL_H
19568+#include "des_enc.c"
19569+
19570+#endif
19571+
19572+/* The following if from times(3) man page. It may need to be changed */
19573+#ifndef HZ
19574+# ifndef CLK_TCK
19575+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
19576+# ifndef VMS
19577+# define HZ 100.0
19578+# else /* VMS */
19579+# define HZ 100.0
19580+# endif
19581+# else /* _BSD_CLK_TCK_ */
19582+# define HZ ((double)_BSD_CLK_TCK_)
19583+# endif
19584+# else /* CLK_TCK */
19585+# define HZ ((double)CLK_TCK)
19586+# endif
19587+#endif
19588+
19589+#define BUFSIZE ((long)1024)
19590+long run=0;
19591+
19592+#ifndef NOPROTO
19593+double Time_F(int s);
19594+#else
19595+double Time_F();
19596+#endif
19597+
19598+#ifdef SIGALRM
19599+#if defined(__STDC__) || defined(sgi)
19600+#define SIGRETTYPE void
19601+#else
19602+#define SIGRETTYPE int
19603+#endif
19604+
19605+#ifndef NOPROTO
19606+SIGRETTYPE sig_done(int sig);
19607+#else
19608+SIGRETTYPE sig_done();
19609+#endif
19610+
19611+SIGRETTYPE sig_done(sig)
19612+int sig;
19613+ {
19614+ signal(SIGALRM,sig_done);
19615+ run=0;
19616+#ifdef LINT
19617+ sig=sig;
19618+#endif
19619+ }
19620+#endif
19621+
19622+#define START 0
19623+#define STOP 1
19624+
19625+double Time_F(s)
19626+int s;
19627+ {
19628+ double ret;
19629+#ifdef TIMES
19630+ static struct tms tstart,tend;
19631+
19632+ if (s == START)
19633+ {
19634+ times(&tstart);
19635+ return(0);
19636+ }
19637+ else
19638+ {
19639+ times(&tend);
19640+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
19641+ return((ret == 0.0)?1e-6:ret);
19642+ }
19643+#else /* !times() */
19644+ static struct timeb tstart,tend;
19645+ long i;
19646+
19647+ if (s == START)
19648+ {
19649+ ftime(&tstart);
19650+ return(0);
19651+ }
19652+ else
19653+ {
19654+ ftime(&tend);
19655+ i=(long)tend.millitm-(long)tstart.millitm;
19656+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
19657+ return((ret == 0.0)?1e-6:ret);
19658+ }
19659+#endif
19660+ }
19661+
19662+#ifdef SIGALRM
19663+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
19664+#else
19665+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
19666+#endif
19667+
19668+#define time_it(func,name,index) \
19669+ print_name(name); \
19670+ Time_F(START); \
19671+ for (count=0,run=1; COND(cb); count++) \
19672+ { \
19673+ unsigned long d[2]; \
19674+ func(d,&(sch[0]),DES_ENCRYPT); \
19675+ } \
19676+ tm[index]=Time_F(STOP); \
19677+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
19678+ tm[index]=((double)COUNT(cb))/tm[index];
19679+
19680+#define print_it(name,index) \
19681+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
19682+ tm[index]*8,1.0e6/tm[index]);
19683+
19684+int main(argc,argv)
19685+int argc;
19686+char **argv;
19687+ {
19688+ long count;
19689+ static unsigned char buf[BUFSIZE];
19690+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
19691+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
19692+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
19693+ des_key_schedule sch,sch2,sch3;
19694+ double d,tm[16],max=0;
19695+ int rank[16];
19696+ char *str[16];
19697+ int max_idx=0,i,num=0,j;
19698+#ifndef SIGALARM
19699+ long ca,cb,cc,cd,ce;
19700+#endif
19701+
19702+ for (i=0; i<12; i++)
19703+ {
19704+ tm[i]=0.0;
19705+ rank[i]=0;
19706+ }
19707+
19708+#ifndef TIMES
19709+ fprintf(stderr,"To get the most acurate results, try to run this\n");
19710+ fprintf(stderr,"program when this computer is idle.\n");
19711+#endif
19712+
19713+ des_set_key((C_Block *)key,sch);
19714+ des_set_key((C_Block *)key2,sch2);
19715+ des_set_key((C_Block *)key3,sch3);
19716+
19717+#ifndef SIGALRM
19718+ fprintf(stderr,"First we calculate the approximate speed ...\n");
19719+ des_set_key((C_Block *)key,sch);
19720+ count=10;
19721+ do {
19722+ long i;
19723+ unsigned long data[2];
19724+
19725+ count*=2;
19726+ Time_F(START);
19727+ for (i=count; i; i--)
19728+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
19729+ d=Time_F(STOP);
19730+ } while (d < 3.0);
19731+ ca=count;
19732+ cb=count*3;
19733+ cc=count*3*8/BUFSIZE+1;
19734+ cd=count*8/BUFSIZE+1;
19735+
19736+ ce=count/20+1;
19737+#define COND(d) (count != (d))
19738+#define COUNT(d) (d)
19739+#else
19740+#define COND(c) (run)
19741+#define COUNT(d) (count)
19742+ signal(SIGALRM,sig_done);
19743+ alarm(10);
19744+#endif
19745+
19746+#ifdef PART1
19747+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
19748+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
19749+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
19750+ num+=3;
19751+#endif
19752+#ifdef PART2
19753+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
19754+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
19755+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
19756+ num+=3;
19757+#endif
19758+#ifdef PART3
19759+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
19760+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
19761+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
19762+ num+=3;
19763+#endif
19764+#ifdef PART4
19765+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
19766+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
19767+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
19768+ num+=3;
19769+#endif
19770+
19771+#ifdef PART1
19772+ str[0]=" 4 c i";
19773+ print_it("des_encrypt_u4_cisc_idx ",0);
19774+ max=tm[0];
19775+ max_idx=0;
19776+ str[1]="16 c i";
19777+ print_it("des_encrypt_u16_cisc_idx ",1);
19778+ if (max < tm[1]) { max=tm[1]; max_idx=1; }
19779+ str[2]=" 4 r1 i";
19780+ print_it("des_encrypt_u4_risc1_idx ",2);
19781+ if (max < tm[2]) { max=tm[2]; max_idx=2; }
19782+#endif
19783+#ifdef PART2
19784+ str[3]="16 r1 i";
19785+ print_it("des_encrypt_u16_risc1_idx",3);
19786+ if (max < tm[3]) { max=tm[3]; max_idx=3; }
19787+ str[4]=" 4 r2 i";
19788+ print_it("des_encrypt_u4_risc2_idx ",4);
19789+ if (max < tm[4]) { max=tm[4]; max_idx=4; }
19790+ str[5]="16 r2 i";
19791+ print_it("des_encrypt_u16_risc2_idx",5);
19792+ if (max < tm[5]) { max=tm[5]; max_idx=5; }
19793+#endif
19794+#ifdef PART3
19795+ str[6]=" 4 c p";
19796+ print_it("des_encrypt_u4_cisc_ptr ",6);
19797+ if (max < tm[6]) { max=tm[6]; max_idx=6; }
19798+ str[7]="16 c p";
19799+ print_it("des_encrypt_u16_cisc_ptr ",7);
19800+ if (max < tm[7]) { max=tm[7]; max_idx=7; }
19801+ str[8]=" 4 r1 p";
19802+ print_it("des_encrypt_u4_risc1_ptr ",8);
19803+ if (max < tm[8]) { max=tm[8]; max_idx=8; }
19804+#endif
19805+#ifdef PART4
19806+ str[9]="16 r1 p";
19807+ print_it("des_encrypt_u16_risc1_ptr",9);
19808+ if (max < tm[9]) { max=tm[9]; max_idx=9; }
19809+ str[10]=" 4 r2 p";
19810+ print_it("des_encrypt_u4_risc2_ptr ",10);
19811+ if (max < tm[10]) { max=tm[10]; max_idx=10; }
19812+ str[11]="16 r2 p";
19813+ print_it("des_encrypt_u16_risc2_ptr",11);
19814+ if (max < tm[11]) { max=tm[11]; max_idx=11; }
19815+#endif
19816+ printf("options des ecb/s\n");
19817+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
19818+ d=tm[max_idx];
19819+ tm[max_idx]= -2.0;
19820+ max= -1.0;
19821+ for (;;)
19822+ {
19823+ for (i=0; i<12; i++)
19824+ {
19825+ if (max < tm[i]) { max=tm[i]; j=i; }
19826+ }
19827+ if (max < 0.0) break;
19828+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
19829+ tm[j]= -2.0;
19830+ max= -1.0;
19831+ }
19832+
19833+ switch (max_idx)
19834+ {
19835+ case 0:
19836+ printf("-DDES_DEFAULT_OPTIONS\n");
19837+ break;
19838+ case 1:
19839+ printf("-DDES_UNROLL\n");
19840+ break;
19841+ case 2:
19842+ printf("-DDES_RISC1\n");
19843+ break;
19844+ case 3:
19845+ printf("-DDES_UNROLL -DDES_RISC1\n");
19846+ break;
19847+ case 4:
19848+ printf("-DDES_RISC2\n");
19849+ break;
19850+ case 5:
19851+ printf("-DDES_UNROLL -DDES_RISC2\n");
19852+ break;
19853+ case 6:
19854+ printf("-DDES_PTR\n");
19855+ break;
19856+ case 7:
19857+ printf("-DDES_UNROLL -DDES_PTR\n");
19858+ break;
19859+ case 8:
19860+ printf("-DDES_RISC1 -DDES_PTR\n");
19861+ break;
19862+ case 9:
19863+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
19864+ break;
19865+ case 10:
19866+ printf("-DDES_RISC2 -DDES_PTR\n");
19867+ break;
19868+ case 11:
19869+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
19870+ break;
19871+ }
19872+ exit(0);
19873+#if defined(LINT) || defined(MSDOS)
19874+ return(0);
19875+#endif
19876+ }
19877--- /dev/null Tue Mar 11 13:02:56 2003
19878+++ linux/net/ipsec/des/dx86unix.S Mon Feb 9 13:51:03 2004
19879@@ -0,0 +1,3160 @@
19880+/*
19881+ * This file was originally generated by Michael Richardson <mcr@freeswan.org>
19882+ * via the perl scripts found in the ASM subdir. It remains copyright of
19883+ * Eric Young, see the file COPYRIGHT.
19884+ *
19885+ * This was last done on October 9, 2002.
19886+ *
19887+ * While this file does not need to go through cpp, we pass it through
19888+ * CPP by naming it dx86unix.S instead of dx86unix.s because there is
19889+ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
19890+ * which may contain stuff that AS doesn't understand instead of
19891+ * referencing EXTRA_AFLAGS.
19892+ */
19893+
19894+ .file "dx86unix.S"
19895+ .version "01.01"
19896+.text
19897+ .align 16
19898+.globl des_encrypt
19899+ .type des_encrypt , @function
19900+des_encrypt:
19901+ pushl %esi
19902+ pushl %edi
19903+
19904+
19905+ movl 12(%esp), %esi
19906+ xorl %ecx, %ecx
19907+ pushl %ebx
19908+ pushl %ebp
19909+ movl (%esi), %eax
19910+ movl 28(%esp), %ebx
19911+ movl 4(%esi), %edi
19912+
19913+
19914+ roll $4, %eax
19915+ movl %eax, %esi
19916+ xorl %edi, %eax
19917+ andl $0xf0f0f0f0, %eax
19918+ xorl %eax, %esi
19919+ xorl %eax, %edi
19920+
19921+ roll $20, %edi
19922+ movl %edi, %eax
19923+ xorl %esi, %edi
19924+ andl $0xfff0000f, %edi
19925+ xorl %edi, %eax
19926+ xorl %edi, %esi
19927+
19928+ roll $14, %eax
19929+ movl %eax, %edi
19930+ xorl %esi, %eax
19931+ andl $0x33333333, %eax
19932+ xorl %eax, %edi
19933+ xorl %eax, %esi
19934+
19935+ roll $22, %esi
19936+ movl %esi, %eax
19937+ xorl %edi, %esi
19938+ andl $0x03fc03fc, %esi
19939+ xorl %esi, %eax
19940+ xorl %esi, %edi
19941+
19942+ roll $9, %eax
19943+ movl %eax, %esi
19944+ xorl %edi, %eax
19945+ andl $0xaaaaaaaa, %eax
19946+ xorl %eax, %esi
19947+ xorl %eax, %edi
19948+
19949+.byte 209
19950+.byte 199
19951+ movl 24(%esp), %ebp
19952+ cmpl $0, %ebx
19953+ je .L000start_decrypt
19954+
19955+
19956+ movl (%ebp), %eax
19957+ xorl %ebx, %ebx
19958+ movl 4(%ebp), %edx
19959+ xorl %esi, %eax
19960+ xorl %esi, %edx
19961+ andl $0xfcfcfcfc, %eax
19962+ andl $0xcfcfcfcf, %edx
19963+ movb %al, %bl
19964+ movb %ah, %cl
19965+ rorl $4, %edx
19966+ movl des_SPtrans(%ebx),%ebp
19967+ movb %dl, %bl
19968+ xorl %ebp, %edi
19969+ movl 0x200+des_SPtrans(%ecx),%ebp
19970+ xorl %ebp, %edi
19971+ movb %dh, %cl
19972+ shrl $16, %eax
19973+ movl 0x100+des_SPtrans(%ebx),%ebp
19974+ xorl %ebp, %edi
19975+ movb %ah, %bl
19976+ shrl $16, %edx
19977+ movl 0x300+des_SPtrans(%ecx),%ebp
19978+ xorl %ebp, %edi
19979+ movl 24(%esp), %ebp
19980+ movb %dh, %cl
19981+ andl $0xff, %eax
19982+ andl $0xff, %edx
19983+ movl 0x600+des_SPtrans(%ebx),%ebx
19984+ xorl %ebx, %edi
19985+ movl 0x700+des_SPtrans(%ecx),%ebx
19986+ xorl %ebx, %edi
19987+ movl 0x400+des_SPtrans(%eax),%ebx
19988+ xorl %ebx, %edi
19989+ movl 0x500+des_SPtrans(%edx),%ebx
19990+ xorl %ebx, %edi
19991+
19992+
19993+ movl 8(%ebp), %eax
19994+ xorl %ebx, %ebx
19995+ movl 12(%ebp), %edx
19996+ xorl %edi, %eax
19997+ xorl %edi, %edx
19998+ andl $0xfcfcfcfc, %eax
19999+ andl $0xcfcfcfcf, %edx
20000+ movb %al, %bl
20001+ movb %ah, %cl
20002+ rorl $4, %edx
20003+ movl des_SPtrans(%ebx),%ebp
20004+ movb %dl, %bl
20005+ xorl %ebp, %esi
20006+ movl 0x200+des_SPtrans(%ecx),%ebp
20007+ xorl %ebp, %esi
20008+ movb %dh, %cl
20009+ shrl $16, %eax
20010+ movl 0x100+des_SPtrans(%ebx),%ebp
20011+ xorl %ebp, %esi
20012+ movb %ah, %bl
20013+ shrl $16, %edx
20014+ movl 0x300+des_SPtrans(%ecx),%ebp
20015+ xorl %ebp, %esi
20016+ movl 24(%esp), %ebp
20017+ movb %dh, %cl
20018+ andl $0xff, %eax
20019+ andl $0xff, %edx
20020+ movl 0x600+des_SPtrans(%ebx),%ebx
20021+ xorl %ebx, %esi
20022+ movl 0x700+des_SPtrans(%ecx),%ebx
20023+ xorl %ebx, %esi
20024+ movl 0x400+des_SPtrans(%eax),%ebx
20025+ xorl %ebx, %esi
20026+ movl 0x500+des_SPtrans(%edx),%ebx
20027+ xorl %ebx, %esi
20028+
20029+
20030+ movl 16(%ebp), %eax
20031+ xorl %ebx, %ebx
20032+ movl 20(%ebp), %edx
20033+ xorl %esi, %eax
20034+ xorl %esi, %edx
20035+ andl $0xfcfcfcfc, %eax
20036+ andl $0xcfcfcfcf, %edx
20037+ movb %al, %bl
20038+ movb %ah, %cl
20039+ rorl $4, %edx
20040+ movl des_SPtrans(%ebx),%ebp
20041+ movb %dl, %bl
20042+ xorl %ebp, %edi
20043+ movl 0x200+des_SPtrans(%ecx),%ebp
20044+ xorl %ebp, %edi
20045+ movb %dh, %cl
20046+ shrl $16, %eax
20047+ movl 0x100+des_SPtrans(%ebx),%ebp
20048+ xorl %ebp, %edi
20049+ movb %ah, %bl
20050+ shrl $16, %edx
20051+ movl 0x300+des_SPtrans(%ecx),%ebp
20052+ xorl %ebp, %edi
20053+ movl 24(%esp), %ebp
20054+ movb %dh, %cl
20055+ andl $0xff, %eax
20056+ andl $0xff, %edx
20057+ movl 0x600+des_SPtrans(%ebx),%ebx
20058+ xorl %ebx, %edi
20059+ movl 0x700+des_SPtrans(%ecx),%ebx
20060+ xorl %ebx, %edi
20061+ movl 0x400+des_SPtrans(%eax),%ebx
20062+ xorl %ebx, %edi
20063+ movl 0x500+des_SPtrans(%edx),%ebx
20064+ xorl %ebx, %edi
20065+
20066+
20067+ movl 24(%ebp), %eax
20068+ xorl %ebx, %ebx
20069+ movl 28(%ebp), %edx
20070+ xorl %edi, %eax
20071+ xorl %edi, %edx
20072+ andl $0xfcfcfcfc, %eax
20073+ andl $0xcfcfcfcf, %edx
20074+ movb %al, %bl
20075+ movb %ah, %cl
20076+ rorl $4, %edx
20077+ movl des_SPtrans(%ebx),%ebp
20078+ movb %dl, %bl
20079+ xorl %ebp, %esi
20080+ movl 0x200+des_SPtrans(%ecx),%ebp
20081+ xorl %ebp, %esi
20082+ movb %dh, %cl
20083+ shrl $16, %eax
20084+ movl 0x100+des_SPtrans(%ebx),%ebp
20085+ xorl %ebp, %esi
20086+ movb %ah, %bl
20087+ shrl $16, %edx
20088+ movl 0x300+des_SPtrans(%ecx),%ebp
20089+ xorl %ebp, %esi
20090+ movl 24(%esp), %ebp
20091+ movb %dh, %cl
20092+ andl $0xff, %eax
20093+ andl $0xff, %edx
20094+ movl 0x600+des_SPtrans(%ebx),%ebx
20095+ xorl %ebx, %esi
20096+ movl 0x700+des_SPtrans(%ecx),%ebx
20097+ xorl %ebx, %esi
20098+ movl 0x400+des_SPtrans(%eax),%ebx
20099+ xorl %ebx, %esi
20100+ movl 0x500+des_SPtrans(%edx),%ebx
20101+ xorl %ebx, %esi
20102+
20103+
20104+ movl 32(%ebp), %eax
20105+ xorl %ebx, %ebx
20106+ movl 36(%ebp), %edx
20107+ xorl %esi, %eax
20108+ xorl %esi, %edx
20109+ andl $0xfcfcfcfc, %eax
20110+ andl $0xcfcfcfcf, %edx
20111+ movb %al, %bl
20112+ movb %ah, %cl
20113+ rorl $4, %edx
20114+ movl des_SPtrans(%ebx),%ebp
20115+ movb %dl, %bl
20116+ xorl %ebp, %edi
20117+ movl 0x200+des_SPtrans(%ecx),%ebp
20118+ xorl %ebp, %edi
20119+ movb %dh, %cl
20120+ shrl $16, %eax
20121+ movl 0x100+des_SPtrans(%ebx),%ebp
20122+ xorl %ebp, %edi
20123+ movb %ah, %bl
20124+ shrl $16, %edx
20125+ movl 0x300+des_SPtrans(%ecx),%ebp
20126+ xorl %ebp, %edi
20127+ movl 24(%esp), %ebp
20128+ movb %dh, %cl
20129+ andl $0xff, %eax
20130+ andl $0xff, %edx
20131+ movl 0x600+des_SPtrans(%ebx),%ebx
20132+ xorl %ebx, %edi
20133+ movl 0x700+des_SPtrans(%ecx),%ebx
20134+ xorl %ebx, %edi
20135+ movl 0x400+des_SPtrans(%eax),%ebx
20136+ xorl %ebx, %edi
20137+ movl 0x500+des_SPtrans(%edx),%ebx
20138+ xorl %ebx, %edi
20139+
20140+
20141+ movl 40(%ebp), %eax
20142+ xorl %ebx, %ebx
20143+ movl 44(%ebp), %edx
20144+ xorl %edi, %eax
20145+ xorl %edi, %edx
20146+ andl $0xfcfcfcfc, %eax
20147+ andl $0xcfcfcfcf, %edx
20148+ movb %al, %bl
20149+ movb %ah, %cl
20150+ rorl $4, %edx
20151+ movl des_SPtrans(%ebx),%ebp
20152+ movb %dl, %bl
20153+ xorl %ebp, %esi
20154+ movl 0x200+des_SPtrans(%ecx),%ebp
20155+ xorl %ebp, %esi
20156+ movb %dh, %cl
20157+ shrl $16, %eax
20158+ movl 0x100+des_SPtrans(%ebx),%ebp
20159+ xorl %ebp, %esi
20160+ movb %ah, %bl
20161+ shrl $16, %edx
20162+ movl 0x300+des_SPtrans(%ecx),%ebp
20163+ xorl %ebp, %esi
20164+ movl 24(%esp), %ebp
20165+ movb %dh, %cl
20166+ andl $0xff, %eax
20167+ andl $0xff, %edx
20168+ movl 0x600+des_SPtrans(%ebx),%ebx
20169+ xorl %ebx, %esi
20170+ movl 0x700+des_SPtrans(%ecx),%ebx
20171+ xorl %ebx, %esi
20172+ movl 0x400+des_SPtrans(%eax),%ebx
20173+ xorl %ebx, %esi
20174+ movl 0x500+des_SPtrans(%edx),%ebx
20175+ xorl %ebx, %esi
20176+
20177+
20178+ movl 48(%ebp), %eax
20179+ xorl %ebx, %ebx
20180+ movl 52(%ebp), %edx
20181+ xorl %esi, %eax
20182+ xorl %esi, %edx
20183+ andl $0xfcfcfcfc, %eax
20184+ andl $0xcfcfcfcf, %edx
20185+ movb %al, %bl
20186+ movb %ah, %cl
20187+ rorl $4, %edx
20188+ movl des_SPtrans(%ebx),%ebp
20189+ movb %dl, %bl
20190+ xorl %ebp, %edi
20191+ movl 0x200+des_SPtrans(%ecx),%ebp
20192+ xorl %ebp, %edi
20193+ movb %dh, %cl
20194+ shrl $16, %eax
20195+ movl 0x100+des_SPtrans(%ebx),%ebp
20196+ xorl %ebp, %edi
20197+ movb %ah, %bl
20198+ shrl $16, %edx
20199+ movl 0x300+des_SPtrans(%ecx),%ebp
20200+ xorl %ebp, %edi
20201+ movl 24(%esp), %ebp
20202+ movb %dh, %cl
20203+ andl $0xff, %eax
20204+ andl $0xff, %edx
20205+ movl 0x600+des_SPtrans(%ebx),%ebx
20206+ xorl %ebx, %edi
20207+ movl 0x700+des_SPtrans(%ecx),%ebx
20208+ xorl %ebx, %edi
20209+ movl 0x400+des_SPtrans(%eax),%ebx
20210+ xorl %ebx, %edi
20211+ movl 0x500+des_SPtrans(%edx),%ebx
20212+ xorl %ebx, %edi
20213+
20214+
20215+ movl 56(%ebp), %eax
20216+ xorl %ebx, %ebx
20217+ movl 60(%ebp), %edx
20218+ xorl %edi, %eax
20219+ xorl %edi, %edx
20220+ andl $0xfcfcfcfc, %eax
20221+ andl $0xcfcfcfcf, %edx
20222+ movb %al, %bl
20223+ movb %ah, %cl
20224+ rorl $4, %edx
20225+ movl des_SPtrans(%ebx),%ebp
20226+ movb %dl, %bl
20227+ xorl %ebp, %esi
20228+ movl 0x200+des_SPtrans(%ecx),%ebp
20229+ xorl %ebp, %esi
20230+ movb %dh, %cl
20231+ shrl $16, %eax
20232+ movl 0x100+des_SPtrans(%ebx),%ebp
20233+ xorl %ebp, %esi
20234+ movb %ah, %bl
20235+ shrl $16, %edx
20236+ movl 0x300+des_SPtrans(%ecx),%ebp
20237+ xorl %ebp, %esi
20238+ movl 24(%esp), %ebp
20239+ movb %dh, %cl
20240+ andl $0xff, %eax
20241+ andl $0xff, %edx
20242+ movl 0x600+des_SPtrans(%ebx),%ebx
20243+ xorl %ebx, %esi
20244+ movl 0x700+des_SPtrans(%ecx),%ebx
20245+ xorl %ebx, %esi
20246+ movl 0x400+des_SPtrans(%eax),%ebx
20247+ xorl %ebx, %esi
20248+ movl 0x500+des_SPtrans(%edx),%ebx
20249+ xorl %ebx, %esi
20250+
20251+
20252+ movl 64(%ebp), %eax
20253+ xorl %ebx, %ebx
20254+ movl 68(%ebp), %edx
20255+ xorl %esi, %eax
20256+ xorl %esi, %edx
20257+ andl $0xfcfcfcfc, %eax
20258+ andl $0xcfcfcfcf, %edx
20259+ movb %al, %bl
20260+ movb %ah, %cl
20261+ rorl $4, %edx
20262+ movl des_SPtrans(%ebx),%ebp
20263+ movb %dl, %bl
20264+ xorl %ebp, %edi
20265+ movl 0x200+des_SPtrans(%ecx),%ebp
20266+ xorl %ebp, %edi
20267+ movb %dh, %cl
20268+ shrl $16, %eax
20269+ movl 0x100+des_SPtrans(%ebx),%ebp
20270+ xorl %ebp, %edi
20271+ movb %ah, %bl
20272+ shrl $16, %edx
20273+ movl 0x300+des_SPtrans(%ecx),%ebp
20274+ xorl %ebp, %edi
20275+ movl 24(%esp), %ebp
20276+ movb %dh, %cl
20277+ andl $0xff, %eax
20278+ andl $0xff, %edx
20279+ movl 0x600+des_SPtrans(%ebx),%ebx
20280+ xorl %ebx, %edi
20281+ movl 0x700+des_SPtrans(%ecx),%ebx
20282+ xorl %ebx, %edi
20283+ movl 0x400+des_SPtrans(%eax),%ebx
20284+ xorl %ebx, %edi
20285+ movl 0x500+des_SPtrans(%edx),%ebx
20286+ xorl %ebx, %edi
20287+
20288+
20289+ movl 72(%ebp), %eax
20290+ xorl %ebx, %ebx
20291+ movl 76(%ebp), %edx
20292+ xorl %edi, %eax
20293+ xorl %edi, %edx
20294+ andl $0xfcfcfcfc, %eax
20295+ andl $0xcfcfcfcf, %edx
20296+ movb %al, %bl
20297+ movb %ah, %cl
20298+ rorl $4, %edx
20299+ movl des_SPtrans(%ebx),%ebp
20300+ movb %dl, %bl
20301+ xorl %ebp, %esi
20302+ movl 0x200+des_SPtrans(%ecx),%ebp
20303+ xorl %ebp, %esi
20304+ movb %dh, %cl
20305+ shrl $16, %eax
20306+ movl 0x100+des_SPtrans(%ebx),%ebp
20307+ xorl %ebp, %esi
20308+ movb %ah, %bl
20309+ shrl $16, %edx
20310+ movl 0x300+des_SPtrans(%ecx),%ebp
20311+ xorl %ebp, %esi
20312+ movl 24(%esp), %ebp
20313+ movb %dh, %cl
20314+ andl $0xff, %eax
20315+ andl $0xff, %edx
20316+ movl 0x600+des_SPtrans(%ebx),%ebx
20317+ xorl %ebx, %esi
20318+ movl 0x700+des_SPtrans(%ecx),%ebx
20319+ xorl %ebx, %esi
20320+ movl 0x400+des_SPtrans(%eax),%ebx
20321+ xorl %ebx, %esi
20322+ movl 0x500+des_SPtrans(%edx),%ebx
20323+ xorl %ebx, %esi
20324+
20325+
20326+ movl 80(%ebp), %eax
20327+ xorl %ebx, %ebx
20328+ movl 84(%ebp), %edx
20329+ xorl %esi, %eax
20330+ xorl %esi, %edx
20331+ andl $0xfcfcfcfc, %eax
20332+ andl $0xcfcfcfcf, %edx
20333+ movb %al, %bl
20334+ movb %ah, %cl
20335+ rorl $4, %edx
20336+ movl des_SPtrans(%ebx),%ebp
20337+ movb %dl, %bl
20338+ xorl %ebp, %edi
20339+ movl 0x200+des_SPtrans(%ecx),%ebp
20340+ xorl %ebp, %edi
20341+ movb %dh, %cl
20342+ shrl $16, %eax
20343+ movl 0x100+des_SPtrans(%ebx),%ebp
20344+ xorl %ebp, %edi
20345+ movb %ah, %bl
20346+ shrl $16, %edx
20347+ movl 0x300+des_SPtrans(%ecx),%ebp
20348+ xorl %ebp, %edi
20349+ movl 24(%esp), %ebp
20350+ movb %dh, %cl
20351+ andl $0xff, %eax
20352+ andl $0xff, %edx
20353+ movl 0x600+des_SPtrans(%ebx),%ebx
20354+ xorl %ebx, %edi
20355+ movl 0x700+des_SPtrans(%ecx),%ebx
20356+ xorl %ebx, %edi
20357+ movl 0x400+des_SPtrans(%eax),%ebx
20358+ xorl %ebx, %edi
20359+ movl 0x500+des_SPtrans(%edx),%ebx
20360+ xorl %ebx, %edi
20361+
20362+
20363+ movl 88(%ebp), %eax
20364+ xorl %ebx, %ebx
20365+ movl 92(%ebp), %edx
20366+ xorl %edi, %eax
20367+ xorl %edi, %edx
20368+ andl $0xfcfcfcfc, %eax
20369+ andl $0xcfcfcfcf, %edx
20370+ movb %al, %bl
20371+ movb %ah, %cl
20372+ rorl $4, %edx
20373+ movl des_SPtrans(%ebx),%ebp
20374+ movb %dl, %bl
20375+ xorl %ebp, %esi
20376+ movl 0x200+des_SPtrans(%ecx),%ebp
20377+ xorl %ebp, %esi
20378+ movb %dh, %cl
20379+ shrl $16, %eax
20380+ movl 0x100+des_SPtrans(%ebx),%ebp
20381+ xorl %ebp, %esi
20382+ movb %ah, %bl
20383+ shrl $16, %edx
20384+ movl 0x300+des_SPtrans(%ecx),%ebp
20385+ xorl %ebp, %esi
20386+ movl 24(%esp), %ebp
20387+ movb %dh, %cl
20388+ andl $0xff, %eax
20389+ andl $0xff, %edx
20390+ movl 0x600+des_SPtrans(%ebx),%ebx
20391+ xorl %ebx, %esi
20392+ movl 0x700+des_SPtrans(%ecx),%ebx
20393+ xorl %ebx, %esi
20394+ movl 0x400+des_SPtrans(%eax),%ebx
20395+ xorl %ebx, %esi
20396+ movl 0x500+des_SPtrans(%edx),%ebx
20397+ xorl %ebx, %esi
20398+
20399+
20400+ movl 96(%ebp), %eax
20401+ xorl %ebx, %ebx
20402+ movl 100(%ebp), %edx
20403+ xorl %esi, %eax
20404+ xorl %esi, %edx
20405+ andl $0xfcfcfcfc, %eax
20406+ andl $0xcfcfcfcf, %edx
20407+ movb %al, %bl
20408+ movb %ah, %cl
20409+ rorl $4, %edx
20410+ movl des_SPtrans(%ebx),%ebp
20411+ movb %dl, %bl
20412+ xorl %ebp, %edi
20413+ movl 0x200+des_SPtrans(%ecx),%ebp
20414+ xorl %ebp, %edi
20415+ movb %dh, %cl
20416+ shrl $16, %eax
20417+ movl 0x100+des_SPtrans(%ebx),%ebp
20418+ xorl %ebp, %edi
20419+ movb %ah, %bl
20420+ shrl $16, %edx
20421+ movl 0x300+des_SPtrans(%ecx),%ebp
20422+ xorl %ebp, %edi
20423+ movl 24(%esp), %ebp
20424+ movb %dh, %cl
20425+ andl $0xff, %eax
20426+ andl $0xff, %edx
20427+ movl 0x600+des_SPtrans(%ebx),%ebx
20428+ xorl %ebx, %edi
20429+ movl 0x700+des_SPtrans(%ecx),%ebx
20430+ xorl %ebx, %edi
20431+ movl 0x400+des_SPtrans(%eax),%ebx
20432+ xorl %ebx, %edi
20433+ movl 0x500+des_SPtrans(%edx),%ebx
20434+ xorl %ebx, %edi
20435+
20436+
20437+ movl 104(%ebp), %eax
20438+ xorl %ebx, %ebx
20439+ movl 108(%ebp), %edx
20440+ xorl %edi, %eax
20441+ xorl %edi, %edx
20442+ andl $0xfcfcfcfc, %eax
20443+ andl $0xcfcfcfcf, %edx
20444+ movb %al, %bl
20445+ movb %ah, %cl
20446+ rorl $4, %edx
20447+ movl des_SPtrans(%ebx),%ebp
20448+ movb %dl, %bl
20449+ xorl %ebp, %esi
20450+ movl 0x200+des_SPtrans(%ecx),%ebp
20451+ xorl %ebp, %esi
20452+ movb %dh, %cl
20453+ shrl $16, %eax
20454+ movl 0x100+des_SPtrans(%ebx),%ebp
20455+ xorl %ebp, %esi
20456+ movb %ah, %bl
20457+ shrl $16, %edx
20458+ movl 0x300+des_SPtrans(%ecx),%ebp
20459+ xorl %ebp, %esi
20460+ movl 24(%esp), %ebp
20461+ movb %dh, %cl
20462+ andl $0xff, %eax
20463+ andl $0xff, %edx
20464+ movl 0x600+des_SPtrans(%ebx),%ebx
20465+ xorl %ebx, %esi
20466+ movl 0x700+des_SPtrans(%ecx),%ebx
20467+ xorl %ebx, %esi
20468+ movl 0x400+des_SPtrans(%eax),%ebx
20469+ xorl %ebx, %esi
20470+ movl 0x500+des_SPtrans(%edx),%ebx
20471+ xorl %ebx, %esi
20472+
20473+
20474+ movl 112(%ebp), %eax
20475+ xorl %ebx, %ebx
20476+ movl 116(%ebp), %edx
20477+ xorl %esi, %eax
20478+ xorl %esi, %edx
20479+ andl $0xfcfcfcfc, %eax
20480+ andl $0xcfcfcfcf, %edx
20481+ movb %al, %bl
20482+ movb %ah, %cl
20483+ rorl $4, %edx
20484+ movl des_SPtrans(%ebx),%ebp
20485+ movb %dl, %bl
20486+ xorl %ebp, %edi
20487+ movl 0x200+des_SPtrans(%ecx),%ebp
20488+ xorl %ebp, %edi
20489+ movb %dh, %cl
20490+ shrl $16, %eax
20491+ movl 0x100+des_SPtrans(%ebx),%ebp
20492+ xorl %ebp, %edi
20493+ movb %ah, %bl
20494+ shrl $16, %edx
20495+ movl 0x300+des_SPtrans(%ecx),%ebp
20496+ xorl %ebp, %edi
20497+ movl 24(%esp), %ebp
20498+ movb %dh, %cl
20499+ andl $0xff, %eax
20500+ andl $0xff, %edx
20501+ movl 0x600+des_SPtrans(%ebx),%ebx
20502+ xorl %ebx, %edi
20503+ movl 0x700+des_SPtrans(%ecx),%ebx
20504+ xorl %ebx, %edi
20505+ movl 0x400+des_SPtrans(%eax),%ebx
20506+ xorl %ebx, %edi
20507+ movl 0x500+des_SPtrans(%edx),%ebx
20508+ xorl %ebx, %edi
20509+
20510+
20511+ movl 120(%ebp), %eax
20512+ xorl %ebx, %ebx
20513+ movl 124(%ebp), %edx
20514+ xorl %edi, %eax
20515+ xorl %edi, %edx
20516+ andl $0xfcfcfcfc, %eax
20517+ andl $0xcfcfcfcf, %edx
20518+ movb %al, %bl
20519+ movb %ah, %cl
20520+ rorl $4, %edx
20521+ movl des_SPtrans(%ebx),%ebp
20522+ movb %dl, %bl
20523+ xorl %ebp, %esi
20524+ movl 0x200+des_SPtrans(%ecx),%ebp
20525+ xorl %ebp, %esi
20526+ movb %dh, %cl
20527+ shrl $16, %eax
20528+ movl 0x100+des_SPtrans(%ebx),%ebp
20529+ xorl %ebp, %esi
20530+ movb %ah, %bl
20531+ shrl $16, %edx
20532+ movl 0x300+des_SPtrans(%ecx),%ebp
20533+ xorl %ebp, %esi
20534+ movl 24(%esp), %ebp
20535+ movb %dh, %cl
20536+ andl $0xff, %eax
20537+ andl $0xff, %edx
20538+ movl 0x600+des_SPtrans(%ebx),%ebx
20539+ xorl %ebx, %esi
20540+ movl 0x700+des_SPtrans(%ecx),%ebx
20541+ xorl %ebx, %esi
20542+ movl 0x400+des_SPtrans(%eax),%ebx
20543+ xorl %ebx, %esi
20544+ movl 0x500+des_SPtrans(%edx),%ebx
20545+ xorl %ebx, %esi
20546+ jmp .L001end
20547+.L000start_decrypt:
20548+
20549+
20550+ movl 120(%ebp), %eax
20551+ xorl %ebx, %ebx
20552+ movl 124(%ebp), %edx
20553+ xorl %esi, %eax
20554+ xorl %esi, %edx
20555+ andl $0xfcfcfcfc, %eax
20556+ andl $0xcfcfcfcf, %edx
20557+ movb %al, %bl
20558+ movb %ah, %cl
20559+ rorl $4, %edx
20560+ movl des_SPtrans(%ebx),%ebp
20561+ movb %dl, %bl
20562+ xorl %ebp, %edi
20563+ movl 0x200+des_SPtrans(%ecx),%ebp
20564+ xorl %ebp, %edi
20565+ movb %dh, %cl
20566+ shrl $16, %eax
20567+ movl 0x100+des_SPtrans(%ebx),%ebp
20568+ xorl %ebp, %edi
20569+ movb %ah, %bl
20570+ shrl $16, %edx
20571+ movl 0x300+des_SPtrans(%ecx),%ebp
20572+ xorl %ebp, %edi
20573+ movl 24(%esp), %ebp
20574+ movb %dh, %cl
20575+ andl $0xff, %eax
20576+ andl $0xff, %edx
20577+ movl 0x600+des_SPtrans(%ebx),%ebx
20578+ xorl %ebx, %edi
20579+ movl 0x700+des_SPtrans(%ecx),%ebx
20580+ xorl %ebx, %edi
20581+ movl 0x400+des_SPtrans(%eax),%ebx
20582+ xorl %ebx, %edi
20583+ movl 0x500+des_SPtrans(%edx),%ebx
20584+ xorl %ebx, %edi
20585+
20586+
20587+ movl 112(%ebp), %eax
20588+ xorl %ebx, %ebx
20589+ movl 116(%ebp), %edx
20590+ xorl %edi, %eax
20591+ xorl %edi, %edx
20592+ andl $0xfcfcfcfc, %eax
20593+ andl $0xcfcfcfcf, %edx
20594+ movb %al, %bl
20595+ movb %ah, %cl
20596+ rorl $4, %edx
20597+ movl des_SPtrans(%ebx),%ebp
20598+ movb %dl, %bl
20599+ xorl %ebp, %esi
20600+ movl 0x200+des_SPtrans(%ecx),%ebp
20601+ xorl %ebp, %esi
20602+ movb %dh, %cl
20603+ shrl $16, %eax
20604+ movl 0x100+des_SPtrans(%ebx),%ebp
20605+ xorl %ebp, %esi
20606+ movb %ah, %bl
20607+ shrl $16, %edx
20608+ movl 0x300+des_SPtrans(%ecx),%ebp
20609+ xorl %ebp, %esi
20610+ movl 24(%esp), %ebp
20611+ movb %dh, %cl
20612+ andl $0xff, %eax
20613+ andl $0xff, %edx
20614+ movl 0x600+des_SPtrans(%ebx),%ebx
20615+ xorl %ebx, %esi
20616+ movl 0x700+des_SPtrans(%ecx),%ebx
20617+ xorl %ebx, %esi
20618+ movl 0x400+des_SPtrans(%eax),%ebx
20619+ xorl %ebx, %esi
20620+ movl 0x500+des_SPtrans(%edx),%ebx
20621+ xorl %ebx, %esi
20622+
20623+
20624+ movl 104(%ebp), %eax
20625+ xorl %ebx, %ebx
20626+ movl 108(%ebp), %edx
20627+ xorl %esi, %eax
20628+ xorl %esi, %edx
20629+ andl $0xfcfcfcfc, %eax
20630+ andl $0xcfcfcfcf, %edx
20631+ movb %al, %bl
20632+ movb %ah, %cl
20633+ rorl $4, %edx
20634+ movl des_SPtrans(%ebx),%ebp
20635+ movb %dl, %bl
20636+ xorl %ebp, %edi
20637+ movl 0x200+des_SPtrans(%ecx),%ebp
20638+ xorl %ebp, %edi
20639+ movb %dh, %cl
20640+ shrl $16, %eax
20641+ movl 0x100+des_SPtrans(%ebx),%ebp
20642+ xorl %ebp, %edi
20643+ movb %ah, %bl
20644+ shrl $16, %edx
20645+ movl 0x300+des_SPtrans(%ecx),%ebp
20646+ xorl %ebp, %edi
20647+ movl 24(%esp), %ebp
20648+ movb %dh, %cl
20649+ andl $0xff, %eax
20650+ andl $0xff, %edx
20651+ movl 0x600+des_SPtrans(%ebx),%ebx
20652+ xorl %ebx, %edi
20653+ movl 0x700+des_SPtrans(%ecx),%ebx
20654+ xorl %ebx, %edi
20655+ movl 0x400+des_SPtrans(%eax),%ebx
20656+ xorl %ebx, %edi
20657+ movl 0x500+des_SPtrans(%edx),%ebx
20658+ xorl %ebx, %edi
20659+
20660+
20661+ movl 96(%ebp), %eax
20662+ xorl %ebx, %ebx
20663+ movl 100(%ebp), %edx
20664+ xorl %edi, %eax
20665+ xorl %edi, %edx
20666+ andl $0xfcfcfcfc, %eax
20667+ andl $0xcfcfcfcf, %edx
20668+ movb %al, %bl
20669+ movb %ah, %cl
20670+ rorl $4, %edx
20671+ movl des_SPtrans(%ebx),%ebp
20672+ movb %dl, %bl
20673+ xorl %ebp, %esi
20674+ movl 0x200+des_SPtrans(%ecx),%ebp
20675+ xorl %ebp, %esi
20676+ movb %dh, %cl
20677+ shrl $16, %eax
20678+ movl 0x100+des_SPtrans(%ebx),%ebp
20679+ xorl %ebp, %esi
20680+ movb %ah, %bl
20681+ shrl $16, %edx
20682+ movl 0x300+des_SPtrans(%ecx),%ebp
20683+ xorl %ebp, %esi
20684+ movl 24(%esp), %ebp
20685+ movb %dh, %cl
20686+ andl $0xff, %eax
20687+ andl $0xff, %edx
20688+ movl 0x600+des_SPtrans(%ebx),%ebx
20689+ xorl %ebx, %esi
20690+ movl 0x700+des_SPtrans(%ecx),%ebx
20691+ xorl %ebx, %esi
20692+ movl 0x400+des_SPtrans(%eax),%ebx
20693+ xorl %ebx, %esi
20694+ movl 0x500+des_SPtrans(%edx),%ebx
20695+ xorl %ebx, %esi
20696+
20697+
20698+ movl 88(%ebp), %eax
20699+ xorl %ebx, %ebx
20700+ movl 92(%ebp), %edx
20701+ xorl %esi, %eax
20702+ xorl %esi, %edx
20703+ andl $0xfcfcfcfc, %eax
20704+ andl $0xcfcfcfcf, %edx
20705+ movb %al, %bl
20706+ movb %ah, %cl
20707+ rorl $4, %edx
20708+ movl des_SPtrans(%ebx),%ebp
20709+ movb %dl, %bl
20710+ xorl %ebp, %edi
20711+ movl 0x200+des_SPtrans(%ecx),%ebp
20712+ xorl %ebp, %edi
20713+ movb %dh, %cl
20714+ shrl $16, %eax
20715+ movl 0x100+des_SPtrans(%ebx),%ebp
20716+ xorl %ebp, %edi
20717+ movb %ah, %bl
20718+ shrl $16, %edx
20719+ movl 0x300+des_SPtrans(%ecx),%ebp
20720+ xorl %ebp, %edi
20721+ movl 24(%esp), %ebp
20722+ movb %dh, %cl
20723+ andl $0xff, %eax
20724+ andl $0xff, %edx
20725+ movl 0x600+des_SPtrans(%ebx),%ebx
20726+ xorl %ebx, %edi
20727+ movl 0x700+des_SPtrans(%ecx),%ebx
20728+ xorl %ebx, %edi
20729+ movl 0x400+des_SPtrans(%eax),%ebx
20730+ xorl %ebx, %edi
20731+ movl 0x500+des_SPtrans(%edx),%ebx
20732+ xorl %ebx, %edi
20733+
20734+
20735+ movl 80(%ebp), %eax
20736+ xorl %ebx, %ebx
20737+ movl 84(%ebp), %edx
20738+ xorl %edi, %eax
20739+ xorl %edi, %edx
20740+ andl $0xfcfcfcfc, %eax
20741+ andl $0xcfcfcfcf, %edx
20742+ movb %al, %bl
20743+ movb %ah, %cl
20744+ rorl $4, %edx
20745+ movl des_SPtrans(%ebx),%ebp
20746+ movb %dl, %bl
20747+ xorl %ebp, %esi
20748+ movl 0x200+des_SPtrans(%ecx),%ebp
20749+ xorl %ebp, %esi
20750+ movb %dh, %cl
20751+ shrl $16, %eax
20752+ movl 0x100+des_SPtrans(%ebx),%ebp
20753+ xorl %ebp, %esi
20754+ movb %ah, %bl
20755+ shrl $16, %edx
20756+ movl 0x300+des_SPtrans(%ecx),%ebp
20757+ xorl %ebp, %esi
20758+ movl 24(%esp), %ebp
20759+ movb %dh, %cl
20760+ andl $0xff, %eax
20761+ andl $0xff, %edx
20762+ movl 0x600+des_SPtrans(%ebx),%ebx
20763+ xorl %ebx, %esi
20764+ movl 0x700+des_SPtrans(%ecx),%ebx
20765+ xorl %ebx, %esi
20766+ movl 0x400+des_SPtrans(%eax),%ebx
20767+ xorl %ebx, %esi
20768+ movl 0x500+des_SPtrans(%edx),%ebx
20769+ xorl %ebx, %esi
20770+
20771+
20772+ movl 72(%ebp), %eax
20773+ xorl %ebx, %ebx
20774+ movl 76(%ebp), %edx
20775+ xorl %esi, %eax
20776+ xorl %esi, %edx
20777+ andl $0xfcfcfcfc, %eax
20778+ andl $0xcfcfcfcf, %edx
20779+ movb %al, %bl
20780+ movb %ah, %cl
20781+ rorl $4, %edx
20782+ movl des_SPtrans(%ebx),%ebp
20783+ movb %dl, %bl
20784+ xorl %ebp, %edi
20785+ movl 0x200+des_SPtrans(%ecx),%ebp
20786+ xorl %ebp, %edi
20787+ movb %dh, %cl
20788+ shrl $16, %eax
20789+ movl 0x100+des_SPtrans(%ebx),%ebp
20790+ xorl %ebp, %edi
20791+ movb %ah, %bl
20792+ shrl $16, %edx
20793+ movl 0x300+des_SPtrans(%ecx),%ebp
20794+ xorl %ebp, %edi
20795+ movl 24(%esp), %ebp
20796+ movb %dh, %cl
20797+ andl $0xff, %eax
20798+ andl $0xff, %edx
20799+ movl 0x600+des_SPtrans(%ebx),%ebx
20800+ xorl %ebx, %edi
20801+ movl 0x700+des_SPtrans(%ecx),%ebx
20802+ xorl %ebx, %edi
20803+ movl 0x400+des_SPtrans(%eax),%ebx
20804+ xorl %ebx, %edi
20805+ movl 0x500+des_SPtrans(%edx),%ebx
20806+ xorl %ebx, %edi
20807+
20808+
20809+ movl 64(%ebp), %eax
20810+ xorl %ebx, %ebx
20811+ movl 68(%ebp), %edx
20812+ xorl %edi, %eax
20813+ xorl %edi, %edx
20814+ andl $0xfcfcfcfc, %eax
20815+ andl $0xcfcfcfcf, %edx
20816+ movb %al, %bl
20817+ movb %ah, %cl
20818+ rorl $4, %edx
20819+ movl des_SPtrans(%ebx),%ebp
20820+ movb %dl, %bl
20821+ xorl %ebp, %esi
20822+ movl 0x200+des_SPtrans(%ecx),%ebp
20823+ xorl %ebp, %esi
20824+ movb %dh, %cl
20825+ shrl $16, %eax
20826+ movl 0x100+des_SPtrans(%ebx),%ebp
20827+ xorl %ebp, %esi
20828+ movb %ah, %bl
20829+ shrl $16, %edx
20830+ movl 0x300+des_SPtrans(%ecx),%ebp
20831+ xorl %ebp, %esi
20832+ movl 24(%esp), %ebp
20833+ movb %dh, %cl
20834+ andl $0xff, %eax
20835+ andl $0xff, %edx
20836+ movl 0x600+des_SPtrans(%ebx),%ebx
20837+ xorl %ebx, %esi
20838+ movl 0x700+des_SPtrans(%ecx),%ebx
20839+ xorl %ebx, %esi
20840+ movl 0x400+des_SPtrans(%eax),%ebx
20841+ xorl %ebx, %esi
20842+ movl 0x500+des_SPtrans(%edx),%ebx
20843+ xorl %ebx, %esi
20844+
20845+
20846+ movl 56(%ebp), %eax
20847+ xorl %ebx, %ebx
20848+ movl 60(%ebp), %edx
20849+ xorl %esi, %eax
20850+ xorl %esi, %edx
20851+ andl $0xfcfcfcfc, %eax
20852+ andl $0xcfcfcfcf, %edx
20853+ movb %al, %bl
20854+ movb %ah, %cl
20855+ rorl $4, %edx
20856+ movl des_SPtrans(%ebx),%ebp
20857+ movb %dl, %bl
20858+ xorl %ebp, %edi
20859+ movl 0x200+des_SPtrans(%ecx),%ebp
20860+ xorl %ebp, %edi
20861+ movb %dh, %cl
20862+ shrl $16, %eax
20863+ movl 0x100+des_SPtrans(%ebx),%ebp
20864+ xorl %ebp, %edi
20865+ movb %ah, %bl
20866+ shrl $16, %edx
20867+ movl 0x300+des_SPtrans(%ecx),%ebp
20868+ xorl %ebp, %edi
20869+ movl 24(%esp), %ebp
20870+ movb %dh, %cl
20871+ andl $0xff, %eax
20872+ andl $0xff, %edx
20873+ movl 0x600+des_SPtrans(%ebx),%ebx
20874+ xorl %ebx, %edi
20875+ movl 0x700+des_SPtrans(%ecx),%ebx
20876+ xorl %ebx, %edi
20877+ movl 0x400+des_SPtrans(%eax),%ebx
20878+ xorl %ebx, %edi
20879+ movl 0x500+des_SPtrans(%edx),%ebx
20880+ xorl %ebx, %edi
20881+
20882+
20883+ movl 48(%ebp), %eax
20884+ xorl %ebx, %ebx
20885+ movl 52(%ebp), %edx
20886+ xorl %edi, %eax
20887+ xorl %edi, %edx
20888+ andl $0xfcfcfcfc, %eax
20889+ andl $0xcfcfcfcf, %edx
20890+ movb %al, %bl
20891+ movb %ah, %cl
20892+ rorl $4, %edx
20893+ movl des_SPtrans(%ebx),%ebp
20894+ movb %dl, %bl
20895+ xorl %ebp, %esi
20896+ movl 0x200+des_SPtrans(%ecx),%ebp
20897+ xorl %ebp, %esi
20898+ movb %dh, %cl
20899+ shrl $16, %eax
20900+ movl 0x100+des_SPtrans(%ebx),%ebp
20901+ xorl %ebp, %esi
20902+ movb %ah, %bl
20903+ shrl $16, %edx
20904+ movl 0x300+des_SPtrans(%ecx),%ebp
20905+ xorl %ebp, %esi
20906+ movl 24(%esp), %ebp
20907+ movb %dh, %cl
20908+ andl $0xff, %eax
20909+ andl $0xff, %edx
20910+ movl 0x600+des_SPtrans(%ebx),%ebx
20911+ xorl %ebx, %esi
20912+ movl 0x700+des_SPtrans(%ecx),%ebx
20913+ xorl %ebx, %esi
20914+ movl 0x400+des_SPtrans(%eax),%ebx
20915+ xorl %ebx, %esi
20916+ movl 0x500+des_SPtrans(%edx),%ebx
20917+ xorl %ebx, %esi
20918+
20919+
20920+ movl 40(%ebp), %eax
20921+ xorl %ebx, %ebx
20922+ movl 44(%ebp), %edx
20923+ xorl %esi, %eax
20924+ xorl %esi, %edx
20925+ andl $0xfcfcfcfc, %eax
20926+ andl $0xcfcfcfcf, %edx
20927+ movb %al, %bl
20928+ movb %ah, %cl
20929+ rorl $4, %edx
20930+ movl des_SPtrans(%ebx),%ebp
20931+ movb %dl, %bl
20932+ xorl %ebp, %edi
20933+ movl 0x200+des_SPtrans(%ecx),%ebp
20934+ xorl %ebp, %edi
20935+ movb %dh, %cl
20936+ shrl $16, %eax
20937+ movl 0x100+des_SPtrans(%ebx),%ebp
20938+ xorl %ebp, %edi
20939+ movb %ah, %bl
20940+ shrl $16, %edx
20941+ movl 0x300+des_SPtrans(%ecx),%ebp
20942+ xorl %ebp, %edi
20943+ movl 24(%esp), %ebp
20944+ movb %dh, %cl
20945+ andl $0xff, %eax
20946+ andl $0xff, %edx
20947+ movl 0x600+des_SPtrans(%ebx),%ebx
20948+ xorl %ebx, %edi
20949+ movl 0x700+des_SPtrans(%ecx),%ebx
20950+ xorl %ebx, %edi
20951+ movl 0x400+des_SPtrans(%eax),%ebx
20952+ xorl %ebx, %edi
20953+ movl 0x500+des_SPtrans(%edx),%ebx
20954+ xorl %ebx, %edi
20955+
20956+
20957+ movl 32(%ebp), %eax
20958+ xorl %ebx, %ebx
20959+ movl 36(%ebp), %edx
20960+ xorl %edi, %eax
20961+ xorl %edi, %edx
20962+ andl $0xfcfcfcfc, %eax
20963+ andl $0xcfcfcfcf, %edx
20964+ movb %al, %bl
20965+ movb %ah, %cl
20966+ rorl $4, %edx
20967+ movl des_SPtrans(%ebx),%ebp
20968+ movb %dl, %bl
20969+ xorl %ebp, %esi
20970+ movl 0x200+des_SPtrans(%ecx),%ebp
20971+ xorl %ebp, %esi
20972+ movb %dh, %cl
20973+ shrl $16, %eax
20974+ movl 0x100+des_SPtrans(%ebx),%ebp
20975+ xorl %ebp, %esi
20976+ movb %ah, %bl
20977+ shrl $16, %edx
20978+ movl 0x300+des_SPtrans(%ecx),%ebp
20979+ xorl %ebp, %esi
20980+ movl 24(%esp), %ebp
20981+ movb %dh, %cl
20982+ andl $0xff, %eax
20983+ andl $0xff, %edx
20984+ movl 0x600+des_SPtrans(%ebx),%ebx
20985+ xorl %ebx, %esi
20986+ movl 0x700+des_SPtrans(%ecx),%ebx
20987+ xorl %ebx, %esi
20988+ movl 0x400+des_SPtrans(%eax),%ebx
20989+ xorl %ebx, %esi
20990+ movl 0x500+des_SPtrans(%edx),%ebx
20991+ xorl %ebx, %esi
20992+
20993+
20994+ movl 24(%ebp), %eax
20995+ xorl %ebx, %ebx
20996+ movl 28(%ebp), %edx
20997+ xorl %esi, %eax
20998+ xorl %esi, %edx
20999+ andl $0xfcfcfcfc, %eax
21000+ andl $0xcfcfcfcf, %edx
21001+ movb %al, %bl
21002+ movb %ah, %cl
21003+ rorl $4, %edx
21004+ movl des_SPtrans(%ebx),%ebp
21005+ movb %dl, %bl
21006+ xorl %ebp, %edi
21007+ movl 0x200+des_SPtrans(%ecx),%ebp
21008+ xorl %ebp, %edi
21009+ movb %dh, %cl
21010+ shrl $16, %eax
21011+ movl 0x100+des_SPtrans(%ebx),%ebp
21012+ xorl %ebp, %edi
21013+ movb %ah, %bl
21014+ shrl $16, %edx
21015+ movl 0x300+des_SPtrans(%ecx),%ebp
21016+ xorl %ebp, %edi
21017+ movl 24(%esp), %ebp
21018+ movb %dh, %cl
21019+ andl $0xff, %eax
21020+ andl $0xff, %edx
21021+ movl 0x600+des_SPtrans(%ebx),%ebx
21022+ xorl %ebx, %edi
21023+ movl 0x700+des_SPtrans(%ecx),%ebx
21024+ xorl %ebx, %edi
21025+ movl 0x400+des_SPtrans(%eax),%ebx
21026+ xorl %ebx, %edi
21027+ movl 0x500+des_SPtrans(%edx),%ebx
21028+ xorl %ebx, %edi
21029+
21030+
21031+ movl 16(%ebp), %eax
21032+ xorl %ebx, %ebx
21033+ movl 20(%ebp), %edx
21034+ xorl %edi, %eax
21035+ xorl %edi, %edx
21036+ andl $0xfcfcfcfc, %eax
21037+ andl $0xcfcfcfcf, %edx
21038+ movb %al, %bl
21039+ movb %ah, %cl
21040+ rorl $4, %edx
21041+ movl des_SPtrans(%ebx),%ebp
21042+ movb %dl, %bl
21043+ xorl %ebp, %esi
21044+ movl 0x200+des_SPtrans(%ecx),%ebp
21045+ xorl %ebp, %esi
21046+ movb %dh, %cl
21047+ shrl $16, %eax
21048+ movl 0x100+des_SPtrans(%ebx),%ebp
21049+ xorl %ebp, %esi
21050+ movb %ah, %bl
21051+ shrl $16, %edx
21052+ movl 0x300+des_SPtrans(%ecx),%ebp
21053+ xorl %ebp, %esi
21054+ movl 24(%esp), %ebp
21055+ movb %dh, %cl
21056+ andl $0xff, %eax
21057+ andl $0xff, %edx
21058+ movl 0x600+des_SPtrans(%ebx),%ebx
21059+ xorl %ebx, %esi
21060+ movl 0x700+des_SPtrans(%ecx),%ebx
21061+ xorl %ebx, %esi
21062+ movl 0x400+des_SPtrans(%eax),%ebx
21063+ xorl %ebx, %esi
21064+ movl 0x500+des_SPtrans(%edx),%ebx
21065+ xorl %ebx, %esi
21066+
21067+
21068+ movl 8(%ebp), %eax
21069+ xorl %ebx, %ebx
21070+ movl 12(%ebp), %edx
21071+ xorl %esi, %eax
21072+ xorl %esi, %edx
21073+ andl $0xfcfcfcfc, %eax
21074+ andl $0xcfcfcfcf, %edx
21075+ movb %al, %bl
21076+ movb %ah, %cl
21077+ rorl $4, %edx
21078+ movl des_SPtrans(%ebx),%ebp
21079+ movb %dl, %bl
21080+ xorl %ebp, %edi
21081+ movl 0x200+des_SPtrans(%ecx),%ebp
21082+ xorl %ebp, %edi
21083+ movb %dh, %cl
21084+ shrl $16, %eax
21085+ movl 0x100+des_SPtrans(%ebx),%ebp
21086+ xorl %ebp, %edi
21087+ movb %ah, %bl
21088+ shrl $16, %edx
21089+ movl 0x300+des_SPtrans(%ecx),%ebp
21090+ xorl %ebp, %edi
21091+ movl 24(%esp), %ebp
21092+ movb %dh, %cl
21093+ andl $0xff, %eax
21094+ andl $0xff, %edx
21095+ movl 0x600+des_SPtrans(%ebx),%ebx
21096+ xorl %ebx, %edi
21097+ movl 0x700+des_SPtrans(%ecx),%ebx
21098+ xorl %ebx, %edi
21099+ movl 0x400+des_SPtrans(%eax),%ebx
21100+ xorl %ebx, %edi
21101+ movl 0x500+des_SPtrans(%edx),%ebx
21102+ xorl %ebx, %edi
21103+
21104+
21105+ movl (%ebp), %eax
21106+ xorl %ebx, %ebx
21107+ movl 4(%ebp), %edx
21108+ xorl %edi, %eax
21109+ xorl %edi, %edx
21110+ andl $0xfcfcfcfc, %eax
21111+ andl $0xcfcfcfcf, %edx
21112+ movb %al, %bl
21113+ movb %ah, %cl
21114+ rorl $4, %edx
21115+ movl des_SPtrans(%ebx),%ebp
21116+ movb %dl, %bl
21117+ xorl %ebp, %esi
21118+ movl 0x200+des_SPtrans(%ecx),%ebp
21119+ xorl %ebp, %esi
21120+ movb %dh, %cl
21121+ shrl $16, %eax
21122+ movl 0x100+des_SPtrans(%ebx),%ebp
21123+ xorl %ebp, %esi
21124+ movb %ah, %bl
21125+ shrl $16, %edx
21126+ movl 0x300+des_SPtrans(%ecx),%ebp
21127+ xorl %ebp, %esi
21128+ movl 24(%esp), %ebp
21129+ movb %dh, %cl
21130+ andl $0xff, %eax
21131+ andl $0xff, %edx
21132+ movl 0x600+des_SPtrans(%ebx),%ebx
21133+ xorl %ebx, %esi
21134+ movl 0x700+des_SPtrans(%ecx),%ebx
21135+ xorl %ebx, %esi
21136+ movl 0x400+des_SPtrans(%eax),%ebx
21137+ xorl %ebx, %esi
21138+ movl 0x500+des_SPtrans(%edx),%ebx
21139+ xorl %ebx, %esi
21140+.L001end:
21141+
21142+
21143+ movl 20(%esp), %edx
21144+.byte 209
21145+.byte 206
21146+ movl %edi, %eax
21147+ xorl %esi, %edi
21148+ andl $0xaaaaaaaa, %edi
21149+ xorl %edi, %eax
21150+ xorl %edi, %esi
21151+
21152+ roll $23, %eax
21153+ movl %eax, %edi
21154+ xorl %esi, %eax
21155+ andl $0x03fc03fc, %eax
21156+ xorl %eax, %edi
21157+ xorl %eax, %esi
21158+
21159+ roll $10, %edi
21160+ movl %edi, %eax
21161+ xorl %esi, %edi
21162+ andl $0x33333333, %edi
21163+ xorl %edi, %eax
21164+ xorl %edi, %esi
21165+
21166+ roll $18, %esi
21167+ movl %esi, %edi
21168+ xorl %eax, %esi
21169+ andl $0xfff0000f, %esi
21170+ xorl %esi, %edi
21171+ xorl %esi, %eax
21172+
21173+ roll $12, %edi
21174+ movl %edi, %esi
21175+ xorl %eax, %edi
21176+ andl $0xf0f0f0f0, %edi
21177+ xorl %edi, %esi
21178+ xorl %edi, %eax
21179+
21180+ rorl $4, %eax
21181+ movl %eax, (%edx)
21182+ movl %esi, 4(%edx)
21183+ popl %ebp
21184+ popl %ebx
21185+ popl %edi
21186+ popl %esi
21187+ ret
21188+.des_encrypt_end:
21189+ .size des_encrypt , .des_encrypt_end-des_encrypt
21190+.ident "desasm.pl"
21191+.text
21192+ .align 16
21193+.globl des_encrypt2
21194+ .type des_encrypt2 , @function
21195+des_encrypt2:
21196+ pushl %esi
21197+ pushl %edi
21198+
21199+
21200+ movl 12(%esp), %eax
21201+ xorl %ecx, %ecx
21202+ pushl %ebx
21203+ pushl %ebp
21204+ movl (%eax), %esi
21205+ movl 28(%esp), %ebx
21206+ roll $3, %esi
21207+ movl 4(%eax), %edi
21208+ roll $3, %edi
21209+ movl 24(%esp), %ebp
21210+ cmpl $0, %ebx
21211+ je .L002start_decrypt
21212+
21213+
21214+ movl (%ebp), %eax
21215+ xorl %ebx, %ebx
21216+ movl 4(%ebp), %edx
21217+ xorl %esi, %eax
21218+ xorl %esi, %edx
21219+ andl $0xfcfcfcfc, %eax
21220+ andl $0xcfcfcfcf, %edx
21221+ movb %al, %bl
21222+ movb %ah, %cl
21223+ rorl $4, %edx
21224+ movl des_SPtrans(%ebx),%ebp
21225+ movb %dl, %bl
21226+ xorl %ebp, %edi
21227+ movl 0x200+des_SPtrans(%ecx),%ebp
21228+ xorl %ebp, %edi
21229+ movb %dh, %cl
21230+ shrl $16, %eax
21231+ movl 0x100+des_SPtrans(%ebx),%ebp
21232+ xorl %ebp, %edi
21233+ movb %ah, %bl
21234+ shrl $16, %edx
21235+ movl 0x300+des_SPtrans(%ecx),%ebp
21236+ xorl %ebp, %edi
21237+ movl 24(%esp), %ebp
21238+ movb %dh, %cl
21239+ andl $0xff, %eax
21240+ andl $0xff, %edx
21241+ movl 0x600+des_SPtrans(%ebx),%ebx
21242+ xorl %ebx, %edi
21243+ movl 0x700+des_SPtrans(%ecx),%ebx
21244+ xorl %ebx, %edi
21245+ movl 0x400+des_SPtrans(%eax),%ebx
21246+ xorl %ebx, %edi
21247+ movl 0x500+des_SPtrans(%edx),%ebx
21248+ xorl %ebx, %edi
21249+
21250+
21251+ movl 8(%ebp), %eax
21252+ xorl %ebx, %ebx
21253+ movl 12(%ebp), %edx
21254+ xorl %edi, %eax
21255+ xorl %edi, %edx
21256+ andl $0xfcfcfcfc, %eax
21257+ andl $0xcfcfcfcf, %edx
21258+ movb %al, %bl
21259+ movb %ah, %cl
21260+ rorl $4, %edx
21261+ movl des_SPtrans(%ebx),%ebp
21262+ movb %dl, %bl
21263+ xorl %ebp, %esi
21264+ movl 0x200+des_SPtrans(%ecx),%ebp
21265+ xorl %ebp, %esi
21266+ movb %dh, %cl
21267+ shrl $16, %eax
21268+ movl 0x100+des_SPtrans(%ebx),%ebp
21269+ xorl %ebp, %esi
21270+ movb %ah, %bl
21271+ shrl $16, %edx
21272+ movl 0x300+des_SPtrans(%ecx),%ebp
21273+ xorl %ebp, %esi
21274+ movl 24(%esp), %ebp
21275+ movb %dh, %cl
21276+ andl $0xff, %eax
21277+ andl $0xff, %edx
21278+ movl 0x600+des_SPtrans(%ebx),%ebx
21279+ xorl %ebx, %esi
21280+ movl 0x700+des_SPtrans(%ecx),%ebx
21281+ xorl %ebx, %esi
21282+ movl 0x400+des_SPtrans(%eax),%ebx
21283+ xorl %ebx, %esi
21284+ movl 0x500+des_SPtrans(%edx),%ebx
21285+ xorl %ebx, %esi
21286+
21287+
21288+ movl 16(%ebp), %eax
21289+ xorl %ebx, %ebx
21290+ movl 20(%ebp), %edx
21291+ xorl %esi, %eax
21292+ xorl %esi, %edx
21293+ andl $0xfcfcfcfc, %eax
21294+ andl $0xcfcfcfcf, %edx
21295+ movb %al, %bl
21296+ movb %ah, %cl
21297+ rorl $4, %edx
21298+ movl des_SPtrans(%ebx),%ebp
21299+ movb %dl, %bl
21300+ xorl %ebp, %edi
21301+ movl 0x200+des_SPtrans(%ecx),%ebp
21302+ xorl %ebp, %edi
21303+ movb %dh, %cl
21304+ shrl $16, %eax
21305+ movl 0x100+des_SPtrans(%ebx),%ebp
21306+ xorl %ebp, %edi
21307+ movb %ah, %bl
21308+ shrl $16, %edx
21309+ movl 0x300+des_SPtrans(%ecx),%ebp
21310+ xorl %ebp, %edi
21311+ movl 24(%esp), %ebp
21312+ movb %dh, %cl
21313+ andl $0xff, %eax
21314+ andl $0xff, %edx
21315+ movl 0x600+des_SPtrans(%ebx),%ebx
21316+ xorl %ebx, %edi
21317+ movl 0x700+des_SPtrans(%ecx),%ebx
21318+ xorl %ebx, %edi
21319+ movl 0x400+des_SPtrans(%eax),%ebx
21320+ xorl %ebx, %edi
21321+ movl 0x500+des_SPtrans(%edx),%ebx
21322+ xorl %ebx, %edi
21323+
21324+
21325+ movl 24(%ebp), %eax
21326+ xorl %ebx, %ebx
21327+ movl 28(%ebp), %edx
21328+ xorl %edi, %eax
21329+ xorl %edi, %edx
21330+ andl $0xfcfcfcfc, %eax
21331+ andl $0xcfcfcfcf, %edx
21332+ movb %al, %bl
21333+ movb %ah, %cl
21334+ rorl $4, %edx
21335+ movl des_SPtrans(%ebx),%ebp
21336+ movb %dl, %bl
21337+ xorl %ebp, %esi
21338+ movl 0x200+des_SPtrans(%ecx),%ebp
21339+ xorl %ebp, %esi
21340+ movb %dh, %cl
21341+ shrl $16, %eax
21342+ movl 0x100+des_SPtrans(%ebx),%ebp
21343+ xorl %ebp, %esi
21344+ movb %ah, %bl
21345+ shrl $16, %edx
21346+ movl 0x300+des_SPtrans(%ecx),%ebp
21347+ xorl %ebp, %esi
21348+ movl 24(%esp), %ebp
21349+ movb %dh, %cl
21350+ andl $0xff, %eax
21351+ andl $0xff, %edx
21352+ movl 0x600+des_SPtrans(%ebx),%ebx
21353+ xorl %ebx, %esi
21354+ movl 0x700+des_SPtrans(%ecx),%ebx
21355+ xorl %ebx, %esi
21356+ movl 0x400+des_SPtrans(%eax),%ebx
21357+ xorl %ebx, %esi
21358+ movl 0x500+des_SPtrans(%edx),%ebx
21359+ xorl %ebx, %esi
21360+
21361+
21362+ movl 32(%ebp), %eax
21363+ xorl %ebx, %ebx
21364+ movl 36(%ebp), %edx
21365+ xorl %esi, %eax
21366+ xorl %esi, %edx
21367+ andl $0xfcfcfcfc, %eax
21368+ andl $0xcfcfcfcf, %edx
21369+ movb %al, %bl
21370+ movb %ah, %cl
21371+ rorl $4, %edx
21372+ movl des_SPtrans(%ebx),%ebp
21373+ movb %dl, %bl
21374+ xorl %ebp, %edi
21375+ movl 0x200+des_SPtrans(%ecx),%ebp
21376+ xorl %ebp, %edi
21377+ movb %dh, %cl
21378+ shrl $16, %eax
21379+ movl 0x100+des_SPtrans(%ebx),%ebp
21380+ xorl %ebp, %edi
21381+ movb %ah, %bl
21382+ shrl $16, %edx
21383+ movl 0x300+des_SPtrans(%ecx),%ebp
21384+ xorl %ebp, %edi
21385+ movl 24(%esp), %ebp
21386+ movb %dh, %cl
21387+ andl $0xff, %eax
21388+ andl $0xff, %edx
21389+ movl 0x600+des_SPtrans(%ebx),%ebx
21390+ xorl %ebx, %edi
21391+ movl 0x700+des_SPtrans(%ecx),%ebx
21392+ xorl %ebx, %edi
21393+ movl 0x400+des_SPtrans(%eax),%ebx
21394+ xorl %ebx, %edi
21395+ movl 0x500+des_SPtrans(%edx),%ebx
21396+ xorl %ebx, %edi
21397+
21398+
21399+ movl 40(%ebp), %eax
21400+ xorl %ebx, %ebx
21401+ movl 44(%ebp), %edx
21402+ xorl %edi, %eax
21403+ xorl %edi, %edx
21404+ andl $0xfcfcfcfc, %eax
21405+ andl $0xcfcfcfcf, %edx
21406+ movb %al, %bl
21407+ movb %ah, %cl
21408+ rorl $4, %edx
21409+ movl des_SPtrans(%ebx),%ebp
21410+ movb %dl, %bl
21411+ xorl %ebp, %esi
21412+ movl 0x200+des_SPtrans(%ecx),%ebp
21413+ xorl %ebp, %esi
21414+ movb %dh, %cl
21415+ shrl $16, %eax
21416+ movl 0x100+des_SPtrans(%ebx),%ebp
21417+ xorl %ebp, %esi
21418+ movb %ah, %bl
21419+ shrl $16, %edx
21420+ movl 0x300+des_SPtrans(%ecx),%ebp
21421+ xorl %ebp, %esi
21422+ movl 24(%esp), %ebp
21423+ movb %dh, %cl
21424+ andl $0xff, %eax
21425+ andl $0xff, %edx
21426+ movl 0x600+des_SPtrans(%ebx),%ebx
21427+ xorl %ebx, %esi
21428+ movl 0x700+des_SPtrans(%ecx),%ebx
21429+ xorl %ebx, %esi
21430+ movl 0x400+des_SPtrans(%eax),%ebx
21431+ xorl %ebx, %esi
21432+ movl 0x500+des_SPtrans(%edx),%ebx
21433+ xorl %ebx, %esi
21434+
21435+
21436+ movl 48(%ebp), %eax
21437+ xorl %ebx, %ebx
21438+ movl 52(%ebp), %edx
21439+ xorl %esi, %eax
21440+ xorl %esi, %edx
21441+ andl $0xfcfcfcfc, %eax
21442+ andl $0xcfcfcfcf, %edx
21443+ movb %al, %bl
21444+ movb %ah, %cl
21445+ rorl $4, %edx
21446+ movl des_SPtrans(%ebx),%ebp
21447+ movb %dl, %bl
21448+ xorl %ebp, %edi
21449+ movl 0x200+des_SPtrans(%ecx),%ebp
21450+ xorl %ebp, %edi
21451+ movb %dh, %cl
21452+ shrl $16, %eax
21453+ movl 0x100+des_SPtrans(%ebx),%ebp
21454+ xorl %ebp, %edi
21455+ movb %ah, %bl
21456+ shrl $16, %edx
21457+ movl 0x300+des_SPtrans(%ecx),%ebp
21458+ xorl %ebp, %edi
21459+ movl 24(%esp), %ebp
21460+ movb %dh, %cl
21461+ andl $0xff, %eax
21462+ andl $0xff, %edx
21463+ movl 0x600+des_SPtrans(%ebx),%ebx
21464+ xorl %ebx, %edi
21465+ movl 0x700+des_SPtrans(%ecx),%ebx
21466+ xorl %ebx, %edi
21467+ movl 0x400+des_SPtrans(%eax),%ebx
21468+ xorl %ebx, %edi
21469+ movl 0x500+des_SPtrans(%edx),%ebx
21470+ xorl %ebx, %edi
21471+
21472+
21473+ movl 56(%ebp), %eax
21474+ xorl %ebx, %ebx
21475+ movl 60(%ebp), %edx
21476+ xorl %edi, %eax
21477+ xorl %edi, %edx
21478+ andl $0xfcfcfcfc, %eax
21479+ andl $0xcfcfcfcf, %edx
21480+ movb %al, %bl
21481+ movb %ah, %cl
21482+ rorl $4, %edx
21483+ movl des_SPtrans(%ebx),%ebp
21484+ movb %dl, %bl
21485+ xorl %ebp, %esi
21486+ movl 0x200+des_SPtrans(%ecx),%ebp
21487+ xorl %ebp, %esi
21488+ movb %dh, %cl
21489+ shrl $16, %eax
21490+ movl 0x100+des_SPtrans(%ebx),%ebp
21491+ xorl %ebp, %esi
21492+ movb %ah, %bl
21493+ shrl $16, %edx
21494+ movl 0x300+des_SPtrans(%ecx),%ebp
21495+ xorl %ebp, %esi
21496+ movl 24(%esp), %ebp
21497+ movb %dh, %cl
21498+ andl $0xff, %eax
21499+ andl $0xff, %edx
21500+ movl 0x600+des_SPtrans(%ebx),%ebx
21501+ xorl %ebx, %esi
21502+ movl 0x700+des_SPtrans(%ecx),%ebx
21503+ xorl %ebx, %esi
21504+ movl 0x400+des_SPtrans(%eax),%ebx
21505+ xorl %ebx, %esi
21506+ movl 0x500+des_SPtrans(%edx),%ebx
21507+ xorl %ebx, %esi
21508+
21509+
21510+ movl 64(%ebp), %eax
21511+ xorl %ebx, %ebx
21512+ movl 68(%ebp), %edx
21513+ xorl %esi, %eax
21514+ xorl %esi, %edx
21515+ andl $0xfcfcfcfc, %eax
21516+ andl $0xcfcfcfcf, %edx
21517+ movb %al, %bl
21518+ movb %ah, %cl
21519+ rorl $4, %edx
21520+ movl des_SPtrans(%ebx),%ebp
21521+ movb %dl, %bl
21522+ xorl %ebp, %edi
21523+ movl 0x200+des_SPtrans(%ecx),%ebp
21524+ xorl %ebp, %edi
21525+ movb %dh, %cl
21526+ shrl $16, %eax
21527+ movl 0x100+des_SPtrans(%ebx),%ebp
21528+ xorl %ebp, %edi
21529+ movb %ah, %bl
21530+ shrl $16, %edx
21531+ movl 0x300+des_SPtrans(%ecx),%ebp
21532+ xorl %ebp, %edi
21533+ movl 24(%esp), %ebp
21534+ movb %dh, %cl
21535+ andl $0xff, %eax
21536+ andl $0xff, %edx
21537+ movl 0x600+des_SPtrans(%ebx),%ebx
21538+ xorl %ebx, %edi
21539+ movl 0x700+des_SPtrans(%ecx),%ebx
21540+ xorl %ebx, %edi
21541+ movl 0x400+des_SPtrans(%eax),%ebx
21542+ xorl %ebx, %edi
21543+ movl 0x500+des_SPtrans(%edx),%ebx
21544+ xorl %ebx, %edi
21545+
21546+
21547+ movl 72(%ebp), %eax
21548+ xorl %ebx, %ebx
21549+ movl 76(%ebp), %edx
21550+ xorl %edi, %eax
21551+ xorl %edi, %edx
21552+ andl $0xfcfcfcfc, %eax
21553+ andl $0xcfcfcfcf, %edx
21554+ movb %al, %bl
21555+ movb %ah, %cl
21556+ rorl $4, %edx
21557+ movl des_SPtrans(%ebx),%ebp
21558+ movb %dl, %bl
21559+ xorl %ebp, %esi
21560+ movl 0x200+des_SPtrans(%ecx),%ebp
21561+ xorl %ebp, %esi
21562+ movb %dh, %cl
21563+ shrl $16, %eax
21564+ movl 0x100+des_SPtrans(%ebx),%ebp
21565+ xorl %ebp, %esi
21566+ movb %ah, %bl
21567+ shrl $16, %edx
21568+ movl 0x300+des_SPtrans(%ecx),%ebp
21569+ xorl %ebp, %esi
21570+ movl 24(%esp), %ebp
21571+ movb %dh, %cl
21572+ andl $0xff, %eax
21573+ andl $0xff, %edx
21574+ movl 0x600+des_SPtrans(%ebx),%ebx
21575+ xorl %ebx, %esi
21576+ movl 0x700+des_SPtrans(%ecx),%ebx
21577+ xorl %ebx, %esi
21578+ movl 0x400+des_SPtrans(%eax),%ebx
21579+ xorl %ebx, %esi
21580+ movl 0x500+des_SPtrans(%edx),%ebx
21581+ xorl %ebx, %esi
21582+
21583+
21584+ movl 80(%ebp), %eax
21585+ xorl %ebx, %ebx
21586+ movl 84(%ebp), %edx
21587+ xorl %esi, %eax
21588+ xorl %esi, %edx
21589+ andl $0xfcfcfcfc, %eax
21590+ andl $0xcfcfcfcf, %edx
21591+ movb %al, %bl
21592+ movb %ah, %cl
21593+ rorl $4, %edx
21594+ movl des_SPtrans(%ebx),%ebp
21595+ movb %dl, %bl
21596+ xorl %ebp, %edi
21597+ movl 0x200+des_SPtrans(%ecx),%ebp
21598+ xorl %ebp, %edi
21599+ movb %dh, %cl
21600+ shrl $16, %eax
21601+ movl 0x100+des_SPtrans(%ebx),%ebp
21602+ xorl %ebp, %edi
21603+ movb %ah, %bl
21604+ shrl $16, %edx
21605+ movl 0x300+des_SPtrans(%ecx),%ebp
21606+ xorl %ebp, %edi
21607+ movl 24(%esp), %ebp
21608+ movb %dh, %cl
21609+ andl $0xff, %eax
21610+ andl $0xff, %edx
21611+ movl 0x600+des_SPtrans(%ebx),%ebx
21612+ xorl %ebx, %edi
21613+ movl 0x700+des_SPtrans(%ecx),%ebx
21614+ xorl %ebx, %edi
21615+ movl 0x400+des_SPtrans(%eax),%ebx
21616+ xorl %ebx, %edi
21617+ movl 0x500+des_SPtrans(%edx),%ebx
21618+ xorl %ebx, %edi
21619+
21620+
21621+ movl 88(%ebp), %eax
21622+ xorl %ebx, %ebx
21623+ movl 92(%ebp), %edx
21624+ xorl %edi, %eax
21625+ xorl %edi, %edx
21626+ andl $0xfcfcfcfc, %eax
21627+ andl $0xcfcfcfcf, %edx
21628+ movb %al, %bl
21629+ movb %ah, %cl
21630+ rorl $4, %edx
21631+ movl des_SPtrans(%ebx),%ebp
21632+ movb %dl, %bl
21633+ xorl %ebp, %esi
21634+ movl 0x200+des_SPtrans(%ecx),%ebp
21635+ xorl %ebp, %esi
21636+ movb %dh, %cl
21637+ shrl $16, %eax
21638+ movl 0x100+des_SPtrans(%ebx),%ebp
21639+ xorl %ebp, %esi
21640+ movb %ah, %bl
21641+ shrl $16, %edx
21642+ movl 0x300+des_SPtrans(%ecx),%ebp
21643+ xorl %ebp, %esi
21644+ movl 24(%esp), %ebp
21645+ movb %dh, %cl
21646+ andl $0xff, %eax
21647+ andl $0xff, %edx
21648+ movl 0x600+des_SPtrans(%ebx),%ebx
21649+ xorl %ebx, %esi
21650+ movl 0x700+des_SPtrans(%ecx),%ebx
21651+ xorl %ebx, %esi
21652+ movl 0x400+des_SPtrans(%eax),%ebx
21653+ xorl %ebx, %esi
21654+ movl 0x500+des_SPtrans(%edx),%ebx
21655+ xorl %ebx, %esi
21656+
21657+
21658+ movl 96(%ebp), %eax
21659+ xorl %ebx, %ebx
21660+ movl 100(%ebp), %edx
21661+ xorl %esi, %eax
21662+ xorl %esi, %edx
21663+ andl $0xfcfcfcfc, %eax
21664+ andl $0xcfcfcfcf, %edx
21665+ movb %al, %bl
21666+ movb %ah, %cl
21667+ rorl $4, %edx
21668+ movl des_SPtrans(%ebx),%ebp
21669+ movb %dl, %bl
21670+ xorl %ebp, %edi
21671+ movl 0x200+des_SPtrans(%ecx),%ebp
21672+ xorl %ebp, %edi
21673+ movb %dh, %cl
21674+ shrl $16, %eax
21675+ movl 0x100+des_SPtrans(%ebx),%ebp
21676+ xorl %ebp, %edi
21677+ movb %ah, %bl
21678+ shrl $16, %edx
21679+ movl 0x300+des_SPtrans(%ecx),%ebp
21680+ xorl %ebp, %edi
21681+ movl 24(%esp), %ebp
21682+ movb %dh, %cl
21683+ andl $0xff, %eax
21684+ andl $0xff, %edx
21685+ movl 0x600+des_SPtrans(%ebx),%ebx
21686+ xorl %ebx, %edi
21687+ movl 0x700+des_SPtrans(%ecx),%ebx
21688+ xorl %ebx, %edi
21689+ movl 0x400+des_SPtrans(%eax),%ebx
21690+ xorl %ebx, %edi
21691+ movl 0x500+des_SPtrans(%edx),%ebx
21692+ xorl %ebx, %edi
21693+
21694+
21695+ movl 104(%ebp), %eax
21696+ xorl %ebx, %ebx
21697+ movl 108(%ebp), %edx
21698+ xorl %edi, %eax
21699+ xorl %edi, %edx
21700+ andl $0xfcfcfcfc, %eax
21701+ andl $0xcfcfcfcf, %edx
21702+ movb %al, %bl
21703+ movb %ah, %cl
21704+ rorl $4, %edx
21705+ movl des_SPtrans(%ebx),%ebp
21706+ movb %dl, %bl
21707+ xorl %ebp, %esi
21708+ movl 0x200+des_SPtrans(%ecx),%ebp
21709+ xorl %ebp, %esi
21710+ movb %dh, %cl
21711+ shrl $16, %eax
21712+ movl 0x100+des_SPtrans(%ebx),%ebp
21713+ xorl %ebp, %esi
21714+ movb %ah, %bl
21715+ shrl $16, %edx
21716+ movl 0x300+des_SPtrans(%ecx),%ebp
21717+ xorl %ebp, %esi
21718+ movl 24(%esp), %ebp
21719+ movb %dh, %cl
21720+ andl $0xff, %eax
21721+ andl $0xff, %edx
21722+ movl 0x600+des_SPtrans(%ebx),%ebx
21723+ xorl %ebx, %esi
21724+ movl 0x700+des_SPtrans(%ecx),%ebx
21725+ xorl %ebx, %esi
21726+ movl 0x400+des_SPtrans(%eax),%ebx
21727+ xorl %ebx, %esi
21728+ movl 0x500+des_SPtrans(%edx),%ebx
21729+ xorl %ebx, %esi
21730+
21731+
21732+ movl 112(%ebp), %eax
21733+ xorl %ebx, %ebx
21734+ movl 116(%ebp), %edx
21735+ xorl %esi, %eax
21736+ xorl %esi, %edx
21737+ andl $0xfcfcfcfc, %eax
21738+ andl $0xcfcfcfcf, %edx
21739+ movb %al, %bl
21740+ movb %ah, %cl
21741+ rorl $4, %edx
21742+ movl des_SPtrans(%ebx),%ebp
21743+ movb %dl, %bl
21744+ xorl %ebp, %edi
21745+ movl 0x200+des_SPtrans(%ecx),%ebp
21746+ xorl %ebp, %edi
21747+ movb %dh, %cl
21748+ shrl $16, %eax
21749+ movl 0x100+des_SPtrans(%ebx),%ebp
21750+ xorl %ebp, %edi
21751+ movb %ah, %bl
21752+ shrl $16, %edx
21753+ movl 0x300+des_SPtrans(%ecx),%ebp
21754+ xorl %ebp, %edi
21755+ movl 24(%esp), %ebp
21756+ movb %dh, %cl
21757+ andl $0xff, %eax
21758+ andl $0xff, %edx
21759+ movl 0x600+des_SPtrans(%ebx),%ebx
21760+ xorl %ebx, %edi
21761+ movl 0x700+des_SPtrans(%ecx),%ebx
21762+ xorl %ebx, %edi
21763+ movl 0x400+des_SPtrans(%eax),%ebx
21764+ xorl %ebx, %edi
21765+ movl 0x500+des_SPtrans(%edx),%ebx
21766+ xorl %ebx, %edi
21767+
21768+
21769+ movl 120(%ebp), %eax
21770+ xorl %ebx, %ebx
21771+ movl 124(%ebp), %edx
21772+ xorl %edi, %eax
21773+ xorl %edi, %edx
21774+ andl $0xfcfcfcfc, %eax
21775+ andl $0xcfcfcfcf, %edx
21776+ movb %al, %bl
21777+ movb %ah, %cl
21778+ rorl $4, %edx
21779+ movl des_SPtrans(%ebx),%ebp
21780+ movb %dl, %bl
21781+ xorl %ebp, %esi
21782+ movl 0x200+des_SPtrans(%ecx),%ebp
21783+ xorl %ebp, %esi
21784+ movb %dh, %cl
21785+ shrl $16, %eax
21786+ movl 0x100+des_SPtrans(%ebx),%ebp
21787+ xorl %ebp, %esi
21788+ movb %ah, %bl
21789+ shrl $16, %edx
21790+ movl 0x300+des_SPtrans(%ecx),%ebp
21791+ xorl %ebp, %esi
21792+ movl 24(%esp), %ebp
21793+ movb %dh, %cl
21794+ andl $0xff, %eax
21795+ andl $0xff, %edx
21796+ movl 0x600+des_SPtrans(%ebx),%ebx
21797+ xorl %ebx, %esi
21798+ movl 0x700+des_SPtrans(%ecx),%ebx
21799+ xorl %ebx, %esi
21800+ movl 0x400+des_SPtrans(%eax),%ebx
21801+ xorl %ebx, %esi
21802+ movl 0x500+des_SPtrans(%edx),%ebx
21803+ xorl %ebx, %esi
21804+ jmp .L003end
21805+.L002start_decrypt:
21806+
21807+
21808+ movl 120(%ebp), %eax
21809+ xorl %ebx, %ebx
21810+ movl 124(%ebp), %edx
21811+ xorl %esi, %eax
21812+ xorl %esi, %edx
21813+ andl $0xfcfcfcfc, %eax
21814+ andl $0xcfcfcfcf, %edx
21815+ movb %al, %bl
21816+ movb %ah, %cl
21817+ rorl $4, %edx
21818+ movl des_SPtrans(%ebx),%ebp
21819+ movb %dl, %bl
21820+ xorl %ebp, %edi
21821+ movl 0x200+des_SPtrans(%ecx),%ebp
21822+ xorl %ebp, %edi
21823+ movb %dh, %cl
21824+ shrl $16, %eax
21825+ movl 0x100+des_SPtrans(%ebx),%ebp
21826+ xorl %ebp, %edi
21827+ movb %ah, %bl
21828+ shrl $16, %edx
21829+ movl 0x300+des_SPtrans(%ecx),%ebp
21830+ xorl %ebp, %edi
21831+ movl 24(%esp), %ebp
21832+ movb %dh, %cl
21833+ andl $0xff, %eax
21834+ andl $0xff, %edx
21835+ movl 0x600+des_SPtrans(%ebx),%ebx
21836+ xorl %ebx, %edi
21837+ movl 0x700+des_SPtrans(%ecx),%ebx
21838+ xorl %ebx, %edi
21839+ movl 0x400+des_SPtrans(%eax),%ebx
21840+ xorl %ebx, %edi
21841+ movl 0x500+des_SPtrans(%edx),%ebx
21842+ xorl %ebx, %edi
21843+
21844+
21845+ movl 112(%ebp), %eax
21846+ xorl %ebx, %ebx
21847+ movl 116(%ebp), %edx
21848+ xorl %edi, %eax
21849+ xorl %edi, %edx
21850+ andl $0xfcfcfcfc, %eax
21851+ andl $0xcfcfcfcf, %edx
21852+ movb %al, %bl
21853+ movb %ah, %cl
21854+ rorl $4, %edx
21855+ movl des_SPtrans(%ebx),%ebp
21856+ movb %dl, %bl
21857+ xorl %ebp, %esi
21858+ movl 0x200+des_SPtrans(%ecx),%ebp
21859+ xorl %ebp, %esi
21860+ movb %dh, %cl
21861+ shrl $16, %eax
21862+ movl 0x100+des_SPtrans(%ebx),%ebp
21863+ xorl %ebp, %esi
21864+ movb %ah, %bl
21865+ shrl $16, %edx
21866+ movl 0x300+des_SPtrans(%ecx),%ebp
21867+ xorl %ebp, %esi
21868+ movl 24(%esp), %ebp
21869+ movb %dh, %cl
21870+ andl $0xff, %eax
21871+ andl $0xff, %edx
21872+ movl 0x600+des_SPtrans(%ebx),%ebx
21873+ xorl %ebx, %esi
21874+ movl 0x700+des_SPtrans(%ecx),%ebx
21875+ xorl %ebx, %esi
21876+ movl 0x400+des_SPtrans(%eax),%ebx
21877+ xorl %ebx, %esi
21878+ movl 0x500+des_SPtrans(%edx),%ebx
21879+ xorl %ebx, %esi
21880+
21881+
21882+ movl 104(%ebp), %eax
21883+ xorl %ebx, %ebx
21884+ movl 108(%ebp), %edx
21885+ xorl %esi, %eax
21886+ xorl %esi, %edx
21887+ andl $0xfcfcfcfc, %eax
21888+ andl $0xcfcfcfcf, %edx
21889+ movb %al, %bl
21890+ movb %ah, %cl
21891+ rorl $4, %edx
21892+ movl des_SPtrans(%ebx),%ebp
21893+ movb %dl, %bl
21894+ xorl %ebp, %edi
21895+ movl 0x200+des_SPtrans(%ecx),%ebp
21896+ xorl %ebp, %edi
21897+ movb %dh, %cl
21898+ shrl $16, %eax
21899+ movl 0x100+des_SPtrans(%ebx),%ebp
21900+ xorl %ebp, %edi
21901+ movb %ah, %bl
21902+ shrl $16, %edx
21903+ movl 0x300+des_SPtrans(%ecx),%ebp
21904+ xorl %ebp, %edi
21905+ movl 24(%esp), %ebp
21906+ movb %dh, %cl
21907+ andl $0xff, %eax
21908+ andl $0xff, %edx
21909+ movl 0x600+des_SPtrans(%ebx),%ebx
21910+ xorl %ebx, %edi
21911+ movl 0x700+des_SPtrans(%ecx),%ebx
21912+ xorl %ebx, %edi
21913+ movl 0x400+des_SPtrans(%eax),%ebx
21914+ xorl %ebx, %edi
21915+ movl 0x500+des_SPtrans(%edx),%ebx
21916+ xorl %ebx, %edi
21917+
21918+
21919+ movl 96(%ebp), %eax
21920+ xorl %ebx, %ebx
21921+ movl 100(%ebp), %edx
21922+ xorl %edi, %eax
21923+ xorl %edi, %edx
21924+ andl $0xfcfcfcfc, %eax
21925+ andl $0xcfcfcfcf, %edx
21926+ movb %al, %bl
21927+ movb %ah, %cl
21928+ rorl $4, %edx
21929+ movl des_SPtrans(%ebx),%ebp
21930+ movb %dl, %bl
21931+ xorl %ebp, %esi
21932+ movl 0x200+des_SPtrans(%ecx),%ebp
21933+ xorl %ebp, %esi
21934+ movb %dh, %cl
21935+ shrl $16, %eax
21936+ movl 0x100+des_SPtrans(%ebx),%ebp
21937+ xorl %ebp, %esi
21938+ movb %ah, %bl
21939+ shrl $16, %edx
21940+ movl 0x300+des_SPtrans(%ecx),%ebp
21941+ xorl %ebp, %esi
21942+ movl 24(%esp), %ebp
21943+ movb %dh, %cl
21944+ andl $0xff, %eax
21945+ andl $0xff, %edx
21946+ movl 0x600+des_SPtrans(%ebx),%ebx
21947+ xorl %ebx, %esi
21948+ movl 0x700+des_SPtrans(%ecx),%ebx
21949+ xorl %ebx, %esi
21950+ movl 0x400+des_SPtrans(%eax),%ebx
21951+ xorl %ebx, %esi
21952+ movl 0x500+des_SPtrans(%edx),%ebx
21953+ xorl %ebx, %esi
21954+
21955+
21956+ movl 88(%ebp), %eax
21957+ xorl %ebx, %ebx
21958+ movl 92(%ebp), %edx
21959+ xorl %esi, %eax
21960+ xorl %esi, %edx
21961+ andl $0xfcfcfcfc, %eax
21962+ andl $0xcfcfcfcf, %edx
21963+ movb %al, %bl
21964+ movb %ah, %cl
21965+ rorl $4, %edx
21966+ movl des_SPtrans(%ebx),%ebp
21967+ movb %dl, %bl
21968+ xorl %ebp, %edi
21969+ movl 0x200+des_SPtrans(%ecx),%ebp
21970+ xorl %ebp, %edi
21971+ movb %dh, %cl
21972+ shrl $16, %eax
21973+ movl 0x100+des_SPtrans(%ebx),%ebp
21974+ xorl %ebp, %edi
21975+ movb %ah, %bl
21976+ shrl $16, %edx
21977+ movl 0x300+des_SPtrans(%ecx),%ebp
21978+ xorl %ebp, %edi
21979+ movl 24(%esp), %ebp
21980+ movb %dh, %cl
21981+ andl $0xff, %eax
21982+ andl $0xff, %edx
21983+ movl 0x600+des_SPtrans(%ebx),%ebx
21984+ xorl %ebx, %edi
21985+ movl 0x700+des_SPtrans(%ecx),%ebx
21986+ xorl %ebx, %edi
21987+ movl 0x400+des_SPtrans(%eax),%ebx
21988+ xorl %ebx, %edi
21989+ movl 0x500+des_SPtrans(%edx),%ebx
21990+ xorl %ebx, %edi
21991+
21992+
21993+ movl 80(%ebp), %eax
21994+ xorl %ebx, %ebx
21995+ movl 84(%ebp), %edx
21996+ xorl %edi, %eax
21997+ xorl %edi, %edx
21998+ andl $0xfcfcfcfc, %eax
21999+ andl $0xcfcfcfcf, %edx
22000+ movb %al, %bl
22001+ movb %ah, %cl
22002+ rorl $4, %edx
22003+ movl des_SPtrans(%ebx),%ebp
22004+ movb %dl, %bl
22005+ xorl %ebp, %esi
22006+ movl 0x200+des_SPtrans(%ecx),%ebp
22007+ xorl %ebp, %esi
22008+ movb %dh, %cl
22009+ shrl $16, %eax
22010+ movl 0x100+des_SPtrans(%ebx),%ebp
22011+ xorl %ebp, %esi
22012+ movb %ah, %bl
22013+ shrl $16, %edx
22014+ movl 0x300+des_SPtrans(%ecx),%ebp
22015+ xorl %ebp, %esi
22016+ movl 24(%esp), %ebp
22017+ movb %dh, %cl
22018+ andl $0xff, %eax
22019+ andl $0xff, %edx
22020+ movl 0x600+des_SPtrans(%ebx),%ebx
22021+ xorl %ebx, %esi
22022+ movl 0x700+des_SPtrans(%ecx),%ebx
22023+ xorl %ebx, %esi
22024+ movl 0x400+des_SPtrans(%eax),%ebx
22025+ xorl %ebx, %esi
22026+ movl 0x500+des_SPtrans(%edx),%ebx
22027+ xorl %ebx, %esi
22028+
22029+
22030+ movl 72(%ebp), %eax
22031+ xorl %ebx, %ebx
22032+ movl 76(%ebp), %edx
22033+ xorl %esi, %eax
22034+ xorl %esi, %edx
22035+ andl $0xfcfcfcfc, %eax
22036+ andl $0xcfcfcfcf, %edx
22037+ movb %al, %bl
22038+ movb %ah, %cl
22039+ rorl $4, %edx
22040+ movl des_SPtrans(%ebx),%ebp
22041+ movb %dl, %bl
22042+ xorl %ebp, %edi
22043+ movl 0x200+des_SPtrans(%ecx),%ebp
22044+ xorl %ebp, %edi
22045+ movb %dh, %cl
22046+ shrl $16, %eax
22047+ movl 0x100+des_SPtrans(%ebx),%ebp
22048+ xorl %ebp, %edi
22049+ movb %ah, %bl
22050+ shrl $16, %edx
22051+ movl 0x300+des_SPtrans(%ecx),%ebp
22052+ xorl %ebp, %edi
22053+ movl 24(%esp), %ebp
22054+ movb %dh, %cl
22055+ andl $0xff, %eax
22056+ andl $0xff, %edx
22057+ movl 0x600+des_SPtrans(%ebx),%ebx
22058+ xorl %ebx, %edi
22059+ movl 0x700+des_SPtrans(%ecx),%ebx
22060+ xorl %ebx, %edi
22061+ movl 0x400+des_SPtrans(%eax),%ebx
22062+ xorl %ebx, %edi
22063+ movl 0x500+des_SPtrans(%edx),%ebx
22064+ xorl %ebx, %edi
22065+
22066+
22067+ movl 64(%ebp), %eax
22068+ xorl %ebx, %ebx
22069+ movl 68(%ebp), %edx
22070+ xorl %edi, %eax
22071+ xorl %edi, %edx
22072+ andl $0xfcfcfcfc, %eax
22073+ andl $0xcfcfcfcf, %edx
22074+ movb %al, %bl
22075+ movb %ah, %cl
22076+ rorl $4, %edx
22077+ movl des_SPtrans(%ebx),%ebp
22078+ movb %dl, %bl
22079+ xorl %ebp, %esi
22080+ movl 0x200+des_SPtrans(%ecx),%ebp
22081+ xorl %ebp, %esi
22082+ movb %dh, %cl
22083+ shrl $16, %eax
22084+ movl 0x100+des_SPtrans(%ebx),%ebp
22085+ xorl %ebp, %esi
22086+ movb %ah, %bl
22087+ shrl $16, %edx
22088+ movl 0x300+des_SPtrans(%ecx),%ebp
22089+ xorl %ebp, %esi
22090+ movl 24(%esp), %ebp
22091+ movb %dh, %cl
22092+ andl $0xff, %eax
22093+ andl $0xff, %edx
22094+ movl 0x600+des_SPtrans(%ebx),%ebx
22095+ xorl %ebx, %esi
22096+ movl 0x700+des_SPtrans(%ecx),%ebx
22097+ xorl %ebx, %esi
22098+ movl 0x400+des_SPtrans(%eax),%ebx
22099+ xorl %ebx, %esi
22100+ movl 0x500+des_SPtrans(%edx),%ebx
22101+ xorl %ebx, %esi
22102+
22103+
22104+ movl 56(%ebp), %eax
22105+ xorl %ebx, %ebx
22106+ movl 60(%ebp), %edx
22107+ xorl %esi, %eax
22108+ xorl %esi, %edx
22109+ andl $0xfcfcfcfc, %eax
22110+ andl $0xcfcfcfcf, %edx
22111+ movb %al, %bl
22112+ movb %ah, %cl
22113+ rorl $4, %edx
22114+ movl des_SPtrans(%ebx),%ebp
22115+ movb %dl, %bl
22116+ xorl %ebp, %edi
22117+ movl 0x200+des_SPtrans(%ecx),%ebp
22118+ xorl %ebp, %edi
22119+ movb %dh, %cl
22120+ shrl $16, %eax
22121+ movl 0x100+des_SPtrans(%ebx),%ebp
22122+ xorl %ebp, %edi
22123+ movb %ah, %bl
22124+ shrl $16, %edx
22125+ movl 0x300+des_SPtrans(%ecx),%ebp
22126+ xorl %ebp, %edi
22127+ movl 24(%esp), %ebp
22128+ movb %dh, %cl
22129+ andl $0xff, %eax
22130+ andl $0xff, %edx
22131+ movl 0x600+des_SPtrans(%ebx),%ebx
22132+ xorl %ebx, %edi
22133+ movl 0x700+des_SPtrans(%ecx),%ebx
22134+ xorl %ebx, %edi
22135+ movl 0x400+des_SPtrans(%eax),%ebx
22136+ xorl %ebx, %edi
22137+ movl 0x500+des_SPtrans(%edx),%ebx
22138+ xorl %ebx, %edi
22139+
22140+
22141+ movl 48(%ebp), %eax
22142+ xorl %ebx, %ebx
22143+ movl 52(%ebp), %edx
22144+ xorl %edi, %eax
22145+ xorl %edi, %edx
22146+ andl $0xfcfcfcfc, %eax
22147+ andl $0xcfcfcfcf, %edx
22148+ movb %al, %bl
22149+ movb %ah, %cl
22150+ rorl $4, %edx
22151+ movl des_SPtrans(%ebx),%ebp
22152+ movb %dl, %bl
22153+ xorl %ebp, %esi
22154+ movl 0x200+des_SPtrans(%ecx),%ebp
22155+ xorl %ebp, %esi
22156+ movb %dh, %cl
22157+ shrl $16, %eax
22158+ movl 0x100+des_SPtrans(%ebx),%ebp
22159+ xorl %ebp, %esi
22160+ movb %ah, %bl
22161+ shrl $16, %edx
22162+ movl 0x300+des_SPtrans(%ecx),%ebp
22163+ xorl %ebp, %esi
22164+ movl 24(%esp), %ebp
22165+ movb %dh, %cl
22166+ andl $0xff, %eax
22167+ andl $0xff, %edx
22168+ movl 0x600+des_SPtrans(%ebx),%ebx
22169+ xorl %ebx, %esi
22170+ movl 0x700+des_SPtrans(%ecx),%ebx
22171+ xorl %ebx, %esi
22172+ movl 0x400+des_SPtrans(%eax),%ebx
22173+ xorl %ebx, %esi
22174+ movl 0x500+des_SPtrans(%edx),%ebx
22175+ xorl %ebx, %esi
22176+
22177+
22178+ movl 40(%ebp), %eax
22179+ xorl %ebx, %ebx
22180+ movl 44(%ebp), %edx
22181+ xorl %esi, %eax
22182+ xorl %esi, %edx
22183+ andl $0xfcfcfcfc, %eax
22184+ andl $0xcfcfcfcf, %edx
22185+ movb %al, %bl
22186+ movb %ah, %cl
22187+ rorl $4, %edx
22188+ movl des_SPtrans(%ebx),%ebp
22189+ movb %dl, %bl
22190+ xorl %ebp, %edi
22191+ movl 0x200+des_SPtrans(%ecx),%ebp
22192+ xorl %ebp, %edi
22193+ movb %dh, %cl
22194+ shrl $16, %eax
22195+ movl 0x100+des_SPtrans(%ebx),%ebp
22196+ xorl %ebp, %edi
22197+ movb %ah, %bl
22198+ shrl $16, %edx
22199+ movl 0x300+des_SPtrans(%ecx),%ebp
22200+ xorl %ebp, %edi
22201+ movl 24(%esp), %ebp
22202+ movb %dh, %cl
22203+ andl $0xff, %eax
22204+ andl $0xff, %edx
22205+ movl 0x600+des_SPtrans(%ebx),%ebx
22206+ xorl %ebx, %edi
22207+ movl 0x700+des_SPtrans(%ecx),%ebx
22208+ xorl %ebx, %edi
22209+ movl 0x400+des_SPtrans(%eax),%ebx
22210+ xorl %ebx, %edi
22211+ movl 0x500+des_SPtrans(%edx),%ebx
22212+ xorl %ebx, %edi
22213+
22214+
22215+ movl 32(%ebp), %eax
22216+ xorl %ebx, %ebx
22217+ movl 36(%ebp), %edx
22218+ xorl %edi, %eax
22219+ xorl %edi, %edx
22220+ andl $0xfcfcfcfc, %eax
22221+ andl $0xcfcfcfcf, %edx
22222+ movb %al, %bl
22223+ movb %ah, %cl
22224+ rorl $4, %edx
22225+ movl des_SPtrans(%ebx),%ebp
22226+ movb %dl, %bl
22227+ xorl %ebp, %esi
22228+ movl 0x200+des_SPtrans(%ecx),%ebp
22229+ xorl %ebp, %esi
22230+ movb %dh, %cl
22231+ shrl $16, %eax
22232+ movl 0x100+des_SPtrans(%ebx),%ebp
22233+ xorl %ebp, %esi
22234+ movb %ah, %bl
22235+ shrl $16, %edx
22236+ movl 0x300+des_SPtrans(%ecx),%ebp
22237+ xorl %ebp, %esi
22238+ movl 24(%esp), %ebp
22239+ movb %dh, %cl
22240+ andl $0xff, %eax
22241+ andl $0xff, %edx
22242+ movl 0x600+des_SPtrans(%ebx),%ebx
22243+ xorl %ebx, %esi
22244+ movl 0x700+des_SPtrans(%ecx),%ebx
22245+ xorl %ebx, %esi
22246+ movl 0x400+des_SPtrans(%eax),%ebx
22247+ xorl %ebx, %esi
22248+ movl 0x500+des_SPtrans(%edx),%ebx
22249+ xorl %ebx, %esi
22250+
22251+
22252+ movl 24(%ebp), %eax
22253+ xorl %ebx, %ebx
22254+ movl 28(%ebp), %edx
22255+ xorl %esi, %eax
22256+ xorl %esi, %edx
22257+ andl $0xfcfcfcfc, %eax
22258+ andl $0xcfcfcfcf, %edx
22259+ movb %al, %bl
22260+ movb %ah, %cl
22261+ rorl $4, %edx
22262+ movl des_SPtrans(%ebx),%ebp
22263+ movb %dl, %bl
22264+ xorl %ebp, %edi
22265+ movl 0x200+des_SPtrans(%ecx),%ebp
22266+ xorl %ebp, %edi
22267+ movb %dh, %cl
22268+ shrl $16, %eax
22269+ movl 0x100+des_SPtrans(%ebx),%ebp
22270+ xorl %ebp, %edi
22271+ movb %ah, %bl
22272+ shrl $16, %edx
22273+ movl 0x300+des_SPtrans(%ecx),%ebp
22274+ xorl %ebp, %edi
22275+ movl 24(%esp), %ebp
22276+ movb %dh, %cl
22277+ andl $0xff, %eax
22278+ andl $0xff, %edx
22279+ movl 0x600+des_SPtrans(%ebx),%ebx
22280+ xorl %ebx, %edi
22281+ movl 0x700+des_SPtrans(%ecx),%ebx
22282+ xorl %ebx, %edi
22283+ movl 0x400+des_SPtrans(%eax),%ebx
22284+ xorl %ebx, %edi
22285+ movl 0x500+des_SPtrans(%edx),%ebx
22286+ xorl %ebx, %edi
22287+
22288+
22289+ movl 16(%ebp), %eax
22290+ xorl %ebx, %ebx
22291+ movl 20(%ebp), %edx
22292+ xorl %edi, %eax
22293+ xorl %edi, %edx
22294+ andl $0xfcfcfcfc, %eax
22295+ andl $0xcfcfcfcf, %edx
22296+ movb %al, %bl
22297+ movb %ah, %cl
22298+ rorl $4, %edx
22299+ movl des_SPtrans(%ebx),%ebp
22300+ movb %dl, %bl
22301+ xorl %ebp, %esi
22302+ movl 0x200+des_SPtrans(%ecx),%ebp
22303+ xorl %ebp, %esi
22304+ movb %dh, %cl
22305+ shrl $16, %eax
22306+ movl 0x100+des_SPtrans(%ebx),%ebp
22307+ xorl %ebp, %esi
22308+ movb %ah, %bl
22309+ shrl $16, %edx
22310+ movl 0x300+des_SPtrans(%ecx),%ebp
22311+ xorl %ebp, %esi
22312+ movl 24(%esp), %ebp
22313+ movb %dh, %cl
22314+ andl $0xff, %eax
22315+ andl $0xff, %edx
22316+ movl 0x600+des_SPtrans(%ebx),%ebx
22317+ xorl %ebx, %esi
22318+ movl 0x700+des_SPtrans(%ecx),%ebx
22319+ xorl %ebx, %esi
22320+ movl 0x400+des_SPtrans(%eax),%ebx
22321+ xorl %ebx, %esi
22322+ movl 0x500+des_SPtrans(%edx),%ebx
22323+ xorl %ebx, %esi
22324+
22325+
22326+ movl 8(%ebp), %eax
22327+ xorl %ebx, %ebx
22328+ movl 12(%ebp), %edx
22329+ xorl %esi, %eax
22330+ xorl %esi, %edx
22331+ andl $0xfcfcfcfc, %eax
22332+ andl $0xcfcfcfcf, %edx
22333+ movb %al, %bl
22334+ movb %ah, %cl
22335+ rorl $4, %edx
22336+ movl des_SPtrans(%ebx),%ebp
22337+ movb %dl, %bl
22338+ xorl %ebp, %edi
22339+ movl 0x200+des_SPtrans(%ecx),%ebp
22340+ xorl %ebp, %edi
22341+ movb %dh, %cl
22342+ shrl $16, %eax
22343+ movl 0x100+des_SPtrans(%ebx),%ebp
22344+ xorl %ebp, %edi
22345+ movb %ah, %bl
22346+ shrl $16, %edx
22347+ movl 0x300+des_SPtrans(%ecx),%ebp
22348+ xorl %ebp, %edi
22349+ movl 24(%esp), %ebp
22350+ movb %dh, %cl
22351+ andl $0xff, %eax
22352+ andl $0xff, %edx
22353+ movl 0x600+des_SPtrans(%ebx),%ebx
22354+ xorl %ebx, %edi
22355+ movl 0x700+des_SPtrans(%ecx),%ebx
22356+ xorl %ebx, %edi
22357+ movl 0x400+des_SPtrans(%eax),%ebx
22358+ xorl %ebx, %edi
22359+ movl 0x500+des_SPtrans(%edx),%ebx
22360+ xorl %ebx, %edi
22361+
22362+
22363+ movl (%ebp), %eax
22364+ xorl %ebx, %ebx
22365+ movl 4(%ebp), %edx
22366+ xorl %edi, %eax
22367+ xorl %edi, %edx
22368+ andl $0xfcfcfcfc, %eax
22369+ andl $0xcfcfcfcf, %edx
22370+ movb %al, %bl
22371+ movb %ah, %cl
22372+ rorl $4, %edx
22373+ movl des_SPtrans(%ebx),%ebp
22374+ movb %dl, %bl
22375+ xorl %ebp, %esi
22376+ movl 0x200+des_SPtrans(%ecx),%ebp
22377+ xorl %ebp, %esi
22378+ movb %dh, %cl
22379+ shrl $16, %eax
22380+ movl 0x100+des_SPtrans(%ebx),%ebp
22381+ xorl %ebp, %esi
22382+ movb %ah, %bl
22383+ shrl $16, %edx
22384+ movl 0x300+des_SPtrans(%ecx),%ebp
22385+ xorl %ebp, %esi
22386+ movl 24(%esp), %ebp
22387+ movb %dh, %cl
22388+ andl $0xff, %eax
22389+ andl $0xff, %edx
22390+ movl 0x600+des_SPtrans(%ebx),%ebx
22391+ xorl %ebx, %esi
22392+ movl 0x700+des_SPtrans(%ecx),%ebx
22393+ xorl %ebx, %esi
22394+ movl 0x400+des_SPtrans(%eax),%ebx
22395+ xorl %ebx, %esi
22396+ movl 0x500+des_SPtrans(%edx),%ebx
22397+ xorl %ebx, %esi
22398+.L003end:
22399+
22400+
22401+ rorl $3, %edi
22402+ movl 20(%esp), %eax
22403+ rorl $3, %esi
22404+ movl %edi, (%eax)
22405+ movl %esi, 4(%eax)
22406+ popl %ebp
22407+ popl %ebx
22408+ popl %edi
22409+ popl %esi
22410+ ret
22411+.des_encrypt2_end:
22412+ .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
22413+.ident "desasm.pl"
22414+.text
22415+ .align 16
22416+.globl des_encrypt3
22417+ .type des_encrypt3 , @function
22418+des_encrypt3:
22419+ pushl %ebx
22420+ movl 8(%esp), %ebx
22421+ pushl %ebp
22422+ pushl %esi
22423+ pushl %edi
22424+
22425+
22426+ movl (%ebx), %edi
22427+ movl 4(%ebx), %esi
22428+ subl $12, %esp
22429+
22430+
22431+ roll $4, %edi
22432+ movl %edi, %edx
22433+ xorl %esi, %edi
22434+ andl $0xf0f0f0f0, %edi
22435+ xorl %edi, %edx
22436+ xorl %edi, %esi
22437+
22438+ roll $20, %esi
22439+ movl %esi, %edi
22440+ xorl %edx, %esi
22441+ andl $0xfff0000f, %esi
22442+ xorl %esi, %edi
22443+ xorl %esi, %edx
22444+
22445+ roll $14, %edi
22446+ movl %edi, %esi
22447+ xorl %edx, %edi
22448+ andl $0x33333333, %edi
22449+ xorl %edi, %esi
22450+ xorl %edi, %edx
22451+
22452+ roll $22, %edx
22453+ movl %edx, %edi
22454+ xorl %esi, %edx
22455+ andl $0x03fc03fc, %edx
22456+ xorl %edx, %edi
22457+ xorl %edx, %esi
22458+
22459+ roll $9, %edi
22460+ movl %edi, %edx
22461+ xorl %esi, %edi
22462+ andl $0xaaaaaaaa, %edi
22463+ xorl %edi, %edx
22464+ xorl %edi, %esi
22465+
22466+ rorl $3, %edx
22467+ rorl $2, %esi
22468+ movl %esi, 4(%ebx)
22469+ movl 36(%esp), %eax
22470+ movl %edx, (%ebx)
22471+ movl 40(%esp), %edi
22472+ movl 44(%esp), %esi
22473+ movl $1, 8(%esp)
22474+ movl %eax, 4(%esp)
22475+ movl %ebx, (%esp)
22476+ call des_encrypt2
22477+ movl $0, 8(%esp)
22478+ movl %edi, 4(%esp)
22479+ movl %ebx, (%esp)
22480+ call des_encrypt2
22481+ movl $1, 8(%esp)
22482+ movl %esi, 4(%esp)
22483+ movl %ebx, (%esp)
22484+ call des_encrypt2
22485+ addl $12, %esp
22486+ movl (%ebx), %edi
22487+ movl 4(%ebx), %esi
22488+
22489+
22490+ roll $2, %esi
22491+ roll $3, %edi
22492+ movl %edi, %eax
22493+ xorl %esi, %edi
22494+ andl $0xaaaaaaaa, %edi
22495+ xorl %edi, %eax
22496+ xorl %edi, %esi
22497+
22498+ roll $23, %eax
22499+ movl %eax, %edi
22500+ xorl %esi, %eax
22501+ andl $0x03fc03fc, %eax
22502+ xorl %eax, %edi
22503+ xorl %eax, %esi
22504+
22505+ roll $10, %edi
22506+ movl %edi, %eax
22507+ xorl %esi, %edi
22508+ andl $0x33333333, %edi
22509+ xorl %edi, %eax
22510+ xorl %edi, %esi
22511+
22512+ roll $18, %esi
22513+ movl %esi, %edi
22514+ xorl %eax, %esi
22515+ andl $0xfff0000f, %esi
22516+ xorl %esi, %edi
22517+ xorl %esi, %eax
22518+
22519+ roll $12, %edi
22520+ movl %edi, %esi
22521+ xorl %eax, %edi
22522+ andl $0xf0f0f0f0, %edi
22523+ xorl %edi, %esi
22524+ xorl %edi, %eax
22525+
22526+ rorl $4, %eax
22527+ movl %eax, (%ebx)
22528+ movl %esi, 4(%ebx)
22529+ popl %edi
22530+ popl %esi
22531+ popl %ebp
22532+ popl %ebx
22533+ ret
22534+.des_encrypt3_end:
22535+ .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
22536+.ident "desasm.pl"
22537+.text
22538+ .align 16
22539+.globl des_decrypt3
22540+ .type des_decrypt3 , @function
22541+des_decrypt3:
22542+ pushl %ebx
22543+ movl 8(%esp), %ebx
22544+ pushl %ebp
22545+ pushl %esi
22546+ pushl %edi
22547+
22548+
22549+ movl (%ebx), %edi
22550+ movl 4(%ebx), %esi
22551+ subl $12, %esp
22552+
22553+
22554+ roll $4, %edi
22555+ movl %edi, %edx
22556+ xorl %esi, %edi
22557+ andl $0xf0f0f0f0, %edi
22558+ xorl %edi, %edx
22559+ xorl %edi, %esi
22560+
22561+ roll $20, %esi
22562+ movl %esi, %edi
22563+ xorl %edx, %esi
22564+ andl $0xfff0000f, %esi
22565+ xorl %esi, %edi
22566+ xorl %esi, %edx
22567+
22568+ roll $14, %edi
22569+ movl %edi, %esi
22570+ xorl %edx, %edi
22571+ andl $0x33333333, %edi
22572+ xorl %edi, %esi
22573+ xorl %edi, %edx
22574+
22575+ roll $22, %edx
22576+ movl %edx, %edi
22577+ xorl %esi, %edx
22578+ andl $0x03fc03fc, %edx
22579+ xorl %edx, %edi
22580+ xorl %edx, %esi
22581+
22582+ roll $9, %edi
22583+ movl %edi, %edx
22584+ xorl %esi, %edi
22585+ andl $0xaaaaaaaa, %edi
22586+ xorl %edi, %edx
22587+ xorl %edi, %esi
22588+
22589+ rorl $3, %edx
22590+ rorl $2, %esi
22591+ movl %esi, 4(%ebx)
22592+ movl 36(%esp), %esi
22593+ movl %edx, (%ebx)
22594+ movl 40(%esp), %edi
22595+ movl 44(%esp), %eax
22596+ movl $0, 8(%esp)
22597+ movl %eax, 4(%esp)
22598+ movl %ebx, (%esp)
22599+ call des_encrypt2
22600+ movl $1, 8(%esp)
22601+ movl %edi, 4(%esp)
22602+ movl %ebx, (%esp)
22603+ call des_encrypt2
22604+ movl $0, 8(%esp)
22605+ movl %esi, 4(%esp)
22606+ movl %ebx, (%esp)
22607+ call des_encrypt2
22608+ addl $12, %esp
22609+ movl (%ebx), %edi
22610+ movl 4(%ebx), %esi
22611+
22612+
22613+ roll $2, %esi
22614+ roll $3, %edi
22615+ movl %edi, %eax
22616+ xorl %esi, %edi
22617+ andl $0xaaaaaaaa, %edi
22618+ xorl %edi, %eax
22619+ xorl %edi, %esi
22620+
22621+ roll $23, %eax
22622+ movl %eax, %edi
22623+ xorl %esi, %eax
22624+ andl $0x03fc03fc, %eax
22625+ xorl %eax, %edi
22626+ xorl %eax, %esi
22627+
22628+ roll $10, %edi
22629+ movl %edi, %eax
22630+ xorl %esi, %edi
22631+ andl $0x33333333, %edi
22632+ xorl %edi, %eax
22633+ xorl %edi, %esi
22634+
22635+ roll $18, %esi
22636+ movl %esi, %edi
22637+ xorl %eax, %esi
22638+ andl $0xfff0000f, %esi
22639+ xorl %esi, %edi
22640+ xorl %esi, %eax
22641+
22642+ roll $12, %edi
22643+ movl %edi, %esi
22644+ xorl %eax, %edi
22645+ andl $0xf0f0f0f0, %edi
22646+ xorl %edi, %esi
22647+ xorl %edi, %eax
22648+
22649+ rorl $4, %eax
22650+ movl %eax, (%ebx)
22651+ movl %esi, 4(%ebx)
22652+ popl %edi
22653+ popl %esi
22654+ popl %ebp
22655+ popl %ebx
22656+ ret
22657+.des_decrypt3_end:
22658+ .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
22659+.ident "desasm.pl"
22660+.text
22661+ .align 16
22662+.globl des_ncbc_encrypt
22663+ .type des_ncbc_encrypt , @function
22664+des_ncbc_encrypt:
22665+
22666+ pushl %ebp
22667+ pushl %ebx
22668+ pushl %esi
22669+ pushl %edi
22670+ movl 28(%esp), %ebp
22671+
22672+ movl 36(%esp), %ebx
22673+ movl (%ebx), %esi
22674+ movl 4(%ebx), %edi
22675+ pushl %edi
22676+ pushl %esi
22677+ pushl %edi
22678+ pushl %esi
22679+ movl %esp, %ebx
22680+ movl 36(%esp), %esi
22681+ movl 40(%esp), %edi
22682+
22683+ movl 56(%esp), %ecx
22684+
22685+ pushl %ecx
22686+
22687+ movl 52(%esp), %eax
22688+ pushl %eax
22689+ pushl %ebx
22690+ cmpl $0, %ecx
22691+ jz .L004decrypt
22692+ andl $4294967288, %ebp
22693+ movl 12(%esp), %eax
22694+ movl 16(%esp), %ebx
22695+ jz .L005encrypt_finish
22696+.L006encrypt_loop:
22697+ movl (%esi), %ecx
22698+ movl 4(%esi), %edx
22699+ xorl %ecx, %eax
22700+ xorl %edx, %ebx
22701+ movl %eax, 12(%esp)
22702+ movl %ebx, 16(%esp)
22703+ call des_encrypt
22704+ movl 12(%esp), %eax
22705+ movl 16(%esp), %ebx
22706+ movl %eax, (%edi)
22707+ movl %ebx, 4(%edi)
22708+ addl $8, %esi
22709+ addl $8, %edi
22710+ subl $8, %ebp
22711+ jnz .L006encrypt_loop
22712+.L005encrypt_finish:
22713+ movl 56(%esp), %ebp
22714+ andl $7, %ebp
22715+ jz .L007finish
22716+ xorl %ecx, %ecx
22717+ xorl %edx, %edx
22718+ movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
22719+ jmp *%ebp
22720+.L009ej7:
22721+ movb 6(%esi), %dh
22722+ sall $8, %edx
22723+.L010ej6:
22724+ movb 5(%esi), %dh
22725+.L011ej5:
22726+ movb 4(%esi), %dl
22727+.L012ej4:
22728+ movl (%esi), %ecx
22729+ jmp .L013ejend
22730+.L014ej3:
22731+ movb 2(%esi), %ch
22732+ sall $8, %ecx
22733+.L015ej2:
22734+ movb 1(%esi), %ch
22735+.L016ej1:
22736+ movb (%esi), %cl
22737+.L013ejend:
22738+ xorl %ecx, %eax
22739+ xorl %edx, %ebx
22740+ movl %eax, 12(%esp)
22741+ movl %ebx, 16(%esp)
22742+ call des_encrypt
22743+ movl 12(%esp), %eax
22744+ movl 16(%esp), %ebx
22745+ movl %eax, (%edi)
22746+ movl %ebx, 4(%edi)
22747+ jmp .L007finish
22748+.align 16
22749+.L004decrypt:
22750+ andl $4294967288, %ebp
22751+ movl 20(%esp), %eax
22752+ movl 24(%esp), %ebx
22753+ jz .L017decrypt_finish
22754+.L018decrypt_loop:
22755+ movl (%esi), %eax
22756+ movl 4(%esi), %ebx
22757+ movl %eax, 12(%esp)
22758+ movl %ebx, 16(%esp)
22759+ call des_encrypt
22760+ movl 12(%esp), %eax
22761+ movl 16(%esp), %ebx
22762+ movl 20(%esp), %ecx
22763+ movl 24(%esp), %edx
22764+ xorl %eax, %ecx
22765+ xorl %ebx, %edx
22766+ movl (%esi), %eax
22767+ movl 4(%esi), %ebx
22768+ movl %ecx, (%edi)
22769+ movl %edx, 4(%edi)
22770+ movl %eax, 20(%esp)
22771+ movl %ebx, 24(%esp)
22772+ addl $8, %esi
22773+ addl $8, %edi
22774+ subl $8, %ebp
22775+ jnz .L018decrypt_loop
22776+.L017decrypt_finish:
22777+ movl 56(%esp), %ebp
22778+ andl $7, %ebp
22779+ jz .L007finish
22780+ movl (%esi), %eax
22781+ movl 4(%esi), %ebx
22782+ movl %eax, 12(%esp)
22783+ movl %ebx, 16(%esp)
22784+ call des_encrypt
22785+ movl 12(%esp), %eax
22786+ movl 16(%esp), %ebx
22787+ movl 20(%esp), %ecx
22788+ movl 24(%esp), %edx
22789+ xorl %eax, %ecx
22790+ xorl %ebx, %edx
22791+ movl (%esi), %eax
22792+ movl 4(%esi), %ebx
22793+.L019dj7:
22794+ rorl $16, %edx
22795+ movb %dl, 6(%edi)
22796+ shrl $16, %edx
22797+.L020dj6:
22798+ movb %dh, 5(%edi)
22799+.L021dj5:
22800+ movb %dl, 4(%edi)
22801+.L022dj4:
22802+ movl %ecx, (%edi)
22803+ jmp .L023djend
22804+.L024dj3:
22805+ rorl $16, %ecx
22806+ movb %cl, 2(%edi)
22807+ sall $16, %ecx
22808+.L025dj2:
22809+ movb %ch, 1(%esi)
22810+.L026dj1:
22811+ movb %cl, (%esi)
22812+.L023djend:
22813+ jmp .L007finish
22814+.align 16
22815+.L007finish:
22816+ movl 64(%esp), %ecx
22817+ addl $28, %esp
22818+ movl %eax, (%ecx)
22819+ movl %ebx, 4(%ecx)
22820+ popl %edi
22821+ popl %esi
22822+ popl %ebx
22823+ popl %ebp
22824+ ret
22825+.align 16
22826+.L008cbc_enc_jmp_table:
22827+ .long 0
22828+ .long .L016ej1
22829+ .long .L015ej2
22830+ .long .L014ej3
22831+ .long .L012ej4
22832+ .long .L011ej5
22833+ .long .L010ej6
22834+ .long .L009ej7
22835+.align 16
22836+.L027cbc_dec_jmp_table:
22837+ .long 0
22838+ .long .L026dj1
22839+ .long .L025dj2
22840+ .long .L024dj3
22841+ .long .L022dj4
22842+ .long .L021dj5
22843+ .long .L020dj6
22844+ .long .L019dj7
22845+.des_ncbc_encrypt_end:
22846+ .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
22847+.ident "desasm.pl"
22848+.text
22849+ .align 16
22850+.globl des_ede3_cbc_encrypt
22851+ .type des_ede3_cbc_encrypt , @function
22852+des_ede3_cbc_encrypt:
22853+
22854+ pushl %ebp
22855+ pushl %ebx
22856+ pushl %esi
22857+ pushl %edi
22858+ movl 28(%esp), %ebp
22859+
22860+ movl 44(%esp), %ebx
22861+ movl (%ebx), %esi
22862+ movl 4(%ebx), %edi
22863+ pushl %edi
22864+ pushl %esi
22865+ pushl %edi
22866+ pushl %esi
22867+ movl %esp, %ebx
22868+ movl 36(%esp), %esi
22869+ movl 40(%esp), %edi
22870+
22871+ movl 64(%esp), %ecx
22872+
22873+ movl 56(%esp), %eax
22874+ pushl %eax
22875+
22876+ movl 56(%esp), %eax
22877+ pushl %eax
22878+
22879+ movl 56(%esp), %eax
22880+ pushl %eax
22881+ pushl %ebx
22882+ cmpl $0, %ecx
22883+ jz .L028decrypt
22884+ andl $4294967288, %ebp
22885+ movl 16(%esp), %eax
22886+ movl 20(%esp), %ebx
22887+ jz .L029encrypt_finish
22888+.L030encrypt_loop:
22889+ movl (%esi), %ecx
22890+ movl 4(%esi), %edx
22891+ xorl %ecx, %eax
22892+ xorl %edx, %ebx
22893+ movl %eax, 16(%esp)
22894+ movl %ebx, 20(%esp)
22895+ call des_encrypt3
22896+ movl 16(%esp), %eax
22897+ movl 20(%esp), %ebx
22898+ movl %eax, (%edi)
22899+ movl %ebx, 4(%edi)
22900+ addl $8, %esi
22901+ addl $8, %edi
22902+ subl $8, %ebp
22903+ jnz .L030encrypt_loop
22904+.L029encrypt_finish:
22905+ movl 60(%esp), %ebp
22906+ andl $7, %ebp
22907+ jz .L031finish
22908+ xorl %ecx, %ecx
22909+ xorl %edx, %edx
22910+ movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
22911+ jmp *%ebp
22912+.L033ej7:
22913+ movb 6(%esi), %dh
22914+ sall $8, %edx
22915+.L034ej6:
22916+ movb 5(%esi), %dh
22917+.L035ej5:
22918+ movb 4(%esi), %dl
22919+.L036ej4:
22920+ movl (%esi), %ecx
22921+ jmp .L037ejend
22922+.L038ej3:
22923+ movb 2(%esi), %ch
22924+ sall $8, %ecx
22925+.L039ej2:
22926+ movb 1(%esi), %ch
22927+.L040ej1:
22928+ movb (%esi), %cl
22929+.L037ejend:
22930+ xorl %ecx, %eax
22931+ xorl %edx, %ebx
22932+ movl %eax, 16(%esp)
22933+ movl %ebx, 20(%esp)
22934+ call des_encrypt3
22935+ movl 16(%esp), %eax
22936+ movl 20(%esp), %ebx
22937+ movl %eax, (%edi)
22938+ movl %ebx, 4(%edi)
22939+ jmp .L031finish
22940+.align 16
22941+.L028decrypt:
22942+ andl $4294967288, %ebp
22943+ movl 24(%esp), %eax
22944+ movl 28(%esp), %ebx
22945+ jz .L041decrypt_finish
22946+.L042decrypt_loop:
22947+ movl (%esi), %eax
22948+ movl 4(%esi), %ebx
22949+ movl %eax, 16(%esp)
22950+ movl %ebx, 20(%esp)
22951+ call des_decrypt3
22952+ movl 16(%esp), %eax
22953+ movl 20(%esp), %ebx
22954+ movl 24(%esp), %ecx
22955+ movl 28(%esp), %edx
22956+ xorl %eax, %ecx
22957+ xorl %ebx, %edx
22958+ movl (%esi), %eax
22959+ movl 4(%esi), %ebx
22960+ movl %ecx, (%edi)
22961+ movl %edx, 4(%edi)
22962+ movl %eax, 24(%esp)
22963+ movl %ebx, 28(%esp)
22964+ addl $8, %esi
22965+ addl $8, %edi
22966+ subl $8, %ebp
22967+ jnz .L042decrypt_loop
22968+.L041decrypt_finish:
22969+ movl 60(%esp), %ebp
22970+ andl $7, %ebp
22971+ jz .L031finish
22972+ movl (%esi), %eax
22973+ movl 4(%esi), %ebx
22974+ movl %eax, 16(%esp)
22975+ movl %ebx, 20(%esp)
22976+ call des_decrypt3
22977+ movl 16(%esp), %eax
22978+ movl 20(%esp), %ebx
22979+ movl 24(%esp), %ecx
22980+ movl 28(%esp), %edx
22981+ xorl %eax, %ecx
22982+ xorl %ebx, %edx
22983+ movl (%esi), %eax
22984+ movl 4(%esi), %ebx
22985+.L043dj7:
22986+ rorl $16, %edx
22987+ movb %dl, 6(%edi)
22988+ shrl $16, %edx
22989+.L044dj6:
22990+ movb %dh, 5(%edi)
22991+.L045dj5:
22992+ movb %dl, 4(%edi)
22993+.L046dj4:
22994+ movl %ecx, (%edi)
22995+ jmp .L047djend
22996+.L048dj3:
22997+ rorl $16, %ecx
22998+ movb %cl, 2(%edi)
22999+ sall $16, %ecx
23000+.L049dj2:
23001+ movb %ch, 1(%esi)
23002+.L050dj1:
23003+ movb %cl, (%esi)
23004+.L047djend:
23005+ jmp .L031finish
23006+.align 16
23007+.L031finish:
23008+ movl 76(%esp), %ecx
23009+ addl $32, %esp
23010+ movl %eax, (%ecx)
23011+ movl %ebx, 4(%ecx)
23012+ popl %edi
23013+ popl %esi
23014+ popl %ebx
23015+ popl %ebp
23016+ ret
23017+.align 16
23018+.L032cbc_enc_jmp_table:
23019+ .long 0
23020+ .long .L040ej1
23021+ .long .L039ej2
23022+ .long .L038ej3
23023+ .long .L036ej4
23024+ .long .L035ej5
23025+ .long .L034ej6
23026+ .long .L033ej7
23027+.align 16
23028+.L051cbc_dec_jmp_table:
23029+ .long 0
23030+ .long .L050dj1
23031+ .long .L049dj2
23032+ .long .L048dj3
23033+ .long .L046dj4
23034+ .long .L045dj5
23035+ .long .L044dj6
23036+ .long .L043dj7
23037+.des_ede3_cbc_encrypt_end:
23038+ .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
23039+.ident "desasm.pl"
23040--- /dev/null Tue Mar 11 13:02:56 2003
23041+++ linux/net/ipsec/des/ecb_enc.c Mon Feb 9 13:51:03 2004
23042@@ -0,0 +1,128 @@
23043+/* crypto/des/ecb_enc.c */
23044+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
23045+ * All rights reserved.
23046+ *
23047+ * This package is an SSL implementation written
23048+ * by Eric Young (eay@cryptsoft.com).
23049+ * The implementation was written so as to conform with Netscapes SSL.
23050+ *
23051+ * This library is free for commercial and non-commercial use as long as
23052+ * the following conditions are aheared to. The following conditions
23053+ * apply to all code found in this distribution, be it the RC4, RSA,
23054+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
23055+ * included with this distribution is covered by the same copyright terms
23056+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
23057+ *
23058+ * Copyright remains Eric Young's, and as such any Copyright notices in
23059+ * the code are not to be removed.
23060+ * If this package is used in a product, Eric Young should be given attribution
23061+ * as the author of the parts of the library used.
23062+ * This can be in the form of a textual message at program startup or
23063+ * in documentation (online or textual) provided with the package.
23064+ *
23065+ * Redistribution and use in source and binary forms, with or without
23066+ * modification, are permitted provided that the following conditions
23067+ * are met:
23068+ * 1. Redistributions of source code must retain the copyright
23069+ * notice, this list of conditions and the following disclaimer.
23070+ * 2. Redistributions in binary form must reproduce the above copyright
23071+ * notice, this list of conditions and the following disclaimer in the
23072+ * documentation and/or other materials provided with the distribution.
23073+ * 3. All advertising materials mentioning features or use of this software
23074+ * must display the following acknowledgement:
23075+ * "This product includes cryptographic software written by
23076+ * Eric Young (eay@cryptsoft.com)"
23077+ * The word 'cryptographic' can be left out if the rouines from the library
23078+ * being used are not cryptographic related :-).
23079+ * 4. If you include any Windows specific code (or a derivative thereof) from
23080+ * the apps directory (application code) you must include an acknowledgement:
23081+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
23082+ *
23083+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
23084+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23085+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23086+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23087+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23088+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23089+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23090+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23091+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23092+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23093+ * SUCH DAMAGE.
23094+ *
23095+ * The licence and distribution terms for any publically available version or
23096+ * derivative of this code cannot be changed. i.e. this code cannot simply be
23097+ * copied and put under another distribution licence
23098+ * [including the GNU Public Licence.]
23099+ */
23100+
23101+#include "des/des_locl.h"
23102+#include "des/spr.h"
23103+
23104+char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
23105+char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
23106+
23107+/* RCSID $Id: ecb_enc.c,v 1.8 2004/08/04 15:57:22 mcr Exp $ */
23108+/* This function ifdef'ed out for FreeS/WAN project. */
23109+#ifdef notdef
23110+char *des_options()
23111+ {
23112+ static int init=1;
23113+ static char buf[32];
23114+
23115+ if (init)
23116+ {
23117+ char *ptr,*unroll,*risc,*size;
23118+
23119+ init=0;
23120+#ifdef DES_PTR
23121+ ptr="ptr";
23122+#else
23123+ ptr="idx";
23124+#endif
23125+#if defined(DES_RISC1) || defined(DES_RISC2)
23126+#ifdef DES_RISC1
23127+ risc="risc1";
23128+#endif
23129+#ifdef DES_RISC2
23130+ risc="risc2";
23131+#endif
23132+#else
23133+ risc="cisc";
23134+#endif
23135+#ifdef DES_UNROLL
23136+ unroll="16";
23137+#else
23138+ unroll="4";
23139+#endif
23140+ if (sizeof(DES_LONG) != sizeof(long))
23141+ size="int";
23142+ else
23143+ size="long";
23144+ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
23145+ }
23146+ return(buf);
23147+ }
23148+#endif
23149+
23150+
23151+void des_ecb_encrypt(input, output, ks, enc)
23152+des_cblock (*input);
23153+des_cblock (*output);
23154+des_key_schedule ks;
23155+int enc;
23156+ {
23157+ register DES_LONG l;
23158+ register unsigned char *in,*out;
23159+ DES_LONG ll[2];
23160+
23161+ in=(unsigned char *)input;
23162+ out=(unsigned char *)output;
23163+ c2l(in,l); ll[0]=l;
23164+ c2l(in,l); ll[1]=l;
23165+ des_encrypt(ll,ks,enc);
23166+ l=ll[0]; l2c(l,out);
23167+ l=ll[1]; l2c(l,out);
23168+ l=ll[0]=ll[1]=0;
23169+ }
23170+
23171--- /dev/null Tue Mar 11 13:02:56 2003
23172+++ linux/net/ipsec/des/ipsec_alg_3des.c Mon Feb 9 13:51:03 2004
23173@@ -0,0 +1,181 @@
23174+/*
23175+ * ipsec_alg 3DES cipher stubs
23176+ *
23177+ * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
23178+ *
23179+ * Adapted from ipsec_alg_aes.c by JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
23180+ *
23181+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
23182+ *
23183+ * This program is free software; you can redistribute it and/or modify it
23184+ * under the terms of the GNU General Public License as published by the
23185+ * Free Software Foundation; either version 2 of the License, or (at your
23186+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
23187+ *
23188+ * This program is distributed in the hope that it will be useful, but
23189+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23190+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23191+ * for more details.
23192+ *
23193+ */
23194+#ifndef AUTOCONF_INCLUDED
23195+#include <linux/config.h>
23196+#endif
23197+#include <linux/version.h>
23198+
23199+/*
23200+ * special case: ipsec core modular with this static algo inside:
23201+ * must avoid MODULE magic for this file
23202+ */
23203+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_3DES)
23204+#undef MODULE
23205+#endif
23206+
23207+#include <linux/module.h>
23208+#include <linux/init.h>
23209+
23210+#include <linux/kernel.h> /* printk() */
23211+#include <linux/errno.h> /* error codes */
23212+#include <linux/types.h> /* size_t */
23213+#include <linux/string.h>
23214+
23215+/* Low freeswan header coupling */
23216+#include "openswan/ipsec_xform.h"
23217+#include "openswan/ipsec_alg.h"
23218+#include "crypto/des.h"
23219+#include "openswan/ipsec_alg_3des.h"
23220+
23221+#define AES_CONTEXT_T aes_context
23222+static int debug_3des=0;
23223+static int test_3des=0;
23224+static int excl_3des=0;
23225+
23226+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23227+MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
23228+#ifdef module_param
23229+module_param(debug_3des,int,0600)
23230+module_param(test_des,int,0600)
23231+module_param(excl_des,int,0600)
23232+#else
23233+MODULE_PARM(debug_3des, "i");
23234+MODULE_PARM(test_des, "i");
23235+MODULE_PARM(excl_des, "i");
23236+#endif
23237+#endif
23238+
23239+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
23240+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
23241+
23242+static int _3des_set_key(struct ipsec_alg_enc *alg,
23243+ __u8 * key_e, const __u8 * key,
23244+ size_t keysize)
23245+{
23246+ int ret = 0;
23247+ TripleDES_context *ctx = (TripleDES_context*)key_e;
23248+
23249+ if(keysize != 192/8) {
23250+ return EINVAL;
23251+ }
23252+
23253+ des_set_key((des_cblock *)(key + DES_KEY_SZ*0), ctx->s1);
23254+ des_set_key((des_cblock *)(key + DES_KEY_SZ*1), ctx->s2);
23255+ des_set_key((des_cblock *)(key + DES_KEY_SZ*2), ctx->s3);
23256+
23257+ if (debug_3des > 0)
23258+ printk(KERN_DEBUG "klips_debug:_3des_set_key:"
23259+ "ret=%d key_e=%p key=%p keysize=%ld\n",
23260+ ret, key_e, key, (unsigned long int) keysize);
23261+ return ret;
23262+}
23263+
23264+static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg,
23265+ __u8 * key_e,
23266+ __u8 * in,
23267+ int ilen, const __u8 * iv,
23268+ int encrypt)
23269+{
23270+ TripleDES_context *ctx=(TripleDES_context*)key_e;
23271+ des_cblock miv;
23272+
23273+ memcpy(&miv, iv, sizeof(miv));
23274+
23275+ if (debug_3des > 0)
23276+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
23277+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
23278+ key_e, in, ilen, iv, encrypt);
23279+
23280+ des_ede3_cbc_encrypt((des_cblock *)in,
23281+ (des_cblock *)in,
23282+ ilen,
23283+ ctx->s1,
23284+ ctx->s2,
23285+ ctx->s3,
23286+ &miv, encrypt);
23287+ return 1;
23288+}
23289+
23290+static struct ipsec_alg_enc ipsec_alg_3DES = {
23291+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
23292+ ixt_refcnt: ATOMIC_INIT(0),
23293+ ixt_name: "3des",
23294+ ixt_blocksize: ESP_3DES_CBC_BLK_LEN,
23295+ ixt_support: {
23296+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
23297+ ias_id: ESP_3DES,
23298+ ias_keyminbits: ESP_3DES_KEY_SZ*8,
23299+ ias_keymaxbits: ESP_3DES_KEY_SZ*8,
23300+ },
23301+ },
23302+#if defined(MODULE_KLIPS_ENC_3DES_MODULE)
23303+ ixt_module: THIS_MODULE,
23304+#endif
23305+ ixt_e_keylen: ESP_3DES_KEY_SZ*8,
23306+ ixt_e_ctx_size: sizeof(TripleDES_context),
23307+ ixt_e_set_key: _3des_set_key,
23308+ ixt_e_cbc_encrypt:_3des_cbc_encrypt,
23309+};
23310+
23311+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23312+IPSEC_ALG_MODULE_INIT_MOD( ipsec_3des_init )
23313+#else
23314+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_3des_init )
23315+#endif
23316+{
23317+ int ret, test_ret;
23318+
23319+ if (excl_3des) ipsec_alg_3DES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
23320+ ret=register_ipsec_alg_enc(&ipsec_alg_3DES);
23321+ printk("ipsec_3des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
23322+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23323+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23324+ ipsec_alg_3DES.ixt_common.ixt_name,
23325+ ret);
23326+ if (ret==0 && test_3des) {
23327+ test_ret=ipsec_alg_test(
23328+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23329+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23330+ test_3des);
23331+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
23332+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23333+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23334+ test_ret);
23335+ }
23336+ return ret;
23337+}
23338+
23339+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23340+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_3des_fini )
23341+#else
23342+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_3des_fini )
23343+#endif
23344+{
23345+ unregister_ipsec_alg_enc(&ipsec_alg_3DES);
23346+ return;
23347+}
23348+
23349+/* Dual, because 3des code is 4-clause BSD licensed */
23350+#ifdef MODULE_LICENSE
23351+MODULE_LICENSE("Dual BSD/GPL");
23352+#endif
23353+
23354+
23355--- /dev/null Tue Mar 11 13:02:56 2003
23356+++ linux/net/ipsec/des/set_key.c Mon Feb 9 13:51:03 2004
23357@@ -0,0 +1,246 @@
23358+/* crypto/des/set_key.c */
23359+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
23360+ * All rights reserved.
23361+ *
23362+ * This package is an SSL implementation written
23363+ * by Eric Young (eay@cryptsoft.com).
23364+ * The implementation was written so as to conform with Netscapes SSL.
23365+ *
23366+ * This library is free for commercial and non-commercial use as long as
23367+ * the following conditions are aheared to. The following conditions
23368+ * apply to all code found in this distribution, be it the RC4, RSA,
23369+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
23370+ * included with this distribution is covered by the same copyright terms
23371+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
23372+ *
23373+ * Copyright remains Eric Young's, and as such any Copyright notices in
23374+ * the code are not to be removed.
23375+ * If this package is used in a product, Eric Young should be given attribution
23376+ * as the author of the parts of the library used.
23377+ * This can be in the form of a textual message at program startup or
23378+ * in documentation (online or textual) provided with the package.
23379+ *
23380+ * Redistribution and use in source and binary forms, with or without
23381+ * modification, are permitted provided that the following conditions
23382+ * are met:
23383+ * 1. Redistributions of source code must retain the copyright
23384+ * notice, this list of conditions and the following disclaimer.
23385+ * 2. Redistributions in binary form must reproduce the above copyright
23386+ * notice, this list of conditions and the following disclaimer in the
23387+ * documentation and/or other materials provided with the distribution.
23388+ * 3. All advertising materials mentioning features or use of this software
23389+ * must display the following acknowledgement:
23390+ * "This product includes cryptographic software written by
23391+ * Eric Young (eay@cryptsoft.com)"
23392+ * The word 'cryptographic' can be left out if the rouines from the library
23393+ * being used are not cryptographic related :-).
23394+ * 4. If you include any Windows specific code (or a derivative thereof) from
23395+ * the apps directory (application code) you must include an acknowledgement:
23396+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
23397+ *
23398+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
23399+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23400+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23401+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23402+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23403+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23404+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23405+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23406+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23407+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23408+ * SUCH DAMAGE.
23409+ *
23410+ * The licence and distribution terms for any publically available version or
23411+ * derivative of this code cannot be changed. i.e. this code cannot simply be
23412+ * copied and put under another distribution licence
23413+ * [including the GNU Public Licence.]
23414+ */
23415+
23416+/* set_key.c v 1.4 eay 24/9/91
23417+ * 1.4 Speed up by 400% :-)
23418+ * 1.3 added register declarations.
23419+ * 1.2 unrolled make_key_sched a bit more
23420+ * 1.1 added norm_expand_bits
23421+ * 1.0 First working version
23422+ */
23423+#include "des/des_locl.h"
23424+#include "des/podd.h"
23425+#include "des/sk.h"
23426+
23427+#ifndef NOPROTO
23428+static int check_parity(des_cblock (*key));
23429+#else
23430+static int check_parity();
23431+#endif
23432+
23433+int des_check_key=0;
23434+
23435+void des_set_odd_parity(key)
23436+des_cblock (*key);
23437+ {
23438+ int i;
23439+
23440+ for (i=0; i<DES_KEY_SZ; i++)
23441+ (*key)[i]=odd_parity[(*key)[i]];
23442+ }
23443+
23444+static int check_parity(key)
23445+des_cblock (*key);
23446+ {
23447+ int i;
23448+
23449+ for (i=0; i<DES_KEY_SZ; i++)
23450+ {
23451+ if ((*key)[i] != odd_parity[(*key)[i]])
23452+ return(0);
23453+ }
23454+ return(1);
23455+ }
23456+
23457+/* Weak and semi week keys as take from
23458+ * %A D.W. Davies
23459+ * %A W.L. Price
23460+ * %T Security for Computer Networks
23461+ * %I John Wiley & Sons
23462+ * %D 1984
23463+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
23464+ * (and actual cblock values).
23465+ */
23466+#define NUM_WEAK_KEY 16
23467+static des_cblock weak_keys[NUM_WEAK_KEY]={
23468+ /* weak keys */
23469+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
23470+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
23471+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
23472+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
23473+ /* semi-weak keys */
23474+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
23475+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
23476+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
23477+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
23478+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
23479+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
23480+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
23481+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
23482+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
23483+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
23484+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
23485+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
23486+
23487+int des_is_weak_key(key)
23488+des_cblock (*key);
23489+ {
23490+ int i;
23491+
23492+ for (i=0; i<NUM_WEAK_KEY; i++)
23493+ /* Added == 0 to comparision, I obviously don't run
23494+ * this section very often :-(, thanks to
23495+ * engineering@MorningStar.Com for the fix
23496+ * eay 93/06/29
23497+ * Another problem, I was comparing only the first 4
23498+ * bytes, 97/03/18 */
23499+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
23500+ return(0);
23501+ }
23502+
23503+/* NOW DEFINED IN des_local.h
23504+ * See ecb_encrypt.c for a pseudo description of these macros.
23505+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
23506+ * (b)^=(t),\
23507+ * (a)=((a)^((t)<<(n))))
23508+ */
23509+
23510+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
23511+ (a)=(a)^(t)^(t>>(16-(n))))
23512+
23513+/* return 0 if key parity is odd (correct),
23514+ * return -1 if key parity error,
23515+ * return -2 if illegal weak key.
23516+ */
23517+int des_set_key(key, schedule)
23518+des_cblock (*key);
23519+des_key_schedule schedule;
23520+ {
23521+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
23522+ register DES_LONG c,d,t,s,t2;
23523+ register unsigned char *in;
23524+ register DES_LONG *k;
23525+ register int i;
23526+
23527+ if (des_check_key)
23528+ {
23529+ if (!check_parity(key))
23530+ return(-1);
23531+
23532+ if (des_is_weak_key(key))
23533+ return(-2);
23534+ }
23535+
23536+ k=(DES_LONG *)schedule;
23537+ in=(unsigned char *)key;
23538+
23539+ c2l(in,c);
23540+ c2l(in,d);
23541+
23542+ /* do PC1 in 60 simple operations */
23543+/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
23544+ HPERM_OP(c,t,-2, 0xcccc0000L);
23545+ HPERM_OP(c,t,-1, 0xaaaa0000L);
23546+ HPERM_OP(c,t, 8, 0x00ff0000L);
23547+ HPERM_OP(c,t,-1, 0xaaaa0000L);
23548+ HPERM_OP(d,t,-8, 0xff000000L);
23549+ HPERM_OP(d,t, 8, 0x00ff0000L);
23550+ HPERM_OP(d,t, 2, 0x33330000L);
23551+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
23552+ d=(d>>8)|((c&0xf0000000L)>>4);
23553+ c&=0x0fffffffL; */
23554+
23555+ /* I now do it in 47 simple operations :-)
23556+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
23557+ * for the inspiration. :-) */
23558+ PERM_OP (d,c,t,4,0x0f0f0f0fL);
23559+ HPERM_OP(c,t,-2,0xcccc0000L);
23560+ HPERM_OP(d,t,-2,0xcccc0000L);
23561+ PERM_OP (d,c,t,1,0x55555555L);
23562+ PERM_OP (c,d,t,8,0x00ff00ffL);
23563+ PERM_OP (d,c,t,1,0x55555555L);
23564+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
23565+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
23566+ c&=0x0fffffffL;
23567+
23568+ for (i=0; i<ITERATIONS; i++)
23569+ {
23570+ if (shifts2[i])
23571+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
23572+ else
23573+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
23574+ c&=0x0fffffffL;
23575+ d&=0x0fffffffL;
23576+ /* could be a few less shifts but I am to lazy at this
23577+ * point in time to investigate */
23578+ s= des_skb[0][ (c )&0x3f ]|
23579+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
23580+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
23581+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
23582+ ((c>>22L)&0x38)];
23583+ t= des_skb[4][ (d )&0x3f ]|
23584+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
23585+ des_skb[6][ (d>>15L)&0x3f ]|
23586+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
23587+
23588+ /* table contained 0213 4657 */
23589+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
23590+ *(k++)=ROTATE(t2,30)&0xffffffffL;
23591+
23592+ t2=((s>>16L)|(t&0xffff0000L));
23593+ *(k++)=ROTATE(t2,26)&0xffffffffL;
23594+ }
23595+ return(0);
23596+ }
23597+
23598+int des_key_sched(key, schedule)
23599+des_cblock (*key);
23600+des_key_schedule schedule;
23601+ {
23602+ return(des_set_key(key,schedule));
23603+ }
23604--- /dev/null Tue Mar 11 13:02:56 2003
23605+++ linux/net/ipsec/goodmask.c Mon Feb 9 13:51:03 2004
23606@@ -0,0 +1,100 @@
23607+/*
23608+ * minor utilities for subnet-mask manipulation
23609+ * Copyright (C) 1998, 1999 Henry Spencer.
23610+ *
23611+ * This library is free software; you can redistribute it and/or modify it
23612+ * under the terms of the GNU Library General Public License as published by
23613+ * the Free Software Foundation; either version 2 of the License, or (at your
23614+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
23615+ *
23616+ * This library is distributed in the hope that it will be useful, but
23617+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23618+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
23619+ * License for more details.
23620+ *
23621+ * RCSID $Id: goodmask.c,v 1.12 2004/07/10 07:43:47 mcr Exp $
23622+ */
23623+#include "openswan.h"
23624+
23625+#ifndef ABITS
23626+#define ABITS 32 /* bits in an IPv4 address */
23627+#endif
23628+
23629+/*
23630+ - goodmask - is this a good (^1*0*$) subnet mask?
23631+ * You are not expected to understand this. See Henry S. Warren Jr,
23632+ * "Functions realizable with word-parallel logical and two's-complement
23633+ * addition instructions", CACM 20.6 (June 1977), p.439.
23634+ */
23635+int /* predicate */
23636+goodmask(mask)
23637+struct in_addr mask;
23638+{
23639+ unsigned long x = ntohl(mask.s_addr);
23640+ /* clear rightmost contiguous string of 1-bits */
23641+# define CRCS1B(x) (((x|(x-1))+1)&x)
23642+# define TOPBIT (1UL << 31)
23643+
23644+ /* either zero, or has one string of 1-bits which is left-justified */
23645+ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
23646+ return 1;
23647+ return 0;
23648+}
23649+
23650+/*
23651+ - masktobits - how many bits in this mask?
23652+ * The algorithm is essentially a binary search, but highly optimized
23653+ * for this particular task.
23654+ */
23655+int /* -1 means !goodmask() */
23656+masktobits(mask)
23657+struct in_addr mask;
23658+{
23659+ unsigned long m = ntohl(mask.s_addr);
23660+ int masklen;
23661+
23662+ if (!goodmask(mask))
23663+ return -1;
23664+
23665+ if (m&0x00000001UL)
23666+ return 32;
23667+ masklen = 0;
23668+ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
23669+ masklen |= 0x10;
23670+ m <<= 16;
23671+ }
23672+ if (m&(0x00ff0000UL<<1)) {
23673+ masklen |= 0x08;
23674+ m <<= 8;
23675+ }
23676+ if (m&(0x0f000000UL<<1)) {
23677+ masklen |= 0x04;
23678+ m <<= 4;
23679+ }
23680+ if (m&(0x30000000UL<<1)) {
23681+ masklen |= 0x02;
23682+ m <<= 2;
23683+ }
23684+ if (m&(0x40000000UL<<1))
23685+ masklen |= 0x01;
23686+
23687+ return masklen;
23688+}
23689+
23690+/*
23691+ - bitstomask - return a mask with this many high bits on
23692+ */
23693+struct in_addr
23694+bitstomask(n)
23695+int n;
23696+{
23697+ struct in_addr result;
23698+
23699+ if (n > 0 && n <= ABITS)
23700+ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
23701+ else if (n == 0)
23702+ result.s_addr = 0;
23703+ else
23704+ result.s_addr = 0; /* best error report we can do */
23705+ return result;
23706+}
23707--- /dev/null Tue Mar 11 13:02:56 2003
23708+++ linux/net/ipsec/infblock.c Mon Feb 9 13:51:03 2004
23709@@ -0,0 +1,403 @@
23710+/* infblock.c -- interpret and process block types to last block
23711+ * Copyright (C) 1995-2002 Mark Adler
23712+ * For conditions of distribution and use, see copyright notice in zlib.h
23713+ */
23714+
23715+#include <zlib/zutil.h>
23716+#include "infblock.h"
23717+#include "inftrees.h"
23718+#include "infcodes.h"
23719+#include "infutil.h"
23720+
23721+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
23722+
23723+/* simplify the use of the inflate_huft type with some defines */
23724+#define exop word.what.Exop
23725+#define bits word.what.Bits
23726+
23727+/* Table for deflate from PKZIP's appnote.txt. */
23728+local const uInt border[] = { /* Order of the bit length code lengths */
23729+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
23730+
23731+/*
23732+ Notes beyond the 1.93a appnote.txt:
23733+
23734+ 1. Distance pointers never point before the beginning of the output
23735+ stream.
23736+ 2. Distance pointers can point back across blocks, up to 32k away.
23737+ 3. There is an implied maximum of 7 bits for the bit length table and
23738+ 15 bits for the actual data.
23739+ 4. If only one code exists, then it is encoded using one bit. (Zero
23740+ would be more efficient, but perhaps a little confusing.) If two
23741+ codes exist, they are coded using one bit each (0 and 1).
23742+ 5. There is no way of sending zero distance codes--a dummy must be
23743+ sent if there are none. (History: a pre 2.0 version of PKZIP would
23744+ store blocks with no distance codes, but this was discovered to be
23745+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
23746+ zero distance codes, which is sent as one code of zero bits in
23747+ length.
23748+ 6. There are up to 286 literal/length codes. Code 256 represents the
23749+ end-of-block. Note however that the static length tree defines
23750+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
23751+ cannot be used though, since there is no length base or extra bits
23752+ defined for them. Similarily, there are up to 30 distance codes.
23753+ However, static trees define 32 codes (all 5 bits) to fill out the
23754+ Huffman codes, but the last two had better not show up in the data.
23755+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
23756+ The exception is that a single code would not be complete (see #4).
23757+ 8. The five bits following the block type is really the number of
23758+ literal codes sent minus 257.
23759+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
23760+ (1+6+6). Therefore, to output three times the length, you output
23761+ three codes (1+1+1), whereas to output four times the same length,
23762+ you only need two codes (1+3). Hmm.
23763+ 10. In the tree reconstruction algorithm, Code = Code + Increment
23764+ only if BitLength(i) is not zero. (Pretty obvious.)
23765+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
23766+ 12. Note: length code 284 can represent 227-258, but length code 285
23767+ really is 258. The last length deserves its own, short code
23768+ since it gets used a lot in very redundant files. The length
23769+ 258 is special since 258 - 3 (the min match length) is 255.
23770+ 13. The literal/length and distance code bit lengths are read as a
23771+ single stream of lengths. It is possible (and advantageous) for
23772+ a repeat code (16, 17, or 18) to go across the boundary between
23773+ the two sets of lengths.
23774+ */
23775+
23776+
23777+void inflate_blocks_reset(s, z, c)
23778+inflate_blocks_statef *s;
23779+z_streamp z;
23780+uLongf *c;
23781+{
23782+ if (c != Z_NULL)
23783+ *c = s->check;
23784+ if (s->mode == BTREE || s->mode == DTREE)
23785+ ZFREE(z, s->sub.trees.blens);
23786+ if (s->mode == CODES)
23787+ inflate_codes_free(s->sub.decode.codes, z);
23788+ s->mode = TYPE;
23789+ s->bitk = 0;
23790+ s->bitb = 0;
23791+ s->read = s->write = s->window;
23792+ if (s->checkfn != Z_NULL)
23793+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
23794+ Tracev((stderr, "inflate: blocks reset\n"));
23795+}
23796+
23797+
23798+inflate_blocks_statef *inflate_blocks_new(z, c, w)
23799+z_streamp z;
23800+check_func c;
23801+uInt w;
23802+{
23803+ inflate_blocks_statef *s;
23804+
23805+ if ((s = (inflate_blocks_statef *)ZALLOC
23806+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
23807+ return s;
23808+ if ((s->hufts =
23809+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
23810+ {
23811+ ZFREE(z, s);
23812+ return Z_NULL;
23813+ }
23814+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
23815+ {
23816+ ZFREE(z, s->hufts);
23817+ ZFREE(z, s);
23818+ return Z_NULL;
23819+ }
23820+ s->end = s->window + w;
23821+ s->checkfn = c;
23822+ s->mode = TYPE;
23823+ Tracev((stderr, "inflate: blocks allocated\n"));
23824+ inflate_blocks_reset(s, z, Z_NULL);
23825+ return s;
23826+}
23827+
23828+
23829+int inflate_blocks(s, z, r)
23830+inflate_blocks_statef *s;
23831+z_streamp z;
23832+int r;
23833+{
23834+ uInt t; /* temporary storage */
23835+ uLong b; /* bit buffer */
23836+ uInt k; /* bits in bit buffer */
23837+ Bytef *p; /* input data pointer */
23838+ uInt n; /* bytes available there */
23839+ Bytef *q; /* output window write pointer */
23840+ uInt m; /* bytes to end of window or read pointer */
23841+
23842+ /* copy input/output information to locals (UPDATE macro restores) */
23843+ LOAD
23844+
23845+ /* process input based on current state */
23846+ while (1) switch (s->mode)
23847+ {
23848+ case TYPE:
23849+ NEEDBITS(3)
23850+ t = (uInt)b & 7;
23851+ s->last = t & 1;
23852+ switch (t >> 1)
23853+ {
23854+ case 0: /* stored */
23855+ Tracev((stderr, "inflate: stored block%s\n",
23856+ s->last ? " (last)" : ""));
23857+ DUMPBITS(3)
23858+ t = k & 7; /* go to byte boundary */
23859+ DUMPBITS(t)
23860+ s->mode = LENS; /* get length of stored block */
23861+ break;
23862+ case 1: /* fixed */
23863+ Tracev((stderr, "inflate: fixed codes block%s\n",
23864+ s->last ? " (last)" : ""));
23865+ {
23866+ uInt bl, bd;
23867+ inflate_huft *tl, *td;
23868+
23869+ inflate_trees_fixed(&bl, &bd, &tl, &td, z);
23870+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
23871+ if (s->sub.decode.codes == Z_NULL)
23872+ {
23873+ r = Z_MEM_ERROR;
23874+ LEAVE
23875+ }
23876+ }
23877+ DUMPBITS(3)
23878+ s->mode = CODES;
23879+ break;
23880+ case 2: /* dynamic */
23881+ Tracev((stderr, "inflate: dynamic codes block%s\n",
23882+ s->last ? " (last)" : ""));
23883+ DUMPBITS(3)
23884+ s->mode = TABLE;
23885+ break;
23886+ case 3: /* illegal */
23887+ DUMPBITS(3)
23888+ s->mode = BAD;
23889+ z->msg = (char*)"invalid block type";
23890+ r = Z_DATA_ERROR;
23891+ LEAVE
23892+ }
23893+ break;
23894+ case LENS:
23895+ NEEDBITS(32)
23896+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
23897+ {
23898+ s->mode = BAD;
23899+ z->msg = (char*)"invalid stored block lengths";
23900+ r = Z_DATA_ERROR;
23901+ LEAVE
23902+ }
23903+ s->sub.left = (uInt)b & 0xffff;
23904+ b = k = 0; /* dump bits */
23905+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
23906+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
23907+ break;
23908+ case STORED:
23909+ if (n == 0)
23910+ LEAVE
23911+ NEEDOUT
23912+ t = s->sub.left;
23913+ if (t > n) t = n;
23914+ if (t > m) t = m;
23915+ zmemcpy(q, p, t);
23916+ p += t; n -= t;
23917+ q += t; m -= t;
23918+ if ((s->sub.left -= t) != 0)
23919+ break;
23920+ Tracev((stderr, "inflate: stored end, %lu total out\n",
23921+ z->total_out + (q >= s->read ? q - s->read :
23922+ (s->end - s->read) + (q - s->window))));
23923+ s->mode = s->last ? DRY : TYPE;
23924+ break;
23925+ case TABLE:
23926+ NEEDBITS(14)
23927+ s->sub.trees.table = t = (uInt)b & 0x3fff;
23928+#ifndef PKZIP_BUG_WORKAROUND
23929+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
23930+ {
23931+ s->mode = BAD;
23932+ z->msg = (char*)"too many length or distance symbols";
23933+ r = Z_DATA_ERROR;
23934+ LEAVE
23935+ }
23936+#endif
23937+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
23938+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
23939+ {
23940+ r = Z_MEM_ERROR;
23941+ LEAVE
23942+ }
23943+ DUMPBITS(14)
23944+ s->sub.trees.index = 0;
23945+ Tracev((stderr, "inflate: table sizes ok\n"));
23946+ s->mode = BTREE;
23947+ case BTREE:
23948+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
23949+ {
23950+ NEEDBITS(3)
23951+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
23952+ DUMPBITS(3)
23953+ }
23954+ while (s->sub.trees.index < 19)
23955+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
23956+ s->sub.trees.bb = 7;
23957+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
23958+ &s->sub.trees.tb, s->hufts, z);
23959+ if (t != Z_OK)
23960+ {
23961+ r = t;
23962+ if (r == Z_DATA_ERROR)
23963+ {
23964+ ZFREE(z, s->sub.trees.blens);
23965+ s->mode = BAD;
23966+ }
23967+ LEAVE
23968+ }
23969+ s->sub.trees.index = 0;
23970+ Tracev((stderr, "inflate: bits tree ok\n"));
23971+ s->mode = DTREE;
23972+ case DTREE:
23973+ while (t = s->sub.trees.table,
23974+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
23975+ {
23976+ inflate_huft *h;
23977+ uInt i, j, c;
23978+
23979+ t = s->sub.trees.bb;
23980+ NEEDBITS(t)
23981+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
23982+ t = h->bits;
23983+ c = h->base;
23984+ if (c < 16)
23985+ {
23986+ DUMPBITS(t)
23987+ s->sub.trees.blens[s->sub.trees.index++] = c;
23988+ }
23989+ else /* c == 16..18 */
23990+ {
23991+ i = c == 18 ? 7 : c - 14;
23992+ j = c == 18 ? 11 : 3;
23993+ NEEDBITS(t + i)
23994+ DUMPBITS(t)
23995+ j += (uInt)b & inflate_mask[i];
23996+ DUMPBITS(i)
23997+ i = s->sub.trees.index;
23998+ t = s->sub.trees.table;
23999+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
24000+ (c == 16 && i < 1))
24001+ {
24002+ ZFREE(z, s->sub.trees.blens);
24003+ s->mode = BAD;
24004+ z->msg = (char*)"invalid bit length repeat";
24005+ r = Z_DATA_ERROR;
24006+ LEAVE
24007+ }
24008+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
24009+ do {
24010+ s->sub.trees.blens[i++] = c;
24011+ } while (--j);
24012+ s->sub.trees.index = i;
24013+ }
24014+ }
24015+ s->sub.trees.tb = Z_NULL;
24016+ {
24017+ uInt bl, bd;
24018+ inflate_huft *tl, *td;
24019+ inflate_codes_statef *c;
24020+
24021+ bl = 9; /* must be <= 9 for lookahead assumptions */
24022+ bd = 6; /* must be <= 9 for lookahead assumptions */
24023+ t = s->sub.trees.table;
24024+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
24025+ s->sub.trees.blens, &bl, &bd, &tl, &td,
24026+ s->hufts, z);
24027+ if (t != Z_OK)
24028+ {
24029+ if (t == (uInt)Z_DATA_ERROR)
24030+ {
24031+ ZFREE(z, s->sub.trees.blens);
24032+ s->mode = BAD;
24033+ }
24034+ r = t;
24035+ LEAVE
24036+ }
24037+ Tracev((stderr, "inflate: trees ok\n"));
24038+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
24039+ {
24040+ r = Z_MEM_ERROR;
24041+ LEAVE
24042+ }
24043+ s->sub.decode.codes = c;
24044+ }
24045+ ZFREE(z, s->sub.trees.blens);
24046+ s->mode = CODES;
24047+ case CODES:
24048+ UPDATE
24049+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
24050+ return inflate_flush(s, z, r);
24051+ r = Z_OK;
24052+ inflate_codes_free(s->sub.decode.codes, z);
24053+ LOAD
24054+ Tracev((stderr, "inflate: codes end, %lu total out\n",
24055+ z->total_out + (q >= s->read ? q - s->read :
24056+ (s->end - s->read) + (q - s->window))));
24057+ if (!s->last)
24058+ {
24059+ s->mode = TYPE;
24060+ break;
24061+ }
24062+ s->mode = DRY;
24063+ case DRY:
24064+ FLUSH
24065+ if (s->read != s->write)
24066+ LEAVE
24067+ s->mode = DONE;
24068+ case DONE:
24069+ r = Z_STREAM_END;
24070+ LEAVE
24071+ case BAD:
24072+ r = Z_DATA_ERROR;
24073+ LEAVE
24074+ default:
24075+ r = Z_STREAM_ERROR;
24076+ LEAVE
24077+ }
24078+}
24079+
24080+
24081+int inflate_blocks_free(s, z)
24082+inflate_blocks_statef *s;
24083+z_streamp z;
24084+{
24085+ inflate_blocks_reset(s, z, Z_NULL);
24086+ ZFREE(z, s->window);
24087+ ZFREE(z, s->hufts);
24088+ ZFREE(z, s);
24089+ Tracev((stderr, "inflate: blocks freed\n"));
24090+ return Z_OK;
24091+}
24092+
24093+
24094+void inflate_set_dictionary(s, d, n)
24095+inflate_blocks_statef *s;
24096+const Bytef *d;
24097+uInt n;
24098+{
24099+ zmemcpy(s->window, d, n);
24100+ s->read = s->write = s->window + n;
24101+}
24102+
24103+
24104+/* Returns true if inflate is currently at the end of a block generated
24105+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
24106+ * IN assertion: s != Z_NULL
24107+ */
24108+int inflate_blocks_sync_point(s)
24109+inflate_blocks_statef *s;
24110+{
24111+ return s->mode == LENS;
24112+}
24113--- /dev/null Tue Mar 11 13:02:56 2003
24114+++ linux/net/ipsec/infblock.h Mon Feb 9 13:51:03 2004
24115@@ -0,0 +1,39 @@
24116+/* infblock.h -- header to use infblock.c
24117+ * Copyright (C) 1995-2002 Mark Adler
24118+ * For conditions of distribution and use, see copyright notice in zlib.h
24119+ */
24120+
24121+/* WARNING: this file should *not* be used by applications. It is
24122+ part of the implementation of the compression library and is
24123+ subject to change. Applications should only use zlib.h.
24124+ */
24125+
24126+struct inflate_blocks_state;
24127+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
24128+
24129+extern inflate_blocks_statef * inflate_blocks_new OF((
24130+ z_streamp z,
24131+ check_func c, /* check function */
24132+ uInt w)); /* window size */
24133+
24134+extern int inflate_blocks OF((
24135+ inflate_blocks_statef *,
24136+ z_streamp ,
24137+ int)); /* initial return code */
24138+
24139+extern void inflate_blocks_reset OF((
24140+ inflate_blocks_statef *,
24141+ z_streamp ,
24142+ uLongf *)); /* check value on output */
24143+
24144+extern int inflate_blocks_free OF((
24145+ inflate_blocks_statef *,
24146+ z_streamp));
24147+
24148+extern void inflate_set_dictionary OF((
24149+ inflate_blocks_statef *s,
24150+ const Bytef *d, /* dictionary */
24151+ uInt n)); /* dictionary length */
24152+
24153+extern int inflate_blocks_sync_point OF((
24154+ inflate_blocks_statef *s));
24155--- /dev/null Tue Mar 11 13:02:56 2003
24156+++ linux/net/ipsec/infcodes.c Mon Feb 9 13:51:03 2004
24157@@ -0,0 +1,251 @@
24158+/* infcodes.c -- process literals and length/distance pairs
24159+ * Copyright (C) 1995-2002 Mark Adler
24160+ * For conditions of distribution and use, see copyright notice in zlib.h
24161+ */
24162+
24163+#include <zlib/zutil.h>
24164+#include "inftrees.h"
24165+#include "infblock.h"
24166+#include "infcodes.h"
24167+#include "infutil.h"
24168+#include "inffast.h"
24169+
24170+/* simplify the use of the inflate_huft type with some defines */
24171+#define exop word.what.Exop
24172+#define bits word.what.Bits
24173+
24174+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
24175+ START, /* x: set up for LEN */
24176+ LEN, /* i: get length/literal/eob next */
24177+ LENEXT, /* i: getting length extra (have base) */
24178+ DIST, /* i: get distance next */
24179+ DISTEXT, /* i: getting distance extra */
24180+ COPY, /* o: copying bytes in window, waiting for space */
24181+ LIT, /* o: got literal, waiting for output space */
24182+ WASH, /* o: got eob, possibly still output waiting */
24183+ END, /* x: got eob and all data flushed */
24184+ BADCODE} /* x: got error */
24185+inflate_codes_mode;
24186+
24187+/* inflate codes private state */
24188+struct inflate_codes_state {
24189+
24190+ /* mode */
24191+ inflate_codes_mode mode; /* current inflate_codes mode */
24192+
24193+ /* mode dependent information */
24194+ uInt len;
24195+ union {
24196+ struct {
24197+ inflate_huft *tree; /* pointer into tree */
24198+ uInt need; /* bits needed */
24199+ } code; /* if LEN or DIST, where in tree */
24200+ uInt lit; /* if LIT, literal */
24201+ struct {
24202+ uInt get; /* bits to get for extra */
24203+ uInt dist; /* distance back to copy from */
24204+ } copy; /* if EXT or COPY, where and how much */
24205+ } sub; /* submode */
24206+
24207+ /* mode independent information */
24208+ Byte lbits; /* ltree bits decoded per branch */
24209+ Byte dbits; /* dtree bits decoder per branch */
24210+ inflate_huft *ltree; /* literal/length/eob tree */
24211+ inflate_huft *dtree; /* distance tree */
24212+
24213+};
24214+
24215+
24216+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
24217+uInt bl, bd;
24218+inflate_huft *tl;
24219+inflate_huft *td; /* need separate declaration for Borland C++ */
24220+z_streamp z;
24221+{
24222+ inflate_codes_statef *c;
24223+
24224+ if ((c = (inflate_codes_statef *)
24225+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
24226+ {
24227+ c->mode = START;
24228+ c->lbits = (Byte)bl;
24229+ c->dbits = (Byte)bd;
24230+ c->ltree = tl;
24231+ c->dtree = td;
24232+ Tracev((stderr, "inflate: codes new\n"));
24233+ }
24234+ return c;
24235+}
24236+
24237+
24238+int inflate_codes(s, z, r)
24239+inflate_blocks_statef *s;
24240+z_streamp z;
24241+int r;
24242+{
24243+ uInt j; /* temporary storage */
24244+ inflate_huft *t; /* temporary pointer */
24245+ uInt e; /* extra bits or operation */
24246+ uLong b; /* bit buffer */
24247+ uInt k; /* bits in bit buffer */
24248+ Bytef *p; /* input data pointer */
24249+ uInt n; /* bytes available there */
24250+ Bytef *q; /* output window write pointer */
24251+ uInt m; /* bytes to end of window or read pointer */
24252+ Bytef *f; /* pointer to copy strings from */
24253+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
24254+
24255+ /* copy input/output information to locals (UPDATE macro restores) */
24256+ LOAD
24257+
24258+ /* process input and output based on current state */
24259+ while (1) switch (c->mode)
24260+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
24261+ case START: /* x: set up for LEN */
24262+#ifndef SLOW
24263+ if (m >= 258 && n >= 10)
24264+ {
24265+ UPDATE
24266+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
24267+ LOAD
24268+ if (r != Z_OK)
24269+ {
24270+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
24271+ break;
24272+ }
24273+ }
24274+#endif /* !SLOW */
24275+ c->sub.code.need = c->lbits;
24276+ c->sub.code.tree = c->ltree;
24277+ c->mode = LEN;
24278+ case LEN: /* i: get length/literal/eob next */
24279+ j = c->sub.code.need;
24280+ NEEDBITS(j)
24281+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
24282+ DUMPBITS(t->bits)
24283+ e = (uInt)(t->exop);
24284+ if (e == 0) /* literal */
24285+ {
24286+ c->sub.lit = t->base;
24287+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24288+ "inflate: literal '%c'\n" :
24289+ "inflate: literal 0x%02x\n", t->base));
24290+ c->mode = LIT;
24291+ break;
24292+ }
24293+ if (e & 16) /* length */
24294+ {
24295+ c->sub.copy.get = e & 15;
24296+ c->len = t->base;
24297+ c->mode = LENEXT;
24298+ break;
24299+ }
24300+ if ((e & 64) == 0) /* next table */
24301+ {
24302+ c->sub.code.need = e;
24303+ c->sub.code.tree = t + t->base;
24304+ break;
24305+ }
24306+ if (e & 32) /* end of block */
24307+ {
24308+ Tracevv((stderr, "inflate: end of block\n"));
24309+ c->mode = WASH;
24310+ break;
24311+ }
24312+ c->mode = BADCODE; /* invalid code */
24313+ z->msg = (char*)"invalid literal/length code";
24314+ r = Z_DATA_ERROR;
24315+ LEAVE
24316+ case LENEXT: /* i: getting length extra (have base) */
24317+ j = c->sub.copy.get;
24318+ NEEDBITS(j)
24319+ c->len += (uInt)b & inflate_mask[j];
24320+ DUMPBITS(j)
24321+ c->sub.code.need = c->dbits;
24322+ c->sub.code.tree = c->dtree;
24323+ Tracevv((stderr, "inflate: length %u\n", c->len));
24324+ c->mode = DIST;
24325+ case DIST: /* i: get distance next */
24326+ j = c->sub.code.need;
24327+ NEEDBITS(j)
24328+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
24329+ DUMPBITS(t->bits)
24330+ e = (uInt)(t->exop);
24331+ if (e & 16) /* distance */
24332+ {
24333+ c->sub.copy.get = e & 15;
24334+ c->sub.copy.dist = t->base;
24335+ c->mode = DISTEXT;
24336+ break;
24337+ }
24338+ if ((e & 64) == 0) /* next table */
24339+ {
24340+ c->sub.code.need = e;
24341+ c->sub.code.tree = t + t->base;
24342+ break;
24343+ }
24344+ c->mode = BADCODE; /* invalid code */
24345+ z->msg = (char*)"invalid distance code";
24346+ r = Z_DATA_ERROR;
24347+ LEAVE
24348+ case DISTEXT: /* i: getting distance extra */
24349+ j = c->sub.copy.get;
24350+ NEEDBITS(j)
24351+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
24352+ DUMPBITS(j)
24353+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
24354+ c->mode = COPY;
24355+ case COPY: /* o: copying bytes in window, waiting for space */
24356+ f = q - c->sub.copy.dist;
24357+ while (f < s->window) /* modulo window size-"while" instead */
24358+ f += s->end - s->window; /* of "if" handles invalid distances */
24359+ while (c->len)
24360+ {
24361+ NEEDOUT
24362+ OUTBYTE(*f++)
24363+ if (f == s->end)
24364+ f = s->window;
24365+ c->len--;
24366+ }
24367+ c->mode = START;
24368+ break;
24369+ case LIT: /* o: got literal, waiting for output space */
24370+ NEEDOUT
24371+ OUTBYTE(c->sub.lit)
24372+ c->mode = START;
24373+ break;
24374+ case WASH: /* o: got eob, possibly more output */
24375+ if (k > 7) /* return unused byte, if any */
24376+ {
24377+ Assert(k < 16, "inflate_codes grabbed too many bytes")
24378+ k -= 8;
24379+ n++;
24380+ p--; /* can always return one */
24381+ }
24382+ FLUSH
24383+ if (s->read != s->write)
24384+ LEAVE
24385+ c->mode = END;
24386+ case END:
24387+ r = Z_STREAM_END;
24388+ LEAVE
24389+ case BADCODE: /* x: got error */
24390+ r = Z_DATA_ERROR;
24391+ LEAVE
24392+ default:
24393+ r = Z_STREAM_ERROR;
24394+ LEAVE
24395+ }
24396+#ifdef NEED_DUMMY_RETURN
24397+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
24398+#endif
24399+}
24400+
24401+
24402+void inflate_codes_free(c, z)
24403+inflate_codes_statef *c;
24404+z_streamp z;
24405+{
24406+ ZFREE(z, c);
24407+ Tracev((stderr, "inflate: codes free\n"));
24408+}
24409--- /dev/null Tue Mar 11 13:02:56 2003
24410+++ linux/net/ipsec/infcodes.h Mon Feb 9 13:51:03 2004
24411@@ -0,0 +1,31 @@
24412+/* infcodes.h -- header to use infcodes.c
24413+ * Copyright (C) 1995-2002 Mark Adler
24414+ * For conditions of distribution and use, see copyright notice in zlib.h
24415+ */
24416+
24417+/* WARNING: this file should *not* be used by applications. It is
24418+ part of the implementation of the compression library and is
24419+ subject to change. Applications should only use zlib.h.
24420+ */
24421+
24422+#ifndef _INFCODES_H
24423+#define _INFCODES_H
24424+
24425+struct inflate_codes_state;
24426+typedef struct inflate_codes_state FAR inflate_codes_statef;
24427+
24428+extern inflate_codes_statef *inflate_codes_new OF((
24429+ uInt, uInt,
24430+ inflate_huft *, inflate_huft *,
24431+ z_streamp ));
24432+
24433+extern int inflate_codes OF((
24434+ inflate_blocks_statef *,
24435+ z_streamp ,
24436+ int));
24437+
24438+extern void inflate_codes_free OF((
24439+ inflate_codes_statef *,
24440+ z_streamp ));
24441+
24442+#endif /* _INFCODES_H */
24443--- /dev/null Tue Mar 11 13:02:56 2003
24444+++ linux/net/ipsec/inffast.c Mon Feb 9 13:51:03 2004
24445@@ -0,0 +1,183 @@
24446+/* inffast.c -- process literals and length/distance pairs fast
24447+ * Copyright (C) 1995-2002 Mark Adler
24448+ * For conditions of distribution and use, see copyright notice in zlib.h
24449+ */
24450+
24451+#include <zlib/zutil.h>
24452+#include "inftrees.h"
24453+#include "infblock.h"
24454+#include "infcodes.h"
24455+#include "infutil.h"
24456+#include "inffast.h"
24457+
24458+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
24459+
24460+/* simplify the use of the inflate_huft type with some defines */
24461+#define exop word.what.Exop
24462+#define bits word.what.Bits
24463+
24464+/* macros for bit input with no checking and for returning unused bytes */
24465+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
24466+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
24467+
24468+/* Called with number of bytes left to write in window at least 258
24469+ (the maximum string length) and number of input bytes available
24470+ at least ten. The ten bytes are six bytes for the longest length/
24471+ distance pair plus four bytes for overloading the bit buffer. */
24472+
24473+int inflate_fast(bl, bd, tl, td, s, z)
24474+uInt bl, bd;
24475+inflate_huft *tl;
24476+inflate_huft *td; /* need separate declaration for Borland C++ */
24477+inflate_blocks_statef *s;
24478+z_streamp z;
24479+{
24480+ inflate_huft *t; /* temporary pointer */
24481+ uInt e; /* extra bits or operation */
24482+ uLong b; /* bit buffer */
24483+ uInt k; /* bits in bit buffer */
24484+ Bytef *p; /* input data pointer */
24485+ uInt n; /* bytes available there */
24486+ Bytef *q; /* output window write pointer */
24487+ uInt m; /* bytes to end of window or read pointer */
24488+ uInt ml; /* mask for literal/length tree */
24489+ uInt md; /* mask for distance tree */
24490+ uInt c; /* bytes to copy */
24491+ uInt d; /* distance back to copy from */
24492+ Bytef *r; /* copy source pointer */
24493+
24494+ /* load input, output, bit values */
24495+ LOAD
24496+
24497+ /* initialize masks */
24498+ ml = inflate_mask[bl];
24499+ md = inflate_mask[bd];
24500+
24501+ /* do until not enough input or output space for fast loop */
24502+ do { /* assume called with m >= 258 && n >= 10 */
24503+ /* get literal/length code */
24504+ GRABBITS(20) /* max bits for literal/length code */
24505+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
24506+ {
24507+ DUMPBITS(t->bits)
24508+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24509+ "inflate: * literal '%c'\n" :
24510+ "inflate: * literal 0x%02x\n", t->base));
24511+ *q++ = (Byte)t->base;
24512+ m--;
24513+ continue;
24514+ }
24515+ do {
24516+ DUMPBITS(t->bits)
24517+ if (e & 16)
24518+ {
24519+ /* get extra bits for length */
24520+ e &= 15;
24521+ c = t->base + ((uInt)b & inflate_mask[e]);
24522+ DUMPBITS(e)
24523+ Tracevv((stderr, "inflate: * length %u\n", c));
24524+
24525+ /* decode distance base of block to copy */
24526+ GRABBITS(15); /* max bits for distance code */
24527+ e = (t = td + ((uInt)b & md))->exop;
24528+ do {
24529+ DUMPBITS(t->bits)
24530+ if (e & 16)
24531+ {
24532+ /* get extra bits to add to distance base */
24533+ e &= 15;
24534+ GRABBITS(e) /* get extra bits (up to 13) */
24535+ d = t->base + ((uInt)b & inflate_mask[e]);
24536+ DUMPBITS(e)
24537+ Tracevv((stderr, "inflate: * distance %u\n", d));
24538+
24539+ /* do the copy */
24540+ m -= c;
24541+ r = q - d;
24542+ if (r < s->window) /* wrap if needed */
24543+ {
24544+ do {
24545+ r += s->end - s->window; /* force pointer in window */
24546+ } while (r < s->window); /* covers invalid distances */
24547+ e = s->end - r;
24548+ if (c > e)
24549+ {
24550+ c -= e; /* wrapped copy */
24551+ do {
24552+ *q++ = *r++;
24553+ } while (--e);
24554+ r = s->window;
24555+ do {
24556+ *q++ = *r++;
24557+ } while (--c);
24558+ }
24559+ else /* normal copy */
24560+ {
24561+ *q++ = *r++; c--;
24562+ *q++ = *r++; c--;
24563+ do {
24564+ *q++ = *r++;
24565+ } while (--c);
24566+ }
24567+ }
24568+ else /* normal copy */
24569+ {
24570+ *q++ = *r++; c--;
24571+ *q++ = *r++; c--;
24572+ do {
24573+ *q++ = *r++;
24574+ } while (--c);
24575+ }
24576+ break;
24577+ }
24578+ else if ((e & 64) == 0)
24579+ {
24580+ t += t->base;
24581+ e = (t += ((uInt)b & inflate_mask[e]))->exop;
24582+ }
24583+ else
24584+ {
24585+ z->msg = (char*)"invalid distance code";
24586+ UNGRAB
24587+ UPDATE
24588+ return Z_DATA_ERROR;
24589+ }
24590+ } while (1);
24591+ break;
24592+ }
24593+ if ((e & 64) == 0)
24594+ {
24595+ t += t->base;
24596+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
24597+ {
24598+ DUMPBITS(t->bits)
24599+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24600+ "inflate: * literal '%c'\n" :
24601+ "inflate: * literal 0x%02x\n", t->base));
24602+ *q++ = (Byte)t->base;
24603+ m--;
24604+ break;
24605+ }
24606+ }
24607+ else if (e & 32)
24608+ {
24609+ Tracevv((stderr, "inflate: * end of block\n"));
24610+ UNGRAB
24611+ UPDATE
24612+ return Z_STREAM_END;
24613+ }
24614+ else
24615+ {
24616+ z->msg = (char*)"invalid literal/length code";
24617+ UNGRAB
24618+ UPDATE
24619+ return Z_DATA_ERROR;
24620+ }
24621+ } while (1);
24622+ } while (m >= 258 && n >= 10);
24623+
24624+ /* not enough input or output--restore pointers and return */
24625+ UNGRAB
24626+ UPDATE
24627+ return Z_OK;
24628+}
24629--- /dev/null Tue Mar 11 13:02:56 2003
24630+++ linux/net/ipsec/inffast.h Mon Feb 9 13:51:03 2004
24631@@ -0,0 +1,22 @@
24632+/* inffast.h -- header to use inffast.c
24633+ * Copyright (C) 1995-2002 Mark Adler
24634+ * For conditions of distribution and use, see copyright notice in zlib.h
24635+ */
24636+
24637+/* WARNING: this file should *not* be used by applications. It is
24638+ part of the implementation of the compression library and is
24639+ subject to change. Applications should only use zlib.h.
24640+ */
24641+
24642+#ifndef _INFFAST_H
24643+#define _INFFAST_H
24644+
24645+extern int inflate_fast OF((
24646+ uInt,
24647+ uInt,
24648+ inflate_huft *,
24649+ inflate_huft *,
24650+ inflate_blocks_statef *,
24651+ z_streamp ));
24652+
24653+#endif /* _INFFAST_H */
24654--- /dev/null Tue Mar 11 13:02:56 2003
24655+++ linux/net/ipsec/inffixed.h Mon Feb 9 13:51:03 2004
24656@@ -0,0 +1,151 @@
24657+/* inffixed.h -- table for decoding fixed codes
24658+ * Generated automatically by the maketree.c program
24659+ */
24660+
24661+/* WARNING: this file should *not* be used by applications. It is
24662+ part of the implementation of the compression library and is
24663+ subject to change. Applications should only use zlib.h.
24664+ */
24665+
24666+local uInt fixed_bl = 9;
24667+local uInt fixed_bd = 5;
24668+local inflate_huft fixed_tl[] = {
24669+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24670+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
24671+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
24672+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
24673+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
24674+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
24675+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
24676+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
24677+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24678+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
24679+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
24680+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
24681+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
24682+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
24683+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
24684+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
24685+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24686+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
24687+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
24688+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
24689+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
24690+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
24691+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
24692+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
24693+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24694+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
24695+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
24696+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
24697+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
24698+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
24699+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
24700+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
24701+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24702+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
24703+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
24704+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
24705+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
24706+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
24707+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
24708+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
24709+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24710+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
24711+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
24712+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
24713+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
24714+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
24715+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
24716+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
24717+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24718+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
24719+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
24720+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
24721+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
24722+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
24723+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
24724+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
24725+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24726+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
24727+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
24728+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
24729+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
24730+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
24731+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
24732+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
24733+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24734+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
24735+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
24736+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
24737+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
24738+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
24739+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
24740+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
24741+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24742+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
24743+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
24744+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
24745+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
24746+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
24747+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
24748+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
24749+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24750+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
24751+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
24752+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
24753+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
24754+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
24755+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
24756+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
24757+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24758+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
24759+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
24760+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
24761+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
24762+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
24763+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
24764+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
24765+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24766+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
24767+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
24768+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
24769+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
24770+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
24771+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
24772+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
24773+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24774+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
24775+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
24776+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
24777+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
24778+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
24779+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
24780+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
24781+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24782+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
24783+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
24784+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
24785+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
24786+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
24787+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
24788+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
24789+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24790+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
24791+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
24792+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
24793+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
24794+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
24795+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
24796+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
24797+ };
24798+local inflate_huft fixed_td[] = {
24799+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
24800+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
24801+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
24802+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
24803+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
24804+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
24805+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
24806+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
24807+ };
24808--- /dev/null Tue Mar 11 13:02:56 2003
24809+++ linux/net/ipsec/inflate.c Mon Feb 9 13:51:03 2004
24810@@ -0,0 +1,368 @@
24811+/* inflate.c -- zlib interface to inflate modules
24812+ * Copyright (C) 1995-2002 Mark Adler
24813+ * For conditions of distribution and use, see copyright notice in zlib.h
24814+ */
24815+
24816+#include <zlib/zutil.h>
24817+#include "infblock.h"
24818+
24819+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
24820+
24821+typedef enum {
24822+ METHOD, /* waiting for method byte */
24823+ FLAG, /* waiting for flag byte */
24824+ DICT4, /* four dictionary check bytes to go */
24825+ DICT3, /* three dictionary check bytes to go */
24826+ DICT2, /* two dictionary check bytes to go */
24827+ DICT1, /* one dictionary check byte to go */
24828+ DICT0, /* waiting for inflateSetDictionary */
24829+ BLOCKS, /* decompressing blocks */
24830+ CHECK4, /* four check bytes to go */
24831+ CHECK3, /* three check bytes to go */
24832+ CHECK2, /* two check bytes to go */
24833+ CHECK1, /* one check byte to go */
24834+ DONE, /* finished check, done */
24835+ BAD} /* got an error--stay here */
24836+inflate_mode;
24837+
24838+/* inflate private state */
24839+struct internal_state {
24840+
24841+ /* mode */
24842+ inflate_mode mode; /* current inflate mode */
24843+
24844+ /* mode dependent information */
24845+ union {
24846+ uInt method; /* if FLAGS, method byte */
24847+ struct {
24848+ uLong was; /* computed check value */
24849+ uLong need; /* stream check value */
24850+ } check; /* if CHECK, check values to compare */
24851+ uInt marker; /* if BAD, inflateSync's marker bytes count */
24852+ } sub; /* submode */
24853+
24854+ /* mode independent information */
24855+ int nowrap; /* flag for no wrapper */
24856+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
24857+ inflate_blocks_statef
24858+ *blocks; /* current inflate_blocks state */
24859+
24860+};
24861+
24862+
24863+int ZEXPORT inflateReset(z)
24864+z_streamp z;
24865+{
24866+ if (z == Z_NULL || z->state == Z_NULL)
24867+ return Z_STREAM_ERROR;
24868+ z->total_in = z->total_out = 0;
24869+ z->msg = Z_NULL;
24870+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
24871+ inflate_blocks_reset(z->state->blocks, z, Z_NULL);
24872+ Tracev((stderr, "inflate: reset\n"));
24873+ return Z_OK;
24874+}
24875+
24876+
24877+int ZEXPORT inflateEnd(z)
24878+z_streamp z;
24879+{
24880+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
24881+ return Z_STREAM_ERROR;
24882+ if (z->state->blocks != Z_NULL)
24883+ inflate_blocks_free(z->state->blocks, z);
24884+ ZFREE(z, z->state);
24885+ z->state = Z_NULL;
24886+ Tracev((stderr, "inflate: end\n"));
24887+ return Z_OK;
24888+}
24889+
24890+
24891+int ZEXPORT inflateInit2_(z, w, version, stream_size)
24892+z_streamp z;
24893+int w;
24894+const char *version;
24895+int stream_size;
24896+{
24897+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
24898+ stream_size != sizeof(z_stream))
24899+ return Z_VERSION_ERROR;
24900+
24901+ /* initialize state */
24902+ if (z == Z_NULL)
24903+ return Z_STREAM_ERROR;
24904+ z->msg = Z_NULL;
24905+ if (z->zalloc == Z_NULL)
24906+ {
24907+ return Z_STREAM_ERROR;
24908+/* z->zalloc = zcalloc;
24909+ z->opaque = (voidpf)0;
24910+*/
24911+ }
24912+ if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
24913+ if ((z->state = (struct internal_state FAR *)
24914+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
24915+ return Z_MEM_ERROR;
24916+ z->state->blocks = Z_NULL;
24917+
24918+ /* handle undocumented nowrap option (no zlib header or check) */
24919+ z->state->nowrap = 0;
24920+ if (w < 0)
24921+ {
24922+ w = - w;
24923+ z->state->nowrap = 1;
24924+ }
24925+
24926+ /* set window size */
24927+ if (w < 8 || w > 15)
24928+ {
24929+ inflateEnd(z);
24930+ return Z_STREAM_ERROR;
24931+ }
24932+ z->state->wbits = (uInt)w;
24933+
24934+ /* create inflate_blocks state */
24935+ if ((z->state->blocks =
24936+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
24937+ == Z_NULL)
24938+ {
24939+ inflateEnd(z);
24940+ return Z_MEM_ERROR;
24941+ }
24942+ Tracev((stderr, "inflate: allocated\n"));
24943+
24944+ /* reset state */
24945+ inflateReset(z);
24946+ return Z_OK;
24947+}
24948+
24949+
24950+int ZEXPORT inflateInit_(z, version, stream_size)
24951+z_streamp z;
24952+const char *version;
24953+int stream_size;
24954+{
24955+ return inflateInit2_(z, DEF_WBITS, version, stream_size);
24956+}
24957+
24958+
24959+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
24960+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
24961+
24962+int ZEXPORT inflate(z, f)
24963+z_streamp z;
24964+int f;
24965+{
24966+ int r;
24967+ uInt b;
24968+
24969+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
24970+ return Z_STREAM_ERROR;
24971+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
24972+ r = Z_BUF_ERROR;
24973+ while (1) switch (z->state->mode)
24974+ {
24975+ case METHOD:
24976+ NEEDBYTE
24977+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
24978+ {
24979+ z->state->mode = BAD;
24980+ z->msg = (char*)"unknown compression method";
24981+ z->state->sub.marker = 5; /* can't try inflateSync */
24982+ break;
24983+ }
24984+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
24985+ {
24986+ z->state->mode = BAD;
24987+ z->msg = (char*)"invalid window size";
24988+ z->state->sub.marker = 5; /* can't try inflateSync */
24989+ break;
24990+ }
24991+ z->state->mode = FLAG;
24992+ case FLAG:
24993+ NEEDBYTE
24994+ b = NEXTBYTE;
24995+ if (((z->state->sub.method << 8) + b) % 31)
24996+ {
24997+ z->state->mode = BAD;
24998+ z->msg = (char*)"incorrect header check";
24999+ z->state->sub.marker = 5; /* can't try inflateSync */
25000+ break;
25001+ }
25002+ Tracev((stderr, "inflate: zlib header ok\n"));
25003+ if (!(b & PRESET_DICT))
25004+ {
25005+ z->state->mode = BLOCKS;
25006+ break;
25007+ }
25008+ z->state->mode = DICT4;
25009+ case DICT4:
25010+ NEEDBYTE
25011+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
25012+ z->state->mode = DICT3;
25013+ case DICT3:
25014+ NEEDBYTE
25015+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
25016+ z->state->mode = DICT2;
25017+ case DICT2:
25018+ NEEDBYTE
25019+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
25020+ z->state->mode = DICT1;
25021+ case DICT1:
25022+ NEEDBYTE
25023+ z->state->sub.check.need += (uLong)NEXTBYTE;
25024+ z->adler = z->state->sub.check.need;
25025+ z->state->mode = DICT0;
25026+ return Z_NEED_DICT;
25027+ case DICT0:
25028+ z->state->mode = BAD;
25029+ z->msg = (char*)"need dictionary";
25030+ z->state->sub.marker = 0; /* can try inflateSync */
25031+ return Z_STREAM_ERROR;
25032+ case BLOCKS:
25033+ r = inflate_blocks(z->state->blocks, z, r);
25034+ if (r == Z_DATA_ERROR)
25035+ {
25036+ z->state->mode = BAD;
25037+ z->state->sub.marker = 0; /* can try inflateSync */
25038+ break;
25039+ }
25040+ if (r == Z_OK)
25041+ r = f;
25042+ if (r != Z_STREAM_END)
25043+ return r;
25044+ r = f;
25045+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
25046+ if (z->state->nowrap)
25047+ {
25048+ z->state->mode = DONE;
25049+ break;
25050+ }
25051+ z->state->mode = CHECK4;
25052+ case CHECK4:
25053+ NEEDBYTE
25054+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
25055+ z->state->mode = CHECK3;
25056+ case CHECK3:
25057+ NEEDBYTE
25058+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
25059+ z->state->mode = CHECK2;
25060+ case CHECK2:
25061+ NEEDBYTE
25062+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
25063+ z->state->mode = CHECK1;
25064+ case CHECK1:
25065+ NEEDBYTE
25066+ z->state->sub.check.need += (uLong)NEXTBYTE;
25067+
25068+ if (z->state->sub.check.was != z->state->sub.check.need)
25069+ {
25070+ z->state->mode = BAD;
25071+ z->msg = (char*)"incorrect data check";
25072+ z->state->sub.marker = 5; /* can't try inflateSync */
25073+ break;
25074+ }
25075+ Tracev((stderr, "inflate: zlib check ok\n"));
25076+ z->state->mode = DONE;
25077+ case DONE:
25078+ return Z_STREAM_END;
25079+ case BAD:
25080+ return Z_DATA_ERROR;
25081+ default:
25082+ return Z_STREAM_ERROR;
25083+ }
25084+#ifdef NEED_DUMMY_RETURN
25085+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
25086+#endif
25087+}
25088+
25089+
25090+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
25091+z_streamp z;
25092+const Bytef *dictionary;
25093+uInt dictLength;
25094+{
25095+ uInt length = dictLength;
25096+
25097+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
25098+ return Z_STREAM_ERROR;
25099+
25100+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
25101+ z->adler = 1L;
25102+
25103+ if (length >= ((uInt)1<<z->state->wbits))
25104+ {
25105+ length = (1<<z->state->wbits)-1;
25106+ dictionary += dictLength - length;
25107+ }
25108+ inflate_set_dictionary(z->state->blocks, dictionary, length);
25109+ z->state->mode = BLOCKS;
25110+ return Z_OK;
25111+}
25112+
25113+
25114+int ZEXPORT inflateSync(z)
25115+z_streamp z;
25116+{
25117+ uInt n; /* number of bytes to look at */
25118+ Bytef *p; /* pointer to bytes */
25119+ uInt m; /* number of marker bytes found in a row */
25120+ uLong r, w; /* temporaries to save total_in and total_out */
25121+
25122+ /* set up */
25123+ if (z == Z_NULL || z->state == Z_NULL)
25124+ return Z_STREAM_ERROR;
25125+ if (z->state->mode != BAD)
25126+ {
25127+ z->state->mode = BAD;
25128+ z->state->sub.marker = 0;
25129+ }
25130+ if ((n = z->avail_in) == 0)
25131+ return Z_BUF_ERROR;
25132+ p = z->next_in;
25133+ m = z->state->sub.marker;
25134+
25135+ /* search */
25136+ while (n && m < 4)
25137+ {
25138+ static const Byte mark[4] = {0, 0, 0xff, 0xff};
25139+ if (*p == mark[m])
25140+ m++;
25141+ else if (*p)
25142+ m = 0;
25143+ else
25144+ m = 4 - m;
25145+ p++, n--;
25146+ }
25147+
25148+ /* restore */
25149+ z->total_in += p - z->next_in;
25150+ z->next_in = p;
25151+ z->avail_in = n;
25152+ z->state->sub.marker = m;
25153+
25154+ /* return no joy or set up to restart on a new block */
25155+ if (m != 4)
25156+ return Z_DATA_ERROR;
25157+ r = z->total_in; w = z->total_out;
25158+ inflateReset(z);
25159+ z->total_in = r; z->total_out = w;
25160+ z->state->mode = BLOCKS;
25161+ return Z_OK;
25162+}
25163+
25164+
25165+/* Returns true if inflate is currently at the end of a block generated
25166+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
25167+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
25168+ * but removes the length bytes of the resulting empty stored block. When
25169+ * decompressing, PPP checks that at the end of input packet, inflate is
25170+ * waiting for these length bytes.
25171+ */
25172+int ZEXPORT inflateSyncPoint(z)
25173+z_streamp z;
25174+{
25175+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
25176+ return Z_STREAM_ERROR;
25177+ return inflate_blocks_sync_point(z->state->blocks);
25178+}
25179--- /dev/null Tue Mar 11 13:02:56 2003
25180+++ linux/net/ipsec/inftrees.c Mon Feb 9 13:51:03 2004
25181@@ -0,0 +1,454 @@
25182+/* inftrees.c -- generate Huffman trees for efficient decoding
25183+ * Copyright (C) 1995-2002 Mark Adler
25184+ * For conditions of distribution and use, see copyright notice in zlib.h
25185+ */
25186+
25187+#include <zlib/zutil.h>
25188+#include "inftrees.h"
25189+
25190+#if !defined(BUILDFIXED) && !defined(STDC)
25191+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
25192+#endif
25193+
25194+local const char inflate_copyright[] =
25195+ " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
25196+/*
25197+ If you use the zlib library in a product, an acknowledgment is welcome
25198+ in the documentation of your product. If for some reason you cannot
25199+ include such an acknowledgment, I would appreciate that you keep this
25200+ copyright string in the executable of your product.
25201+ */
25202+struct internal_state {int dummy;}; /* for buggy compilers */
25203+
25204+/* simplify the use of the inflate_huft type with some defines */
25205+#define exop word.what.Exop
25206+#define bits word.what.Bits
25207+
25208+
25209+local int huft_build OF((
25210+ uIntf *, /* code lengths in bits */
25211+ uInt, /* number of codes */
25212+ uInt, /* number of "simple" codes */
25213+ const uIntf *, /* list of base values for non-simple codes */
25214+ const uIntf *, /* list of extra bits for non-simple codes */
25215+ inflate_huft * FAR*,/* result: starting table */
25216+ uIntf *, /* maximum lookup bits (returns actual) */
25217+ inflate_huft *, /* space for trees */
25218+ uInt *, /* hufts used in space */
25219+ uIntf * )); /* space for values */
25220+
25221+/* Tables for deflate from PKZIP's appnote.txt. */
25222+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
25223+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
25224+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
25225+ /* see note #13 above about 258 */
25226+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
25227+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
25228+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
25229+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
25230+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
25231+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
25232+ 8193, 12289, 16385, 24577};
25233+local const uInt cpdext[30] = { /* Extra bits for distance codes */
25234+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
25235+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
25236+ 12, 12, 13, 13};
25237+
25238+/*
25239+ Huffman code decoding is performed using a multi-level table lookup.
25240+ The fastest way to decode is to simply build a lookup table whose
25241+ size is determined by the longest code. However, the time it takes
25242+ to build this table can also be a factor if the data being decoded
25243+ is not very long. The most common codes are necessarily the
25244+ shortest codes, so those codes dominate the decoding time, and hence
25245+ the speed. The idea is you can have a shorter table that decodes the
25246+ shorter, more probable codes, and then point to subsidiary tables for
25247+ the longer codes. The time it costs to decode the longer codes is
25248+ then traded against the time it takes to make longer tables.
25249+
25250+ This results of this trade are in the variables lbits and dbits
25251+ below. lbits is the number of bits the first level table for literal/
25252+ length codes can decode in one step, and dbits is the same thing for
25253+ the distance codes. Subsequent tables are also less than or equal to
25254+ those sizes. These values may be adjusted either when all of the
25255+ codes are shorter than that, in which case the longest code length in
25256+ bits is used, or when the shortest code is *longer* than the requested
25257+ table size, in which case the length of the shortest code in bits is
25258+ used.
25259+
25260+ There are two different values for the two tables, since they code a
25261+ different number of possibilities each. The literal/length table
25262+ codes 286 possible values, or in a flat code, a little over eight
25263+ bits. The distance table codes 30 possible values, or a little less
25264+ than five bits, flat. The optimum values for speed end up being
25265+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
25266+ The optimum values may differ though from machine to machine, and
25267+ possibly even between compilers. Your mileage may vary.
25268+ */
25269+
25270+
25271+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
25272+#define BMAX 15 /* maximum bit length of any code */
25273+
25274+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
25275+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
25276+uInt n; /* number of codes (assumed <= 288) */
25277+uInt s; /* number of simple-valued codes (0..s-1) */
25278+const uIntf *d; /* list of base values for non-simple codes */
25279+const uIntf *e; /* list of extra bits for non-simple codes */
25280+inflate_huft * FAR *t; /* result: starting table */
25281+uIntf *m; /* maximum lookup bits, returns actual */
25282+inflate_huft *hp; /* space for trees */
25283+uInt *hn; /* hufts used in space */
25284+uIntf *v; /* working area: values in order of bit length */
25285+/* Given a list of code lengths and a maximum table size, make a set of
25286+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
25287+ if the given code set is incomplete (the tables are still built in this
25288+ case), or Z_DATA_ERROR if the input is invalid. */
25289+{
25290+
25291+ uInt a; /* counter for codes of length k */
25292+ uInt c[BMAX+1]; /* bit length count table */
25293+ uInt f; /* i repeats in table every f entries */
25294+ int g; /* maximum code length */
25295+ int h; /* table level */
25296+ register uInt i; /* counter, current code */
25297+ register uInt j; /* counter */
25298+ register int k; /* number of bits in current code */
25299+ int l; /* bits per table (returned in m) */
25300+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
25301+ register uIntf *p; /* pointer into c[], b[], or v[] */
25302+ inflate_huft *q; /* points to current table */
25303+ struct inflate_huft_s r; /* table entry for structure assignment */
25304+ inflate_huft *u[BMAX]; /* table stack */
25305+ register int w; /* bits before this table == (l * h) */
25306+ uInt x[BMAX+1]; /* bit offsets, then code stack */
25307+ uIntf *xp; /* pointer into x */
25308+ int y; /* number of dummy codes added */
25309+ uInt z; /* number of entries in current table */
25310+
25311+
25312+ /* Generate counts for each bit length */
25313+ p = c;
25314+#define C0 *p++ = 0;
25315+#define C2 C0 C0 C0 C0
25316+#define C4 C2 C2 C2 C2
25317+ C4 /* clear c[]--assume BMAX+1 is 16 */
25318+ p = b; i = n;
25319+ do {
25320+ c[*p++]++; /* assume all entries <= BMAX */
25321+ } while (--i);
25322+ if (c[0] == n) /* null input--all zero length codes */
25323+ {
25324+ *t = (inflate_huft *)Z_NULL;
25325+ *m = 0;
25326+ return Z_OK;
25327+ }
25328+
25329+
25330+ /* Find minimum and maximum length, bound *m by those */
25331+ l = *m;
25332+ for (j = 1; j <= BMAX; j++)
25333+ if (c[j])
25334+ break;
25335+ k = j; /* minimum code length */
25336+ if ((uInt)l < j)
25337+ l = j;
25338+ for (i = BMAX; i; i--)
25339+ if (c[i])
25340+ break;
25341+ g = i; /* maximum code length */
25342+ if ((uInt)l > i)
25343+ l = i;
25344+ *m = l;
25345+
25346+
25347+ /* Adjust last length count to fill out codes, if needed */
25348+ for (y = 1 << j; j < i; j++, y <<= 1)
25349+ if ((y -= c[j]) < 0)
25350+ return Z_DATA_ERROR;
25351+ if ((y -= c[i]) < 0)
25352+ return Z_DATA_ERROR;
25353+ c[i] += y;
25354+
25355+
25356+ /* Generate starting offsets into the value table for each length */
25357+ x[1] = j = 0;
25358+ p = c + 1; xp = x + 2;
25359+ while (--i) { /* note that i == g from above */
25360+ *xp++ = (j += *p++);
25361+ }
25362+
25363+
25364+ /* Make a table of values in order of bit lengths */
25365+ p = b; i = 0;
25366+ do {
25367+ if ((j = *p++) != 0)
25368+ v[x[j]++] = i;
25369+ } while (++i < n);
25370+ n = x[g]; /* set n to length of v */
25371+
25372+
25373+ /* Generate the Huffman codes and for each, make the table entries */
25374+ x[0] = i = 0; /* first Huffman code is zero */
25375+ p = v; /* grab values in bit order */
25376+ h = -1; /* no tables yet--level -1 */
25377+ w = -l; /* bits decoded == (l * h) */
25378+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
25379+ q = (inflate_huft *)Z_NULL; /* ditto */
25380+ z = 0; /* ditto */
25381+
25382+ /* go through the bit lengths (k already is bits in shortest code) */
25383+ for (; k <= g; k++)
25384+ {
25385+ a = c[k];
25386+ while (a--)
25387+ {
25388+ /* here i is the Huffman code of length k bits for value *p */
25389+ /* make tables up to required level */
25390+ while (k > w + l)
25391+ {
25392+ h++;
25393+ w += l; /* previous table always l bits */
25394+
25395+ /* compute minimum size table less than or equal to l bits */
25396+ z = g - w;
25397+ z = z > (uInt)l ? l : z; /* table size upper limit */
25398+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
25399+ { /* too few codes for k-w bit table */
25400+ f -= a + 1; /* deduct codes from patterns left */
25401+ xp = c + k;
25402+ if (j < z)
25403+ while (++j < z) /* try smaller tables up to z bits */
25404+ {
25405+ if ((f <<= 1) <= *++xp)
25406+ break; /* enough codes to use up j bits */
25407+ f -= *xp; /* else deduct codes from patterns */
25408+ }
25409+ }
25410+ z = 1 << j; /* table entries for j-bit table */
25411+
25412+ /* allocate new table */
25413+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
25414+ return Z_DATA_ERROR; /* overflow of MANY */
25415+ u[h] = q = hp + *hn;
25416+ *hn += z;
25417+
25418+ /* connect to last table, if there is one */
25419+ if (h)
25420+ {
25421+ x[h] = i; /* save pattern for backing up */
25422+ r.bits = (Byte)l; /* bits to dump before this table */
25423+ r.exop = (Byte)j; /* bits in this table */
25424+ j = i >> (w - l);
25425+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
25426+ u[h-1][j] = r; /* connect to last table */
25427+ }
25428+ else
25429+ *t = q; /* first table is returned result */
25430+ }
25431+
25432+ /* set up table entry in r */
25433+ r.bits = (Byte)(k - w);
25434+ if (p >= v + n)
25435+ r.exop = 128 + 64; /* out of values--invalid code */
25436+ else if (*p < s)
25437+ {
25438+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
25439+ r.base = *p++; /* simple code is just the value */
25440+ }
25441+ else
25442+ {
25443+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
25444+ r.base = d[*p++ - s];
25445+ }
25446+
25447+ /* fill code-like entries with r */
25448+ f = 1 << (k - w);
25449+ for (j = i >> w; j < z; j += f)
25450+ q[j] = r;
25451+
25452+ /* backwards increment the k-bit code i */
25453+ for (j = 1 << (k - 1); i & j; j >>= 1)
25454+ i ^= j;
25455+ i ^= j;
25456+
25457+ /* backup over finished tables */
25458+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */
25459+ while ((i & mask) != x[h])
25460+ {
25461+ h--; /* don't need to update q */
25462+ w -= l;
25463+ mask = (1 << w) - 1;
25464+ }
25465+ }
25466+ }
25467+
25468+
25469+ /* Return Z_BUF_ERROR if we were given an incomplete table */
25470+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
25471+}
25472+
25473+
25474+int inflate_trees_bits(c, bb, tb, hp, z)
25475+uIntf *c; /* 19 code lengths */
25476+uIntf *bb; /* bits tree desired/actual depth */
25477+inflate_huft * FAR *tb; /* bits tree result */
25478+inflate_huft *hp; /* space for trees */
25479+z_streamp z; /* for messages */
25480+{
25481+ int r;
25482+ uInt hn = 0; /* hufts used in space */
25483+ uIntf *v; /* work area for huft_build */
25484+
25485+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
25486+ return Z_MEM_ERROR;
25487+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
25488+ tb, bb, hp, &hn, v);
25489+ if (r == Z_DATA_ERROR)
25490+ z->msg = (char*)"oversubscribed dynamic bit lengths tree";
25491+ else if (r == Z_BUF_ERROR || *bb == 0)
25492+ {
25493+ z->msg = (char*)"incomplete dynamic bit lengths tree";
25494+ r = Z_DATA_ERROR;
25495+ }
25496+ ZFREE(z, v);
25497+ return r;
25498+}
25499+
25500+
25501+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
25502+uInt nl; /* number of literal/length codes */
25503+uInt nd; /* number of distance codes */
25504+uIntf *c; /* that many (total) code lengths */
25505+uIntf *bl; /* literal desired/actual bit depth */
25506+uIntf *bd; /* distance desired/actual bit depth */
25507+inflate_huft * FAR *tl; /* literal/length tree result */
25508+inflate_huft * FAR *td; /* distance tree result */
25509+inflate_huft *hp; /* space for trees */
25510+z_streamp z; /* for messages */
25511+{
25512+ int r;
25513+ uInt hn = 0; /* hufts used in space */
25514+ uIntf *v; /* work area for huft_build */
25515+
25516+ /* allocate work area */
25517+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25518+ return Z_MEM_ERROR;
25519+
25520+ /* build literal/length tree */
25521+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
25522+ if (r != Z_OK || *bl == 0)
25523+ {
25524+ if (r == Z_DATA_ERROR)
25525+ z->msg = (char*)"oversubscribed literal/length tree";
25526+ else if (r != Z_MEM_ERROR)
25527+ {
25528+ z->msg = (char*)"incomplete literal/length tree";
25529+ r = Z_DATA_ERROR;
25530+ }
25531+ ZFREE(z, v);
25532+ return r;
25533+ }
25534+
25535+ /* build distance tree */
25536+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
25537+ if (r != Z_OK || (*bd == 0 && nl > 257))
25538+ {
25539+ if (r == Z_DATA_ERROR)
25540+ z->msg = (char*)"oversubscribed distance tree";
25541+ else if (r == Z_BUF_ERROR) {
25542+#ifdef PKZIP_BUG_WORKAROUND
25543+ r = Z_OK;
25544+ }
25545+#else
25546+ z->msg = (char*)"incomplete distance tree";
25547+ r = Z_DATA_ERROR;
25548+ }
25549+ else if (r != Z_MEM_ERROR)
25550+ {
25551+ z->msg = (char*)"empty distance tree with lengths";
25552+ r = Z_DATA_ERROR;
25553+ }
25554+ ZFREE(z, v);
25555+ return r;
25556+#endif
25557+ }
25558+
25559+ /* done */
25560+ ZFREE(z, v);
25561+ return Z_OK;
25562+}
25563+
25564+
25565+/* build fixed tables only once--keep them here */
25566+#ifdef BUILDFIXED
25567+local int fixed_built = 0;
25568+#define FIXEDH 544 /* number of hufts used by fixed tables */
25569+local inflate_huft fixed_mem[FIXEDH];
25570+local uInt fixed_bl;
25571+local uInt fixed_bd;
25572+local inflate_huft *fixed_tl;
25573+local inflate_huft *fixed_td;
25574+#else
25575+#include "inffixed.h"
25576+#endif
25577+
25578+
25579+int inflate_trees_fixed(bl, bd, tl, td, z)
25580+uIntf *bl; /* literal desired/actual bit depth */
25581+uIntf *bd; /* distance desired/actual bit depth */
25582+inflate_huft * FAR *tl; /* literal/length tree result */
25583+inflate_huft * FAR *td; /* distance tree result */
25584+z_streamp z; /* for memory allocation */
25585+{
25586+#ifdef BUILDFIXED
25587+ /* build fixed tables if not already */
25588+ if (!fixed_built)
25589+ {
25590+ int k; /* temporary variable */
25591+ uInt f = 0; /* number of hufts used in fixed_mem */
25592+ uIntf *c; /* length list for huft_build */
25593+ uIntf *v; /* work area for huft_build */
25594+
25595+ /* allocate memory */
25596+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25597+ return Z_MEM_ERROR;
25598+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25599+ {
25600+ ZFREE(z, c);
25601+ return Z_MEM_ERROR;
25602+ }
25603+
25604+ /* literal table */
25605+ for (k = 0; k < 144; k++)
25606+ c[k] = 8;
25607+ for (; k < 256; k++)
25608+ c[k] = 9;
25609+ for (; k < 280; k++)
25610+ c[k] = 7;
25611+ for (; k < 288; k++)
25612+ c[k] = 8;
25613+ fixed_bl = 9;
25614+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
25615+ fixed_mem, &f, v);
25616+
25617+ /* distance table */
25618+ for (k = 0; k < 30; k++)
25619+ c[k] = 5;
25620+ fixed_bd = 5;
25621+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
25622+ fixed_mem, &f, v);
25623+
25624+ /* done */
25625+ ZFREE(z, v);
25626+ ZFREE(z, c);
25627+ fixed_built = 1;
25628+ }
25629+#endif
25630+ *bl = fixed_bl;
25631+ *bd = fixed_bd;
25632+ *tl = fixed_tl;
25633+ *td = fixed_td;
25634+ return Z_OK;
25635+}
25636--- /dev/null Tue Mar 11 13:02:56 2003
25637+++ linux/net/ipsec/inftrees.h Mon Feb 9 13:51:03 2004
25638@@ -0,0 +1,63 @@
25639+/* inftrees.h -- header to use inftrees.c
25640+ * Copyright (C) 1995-2002 Mark Adler
25641+ * For conditions of distribution and use, see copyright notice in zlib.h
25642+ */
25643+
25644+/* WARNING: this file should *not* be used by applications. It is
25645+ part of the implementation of the compression library and is
25646+ subject to change. Applications should only use zlib.h.
25647+ */
25648+
25649+/* Huffman code lookup table entry--this entry is four bytes for machines
25650+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
25651+
25652+#ifndef _INFTREES_H
25653+#define _INFTREES_H
25654+
25655+typedef struct inflate_huft_s FAR inflate_huft;
25656+
25657+struct inflate_huft_s {
25658+ union {
25659+ struct {
25660+ Byte Exop; /* number of extra bits or operation */
25661+ Byte Bits; /* number of bits in this code or subcode */
25662+ } what;
25663+ uInt pad; /* pad structure to a power of 2 (4 bytes for */
25664+ } word; /* 16-bit, 8 bytes for 32-bit int's) */
25665+ uInt base; /* literal, length base, distance base,
25666+ or table offset */
25667+};
25668+
25669+/* Maximum size of dynamic tree. The maximum found in a long but non-
25670+ exhaustive search was 1004 huft structures (850 for length/literals
25671+ and 154 for distances, the latter actually the result of an
25672+ exhaustive search). The actual maximum is not known, but the
25673+ value below is more than safe. */
25674+#define MANY 1440
25675+
25676+extern int inflate_trees_bits OF((
25677+ uIntf *, /* 19 code lengths */
25678+ uIntf *, /* bits tree desired/actual depth */
25679+ inflate_huft * FAR *, /* bits tree result */
25680+ inflate_huft *, /* space for trees */
25681+ z_streamp)); /* for messages */
25682+
25683+extern int inflate_trees_dynamic OF((
25684+ uInt, /* number of literal/length codes */
25685+ uInt, /* number of distance codes */
25686+ uIntf *, /* that many (total) code lengths */
25687+ uIntf *, /* literal desired/actual bit depth */
25688+ uIntf *, /* distance desired/actual bit depth */
25689+ inflate_huft * FAR *, /* literal/length tree result */
25690+ inflate_huft * FAR *, /* distance tree result */
25691+ inflate_huft *, /* space for trees */
25692+ z_streamp)); /* for messages */
25693+
25694+extern int inflate_trees_fixed OF((
25695+ uIntf *, /* literal desired/actual bit depth */
25696+ uIntf *, /* distance desired/actual bit depth */
25697+ inflate_huft * FAR *, /* literal/length tree result */
25698+ inflate_huft * FAR *, /* distance tree result */
25699+ z_streamp)); /* for memory allocation */
25700+
25701+#endif /* _INFTREES_H */
25702--- /dev/null Tue Mar 11 13:02:56 2003
25703+++ linux/net/ipsec/infutil.c Mon Feb 9 13:51:03 2004
25704@@ -0,0 +1,87 @@
25705+/* inflate_util.c -- data and routines common to blocks and codes
25706+ * Copyright (C) 1995-2002 Mark Adler
25707+ * For conditions of distribution and use, see copyright notice in zlib.h
25708+ */
25709+
25710+#include <zlib/zutil.h>
25711+#include "infblock.h"
25712+#include "inftrees.h"
25713+#include "infcodes.h"
25714+#include "infutil.h"
25715+
25716+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
25717+
25718+/* And'ing with mask[n] masks the lower n bits */
25719+uInt inflate_mask[17] = {
25720+ 0x0000,
25721+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
25722+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
25723+};
25724+
25725+
25726+/* copy as much as possible from the sliding window to the output area */
25727+int inflate_flush(s, z, r)
25728+inflate_blocks_statef *s;
25729+z_streamp z;
25730+int r;
25731+{
25732+ uInt n;
25733+ Bytef *p;
25734+ Bytef *q;
25735+
25736+ /* local copies of source and destination pointers */
25737+ p = z->next_out;
25738+ q = s->read;
25739+
25740+ /* compute number of bytes to copy as far as end of window */
25741+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
25742+ if (n > z->avail_out) n = z->avail_out;
25743+ if (n && r == Z_BUF_ERROR) r = Z_OK;
25744+
25745+ /* update counters */
25746+ z->avail_out -= n;
25747+ z->total_out += n;
25748+
25749+ /* update check information */
25750+ if (s->checkfn != Z_NULL)
25751+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
25752+
25753+ /* copy as far as end of window */
25754+ zmemcpy(p, q, n);
25755+ p += n;
25756+ q += n;
25757+
25758+ /* see if more to copy at beginning of window */
25759+ if (q == s->end)
25760+ {
25761+ /* wrap pointers */
25762+ q = s->window;
25763+ if (s->write == s->end)
25764+ s->write = s->window;
25765+
25766+ /* compute bytes to copy */
25767+ n = (uInt)(s->write - q);
25768+ if (n > z->avail_out) n = z->avail_out;
25769+ if (n && r == Z_BUF_ERROR) r = Z_OK;
25770+
25771+ /* update counters */
25772+ z->avail_out -= n;
25773+ z->total_out += n;
25774+
25775+ /* update check information */
25776+ if (s->checkfn != Z_NULL)
25777+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
25778+
25779+ /* copy */
25780+ zmemcpy(p, q, n);
25781+ p += n;
25782+ q += n;
25783+ }
25784+
25785+ /* update pointers */
25786+ z->next_out = p;
25787+ s->read = q;
25788+
25789+ /* done */
25790+ return r;
25791+}
25792--- /dev/null Tue Mar 11 13:02:56 2003
25793+++ linux/net/ipsec/infutil.h Mon Feb 9 13:51:03 2004
25794@@ -0,0 +1,98 @@
25795+/* infutil.h -- types and macros common to blocks and codes
25796+ * Copyright (C) 1995-2002 Mark Adler
25797+ * For conditions of distribution and use, see copyright notice in zlib.h
25798+ */
25799+
25800+/* WARNING: this file should *not* be used by applications. It is
25801+ part of the implementation of the compression library and is
25802+ subject to change. Applications should only use zlib.h.
25803+ */
25804+
25805+#ifndef _INFUTIL_H
25806+#define _INFUTIL_H
25807+
25808+typedef enum {
25809+ TYPE, /* get type bits (3, including end bit) */
25810+ LENS, /* get lengths for stored */
25811+ STORED, /* processing stored block */
25812+ TABLE, /* get table lengths */
25813+ BTREE, /* get bit lengths tree for a dynamic block */
25814+ DTREE, /* get length, distance trees for a dynamic block */
25815+ CODES, /* processing fixed or dynamic block */
25816+ DRY, /* output remaining window bytes */
25817+ DONE, /* finished last block, done */
25818+ BAD} /* got a data error--stuck here */
25819+inflate_block_mode;
25820+
25821+/* inflate blocks semi-private state */
25822+struct inflate_blocks_state {
25823+
25824+ /* mode */
25825+ inflate_block_mode mode; /* current inflate_block mode */
25826+
25827+ /* mode dependent information */
25828+ union {
25829+ uInt left; /* if STORED, bytes left to copy */
25830+ struct {
25831+ uInt table; /* table lengths (14 bits) */
25832+ uInt index; /* index into blens (or border) */
25833+ uIntf *blens; /* bit lengths of codes */
25834+ uInt bb; /* bit length tree depth */
25835+ inflate_huft *tb; /* bit length decoding tree */
25836+ } trees; /* if DTREE, decoding info for trees */
25837+ struct {
25838+ inflate_codes_statef
25839+ *codes;
25840+ } decode; /* if CODES, current state */
25841+ } sub; /* submode */
25842+ uInt last; /* true if this block is the last block */
25843+
25844+ /* mode independent information */
25845+ uInt bitk; /* bits in bit buffer */
25846+ uLong bitb; /* bit buffer */
25847+ inflate_huft *hufts; /* single malloc for tree space */
25848+ Bytef *window; /* sliding window */
25849+ Bytef *end; /* one byte after sliding window */
25850+ Bytef *read; /* window read pointer */
25851+ Bytef *write; /* window write pointer */
25852+ check_func checkfn; /* check function */
25853+ uLong check; /* check on output */
25854+
25855+};
25856+
25857+
25858+/* defines for inflate input/output */
25859+/* update pointers and return */
25860+#define UPDBITS {s->bitb=b;s->bitk=k;}
25861+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
25862+#define UPDOUT {s->write=q;}
25863+#define UPDATE {UPDBITS UPDIN UPDOUT}
25864+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
25865+/* get bytes and bits */
25866+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
25867+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
25868+#define NEXTBYTE (n--,*p++)
25869+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
25870+#define DUMPBITS(j) {b>>=(j);k-=(j);}
25871+/* output bytes */
25872+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
25873+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
25874+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
25875+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
25876+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
25877+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
25878+/* load local pointers */
25879+#define LOAD {LOADIN LOADOUT}
25880+
25881+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
25882+extern uInt inflate_mask[17];
25883+
25884+/* copy as much as possible from the sliding window to the output area */
25885+extern int inflate_flush OF((
25886+ inflate_blocks_statef *,
25887+ z_streamp ,
25888+ int));
25889+
25890+struct internal_state {int dummy;}; /* for buggy compilers */
25891+
25892+#endif /* _INFUTIL_H */
25893--- /dev/null Tue Mar 11 13:02:56 2003
25894+++ linux/net/ipsec/initaddr.c Mon Feb 9 13:51:03 2004
25895@@ -0,0 +1,50 @@
25896+/*
25897+ * initialize address structure
25898+ * Copyright (C) 2000 Henry Spencer.
25899+ *
25900+ * This library is free software; you can redistribute it and/or modify it
25901+ * under the terms of the GNU Library General Public License as published by
25902+ * the Free Software Foundation; either version 2 of the License, or (at your
25903+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
25904+ *
25905+ * This library is distributed in the hope that it will be useful, but
25906+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25907+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
25908+ * License for more details.
25909+ *
25910+ * RCSID $Id: initaddr.c,v 1.6 2004/07/10 07:43:47 mcr Exp $
25911+ */
25912+#include "openswan.h"
25913+
25914+/*
25915+ - initaddr - initialize ip_address from bytes
25916+ */
25917+err_t /* NULL for success, else string literal */
25918+initaddr(src, srclen, af, dst)
25919+const unsigned char *src;
25920+size_t srclen;
25921+int af; /* address family */
25922+ip_address *dst;
25923+{
25924+ switch (af) {
25925+ case AF_INET:
25926+ if (srclen != 4)
25927+ return "IPv4 address must be exactly 4 bytes";
25928+ dst->u.v4.sin_family = af;
25929+ dst->u.v4.sin_port = 0; /* unused */
25930+ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
25931+ break;
25932+ case AF_INET6:
25933+ if (srclen != 16)
25934+ return "IPv6 address must be exactly 16 bytes";
25935+ dst->u.v6.sin6_family = af;
25936+ dst->u.v6.sin6_flowinfo = 0; /* unused */
25937+ dst->u.v6.sin6_port = 0; /* unused */
25938+ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
25939+ break;
25940+ default:
25941+ return "unknown address family in initaddr";
25942+ break;
25943+ }
25944+ return NULL;
25945+}
25946--- /dev/null Tue Mar 11 13:02:56 2003
25947+++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004
25948@@ -0,0 +1,701 @@
25949+/*
25950+ * IPCOMP zlib interface code.
25951+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
25952+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
25953+ *
25954+ * This program is free software; you can redistribute it and/or modify it
25955+ * under the terms of the GNU General Public License as published by the
25956+ * Free Software Foundation; either version 2 of the License, or (at your
25957+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
25958+ *
25959+ * This program is distributed in the hope that it will be useful, but
25960+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25961+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25962+ * for more details.
25963+ */
25964+
25965+char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.41.2.5 2006/10/06 21:39:26 paul Exp $";
25966+
25967+/* SSS */
25968+
25969+#ifndef AUTOCONF_INCLUDED
25970+#include <linux/config.h>
25971+#endif
25972+#include <linux/version.h>
25973+
25974+#define __NO_VERSION__
25975+#include <linux/module.h>
25976+#include <linux/kernel.h> /* printk() */
25977+
25978+#include "openswan/ipsec_param.h"
25979+
25980+#ifdef MALLOC_SLAB
25981+# include <linux/slab.h> /* kmalloc() */
25982+#else /* MALLOC_SLAB */
25983+# include <linux/malloc.h> /* kmalloc() */
25984+#endif /* MALLOC_SLAB */
25985+#include <linux/errno.h> /* error codes */
25986+#include <linux/types.h>
25987+#include <linux/netdevice.h>
25988+#include <linux/ip.h>
25989+#include <linux/skbuff.h>
25990+
25991+#include <linux/netdevice.h> /* struct device, and other headers */
25992+#include <linux/etherdevice.h> /* eth_type_trans */
25993+#include <linux/ip.h> /* struct iphdr */
25994+#include <linux/skbuff.h>
25995+#include <asm/uaccess.h>
25996+#include <asm/checksum.h>
25997+
25998+#include <openswan.h>
25999+
26000+#include <net/ip.h>
26001+
26002+#include "openswan/radij.h"
26003+#include "openswan/ipsec_encap.h"
26004+#include "openswan/ipsec_sa.h"
26005+
26006+#include "openswan/ipsec_xform.h"
26007+#include "openswan/ipsec_tunnel.h"
26008+#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
26009+#include "openswan/ipsec_proto.h"
26010+#include "openswan/ipcomp.h"
26011+#include "zlib/zlib.h"
26012+#include "zlib/zutil.h"
26013+
26014+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
26015+
26016+#ifdef CONFIG_KLIPS_DEBUG
26017+int sysctl_ipsec_debug_ipcomp = 0;
26018+#endif /* CONFIG_KLIPS_DEBUG */
26019+
26020+static
26021+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
26022+
26023+static
26024+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
26025+{
26026+ return (voidpf) kmalloc(items*size, GFP_ATOMIC);
26027+}
26028+
26029+static
26030+void my_zfree(voidpf opaque, voidpf address)
26031+{
26032+ kfree(address);
26033+}
26034+
26035+/*
26036+ * We use this function because sometimes we want to pass a negative offset
26037+ * into skb_put(), this does not work on 64bit platforms because long to
26038+ * unsigned int casting.
26039+ */
26040+static inline unsigned char *
26041+safe_skb_put(struct sk_buff *skb, int extend)
26042+{
26043+ unsigned char *ptr;
26044+
26045+ if (extend>0) {
26046+ // increase the size of the packet
26047+ ptr = skb_put(skb, extend);
26048+ } else {
26049+ // shrink the size of the packet
26050+ ptr = skb->tail;
26051+ skb_trim (skb, skb->len + extend);
26052+ }
26053+
26054+ return ptr;
26055+}
26056+
26057+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
26058+{
26059+ struct iphdr *iph;
26060+ unsigned int iphlen, pyldsz, cpyldsz;
26061+ unsigned char *buffer;
26062+ z_stream zs;
26063+ int zresult;
26064+
26065+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26066+ "klips_debug:skb_compress: .\n");
26067+
26068+ if(skb == NULL) {
26069+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26070+ "klips_debug:skb_compress: "
26071+ "passed in NULL skb, returning ERROR.\n");
26072+ if(flags != NULL) {
26073+ *flags |= IPCOMP_PARMERROR;
26074+ }
26075+ return skb;
26076+ }
26077+
26078+ if(ips == NULL) {
26079+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26080+ "klips_debug:skb_compress: "
26081+ "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
26082+ if(flags) {
26083+ *flags |= IPCOMP_PARMERROR;
26084+ }
26085+ return skb;
26086+ }
26087+
26088+ if (flags == NULL) {
26089+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26090+ "klips_debug:skb_compress: "
26091+ "passed in NULL flags, returning ERROR.\n");
26092+ ipsec_kfree_skb(skb);
26093+ return NULL;
26094+ }
26095+
26096+#ifdef NET_21
26097+ iph = skb->nh.iph;
26098+#else /* NET_21 */
26099+ iph = skb->ip_hdr;
26100+#endif /* NET_21 */
26101+
26102+ switch (iph->protocol) {
26103+ case IPPROTO_COMP:
26104+ case IPPROTO_AH:
26105+ case IPPROTO_ESP:
26106+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26107+ "klips_debug:skb_compress: "
26108+ "skipping compression of packet with ip protocol %d.\n",
26109+ iph->protocol);
26110+ *flags |= IPCOMP_UNCOMPRESSABLE;
26111+ return skb;
26112+ }
26113+
26114+ /* Don't compress packets already fragmented */
26115+ if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
26116+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26117+ "klips_debug:skb_compress: "
26118+ "skipping compression of fragmented packet.\n");
26119+ *flags |= IPCOMP_UNCOMPRESSABLE;
26120+ return skb;
26121+ }
26122+
26123+ iphlen = iph->ihl << 2;
26124+ pyldsz = ntohs(iph->tot_len) - iphlen;
26125+
26126+ /* Don't compress less than 90 bytes (rfc 2394) */
26127+ if (pyldsz < 90) {
26128+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26129+ "klips_debug:skb_compress: "
26130+ "skipping compression of tiny packet, len=%d.\n",
26131+ pyldsz);
26132+ *flags |= IPCOMP_UNCOMPRESSABLE;
26133+ return skb;
26134+ }
26135+
26136+ /* Adaptive decision */
26137+ if (ips->ips_comp_adapt_skip) {
26138+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26139+ "klips_debug:skb_compress: "
26140+ "skipping compression: ips_comp_adapt_skip=%d.\n",
26141+ ips->ips_comp_adapt_skip);
26142+ ips->ips_comp_adapt_skip--;
26143+ *flags |= IPCOMP_UNCOMPRESSABLE;
26144+ return skb;
26145+ }
26146+
26147+ zs.zalloc = my_zcalloc;
26148+ zs.zfree = my_zfree;
26149+ zs.opaque = 0;
26150+
26151+ /* We want to use deflateInit2 because we don't want the adler
26152+ header. */
26153+ zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
26154+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
26155+ if (zresult != Z_OK) {
26156+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26157+ "klips_error:skb_compress: "
26158+ "deflateInit2() returned error %d (%s), "
26159+ "skipping compression.\n",
26160+ zresult,
26161+ zs.msg ? zs.msg : zError(zresult));
26162+ *flags |= IPCOMP_COMPRESSIONERROR;
26163+ return skb;
26164+ }
26165+
26166+
26167+ /* Max output size. Result should be max this size.
26168+ * Implementation specific tweak:
26169+ * If it's not at least 32 bytes and 6.25% smaller than
26170+ * the original packet, it's probably not worth wasting
26171+ * the receiver's CPU cycles decompressing it.
26172+ * Your mileage may vary.
26173+ */
26174+ cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
26175+
26176+ buffer = kmalloc(cpyldsz, GFP_ATOMIC);
26177+ if (!buffer) {
26178+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26179+ "klips_error:skb_compress: "
26180+ "unable to kmalloc(%d, GFP_ATOMIC), "
26181+ "skipping compression.\n",
26182+ cpyldsz);
26183+ *flags |= IPCOMP_COMPRESSIONERROR;
26184+ deflateEnd(&zs);
26185+ return skb;
26186+ }
26187+
26188+#ifdef CONFIG_KLIPS_DEBUG
26189+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26190+ __u8 *c;
26191+
26192+ c = (__u8*)iph + iphlen;
26193+ ipsec_dmp_block("compress before", c, pyldsz);
26194+ }
26195+#endif /* CONFIG_KLIPS_DEBUG */
26196+
26197+ zs.next_in = (char *) iph + iphlen; /* start of payload */
26198+ zs.avail_in = pyldsz;
26199+ zs.next_out = buffer; /* start of compressed payload */
26200+ zs.avail_out = cpyldsz;
26201+
26202+ /* Finish compression in one step */
26203+ zresult = deflate(&zs, Z_FINISH);
26204+
26205+ /* Free all dynamically allocated buffers */
26206+ deflateEnd(&zs);
26207+ if (zresult != Z_STREAM_END) {
26208+ *flags |= IPCOMP_UNCOMPRESSABLE;
26209+ kfree(buffer);
26210+
26211+ /* Adjust adaptive counters */
26212+ if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
26213+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26214+ "klips_debug:skb_compress: "
26215+ "first %d packets didn't compress, "
26216+ "skipping next %d\n",
26217+ IPCOMP_ADAPT_INITIAL_TRIES,
26218+ IPCOMP_ADAPT_INITIAL_SKIP);
26219+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
26220+ }
26221+ else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
26222+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26223+ "klips_debug:skb_compress: "
26224+ "next %d packets didn't compress, "
26225+ "skipping next %d\n",
26226+ IPCOMP_ADAPT_SUBSEQ_TRIES,
26227+ IPCOMP_ADAPT_SUBSEQ_SKIP);
26228+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
26229+ ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
26230+ }
26231+
26232+ return skb;
26233+ }
26234+
26235+ /* resulting compressed size */
26236+ cpyldsz -= zs.avail_out;
26237+
26238+ /* Insert IPCOMP header */
26239+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
26240+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
26241+ /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
26242+ for internal reference only. */
26243+ ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
26244+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26245+ "klips_debug:skb_compress: "
26246+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
26247+ ntohl(ips->ips_said.spi),
26248+ ntohl(ips->ips_said.spi) & 0x0000ffff,
26249+ ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
26250+ pyldsz,
26251+ cpyldsz);
26252+
26253+ /* Update IP header */
26254+ iph->protocol = IPPROTO_COMP;
26255+ iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
26256+#if 1 /* XXX checksum is done by ipsec_tunnel ? */
26257+ iph->check = 0;
26258+ iph->check = ip_fast_csum((char *) iph, iph->ihl);
26259+#endif
26260+
26261+ /* Copy compressed payload */
26262+ memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
26263+ buffer,
26264+ cpyldsz);
26265+ kfree(buffer);
26266+
26267+ /* Update skb length/tail by "unputting" the shrinkage */
26268+ safe_skb_put (skb, cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
26269+
26270+#ifdef CONFIG_KLIPS_DEBUG
26271+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26272+ __u8 *c;
26273+
26274+ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
26275+ ipsec_dmp_block("compress result", c, cpyldsz);
26276+ }
26277+#endif /* CONFIG_KLIPS_DEBUG */
26278+
26279+ ips->ips_comp_adapt_skip = 0;
26280+ ips->ips_comp_adapt_tries = 0;
26281+
26282+ return skb;
26283+}
26284+
26285+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
26286+{
26287+ struct sk_buff *nskb = NULL;
26288+
26289+ /* original ip header */
26290+ struct iphdr *oiph, *iph;
26291+ unsigned int iphlen, pyldsz, cpyldsz;
26292+ z_stream zs;
26293+ int zresult;
26294+
26295+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26296+ "klips_debug:skb_decompress: .\n");
26297+
26298+ if(!skb) {
26299+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26300+ "klips_error:skb_decompress: "
26301+ "passed in NULL skb, returning ERROR.\n");
26302+ if (flags) *flags |= IPCOMP_PARMERROR;
26303+ return skb;
26304+ }
26305+
26306+ if(!ips && sysctl_ipsec_inbound_policy_check) {
26307+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26308+ "klips_error:skb_decompress: "
26309+ "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
26310+ if (flags) *flags |= IPCOMP_PARMERROR;
26311+ return skb;
26312+ }
26313+
26314+ if (!flags) {
26315+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26316+ "klips_error:skb_decompress: "
26317+ "passed in NULL flags, returning ERROR.\n");
26318+ ipsec_kfree_skb(skb);
26319+ return NULL;
26320+ }
26321+
26322+#ifdef NET_21
26323+ oiph = skb->nh.iph;
26324+#else /* NET_21 */
26325+ oiph = skb->ip_hdr;
26326+#endif /* NET_21 */
26327+
26328+ iphlen = oiph->ihl << 2;
26329+
26330+ if (oiph->protocol != IPPROTO_COMP) {
26331+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26332+ "klips_error:skb_decompress: "
26333+ "called with non-IPCOMP packet (protocol=%d),"
26334+ "skipping decompression.\n",
26335+ oiph->protocol);
26336+ *flags |= IPCOMP_PARMERROR;
26337+ return skb;
26338+ }
26339+
26340+ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
26341+ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
26342+ != htons(SADB_X_CALG_DEFLATE))
26343+ && sysctl_ipsec_inbound_policy_check
26344+ && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
26345+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26346+ "klips_error:skb_decompress: "
26347+ "called with incompatible IPCOMP packet (flags=%d, "
26348+ "cpi=%d), ips-compalg=%d, skipping decompression.\n",
26349+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
26350+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
26351+ ips ? ips->ips_encalg : 0);
26352+ *flags |= IPCOMP_PARMERROR;
26353+
26354+ return skb;
26355+ }
26356+
26357+ if (ntohs(oiph->frag_off) & ~0x4000) {
26358+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26359+ "klips_error:skb_decompress: "
26360+ "called with fragmented IPCOMP packet, "
26361+ "skipping decompression.\n");
26362+ *flags |= IPCOMP_PARMERROR;
26363+ return skb;
26364+ }
26365+
26366+ /* original compressed payload size */
26367+ cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
26368+
26369+ zs.zalloc = my_zcalloc;
26370+ zs.zfree = my_zfree;
26371+ zs.opaque = 0;
26372+
26373+ zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
26374+ zs.avail_in = cpyldsz;
26375+
26376+ /* Maybe we should be a bit conservative about memory
26377+ requirements and use inflateInit2 */
26378+ /* Beware, that this might make us unable to decompress packets
26379+ from other implementations - HINT: check PGPnet source code */
26380+ /* We want to use inflateInit2 because we don't want the adler
26381+ header. */
26382+ zresult = inflateInit2(&zs, -15);
26383+ if (zresult != Z_OK) {
26384+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26385+ "klips_error:skb_decompress: "
26386+ "inflateInit2() returned error %d (%s), "
26387+ "skipping decompression.\n",
26388+ zresult,
26389+ zs.msg ? zs.msg : zError(zresult));
26390+ *flags |= IPCOMP_DECOMPRESSIONERROR;
26391+
26392+ return skb;
26393+ }
26394+
26395+ /* We have no way of knowing the exact length of the resulting
26396+ decompressed output before we have actually done the decompression.
26397+ For now, we guess that the packet will not be bigger than the
26398+ attached ipsec device's mtu or 16260, whichever is biggest.
26399+ This may be wrong, since the sender's mtu may be bigger yet.
26400+ XXX This must be dealt with later XXX
26401+ */
26402+
26403+ /* max payload size */
26404+ pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
26405+ : (65520 - iphlen);
26406+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26407+ "klips_debug:skb_decompress: "
26408+ "max payload size: %d\n", pyldsz);
26409+
26410+ while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
26411+ (nskb = skb_copy_ipcomp(skb,
26412+ pyldsz - cpyldsz - sizeof(struct ipcomphdr),
26413+ GFP_ATOMIC)) == NULL) {
26414+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26415+ "klips_error:skb_decompress: "
26416+ "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
26417+ "trying with less payload size.\n",
26418+ (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
26419+ pyldsz >>=1;
26420+ }
26421+
26422+ if (!nskb) {
26423+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26424+ "klips_error:skb_decompress: "
26425+ "unable to allocate memory, dropping packet.\n");
26426+ *flags |= IPCOMP_DECOMPRESSIONERROR;
26427+ inflateEnd(&zs);
26428+
26429+ return skb;
26430+ }
26431+
26432+#ifdef CONFIG_KLIPS_DEBUG
26433+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26434+ __u8 *c;
26435+
26436+ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
26437+ ipsec_dmp_block("decompress before", c, cpyldsz);
26438+ }
26439+#endif /* CONFIG_KLIPS_DEBUG */
26440+
26441+#ifdef NET_21
26442+ iph = nskb->nh.iph;
26443+#else /* NET_21 */
26444+ iph = nskb->ip_hdr;
26445+#endif /* NET_21 */
26446+ zs.next_out = (char *)iph + iphlen;
26447+ zs.avail_out = pyldsz;
26448+
26449+ zresult = inflate(&zs, Z_SYNC_FLUSH);
26450+
26451+ /* work around a bug in zlib, which sometimes wants to taste an extra
26452+ * byte when being used in the (undocumented) raw deflate mode.
26453+ */
26454+ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
26455+ __u8 zerostuff = 0;
26456+
26457+ zs.next_in = &zerostuff;
26458+ zs.avail_in = 1;
26459+ zresult = inflate(&zs, Z_FINISH);
26460+ }
26461+
26462+ inflateEnd(&zs);
26463+ if (zresult != Z_STREAM_END) {
26464+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26465+ "klips_error:skb_decompress: "
26466+ "inflate() returned error %d (%s), "
26467+ "skipping decompression.\n",
26468+ zresult,
26469+ zs.msg ? zs.msg : zError(zresult));
26470+ *flags |= IPCOMP_DECOMPRESSIONERROR;
26471+ ipsec_kfree_skb(nskb);
26472+
26473+ return skb;
26474+ }
26475+
26476+ /* Update IP header */
26477+ /* resulting decompressed size */
26478+ pyldsz -= zs.avail_out;
26479+ iph->tot_len = htons(iphlen + pyldsz);
26480+ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
26481+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26482+ "klips_debug:skb_decompress: "
26483+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
26484+ ips ? ntohl(ips->ips_said.spi) : 0,
26485+ ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
26486+ ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
26487+ cpyldsz,
26488+ pyldsz,
26489+ iph->protocol);
26490+
26491+#if 1 /* XXX checksum is done by ipsec_rcv ? */
26492+ iph->check = 0;
26493+ iph->check = ip_fast_csum((char*) iph, iph->ihl);
26494+#endif
26495+
26496+ /* Update skb length/tail by "unputting" the unused data area */
26497+ safe_skb_put(nskb, -zs.avail_out);
26498+
26499+ ipsec_kfree_skb(skb);
26500+
26501+ if (iph->protocol == IPPROTO_COMP)
26502+ {
26503+#ifdef CONFIG_KLIPS_DEBUG
26504+ if(sysctl_ipsec_debug_ipcomp)
26505+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26506+ "klips_debug:skb_decompress: "
26507+ "Eh? inner packet is also compressed, dropping.\n");
26508+#endif /* CONFIG_KLIPS_DEBUG */
26509+
26510+ ipsec_kfree_skb(nskb);
26511+ return NULL;
26512+ }
26513+
26514+#ifdef CONFIG_KLIPS_DEBUG
26515+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26516+ __u8 *c;
26517+
26518+ c = (__u8*)iph + iphlen;
26519+ ipsec_dmp_block("decompress result", c, pyldsz);
26520+ }
26521+#endif /* CONFIG_KLIPS_DEBUG */
26522+
26523+ return nskb;
26524+}
26525+
26526+
26527+/* this is derived from skb_copy() in linux 2.2.14 */
26528+/* May be incompatible with other kernel versions!! */
26529+static
26530+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
26531+{
26532+ struct sk_buff *n;
26533+ struct iphdr *iph;
26534+ unsigned long offset;
26535+ unsigned int iphlen;
26536+
26537+ if(!skb) {
26538+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26539+ "klips_debug:skb_copy_ipcomp: "
26540+ "passed in NULL skb, returning NULL.\n");
26541+ return NULL;
26542+ }
26543+
26544+ /*
26545+ * Allocate the copy buffer
26546+ */
26547+
26548+#ifdef NET_21
26549+ iph = skb->nh.iph;
26550+#else /* NET_21 */
26551+ iph = skb->ip_hdr;
26552+#endif /* NET_21 */
26553+ if (!iph) return NULL;
26554+ iphlen = iph->ihl << 2;
26555+
26556+ n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
26557+ if(n==NULL)
26558+ return NULL;
26559+
26560+ /*
26561+ * Shift between the two data areas in bytes
26562+ */
26563+
26564+ offset=n->head-skb->head;
26565+
26566+ /* Set the data pointer */
26567+ skb_reserve(n,skb->data-skb->head);
26568+ /* Set the tail pointer and length */
26569+ safe_skb_put(n,skb->len+data_growth);
26570+ /* Copy the bytes up to and including the ip header */
26571+ memcpy(n->head,
26572+ skb->head,
26573+ ((char *)iph - (char *)skb->head) + iphlen);
26574+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
26575+ n->list=NULL;
26576+#endif
26577+ n->next=NULL;
26578+ n->prev=NULL;
26579+ n->sk=NULL;
26580+ n->dev=skb->dev;
26581+ if (skb->h.raw)
26582+ n->h.raw=skb->h.raw+offset;
26583+ else
26584+ n->h.raw=NULL;
26585+ n->protocol=skb->protocol;
26586+#ifdef NET_21
26587+ n->csum = 0;
26588+ n->priority=skb->priority;
26589+ n->dst=dst_clone(skb->dst);
26590+ n->nh.raw=skb->nh.raw+offset;
26591+#ifndef NETDEV_23
26592+ n->is_clone=0;
26593+#endif /* NETDEV_23 */
26594+ atomic_set(&n->users, 1);
26595+ n->destructor = NULL;
26596+#ifdef HAVE_SOCK_SECURITY
26597+ n->security=skb->security;
26598+#endif
26599+ memcpy(n->cb, skb->cb, sizeof(skb->cb));
26600+#ifdef CONFIG_IP_FIREWALL
26601+ n->fwmark = skb->fwmark;
26602+#endif
26603+#else /* NET_21 */
26604+ n->link3=NULL;
26605+ n->when=skb->when;
26606+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
26607+ n->saddr=skb->saddr;
26608+ n->daddr=skb->daddr;
26609+ n->raddr=skb->raddr;
26610+ n->seq=skb->seq;
26611+ n->end_seq=skb->end_seq;
26612+ n->ack_seq=skb->ack_seq;
26613+ n->acked=skb->acked;
26614+ n->free=1;
26615+ n->arp=skb->arp;
26616+ n->tries=0;
26617+ n->lock=0;
26618+ n->users=0;
26619+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
26620+#endif /* NET_21 */
26621+ if (skb->mac.raw)
26622+ n->mac.raw=skb->mac.raw+offset;
26623+ else
26624+ n->mac.raw=NULL;
26625+#ifndef NETDEV_23
26626+ n->used=skb->used;
26627+#endif /* !NETDEV_23 */
26628+ n->pkt_type=skb->pkt_type;
26629+#ifndef NETDEV_23
26630+ n->pkt_bridged=skb->pkt_bridged;
26631+#endif /* NETDEV_23 */
26632+ n->ip_summed=0;
26633+#ifdef HAVE_TSTAMP
26634+ n->tstamp = skb->tstamp;
26635+#else
26636+ n->stamp=skb->stamp;
26637+#endif
26638+#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
26639+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
26640+ n->shapelatency=skb->shapelatency; /* Latency on frame */
26641+ n->shapeclock=skb->shapeclock; /* Time it should go out */
26642+ n->shapelen=skb->shapelen; /* Frame length in clocks */
26643+ n->shapestamp=skb->shapestamp; /* Stamp for shaper */
26644+ n->shapepend=skb->shapepend; /* Pending */
26645+#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
26646+#endif /* NETDEV_23 */
26647+
26648+ return n;
26649+}
26650--- /dev/null Tue Mar 11 13:02:56 2003
26651+++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004
26652@@ -0,0 +1,407 @@
26653+/*
26654+ * processing code for AH
26655+ * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com>
26656+ *
26657+ * This program is free software; you can redistribute it and/or modify it
26658+ * under the terms of the GNU General Public License as published by the
26659+ * Free Software Foundation; either version 2 of the License, or (at your
26660+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
26661+ *
26662+ * This program is distributed in the hope that it will be useful, but
26663+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26664+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26665+ * for more details.
26666+ */
26667+
26668+char ipsec_ah_c_version[] = "RCSID $Id: ipsec_ah.c,v 1.12.2.2 2006/10/06 21:39:26 paul Exp $";
26669+#ifndef AUTOCONF_INCLUDED
26670+#include <linux/config.h>
26671+#endif
26672+#include <linux/version.h>
26673+
26674+#define __NO_VERSION__
26675+#include <linux/module.h>
26676+#include <linux/kernel.h> /* printk() */
26677+
26678+#include "openswan/ipsec_param.h"
26679+
26680+#ifdef MALLOC_SLAB
26681+# include <linux/slab.h> /* kmalloc() */
26682+#else /* MALLOC_SLAB */
26683+# include <linux/malloc.h> /* kmalloc() */
26684+#endif /* MALLOC_SLAB */
26685+#include <linux/errno.h> /* error codes */
26686+#include <linux/types.h> /* size_t */
26687+#include <linux/interrupt.h> /* mark_bh */
26688+
26689+#include <linux/netdevice.h> /* struct device, and other headers */
26690+#include <linux/etherdevice.h> /* eth_type_trans */
26691+#include <linux/ip.h> /* struct iphdr */
26692+#include <linux/skbuff.h>
26693+#include <openswan.h>
26694+#ifdef SPINLOCK
26695+# ifdef SPINLOCK_23
26696+# include <linux/spinlock.h> /* *lock* */
26697+# else /* SPINLOCK_23 */
26698+# include <asm/spinlock.h> /* *lock* */
26699+# endif /* SPINLOCK_23 */
26700+#endif /* SPINLOCK */
26701+
26702+#include <net/ip.h>
26703+#include <net/protocol.h>
26704+
26705+#include "openswan/radij.h"
26706+#include "openswan/ipsec_encap.h"
26707+#include "openswan/ipsec_sa.h"
26708+
26709+#include "openswan/ipsec_radij.h"
26710+#include "openswan/ipsec_xform.h"
26711+#include "openswan/ipsec_tunnel.h"
26712+#include "openswan/ipsec_rcv.h"
26713+#include "openswan/ipsec_xmit.h"
26714+
26715+#include "openswan/ipsec_auth.h"
26716+#include "openswan/ipsec_ah.h"
26717+#include "openswan/ipsec_proto.h"
26718+
26719+__u32 zeroes[AH_AMAX];
26720+
26721+enum ipsec_rcv_value
26722+ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
26723+ struct sk_buff *skb)
26724+{
26725+ int ahminlen;
26726+
26727+ ahminlen = irs->hard_header_len + sizeof(struct iphdr);
26728+
26729+ /* take care not to deref this pointer until we check the minlen though */
26730+ irs->protostuff.ahstuff.ahp = (struct ahhdr *)skb->h.raw;
26731+
26732+ if((skb->len < ahminlen+sizeof(struct ahhdr)) ||
26733+ (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
26734+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26735+ "klips_debug:ipsec_rcv: "
26736+ "runt ah packet of skb->len=%d received from %s, dropped.\n",
26737+ skb->len,
26738+ irs->ipsaddr_txt);
26739+ if(irs->stats) {
26740+ irs->stats->rx_errors++;
26741+ }
26742+ return IPSEC_RCV_BADLEN;
26743+ }
26744+
26745+ irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
26746+
26747+ /* XXX we only support the one 12-byte authenticator for now */
26748+ if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
26749+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26750+ "klips_debug:ipsec_rcv: "
26751+ "bad authenticator length %ld, expected %lu from %s.\n",
26752+ (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
26753+ (unsigned long) sizeof(struct ahhdr),
26754+ irs->ipsaddr_txt);
26755+ if(irs->stats) {
26756+ irs->stats->rx_errors++;
26757+ }
26758+ return IPSEC_RCV_BADLEN;
26759+ }
26760+
26761+ return IPSEC_RCV_OK;
26762+}
26763+
26764+
26765+enum ipsec_rcv_value
26766+ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
26767+ struct sk_buff *skb,
26768+ __u32 *replay,
26769+ unsigned char **authenticator)
26770+{
26771+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26772+
26773+ *replay = ntohl(ahp->ah_rpl);
26774+ *authenticator = ahp->ah_data;
26775+
26776+ return IPSEC_RCV_OK;
26777+}
26778+
26779+enum ipsec_rcv_value
26780+ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
26781+ struct sk_buff *skb)
26782+{
26783+ struct auth_alg *aa;
26784+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26785+ union {
26786+ MD5_CTX md5;
26787+ SHA1_CTX sha1;
26788+ } tctx;
26789+ struct iphdr ipo;
26790+ int ahhlen;
26791+
26792+ aa = irs->authfuncs;
26793+
26794+ /* copy the initialized keying material */
26795+ memcpy(&tctx, irs->ictx, irs->ictx_len);
26796+
26797+ ipo = *irs->ipp;
26798+ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
26799+ ipo.frag_off = 0;
26800+ ipo.ttl = 0;
26801+ ipo.check = 0;
26802+
26803+
26804+ /* do the sanitized header */
26805+ (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
26806+
26807+ /* XXX we didn't do the options here! */
26808+
26809+ /* now do the AH header itself */
26810+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26811+ (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN);
26812+
26813+ /* now, do some zeroes */
26814+ (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN);
26815+
26816+ /* finally, do the packet contents themselves */
26817+ (*aa->update)((void*)&tctx,
26818+ (caddr_t)skb->h.raw + ahhlen,
26819+ skb->len - ahhlen);
26820+
26821+ (*aa->final)(irs->hash, (void *)&tctx);
26822+
26823+ memcpy(&tctx, irs->octx, irs->octx_len);
26824+
26825+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
26826+ (*aa->final)(irs->hash, (void *)&tctx);
26827+
26828+ return IPSEC_RCV_OK;
26829+}
26830+
26831+enum ipsec_rcv_value
26832+ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
26833+{
26834+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26835+ struct sk_buff *skb;
26836+ int ahhlen;
26837+
26838+ skb=irs->skb;
26839+
26840+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26841+
26842+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
26843+ irs->next_header = ahp->ah_nh;
26844+
26845+ /*
26846+ * move the IP header forward by the size of the AH header, which
26847+ * will remove the the AH header from the packet.
26848+ */
26849+ memmove((void *)(skb->nh.raw + ahhlen),
26850+ (void *)(skb->nh.raw), irs->iphlen);
26851+
26852+ ipsec_rcv_dmp("ah postmove", skb->data, skb->len);
26853+
26854+ /* skb_pull below, will move up by ahhlen */
26855+
26856+ /* XXX not clear how this can happen, as the message indicates */
26857+ if(skb->len < ahhlen) {
26858+ printk(KERN_WARNING
26859+ "klips_error:ipsec_rcv: "
26860+ "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n",
26861+ ahhlen,
26862+ (int)(skb->len));
26863+ return IPSEC_RCV_DECAPFAIL;
26864+ }
26865+ skb_pull(skb, ahhlen);
26866+
26867+ skb->nh.raw = skb->nh.raw + ahhlen;
26868+ irs->ipp = skb->nh.iph;
26869+
26870+ ipsec_rcv_dmp("ah postpull", (void *)skb->nh.iph, skb->len);
26871+
26872+ return IPSEC_RCV_OK;
26873+}
26874+
26875+enum ipsec_xmit_value
26876+ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs)
26877+{
26878+ struct iphdr ipo;
26879+ struct ahhdr *ahp;
26880+ __u8 hash[AH_AMAX];
26881+ union {
26882+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26883+ MD5_CTX md5;
26884+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26885+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26886+ SHA1_CTX sha1;
26887+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26888+ } tctx;
26889+ unsigned char *dat = (unsigned char *)ixs->iph;
26890+
26891+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
26892+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
26893+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
26894+ ahp->ah_rv = 0;
26895+ ahp->ah_nh = ixs->iph->protocol;
26896+ ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32);
26897+ ixs->iph->protocol = IPPROTO_AH;
26898+ ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp));
26899+
26900+ ipo = *ixs->iph;
26901+ ipo.tos = 0;
26902+ ipo.frag_off = 0;
26903+ ipo.ttl = 0;
26904+ ipo.check = 0;
26905+ ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo));
26906+
26907+ switch(ixs->ipsp->ips_authalg) {
26908+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26909+ case AH_MD5:
26910+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26911+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
26912+ osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
26913+ ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
26914+ osMD5Update(&tctx.md5, (unsigned char *)ahp,
26915+ sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26916+ ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
26917+ osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26918+ ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
26919+ osMD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr),
26920+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26921+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
26922+ osMD5Final(hash, &tctx.md5);
26923+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
26924+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
26925+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
26926+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
26927+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
26928+ osMD5Final(hash, &tctx.md5);
26929+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
26930+
26931+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26932+
26933+ /* paranoid */
26934+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
26935+ memset((caddr_t)hash, 0, sizeof(*hash));
26936+ break;
26937+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26938+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26939+ case AH_SHA:
26940+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26941+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
26942+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26943+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26944+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr),
26945+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26946+ SHA1Final(hash, &tctx.sha1);
26947+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
26948+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
26949+ SHA1Final(hash, &tctx.sha1);
26950+
26951+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26952+
26953+ /* paranoid */
26954+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
26955+ memset((caddr_t)hash, 0, sizeof(*hash));
26956+ break;
26957+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26958+ default:
26959+ ixs->stats->tx_errors++;
26960+ return IPSEC_XMIT_AH_BADALG;
26961+ }
26962+#ifdef NET_21
26963+ ixs->skb->h.raw = (unsigned char*)ahp;
26964+#endif /* NET_21 */
26965+
26966+ return IPSEC_XMIT_OK;
26967+}
26968+
26969+struct xform_functions ah_xform_funcs[]={
26970+ { rcv_checks: ipsec_rcv_ah_checks,
26971+ rcv_setup_auth: ipsec_rcv_ah_setup_auth,
26972+ rcv_calc_auth: ipsec_rcv_ah_authcalc,
26973+ rcv_decrypt: ipsec_rcv_ah_decap,
26974+
26975+ xmit_setup: ipsec_xmit_ah_setup,
26976+ xmit_headroom: sizeof(struct ahhdr),
26977+ xmit_needtailroom: 0,
26978+ },
26979+};
26980+
26981+
26982+#ifdef NET_26
26983+struct inet_protocol ah_protocol = {
26984+ .handler = ipsec_rcv,
26985+ .no_policy = 1,
26986+};
26987+#else
26988+struct inet_protocol ah_protocol =
26989+{
26990+ ipsec_rcv, /* AH handler */
26991+ NULL, /* TUNNEL error control */
26992+#ifdef NETDEV_25
26993+ 1, /* no policy */
26994+#else
26995+ 0, /* next */
26996+ IPPROTO_AH, /* protocol ID */
26997+ 0, /* copy */
26998+ NULL, /* data */
26999+ "AH" /* name */
27000+#endif
27001+};
27002+#endif /* NET_26 */
27003+
27004+/*
27005+ * $Log: ipsec_ah.c,v $
27006+ * Revision 1.12.2.2 2006/10/06 21:39:26 paul
27007+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
27008+ * set. This is defined through autoconf.h which is included through the
27009+ * linux kernel build macros.
27010+ *
27011+ * Revision 1.12.2.1 2006/02/15 05:35:14 paul
27012+ * Patch by David McCullough <davidm@snapgear.com>
27013+ * If you setup a tunnel without ESP it doesn't work. It used to work in
27014+ * an older openswan version but stopped when klips was modified to deal
27015+ * with the pulled IP header on the received SKB's.
27016+ *
27017+ * The code in ipsec_ah.c still thinks the IP header is there and runs the
27018+ * hash on the incorrect data.
27019+ *
27020+ * Revision 1.12 2005/04/29 05:10:22 mcr
27021+ * removed from extraenous includes to make unit testing easier.
27022+ *
27023+ * Revision 1.11 2005/04/15 19:50:55 mcr
27024+ * adjustments to use proper skb fields for data.
27025+ *
27026+ * Revision 1.10 2004/09/14 00:22:57 mcr
27027+ * adjustment of MD5* functions.
27028+ *
27029+ * Revision 1.9 2004/09/13 02:22:47 mcr
27030+ * #define inet_protocol if necessary.
27031+ *
27032+ * Revision 1.8 2004/09/06 18:35:48 mcr
27033+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
27034+ * so adjust for that.
27035+ *
27036+ * Revision 1.7 2004/08/22 05:00:48 mcr
27037+ * if we choose to compile the file, we want the contents,
27038+ * so don't pull any punches.
27039+ *
27040+ * Revision 1.6 2004/08/17 03:27:23 mcr
27041+ * klips 2.6 edits.
27042+ *
27043+ * Revision 1.5 2004/08/14 03:28:24 mcr
27044+ * fixed log comment to remove warning about embedded comment.
27045+ *
27046+ * Revision 1.4 2004/08/04 15:57:07 mcr
27047+ * moved des .h files to include/des/ *
27048+ * included 2.6 protocol specific things
27049+ * started at NAT-T support, but it will require a kernel patch.
27050+ *
27051+ * Revision 1.3 2004/07/10 19:11:18 mcr
27052+ * CONFIG_IPSEC -> CONFIG_KLIPS.
27053+ *
27054+ * Revision 1.2 2004/04/06 02:49:25 mcr
27055+ * pullup of algo code from alg-branch.
27056+ *
27057+ *
27058+ *
27059+ */
27060--- /dev/null Tue Mar 11 13:02:56 2003
27061+++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004
27062@@ -0,0 +1,1057 @@
27063+/*
27064+ * Modular extensions service and registration functions
27065+ *
27066+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
27067+ *
27068+ * Version: 0.8.1
27069+ *
27070+ * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
27071+ *
27072+ * This program is free software; you can redistribute it and/or modify it
27073+ * under the terms of the GNU General Public License as published by the
27074+ * Free Software Foundation; either version 2 of the License, or (at your
27075+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
27076+ *
27077+ * This program is distributed in the hope that it will be useful, but
27078+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27079+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27080+ * for more details.
27081+ *
27082+ */
27083+#define __NO_VERSION__
27084+
27085+#if defined (MODULE)
27086+#include <linux/module.h>
27087+#endif
27088+
27089+#include <linux/kernel.h> /* printk() */
27090+
27091+#include <linux/netdevice.h> /* struct device, and other headers */
27092+#include <linux/etherdevice.h> /* eth_type_trans */
27093+#include <linux/ip.h> /* struct iphdr */
27094+#include <linux/skbuff.h>
27095+#include <linux/socket.h>
27096+#include <linux/in.h>
27097+#include <linux/types.h>
27098+#include <linux/string.h> /* memcmp() */
27099+#include <linux/random.h> /* get_random_bytes() */
27100+#include <linux/errno.h> /* error codes */
27101+#ifdef SPINLOCK
27102+# ifdef SPINLOCK_23
27103+# include <linux/spinlock.h> /* *lock* */
27104+# else /* SPINLOCK_23 */
27105+# include <asm/spinlock.h> /* *lock* */
27106+# endif /* SPINLOCK_23 */
27107+#endif /* SPINLOCK */
27108+
27109+#include "openswan/ipsec_param.h"
27110+#include <openswan.h>
27111+#include "openswan/ipsec_sa.h"
27112+#include "openswan/radij.h"
27113+#include "openswan/ipsec_encap.h"
27114+#include "openswan/ipsec_radij.h"
27115+#include "openswan/ipsec_xform.h"
27116+#include "openswan/ipsec_tunnel.h"
27117+#include "openswan/ipsec_rcv.h"
27118+#if defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH)
27119+# include "openswan/ipsec_ah.h"
27120+#endif /* defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH) */
27121+#ifdef CONFIG_KLIPS_ESP
27122+# include "openswan/ipsec_esp.h"
27123+#endif /* !CONFIG_KLIPS_ESP */
27124+#ifdef CONFIG_KLIPS_IPCOMP
27125+# include "openswan/ipcomp.h"
27126+#endif /* CONFIG_KLIPS_COMP */
27127+
27128+#include <pfkeyv2.h>
27129+#include <pfkey.h>
27130+
27131+#include "openswan/ipsec_alg.h"
27132+#include "openswan/ipsec_proto.h"
27133+
27134+#if SADB_EALG_MAX < 255
27135+#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
27136+#endif
27137+
27138+static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
27139+#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
27140+static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
27141+
27142+/* Old gcc's will fail here */
27143+#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) \
27144+ ; goto out; } while(0)
27145+
27146+#ifdef NET_26
27147+/*
27148+ * Must be already protected by lock
27149+ */
27150+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt)
27151+{
27152+#ifdef MODULE
27153+ if (ixt->ixt_module)
27154+ try_module_get(ixt->ixt_module);
27155+#endif
27156+ atomic_inc(&ixt->ixt_refcnt);
27157+}
27158+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
27159+ atomic_dec(&ixt->ixt_refcnt);
27160+#ifdef MODULE
27161+ if (ixt->ixt_module)
27162+ module_put(ixt->ixt_module);
27163+#endif
27164+}
27165+
27166+#else
27167+
27168+/*
27169+ * Must be already protected by lock
27170+ */
27171+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
27172+#ifdef MODULE
27173+ if (ixt->ixt_module) {
27174+ __MOD_INC_USE_COUNT(ixt->ixt_module);
27175+ }
27176+#endif
27177+ atomic_inc(&ixt->ixt_refcnt);
27178+}
27179+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
27180+ atomic_dec(&ixt->ixt_refcnt);
27181+#ifdef MODULE
27182+ if (ixt->ixt_module)
27183+ __MOD_DEC_USE_COUNT(ixt->ixt_module);
27184+#endif
27185+}
27186+#endif
27187+
27188+/*
27189+ * simple hash function, optimized for 0-hash (1 list) special
27190+ * case
27191+ */
27192+#if IPSEC_ALG_HASHSZ > 1
27193+static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
27194+ return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
27195+}
27196+#else
27197+#define ipsec_alg_hashfn(x,y) (0)
27198+#endif
27199+
27200+/*****************************************************************
27201+ *
27202+ * INTERNAL table handling: insert, delete, find
27203+ *
27204+ *****************************************************************/
27205+
27206+/*
27207+ * hash table initialization, called from ipsec_alg_init()
27208+ */
27209+static void ipsec_alg_hash_init(void) {
27210+ struct list_head *head = ipsec_alg_hash_table;
27211+ int i = IPSEC_ALG_HASHSZ;
27212+ do {
27213+ INIT_LIST_HEAD(head);
27214+ head++;
27215+ i--;
27216+ } while (i);
27217+}
27218+/*
27219+ * hash list lookup by {alg_type, alg_id} and table head,
27220+ * must be already protected by lock
27221+ */
27222+static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
27223+ struct list_head *p;
27224+ struct ipsec_alg *ixt=NULL;
27225+ for (p=head->next; p!=head; p=p->next) {
27226+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
27227+ if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
27228+ goto out;
27229+ }
27230+ }
27231+ ixt=NULL;
27232+out:
27233+ return ixt;
27234+}
27235+/*
27236+ * inserts (in front) a new entry in hash table,
27237+ * called from ipsec_alg_register() when new algorithm is registered.
27238+ */
27239+static int ipsec_alg_insert(struct ipsec_alg *ixt) {
27240+ int ret=-EINVAL;
27241+ unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
27242+ struct list_head *head= ipsec_alg_hash_table + hashval;
27243+ struct ipsec_alg *ixt_cur;
27244+
27245+ /* new element must be virgin ... */
27246+ if (ixt->ixt_list.next != &ixt->ixt_list ||
27247+ ixt->ixt_list.prev != &ixt->ixt_list) {
27248+ printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
27249+ "list head not initialized\n",
27250+ ixt->ixt_name);
27251+ return ret;
27252+ }
27253+ write_lock_bh(&ipsec_alg_lock);
27254+
27255+ ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
27256+
27257+ /* if previous (current) ipsec_alg found check excl flag of _anyone_ */
27258+ if (ixt_cur
27259+ && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) {
27260+ barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
27261+ "Not loaded (ret=%d).\n",
27262+ ixt->ixt_alg_type,
27263+ ixt->ixt_alg_id, ret=-EEXIST);
27264+ }
27265+ list_add(&ixt->ixt_list, head);
27266+ ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
27267+ ret=0;
27268+out:
27269+ write_unlock_bh(&ipsec_alg_lock);
27270+ return ret;
27271+}
27272+
27273+/*
27274+ * deletes an existing entry in hash table,
27275+ * called from ipsec_alg_unregister() when algorithm is unregistered.
27276+ */
27277+static int ipsec_alg_delete(struct ipsec_alg *ixt) {
27278+ write_lock_bh(&ipsec_alg_lock);
27279+ list_del(&ixt->ixt_list);
27280+ write_unlock_bh(&ipsec_alg_lock);
27281+ return 0;
27282+}
27283+
27284+/*
27285+ * here @user context (read-only when @kernel bh context)
27286+ * -> no bh disabling
27287+ *
27288+ * called from ipsec_sa_init() -> ipsec_alg_sa_init()
27289+ */
27290+static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id)
27291+{
27292+ unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
27293+ struct list_head *head= ipsec_alg_hash_table + hashval;
27294+ struct ipsec_alg *ixt;
27295+
27296+ read_lock(&ipsec_alg_lock);
27297+ ixt=__ipsec_alg_find(alg_type, alg_id, head);
27298+ if (ixt) __ipsec_alg_usage_inc(ixt);
27299+ read_unlock(&ipsec_alg_lock);
27300+
27301+ return ixt;
27302+}
27303+
27304+static void ipsec_alg_put(struct ipsec_alg *ixt) {
27305+ __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
27306+}
27307+
27308+/*****************************************************************
27309+ *
27310+ * INTERFACE for ENC services: key creation, encrypt function
27311+ *
27312+ *****************************************************************/
27313+
27314+/*
27315+ * main encrypt service entry point
27316+ * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
27317+ * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
27318+ */
27319+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat,
27320+ int ilen, const __u8 * iv, int encrypt)
27321+{
27322+ int ret;
27323+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
27324+#ifdef CONFIG_KLIPS_DEBUG
27325+ int debug_flag = (encrypt==IPSEC_ALG_ENCRYPT ?
27326+ debug_tunnel : debug_rcv);
27327+#endif
27328+
27329+ KLIPS_PRINT(debug_flag,
27330+ "klips_debug:ipsec_alg_esp_encrypt: "
27331+ "entering with encalg=%d, ixt_e=%p\n",
27332+ sa_p->ips_encalg, ixt_e);
27333+ if (ixt_e == NULL) {
27334+#ifdef CONFIG_KLIPS_DEBUG
27335+ KLIPS_ERROR(debug_flag,
27336+ "klips_debug:ipsec_alg_esp_encrypt: "
27337+ "NULL ipsec_alg_enc object\n");
27338+#endif
27339+ return -1;
27340+ }
27341+ KLIPS_PRINT(debug_flag,
27342+ "klips_debug:ipsec_alg_esp_encrypt: "
27343+ "calling cbc_encrypt encalg=%d "
27344+ "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
27345+ sa_p->ips_encalg,
27346+ sa_p->ips_key_e, idat, ilen, iv, encrypt);
27347+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat,
27348+ ilen, iv, encrypt);
27349+ KLIPS_PRINT(debug_flag,
27350+ "klips_debug:ipsec_alg_esp_encrypt: "
27351+ "returned ret=%d\n",
27352+ ret);
27353+ return ret;
27354+}
27355+
27356+/*
27357+ * encryption key context creation function
27358+ * called from pfkey_v2_parser.c:pfkey_ips_init()
27359+ */
27360+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
27361+ int ret=-EINVAL;
27362+ int keyminbits, keymaxbits;
27363+ caddr_t ekp;
27364+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
27365+
27366+ KLIPS_PRINT(debug_pfkey,
27367+ "klips_debug:ipsec_alg_enc_key_create: "
27368+ "entering with encalg=%d ixt_e=%p\n",
27369+ sa_p->ips_encalg, ixt_e);
27370+ if (!ixt_e) {
27371+ KLIPS_PRINT(debug_pfkey,
27372+ "klips_debug:ipsec_alg_enc_key_create: "
27373+ "NULL ipsec_alg_enc object\n");
27374+ return -EPROTO;
27375+ }
27376+
27377+ /*
27378+ * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo
27379+ */
27380+ switch(ixt_e->ixt_common.ixt_support.ias_id) {
27381+ case ESP_3DES:
27382+ keyminbits=keymaxbits=192;break;
27383+ case ESP_DES:
27384+ keyminbits=keymaxbits=64;break;
27385+ default:
27386+ keyminbits=ixt_e->ixt_common.ixt_support.ias_keyminbits;
27387+ keymaxbits=ixt_e->ixt_common.ixt_support.ias_keymaxbits;
27388+ }
27389+ if(sa_p->ips_key_bits_e<keyminbits ||
27390+ sa_p->ips_key_bits_e>keymaxbits) {
27391+ KLIPS_PRINT(debug_pfkey,
27392+ "klips_debug:ipsec_alg_enc_key_create: "
27393+ "incorrect encryption key size for id=%d: %d bits -- "
27394+ "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
27395+ ixt_e->ixt_common.ixt_support.ias_id,
27396+ sa_p->ips_key_bits_e, keyminbits, keymaxbits);
27397+ ret=-EINVAL;
27398+ goto ixt_out;
27399+ }
27400+ /* save encryption key pointer */
27401+ ekp = sa_p->ips_key_e;
27402+
27403+
27404+ if (ixt_e->ixt_e_new_key) {
27405+ sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
27406+ ekp, sa_p->ips_key_bits_e/8);
27407+ ret = (sa_p->ips_key_e)? 0 : -EINVAL;
27408+ } else {
27409+ if((sa_p->ips_key_e = (caddr_t)
27410+ kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
27411+ GFP_ATOMIC)) == NULL) {
27412+ ret=-ENOMEM;
27413+ goto ixt_out;
27414+ }
27415+ /* zero-out key_e */
27416+ memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
27417+
27418+ /* I cast here to allow more decoupling in alg module */
27419+ KLIPS_PRINT(debug_pfkey,
27420+ "klips_debug:ipsec_alg_enc_key_create: about to call:"
27421+ "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
27422+ (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27423+ ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27424+ }
27425+ /* paranoid */
27426+ memset(ekp, 0, sa_p->ips_key_bits_e/8);
27427+ kfree(ekp);
27428+ixt_out:
27429+ return ret;
27430+}
27431+
27432+/***************************************************************
27433+ *
27434+ * INTERFACE for AUTH services: key creation, hash functions
27435+ *
27436+ ***************************************************************/
27437+
27438+/*
27439+ * auth key context creation function
27440+ * called from pfkey_v2_parser.c:pfkey_ips_init()
27441+ */
27442+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
27443+ int ret=-EINVAL;
27444+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27445+ int keyminbits, keymaxbits;
27446+ unsigned char *akp;
27447+ unsigned int aks;
27448+ KLIPS_PRINT(debug_pfkey,
27449+ "klips_debug:ipsec_alg_auth_key_create: "
27450+ "entering with authalg=%d ixt_a=%p\n",
27451+ sa_p->ips_authalg, ixt_a);
27452+ if (!ixt_a) {
27453+ KLIPS_PRINT(debug_pfkey,
27454+ "klips_debug:ipsec_alg_auth_key_create: "
27455+ "NULL ipsec_alg_auth object\n");
27456+ return -EPROTO;
27457+ }
27458+ keyminbits=ixt_a->ixt_common.ixt_support.ias_keyminbits;
27459+ keymaxbits=ixt_a->ixt_common.ixt_support.ias_keymaxbits;
27460+ if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
27461+ KLIPS_PRINT(debug_pfkey,
27462+ "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
27463+ "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
27464+ sa_p->ips_key_bits_a, keyminbits, keymaxbits);
27465+ ret=-EINVAL;
27466+ goto ixt_out;
27467+ }
27468+ /* save auth key pointer */
27469+ sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
27470+ akp = sa_p->ips_key_a;
27471+ aks = sa_p->ips_key_a_size;
27472+
27473+ /* will hold: 2 ctx and a blocksize buffer: kb */
27474+ sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
27475+ if((sa_p->ips_key_a =
27476+ (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
27477+ ret=-ENOMEM;
27478+ goto ixt_out;
27479+ }
27480+ ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
27481+ ret=0;
27482+ memset(akp, 0, aks);
27483+ kfree(akp);
27484+
27485+ixt_out:
27486+ return ret;
27487+}
27488+
27489+
27490+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp,
27491+ int len, __u8 *hash, int hashlen)
27492+{
27493+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27494+ if (!ixt_a) {
27495+ KLIPS_PRINT(debug_pfkey,
27496+ "klips_debug:ipsec_sa_esp_hash: "
27497+ "NULL ipsec_alg_auth object\n");
27498+ return -EPROTO;
27499+ }
27500+ KLIPS_PRINT(debug_tunnel|debug_rcv,
27501+ "klips_debug:ipsec_sa_esp_hash: "
27502+ "hashing %p (%d bytes) to %p (%d bytes)\n",
27503+ espp, len,
27504+ hash, hashlen);
27505+ ixt_a->ixt_a_hmac_hash(ixt_a,
27506+ sa_p->ips_key_a,
27507+ espp, len,
27508+ hash, hashlen);
27509+ return 0;
27510+}
27511+
27512+/***************************************************************
27513+ *
27514+ * INTERFACE for module loading,testing, and unloading
27515+ *
27516+ ***************************************************************/
27517+
27518+/* validation for registering (enc) module */
27519+static int check_enc(struct ipsec_alg_enc *ixt)
27520+{
27521+ int ret=-EINVAL;
27522+ if (ixt->ixt_common.ixt_blocksize==0) /* || ixt->ixt_common.ixt_blocksize%2) need for ESP_NULL */
27523+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_common.ixt_blocksize);
27524+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0
27525+ && ixt->ixt_common.ixt_support.ias_keymaxbits==0
27526+ && ixt->ixt_e_keylen==0)
27527+ goto zero_key_ok;
27528+
27529+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27530+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27531+
27532+ if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27533+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27534+
27535+ if (ixt->ixt_e_keylen==0)
27536+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
27537+
27538+zero_key_ok:
27539+ if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
27540+ barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
27541+ if (ixt->ixt_e_cbc_encrypt==NULL)
27542+ barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
27543+ ret=0;
27544+out:
27545+ return ret;
27546+}
27547+
27548+/* validation for registering (auth) module */
27549+static int check_auth(struct ipsec_alg_auth *ixt)
27550+{
27551+ int ret=-EINVAL;
27552+ if (ixt->ixt_common.ixt_support.ias_id==0 || ixt->ixt_common.ixt_support.ias_id > SADB_AALG_MAX)
27553+ barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n",
27554+ ixt->ixt_common.ixt_support.ias_id, SADB_AALG_MAX);
27555+
27556+ if (ixt->ixt_common.ixt_blocksize==0
27557+ || ixt->ixt_common.ixt_blocksize%2)
27558+ barf_out(KERN_ERR "invalid blocksize=%d\n",
27559+ ixt->ixt_common.ixt_blocksize);
27560+
27561+ if (ixt->ixt_common.ixt_blocksize>AH_BLKLEN_MAX)
27562+ barf_out(KERN_ERR "sorry blocksize=%d > %d. "
27563+ "Please increase AH_BLKLEN_MAX and recompile\n",
27564+ ixt->ixt_common.ixt_blocksize,
27565+ AH_BLKLEN_MAX);
27566+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0 && ixt->ixt_common.ixt_support.ias_keymaxbits==0 && ixt->ixt_a_keylen==0)
27567+ goto zero_key_ok;
27568+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27569+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27570+ if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27571+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27572+ if (ixt->ixt_common.ixt_support.ias_keymaxbits!=ixt->ixt_common.ixt_support.ias_keyminbits)
27573+ barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
27574+ if (ixt->ixt_a_keylen==0)
27575+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
27576+zero_key_ok:
27577+ if (ixt->ixt_a_ctx_size==0)
27578+ barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
27579+ if (ixt->ixt_a_hmac_set_key==NULL)
27580+ barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
27581+ if (ixt->ixt_a_hmac_hash==NULL)
27582+ barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
27583+ ret=0;
27584+out:
27585+ return ret;
27586+}
27587+
27588+/*
27589+ * Generic (enc, auth) registration entry point
27590+ */
27591+int register_ipsec_alg(struct ipsec_alg *ixt)
27592+{
27593+ int ret=-EINVAL;
27594+ /* Validation */
27595+ if (ixt==NULL)
27596+ barf_out("NULL ipsec_alg object passed\n");
27597+ if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
27598+ barf_out("incorrect version: %d.%d.%d-%d, "
27599+ "must be %d.%d.%d[-%d]\n",
27600+ IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
27601+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
27602+
27603+ switch(ixt->ixt_alg_type) {
27604+ case IPSEC_ALG_TYPE_AUTH:
27605+ if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
27606+ goto out;
27607+ break;
27608+ case IPSEC_ALG_TYPE_ENCRYPT:
27609+ if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
27610+ goto out;
27611+ /*
27612+ * Adapted two lines below:
27613+ * ivlen == 0 is possible (NULL enc has blocksize==1)
27614+ *
27615+ * fixed NULL support by David De Reu <DeReu@tComLabs.com>
27616+ */
27617+ if (ixt->ixt_support.ias_ivlen == 0
27618+ && ixt->ixt_blocksize > 1) {
27619+ ixt->ixt_support.ias_ivlen = ixt->ixt_blocksize*8;
27620+ }
27621+ break;
27622+ default:
27623+ barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);
27624+ }
27625+ INIT_LIST_HEAD(&ixt->ixt_list);
27626+ ret = ipsec_alg_insert(ixt);
27627+ if (ret<0)
27628+ barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
27629+ "Not loaded (ret=%d).\n",
27630+ ixt->ixt_support.ias_id, ret);
27631+
27632+
27633+ ret = pfkey_list_insert_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27634+ , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27635+
27636+ if (ret==0) {
27637+ ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
27638+ /* send register event to userspace */
27639+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27640+ } else
27641+ printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
27642+ "Loading anyway.\n", ret);
27643+ ret=0;
27644+out:
27645+ return ret;
27646+}
27647+
27648+/*
27649+ * unregister ipsec_alg object from own tables, if
27650+ * success => calls pfkey_list_remove_supported()
27651+ */
27652+int unregister_ipsec_alg(struct ipsec_alg *ixt) {
27653+ int ret= -EINVAL;
27654+ switch(ixt->ixt_alg_type) {
27655+ case IPSEC_ALG_TYPE_AUTH:
27656+ case IPSEC_ALG_TYPE_ENCRYPT:
27657+ break;
27658+ default:
27659+ /* this is not a typo :) */
27660+ barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
27661+ ixt->ixt_name);
27662+ }
27663+
27664+ ret=ipsec_alg_delete(ixt);
27665+ if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
27666+ ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
27667+ pfkey_list_remove_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27668+ , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27669+
27670+ /* send register event to userspace */
27671+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27672+ }
27673+
27674+out:
27675+ return ret;
27676+}
27677+
27678+/*
27679+ * Must be called from user context
27680+ * used at module load type for testing algo implementation
27681+ */
27682+static int ipsec_alg_test_encrypt(int enc_alg, int test) {
27683+ int ret;
27684+ caddr_t buf = NULL;
27685+ int iv_size, keysize, key_e_size;
27686+ struct ipsec_alg_enc *ixt_e;
27687+ void *tmp_key_e = NULL;
27688+ #define BUFSZ 1024
27689+ #define MARGIN 0
27690+ #define test_enc (buf+MARGIN)
27691+ #define test_dec (test_enc+BUFSZ+MARGIN)
27692+ #define test_tmp (test_dec+BUFSZ+MARGIN)
27693+ #define test_key_e (test_tmp+BUFSZ+MARGIN)
27694+ #define test_iv (test_key_e+key_e_size+MARGIN)
27695+ #define test_key (test_iv+iv_size+MARGIN)
27696+ #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
27697+ ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
27698+ if (ixt_e==NULL) {
27699+ KLIPS_PRINT(1,
27700+ "klips_debug: ipsec_alg_test_encrypt: "
27701+ "encalg=%d object not found\n",
27702+ enc_alg);
27703+ ret=-EINVAL;
27704+ goto out;
27705+ }
27706+ iv_size=ixt_e->ixt_common.ixt_support.ias_ivlen / 8;
27707+ key_e_size=ixt_e->ixt_e_ctx_size;
27708+ keysize=ixt_e->ixt_e_keylen;
27709+ KLIPS_PRINT(1,
27710+ "klips_debug: ipsec_alg_test_encrypt: "
27711+ "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
27712+ enc_alg, iv_size, key_e_size, keysize);
27713+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27714+ ret= -ENOMEM;
27715+ goto out;
27716+ }
27717+ get_random_bytes(test_key, keysize);
27718+ get_random_bytes(test_iv, iv_size);
27719+ if (ixt_e->ixt_e_new_key) {
27720+ tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
27721+ ret = tmp_key_e ? 0 : -EINVAL;
27722+ } else {
27723+ tmp_key_e = test_key_e;
27724+ ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
27725+ }
27726+ if (ret < 0)
27727+ goto out;
27728+ get_random_bytes(test_enc, BUFSZ);
27729+ memcpy(test_tmp, test_enc, BUFSZ);
27730+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
27731+ printk(KERN_INFO
27732+ "klips_info: ipsec_alg_test_encrypt: "
27733+ "cbc_encrypt=1 ret=%d\n",
27734+ ret);
27735+ ret=memcmp(test_enc, test_tmp, BUFSZ);
27736+ printk(KERN_INFO
27737+ "klips_info: ipsec_alg_test_encrypt: "
27738+ "memcmp(enc, tmp) ret=%d: %s\n", ret,
27739+ ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
27740+ memcpy(test_dec, test_enc, BUFSZ);
27741+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
27742+ printk(KERN_INFO
27743+ "klips_info: ipsec_alg_test_encrypt: "
27744+ "cbc_encrypt=0 ret=%d\n", ret);
27745+ ret=memcmp(test_dec, test_tmp, BUFSZ);
27746+ printk(KERN_INFO
27747+ "klips_info: ipsec_alg_test_encrypt: "
27748+ "memcmp(dec,tmp) ret=%d: %s\n", ret,
27749+ ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
27750+ {
27751+ /* Shamelessly taken from drivers/md sources O:) */
27752+ unsigned long now;
27753+ int i, count, max=0;
27754+ int encrypt, speed;
27755+ for (encrypt=0; encrypt <2;encrypt ++) {
27756+ for (i = 0; i < 5; i++) {
27757+ now = jiffies;
27758+ count = 0;
27759+ while (jiffies == now) {
27760+ mb();
27761+ ixt_e->ixt_e_cbc_encrypt(ixt_e,
27762+ tmp_key_e, test_tmp,
27763+ BUFSZ, test_iv, encrypt);
27764+ mb();
27765+ count++;
27766+ mb();
27767+ }
27768+ if (count > max)
27769+ max = count;
27770+ }
27771+ speed = max * (HZ * BUFSZ / 1024);
27772+ printk(KERN_INFO
27773+ "klips_info: ipsec_alg_test_encrypt: "
27774+ "%s %s speed=%d KB/s\n",
27775+ ixt_e->ixt_common.ixt_name,
27776+ encrypt? "encrypt": "decrypt", speed);
27777+ }
27778+ }
27779+out:
27780+ if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
27781+ if (buf) kfree(buf);
27782+ if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
27783+ return ret;
27784+ #undef test_enc
27785+ #undef test_dec
27786+ #undef test_tmp
27787+ #undef test_key_e
27788+ #undef test_iv
27789+ #undef test_key
27790+ #undef test_size
27791+}
27792+
27793+/*
27794+ * Must be called from user context
27795+ * used at module load type for testing algo implementation
27796+ */
27797+static int ipsec_alg_test_auth(int auth_alg, int test) {
27798+ int ret;
27799+ caddr_t buf = NULL;
27800+ int blocksize, keysize, key_a_size;
27801+ struct ipsec_alg_auth *ixt_a;
27802+ #define BUFSZ 1024
27803+ #define MARGIN 0
27804+ #define test_auth (buf+MARGIN)
27805+ #define test_key_a (test_auth+BUFSZ+MARGIN)
27806+ #define test_key (test_key_a+key_a_size+MARGIN)
27807+ #define test_hash (test_key+keysize+MARGIN)
27808+ #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
27809+ ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
27810+ if (ixt_a==NULL) {
27811+ KLIPS_PRINT(1,
27812+ "klips_debug: ipsec_alg_test_auth: "
27813+ "encalg=%d object not found\n",
27814+ auth_alg);
27815+ ret=-EINVAL;
27816+ goto out;
27817+ }
27818+ blocksize=ixt_a->ixt_common.ixt_blocksize;
27819+ key_a_size=ixt_a->ixt_a_ctx_size;
27820+ keysize=ixt_a->ixt_a_keylen;
27821+ KLIPS_PRINT(1,
27822+ "klips_debug: ipsec_alg_test_auth: "
27823+ "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
27824+ auth_alg, blocksize, key_a_size, keysize);
27825+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27826+ ret= -ENOMEM;
27827+ goto out;
27828+ }
27829+ get_random_bytes(test_key, keysize);
27830+ ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
27831+ if (ret < 0 )
27832+ goto out;
27833+ get_random_bytes(test_auth, BUFSZ);
27834+ ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27835+ printk(KERN_INFO
27836+ "klips_info: ipsec_alg_test_auth: "
27837+ "ret=%d\n", ret);
27838+ {
27839+ /* Shamelessly taken from drivers/md sources O:) */
27840+ unsigned long now;
27841+ int i, count, max=0;
27842+ int speed;
27843+ for (i = 0; i < 5; i++) {
27844+ now = jiffies;
27845+ count = 0;
27846+ while (jiffies == now) {
27847+ mb();
27848+ ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27849+ mb();
27850+ count++;
27851+ mb();
27852+ }
27853+ if (count > max)
27854+ max = count;
27855+ }
27856+ speed = max * (HZ * BUFSZ / 1024);
27857+ printk(KERN_INFO
27858+ "klips_info: ipsec_alg_test_auth: "
27859+ "%s hash speed=%d KB/s\n",
27860+ ixt_a->ixt_common.ixt_name,
27861+ speed);
27862+ }
27863+out:
27864+ if (buf) kfree(buf);
27865+ if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
27866+ return ret;
27867+ #undef test_auth
27868+ #undef test_key_a
27869+ #undef test_key
27870+ #undef test_hash
27871+ #undef test_size
27872+}
27873+
27874+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
27875+ switch(alg_type) {
27876+ case IPSEC_ALG_TYPE_ENCRYPT:
27877+ return ipsec_alg_test_encrypt(alg_id, test);
27878+ break;
27879+ case IPSEC_ALG_TYPE_AUTH:
27880+ return ipsec_alg_test_auth(alg_id, test);
27881+ break;
27882+ }
27883+ printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
27884+ "alg_type=%d alg_id=%d\n",
27885+ alg_type, alg_id);
27886+ return -EINVAL;
27887+}
27888+
27889+int ipsec_alg_init(void) {
27890+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27891+ "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
27892+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
27893+ SADB_EALG_MAX, SADB_AALG_MAX);
27894+ /* Initialize tables */
27895+ write_lock_bh(&ipsec_alg_lock);
27896+ ipsec_alg_hash_init();
27897+ write_unlock_bh(&ipsec_alg_lock);
27898+
27899+ /* Initialize static algos */
27900+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27901+ "calling ipsec_alg_static_init()\n");
27902+
27903+ /* If we are suppose to use our AES, and don't have
27904+ * CryptoAPI enabled...
27905+ */
27906+#if defined(CONFIG_KLIPS_ENC_AES) && CONFIG_KLIPS_ENC_AES && !defined(CONFIG_KLIPS_ENC_AES_MODULE)
27907+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27908+#warning "Using built-in AES rather than CryptoAPI AES"
27909+#endif
27910+ {
27911+ extern int ipsec_aes_init(void);
27912+ ipsec_aes_init();
27913+ }
27914+#endif
27915+
27916+#if defined(CONFIG_KLIPS_ENC_3DES) && CONFIG_KLIPS_ENC_3DES && !defined(CONFIG_KLIPS_ENC_3DES_MODULE)
27917+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27918+#warning "Using built-in 3des rather than CryptoAPI 3des"
27919+#endif
27920+ {
27921+ extern int ipsec_3des_init(void);
27922+ ipsec_3des_init();
27923+ }
27924+#endif
27925+#if defined(CONFIG_KLIPS_ENC_NULL) && CONFIG_KLIPS_ENC_NULL && !defined(CONFIG_KLIPS_ENC_NULL_MODULE)
27926+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27927+#warning "Using built-in null cipher rather than CryptoAPI null cipher"
27928+#endif
27929+#warning "Building with null cipher (ESP_NULL), blame on you :-)"
27930+ {
27931+ extern int ipsec_null_init(void);
27932+ ipsec_null_init();
27933+ }
27934+#endif
27935+
27936+
27937+ /* If we are doing CryptoAPI, then init */
27938+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI && !defined(CONFIG_KLIPS_ENC_CRYPTOAPI_MODULE)
27939+ {
27940+ extern int ipsec_cryptoapi_init(void);
27941+ ipsec_cryptoapi_init();
27942+ }
27943+#endif
27944+
27945+
27946+ return 0;
27947+}
27948+
27949+/**********************************************
27950+ *
27951+ * INTERFACE for ipsec_sa init and wipe
27952+ *
27953+ **********************************************/
27954+
27955+/*
27956+ * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
27957+ */
27958+int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
27959+ struct ipsec_alg_enc *ixt_e;
27960+ struct ipsec_alg_auth *ixt_a;
27961+
27962+ /* Only ESP for now ... */
27963+ if (sa_p->ips_said.proto != IPPROTO_ESP)
27964+ return -EPROTONOSUPPORT;
27965+
27966+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
27967+ "entering for encalg=%d, authalg=%d\n",
27968+ sa_p->ips_encalg, sa_p->ips_authalg);
27969+
27970+ if ((ixt_e=(struct ipsec_alg_enc *)
27971+ ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
27972+ KLIPS_PRINT(debug_pfkey,
27973+ "klips_debug: ipsec_alg_sa_init() :"
27974+ "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
27975+ ixt_e, sa_p->ips_encalg);
27976+ sa_p->ips_alg_enc=ixt_e;
27977+ }
27978+
27979+ if ((ixt_a=(struct ipsec_alg_auth *)
27980+ ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
27981+ KLIPS_PRINT(debug_pfkey,
27982+ "klips_debug: ipsec_alg_sa_init() :"
27983+ "found ipsec_alg (ixt_a=%p) for auth=%d\n",
27984+ ixt_a, sa_p->ips_authalg);
27985+ sa_p->ips_alg_auth=ixt_a;
27986+ }
27987+ return 0;
27988+}
27989+
27990+/*
27991+ * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
27992+ */
27993+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
27994+ struct ipsec_alg *ixt;
27995+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
27996+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
27997+ "unlinking for encalg=%d\n",
27998+ ixt->ixt_support.ias_id);
27999+ ipsec_alg_put(ixt);
28000+ }
28001+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
28002+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
28003+ "unlinking for authalg=%d\n",
28004+ ixt->ixt_support.ias_id);
28005+ ipsec_alg_put(ixt);
28006+ }
28007+ return 0;
28008+}
28009+
28010+IPSEC_PROCFS_DEBUG_NO_STATIC
28011+int
28012+ipsec_xform_get_info(char *buffer,
28013+ char **start,
28014+ off_t offset,
28015+ int length IPSEC_PROC_LAST_ARG)
28016+{
28017+ int len = 0;
28018+ off_t begin = 0;
28019+ int i;
28020+ struct list_head *head;
28021+ struct ipsec_alg *ixt;
28022+
28023+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
28024+ "klips_debug:ipsec_tncfg_get_info: "
28025+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
28026+ buffer,
28027+ *start,
28028+ (int)offset,
28029+ length);
28030+
28031+ for(i = 0, head = ipsec_alg_hash_table;
28032+ i<IPSEC_ALG_HASHSZ;
28033+ i++, head++)
28034+ {
28035+ struct list_head *p;
28036+ for (p=head->next; p!=head; p=p->next)
28037+ {
28038+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
28039+ len += ipsec_snprintf(buffer+len, length-len,
28040+ "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
28041+ ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_support.ias_id,
28042+ ixt->ixt_name, ixt->ixt_refcnt);
28043+
28044+ len += ipsec_snprintf(buffer+len, length-len,
28045+ "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
28046+ ixt->ixt_state, ixt->ixt_blocksize,
28047+ ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
28048+
28049+ len += ipsec_snprintf(buffer+len, length-len,
28050+ "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
28051+ ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
28052+
28053+ switch(ixt->ixt_alg_type)
28054+ {
28055+ case IPSEC_ALG_TYPE_AUTH:
28056+ {
28057+ struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
28058+
28059+ len += ipsec_snprintf(buffer+len, length-len,
28060+ "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
28061+ auth->ixt_a_keylen, auth->ixt_a_ctx_size,
28062+ auth->ixt_a_authlen);
28063+ break;
28064+ }
28065+ case IPSEC_ALG_TYPE_ENCRYPT:
28066+ {
28067+ struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
28068+ len += ipsec_snprintf(buffer+len, length-len,
28069+ "KEYLEN=%d CTXSIZE=%d ",
28070+ enc->ixt_e_keylen, enc->ixt_e_ctx_size);
28071+
28072+ break;
28073+ }
28074+ }
28075+
28076+ len += ipsec_snprintf(buffer+len, length-len, "\n");
28077+ }
28078+ }
28079+
28080+ *start = buffer + (offset - begin); /* Start of wanted data */
28081+ len -= (offset - begin); /* Start slop */
28082+ if (len > length)
28083+ len = length;
28084+ return len;
28085+}
28086+
28087+
28088+/*
28089+ * As the author of this module, I ONLY ALLOW using it from
28090+ * GPL (or same LICENSE TERMS as kernel source) modules.
28091+ *
28092+ * In respect to hardware crypto engines this means:
28093+ * * Closed-source device drivers ARE NOT ALLOWED to use
28094+ * this interface.
28095+ * * Closed-source VHDL/Verilog firmware running on
28096+ * the crypto hardware device IS ALLOWED to use this interface
28097+ * via a GPL (or same LICENSE TERMS as kernel source) device driver.
28098+ * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
28099+ */
28100+
28101+/*
28102+ * These symbols can only be used from GPL modules
28103+ * for now, I'm disabling this because it creates false
28104+ * symbol problems for old modutils.
28105+ */
28106+
28107+#ifdef CONFIG_MODULES
28108+#ifndef NET_26
28109+#if 0
28110+#ifndef EXPORT_SYMBOL_GPL
28111+#undef EXPORT_SYMBOL_GPL
28112+#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
28113+#endif
28114+#endif
28115+EXPORT_SYMBOL(register_ipsec_alg);
28116+EXPORT_SYMBOL(unregister_ipsec_alg);
28117+EXPORT_SYMBOL(ipsec_alg_test);
28118+#endif
28119+#endif
28120--- /dev/null Tue Mar 11 13:02:56 2003
28121+++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
28122@@ -0,0 +1,455 @@
28123+/*
28124+ * ipsec_alg to linux cryptoapi GLUE
28125+ *
28126+ * Authors: CODE.ar TEAM
28127+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
28128+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
28129+ * Luciano Ruete <docemeses@softhome.net>
28130+ *
28131+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
28132+ *
28133+ * This program is free software; you can redistribute it and/or modify it
28134+ * under the terms of the GNU General Public License as published by the
28135+ * Free Software Foundation; either version 2 of the License, or (at your
28136+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28137+ *
28138+ * This program is distributed in the hope that it will be useful, but
28139+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28140+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28141+ * for more details.
28142+ *
28143+ * Example usage:
28144+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
28145+ * modprobe ipsec_cryptoapi
28146+ * modprobe ipsec_cryptoapi test=1
28147+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
28148+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
28149+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
28150+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
28151+ */
28152+#ifndef AUTOCONF_INCLUDED
28153+#include <linux/config.h>
28154+#endif
28155+#include <linux/version.h>
28156+
28157+/*
28158+ * special case: ipsec core modular with this static algo inside:
28159+ * must avoid MODULE magic for this file
28160+ */
28161+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_CRYPTOAPI)
28162+#undef MODULE
28163+#endif
28164+
28165+#include <linux/module.h>
28166+#include <linux/init.h>
28167+
28168+#include <linux/kernel.h> /* printk() */
28169+#include <linux/errno.h> /* error codes */
28170+#include <linux/types.h> /* size_t */
28171+#include <linux/string.h>
28172+
28173+/* Check if __exit is defined, if not null it */
28174+#ifndef __exit
28175+#define __exit
28176+#endif
28177+
28178+/* warn the innocent */
28179+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
28180+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
28181+#define NO_CRYPTOAPI_SUPPORT
28182+#endif
28183+
28184+#include "openswan.h"
28185+#include "openswan/ipsec_alg.h"
28186+#include "openswan/ipsec_policy.h"
28187+
28188+#include <linux/crypto.h>
28189+#ifdef CRYPTO_API_VERSION_CODE
28190+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
28191+#define NO_CRYPTOAPI_SUPPORT
28192+#endif
28193+
28194+#ifdef NO_CRYPTOAPI_SUPPORT
28195+#warning "Building an unusable module :P"
28196+/* Catch old CryptoAPI by not allowing module to load */
28197+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
28198+{
28199+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
28200+ return -EINVAL;
28201+}
28202+#else
28203+#include <asm/scatterlist.h>
28204+#include <asm/pgtable.h>
28205+#include <linux/mm.h>
28206+
28207+#define CIPHERNAME_AES "aes"
28208+#define CIPHERNAME_1DES "des"
28209+#define CIPHERNAME_3DES "des3_ede"
28210+#define CIPHERNAME_BLOWFISH "blowfish"
28211+#define CIPHERNAME_CAST "cast5"
28212+#define CIPHERNAME_SERPENT "serpent"
28213+#define CIPHERNAME_TWOFISH "twofish"
28214+
28215+#define ESP_SERPENT 252 /* from ipsec drafts */
28216+#define ESP_TWOFISH 253 /* from ipsec drafts */
28217+
28218+#define DIGESTNAME_MD5 "md5"
28219+#define DIGESTNAME_SHA1 "sha1"
28220+
28221+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
28222+static int debug_crypto=0;
28223+static int test_crypto=0;
28224+static int excl_crypto=0;
28225+
28226+static int noauto = 0;
28227+
28228+#ifdef module_param
28229+module_param(debug_crypto,int,0600)
28230+module_param(test_crypto,int,0600)
28231+module_param(excl_crypto,int,0600)
28232+
28233+module_param(noauto,int,0600)
28234+#else
28235+MODULE_PARM(debug_crypto, "i");
28236+MODULE_PARM(test_crypto, "i");
28237+MODULE_PARM(excl_crypto, "i");
28238+
28239+MODULE_PARM(noauto,"i");
28240+#endif
28241+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
28242+
28243+#ifdef CONFIG_KLIPS_ENC_1DES
28244+static int des_ede1[] = {-1, -1};
28245+#endif
28246+static int des_ede3[] = {-1, -1};
28247+static int aes[] = {-1, -1};
28248+static int blowfish[] = {-1, -1};
28249+static int cast[] = {-1, -1};
28250+static int serpent[] = {-1, -1};
28251+static int twofish[] = {-1, -1};
28252+
28253+#ifdef CONFIG_KLIPS_ENC_1DES
28254+#ifdef module_param
28255+module_param_array(des_ede1,int,NULL,0)
28256+#else
28257+MODULE_PARM(des_ede1,"1-2i");
28258+#endif
28259+#endif
28260+#ifdef module_param
28261+module_param_array(des_ede3,int,NULL,0)
28262+module_param_array(aes,int,NULL,0)
28263+module_param_array(blowfish,int,NULL,0)
28264+module_param_array(cast,int,NULL,0)
28265+module_param_array(serpent,int,NULL,0)
28266+module_param_array(twofish,int,NULL,0)
28267+#else
28268+MODULE_PARM(des_ede3,"1-2i");
28269+MODULE_PARM(aes,"1-2i");
28270+MODULE_PARM(blowfish,"1-2i");
28271+MODULE_PARM(cast,"1-2i");
28272+MODULE_PARM(serpent,"1-2i");
28273+MODULE_PARM(twofish,"1-2i");
28274+#endif
28275+MODULE_PARM_DESC(des_ede1, "0: disable | 1: force_enable | min,max: dontuse");
28276+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
28277+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
28278+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
28279+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
28280+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
28281+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
28282+
28283+struct ipsec_alg_capi_cipher {
28284+ const char *ciphername; /* cryptoapi's ciphername */
28285+ unsigned blocksize;
28286+ unsigned short minbits;
28287+ unsigned short maxbits;
28288+ int *parm; /* lkm param for this cipher */
28289+ struct ipsec_alg_enc alg; /* note it's not a pointer */
28290+};
28291+
28292+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
28293+ { CIPHERNAME_AES, 16, 128, 256, aes, { ixt_common:{ ixt_support:{ ias_id: ESP_AES}}}},
28294+ { CIPHERNAME_TWOFISH, 16, 128, 256, twofish, { ixt_common:{ ixt_support:{ ias_id: ESP_TWOFISH,}}}},
28295+ { CIPHERNAME_SERPENT, 16, 128, 256, serpent, { ixt_common:{ ixt_support:{ ias_id: ESP_SERPENT,}}}},
28296+ { CIPHERNAME_CAST, 8, 128, 128, cast , { ixt_common:{ ixt_support:{ ias_id: ESP_CAST,}}}},
28297+ { CIPHERNAME_BLOWFISH, 8, 96, 448, blowfish, { ixt_common:{ ixt_support:{ ias_id: ESP_BLOWFISH,}}}},
28298+ { CIPHERNAME_3DES, 8, 192, 192, des_ede3, { ixt_common:{ ixt_support:{ ias_id: ESP_3DES,}}}},
28299+#ifdef CONFIG_KLIPS_ENC_1DES
28300+ { CIPHERNAME_1DES, 8, 64, 64, des_ede1, { ixt_common:{ ixt_support:{ ias_id: ESP_DES,}}}},
28301+#endif
28302+ { NULL, 0, 0, 0, NULL, {} }
28303+};
28304+
28305+#ifdef NOT_YET
28306+struct ipsec_alg_capi_digest {
28307+ const char *digestname; /* cryptoapi's digestname */
28308+ struct digest_implementation *di;
28309+ struct ipsec_alg_auth alg; /* note it's not a pointer */
28310+};
28311+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
28312+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
28313+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
28314+ { NULL, NULL, {} }
28315+};
28316+#endif
28317+/*
28318+ * "generic" linux cryptoapi setup_cipher() function
28319+ */
28320+int setup_cipher(const char *ciphername)
28321+{
28322+ return crypto_alg_available(ciphername, 0);
28323+}
28324+
28325+/*
28326+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
28327+ * register_ipsec_alg for cointaned ipsec_alg object
28328+ */
28329+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
28330+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
28331+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
28332+
28333+static int
28334+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
28335+{
28336+ int ret;
28337+ cptr->alg.ixt_common.ixt_version = IPSEC_ALG_VERSION;
28338+ cptr->alg.ixt_common.ixt_module = THIS_MODULE;
28339+ atomic_set (& cptr->alg.ixt_common.ixt_refcnt, 0);
28340+ strncpy (cptr->alg.ixt_common.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_common.ixt_name));
28341+
28342+ cptr->alg.ixt_common.ixt_blocksize=cptr->blocksize;
28343+ cptr->alg.ixt_common.ixt_support.ias_keyminbits=cptr->minbits;
28344+ cptr->alg.ixt_common.ixt_support.ias_keymaxbits=cptr->maxbits;
28345+ cptr->alg.ixt_common.ixt_state = 0;
28346+ if (excl_crypto) cptr->alg.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
28347+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_common.ixt_support.ias_keymaxbits/8;
28348+ cptr->alg.ixt_e_ctx_size = 0;
28349+ cptr->alg.ixt_common.ixt_support.ias_exttype = IPSEC_ALG_TYPE_ENCRYPT;
28350+ cptr->alg.ixt_e_new_key = _capi_new_key;
28351+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
28352+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
28353+ cptr->alg.ixt_common.ixt_data = cptr;
28354+
28355+ ret=register_ipsec_alg_enc(&cptr->alg);
28356+ printk(KERN_INFO "KLIPS cryptoapi interface: "
28357+ "alg_type=%d alg_id=%d name=%s "
28358+ "keyminbits=%d keymaxbits=%d, %s(%d)\n",
28359+ cptr->alg.ixt_common.ixt_support.ias_exttype,
28360+ cptr->alg.ixt_common.ixt_support.ias_id,
28361+ cptr->alg.ixt_common.ixt_name,
28362+ cptr->alg.ixt_common.ixt_support.ias_keyminbits,
28363+ cptr->alg.ixt_common.ixt_support.ias_keymaxbits,
28364+ ret ? "not found" : "found", ret);
28365+ return ret;
28366+}
28367+/*
28368+ * called in ipsec_sa_wipe() time, will destroy key contexts
28369+ * and do 1 unbind()
28370+ */
28371+static void
28372+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
28373+{
28374+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
28375+
28376+ if (debug_crypto > 0)
28377+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
28378+ "name=%s key_e=%p \n",
28379+ alg->ixt_common.ixt_name, key_e);
28380+ if (!key_e) {
28381+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
28382+ "name=%s NULL key_e!\n",
28383+ alg->ixt_common.ixt_name);
28384+ return;
28385+ }
28386+ crypto_free_tfm(tfm);
28387+}
28388+
28389+/*
28390+ * create new key context, need alg->ixt_data to know which
28391+ * (of many) cipher inside this module is the target
28392+ */
28393+static __u8 *
28394+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
28395+{
28396+ struct ipsec_alg_capi_cipher *cptr;
28397+ struct crypto_tfm *tfm=NULL;
28398+
28399+ cptr = alg->ixt_common.ixt_data;
28400+ if (!cptr) {
28401+ printk(KERN_ERR "_capi_new_key(): "
28402+ "NULL ixt_data (?!) for \"%s\" algo\n"
28403+ , alg->ixt_common.ixt_name);
28404+ goto err;
28405+ }
28406+ if (debug_crypto > 0)
28407+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28408+ "name=%s cptr=%p key=%p keysize=%d\n",
28409+ alg->ixt_common.ixt_name, cptr, key, keylen);
28410+
28411+ /*
28412+ * alloc tfm
28413+ */
28414+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
28415+ if (!tfm) {
28416+ printk(KERN_ERR "_capi_new_key(): "
28417+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
28418+ , alg->ixt_common.ixt_name, cptr->ciphername);
28419+ goto err;
28420+ }
28421+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
28422+ printk(KERN_ERR "_capi_new_key(): "
28423+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
28424+ , alg->ixt_common.ixt_name, keylen);
28425+ crypto_free_tfm(tfm);
28426+ tfm=NULL;
28427+ }
28428+err:
28429+ if (debug_crypto > 0)
28430+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28431+ "name=%s key=%p keylen=%d tfm=%p\n",
28432+ alg->ixt_common.ixt_name, key, keylen, tfm);
28433+ return (__u8 *) tfm;
28434+}
28435+/*
28436+ * core encryption function: will use cx->ci to call actual cipher's
28437+ * cbc function
28438+ */
28439+static int
28440+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
28441+ int error =0;
28442+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
28443+ struct scatterlist sg = {
28444+ .page = virt_to_page(in),
28445+ .offset = (unsigned long)(in) % PAGE_SIZE,
28446+ .length=ilen,
28447+ };
28448+ if (debug_crypto > 1)
28449+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28450+ "key_e=%p "
28451+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
28452+ , key_e
28453+ , in, in, ilen, iv, encrypt);
28454+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
28455+ if (encrypt)
28456+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
28457+ else
28458+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
28459+ if (debug_crypto > 1)
28460+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28461+ "error=%d\n"
28462+ , error);
28463+ return (error<0)? error : ilen;
28464+}
28465+/*
28466+ * main initialization loop: for each cipher in list, do
28467+ * 1) setup cryptoapi cipher else continue
28468+ * 2) register ipsec_alg object
28469+ */
28470+static int
28471+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28472+{
28473+ struct ipsec_alg_capi_cipher *cptr;
28474+ /* foreach cipher in list ... */
28475+ for (cptr=clist;cptr->ciphername;cptr++) {
28476+ /*
28477+ * see if cipher has been disabled (0) or
28478+ * if noauto set and not enabled (1)
28479+ */
28480+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
28481+ if (debug_crypto>0)
28482+ printk(KERN_INFO "setup_cipher_list(): "
28483+ "ciphername=%s skipped at user request: "
28484+ "noauto=%d parm[0]=%d parm[1]=%d\n"
28485+ , cptr->ciphername
28486+ , noauto
28487+ , cptr->parm[0]
28488+ , cptr->parm[1]);
28489+ continue;
28490+ }
28491+ /*
28492+ * use a local ci to avoid touching cptr->ci,
28493+ * if register ipsec_alg success then bind cipher
28494+ */
28495+ if(cptr->alg.ixt_common.ixt_support.ias_name == NULL) {
28496+ cptr->alg.ixt_common.ixt_support.ias_name = cptr->ciphername;
28497+ }
28498+
28499+ if( setup_cipher(cptr->ciphername) ) {
28500+ if (debug_crypto > 0)
28501+ printk(KERN_DEBUG "klips_debug:"
28502+ "setup_cipher_list():"
28503+ "ciphername=%s found\n"
28504+ , cptr->ciphername);
28505+
28506+ if (setup_ipsec_alg_capi_cipher(cptr) != 0) {
28507+ printk(KERN_ERR "klips_debug:"
28508+ "setup_cipher_list():"
28509+ "ciphername=%s failed ipsec_alg_register\n"
28510+ , cptr->ciphername);
28511+ }
28512+ } else {
28513+ printk(KERN_INFO "KLIPS: lookup for ciphername=%s: not found \n",
28514+ cptr->ciphername);
28515+ }
28516+ }
28517+ return 0;
28518+}
28519+/*
28520+ * deregister ipsec_alg objects and unbind ciphers
28521+ */
28522+static int
28523+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28524+{
28525+ struct ipsec_alg_capi_cipher *cptr;
28526+ /* foreach cipher in list ... */
28527+ for (cptr=clist;cptr->ciphername;cptr++) {
28528+ if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28529+ unregister_ipsec_alg_enc(&cptr->alg);
28530+ }
28531+ }
28532+ return 0;
28533+}
28534+/*
28535+ * test loop for registered algos
28536+ */
28537+static int
28538+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
28539+{
28540+ int test_ret;
28541+ struct ipsec_alg_capi_cipher *cptr;
28542+ /* foreach cipher in list ... */
28543+ for (cptr=clist;cptr->ciphername;cptr++) {
28544+ if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28545+ test_ret=ipsec_alg_test(
28546+ cptr->alg.ixt_common.ixt_support.ias_exttype,
28547+ cptr->alg.ixt_common.ixt_support.ias_id,
28548+ test_crypto);
28549+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
28550+ cptr->alg.ixt_common.ixt_support.ias_exttype,
28551+ cptr->alg.ixt_common.ixt_support.ias_id,
28552+ test_ret);
28553+ }
28554+ }
28555+ return 0;
28556+}
28557+
28558+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
28559+{
28560+ int ret, test_ret;
28561+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
28562+ return -EPROTONOSUPPORT;
28563+ if (ret==0 && test_crypto) {
28564+ test_ret=test_cipher_list(alg_capi_carray);
28565+ }
28566+ return ret;
28567+}
28568+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini )
28569+{
28570+ unsetup_cipher_list(alg_capi_carray);
28571+ return;
28572+}
28573+#ifdef MODULE_LICENSE
28574+MODULE_LICENSE("GPL");
28575+#endif
28576+
28577+#endif /* NO_CRYPTOAPI_SUPPORT */
28578--- /dev/null Tue Mar 11 13:02:56 2003
28579+++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004
28580@@ -0,0 +1,607 @@
28581+/*
28582+ * processing code for ESP
28583+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
28584+ *
28585+ * This program is free software; you can redistribute it and/or modify it
28586+ * under the terms of the GNU General Public License as published by the
28587+ * Free Software Foundation; either version 2 of the License, or (at your
28588+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28589+ *
28590+ * This program is distributed in the hope that it will be useful, but
28591+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28592+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28593+ * for more details.
28594+ */
28595+
28596+char ipsec_esp_c_version[] = "RCSID $Id: ipsec_esp.c,v 1.13.2.6 2006/10/06 21:39:26 paul Exp $";
28597+#ifndef AUTOCONF_INCLUDED
28598+#include <linux/config.h>
28599+#endif
28600+#include <linux/version.h>
28601+
28602+#define __NO_VERSION__
28603+#include <linux/module.h>
28604+#include <linux/kernel.h> /* printk() */
28605+
28606+#include "openswan/ipsec_param.h"
28607+
28608+#ifdef MALLOC_SLAB
28609+# include <linux/slab.h> /* kmalloc() */
28610+#else /* MALLOC_SLAB */
28611+# include <linux/malloc.h> /* kmalloc() */
28612+#endif /* MALLOC_SLAB */
28613+#include <linux/errno.h> /* error codes */
28614+#include <linux/types.h> /* size_t */
28615+#include <linux/interrupt.h> /* mark_bh */
28616+
28617+#include <linux/netdevice.h> /* struct device, and other headers */
28618+#include <linux/etherdevice.h> /* eth_type_trans */
28619+#include <linux/ip.h> /* struct iphdr */
28620+#include <linux/skbuff.h>
28621+#include <openswan.h>
28622+#ifdef SPINLOCK
28623+# ifdef SPINLOCK_23
28624+# include <linux/spinlock.h> /* *lock* */
28625+# else /* SPINLOCK_23 */
28626+# include <asm/spinlock.h> /* *lock* */
28627+# endif /* SPINLOCK_23 */
28628+#endif /* SPINLOCK */
28629+
28630+#include <net/ip.h>
28631+#include <net/protocol.h>
28632+
28633+#include "openswan/radij.h"
28634+#include "openswan/ipsec_encap.h"
28635+#include "openswan/ipsec_sa.h"
28636+
28637+#include "openswan/ipsec_radij.h"
28638+#include "openswan/ipsec_xform.h"
28639+#include "openswan/ipsec_tunnel.h"
28640+#include "openswan/ipsec_rcv.h"
28641+#include "openswan/ipsec_xmit.h"
28642+
28643+#include "openswan/ipsec_auth.h"
28644+
28645+#ifdef CONFIG_KLIPS_ESP
28646+#include "openswan/ipsec_esp.h"
28647+#endif /* CONFIG_KLIPS_ESP */
28648+
28649+#include "openswan/ipsec_proto.h"
28650+#include "openswan/ipsec_alg.h"
28651+
28652+#ifdef CONFIG_KLIPS_DEBUG
28653+#define ESP_DMP(_x,_y,_z) if(debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
28654+#else
28655+#define ESP_DMP(_x,_y,_z)
28656+#endif
28657+
28658+#ifdef CONFIG_KLIPS_ESP
28659+enum ipsec_rcv_value
28660+ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
28661+ struct sk_buff *skb)
28662+{
28663+ __u8 proto;
28664+ int len; /* packet length */
28665+
28666+ len = skb->len;
28667+ proto = irs->ipp->protocol;
28668+
28669+ /* XXX this will need to be 8 for IPv6 */
28670+ if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
28671+ printk("klips_error:ipsec_rcv: "
28672+ "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
28673+ len - irs->iphlen,
28674+ irs->ipsaddr_txt);
28675+ if(irs->stats) {
28676+ irs->stats->rx_errors++;
28677+ }
28678+ return IPSEC_RCV_BADLEN;
28679+ }
28680+
28681+ if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {
28682+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
28683+ "klips_debug:ipsec_rcv: "
28684+ "runt esp packet of skb->len=%d received from %s, dropped.\n",
28685+ skb->len,
28686+ irs->ipsaddr_txt);
28687+ if(irs->stats) {
28688+ irs->stats->rx_errors++;
28689+ }
28690+ return IPSEC_RCV_BADLEN;
28691+ }
28692+
28693+ irs->protostuff.espstuff.espp = (struct esphdr *)skb->h.raw;
28694+ irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
28695+
28696+ return IPSEC_RCV_OK;
28697+}
28698+
28699+enum ipsec_rcv_value
28700+ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
28701+ struct sk_buff *skb,
28702+ __u32 *replay,
28703+ unsigned char **authenticator)
28704+{
28705+ struct esphdr *espp = irs->protostuff.espstuff.espp;
28706+ //unsigned char *idat = (unsigned char *)espp;
28707+
28708+ KLIPS_PRINT(debug_rcv,
28709+ "klips_debug:ipsec_rcv: "
28710+ "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
28711+ irs->ipsaddr_txt,
28712+ (__u32)ntohl(espp->esp_rpl),
28713+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
28714+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
28715+ irs->len,
28716+ irs->ilen,
28717+ irs->sa_len ? irs->sa : " (error)");
28718+
28719+ *replay = ntohl(espp->esp_rpl);
28720+ *authenticator = &(skb->h.raw[irs->ilen]);
28721+
28722+ return IPSEC_RCV_OK;
28723+}
28724+
28725+enum ipsec_rcv_value
28726+ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
28727+ struct sk_buff *skb)
28728+{
28729+ struct auth_alg *aa;
28730+ struct esphdr *espp = irs->protostuff.espstuff.espp;
28731+ union {
28732+ MD5_CTX md5;
28733+ SHA1_CTX sha1;
28734+ } tctx;
28735+
28736+ if (irs->ipsp->ips_alg_auth) {
28737+ KLIPS_PRINT(debug_rcv,
28738+ "klips_debug:ipsec_rcv: "
28739+ "ipsec_alg hashing proto=%d... ",
28740+ irs->said.proto);
28741+ if(irs->said.proto == IPPROTO_ESP) {
28742+ ipsec_alg_sa_esp_hash(irs->ipsp,
28743+ (caddr_t)espp, irs->ilen,
28744+ irs->hash, AHHMAC_HASHLEN);
28745+ return IPSEC_RCV_OK;
28746+ }
28747+ return IPSEC_RCV_BADPROTO;
28748+ }
28749+ aa = irs->authfuncs;
28750+
28751+ /* copy the initialized keying material */
28752+ memcpy(&tctx, irs->ictx, irs->ictx_len);
28753+
28754+#ifdef HASH_DEBUG
28755+ ESP_DMP("ictx", irs->ictx, irs->ictx_len);
28756+
28757+ ESP_DMP("mac_esp", (caddr_t)espp, irs->ilen);
28758+#endif
28759+ (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
28760+
28761+ (*aa->final)(irs->hash, (void *)&tctx);
28762+
28763+#ifdef HASH_DEBUG
28764+ ESP_DMP("hash1", irs->hash, aa->hashlen);
28765+#endif
28766+
28767+ memcpy(&tctx, irs->octx, irs->octx_len);
28768+
28769+#ifdef HASH_DEBUG
28770+ ESP_DMP("octx", irs->octx, irs->octx_len);
28771+#endif
28772+
28773+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
28774+ (*aa->final)(irs->hash, (void *)&tctx);
28775+
28776+ return IPSEC_RCV_OK;
28777+}
28778+
28779+
28780+enum ipsec_rcv_value
28781+ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
28782+{
28783+ struct ipsec_sa *ipsp = irs->ipsp;
28784+ struct esphdr *espp = irs->protostuff.espstuff.espp;
28785+ int i;
28786+ int pad = 0, padlen;
28787+ int badpad = 0;
28788+ int esphlen = 0;
28789+ __u8 *idat; /* pointer to content to be decrypted/authenticated */
28790+ int encaplen = 0;
28791+ struct sk_buff *skb;
28792+ struct ipsec_alg_enc *ixt_e=NULL;
28793+
28794+ skb=irs->skb;
28795+
28796+ idat = skb->h.raw;
28797+
28798+ /* encaplen is the distance between the end of the IP
28799+ * header and the beginning of the ESP header.
28800+ * on ESP headers it is zero, but on UDP-encap ESP
28801+ * it includes the space for the UDP header.
28802+ *
28803+ * Note: UDP-encap code has already moved the
28804+ * skb->data forward to accomodate this.
28805+ */
28806+ encaplen = idat - (skb->nh.raw + irs->iphlen);
28807+
28808+ ixt_e=ipsp->ips_alg_enc;
28809+ esphlen = ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
28810+ KLIPS_PRINT(debug_rcv,
28811+ "klips_debug:ipsec_rcv: "
28812+ "encalg=%d esphlen=%d\n",
28813+ ipsp->ips_encalg, esphlen);
28814+
28815+ idat += esphlen;
28816+ irs->ilen -= esphlen;
28817+
28818+ if (ipsec_alg_esp_encrypt(ipsp,
28819+ idat, irs->ilen, espp->esp_iv,
28820+ IPSEC_ALG_DECRYPT) <= 0) {
28821+#ifdef CONFIG_KLIPS_DEBUG
28822+ KLIPS_ERROR(debug_rcv, "klips_error:ipsec_rcv: "
28823+ "got packet with esplen = %d "
28824+ "from %s -- should be on "
28825+ "ENC(%d) octet boundary, "
28826+ "packet dropped\n",
28827+ irs->ilen,
28828+ irs->ipsaddr_txt,
28829+ ipsp->ips_encalg);
28830+#endif
28831+ if(irs->stats) {
28832+ irs->stats->rx_errors++;
28833+ }
28834+ return IPSEC_RCV_BAD_DECRYPT;
28835+ }
28836+
28837+ ESP_DMP("postdecrypt", idat, irs->ilen);
28838+
28839+ irs->next_header = idat[irs->ilen - 1];
28840+ padlen = idat[irs->ilen - 2];
28841+ pad = padlen + 2 + irs->authlen;
28842+
28843+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28844+ "klips_debug:ipsec_rcv: "
28845+ "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
28846+ padlen);
28847+
28848+ for (i = 1; i <= padlen; i++) {
28849+ if((i % 16) == 1) {
28850+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28851+ "klips_debug: %02x:",
28852+ i - 1);
28853+ }
28854+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28855+ " %02x",
28856+ idat[irs->ilen - 2 - padlen + i - 1]);
28857+ if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
28858+ badpad = 1;
28859+ }
28860+ if((i % 16) == 0) {
28861+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28862+ "\n");
28863+ }
28864+ }
28865+ if((i % 16) != 1) {
28866+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28867+ "\n");
28868+ }
28869+ if(badpad) {
28870+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28871+ "klips_debug:ipsec_rcv: "
28872+ "warning, decrypted packet from %s has bad padding\n",
28873+ irs->ipsaddr_txt);
28874+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28875+ "klips_debug:ipsec_rcv: "
28876+ "...may be bad decryption -- not dropped\n");
28877+ ipsp->ips_errs.ips_encpad_errs += 1;
28878+ }
28879+
28880+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28881+ "klips_debug:ipsec_rcv: "
28882+ "packet decrypted from %s: next_header = %d, padding = %d\n",
28883+ irs->ipsaddr_txt,
28884+ irs->next_header,
28885+ pad - 2 - irs->authlen);
28886+
28887+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad));
28888+
28889+ /*
28890+ * move the IP header forward by the size of the ESP header, which
28891+ * will remove the the ESP header from the packet.
28892+ *
28893+ * XXX this is really unnecessary, since odds we are in tunnel
28894+ * mode, and we will be *removing* this IP header.
28895+ *
28896+ */
28897+ memmove((void *)(idat - irs->iphlen),
28898+ (void *)(skb->nh.raw), irs->iphlen);
28899+
28900+ ESP_DMP("esp postmove", (idat - irs->iphlen),
28901+ irs->iphlen + irs->ilen);
28902+
28903+ /* skb_pull below, will move up by esphlen */
28904+
28905+ /* XXX not clear how this can happen, as the message indicates */
28906+ if(skb->len < esphlen) {
28907+ printk(KERN_WARNING
28908+ "klips_error:ipsec_rcv: "
28909+ "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n",
28910+ esphlen, (int)(skb->len));
28911+ return IPSEC_RCV_ESP_DECAPFAIL;
28912+ }
28913+ skb_pull(skb, esphlen);
28914+ skb->nh.raw = idat - irs->iphlen;
28915+ irs->ipp = skb->nh.iph;
28916+
28917+ ESP_DMP("esp postpull", skb->data, skb->len);
28918+
28919+ /* now, trip off the padding from the end */
28920+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28921+ "klips_debug:ipsec_rcv: "
28922+ "trimming to %d.\n",
28923+ irs->len - esphlen - pad);
28924+ if(pad + esphlen <= irs->len) {
28925+ skb_trim(skb, irs->len - esphlen - pad);
28926+ } else {
28927+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28928+ "klips_debug:ipsec_rcv: "
28929+ "bogus packet, size is zero or negative, dropping.\n");
28930+ return IPSEC_RCV_DECAPFAIL;
28931+ }
28932+
28933+ return IPSEC_RCV_OK;
28934+}
28935+
28936+/*
28937+ *
28938+ */
28939+enum ipsec_xmit_value
28940+ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs)
28941+{
28942+#ifdef CONFIG_KLIPS_ENC_3DES
28943+ __u32 iv[2];
28944+#endif
28945+ struct esphdr *espp;
28946+ int ilen = 0;
28947+ int padlen = 0, i;
28948+ unsigned char *dat;
28949+ unsigned char *idat, *pad;
28950+ __u8 hash[AH_AMAX];
28951+ union {
28952+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
28953+ MD5_CTX md5;
28954+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
28955+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
28956+ SHA1_CTX sha1;
28957+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
28958+ } tctx;
28959+
28960+ dat = (unsigned char *)ixs->iph;
28961+
28962+ espp = (struct esphdr *)(dat + ixs->iphlen);
28963+ espp->esp_spi = ixs->ipsp->ips_said.spi;
28964+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
28965+
28966+ switch(ixs->ipsp->ips_encalg) {
28967+#if defined(CONFIG_KLIPS_ENC_3DES)
28968+#ifdef CONFIG_KLIPS_ENC_3DES
28969+ case ESP_3DES:
28970+#endif /* CONFIG_KLIPS_ENC_3DES */
28971+ iv[0] = *((__u32*)&(espp->esp_iv) ) =
28972+ ((__u32*)(ixs->ipsp->ips_iv))[0];
28973+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
28974+ ((__u32*)(ixs->ipsp->ips_iv))[1];
28975+ break;
28976+#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
28977+ default:
28978+ ixs->stats->tx_errors++;
28979+ return IPSEC_XMIT_ESP_BADALG;
28980+ }
28981+
28982+ idat = dat + ixs->iphlen + sizeof(struct esphdr);
28983+ ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen);
28984+
28985+ /* Self-describing padding */
28986+ pad = &dat[ixs->skb->len - ixs->tailroom];
28987+ padlen = ixs->tailroom - 2 - ixs->authlen;
28988+ for (i = 0; i < padlen; i++) {
28989+ pad[i] = i + 1;
28990+ }
28991+ dat[ixs->skb->len - ixs->authlen - 2] = padlen;
28992+
28993+ dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol;
28994+ ixs->iph->protocol = IPPROTO_ESP;
28995+
28996+ switch(ixs->ipsp->ips_encalg) {
28997+#ifdef CONFIG_KLIPS_ENC_3DES
28998+ case ESP_3DES:
28999+ des_ede3_cbc_encrypt((des_cblock *)idat,
29000+ (des_cblock *)idat,
29001+ ilen,
29002+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
29003+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
29004+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
29005+ (des_cblock *)iv, 1);
29006+ break;
29007+#endif /* CONFIG_KLIPS_ENC_3DES */
29008+ default:
29009+ ixs->stats->tx_errors++;
29010+ return IPSEC_XMIT_ESP_BADALG;
29011+ }
29012+
29013+ switch(ixs->ipsp->ips_encalg) {
29014+#if defined(CONFIG_KLIPS_ENC_3DES)
29015+#ifdef CONFIG_KLIPS_ENC_3DES
29016+ case ESP_3DES:
29017+#endif /* CONFIG_KLIPS_ENC_3DES */
29018+ /* XXX update IV with the last 8 octets of the encryption */
29019+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
29020+ ((__u32*)(ixs->ipsp->ips_iv))[0] =
29021+ ((__u32 *)(idat))[(ilen >> 2) - 2];
29022+ ((__u32*)(ixs->ipsp->ips_iv))[1] =
29023+ ((__u32 *)(idat))[(ilen >> 2) - 1];
29024+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
29025+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
29026+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
29027+ break;
29028+#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
29029+ default:
29030+ ixs->stats->tx_errors++;
29031+ return IPSEC_XMIT_ESP_BADALG;
29032+ }
29033+
29034+ switch(ixs->ipsp->ips_authalg) {
29035+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
29036+ case AH_MD5:
29037+ ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29038+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
29039+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
29040+ osMD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29041+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
29042+ osMD5Final(hash, &tctx.md5);
29043+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
29044+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
29045+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
29046+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
29047+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
29048+ osMD5Final(hash, &tctx.md5);
29049+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
29050+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
29051+
29052+ /* paranoid */
29053+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
29054+ memset((caddr_t)hash, 0, sizeof(*hash));
29055+ break;
29056+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
29057+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
29058+ case AH_SHA:
29059+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
29060+ SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29061+ SHA1Final(hash, &tctx.sha1);
29062+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
29063+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
29064+ SHA1Final(hash, &tctx.sha1);
29065+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
29066+
29067+ /* paranoid */
29068+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
29069+ memset((caddr_t)hash, 0, sizeof(*hash));
29070+ break;
29071+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
29072+ case AH_NONE:
29073+ break;
29074+ default:
29075+ ixs->stats->tx_errors++;
29076+ return IPSEC_XMIT_AH_BADALG;
29077+ }
29078+
29079+ ixs->skb->h.raw = (unsigned char*)espp;
29080+
29081+ return IPSEC_XMIT_OK;
29082+}
29083+
29084+
29085+struct xform_functions esp_xform_funcs[]={
29086+ { rcv_checks: ipsec_rcv_esp_checks,
29087+ rcv_setup_auth: ipsec_rcv_esp_decrypt_setup,
29088+ rcv_calc_auth: ipsec_rcv_esp_authcalc,
29089+ rcv_decrypt: ipsec_rcv_esp_decrypt,
29090+
29091+ xmit_setup: ipsec_xmit_esp_setup,
29092+ xmit_headroom: sizeof(struct esphdr),
29093+ xmit_needtailroom: 1,
29094+ },
29095+};
29096+
29097+#ifdef NET_26
29098+struct inet_protocol esp_protocol = {
29099+ .handler = ipsec_rcv,
29100+ .no_policy = 1,
29101+};
29102+#else
29103+struct inet_protocol esp_protocol =
29104+{
29105+ ipsec_rcv, /* ESP handler */
29106+ NULL, /* TUNNEL error control */
29107+#ifdef NETDEV_25
29108+ 1, /* no policy */
29109+#else
29110+ 0, /* next */
29111+ IPPROTO_ESP, /* protocol ID */
29112+ 0, /* copy */
29113+ NULL, /* data */
29114+ "ESP" /* name */
29115+#endif
29116+};
29117+#endif /* NET_26 */
29118+
29119+#endif /* !CONFIG_KLIPS_ESP */
29120+
29121+
29122+/*
29123+ * $Log: ipsec_esp.c,v $
29124+ * Revision 1.13.2.6 2006/10/06 21:39:26 paul
29125+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
29126+ * set. This is defined through autoconf.h which is included through the
29127+ * linux kernel build macros.
29128+ *
29129+ * Revision 1.13.2.5 2006/08/24 03:02:01 paul
29130+ * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
29131+ *
29132+ * Revision 1.13.2.4 2006/05/06 03:07:38 ken
29133+ * Pull in proper padsize->tailroom fix from #public
29134+ * Need to do correct math on padlen since padsize is not equal to tailroom
29135+ *
29136+ * Revision 1.13.2.3 2006/05/05 03:58:04 ken
29137+ * ixs->padsize becomes ixs->tailroom
29138+ *
29139+ * Revision 1.13.2.2 2006/05/01 14:36:03 mcr
29140+ * use KLIPS_ERROR for fatal things.
29141+ *
29142+ * Revision 1.13.2.1 2006/04/20 16:33:06 mcr
29143+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
29144+ * Fix in-kernel module compilation. Sub-makefiles do not work.
29145+ *
29146+ * Revision 1.13 2005/05/21 03:19:57 mcr
29147+ * hash ctx is not really that interesting most of the time.
29148+ *
29149+ * Revision 1.12 2005/05/11 01:28:49 mcr
29150+ * removed "poor-man"s OOP in favour of proper C structures.
29151+ *
29152+ * Revision 1.11 2005/04/29 05:10:22 mcr
29153+ * removed from extraenous includes to make unit testing easier.
29154+ *
29155+ * Revision 1.10 2005/04/17 04:36:14 mcr
29156+ * code now deals with ESP and UDP-ESP code.
29157+ *
29158+ * Revision 1.9 2005/04/15 19:52:30 mcr
29159+ * adjustments to use proper skb fields for data.
29160+ *
29161+ * Revision 1.8 2004/09/14 00:22:57 mcr
29162+ * adjustment of MD5* functions.
29163+ *
29164+ * Revision 1.7 2004/09/13 02:23:01 mcr
29165+ * #define inet_protocol if necessary.
29166+ *
29167+ * Revision 1.6 2004/09/06 18:35:49 mcr
29168+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
29169+ * so adjust for that.
29170+ *
29171+ * Revision 1.5 2004/08/17 03:27:23 mcr
29172+ * klips 2.6 edits.
29173+ *
29174+ * Revision 1.4 2004/08/04 15:57:07 mcr
29175+ * moved des .h files to include/des/ *
29176+ * included 2.6 protocol specific things
29177+ * started at NAT-T support, but it will require a kernel patch.
29178+ *
29179+ * Revision 1.3 2004/07/10 19:11:18 mcr
29180+ * CONFIG_IPSEC -> CONFIG_KLIPS.
29181+ *
29182+ * Revision 1.2 2004/04/06 02:49:25 mcr
29183+ * pullup of algo code from alg-branch.
29184+ *
29185+ *
29186+ *
29187+ */
29188--- /dev/null Tue Mar 11 13:02:56 2003
29189+++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004
29190@@ -0,0 +1,614 @@
29191+/*
29192+ * @(#) Initialization code.
29193+ * Copyright (C) 1996, 1997 John Ioannidis.
29194+ * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org>
29195+ * 2001 - 2004 Michael Richardson <mcr@xelerance.com>
29196+ *
29197+ * This program is free software; you can redistribute it and/or modify it
29198+ * under the terms of the GNU General Public License as published by the
29199+ * Free Software Foundation; either version 2 of the License, or (at your
29200+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29201+ *
29202+ * This program is distributed in the hope that it will be useful, but
29203+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29204+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29205+ * for more details.
29206+ *
29207+ * /proc system code was split out into ipsec_proc.c after rev. 1.70.
29208+ *
29209+ */
29210+
29211+char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.104.2.4 2006/10/06 21:39:26 paul Exp $";
29212+
29213+#ifndef AUTOCONF_INCLUDED
29214+#include <linux/config.h>
29215+#endif
29216+#include <linux/version.h>
29217+#include <linux/module.h>
29218+#include <linux/kernel.h> /* printk() */
29219+
29220+#include "openswan/ipsec_param.h"
29221+
29222+#ifdef MALLOC_SLAB
29223+# include <linux/slab.h> /* kmalloc() */
29224+#else /* MALLOC_SLAB */
29225+# include <linux/malloc.h> /* kmalloc() */
29226+#endif /* MALLOC_SLAB */
29227+#include <linux/errno.h> /* error codes */
29228+#include <linux/types.h> /* size_t */
29229+#include <linux/interrupt.h> /* mark_bh */
29230+
29231+#include <linux/netdevice.h> /* struct device, and other headers */
29232+#include <linux/etherdevice.h> /* eth_type_trans */
29233+#include <linux/ip.h> /* struct iphdr */
29234+#include <linux/in.h> /* struct sockaddr_in */
29235+#include <linux/skbuff.h>
29236+#include <linux/random.h> /* get_random_bytes() */
29237+#include <net/protocol.h>
29238+
29239+#include <openswan.h>
29240+
29241+#ifdef SPINLOCK
29242+# ifdef SPINLOCK_23
29243+# include <linux/spinlock.h> /* *lock* */
29244+# else /* 23_SPINLOCK */
29245+# include <asm/spinlock.h> /* *lock* */
29246+# endif /* 23_SPINLOCK */
29247+#endif /* SPINLOCK */
29248+
29249+#include <net/ip.h>
29250+
29251+#ifdef CONFIG_PROC_FS
29252+# include <linux/proc_fs.h>
29253+#endif /* CONFIG_PROC_FS */
29254+
29255+#ifdef NETLINK_SOCK
29256+# include <linux/netlink.h>
29257+#else
29258+# include <net/netlink.h>
29259+#endif
29260+
29261+#include "openswan/radij.h"
29262+
29263+#include "openswan/ipsec_life.h"
29264+#include "openswan/ipsec_stats.h"
29265+#include "openswan/ipsec_sa.h"
29266+
29267+#include "openswan/ipsec_encap.h"
29268+#include "openswan/ipsec_radij.h"
29269+#include "openswan/ipsec_xform.h"
29270+#include "openswan/ipsec_tunnel.h"
29271+
29272+#include "openswan/ipsec_rcv.h"
29273+#include "openswan/ipsec_ah.h"
29274+#include "openswan/ipsec_esp.h"
29275+
29276+#ifdef CONFIG_KLIPS_IPCOMP
29277+# include "openswan/ipcomp.h"
29278+#endif /* CONFIG_KLIPS_IPCOMP */
29279+
29280+#include "openswan/ipsec_proto.h"
29281+#include "openswan/ipsec_alg.h"
29282+
29283+#include <pfkeyv2.h>
29284+#include <pfkey.h>
29285+
29286+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29287+#include <net/xfrmudp.h>
29288+#endif
29289+
29290+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(HAVE_XFRM4_UDP_REGISTER)
29291+#warning "You are trying to build KLIPS2.6 with NAT-T support, but you did not"
29292+#error "properly apply the NAT-T patch to your 2.6 kernel source tree."
29293+#endif
29294+
29295+#if !defined(CONFIG_KLIPS_ESP) && !defined(CONFIG_KLIPS_AH)
29296+#error "kernel configuration must include ESP or AH"
29297+#endif
29298+
29299+/*
29300+ * seems to be present in 2.4.10 (Linus), but also in some RH and other
29301+ * distro kernels of a lower number.
29302+ */
29303+#ifdef MODULE_LICENSE
29304+MODULE_LICENSE("GPL");
29305+#endif
29306+
29307+#ifdef CONFIG_KLIPS_DEBUG
29308+int debug_eroute = 0;
29309+int debug_spi = 0;
29310+int debug_netlink = 0;
29311+#endif /* CONFIG_KLIPS_DEBUG */
29312+
29313+struct prng ipsec_prng;
29314+
29315+
29316+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29317+xfrm4_rcv_encap_t klips_old_encap = NULL;
29318+#endif
29319+
29320+extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
29321+/*
29322+ * the following structure is required so that we receive
29323+ * event notifications when network devices are enabled and
29324+ * disabled (ifconfig up and down).
29325+ */
29326+static struct notifier_block ipsec_dev_notifier={
29327+ ipsec_device_event,
29328+ NULL,
29329+ 0
29330+};
29331+
29332+#ifdef CONFIG_SYSCTL
29333+extern int ipsec_sysctl_register(void);
29334+extern void ipsec_sysctl_unregister(void);
29335+#endif
29336+
29337+#if defined(NET_26) || defined(IPSKB_XFRM_TUNNEL_SIZE)
29338+static inline int
29339+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
29340+{
29341+ return inet_add_protocol(prot, protocol);
29342+}
29343+
29344+static inline int
29345+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
29346+{
29347+ return inet_del_protocol(prot, protocol);
29348+}
29349+
29350+#else
29351+static inline int
29352+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
29353+{
29354+ inet_add_protocol(prot);
29355+ return 0;
29356+}
29357+
29358+static inline int
29359+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
29360+{
29361+ inet_del_protocol(prot);
29362+ return 0;
29363+}
29364+
29365+#endif
29366+
29367+/* void */
29368+int
29369+ipsec_klips_init(void)
29370+{
29371+ int error = 0;
29372+ unsigned char seed[256];
29373+#ifdef CONFIG_KLIPS_ENC_3DES
29374+ extern int des_check_key;
29375+
29376+ /* turn off checking of keys */
29377+ des_check_key=0;
29378+#endif /* CONFIG_KLIPS_ENC_3DES */
29379+
29380+ KLIPS_PRINT(1, "klips_info:ipsec_init: "
29381+ "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n",
29382+ ipsec_version_code());
29383+
29384+ error |= ipsec_proc_init();
29385+
29386+#ifdef SPINLOCK
29387+ ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
29388+#else /* SPINLOCK */
29389+ ipsec_sadb.sadb_lock = 0;
29390+#endif /* SPINLOCK */
29391+
29392+#ifndef SPINLOCK
29393+ tdb_lock.lock = 0;
29394+ eroute_lock.lock = 0;
29395+#endif /* !SPINLOCK */
29396+
29397+ error |= ipsec_sadb_init();
29398+ error |= ipsec_radijinit();
29399+
29400+ error |= pfkey_init();
29401+
29402+ error |= register_netdevice_notifier(&ipsec_dev_notifier);
29403+
29404+#ifdef CONFIG_KLIPS_ESP
29405+ openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP);
29406+#endif /* CONFIG_KLIPS_ESP */
29407+
29408+#ifdef CONFIG_KLIPS_AH
29409+ openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH);
29410+#endif /* CONFIG_KLIPS_AH */
29411+
29412+/* we never actually link IPCOMP to the stack */
29413+#ifdef IPCOMP_USED_ALONE
29414+#ifdef CONFIG_KLIPS_IPCOMP
29415+ openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP);
29416+#endif /* CONFIG_KLIPS_IPCOMP */
29417+#endif
29418+
29419+ error |= ipsec_tunnel_init_devices();
29420+
29421+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29422+ /* register our ESP-UDP handler */
29423+ if(udp4_register_esp_rcvencap(klips26_rcv_encap
29424+ , &klips_old_encap)!=0) {
29425+ printk(KERN_ERR "KLIPS: can not register klips_rcv_encap function\n");
29426+ }
29427+#endif
29428+
29429+
29430+#ifdef CONFIG_SYSCTL
29431+ error |= ipsec_sysctl_register();
29432+#endif
29433+
29434+ ipsec_alg_init();
29435+
29436+ get_random_bytes((void *)seed, sizeof(seed));
29437+ prng_init(&ipsec_prng, seed, sizeof(seed));
29438+
29439+ return error;
29440+}
29441+
29442+
29443+/* void */
29444+int
29445+ipsec_cleanup(void)
29446+{
29447+ int error = 0;
29448+
29449+#ifdef CONFIG_SYSCTL
29450+ ipsec_sysctl_unregister();
29451+#endif
29452+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29453+ if(udp4_unregister_esp_rcvencap(klips_old_encap) < 0) {
29454+ printk(KERN_ERR "KLIPS: can not unregister klips_rcv_encap function\n");
29455+ }
29456+#endif
29457+
29458+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29459+ "klips_debug:ipsec_cleanup: "
29460+ "calling ipsec_tunnel_cleanup_devices.\n");
29461+ error |= ipsec_tunnel_cleanup_devices();
29462+
29463+ KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
29464+
29465+/* we never actually link IPCOMP to the stack */
29466+#ifdef IPCOMP_USED_ALONE
29467+#ifdef CONFIG_KLIPS_IPCOMP
29468+ if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
29469+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29470+ "comp close: can't remove protocol\n");
29471+#endif /* CONFIG_KLIPS_IPCOMP */
29472+#endif /* IPCOMP_USED_ALONE */
29473+
29474+#ifdef CONFIG_KLIPS_AH
29475+ if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
29476+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29477+ "ah close: can't remove protocol\n");
29478+#endif /* CONFIG_KLIPS_AH */
29479+
29480+#ifdef CONFIG_KLIPS_ESP
29481+ if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0)
29482+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29483+ "esp close: can't remove protocol\n");
29484+#endif /* CONFIG_KLIPS_ESP */
29485+
29486+ error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
29487+
29488+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29489+ "klips_debug:ipsec_cleanup: "
29490+ "calling ipsec_sadb_cleanup.\n");
29491+ error |= ipsec_sadb_cleanup(0);
29492+ error |= ipsec_sadb_free();
29493+
29494+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29495+ "klips_debug:ipsec_cleanup: "
29496+ "calling ipsec_radijcleanup.\n");
29497+ error |= ipsec_radijcleanup();
29498+
29499+ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
29500+ "klips_debug:ipsec_cleanup: "
29501+ "calling pfkey_cleanup.\n");
29502+ error |= pfkey_cleanup();
29503+
29504+ ipsec_proc_cleanup();
29505+
29506+ prng_final(&ipsec_prng);
29507+
29508+ return error;
29509+}
29510+
29511+#ifdef MODULE
29512+int
29513+init_module(void)
29514+{
29515+ int error = 0;
29516+
29517+ error |= ipsec_klips_init();
29518+
29519+ return error;
29520+}
29521+
29522+void
29523+cleanup_module(void)
29524+{
29525+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29526+ "klips_debug:cleanup_module: "
29527+ "calling ipsec_cleanup.\n");
29528+
29529+ ipsec_cleanup();
29530+
29531+ KLIPS_PRINT(1, "klips_info:cleanup_module: "
29532+ "ipsec module unloaded.\n");
29533+}
29534+#endif /* MODULE */
29535+
29536+/*
29537+ * $Log: ipsec_init.c,v $
29538+ * Revision 1.104.2.4 2006/10/06 21:39:26 paul
29539+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
29540+ * set. This is defined through autoconf.h which is included through the
29541+ * linux kernel build macros.
29542+ *
29543+ * Revision 1.104.2.3 2006/07/31 15:25:20 paul
29544+ * Check for NETKEY backport in Debian using IPSKB_XFRM_TUNNEL_SIZE to
29545+ * determine wether inet_add_protocol needs the protocol argument.
29546+ *
29547+ * Revision 1.104.2.2 2006/04/20 16:33:06 mcr
29548+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
29549+ * Fix in-kernel module compilation. Sub-makefiles do not work.
29550+ *
29551+ * Revision 1.104.2.1 2005/08/12 01:18:20 ken
29552+ * Warn people who don't have NAT-T patch applied, but try and compile NAT-T code
29553+ *
29554+ * Revision 1.105 2005/08/12 00:56:33 mcr
29555+ * add warning for people who didn't apply nat-t patch.
29556+ *
29557+ * Revision 1.104 2005/07/08 15:51:41 mcr
29558+ * removed duplicate NAT-T code.
29559+ * if CONFIG_IPSEC_NAT_TRAVERSAL isn't defined, then there is no issue.
29560+ *
29561+ * Revision 1.103 2005/07/08 03:02:05 paul
29562+ * Fixed garbled define that accidentally got commited to the real tree.
29563+ *
29564+ * Revision 1.102 2005/07/08 02:56:37 paul
29565+ * gcc4 fixes that were not commited because vault was down
29566+ *
29567+ * Revision 1.101 2005/04/29 05:10:22 mcr
29568+ * removed from extraenous includes to make unit testing easier.
29569+ *
29570+ * Revision 1.100 2005/04/10 22:56:09 mcr
29571+ * change to udp.c registration API.
29572+ *
29573+ * Revision 1.99 2005/04/08 18:26:13 mcr
29574+ * register with udp.c, the klips26 encap receive function
29575+ *
29576+ * Revision 1.98 2004/09/13 02:23:18 mcr
29577+ * #define inet_protocol if necessary.
29578+ *
29579+ * Revision 1.97 2004/09/06 18:35:49 mcr
29580+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
29581+ * so adjust for that.
29582+ *
29583+ * Revision 1.96 2004/08/17 03:27:23 mcr
29584+ * klips 2.6 edits.
29585+ *
29586+ * Revision 1.95 2004/08/03 18:19:08 mcr
29587+ * in 2.6, use "net_device" instead of #define device->net_device.
29588+ * this probably breaks 2.0 compiles.
29589+ *
29590+ * Revision 1.94 2004/07/10 19:11:18 mcr
29591+ * CONFIG_IPSEC -> CONFIG_KLIPS.
29592+ *
29593+ * Revision 1.93 2004/04/06 02:49:26 mcr
29594+ * pullup of algo code from alg-branch.
29595+ *
29596+ * Revision 1.92 2004/03/30 15:30:39 ken
29597+ * Proper Capitalization
29598+ *
29599+ * Revision 1.91 2004/03/22 01:51:51 ken
29600+ * We are open
29601+ *
29602+ * Revision 1.90.4.2 2004/04/05 04:30:46 mcr
29603+ * patches for alg-branch to compile/work with 2.x openswan
29604+ *
29605+ * Revision 1.90.4.1 2003/12/22 15:25:52 jjo
29606+ * Merged algo-0.8.1-rc11-test1 into alg-branch
29607+ *
29608+ * Revision 1.90 2003/10/31 02:27:55 mcr
29609+ * pulled up port-selector patches and sa_id elimination.
29610+ *
29611+ * Revision 1.89.4.1 2003/10/29 01:30:41 mcr
29612+ * elimited "struct sa_id".
29613+ *
29614+ * Revision 1.89 2003/07/31 22:47:16 mcr
29615+ * preliminary (untested by FS-team) 2.5 patches.
29616+ *
29617+ * Revision 1.88 2003/06/22 20:05:36 mcr
29618+ * clarified why IPCOMP was not being registered, and put a new
29619+ * #ifdef in rather than #if 0.
29620+ *
29621+ * Revision 1.87 2002/09/20 15:40:51 rgb
29622+ * Added a lock to the global ipsec_sadb struct for future use.
29623+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
29624+ * of freeing newly created structures when clearing the reftable upon startup
29625+ * to start from a known state.
29626+ *
29627+ * Revision 1.86 2002/08/15 18:39:15 rgb
29628+ * Move ipsec_prng outside debug code.
29629+ *
29630+ * Revision 1.85 2002/05/14 02:35:29 rgb
29631+ * Change reference to tdb to ipsa.
29632+ *
29633+ * Revision 1.84 2002/04/24 07:55:32 mcr
29634+ * #include patches and Makefiles for post-reorg compilation.
29635+ *
29636+ * Revision 1.83 2002/04/24 07:36:28 mcr
29637+ * Moved from ./klips/net/ipsec/ipsec_init.c,v
29638+ *
29639+ * Revision 1.82 2002/04/20 00:12:25 rgb
29640+ * Added esp IV CBC attack fix, disabled.
29641+ *
29642+ * Revision 1.81 2002/04/09 16:13:32 mcr
29643+ * switch license to straight GPL.
29644+ *
29645+ * Revision 1.80 2002/03/24 07:34:08 rgb
29646+ * Sanity check for at least one of AH or ESP configured.
29647+ *
29648+ * Revision 1.79 2002/02/05 22:55:15 mcr
29649+ * added MODULE_LICENSE declaration.
29650+ * This macro does not appear in all kernel versions (see comment).
29651+ *
29652+ * Revision 1.78 2002/01/29 17:17:55 mcr
29653+ * moved include of ipsec_param.h to after include of linux/kernel.h
29654+ * otherwise, it seems that some option that is set in ipsec_param.h
29655+ * screws up something subtle in the include path to kernel.h, and
29656+ * it complains on the snprintf() prototype.
29657+ *
29658+ * Revision 1.77 2002/01/29 04:00:51 mcr
29659+ * more excise of kversions.h header.
29660+ *
29661+ * Revision 1.76 2002/01/29 02:13:17 mcr
29662+ * introduction of ipsec_kversion.h means that include of
29663+ * ipsec_param.h must preceed any decisions about what files to
29664+ * include to deal with differences in kernel source.
29665+ *
29666+ * Revision 1.75 2001/11/26 09:23:48 rgb
29667+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
29668+ *
29669+ * Revision 1.74 2001/11/22 05:44:11 henry
29670+ * new version stuff
29671+ *
29672+ * Revision 1.71.2.2 2001/10/22 20:51:00 mcr
29673+ * explicitely set des_check_key.
29674+ *
29675+ * Revision 1.71.2.1 2001/09/25 02:19:39 mcr
29676+ * /proc manipulation code moved to new ipsec_proc.c
29677+ *
29678+ * Revision 1.73 2001/11/06 19:47:17 rgb
29679+ * Changed lifetime_packets to uint32 from uint64.
29680+ *
29681+ * Revision 1.72 2001/10/18 04:45:19 rgb
29682+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
29683+ * lib/freeswan.h version macros moved to lib/kversions.h.
29684+ * Other compiler directive cleanups.
29685+ *
29686+ * Revision 1.71 2001/09/20 15:32:45 rgb
29687+ * Minor pfkey lifetime fixes.
29688+ *
29689+ * Revision 1.70 2001/07/06 19:51:21 rgb
29690+ * Added inbound policy checking code for IPIP SAs.
29691+ *
29692+ * Revision 1.69 2001/06/14 19:33:26 rgb
29693+ * Silence startup message for console, but allow it to be logged.
29694+ * Update copyright date.
29695+ *
29696+ * Revision 1.68 2001/05/29 05:14:36 rgb
29697+ * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'.
29698+ *
29699+ * Revision 1.67 2001/05/04 16:34:52 rgb
29700+ * Rremove erroneous checking of return codes for proc_net_* in 2.4.
29701+ *
29702+ * Revision 1.66 2001/05/03 19:40:34 rgb
29703+ * Check error return codes in startup and shutdown.
29704+ *
29705+ * Revision 1.65 2001/02/28 05:03:27 rgb
29706+ * Clean up and rationalise startup messages.
29707+ *
29708+ * Revision 1.64 2001/02/27 22:24:53 rgb
29709+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
29710+ * Check for satoa() return codes.
29711+ *
29712+ * Revision 1.63 2000/11/29 20:14:06 rgb
29713+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
29714+ *
29715+ * Revision 1.62 2000/11/06 04:31:24 rgb
29716+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
29717+ * Fixed longlong for pre-2.4 kernels (Svenning).
29718+ * Add Svenning's adaptive content compression.
29719+ * Disabled registration of ipcomp handler.
29720+ *
29721+ * Revision 1.61 2000/10/11 13:37:54 rgb
29722+ * #ifdef out debug print that causes proc/net/ipsec_version to oops.
29723+ *
29724+ * Revision 1.60 2000/09/20 03:59:01 rgb
29725+ * Change static info functions to DEBUG_NO_STATIC to reveal function names
29726+ * in oopsen.
29727+ *
29728+ * Revision 1.59 2000/09/16 01:06:26 rgb
29729+ * Added cast of var to silence compiler warning about long fed to int
29730+ * format.
29731+ *
29732+ * Revision 1.58 2000/09/15 11:37:01 rgb
29733+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
29734+ * IPCOMP zlib deflate code.
29735+ *
29736+ * Revision 1.57 2000/09/12 03:21:50 rgb
29737+ * Moved radij_c_version printing to ipsec_version_get_info().
29738+ * Reformatted ipsec_version_get_info().
29739+ * Added sysctl_{,un}register() calls.
29740+ *
29741+ * Revision 1.56 2000/09/08 19:16:50 rgb
29742+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
29743+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
29744+ *
29745+ * Revision 1.55 2000/08/30 05:19:03 rgb
29746+ * Cleaned up no longer used spi_next, netlink register/unregister, other
29747+ * minor cleanup.
29748+ * Removed cruft replaced by TDB_XFORM_NAME.
29749+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
29750+ * Moved debug version strings to printk when /proc/net/ipsec_version is
29751+ * called.
29752+ *
29753+ * Revision 1.54 2000/08/20 18:31:05 rgb
29754+ * Changed cosmetic alignment in spi_info.
29755+ * Changed addtime and usetime to use actual value which is relative
29756+ * anyways, as intended. (Momchil)
29757+ *
29758+ * Revision 1.53 2000/08/18 17:37:03 rgb
29759+ * Added an (int) cast to shut up the compiler...
29760+ *
29761+ * Revision 1.52 2000/08/01 14:51:50 rgb
29762+ * Removed _all_ remaining traces of DES.
29763+ *
29764+ * Revision 1.51 2000/07/25 20:41:22 rgb
29765+ * Removed duplicate parameter in spi_getinfo.
29766+ *
29767+ * Revision 1.50 2000/07/17 03:21:45 rgb
29768+ * Removed /proc/net/ipsec_spinew.
29769+ *
29770+ * Revision 1.49 2000/06/28 05:46:51 rgb
29771+ * Renamed ivlen to iv_bits for consistency.
29772+ * Changed output of add and use times to be relative to now.
29773+ *
29774+ * Revision 1.48 2000/05/11 18:26:10 rgb
29775+ * Commented out calls to netlink_attach/detach to avoid activating netlink
29776+ * in the kenrel config.
29777+ *
29778+ * Revision 1.47 2000/05/10 22:35:26 rgb
29779+ * Comment out most of the startup version information.
29780+ *
29781+ * Revision 1.46 2000/03/22 16:15:36 rgb
29782+ * Fixed renaming of dev_get (MB).
29783+ *
29784+ * Revision 1.45 2000/03/16 06:40:48 rgb
29785+ * Hardcode PF_KEYv2 support.
29786+ *
29787+ * Revision 1.44 2000/01/22 23:19:20 rgb
29788+ * Simplified code to use existing macro TDB_XFORM_NAME().
29789+ *
29790+ * Revision 1.43 2000/01/21 06:14:04 rgb
29791+ * Print individual stats only if non-zero.
29792+ * Removed 'bits' from each keylength for brevity.
29793+ * Shortened lifetimes legend for brevity.
29794+ * Changed wording from 'last_used' to the clearer 'idle'.
29795+ *
29796+ * Revision 1.42 1999/12/31 14:57:19 rgb
29797+ * MB fix for new dummy-less proc_get_info in 2.3.35.
29798+ *
29799+ *
29800+ * Local variables:
29801+ * c-file-style: "linux"
29802+ * End:
29803+ *
29804+ */
29805--- /dev/null Tue Mar 11 13:02:56 2003
29806+++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004
29807@@ -0,0 +1,256 @@
29808+/*
29809+ * processing code for IPCOMP
29810+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
29811+ *
29812+ * This program is free software; you can redistribute it and/or modify it
29813+ * under the terms of the GNU General Public License as published by the
29814+ * Free Software Foundation; either version 2 of the License, or (at your
29815+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29816+ *
29817+ * This program is distributed in the hope that it will be useful, but
29818+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29819+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29820+ * for more details.
29821+ */
29822+
29823+char ipsec_ipcomp_c_version[] = "RCSID $Id: ipsec_ipcomp.c,v 1.5.2.2 2006/10/06 21:39:26 paul Exp $";
29824+#ifndef AUTOCONF_INCLUDED
29825+#include <linux/config.h>
29826+#endif
29827+#include <linux/version.h>
29828+
29829+#define __NO_VERSION__
29830+#include <linux/module.h>
29831+#include <linux/kernel.h> /* printk() */
29832+
29833+#include "openswan/ipsec_param.h"
29834+
29835+#ifdef MALLOC_SLAB
29836+# include <linux/slab.h> /* kmalloc() */
29837+#else /* MALLOC_SLAB */
29838+# include <linux/malloc.h> /* kmalloc() */
29839+#endif /* MALLOC_SLAB */
29840+#include <linux/errno.h> /* error codes */
29841+#include <linux/types.h> /* size_t */
29842+#include <linux/interrupt.h> /* mark_bh */
29843+
29844+#include <linux/netdevice.h> /* struct device, and other headers */
29845+#include <linux/etherdevice.h> /* eth_type_trans */
29846+#include <linux/ip.h> /* struct iphdr */
29847+#include <linux/skbuff.h>
29848+#include <openswan.h>
29849+#ifdef SPINLOCK
29850+# ifdef SPINLOCK_23
29851+# include <linux/spinlock.h> /* *lock* */
29852+# else /* SPINLOCK_23 */
29853+# include <asm/spinlock.h> /* *lock* */
29854+# endif /* SPINLOCK_23 */
29855+#endif /* SPINLOCK */
29856+
29857+#include <net/ip.h>
29858+
29859+#include "openswan/radij.h"
29860+#include "openswan/ipsec_encap.h"
29861+#include "openswan/ipsec_sa.h"
29862+
29863+#include "openswan/ipsec_radij.h"
29864+#include "openswan/ipsec_xform.h"
29865+#include "openswan/ipsec_tunnel.h"
29866+#include "openswan/ipsec_rcv.h"
29867+#include "openswan/ipsec_xmit.h"
29868+
29869+#include "openswan/ipsec_auth.h"
29870+
29871+#ifdef CONFIG_KLIPS_IPCOMP
29872+#include "openswan/ipsec_ipcomp.h"
29873+#endif /* CONFIG_KLIPS_IPCOMP */
29874+
29875+#include "openswan/ipsec_proto.h"
29876+
29877+#ifdef CONFIG_KLIPS_DEBUG
29878+int debug_ipcomp = 0;
29879+#endif /* CONFIG_KLIPS_DEBUG */
29880+
29881+
29882+#ifdef CONFIG_KLIPS_IPCOMP
29883+enum ipsec_rcv_value
29884+ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
29885+ struct sk_buff *skb)
29886+{
29887+ int ipcompminlen;
29888+
29889+ ipcompminlen = sizeof(struct iphdr);
29890+
29891+ if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
29892+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
29893+ "klips_debug:ipsec_rcv: "
29894+ "runt comp packet of skb->len=%d received from %s, dropped.\n",
29895+ skb->len,
29896+ irs->ipsaddr_txt);
29897+ if(irs->stats) {
29898+ irs->stats->rx_errors++;
29899+ }
29900+ return IPSEC_RCV_BADLEN;
29901+ }
29902+
29903+ irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)skb->h.raw;
29904+ irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
29905+ return IPSEC_RCV_OK;
29906+}
29907+
29908+enum ipsec_rcv_value
29909+ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
29910+{
29911+ unsigned int flags = 0;
29912+ struct ipsec_sa *ipsp = irs->ipsp;
29913+ struct sk_buff *skb;
29914+
29915+ skb=irs->skb;
29916+
29917+ ipsec_xmit_dmp("ipcomp", skb->h.raw, skb->len);
29918+
29919+ if(ipsp == NULL) {
29920+ return IPSEC_RCV_SAIDNOTFOUND;
29921+ }
29922+
29923+ if(sysctl_ipsec_inbound_policy_check &&
29924+ ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
29925+ (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */
29926+ ))) {
29927+ char sa2[SATOT_BUF];
29928+ size_t sa_len2 = 0;
29929+
29930+ sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2));
29931+
29932+ KLIPS_PRINT(debug_rcv,
29933+ "klips_debug:ipsec_rcv: "
29934+ "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",
29935+ irs->sa_len ? irs->sa : " (error)",
29936+ ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
29937+ ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
29938+ (__u32)ntohl(irs->said.spi),
29939+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29940+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
29941+ if(irs->stats) {
29942+ irs->stats->rx_dropped++;
29943+ }
29944+ return IPSEC_RCV_SAIDNOTFOUND;
29945+ }
29946+
29947+ ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
29948+ irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
29949+
29950+ skb = skb_decompress(skb, ipsp, &flags);
29951+ if (!skb || flags) {
29952+ spin_unlock(&tdb_lock);
29953+ KLIPS_PRINT(debug_rcv,
29954+ "klips_debug:ipsec_rcv: "
29955+ "skb_decompress() returned error flags=%x, dropped.\n",
29956+ flags);
29957+ if (irs->stats) {
29958+ if (flags)
29959+ irs->stats->rx_errors++;
29960+ else
29961+ irs->stats->rx_dropped++;
29962+ }
29963+ return IPSEC_RCV_IPCOMPFAILED;
29964+ }
29965+
29966+ /* make sure we update the pointer */
29967+ irs->skb = skb;
29968+
29969+#ifdef NET_21
29970+ irs->ipp = skb->nh.iph;
29971+#else /* NET_21 */
29972+ irs->ipp = skb->ip_hdr;
29973+#endif /* NET_21 */
29974+
29975+ ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
29976+
29977+ KLIPS_PRINT(debug_rcv,
29978+ "klips_debug:ipsec_rcv: "
29979+ "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
29980+ irs->sa_len ? irs->sa : " (error)",
29981+ (__u32)ntohl(irs->said.spi),
29982+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29983+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
29984+ irs->next_header);
29985+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
29986+
29987+ return IPSEC_RCV_OK;
29988+}
29989+
29990+enum ipsec_xmit_value
29991+ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
29992+{
29993+ unsigned int flags = 0;
29994+#ifdef CONFIG_KLIPS_DEBUG
29995+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
29996+#endif /* CONFIG_KLIPS_DEBUG */
29997+
29998+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
29999+
30000+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
30001+
30002+#ifdef NET_21
30003+ ixs->iph = ixs->skb->nh.iph;
30004+#else /* NET_21 */
30005+ ixs->iph = ixs->skb->ip_hdr;
30006+#endif /* NET_21 */
30007+
30008+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
30009+
30010+#ifdef CONFIG_KLIPS_DEBUG
30011+ if (debug_tunnel & DB_TN_CROUT)
30012+ {
30013+ if (old_tot_len > ntohs(ixs->iph->tot_len))
30014+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
30015+ "klips_debug:ipsec_xmit_encap_once: "
30016+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
30017+ old_tot_len, ntohs(ixs->iph->tot_len),
30018+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
30019+ ntohl(ixs->ipsp->ips_said.spi),
30020+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
30021+ else
30022+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
30023+ "klips_debug:ipsec_xmit_encap_once: "
30024+ "packet did not compress (flags = %d).\n",
30025+ flags);
30026+ }
30027+#endif /* CONFIG_KLIPS_DEBUG */
30028+
30029+ return IPSEC_XMIT_OK;
30030+}
30031+
30032+struct xform_functions ipcomp_xform_funcs[]={
30033+ {rcv_checks: ipsec_rcv_ipcomp_checks,
30034+ rcv_decrypt: ipsec_rcv_ipcomp_decomp,
30035+ xmit_setup: ipsec_xmit_ipcomp_setup,
30036+ xmit_headroom: 0,
30037+ xmit_needtailroom: 0,
30038+ },
30039+};
30040+
30041+#if 0
30042+/* We probably don't want to install a pure IPCOMP protocol handler, but
30043+ only want to handle IPCOMP if it is encapsulated inside an ESP payload
30044+ (which is already handled) */
30045+#ifdef CONFIG_KLIPS_IPCOMP
30046+struct inet_protocol comp_protocol =
30047+{
30048+ ipsec_rcv, /* COMP handler */
30049+ NULL, /* COMP error control */
30050+#ifdef NETDEV_25
30051+ 1, /* no policy */
30052+#else
30053+ 0, /* next */
30054+ IPPROTO_COMP, /* protocol ID */
30055+ 0, /* copy */
30056+ NULL, /* data */
30057+ "COMP" /* name */
30058+#endif
30059+};
30060+#endif /* CONFIG_KLIPS_IPCOMP */
30061+#endif
30062+
30063+#endif /* CONFIG_KLIPS_IPCOMP */
30064--- /dev/null Tue Mar 11 13:02:56 2003
30065+++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004
30066@@ -0,0 +1,122 @@
30067+/*
30068+ * processing code for IPIP
30069+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
30070+ *
30071+ * This program is free software; you can redistribute it and/or modify it
30072+ * under the terms of the GNU General Public License as published by the
30073+ * Free Software Foundation; either version 2 of the License, or (at your
30074+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30075+ *
30076+ * This program is distributed in the hope that it will be useful, but
30077+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30078+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30079+ * for more details.
30080+ */
30081+
30082+char ipsec_ipip_c_version[] = "RCSID $Id: ipsec_ipip.c,v 1.3.2.3 2006/10/06 21:39:26 paul Exp $";
30083+#ifndef AUTOCONF_INCLUDED
30084+#include <linux/config.h>
30085+#endif
30086+#include <linux/version.h>
30087+
30088+#define __NO_VERSION__
30089+#include <linux/module.h>
30090+#include <linux/kernel.h> /* printk() */
30091+
30092+#include "openswan/ipsec_param.h"
30093+
30094+#ifdef MALLOC_SLAB
30095+# include <linux/slab.h> /* kmalloc() */
30096+#else /* MALLOC_SLAB */
30097+# include <linux/malloc.h> /* kmalloc() */
30098+#endif /* MALLOC_SLAB */
30099+#include <linux/errno.h> /* error codes */
30100+#include <linux/types.h> /* size_t */
30101+#include <linux/interrupt.h> /* mark_bh */
30102+
30103+#include <linux/netdevice.h> /* struct device, and other headers */
30104+#include <linux/etherdevice.h> /* eth_type_trans */
30105+#include <linux/ip.h> /* struct iphdr */
30106+#include <linux/skbuff.h>
30107+#include <openswan.h>
30108+#ifdef SPINLOCK
30109+# ifdef SPINLOCK_23
30110+# include <linux/spinlock.h> /* *lock* */
30111+# else /* SPINLOCK_23 */
30112+# include <asm/spinlock.h> /* *lock* */
30113+# endif /* SPINLOCK_23 */
30114+#endif /* SPINLOCK */
30115+
30116+#include <net/ip.h>
30117+
30118+#include "openswan/radij.h"
30119+#include "openswan/ipsec_encap.h"
30120+#include "openswan/ipsec_sa.h"
30121+
30122+#include "openswan/ipsec_radij.h"
30123+#include "openswan/ipsec_xform.h"
30124+#include "openswan/ipsec_tunnel.h"
30125+#include "openswan/ipsec_rcv.h"
30126+#include "openswan/ipsec_xmit.h"
30127+
30128+#include "openswan/ipsec_auth.h"
30129+#include "openswan/ipsec_ipip.h"
30130+#include "openswan/ipsec_param.h"
30131+
30132+#include "openswan/ipsec_proto.h"
30133+
30134+enum ipsec_xmit_value
30135+ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
30136+{
30137+ ixs->iph->version = 4;
30138+
30139+ switch(sysctl_ipsec_tos) {
30140+ case 0:
30141+#ifdef NET_21
30142+ ixs->iph->tos = ixs->skb->nh.iph->tos;
30143+#else /* NET_21 */
30144+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
30145+#endif /* NET_21 */
30146+ break;
30147+ case 1:
30148+ ixs->iph->tos = 0;
30149+ break;
30150+ default:
30151+ break;
30152+ }
30153+ ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
30154+ ixs->iph->frag_off = 0;
30155+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
30156+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
30157+ ixs->iph->protocol = IPPROTO_IPIP;
30158+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
30159+
30160+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
30161+
30162+ ixs->newdst = (__u32)ixs->iph->daddr;
30163+ ixs->newsrc = (__u32)ixs->iph->saddr;
30164+
30165+#ifdef NET_21
30166+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
30167+#endif /* NET_21 */
30168+ return IPSEC_XMIT_OK;
30169+}
30170+
30171+struct xform_functions ipip_xform_funcs[]={
30172+ { rcv_checks: NULL,
30173+ rcv_setup_auth: NULL,
30174+ rcv_calc_auth: NULL,
30175+ rcv_decrypt: NULL,
30176+
30177+ xmit_setup: ipsec_xmit_ipip_setup,
30178+ xmit_headroom: sizeof(struct iphdr),
30179+ xmit_needtailroom: 0,
30180+ },
30181+};
30182+
30183+
30184+
30185+
30186+
30187+
30188+
30189--- /dev/null Tue Mar 11 13:02:56 2003
30190+++ linux/net/ipsec/ipsec_kern24.c Mon Feb 9 13:51:03 2004
30191@@ -0,0 +1,74 @@
30192+/*
30193+ * Copyright 2005 (C) Michael Richardson <mcr@xelerance.com>
30194+ *
30195+ * This is a file of functions which are present in 2.6 kernels,
30196+ * but are not available by default in the 2.4 series.
30197+ *
30198+ * As such this code is usually from the Linux kernel, and is covered by
30199+ * GPL.
30200+ *
30201+ * This program is free software; you can redistribute it and/or modify it
30202+ * under the terms of the GNU General Public License as published by the
30203+ * Free Software Foundation; either version 2 of the License, or (at your
30204+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30205+ *
30206+ * This program is distributed in the hope that it will be useful, but
30207+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30208+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30209+ * for more details.
30210+ *
30211+ * $Id: ipsec_kern24.c,v 1.2 2005/05/20 03:19:18 mcr Exp $
30212+ *
30213+ */
30214+
30215+#include <linux/kernel.h>
30216+#include <linux/mm.h>
30217+#include <linux/spinlock.h>
30218+
30219+/*
30220+ * printk rate limiting, lifted from the networking subsystem.
30221+ *
30222+ * This enforces a rate limit: not more than one kernel message
30223+ * every printk_ratelimit_jiffies to make a denial-of-service
30224+ * attack impossible.
30225+ */
30226+static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
30227+
30228+int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
30229+{
30230+ static unsigned long toks = 10*5*HZ;
30231+ static unsigned long last_msg;
30232+ static int missed;
30233+ unsigned long flags;
30234+ unsigned long now = jiffies;
30235+
30236+ spin_lock_irqsave(&ratelimit_lock, flags);
30237+ toks += now - last_msg;
30238+ last_msg = now;
30239+ if (toks > (ratelimit_burst * ratelimit_jiffies))
30240+ toks = ratelimit_burst * ratelimit_jiffies;
30241+ if (toks >= ratelimit_jiffies) {
30242+ int lost = missed;
30243+ missed = 0;
30244+ toks -= ratelimit_jiffies;
30245+ spin_unlock_irqrestore(&ratelimit_lock, flags);
30246+ if (lost)
30247+ printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
30248+ return 1;
30249+ }
30250+ missed++;
30251+ spin_unlock_irqrestore(&ratelimit_lock, flags);
30252+ return 0;
30253+}
30254+
30255+/* minimum time in jiffies between messages */
30256+int printk_ratelimit_jiffies = 5*HZ;
30257+
30258+/* number of messages we send before ratelimiting */
30259+int printk_ratelimit_burst = 10;
30260+
30261+int printk_ratelimit(void)
30262+{
30263+ return __printk_ratelimit(printk_ratelimit_jiffies,
30264+ printk_ratelimit_burst);
30265+}
30266--- /dev/null Tue Mar 11 13:02:56 2003
30267+++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004
30268@@ -0,0 +1,273 @@
30269+/*
30270+ * @(#) lifetime structure utilities
30271+ *
30272+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
30273+ * and Michael Richardson <mcr@freeswan.org>
30274+ *
30275+ * This program is free software; you can redistribute it and/or modify it
30276+ * under the terms of the GNU General Public License as published by the
30277+ * Free Software Foundation; either version 2 of the License, or (at your
30278+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30279+ *
30280+ * This program is distributed in the hope that it will be useful, but
30281+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30282+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30283+ * for more details.
30284+ *
30285+ * RCSID $Id: ipsec_life.c,v 1.13.10.1 2006/10/06 21:39:26 paul Exp $
30286+ *
30287+ */
30288+
30289+/*
30290+ * This provides series of utility functions for dealing with lifetime
30291+ * structures.
30292+ *
30293+ * ipsec_check_lifetime - returns -1 hard lifetime exceeded
30294+ * 0 soft lifetime exceeded
30295+ * 1 everything is okay
30296+ * based upon whether or not the count exceeds hard/soft
30297+ *
30298+ */
30299+
30300+#define __NO_VERSION__
30301+#include <linux/module.h>
30302+#ifndef AUTOCONF_INCLUDED
30303+#include <linux/config.h>
30304+#endif /* for CONFIG_IP_FORWARD */
30305+#include <linux/version.h>
30306+#include <linux/kernel.h> /* printk() */
30307+
30308+#include "openswan/ipsec_param.h"
30309+
30310+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
30311+#include <linux/etherdevice.h> /* eth_type_trans */
30312+#include <linux/skbuff.h>
30313+#include <openswan.h>
30314+
30315+#include "openswan/radij.h"
30316+#include "openswan/ipsec_life.h"
30317+#include "openswan/ipsec_xform.h"
30318+#include "openswan/ipsec_eroute.h"
30319+#include "openswan/ipsec_encap.h"
30320+#include "openswan/ipsec_radij.h"
30321+
30322+#include "openswan/ipsec_sa.h"
30323+#include "openswan/ipsec_tunnel.h"
30324+#include "openswan/ipsec_ipe4.h"
30325+#include "openswan/ipsec_ah.h"
30326+#include "openswan/ipsec_esp.h"
30327+
30328+#ifdef CONFIG_KLIPS_IPCOMP
30329+#include "openswan/ipcomp.h"
30330+#endif /* CONFIG_KLIPS_IPCOMP */
30331+
30332+#include <pfkeyv2.h>
30333+#include <pfkey.h>
30334+
30335+#include "openswan/ipsec_proto.h"
30336+
30337+
30338+enum ipsec_life_alive
30339+ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
30340+ const char *lifename,
30341+ const char *saname,
30342+ enum ipsec_life_type ilt,
30343+ enum ipsec_direction idir,
30344+ struct ipsec_sa *ips)
30345+{
30346+ __u64 count;
30347+ const char *dir;
30348+
30349+ if(saname == NULL) {
30350+ saname = "unknown-SA";
30351+ }
30352+
30353+ if(idir == ipsec_incoming) {
30354+ dir = "incoming";
30355+ } else {
30356+ dir = "outgoing";
30357+ }
30358+
30359+
30360+ if(ilt == ipsec_life_timebased) {
30361+ count = jiffies/HZ - il64->ipl_count;
30362+ } else {
30363+ count = il64->ipl_count;
30364+ }
30365+
30366+ if(il64->ipl_hard &&
30367+ (count > il64->ipl_hard)) {
30368+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
30369+ "klips_debug:ipsec_lifetime_check: "
30370+ "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
30371+ "%s packet dropped.\n",
30372+ lifename,
30373+ IPS_XFORM_NAME(ips),
30374+ saname,
30375+ dir);
30376+
30377+ pfkey_expire(ips, 1);
30378+ return ipsec_life_harddied;
30379+ }
30380+
30381+ if(il64->ipl_soft &&
30382+ (count > il64->ipl_soft)) {
30383+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
30384+ "klips_debug:ipsec_lifetime_check: "
30385+ "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
30386+ "soft expire message sent up, %s packet still processed.\n",
30387+ lifename,
30388+ IPS_XFORM_NAME(ips),
30389+ saname,
30390+ dir);
30391+
30392+ if(ips->ips_state != SADB_SASTATE_DYING) {
30393+ pfkey_expire(ips, 0);
30394+ }
30395+ ips->ips_state = SADB_SASTATE_DYING;
30396+
30397+ return ipsec_life_softdied;
30398+ }
30399+ return ipsec_life_okay;
30400+}
30401+
30402+
30403+/*
30404+ * This function takes a buffer (with length), a lifetime name and type,
30405+ * and formats a string to represent the current values of the lifetime.
30406+ *
30407+ * It returns the number of bytes that the format took (or would take,
30408+ * if the buffer were large enough: snprintf semantics).
30409+ * This is used in /proc routines and in debug output.
30410+ */
30411+int
30412+ipsec_lifetime_format(char *buffer,
30413+ int buflen,
30414+ char *lifename,
30415+ enum ipsec_life_type timebaselife,
30416+ struct ipsec_lifetime64 *lifetime)
30417+{
30418+ int len = 0;
30419+ __u64 count;
30420+
30421+ if(timebaselife == ipsec_life_timebased) {
30422+ count = jiffies/HZ - lifetime->ipl_count;
30423+ } else {
30424+ count = lifetime->ipl_count;
30425+ }
30426+
30427+ if(lifetime->ipl_count > 1 ||
30428+ lifetime->ipl_soft ||
30429+ lifetime->ipl_hard) {
30430+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
30431+ len = ipsec_snprintf(buffer, buflen,
30432+ "%s(%Lu,%Lu,%Lu)",
30433+ lifename,
30434+ count,
30435+ lifetime->ipl_soft,
30436+ lifetime->ipl_hard);
30437+#else /* XXX high 32 bits are not displayed */
30438+ len = ipsec_snprintf(buffer, buflen,
30439+ "%s(%lu,%lu,%lu)",
30440+ lifename,
30441+ (unsigned long)count,
30442+ (unsigned long)lifetime->ipl_soft,
30443+ (unsigned long)lifetime->ipl_hard);
30444+#endif
30445+ }
30446+
30447+ return len;
30448+}
30449+
30450+void
30451+ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
30452+ __u64 newvalue)
30453+{
30454+ if(newvalue &&
30455+ (!lifetime->ipl_hard ||
30456+ (newvalue < lifetime->ipl_hard))) {
30457+ lifetime->ipl_hard = newvalue;
30458+
30459+ if(!lifetime->ipl_soft &&
30460+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
30461+ lifetime->ipl_soft = lifetime->ipl_hard;
30462+ }
30463+ }
30464+}
30465+
30466+void
30467+ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
30468+ __u64 newvalue)
30469+{
30470+ if(newvalue &&
30471+ (!lifetime->ipl_soft ||
30472+ (newvalue < lifetime->ipl_soft))) {
30473+ lifetime->ipl_soft = newvalue;
30474+
30475+ if(lifetime->ipl_hard &&
30476+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
30477+ lifetime->ipl_soft = lifetime->ipl_hard;
30478+ }
30479+ }
30480+}
30481+
30482+
30483+/*
30484+ * $Log: ipsec_life.c,v $
30485+ * Revision 1.13.10.1 2006/10/06 21:39:26 paul
30486+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
30487+ * set. This is defined through autoconf.h which is included through the
30488+ * linux kernel build macros.
30489+ *
30490+ * Revision 1.13 2004/07/10 19:11:18 mcr
30491+ * CONFIG_IPSEC -> CONFIG_KLIPS.
30492+ *
30493+ * Revision 1.12 2004/04/23 20:44:35 ken
30494+ * Update comments
30495+ *
30496+ * Revision 1.11 2004/04/06 02:49:26 mcr
30497+ * pullup of algo code from alg-branch.
30498+ *
30499+ * Revision 1.10 2004/03/30 11:03:10 paul
30500+ * two more occurances of snprintf, found by Sam from a users oops msg.
30501+ *
30502+ * Revision 1.9 2003/10/31 02:27:55 mcr
30503+ * pulled up port-selector patches and sa_id elimination.
30504+ *
30505+ * Revision 1.8.4.1 2003/10/29 01:30:41 mcr
30506+ * elimited "struct sa_id".
30507+ *
30508+ * Revision 1.8 2003/02/06 02:00:10 rgb
30509+ * Fixed incorrect debugging text label
30510+ *
30511+ * Revision 1.7 2002/05/23 07:16:26 rgb
30512+ * Fixed absolute/relative reference to lifetime count printout.
30513+ *
30514+ * Revision 1.6 2002/04/24 07:55:32 mcr
30515+ * #include patches and Makefiles for post-reorg compilation.
30516+ *
30517+ * Revision 1.5 2002/04/24 07:36:28 mcr
30518+ * Moved from ./klips/net/ipsec/ipsec_life.c,v
30519+ *
30520+ * Revision 1.4 2002/01/29 17:17:55 mcr
30521+ * moved include of ipsec_param.h to after include of linux/kernel.h
30522+ * otherwise, it seems that some option that is set in ipsec_param.h
30523+ * screws up something subtle in the include path to kernel.h, and
30524+ * it complains on the snprintf() prototype.
30525+ *
30526+ * Revision 1.3 2002/01/29 02:13:17 mcr
30527+ * introduction of ipsec_kversion.h means that include of
30528+ * ipsec_param.h must preceed any decisions about what files to
30529+ * include to deal with differences in kernel source.
30530+ *
30531+ * Revision 1.2 2001/11/26 09:16:14 rgb
30532+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
30533+ *
30534+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
30535+ * lifetime structure created and common functions created.
30536+ *
30537+ * Local variables:
30538+ * c-file-style: "linux"
30539+ * End:
30540+ *
30541+ */
30542--- /dev/null Tue Mar 11 13:02:56 2003
30543+++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004
30544@@ -0,0 +1,1099 @@
30545+/*
30546+ * IPSEC MAST code.
30547+ * Copyright (C) 1996, 1997 John Ioannidis.
30548+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
30549+ *
30550+ * This program is free software; you can redistribute it and/or modify it
30551+ * under the terms of the GNU General Public License as published by the
30552+ * Free Software Foundation; either version 2 of the License, or (at your
30553+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30554+ *
30555+ * This program is distributed in the hope that it will be useful, but
30556+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30557+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30558+ * for more details.
30559+ */
30560+
30561+char ipsec_mast_c_version[] = "RCSID $Id: ipsec_mast.c,v 1.7.2.1 2006/10/06 21:39:26 paul Exp $";
30562+
30563+#define __NO_VERSION__
30564+#include <linux/module.h>
30565+#ifndef AUTOCONF_INCLUDED
30566+#include <linux/config.h>
30567+#endif /* for CONFIG_IP_FORWARD */
30568+#include <linux/version.h>
30569+#include <linux/kernel.h> /* printk() */
30570+
30571+#include "freeswan/ipsec_param.h"
30572+
30573+#ifdef MALLOC_SLAB
30574+# include <linux/slab.h> /* kmalloc() */
30575+#else /* MALLOC_SLAB */
30576+# include <linux/malloc.h> /* kmalloc() */
30577+#endif /* MALLOC_SLAB */
30578+#include <linux/errno.h> /* error codes */
30579+#include <linux/types.h> /* size_t */
30580+#include <linux/interrupt.h> /* mark_bh */
30581+
30582+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
30583+#include <linux/etherdevice.h> /* eth_type_trans */
30584+#include <linux/ip.h> /* struct iphdr */
30585+#include <linux/tcp.h> /* struct tcphdr */
30586+#include <linux/udp.h> /* struct udphdr */
30587+#include <linux/skbuff.h>
30588+#include <freeswan.h>
30589+#include <linux/in6.h>
30590+#include <net/dst.h>
30591+#undef dev_kfree_skb
30592+#define dev_kfree_skb(a,b) kfree_skb(a)
30593+#define PHYSDEV_TYPE
30594+#include <net/icmp.h> /* icmp_send() */
30595+#include <net/ip.h>
30596+#include <linux/netfilter_ipv4.h>
30597+
30598+#include <linux/if_arp.h>
30599+
30600+#include "freeswan/radij.h"
30601+#include "freeswan/ipsec_life.h"
30602+#include "freeswan/ipsec_xform.h"
30603+#include "freeswan/ipsec_eroute.h"
30604+#include "freeswan/ipsec_encap.h"
30605+#include "freeswan/ipsec_radij.h"
30606+#include "freeswan/ipsec_sa.h"
30607+#include "freeswan/ipsec_tunnel.h"
30608+#include "freeswan/ipsec_mast.h"
30609+#include "freeswan/ipsec_ipe4.h"
30610+#include "freeswan/ipsec_ah.h"
30611+#include "freeswan/ipsec_esp.h"
30612+
30613+#include <pfkeyv2.h>
30614+#include <pfkey.h>
30615+
30616+#include "freeswan/ipsec_proto.h"
30617+
30618+int ipsec_maxdevice_count = -1;
30619+
30620+DEBUG_NO_STATIC int
30621+ipsec_mast_open(struct net_device *dev)
30622+{
30623+ struct ipsecpriv *prv = dev->priv;
30624+
30625+ /*
30626+ * Can't open until attached.
30627+ */
30628+
30629+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30630+ "klips_debug:ipsec_mast_open: "
30631+ "dev = %s, prv->dev = %s\n",
30632+ dev->name, prv->dev?prv->dev->name:"NONE");
30633+
30634+ if (prv->dev == NULL)
30635+ return -ENODEV;
30636+
30637+ KLIPS_INC_USE;
30638+ return 0;
30639+}
30640+
30641+DEBUG_NO_STATIC int
30642+ipsec_mast_close(struct net_device *dev)
30643+{
30644+ KLIPS_DEC_USE;
30645+ return 0;
30646+}
30647+
30648+static inline int ipsec_mast_xmit2(struct sk_buff *skb)
30649+{
30650+ return ip_send(skb);
30651+}
30652+
30653+enum ipsec_xmit_value
30654+ipsec_mast_send(struct ipsec_xmit_state*ixs)
30655+{
30656+ /* new route/dst cache code from James Morris */
30657+ ixs->skb->dev = ixs->physdev;
30658+ /*skb_orphan(ixs->skb);*/
30659+ if((ixs->error = ip_route_output(&ixs->route,
30660+ ixs->skb->nh.iph->daddr,
30661+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
30662+ RT_TOS(ixs->skb->nh.iph->tos),
30663+ ixs->physdev->iflink /* rgb: should this be 0? */))) {
30664+ ixs->stats->tx_errors++;
30665+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30666+ "klips_debug:ipsec_xmit_send: "
30667+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
30668+ ixs->error,
30669+ ixs->route->u.dst.dev->name);
30670+ return IPSEC_XMIT_ROUTEERR;
30671+ }
30672+ if(ixs->dev == ixs->route->u.dst.dev) {
30673+ ip_rt_put(ixs->route);
30674+ /* This is recursion, drop it. */
30675+ ixs->stats->tx_errors++;
30676+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30677+ "klips_debug:ipsec_xmit_send: "
30678+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
30679+ ixs->dev->name);
30680+ return IPSEC_XMIT_RECURSDETECT;
30681+ }
30682+ dst_release(ixs->skb->dst);
30683+ ixs->skb->dst = &ixs->route->u.dst;
30684+ ixs->stats->tx_bytes += ixs->skb->len;
30685+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
30686+ ixs->stats->tx_errors++;
30687+ printk(KERN_WARNING
30688+ "klips_error:ipsec_xmit_send: "
30689+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
30690+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
30691+ ixs->skb->len);
30692+ return IPSEC_XMIT_PUSHPULLERR;
30693+ }
30694+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
30695+#ifdef SKB_RESET_NFCT
30696+ nf_conntrack_put(ixs->skb->nfct);
30697+ ixs->skb->nfct = NULL;
30698+#ifdef CONFIG_NETFILTER_DEBUG
30699+ ixs->skb->nf_debug = 0;
30700+#endif /* CONFIG_NETFILTER_DEBUG */
30701+#endif /* SKB_RESET_NFCT */
30702+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30703+ "klips_debug:ipsec_xmit_send: "
30704+ "...done, calling ip_send() on device:%s\n",
30705+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
30706+ KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
30707+ {
30708+ int err;
30709+
30710+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
30711+ ipsec_mast_xmit2);
30712+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
30713+ if(net_ratelimit())
30714+ printk(KERN_ERR
30715+ "klips_error:ipsec_xmit_send: "
30716+ "ip_send() failed, err=%d\n",
30717+ -err);
30718+ ixs->stats->tx_errors++;
30719+ ixs->stats->tx_aborted_errors++;
30720+ ixs->skb = NULL;
30721+ return IPSEC_XMIT_IPSENDFAILURE;
30722+ }
30723+ }
30724+ ixs->stats->tx_packets++;
30725+
30726+ ixs->skb = NULL;
30727+
30728+ return IPSEC_XMIT_OK;
30729+}
30730+
30731+void
30732+ipsec_mast_cleanup(struct ipsec_xmit_state*ixs)
30733+{
30734+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
30735+ netif_wake_queue(ixs->dev);
30736+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30737+ ixs->dev->tbusy = 0;
30738+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30739+ if(ixs->saved_header) {
30740+ kfree(ixs->saved_header);
30741+ }
30742+ if(ixs->skb) {
30743+ dev_kfree_skb(ixs->skb, FREE_WRITE);
30744+ }
30745+ if(ixs->oskb) {
30746+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
30747+ }
30748+ if (ixs->ips.ips_ident_s.data) {
30749+ kfree(ixs->ips.ips_ident_s.data);
30750+ }
30751+ if (ixs->ips.ips_ident_d.data) {
30752+ kfree(ixs->ips.ips_ident_d.data);
30753+ }
30754+}
30755+
30756+#if 0
30757+/*
30758+ * This function assumes it is being called from dev_queue_xmit()
30759+ * and that skb is filled properly by that function.
30760+ */
30761+int
30762+ipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev, IPsecSAref_t SAref)
30763+{
30764+ struct ipsec_xmit_state ixs_mem;
30765+ struct ipsec_xmit_state *ixs = &ixs_mem;
30766+ enum ipsec_xmit_value stat = IPSEC_XMIT_OK;
30767+
30768+ /* dev could be a mast device, but should be optional, I think... */
30769+ /* SAref is also optional, but one of the two must be present. */
30770+ /* I wonder if it could accept no device or saref and guess? */
30771+
30772+/* ipsec_xmit_sanity_check_dev(ixs); */
30773+
30774+ ipsec_xmit_sanity_check_skb(ixs);
30775+
30776+ ipsec_xmit_adjust_hard_header(ixs);
30777+
30778+ stat = ipsec_xmit_encap_bundle(ixs);
30779+ if(stat != IPSEC_XMIT_OK) {
30780+ /* SA processing failed */
30781+ }
30782+
30783+ ipsec_xmit_hard_header_restore();
30784+}
30785+#endif
30786+
30787+DEBUG_NO_STATIC struct net_device_stats *
30788+ipsec_mast_get_stats(struct net_device *dev)
30789+{
30790+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
30791+}
30792+
30793+/*
30794+ * Revectored calls.
30795+ * For each of these calls, a field exists in our private structure.
30796+ */
30797+
30798+DEBUG_NO_STATIC int
30799+ipsec_mast_hard_header(struct sk_buff *skb, struct net_device *dev,
30800+ unsigned short type, void *daddr, void *saddr, unsigned len)
30801+{
30802+ struct ipsecpriv *prv = dev->priv;
30803+ struct net_device *tmp;
30804+ int ret;
30805+ struct net_device_stats *stats; /* This device's statistics */
30806+
30807+ if(skb == NULL) {
30808+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30809+ "klips_debug:ipsec_mast_hard_header: "
30810+ "no skb...\n");
30811+ return -ENODATA;
30812+ }
30813+
30814+ if(dev == NULL) {
30815+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30816+ "klips_debug:ipsec_mast_hard_header: "
30817+ "no device...\n");
30818+ return -ENODEV;
30819+ }
30820+
30821+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30822+ "klips_debug:ipsec_mast_hard_header: "
30823+ "skb->dev=%s dev=%s.\n",
30824+ skb->dev ? skb->dev->name : "NULL",
30825+ dev->name);
30826+
30827+ if(prv == NULL) {
30828+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30829+ "klips_debug:ipsec_mast_hard_header: "
30830+ "no private space associated with dev=%s\n",
30831+ dev->name ? dev->name : "NULL");
30832+ return -ENODEV;
30833+ }
30834+
30835+ stats = (struct net_device_stats *) &(prv->mystats);
30836+
30837+ if(prv->dev == NULL) {
30838+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30839+ "klips_debug:ipsec_mast_hard_header: "
30840+ "no physical device associated with dev=%s\n",
30841+ dev->name ? dev->name : "NULL");
30842+ stats->tx_dropped++;
30843+ return -ENODEV;
30844+ }
30845+
30846+ /* check if we have to send a IPv6 packet. It might be a Router
30847+ Solicitation, where the building of the packet happens in
30848+ reverse order:
30849+ 1. ll hdr,
30850+ 2. IPv6 hdr,
30851+ 3. ICMPv6 hdr
30852+ -> skb->nh.raw is still uninitialized when this function is
30853+ called!! If this is no IPv6 packet, we can print debugging
30854+ messages, otherwise we skip all debugging messages and just
30855+ build the ll header */
30856+ if(type != ETH_P_IPV6) {
30857+ /* execute this only, if we don't have to build the
30858+ header for a IPv6 packet */
30859+ if(!prv->hard_header) {
30860+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30861+ "klips_debug:ipsec_mast_hard_header: "
30862+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
30863+ saddr,
30864+ daddr,
30865+ len,
30866+ type,
30867+ dev->name);
30868+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
30869+ "ip=%08x->%08x\n",
30870+ (__u32)ntohl(skb->nh.iph->saddr),
30871+ (__u32)ntohl(skb->nh.iph->daddr) );
30872+ stats->tx_dropped++;
30873+ return -ENODEV;
30874+ }
30875+
30876+#define da ((struct net_device *)(prv->dev))->dev_addr
30877+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30878+ "klips_debug:ipsec_mast_hard_header: "
30879+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
30880+ saddr,
30881+ daddr,
30882+ len,
30883+ type,
30884+ dev->name,
30885+ prv->dev->name,
30886+ da[0], da[1], da[2], da[3], da[4], da[5]);
30887+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
30888+ "ip=%08x->%08x\n",
30889+ (__u32)ntohl(skb->nh.iph->saddr),
30890+ (__u32)ntohl(skb->nh.iph->daddr) );
30891+ } else {
30892+ KLIPS_PRINT(debug_mast,
30893+ "klips_debug:ipsec_mast_hard_header: "
30894+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
30895+ }
30896+ tmp = skb->dev;
30897+ skb->dev = prv->dev;
30898+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
30899+ skb->dev = tmp;
30900+ return ret;
30901+}
30902+
30903+DEBUG_NO_STATIC int
30904+ipsec_mast_rebuild_header(struct sk_buff *skb)
30905+{
30906+ struct ipsecpriv *prv = skb->dev->priv;
30907+ struct net_device *tmp;
30908+ int ret;
30909+ struct net_device_stats *stats; /* This device's statistics */
30910+
30911+ if(skb->dev == NULL) {
30912+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30913+ "klips_debug:ipsec_mast_rebuild_header: "
30914+ "no device...");
30915+ return -ENODEV;
30916+ }
30917+
30918+ if(prv == NULL) {
30919+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30920+ "klips_debug:ipsec_mast_rebuild_header: "
30921+ "no private space associated with dev=%s",
30922+ skb->dev->name ? skb->dev->name : "NULL");
30923+ return -ENODEV;
30924+ }
30925+
30926+ stats = (struct net_device_stats *) &(prv->mystats);
30927+
30928+ if(prv->dev == NULL) {
30929+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30930+ "klips_debug:ipsec_mast_rebuild_header: "
30931+ "no physical device associated with dev=%s",
30932+ skb->dev->name ? skb->dev->name : "NULL");
30933+ stats->tx_dropped++;
30934+ return -ENODEV;
30935+ }
30936+
30937+ if(!prv->rebuild_header) {
30938+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30939+ "klips_debug:ipsec_mast_rebuild_header: "
30940+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
30941+ skb->dev->name);
30942+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30943+ "ip=%08x->%08x\n",
30944+ (__u32)ntohl(skb->nh.iph->saddr),
30945+ (__u32)ntohl(skb->nh.iph->daddr) );
30946+ stats->tx_dropped++;
30947+ return -ENODEV;
30948+ }
30949+
30950+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30951+ "klips_debug:ipsec_mast: "
30952+ "Revectored rebuild_header dev=%s->%s ",
30953+ skb->dev->name, prv->dev->name);
30954+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30955+ "ip=%08x->%08x\n",
30956+ (__u32)ntohl(skb->nh.iph->saddr),
30957+ (__u32)ntohl(skb->nh.iph->daddr) );
30958+ tmp = skb->dev;
30959+ skb->dev = prv->dev;
30960+
30961+ ret = prv->rebuild_header(skb);
30962+ skb->dev = tmp;
30963+ return ret;
30964+}
30965+
30966+DEBUG_NO_STATIC int
30967+ipsec_mast_set_mac_address(struct net_device *dev, void *addr)
30968+{
30969+ struct ipsecpriv *prv = dev->priv;
30970+
30971+ struct net_device_stats *stats; /* This device's statistics */
30972+
30973+ if(dev == NULL) {
30974+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30975+ "klips_debug:ipsec_mast_set_mac_address: "
30976+ "no device...");
30977+ return -ENODEV;
30978+ }
30979+
30980+ if(prv == NULL) {
30981+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30982+ "klips_debug:ipsec_mast_set_mac_address: "
30983+ "no private space associated with dev=%s",
30984+ dev->name ? dev->name : "NULL");
30985+ return -ENODEV;
30986+ }
30987+
30988+ stats = (struct net_device_stats *) &(prv->mystats);
30989+
30990+ if(prv->dev == NULL) {
30991+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30992+ "klips_debug:ipsec_mast_set_mac_address: "
30993+ "no physical device associated with dev=%s",
30994+ dev->name ? dev->name : "NULL");
30995+ stats->tx_dropped++;
30996+ return -ENODEV;
30997+ }
30998+
30999+ if(!prv->set_mac_address) {
31000+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31001+ "klips_debug:ipsec_mast_set_mac_address: "
31002+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
31003+ dev->name);
31004+ return -ENODEV;
31005+ }
31006+
31007+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31008+ "klips_debug:ipsec_mast_set_mac_address: "
31009+ "Revectored dev=%s->%s addr=0p%p\n",
31010+ dev->name, prv->dev->name, addr);
31011+ return prv->set_mac_address(prv->dev, addr);
31012+
31013+}
31014+
31015+DEBUG_NO_STATIC void
31016+ipsec_mast_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
31017+{
31018+ struct ipsecpriv *prv = dev->priv;
31019+
31020+ struct net_device_stats *stats; /* This device's statistics */
31021+
31022+ if(dev == NULL) {
31023+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31024+ "klips_debug:ipsec_mast_cache_update: "
31025+ "no device...");
31026+ return;
31027+ }
31028+
31029+ if(prv == NULL) {
31030+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31031+ "klips_debug:ipsec_mast_cache_update: "
31032+ "no private space associated with dev=%s",
31033+ dev->name ? dev->name : "NULL");
31034+ return;
31035+ }
31036+
31037+ stats = (struct net_device_stats *) &(prv->mystats);
31038+
31039+ if(prv->dev == NULL) {
31040+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31041+ "klips_debug:ipsec_mast_cache_update: "
31042+ "no physical device associated with dev=%s",
31043+ dev->name ? dev->name : "NULL");
31044+ stats->tx_dropped++;
31045+ return;
31046+ }
31047+
31048+ if(!prv->header_cache_update) {
31049+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31050+ "klips_debug:ipsec_mast_cache_update: "
31051+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
31052+ dev->name);
31053+ return;
31054+ }
31055+
31056+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31057+ "klips_debug:ipsec_mast: "
31058+ "Revectored cache_update\n");
31059+ prv->header_cache_update(hh, prv->dev, haddr);
31060+ return;
31061+}
31062+
31063+DEBUG_NO_STATIC int
31064+ipsec_mast_neigh_setup(struct neighbour *n)
31065+{
31066+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31067+ "klips_debug:ipsec_mast_neigh_setup:\n");
31068+
31069+ if (n->nud_state == NUD_NONE) {
31070+ n->ops = &arp_broken_ops;
31071+ n->output = n->ops->output;
31072+ }
31073+ return 0;
31074+}
31075+
31076+DEBUG_NO_STATIC int
31077+ipsec_mast_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
31078+{
31079+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31080+ "klips_debug:ipsec_mast_neigh_setup_dev: "
31081+ "setting up %s\n",
31082+ dev ? dev->name : "NULL");
31083+
31084+ if (p->tbl->family == AF_INET) {
31085+ p->neigh_setup = ipsec_mast_neigh_setup;
31086+ p->ucast_probes = 0;
31087+ p->mcast_probes = 0;
31088+ }
31089+ return 0;
31090+}
31091+
31092+/*
31093+ * We call the attach routine to attach another device.
31094+ */
31095+
31096+DEBUG_NO_STATIC int
31097+ipsec_mast_attach(struct net_device *dev, struct net_device *physdev)
31098+{
31099+ int i;
31100+ struct ipsecpriv *prv = dev->priv;
31101+
31102+ if(dev == NULL) {
31103+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31104+ "klips_debug:ipsec_mast_attach: "
31105+ "no device...");
31106+ return -ENODEV;
31107+ }
31108+
31109+ if(prv == NULL) {
31110+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31111+ "klips_debug:ipsec_mast_attach: "
31112+ "no private space associated with dev=%s",
31113+ dev->name ? dev->name : "NULL");
31114+ return -ENODATA;
31115+ }
31116+
31117+ prv->dev = physdev;
31118+ prv->hard_start_xmit = physdev->hard_start_xmit;
31119+ prv->get_stats = physdev->get_stats;
31120+
31121+ if (physdev->hard_header) {
31122+ prv->hard_header = physdev->hard_header;
31123+ dev->hard_header = ipsec_mast_hard_header;
31124+ } else
31125+ dev->hard_header = NULL;
31126+
31127+ if (physdev->rebuild_header) {
31128+ prv->rebuild_header = physdev->rebuild_header;
31129+ dev->rebuild_header = ipsec_mast_rebuild_header;
31130+ } else
31131+ dev->rebuild_header = NULL;
31132+
31133+ if (physdev->set_mac_address) {
31134+ prv->set_mac_address = physdev->set_mac_address;
31135+ dev->set_mac_address = ipsec_mast_set_mac_address;
31136+ } else
31137+ dev->set_mac_address = NULL;
31138+
31139+ if (physdev->header_cache_update) {
31140+ prv->header_cache_update = physdev->header_cache_update;
31141+ dev->header_cache_update = ipsec_mast_cache_update;
31142+ } else
31143+ dev->header_cache_update = NULL;
31144+
31145+ dev->hard_header_len = physdev->hard_header_len;
31146+
31147+/* prv->neigh_setup = physdev->neigh_setup; */
31148+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
31149+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
31150+ prv->mtu = physdev->mtu;
31151+
31152+#ifdef PHYSDEV_TYPE
31153+ dev->type = physdev->type; /* ARPHRD_MAST; */
31154+#endif /* PHYSDEV_TYPE */
31155+
31156+ dev->addr_len = physdev->addr_len;
31157+ for (i=0; i<dev->addr_len; i++) {
31158+ dev->dev_addr[i] = physdev->dev_addr[i];
31159+ }
31160+#ifdef CONFIG_KLIPS_DEBUG
31161+ if(debug_mast & DB_MAST_INIT) {
31162+ printk(KERN_INFO "klips_debug:ipsec_mast_attach: "
31163+ "physical device %s being attached has HW address: %2x",
31164+ physdev->name, physdev->dev_addr[0]);
31165+ for (i=1; i < physdev->addr_len; i++) {
31166+ printk(":%02x", physdev->dev_addr[i]);
31167+ }
31168+ printk("\n");
31169+ }
31170+#endif /* CONFIG_KLIPS_DEBUG */
31171+
31172+ return 0;
31173+}
31174+
31175+/*
31176+ * We call the detach routine to detach the ipsec mast from another device.
31177+ */
31178+
31179+DEBUG_NO_STATIC int
31180+ipsec_mast_detach(struct net_device *dev)
31181+{
31182+ int i;
31183+ struct ipsecpriv *prv = dev->priv;
31184+
31185+ if(dev == NULL) {
31186+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31187+ "klips_debug:ipsec_mast_detach: "
31188+ "no device...");
31189+ return -ENODEV;
31190+ }
31191+
31192+ if(prv == NULL) {
31193+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31194+ "klips_debug:ipsec_mast_detach: "
31195+ "no private space associated with dev=%s",
31196+ dev->name ? dev->name : "NULL");
31197+ return -ENODATA;
31198+ }
31199+
31200+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31201+ "klips_debug:ipsec_mast_detach: "
31202+ "physical device %s being detached from virtual device %s\n",
31203+ prv->dev ? prv->dev->name : "NULL",
31204+ dev->name);
31205+
31206+ prv->dev = NULL;
31207+ prv->hard_start_xmit = NULL;
31208+ prv->get_stats = NULL;
31209+
31210+ prv->hard_header = NULL;
31211+#ifdef DETACH_AND_DOWN
31212+ dev->hard_header = NULL;
31213+#endif /* DETACH_AND_DOWN */
31214+
31215+ prv->rebuild_header = NULL;
31216+#ifdef DETACH_AND_DOWN
31217+ dev->rebuild_header = NULL;
31218+#endif /* DETACH_AND_DOWN */
31219+
31220+ prv->set_mac_address = NULL;
31221+#ifdef DETACH_AND_DOWN
31222+ dev->set_mac_address = NULL;
31223+#endif /* DETACH_AND_DOWN */
31224+
31225+ prv->header_cache_update = NULL;
31226+#ifdef DETACH_AND_DOWN
31227+ dev->header_cache_update = NULL;
31228+#endif /* DETACH_AND_DOWN */
31229+
31230+#ifdef DETACH_AND_DOWN
31231+ dev->neigh_setup = NULL;
31232+#endif /* DETACH_AND_DOWN */
31233+
31234+ dev->hard_header_len = 0;
31235+#ifdef DETACH_AND_DOWN
31236+ dev->mtu = 0;
31237+#endif /* DETACH_AND_DOWN */
31238+ prv->mtu = 0;
31239+ for (i=0; i<MAX_ADDR_LEN; i++) {
31240+ dev->dev_addr[i] = 0;
31241+ }
31242+ dev->addr_len = 0;
31243+#ifdef PHYSDEV_TYPE
31244+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */
31245+#endif /* PHYSDEV_TYPE */
31246+
31247+ return 0;
31248+}
31249+
31250+/*
31251+ * We call the clear routine to detach all ipsec masts from other devices.
31252+ */
31253+DEBUG_NO_STATIC int
31254+ipsec_mast_clear(void)
31255+{
31256+ int i;
31257+ struct net_device *ipsecdev = NULL, *prvdev;
31258+ struct ipsecpriv *prv;
31259+ char name[9];
31260+ int ret;
31261+
31262+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31263+ "klips_debug:ipsec_mast_clear: .\n");
31264+
31265+ for(i = 0; i < IPSEC_NUM_IF; i++) {
31266+ sprintf(name, IPSEC_DEV_FORMAT, i);
31267+ if((ipsecdev = ipsec_dev_get(name)) != NULL) {
31268+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
31269+ prvdev = (struct net_device *)(prv->dev);
31270+ if(prvdev) {
31271+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31272+ "klips_debug:ipsec_mast_clear: "
31273+ "physical device for device %s is %s\n",
31274+ name, prvdev->name);
31275+ if((ret = ipsec_mast_detach(ipsecdev))) {
31276+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31277+ "klips_debug:ipsec_mast_clear: "
31278+ "error %d detatching device %s from device %s.\n",
31279+ ret, name, prvdev->name);
31280+ return ret;
31281+ }
31282+ }
31283+ }
31284+ }
31285+ }
31286+ return 0;
31287+}
31288+
31289+DEBUG_NO_STATIC int
31290+ipsec_mast_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
31291+{
31292+ struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
31293+ struct ipsecpriv *prv = dev->priv;
31294+ struct net_device *them; /* physical device */
31295+#ifdef CONFIG_IP_ALIAS
31296+ char *colon;
31297+ char realphysname[IFNAMSIZ];
31298+#endif /* CONFIG_IP_ALIAS */
31299+
31300+ if(dev == NULL) {
31301+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31302+ "klips_debug:ipsec_mast_ioctl: "
31303+ "device not supplied.\n");
31304+ return -ENODEV;
31305+ }
31306+
31307+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31308+ "klips_debug:ipsec_mast_ioctl: "
31309+ "tncfg service call #%d for dev=%s\n",
31310+ cmd,
31311+ dev->name ? dev->name : "NULL");
31312+ switch (cmd) {
31313+ /* attach a virtual ipsec? device to a physical device */
31314+ case IPSEC_SET_DEV:
31315+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31316+ "klips_debug:ipsec_mast_ioctl: "
31317+ "calling ipsec_mast_attatch...\n");
31318+#ifdef CONFIG_IP_ALIAS
31319+ /* If this is an IP alias interface, get its real physical name */
31320+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
31321+ realphysname[IFNAMSIZ-1] = 0;
31322+ colon = strchr(realphysname, ':');
31323+ if (colon) *colon = 0;
31324+ them = ipsec_dev_get(realphysname);
31325+#else /* CONFIG_IP_ALIAS */
31326+ them = ipsec_dev_get(cf->cf_name);
31327+#endif /* CONFIG_IP_ALIAS */
31328+
31329+ if (them == NULL) {
31330+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31331+ "klips_debug:ipsec_mast_ioctl: "
31332+ "physical device %s requested is null\n",
31333+ cf->cf_name);
31334+ return -ENXIO;
31335+ }
31336+
31337+#if 0
31338+ if (them->flags & IFF_UP) {
31339+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31340+ "klips_debug:ipsec_mast_ioctl: "
31341+ "physical device %s requested is not up.\n",
31342+ cf->cf_name);
31343+ return -ENXIO;
31344+ }
31345+#endif
31346+
31347+ if (prv && prv->dev) {
31348+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31349+ "klips_debug:ipsec_mast_ioctl: "
31350+ "virtual device is already connected to %s.\n",
31351+ prv->dev->name ? prv->dev->name : "NULL");
31352+ return -EBUSY;
31353+ }
31354+ return ipsec_mast_attach(dev, them);
31355+
31356+ case IPSEC_DEL_DEV:
31357+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31358+ "klips_debug:ipsec_mast_ioctl: "
31359+ "calling ipsec_mast_detatch.\n");
31360+ if (! prv->dev) {
31361+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31362+ "klips_debug:ipsec_mast_ioctl: "
31363+ "physical device not connected.\n");
31364+ return -ENODEV;
31365+ }
31366+ return ipsec_mast_detach(dev);
31367+
31368+ case IPSEC_CLR_DEV:
31369+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31370+ "klips_debug:ipsec_mast_ioctl: "
31371+ "calling ipsec_mast_clear.\n");
31372+ return ipsec_mast_clear();
31373+
31374+ default:
31375+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31376+ "klips_debug:ipsec_mast_ioctl: "
31377+ "unknown command %d.\n",
31378+ cmd);
31379+ return -EOPNOTSUPP;
31380+ }
31381+}
31382+
31383+int
31384+ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
31385+{
31386+ struct net_device *dev = ptr;
31387+ struct net_device *ipsec_dev;
31388+ struct ipsecpriv *priv;
31389+ char name[9];
31390+ int i;
31391+
31392+ if (dev == NULL) {
31393+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31394+ "klips_debug:ipsec_mast_device_event: "
31395+ "dev=NULL for event type %ld.\n",
31396+ event);
31397+ return(NOTIFY_DONE);
31398+ }
31399+
31400+ /* check for loopback devices */
31401+ if (dev && (dev->flags & IFF_LOOPBACK)) {
31402+ return(NOTIFY_DONE);
31403+ }
31404+
31405+ switch (event) {
31406+ case NETDEV_DOWN:
31407+ /* look very carefully at the scope of these compiler
31408+ directives before changing anything... -- RGB */
31409+
31410+ case NETDEV_UNREGISTER:
31411+ switch (event) {
31412+ case NETDEV_DOWN:
31413+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31414+ "klips_debug:ipsec_mast_device_event: "
31415+ "NETDEV_DOWN dev=%s flags=%x\n",
31416+ dev->name,
31417+ dev->flags);
31418+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
31419+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
31420+ dev->name);
31421+ }
31422+ break;
31423+ case NETDEV_UNREGISTER:
31424+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31425+ "klips_debug:ipsec_mast_device_event: "
31426+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
31427+ dev->name,
31428+ dev->flags);
31429+ break;
31430+ }
31431+
31432+ /* find the attached physical device and detach it. */
31433+ for(i = 0; i < IPSEC_NUM_IF; i++) {
31434+ sprintf(name, IPSEC_DEV_FORMAT, i);
31435+ ipsec_dev = ipsec_dev_get(name);
31436+ if(ipsec_dev) {
31437+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
31438+ if(priv) {
31439+ ;
31440+ if(((struct net_device *)(priv->dev)) == dev) {
31441+ /* dev_close(ipsec_dev); */
31442+ /* return */ ipsec_mast_detach(ipsec_dev);
31443+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31444+ "klips_debug:ipsec_mast_device_event: "
31445+ "device '%s' has been detached.\n",
31446+ ipsec_dev->name);
31447+ break;
31448+ }
31449+ } else {
31450+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31451+ "klips_debug:ipsec_mast_device_event: "
31452+ "device '%s' has no private data space!\n",
31453+ ipsec_dev->name);
31454+ }
31455+ }
31456+ }
31457+ break;
31458+ case NETDEV_UP:
31459+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31460+ "klips_debug:ipsec_mast_device_event: "
31461+ "NETDEV_UP dev=%s\n",
31462+ dev->name);
31463+ break;
31464+ case NETDEV_REBOOT:
31465+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31466+ "klips_debug:ipsec_mast_device_event: "
31467+ "NETDEV_REBOOT dev=%s\n",
31468+ dev->name);
31469+ break;
31470+ case NETDEV_CHANGE:
31471+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31472+ "klips_debug:ipsec_mast_device_event: "
31473+ "NETDEV_CHANGE dev=%s flags=%x\n",
31474+ dev->name,
31475+ dev->flags);
31476+ break;
31477+ case NETDEV_REGISTER:
31478+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31479+ "klips_debug:ipsec_mast_device_event: "
31480+ "NETDEV_REGISTER dev=%s\n",
31481+ dev->name);
31482+ break;
31483+ case NETDEV_CHANGEMTU:
31484+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31485+ "klips_debug:ipsec_mast_device_event: "
31486+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
31487+ dev->name,
31488+ dev->mtu);
31489+ break;
31490+ case NETDEV_CHANGEADDR:
31491+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31492+ "klips_debug:ipsec_mast_device_event: "
31493+ "NETDEV_CHANGEADDR dev=%s\n",
31494+ dev->name);
31495+ break;
31496+ case NETDEV_GOING_DOWN:
31497+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31498+ "klips_debug:ipsec_mast_device_event: "
31499+ "NETDEV_GOING_DOWN dev=%s\n",
31500+ dev->name);
31501+ break;
31502+ case NETDEV_CHANGENAME:
31503+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31504+ "klips_debug:ipsec_mast_device_event: "
31505+ "NETDEV_CHANGENAME dev=%s\n",
31506+ dev->name);
31507+ break;
31508+ default:
31509+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31510+ "klips_debug:ipsec_mast_device_event: "
31511+ "event type %ld unrecognised for dev=%s\n",
31512+ event,
31513+ dev->name);
31514+ break;
31515+ }
31516+ return NOTIFY_DONE;
31517+}
31518+
31519+/*
31520+ * Called when an ipsec mast device is initialized.
31521+ * The ipsec mast device structure is passed to us.
31522+ */
31523+
31524+int
31525+ipsec_mast_init(struct net_device *dev)
31526+{
31527+ int i;
31528+
31529+ KLIPS_PRINT(debug_mast,
31530+ "klips_debug:ipsec_mast_init: "
31531+ "allocating %lu bytes initialising device: %s\n",
31532+ (unsigned long) sizeof(struct ipsecpriv),
31533+ dev->name ? dev->name : "NULL");
31534+
31535+ /* Add our mast functions to the device */
31536+ dev->open = ipsec_mast_open;
31537+ dev->stop = ipsec_mast_close;
31538+ dev->hard_start_xmit = ipsec_mast_start_xmit;
31539+ dev->get_stats = ipsec_mast_get_stats;
31540+
31541+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
31542+ if (dev->priv == NULL)
31543+ return -ENOMEM;
31544+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
31545+
31546+ for(i = 0; i < sizeof(zeroes); i++) {
31547+ ((__u8*)(zeroes))[i] = 0;
31548+ }
31549+
31550+ dev->set_multicast_list = NULL;
31551+ dev->do_ioctl = ipsec_mast_ioctl;
31552+ dev->hard_header = NULL;
31553+ dev->rebuild_header = NULL;
31554+ dev->set_mac_address = NULL;
31555+ dev->header_cache_update= NULL;
31556+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
31557+ dev->hard_header_len = 0;
31558+ dev->mtu = 0;
31559+ dev->addr_len = 0;
31560+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */
31561+ dev->tx_queue_len = 10; /* Small queue */
31562+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
31563+
31564+ /* New-style flags. */
31565+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
31566+ dev_init_buffers(dev);
31567+
31568+ /* We're done. Have I forgotten anything? */
31569+ return 0;
31570+}
31571+
31572+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31573+/* Module specific interface (but it links with the rest of IPSEC) */
31574+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31575+
31576+int
31577+ipsec_mast_probe(struct net_device *dev)
31578+{
31579+ ipsec_mast_init(dev);
31580+ return 0;
31581+}
31582+
31583+int
31584+ipsec_mast_init_devices(void)
31585+{
31586+ return 0;
31587+}
31588+
31589+/* void */
31590+int
31591+ipsec_mast_cleanup_devices(void)
31592+{
31593+ int error = 0;
31594+ int i;
31595+ char name[10];
31596+ struct net_device *dev_mast;
31597+
31598+ for(i = 0; i < ipsec_mastdevice_count; i++) {
31599+ sprintf(name, MAST_DEV_FORMAT, i);
31600+ if((dev_mast = ipsec_dev_get(name)) == NULL) {
31601+ break;
31602+ }
31603+ unregister_netdev(dev_mast);
31604+ kfree(dev_mast->priv);
31605+ dev_mast->priv=NULL;
31606+ }
31607+ return error;
31608+}
31609+
31610+/*
31611+ * $Log: ipsec_mast.c,v $
31612+ * Revision 1.7.2.1 2006/10/06 21:39:26 paul
31613+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
31614+ * set. This is defined through autoconf.h which is included through the
31615+ * linux kernel build macros.
31616+ *
31617+ * Revision 1.7 2005/04/29 05:10:22 mcr
31618+ * removed from extraenous includes to make unit testing easier.
31619+ *
31620+ * Revision 1.6 2004/12/03 21:25:57 mcr
31621+ * compile time fixes for running on 2.6.
31622+ * still experimental.
31623+ *
31624+ * Revision 1.5 2004/08/03 18:19:08 mcr
31625+ * in 2.6, use "net_device" instead of #define device->net_device.
31626+ * this probably breaks 2.0 compiles.
31627+ *
31628+ * Revision 1.4 2004/07/10 19:11:18 mcr
31629+ * CONFIG_IPSEC -> CONFIG_KLIPS.
31630+ *
31631+ * Revision 1.3 2003/10/31 02:27:55 mcr
31632+ * pulled up port-selector patches and sa_id elimination.
31633+ *
31634+ * Revision 1.2.4.1 2003/10/29 01:30:41 mcr
31635+ * elimited "struct sa_id".
31636+ *
31637+ * Revision 1.2 2003/06/22 20:06:17 mcr
31638+ * refactored mast code still had lots of ipsecX junk in it.
31639+ *
31640+ * Revision 1.1 2003/02/12 19:31:12 rgb
31641+ * Refactored from ipsec_tunnel.c
31642+ *
31643+ */
31644--- /dev/null Tue Mar 11 13:02:56 2003
31645+++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004
31646@@ -0,0 +1,453 @@
31647+/*
31648+ * RCSID $Id: ipsec_md5c.c,v 1.10 2005/04/15 01:25:57 mcr Exp $
31649+ */
31650+
31651+/*
31652+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
31653+ * changes to accomodate it in the kernel by ji.
31654+ */
31655+
31656+#include <asm/byteorder.h>
31657+#include <linux/string.h>
31658+
31659+#include "openswan/ipsec_md5h.h"
31660+
31661+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
31662+ */
31663+
31664+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
31665+rights reserved.
31666+
31667+License to copy and use this software is granted provided that it
31668+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
31669+Algorithm" in all material mentioning or referencing this software
31670+or this function.
31671+
31672+License is also granted to make and use derivative works provided
31673+that such works are identified as "derived from the RSA Data
31674+Security, Inc. MD5 Message-Digest Algorithm" in all material
31675+mentioning or referencing the derived work.
31676+
31677+RSA Data Security, Inc. makes no representations concerning either
31678+the merchantability of this software or the suitability of this
31679+software for any particular purpose. It is provided "as is"
31680+without express or implied warranty of any kind.
31681+
31682+These notices must be retained in any copies of any part of this
31683+documentation and/or software.
31684+ */
31685+
31686+/*
31687+ * Additions by JI
31688+ *
31689+ * HAVEMEMCOPY is defined if mem* routines are available
31690+ *
31691+ * HAVEHTON is defined if htons() and htonl() can be used
31692+ * for big/little endian conversions
31693+ *
31694+ */
31695+
31696+#define HAVEMEMCOPY
31697+#ifdef __LITTLE_ENDIAN
31698+#define LITTLENDIAN
31699+#endif
31700+#ifdef __BIG_ENDIAN
31701+#define BIGENDIAN
31702+#endif
31703+
31704+/* Constants for MD5Transform routine.
31705+ */
31706+
31707+#define S11 7
31708+#define S12 12
31709+#define S13 17
31710+#define S14 22
31711+#define S21 5
31712+#define S22 9
31713+#define S23 14
31714+#define S24 20
31715+#define S31 4
31716+#define S32 11
31717+#define S33 16
31718+#define S34 23
31719+#define S41 6
31720+#define S42 10
31721+#define S43 15
31722+#define S44 21
31723+
31724+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
31725+
31726+#ifdef LITTLEENDIAN
31727+#define Encode MD5_memcpy
31728+#define Decode MD5_memcpy
31729+#else
31730+static void Encode PROTO_LIST
31731+ ((unsigned char *, UINT4 *, unsigned int));
31732+static void Decode PROTO_LIST
31733+ ((UINT4 *, unsigned char *, unsigned int));
31734+#endif
31735+
31736+#ifdef HAVEMEMCOPY
31737+/* no need to include <memory.h> here; <linux/string.h> defines these */
31738+#define MD5_memcpy memcpy
31739+#define MD5_memset memset
31740+#else
31741+#ifdef HAVEBCOPY
31742+#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
31743+#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
31744+#else
31745+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
31746+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
31747+#endif
31748+#endif
31749+static unsigned char PADDING[64] = {
31750+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31751+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31752+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
31753+};
31754+
31755+/* F, G, H and I are basic MD5 functions.
31756+ */
31757+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
31758+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
31759+#define H(x, y, z) ((x) ^ (y) ^ (z))
31760+#define I(x, y, z) ((y) ^ ((x) | (~z)))
31761+
31762+/* ROTATE_LEFT rotates x left n bits.
31763+ */
31764+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
31765+
31766+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
31767+Rotation is separate from addition to prevent recomputation.
31768+ */
31769+#define FF(a, b, c, d, x, s, ac) { \
31770+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
31771+ (a) = ROTATE_LEFT ((a), (s)); \
31772+ (a) += (b); \
31773+ }
31774+#define GG(a, b, c, d, x, s, ac) { \
31775+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
31776+ (a) = ROTATE_LEFT ((a), (s)); \
31777+ (a) += (b); \
31778+ }
31779+#define HH(a, b, c, d, x, s, ac) { \
31780+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
31781+ (a) = ROTATE_LEFT ((a), (s)); \
31782+ (a) += (b); \
31783+ }
31784+#define II(a, b, c, d, x, s, ac) { \
31785+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
31786+ (a) = ROTATE_LEFT ((a), (s)); \
31787+ (a) += (b); \
31788+ }
31789+
31790+/*
31791+ * MD5 initialization. Begins an MD5 operation, writing a new context.
31792+ */
31793+void osMD5Init(void *vcontext)
31794+{
31795+ MD5_CTX *context = vcontext;
31796+
31797+ context->count[0] = context->count[1] = 0;
31798+ /* Load magic initialization constants.*/
31799+ context->state[0] = 0x67452301;
31800+ context->state[1] = 0xefcdab89;
31801+ context->state[2] = 0x98badcfe;
31802+ context->state[3] = 0x10325476;
31803+}
31804+
31805+/* MD5 block update operation. Continues an MD5 message-digest
31806+ operation, processing another message block, and updating the
31807+ context.
31808+ */
31809+void osMD5Update (vcontext, input, inputLen)
31810+ void *vcontext;
31811+ unsigned char *input; /* input block */
31812+ __u32 inputLen; /* length of input block */
31813+{
31814+ MD5_CTX *context = vcontext;
31815+ __u32 i;
31816+ unsigned int index, partLen;
31817+
31818+ /* Compute number of bytes mod 64 */
31819+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
31820+
31821+ /* Update number of bits */
31822+ if ((context->count[0] += ((UINT4)inputLen << 3))
31823+ < ((UINT4)inputLen << 3))
31824+ context->count[1]++;
31825+ context->count[1] += ((UINT4)inputLen >> 29);
31826+
31827+ partLen = 64 - index;
31828+
31829+ /* Transform as many times as possible.
31830+*/
31831+ if (inputLen >= partLen) {
31832+ MD5_memcpy
31833+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
31834+ MD5Transform (context->state, context->buffer);
31835+
31836+ for (i = partLen; i + 63 < inputLen; i += 64)
31837+ MD5Transform (context->state, &input[i]);
31838+
31839+ index = 0;
31840+ }
31841+ else
31842+ i = 0;
31843+
31844+ /* Buffer remaining input */
31845+ MD5_memcpy
31846+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
31847+ inputLen-i);
31848+}
31849+
31850+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
31851+ the message digest and zeroizing the context.
31852+ */
31853+void osMD5Final (digest, vcontext)
31854+unsigned char digest[16]; /* message digest */
31855+void *vcontext; /* context */
31856+{
31857+ MD5_CTX *context = vcontext;
31858+ unsigned char bits[8];
31859+ unsigned int index, padLen;
31860+
31861+ /* Save number of bits */
31862+ Encode (bits, context->count, 8);
31863+
31864+ /* Pad out to 56 mod 64.
31865+*/
31866+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
31867+ padLen = (index < 56) ? (56 - index) : (120 - index);
31868+ osMD5Update (context, PADDING, padLen);
31869+
31870+ /* Append length (before padding) */
31871+ osMD5Update (context, bits, 8);
31872+
31873+ if (digest != NULL) /* Bill Simpson's padding */
31874+ {
31875+ /* store state in digest */
31876+ Encode (digest, context->state, 16);
31877+
31878+ /* Zeroize sensitive information.
31879+ */
31880+ MD5_memset ((POINTER)context, 0, sizeof (*context));
31881+ }
31882+}
31883+
31884+/* MD5 basic transformation. Transforms state based on block.
31885+ */
31886+static void MD5Transform (state, block)
31887+UINT4 state[4];
31888+unsigned char block[64];
31889+{
31890+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
31891+
31892+ Decode (x, block, 64);
31893+
31894+ /* Round 1 */
31895+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
31896+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
31897+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
31898+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
31899+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
31900+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
31901+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
31902+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
31903+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
31904+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
31905+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
31906+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
31907+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
31908+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
31909+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
31910+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
31911+
31912+ /* Round 2 */
31913+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
31914+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
31915+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
31916+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
31917+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
31918+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
31919+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
31920+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
31921+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
31922+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
31923+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
31924+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
31925+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
31926+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
31927+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
31928+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
31929+
31930+ /* Round 3 */
31931+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
31932+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
31933+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
31934+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
31935+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
31936+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
31937+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
31938+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
31939+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
31940+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
31941+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
31942+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
31943+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
31944+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
31945+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
31946+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
31947+
31948+ /* Round 4 */
31949+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
31950+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
31951+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
31952+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
31953+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
31954+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
31955+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
31956+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
31957+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
31958+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
31959+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
31960+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
31961+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
31962+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
31963+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
31964+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
31965+
31966+ state[0] += a;
31967+ state[1] += b;
31968+ state[2] += c;
31969+ state[3] += d;
31970+
31971+ /* Zeroize sensitive information.
31972+*/
31973+ MD5_memset ((POINTER)x, 0, sizeof (x));
31974+}
31975+
31976+#ifndef LITTLEENDIAN
31977+
31978+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
31979+ a multiple of 4.
31980+ */
31981+static void Encode (output, input, len)
31982+unsigned char *output;
31983+UINT4 *input;
31984+unsigned int len;
31985+{
31986+ unsigned int i, j;
31987+
31988+ for (i = 0, j = 0; j < len; i++, j += 4) {
31989+ output[j] = (unsigned char)(input[i] & 0xff);
31990+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
31991+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
31992+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
31993+ }
31994+}
31995+
31996+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
31997+ a multiple of 4.
31998+ */
31999+static void Decode (output, input, len)
32000+UINT4 *output;
32001+unsigned char *input;
32002+unsigned int len;
32003+{
32004+ unsigned int i, j;
32005+
32006+ for (i = 0, j = 0; j < len; i++, j += 4)
32007+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
32008+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
32009+}
32010+
32011+#endif
32012+
32013+#ifndef HAVEMEMCOPY
32014+#ifndef HAVEBCOPY
32015+/* Note: Replace "for loop" with standard memcpy if possible.
32016+ */
32017+
32018+static void MD5_memcpy (output, input, len)
32019+POINTER output;
32020+POINTER input;
32021+unsigned int len;
32022+{
32023+ unsigned int i;
32024+
32025+ for (i = 0; i < len; i++)
32026+
32027+ output[i] = input[i];
32028+}
32029+
32030+/* Note: Replace "for loop" with standard memset if possible.
32031+ */
32032+
32033+static void MD5_memset (output, value, len)
32034+POINTER output;
32035+int value;
32036+unsigned int len;
32037+{
32038+ unsigned int i;
32039+
32040+ for (i = 0; i < len; i++)
32041+ ((char *)output)[i] = (char)value;
32042+}
32043+#endif
32044+#endif
32045+
32046+/*
32047+ * $Log: ipsec_md5c.c,v $
32048+ * Revision 1.10 2005/04/15 01:25:57 mcr
32049+ * minor fix to comments.
32050+ *
32051+ * Revision 1.9 2004/09/08 17:21:36 ken
32052+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
32053+ *
32054+ * Revision 1.8 2004/04/06 02:49:26 mcr
32055+ * pullup of algo code from alg-branch.
32056+ *
32057+ * Revision 1.7 2002/09/10 01:45:14 mcr
32058+ * changed type of MD5_CTX and SHA1_CTX to void * so that
32059+ * the function prototypes would match, and could be placed
32060+ * into a pointer to a function.
32061+ *
32062+ * Revision 1.6 2002/04/24 07:55:32 mcr
32063+ * #include patches and Makefiles for post-reorg compilation.
32064+ *
32065+ * Revision 1.5 2002/04/24 07:36:28 mcr
32066+ * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
32067+ *
32068+ * Revision 1.4 1999/12/13 13:59:12 rgb
32069+ * Quick fix to argument size to Update bugs.
32070+ *
32071+ * Revision 1.3 1999/05/21 18:09:28 henry
32072+ * unnecessary <memory.h> include causes trouble in 2.2
32073+ *
32074+ * Revision 1.2 1999/04/06 04:54:26 rgb
32075+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
32076+ * patch shell fixes.
32077+ *
32078+ * Revision 1.1 1998/06/18 21:27:48 henry
32079+ * move sources from klips/src to klips/net/ipsec, to keep stupid
32080+ * kernel-build scripts happier in the presence of symlinks
32081+ *
32082+ * Revision 1.2 1998/04/23 20:54:02 rgb
32083+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
32084+ * verified.
32085+ *
32086+ * Revision 1.1 1998/04/09 03:06:08 henry
32087+ * sources moved up from linux/net/ipsec
32088+ *
32089+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
32090+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
32091+ *
32092+ * Revision 0.3 1996/11/20 14:48:53 ji
32093+ * Release update only.
32094+ *
32095+ * Revision 0.2 1996/11/02 00:18:33 ji
32096+ * First limited release.
32097+ *
32098+ *
32099+ */
32100--- /dev/null Tue Mar 11 13:02:56 2003
32101+++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004
32102@@ -0,0 +1,1186 @@
32103+/*
32104+ * @(#) /proc file system interface code.
32105+ *
32106+ * Copyright (C) 1996, 1997 John Ioannidis.
32107+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
32108+ * 2001 Michael Richardson <mcr@freeswan.org>
32109+ *
32110+ * This program is free software; you can redistribute it and/or modify it
32111+ * under the terms of the GNU General Public License as published by the
32112+ * Free Software Foundation; either version 2 of the License, or (at your
32113+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
32114+ *
32115+ * This program is distributed in the hope that it will be useful, but
32116+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
32117+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32118+ * for more details.
32119+ *
32120+ * Split out from ipsec_init.c version 1.70.
32121+ */
32122+
32123+char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.39.2.4 2006/11/15 22:21:39 paul Exp $";
32124+
32125+
32126+#ifndef AUTOCONF_INCLUDED
32127+#include <linux/config.h>
32128+#endif
32129+#include <linux/version.h>
32130+#define __NO_VERSION__
32131+#include <linux/module.h>
32132+#include <linux/kernel.h> /* printk() */
32133+
32134+#include "openswan/ipsec_kversion.h"
32135+#include "openswan/ipsec_param.h"
32136+
32137+#ifdef MALLOC_SLAB
32138+# include <linux/slab.h> /* kmalloc() */
32139+#else /* MALLOC_SLAB */
32140+# include <linux/malloc.h> /* kmalloc() */
32141+#endif /* MALLOC_SLAB */
32142+#include <linux/errno.h> /* error codes */
32143+#include <linux/types.h> /* size_t */
32144+#include <linux/interrupt.h> /* mark_bh */
32145+
32146+#include <linux/netdevice.h> /* struct device, and other headers */
32147+#include <linux/etherdevice.h> /* eth_type_trans */
32148+#include <linux/ip.h> /* struct iphdr */
32149+#include <linux/in.h> /* struct sockaddr_in */
32150+#include <linux/skbuff.h>
32151+#include <asm/uaccess.h> /* copy_from_user */
32152+#include <openswan.h>
32153+#ifdef SPINLOCK
32154+#ifdef SPINLOCK_23
32155+#include <linux/spinlock.h> /* *lock* */
32156+#else /* SPINLOCK_23 */
32157+#include <asm/spinlock.h> /* *lock* */
32158+#endif /* SPINLOCK_23 */
32159+#endif /* SPINLOCK */
32160+
32161+#include <net/ip.h>
32162+#ifdef CONFIG_PROC_FS
32163+#include <linux/proc_fs.h>
32164+#endif /* CONFIG_PROC_FS */
32165+#ifdef NETLINK_SOCK
32166+#include <linux/netlink.h>
32167+#else
32168+#include <net/netlink.h>
32169+#endif
32170+
32171+#include "openswan/radij.h"
32172+
32173+#include "openswan/ipsec_life.h"
32174+#include "openswan/ipsec_stats.h"
32175+#include "openswan/ipsec_sa.h"
32176+
32177+#include "openswan/ipsec_encap.h"
32178+#include "openswan/ipsec_radij.h"
32179+#include "openswan/ipsec_xform.h"
32180+#include "openswan/ipsec_tunnel.h"
32181+#include "openswan/ipsec_xmit.h"
32182+
32183+#include "openswan/ipsec_rcv.h"
32184+#include "openswan/ipsec_ah.h"
32185+#include "openswan/ipsec_esp.h"
32186+#include "openswan/ipsec_kern24.h"
32187+
32188+#ifdef CONFIG_KLIPS_IPCOMP
32189+#include "openswan/ipcomp.h"
32190+#endif /* CONFIG_KLIPS_IPCOMP */
32191+
32192+#include "openswan/ipsec_proto.h"
32193+
32194+#include <pfkeyv2.h>
32195+#include <pfkey.h>
32196+
32197+#ifdef CONFIG_PROC_FS
32198+
32199+#ifdef IPSEC_PROC_SUBDIRS
32200+static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
32201+static struct proc_dir_entry *proc_eroute_dir = NULL;
32202+static struct proc_dir_entry *proc_spi_dir = NULL;
32203+static struct proc_dir_entry *proc_spigrp_dir = NULL;
32204+static struct proc_dir_entry *proc_birth_dir = NULL;
32205+static struct proc_dir_entry *proc_stats_dir = NULL;
32206+#endif
32207+
32208+struct ipsec_birth_reply ipsec_ipv4_birth_packet;
32209+struct ipsec_birth_reply ipsec_ipv6_birth_packet;
32210+
32211+#ifdef CONFIG_KLIPS_DEBUG
32212+int debug_esp = 0;
32213+int debug_ah = 0;
32214+#endif /* CONFIG_KLIPS_DEBUG */
32215+
32216+#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)
32217+
32218+extern int ipsec_xform_get_info(char *buffer, char **start,
32219+ off_t offset, int length IPSEC_PROC_LAST_ARG);
32220+
32221+
32222+IPSEC_PROCFS_DEBUG_NO_STATIC
32223+int
32224+ipsec_eroute_get_info(char *buffer,
32225+ char **start,
32226+ off_t offset,
32227+ int length IPSEC_PROC_LAST_ARG)
32228+{
32229+ struct wsbuf w = {buffer, length, offset, 0, 0};
32230+
32231+#ifdef CONFIG_KLIPS_DEBUG
32232+ if (debug_radij & DB_RJ_DUMPTREES)
32233+ rj_dumptrees(); /* XXXXXXXXX */
32234+#endif /* CONFIG_KLIPS_DEBUG */
32235+
32236+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32237+ "klips_debug:ipsec_eroute_get_info: "
32238+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32239+ buffer,
32240+ *start,
32241+ (int)offset,
32242+ length);
32243+
32244+ spin_lock_bh(&eroute_lock);
32245+
32246+ rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
32247+/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
32248+
32249+ spin_unlock_bh(&eroute_lock);
32250+
32251+ *start = buffer + (offset - w.begin); /* Start of wanted data */
32252+ return w.len - (offset - w.begin);
32253+}
32254+
32255+IPSEC_PROCFS_DEBUG_NO_STATIC
32256+int
32257+ipsec_spi_get_info(char *buffer,
32258+ char **start,
32259+ off_t offset,
32260+ int length IPSEC_PROC_LAST_ARG)
32261+{
32262+ const int max_content = length > 0? length-1 : 0;
32263+ int len = 0;
32264+ off_t begin = 0;
32265+ int i;
32266+ struct ipsec_sa *sa_p;
32267+ char sa[SATOT_BUF];
32268+ char buf_s[SUBNETTOA_BUF];
32269+ char buf_d[SUBNETTOA_BUF];
32270+ size_t sa_len;
32271+
32272+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32273+ "klips_debug:ipsec_spi_get_info: "
32274+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32275+ buffer,
32276+ *start,
32277+ (int)offset,
32278+ length);
32279+
32280+ spin_lock_bh(&tdb_lock);
32281+
32282+ for (i = 0; i < SADB_HASHMOD; i++) {
32283+ for (sa_p = ipsec_sadb_hash[i];
32284+ sa_p;
32285+ sa_p = sa_p->ips_hnext) {
32286+ atomic_inc(&sa_p->ips_refcount);
32287+ sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
32288+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
32289+ sa_len ? sa : " (error)");
32290+
32291+ len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
32292+ IPS_XFORM_NAME(sa_p));
32293+
32294+ len += ipsec_snprintf(buffer+len, length-len, ": dir=%s",
32295+ (sa_p->ips_flags & EMT_INBOUND) ?
32296+ "in " : "out");
32297+
32298+ if(sa_p->ips_addr_s) {
32299+ addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
32300+ 0, buf_s, sizeof(buf_s));
32301+ len += ipsec_snprintf(buffer+len, length-len, " src=%s",
32302+ buf_s);
32303+ }
32304+
32305+ if((sa_p->ips_said.proto == IPPROTO_IPIP)
32306+ && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
32307+ subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
32308+ sa_p->ips_mask_s.u.v4.sin_addr,
32309+ 0,
32310+ buf_s,
32311+ sizeof(buf_s));
32312+
32313+ subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
32314+ sa_p->ips_mask_d.u.v4.sin_addr,
32315+ 0,
32316+ buf_d,
32317+ sizeof(buf_d));
32318+
32319+ len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
32320+ buf_s, buf_d);
32321+ }
32322+
32323+ if(sa_p->ips_iv_bits) {
32324+ int j;
32325+ len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
32326+ sa_p->ips_iv_bits);
32327+
32328+ for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
32329+ len += ipsec_snprintf(buffer+len, length-len, "%02x",
32330+ (__u32)((__u8*)(sa_p->ips_iv))[j]);
32331+ }
32332+ }
32333+
32334+ if(sa_p->ips_encalg || sa_p->ips_authalg) {
32335+ if(sa_p->ips_replaywin) {
32336+ len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
32337+ sa_p->ips_replaywin);
32338+ }
32339+ if(sa_p->ips_errs.ips_replaywin_errs) {
32340+ len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
32341+ sa_p->ips_errs.ips_replaywin_errs);
32342+ }
32343+ if(sa_p->ips_replaywin_lastseq) {
32344+ len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
32345+ sa_p->ips_replaywin_lastseq);
32346+ }
32347+ if(sa_p->ips_replaywin_bitmap) {
32348+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32349+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
32350+ sa_p->ips_replaywin_bitmap);
32351+#else
32352+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x",
32353+ (__u32)(sa_p->ips_replaywin_bitmap >> 32),
32354+ (__u32)sa_p->ips_replaywin_bitmap);
32355+#endif
32356+ }
32357+ if(sa_p->ips_replaywin_maxdiff) {
32358+ len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
32359+ sa_p->ips_replaywin_maxdiff);
32360+ }
32361+ }
32362+ if(sa_p->ips_flags & ~EMT_INBOUND) {
32363+ len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
32364+ sa_p->ips_flags & ~EMT_INBOUND);
32365+ len += ipsec_snprintf(buffer+len, length-len, "<");
32366+ /* flag printing goes here */
32367+ len += ipsec_snprintf(buffer+len, length-len, ">");
32368+ }
32369+ if(sa_p->ips_auth_bits) {
32370+ len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
32371+ sa_p->ips_auth_bits);
32372+ }
32373+ if(sa_p->ips_key_bits_a) {
32374+ len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
32375+ sa_p->ips_key_bits_a);
32376+ }
32377+ if(sa_p->ips_errs.ips_auth_errs) {
32378+ len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
32379+ sa_p->ips_errs.ips_auth_errs);
32380+ }
32381+ if(sa_p->ips_key_bits_e) {
32382+ len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
32383+ sa_p->ips_key_bits_e);
32384+ }
32385+ if(sa_p->ips_errs.ips_encsize_errs) {
32386+ len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
32387+ sa_p->ips_errs.ips_encsize_errs);
32388+ }
32389+ if(sa_p->ips_errs.ips_encpad_errs) {
32390+ len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
32391+ sa_p->ips_errs.ips_encpad_errs);
32392+ }
32393+
32394+ len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)=");
32395+
32396+ len += ipsec_lifetime_format(buffer + len,
32397+ length - len,
32398+ "alloc",
32399+ ipsec_life_countbased,
32400+ &sa_p->ips_life.ipl_allocations);
32401+
32402+ len += ipsec_lifetime_format(buffer + len,
32403+ length - len,
32404+ "bytes",
32405+ ipsec_life_countbased,
32406+ &sa_p->ips_life.ipl_bytes);
32407+
32408+ len += ipsec_lifetime_format(buffer + len,
32409+ length - len,
32410+ "addtime",
32411+ ipsec_life_timebased,
32412+ &sa_p->ips_life.ipl_addtime);
32413+
32414+ len += ipsec_lifetime_format(buffer + len,
32415+ length - len,
32416+ "usetime",
32417+ ipsec_life_timebased,
32418+ &sa_p->ips_life.ipl_usetime);
32419+
32420+ len += ipsec_lifetime_format(buffer + len,
32421+ length - len,
32422+ "packets",
32423+ ipsec_life_countbased,
32424+ &sa_p->ips_life.ipl_packets);
32425+
32426+ if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
32427+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32428+ len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
32429+ jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
32430+#else
32431+ len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
32432+ jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
32433+#endif
32434+ }
32435+
32436+#ifdef CONFIG_KLIPS_IPCOMP
32437+ if(sa_p->ips_said.proto == IPPROTO_COMP &&
32438+ (sa_p->ips_comp_ratio_dbytes ||
32439+ sa_p->ips_comp_ratio_cbytes)) {
32440+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32441+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
32442+ sa_p->ips_comp_ratio_dbytes,
32443+ sa_p->ips_comp_ratio_cbytes);
32444+#else
32445+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
32446+ (unsigned long)sa_p->ips_comp_ratio_dbytes,
32447+ (unsigned long)sa_p->ips_comp_ratio_cbytes);
32448+#endif
32449+ }
32450+#endif /* CONFIG_KLIPS_IPCOMP */
32451+
32452+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32453+ {
32454+ char *natttype_name;
32455+
32456+ switch(sa_p->ips_natt_type)
32457+ {
32458+ case 0:
32459+ natttype_name="none";
32460+ break;
32461+ case ESPINUDP_WITH_NON_IKE:
32462+ natttype_name="nonike";
32463+ break;
32464+ case ESPINUDP_WITH_NON_ESP:
32465+ natttype_name="nonesp";
32466+ break;
32467+ default:
32468+ natttype_name = "unknown";
32469+ break;
32470+ }
32471+
32472+ len += ipsec_snprintf(buffer + len, length-len, " natencap=%s",
32473+ natttype_name);
32474+
32475+ len += ipsec_snprintf(buffer + len, length-len, " natsport=%d",
32476+ sa_p->ips_natt_sport);
32477+
32478+ len += ipsec_snprintf(buffer + len,length-len, " natdport=%d",
32479+ sa_p->ips_natt_dport);
32480+ }
32481+#else
32482+ len += ipsec_snprintf(buffer + len, length-len, " natencap=na");
32483+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
32484+
32485+ len += ipsec_snprintf(buffer + len,length-len, " refcount=%d",
32486+ atomic_read(&sa_p->ips_refcount));
32487+
32488+ len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
32489+ sa_p->ips_ref);
32490+#ifdef CONFIG_KLIPS_DEBUG
32491+ if(debug_xform) {
32492+ len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
32493+ (unsigned long)IPsecSAref2table(sa_p->ips_ref),
32494+ (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
32495+ }
32496+#endif /* CONFIG_KLIPS_DEBUG */
32497+
32498+ len += ipsec_snprintf(buffer+len, length-len, "\n");
32499+
32500+ atomic_dec(&sa_p->ips_refcount);
32501+
32502+ if (len >= max_content) {
32503+ /* we've done all that can fit -- stop loops */
32504+ len = max_content; /* truncate crap */
32505+ goto done_spi_i;
32506+ } else {
32507+ const off_t pos = begin + len; /* file position of end of what we've generated */
32508+
32509+ if (pos <= offset) {
32510+ /* all is before first interesting character:
32511+ * discard, but note where we are.
32512+ */
32513+ len = 0;
32514+ begin = pos;
32515+ }
32516+ }
32517+ }
32518+ }
32519+
32520+done_spi_i:
32521+ spin_unlock_bh(&tdb_lock);
32522+
32523+ *start = buffer + (offset - begin); /* Start of wanted data */
32524+ return len - (offset - begin);
32525+}
32526+
32527+IPSEC_PROCFS_DEBUG_NO_STATIC
32528+int
32529+ipsec_spigrp_get_info(char *buffer,
32530+ char **start,
32531+ off_t offset,
32532+ int length IPSEC_PROC_LAST_ARG)
32533+{
32534+ /* Limit of useful snprintf output */
32535+ const int max_content = length > 0? length-1 : 0;
32536+
32537+ int len = 0;
32538+ off_t begin = 0;
32539+ int i;
32540+ struct ipsec_sa *sa_p, *sa_p2;
32541+ char sa[SATOT_BUF];
32542+ size_t sa_len;
32543+
32544+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32545+ "klips_debug:ipsec_spigrp_get_info: "
32546+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32547+ buffer,
32548+ *start,
32549+ (int)offset,
32550+ length);
32551+
32552+ spin_lock_bh(&tdb_lock);
32553+
32554+ for (i = 0; i < SADB_HASHMOD; i++) {
32555+ for (sa_p = ipsec_sadb_hash[i];
32556+ sa_p != NULL;
32557+ sa_p = sa_p->ips_hnext)
32558+ {
32559+ atomic_inc(&sa_p->ips_refcount);
32560+ if(sa_p->ips_inext == NULL) {
32561+ sa_p2 = sa_p;
32562+ while(sa_p2 != NULL) {
32563+ atomic_inc(&sa_p2->ips_refcount);
32564+ sa_len = satot(&sa_p2->ips_said,
32565+ 'x', sa, sizeof(sa));
32566+
32567+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
32568+ sa_len ? sa : " (error)");
32569+ atomic_dec(&sa_p2->ips_refcount);
32570+ sa_p2 = sa_p2->ips_onext;
32571+ }
32572+ len += ipsec_snprintf(buffer+len, length-len, "\n");
32573+ }
32574+
32575+ atomic_dec(&sa_p->ips_refcount);
32576+
32577+ if (len >= max_content) {
32578+ /* we've done all that can fit -- stop loops */
32579+ len = max_content; /* truncate crap */
32580+ goto done_spigrp_i;
32581+ } else {
32582+ const off_t pos = begin + len;
32583+
32584+ if (pos <= offset) {
32585+ /* all is before first interesting character:
32586+ * discard, but note where we are.
32587+ */
32588+ len = 0;
32589+ begin = pos;
32590+ }
32591+ }
32592+ }
32593+ }
32594+
32595+done_spigrp_i:
32596+ spin_unlock_bh(&tdb_lock);
32597+
32598+ *start = buffer + (offset - begin); /* Start of wanted data */
32599+ return len - (offset - begin);
32600+}
32601+
32602+
32603+IPSEC_PROCFS_DEBUG_NO_STATIC
32604+int
32605+ipsec_tncfg_get_info(char *buffer,
32606+ char **start,
32607+ off_t offset,
32608+ int length IPSEC_PROC_LAST_ARG)
32609+{
32610+ /* limit of useful snprintf output */
32611+ const int max_content = length > 0? length-1 : 0;
32612+ int len = 0;
32613+ off_t begin = 0;
32614+ int i;
32615+ char name[9];
32616+ struct net_device *dev, *privdev;
32617+ struct ipsecpriv *priv;
32618+
32619+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32620+ "klips_debug:ipsec_tncfg_get_info: "
32621+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32622+ buffer,
32623+ *start,
32624+ (int)offset,
32625+ length);
32626+
32627+ for(i = 0; i < IPSEC_NUM_IF; i++) {
32628+ ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i);
32629+ dev = __ipsec_dev_get(name);
32630+ if(dev) {
32631+ priv = (struct ipsecpriv *)(dev->priv);
32632+ len += ipsec_snprintf(buffer+len, length-len, "%s",
32633+ dev->name);
32634+ if(priv) {
32635+ privdev = (struct net_device *)(priv->dev);
32636+ len += ipsec_snprintf(buffer+len, length-len, " -> %s",
32637+ privdev ? privdev->name : "NULL");
32638+ len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d",
32639+ dev->mtu,
32640+ priv->mtu,
32641+ privdev ? privdev->mtu : 0);
32642+ } else {
32643+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32644+ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
32645+ dev->name);
32646+ }
32647+ len += ipsec_snprintf(buffer+len, length-len, "\n");
32648+
32649+ if (len >= max_content) {
32650+ /* we've done all that can fit -- stop loop */
32651+ len = max_content; /* truncate crap */
32652+ break;
32653+ } else {
32654+ const off_t pos = begin + len;
32655+ if (pos <= offset) {
32656+ len = 0;
32657+ begin = pos;
32658+ }
32659+ }
32660+ }
32661+ }
32662+ *start = buffer + (offset - begin); /* Start of wanted data */
32663+ len -= (offset - begin); /* Start slop */
32664+ if (len > length)
32665+ len = length;
32666+ return len;
32667+}
32668+
32669+IPSEC_PROCFS_DEBUG_NO_STATIC
32670+int
32671+ipsec_version_get_info(char *buffer,
32672+ char **start,
32673+ off_t offset,
32674+ int length IPSEC_PROC_LAST_ARG)
32675+{
32676+ int len = 0;
32677+ off_t begin = 0;
32678+
32679+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32680+ "klips_debug:ipsec_version_get_info: "
32681+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32682+ buffer,
32683+ *start,
32684+ (int)offset,
32685+ length);
32686+
32687+ len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n",
32688+ ipsec_version_code());
32689+#if 0
32690+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32691+ "klips_debug:ipsec_version_get_info: "
32692+ "ipsec_init version: %s\n",
32693+ ipsec_init_c_version);
32694+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32695+ "klips_debug:ipsec_version_get_info: "
32696+ "ipsec_tunnel version: %s\n",
32697+ ipsec_tunnel_c_version);
32698+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32699+ "klips_debug:ipsec_version_get_info: "
32700+ "ipsec_netlink version: %s\n",
32701+ ipsec_netlink_c_version);
32702+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32703+ "klips_debug:ipsec_version_get_info: "
32704+ "radij_c_version: %s\n",
32705+ radij_c_version);
32706+#endif
32707+
32708+
32709+ *start = buffer + (offset - begin); /* Start of wanted data */
32710+ len -= (offset - begin); /* Start slop */
32711+ if (len > length)
32712+ len = length;
32713+ return len;
32714+}
32715+
32716+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32717+unsigned int natt_available = 1;
32718+#else
32719+unsigned int natt_available = 0;
32720+#endif
32721+module_param(natt_available, int, 0444);
32722+
32723+IPSEC_PROCFS_DEBUG_NO_STATIC
32724+int
32725+ipsec_natt_get_info(char *buffer,
32726+ char **start,
32727+ off_t offset,
32728+ int length IPSEC_PROC_LAST_ARG)
32729+{
32730+ int len = 0;
32731+ off_t begin = 0;
32732+
32733+ len += ipsec_snprintf(buffer + len,
32734+ length-len, "%d\n",
32735+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32736+ 1
32737+#else
32738+ 0
32739+#endif
32740+ );
32741+
32742+ *start = buffer + (offset - begin); /* Start of wanted data */
32743+ len -= (offset - begin); /* Start slop */
32744+ if (len > length)
32745+ len = length;
32746+ return len;
32747+}
32748+
32749+IPSEC_PROCFS_DEBUG_NO_STATIC
32750+int
32751+ipsec_birth_info(char *page,
32752+ char **start,
32753+ off_t offset,
32754+ int count,
32755+ int *eof,
32756+ void *data)
32757+{
32758+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32759+ int len;
32760+
32761+ if(offset >= ibr->packet_template_len) {
32762+ if(eof) {
32763+ *eof=1;
32764+ }
32765+ return 0;
32766+ }
32767+
32768+ len = ibr->packet_template_len;
32769+ len -= offset;
32770+ if (len > count)
32771+ len = count;
32772+
32773+ memcpy(page + offset, ibr->packet_template+offset, len);
32774+
32775+ return len;
32776+}
32777+
32778+IPSEC_PROCFS_DEBUG_NO_STATIC
32779+int
32780+ipsec_birth_set(struct file *file, const char *buffer,
32781+ unsigned long count, void *data)
32782+{
32783+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32784+ int len;
32785+
32786+ KLIPS_INC_USE;
32787+ if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
32788+ len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
32789+ } else {
32790+ len = count;
32791+ }
32792+
32793+ if(copy_from_user(ibr->packet_template, buffer, len)) {
32794+ KLIPS_DEC_USE;
32795+ return -EFAULT;
32796+ }
32797+ ibr->packet_template_len = len;
32798+
32799+ KLIPS_DEC_USE;
32800+
32801+ return len;
32802+}
32803+
32804+
32805+#ifdef CONFIG_KLIPS_DEBUG
32806+IPSEC_PROCFS_DEBUG_NO_STATIC
32807+int
32808+ipsec_klipsdebug_get_info(char *buffer,
32809+ char **start,
32810+ off_t offset,
32811+ int length IPSEC_PROC_LAST_ARG)
32812+{
32813+ int len = 0;
32814+ off_t begin = 0;
32815+
32816+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32817+ "klips_debug:ipsec_klipsdebug_get_info: "
32818+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32819+ buffer,
32820+ *start,
32821+ (int)offset,
32822+ length);
32823+
32824+ len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
32825+ len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
32826+ len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
32827+ len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
32828+ len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
32829+ len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
32830+ len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah);
32831+ len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
32832+ len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
32833+
32834+ *start = buffer + (offset - begin); /* Start of wanted data */
32835+ len -= (offset - begin); /* Start slop */
32836+ if (len > length)
32837+ len = length;
32838+ return len;
32839+}
32840+#endif /* CONFIG_KLIPS_DEBUG */
32841+
32842+IPSEC_PROCFS_DEBUG_NO_STATIC
32843+int
32844+ipsec_stats_get_int_info(char *buffer,
32845+ char **start,
32846+ off_t offset,
32847+ int length,
32848+ int *eof,
32849+ void *data)
32850+{
32851+
32852+ const int max_content = length > 0? length-1 : 0;
32853+ int len = 0;
32854+ int *thing;
32855+
32856+ thing = (int *)data;
32857+
32858+ len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing);
32859+
32860+ if (len >= max_content)
32861+ len = max_content; /* truncate crap */
32862+
32863+ *start = buffer + offset; /* Start of wanted data */
32864+ return len > offset? len - offset : 0;
32865+
32866+}
32867+
32868+#ifndef PROC_FS_2325
32869+struct proc_dir_entry ipsec_eroute =
32870+{
32871+ 0,
32872+ 12, "ipsec_eroute",
32873+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32874+ &proc_net_inode_operations,
32875+ ipsec_eroute_get_info,
32876+ NULL, NULL, NULL, NULL, NULL
32877+};
32878+
32879+struct proc_dir_entry ipsec_spi =
32880+{
32881+ 0,
32882+ 9, "ipsec_spi",
32883+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32884+ &proc_net_inode_operations,
32885+ ipsec_spi_get_info,
32886+ NULL, NULL, NULL, NULL, NULL
32887+};
32888+
32889+struct proc_dir_entry ipsec_spigrp =
32890+{
32891+ 0,
32892+ 12, "ipsec_spigrp",
32893+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32894+ &proc_net_inode_operations,
32895+ ipsec_spigrp_get_info,
32896+ NULL, NULL, NULL, NULL, NULL
32897+};
32898+
32899+struct proc_dir_entry ipsec_tncfg =
32900+{
32901+ 0,
32902+ 11, "ipsec_tncfg",
32903+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32904+ &proc_net_inode_operations,
32905+ ipsec_tncfg_get_info,
32906+ NULL, NULL, NULL, NULL, NULL
32907+};
32908+
32909+struct proc_dir_entry ipsec_version =
32910+{
32911+ 0,
32912+ 13, "ipsec_version",
32913+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32914+ &proc_net_inode_operations,
32915+ ipsec_version_get_info,
32916+ NULL, NULL, NULL, NULL, NULL
32917+};
32918+
32919+#ifdef CONFIG_KLIPS_DEBUG
32920+struct proc_dir_entry ipsec_klipsdebug =
32921+{
32922+ 0,
32923+ 16, "ipsec_klipsdebug",
32924+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
32925+ &proc_net_inode_operations,
32926+ ipsec_klipsdebug_get_info,
32927+ NULL, NULL, NULL, NULL, NULL
32928+};
32929+#endif /* CONFIG_KLIPS_DEBUG */
32930+#endif /* !PROC_FS_2325 */
32931+#endif /* CONFIG_PROC_FS */
32932+
32933+#if defined(PROC_FS_2325)
32934+struct ipsec_proc_list {
32935+ char *name;
32936+ struct proc_dir_entry **parent;
32937+ struct proc_dir_entry **dir;
32938+ read_proc_t *readthing;
32939+ write_proc_t *writething;
32940+ void *data;
32941+};
32942+static struct ipsec_proc_list proc_items[]={
32943+#ifdef CONFIG_KLIPS_DEBUG
32944+ {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL},
32945+#endif
32946+ {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
32947+ {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL},
32948+ {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL},
32949+ {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL},
32950+ {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
32951+ {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL},
32952+ {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL},
32953+ {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
32954+ {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
32955+ {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL},
32956+ {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL},
32957+ {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL},
32958+ {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
32959+ {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
32960+ {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL},
32961+ {NULL, NULL, NULL, NULL, NULL, NULL}
32962+};
32963+#endif
32964+
32965+int
32966+ipsec_proc_init()
32967+{
32968+ int error = 0;
32969+#ifdef IPSEC_PROC_SUBDIRS
32970+ struct proc_dir_entry *item;
32971+#endif
32972+
32973+ /*
32974+ * just complain because pluto won't run without /proc!
32975+ */
32976+#ifndef CONFIG_PROC_FS
32977+#error You must have PROC_FS built in to use KLIPS
32978+#endif
32979+
32980+ /* for 2.0 kernels */
32981+#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
32982+ error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
32983+ error |= proc_register_dynamic(&proc_net, &ipsec_spi);
32984+ error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
32985+ error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
32986+ error |= proc_register_dynamic(&proc_net, &ipsec_version);
32987+#ifdef CONFIG_KLIPS_DEBUG
32988+ error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
32989+#endif /* CONFIG_KLIPS_DEBUG */
32990+#endif
32991+
32992+ /* for 2.2 kernels */
32993+#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
32994+ error |= proc_register(proc_net, &ipsec_eroute);
32995+ error |= proc_register(proc_net, &ipsec_spi);
32996+ error |= proc_register(proc_net, &ipsec_spigrp);
32997+ error |= proc_register(proc_net, &ipsec_tncfg);
32998+ error |= proc_register(proc_net, &ipsec_version);
32999+#ifdef CONFIG_KLIPS_DEBUG
33000+ error |= proc_register(proc_net, &ipsec_klipsdebug);
33001+#endif /* CONFIG_KLIPS_DEBUG */
33002+#endif
33003+
33004+ /* for 2.4 kernels */
33005+#if defined(PROC_FS_2325)
33006+ /* create /proc/net/ipsec */
33007+
33008+ /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
33009+ memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
33010+ memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
33011+
33012+ proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
33013+ if(proc_net_ipsec_dir == NULL) {
33014+ /* no point in continuing */
33015+ return 1;
33016+ }
33017+
33018+ {
33019+ struct ipsec_proc_list *it;
33020+
33021+ it=proc_items;
33022+ while(it->name!=NULL) {
33023+ if(it->dir) {
33024+ /* make a dir instead */
33025+ item = proc_mkdir(it->name, *it->parent);
33026+ *it->dir = item;
33027+ } else {
33028+ item = create_proc_entry(it->name, 0400, *it->parent);
33029+ }
33030+ if(item) {
33031+ item->read_proc = it->readthing;
33032+ item->write_proc = it->writething;
33033+ item->data = it->data;
33034+#ifdef MODULE
33035+ item->owner = THIS_MODULE;
33036+#endif
33037+ } else {
33038+ error |= 1;
33039+ }
33040+ it++;
33041+ }
33042+ }
33043+
33044+ /* now create some symlinks to provide compatibility */
33045+ proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
33046+ proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all");
33047+ proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
33048+ proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg");
33049+ proc_symlink("ipsec_version",proc_net, "ipsec/version");
33050+ proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
33051+
33052+#endif /* !PROC_FS_2325 */
33053+
33054+ return error;
33055+}
33056+
33057+void
33058+ipsec_proc_cleanup()
33059+{
33060+
33061+ /* for 2.0 and 2.2 kernels */
33062+#if !defined(PROC_FS_2325)
33063+
33064+#ifdef CONFIG_KLIPS_DEBUG
33065+ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
33066+ printk("klips_debug:ipsec_cleanup: "
33067+ "cannot unregister /proc/net/ipsec_klipsdebug\n");
33068+#endif /* CONFIG_KLIPS_DEBUG */
33069+
33070+ if (proc_net_unregister(ipsec_version.low_ino) != 0)
33071+ printk("klips_debug:ipsec_cleanup: "
33072+ "cannot unregister /proc/net/ipsec_version\n");
33073+ if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
33074+ printk("klips_debug:ipsec_cleanup: "
33075+ "cannot unregister /proc/net/ipsec_eroute\n");
33076+ if (proc_net_unregister(ipsec_spi.low_ino) != 0)
33077+ printk("klips_debug:ipsec_cleanup: "
33078+ "cannot unregister /proc/net/ipsec_spi\n");
33079+ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
33080+ printk("klips_debug:ipsec_cleanup: "
33081+ "cannot unregister /proc/net/ipsec_spigrp\n");
33082+ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
33083+ printk("klips_debug:ipsec_cleanup: "
33084+ "cannot unregister /proc/net/ipsec_tncfg\n");
33085+#endif
33086+
33087+ /* for 2.4 kernels */
33088+#if defined(PROC_FS_2325)
33089+ {
33090+ struct ipsec_proc_list *it;
33091+
33092+ /* find end of list */
33093+ it=proc_items;
33094+ while(it->name!=NULL) {
33095+ it++;
33096+ }
33097+ it--;
33098+
33099+ do {
33100+ remove_proc_entry(it->name, *it->parent);
33101+ it--;
33102+ } while(it >= proc_items);
33103+ }
33104+
33105+
33106+#ifdef CONFIG_KLIPS_DEBUG
33107+ remove_proc_entry("ipsec_klipsdebug", proc_net);
33108+#endif /* CONFIG_KLIPS_DEBUG */
33109+ remove_proc_entry("ipsec_eroute", proc_net);
33110+ remove_proc_entry("ipsec_spi", proc_net);
33111+ remove_proc_entry("ipsec_spigrp", proc_net);
33112+ remove_proc_entry("ipsec_tncfg", proc_net);
33113+ remove_proc_entry("ipsec_version", proc_net);
33114+ remove_proc_entry("ipsec", proc_net);
33115+#endif /* 2.4 kernel */
33116+}
33117+
33118+/*
33119+ * $Log: ipsec_proc.c,v $
33120+ * Revision 1.39.2.4 2006/11/15 22:21:39 paul
33121+ * backport of creating a /sys/ file to test for nat-t capability in kernel.
33122+ *
33123+ * Revision 1.39.2.3 2006/10/06 21:39:26 paul
33124+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
33125+ * set. This is defined through autoconf.h which is included through the
33126+ * linux kernel build macros.
33127+ *
33128+ * Revision 1.39.2.2 2006/02/13 18:48:12 paul
33129+ * Fix by Ankit Desai <ankit@elitecore.com> for module unloading.
33130+ *
33131+ * Revision 1.39.2.1 2005/09/07 00:45:59 paul
33132+ * pull up of mcr's nat-t klips detection patch from head
33133+ *
33134+ * Revision 1.39 2005/05/20 03:19:18 mcr
33135+ * modifications for use on 2.4.30 kernel, with backported
33136+ * printk_ratelimit(). all warnings removed.
33137+ *
33138+ * Revision 1.38 2005/04/29 05:10:22 mcr
33139+ * removed from extraenous includes to make unit testing easier.
33140+ *
33141+ * Revision 1.37 2005/04/13 22:49:49 mcr
33142+ * moved KLIPS specific snprintf() wrapper to seperate file.
33143+ *
33144+ * Revision 1.36 2005/04/06 17:44:36 mcr
33145+ * when NAT-T is compiled out, show encap as "NA"
33146+ *
33147+ * Revision 1.35 2005/01/26 00:50:35 mcr
33148+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
33149+ * and make sure that NAT_TRAVERSAL is set as well to match
33150+ * userspace compiles of code.
33151+ *
33152+ * Revision 1.34 2004/12/03 21:25:57 mcr
33153+ * compile time fixes for running on 2.6.
33154+ * still experimental.
33155+ *
33156+ * Revision 1.33 2004/08/17 03:27:23 mcr
33157+ * klips 2.6 edits.
33158+ *
33159+ * Revision 1.32 2004/08/03 18:19:08 mcr
33160+ * in 2.6, use "net_device" instead of #define device->net_device.
33161+ * this probably breaks 2.0 compiles.
33162+ *
33163+ * Revision 1.31 2004/07/10 19:11:18 mcr
33164+ * CONFIG_IPSEC -> CONFIG_KLIPS.
33165+ *
33166+ * Revision 1.30 2004/04/25 21:23:11 ken
33167+ * Pull in dhr's changes from FreeS/WAN 2.06
33168+ *
33169+ * Revision 1.29 2004/04/06 02:49:26 mcr
33170+ * pullup of algo code from alg-branch.
33171+ *
33172+ * Revision 1.28 2004/03/28 20:29:58 paul
33173+ * <hugh_> ssize_t, not ssized_t
33174+ *
33175+ * Revision 1.27 2004/03/28 20:27:20 paul
33176+ * Included tested and confirmed fixes mcr made and dhr verified for
33177+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
33178+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
33179+ * dhr. (thanks dhr!)
33180+ *
33181+ * Revision 1.26 2004/02/09 22:07:06 mcr
33182+ * added information about nat-traversal setting to spi-output.
33183+ *
33184+ * Revision 1.25.4.1 2004/04/05 04:30:46 mcr
33185+ * patches for alg-branch to compile/work with 2.x openswan
33186+ *
33187+ * Revision 1.25 2003/10/31 02:27:55 mcr
33188+ * pulled up port-selector patches and sa_id elimination.
33189+ *
33190+ * Revision 1.24.4.1 2003/10/29 01:30:41 mcr
33191+ * elimited "struct sa_id".
33192+ *
33193+ * Revision 1.24 2003/06/20 01:42:21 mcr
33194+ * added counters to measure how many ACQUIREs we send to pluto,
33195+ * and how many are successfully sent.
33196+ *
33197+ * Revision 1.23 2003/04/03 17:38:09 rgb
33198+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
33199+ *
33200+ * Revision 1.22 2002/09/20 15:40:57 rgb
33201+ * Renamed saref macros for consistency and brevity.
33202+ *
33203+ * Revision 1.21 2002/09/20 05:01:35 rgb
33204+ * Print ref and reftable, refentry seperately.
33205+ *
33206+ * Revision 1.20 2002/09/19 02:35:39 mcr
33207+ * do not define structures needed by /proc/net/ipsec/ if we
33208+ * aren't going create that directory.
33209+ *
33210+ * Revision 1.19 2002/09/10 01:43:25 mcr
33211+ * fixed problem in /-* comment.
33212+ *
33213+ * Revision 1.18 2002/09/03 16:22:11 mcr
33214+ * fixed initialization of birth/stuff values - some simple
33215+ * screw ups in the code.
33216+ * removed debugging that was left in by mistake.
33217+ *
33218+ * Revision 1.17 2002/09/02 17:54:53 mcr
33219+ * changed how the table driven /proc entries are created so that
33220+ * making subdirs is now explicit rather than implicit.
33221+ *
33222+ * Revision 1.16 2002/08/30 01:23:37 mcr
33223+ * reorganized /proc creating code to clear up ifdefs,
33224+ * make the 2.4 code table driven, and put things into
33225+ * /proc/net/ipsec subdir. Symlinks are left for compatibility.
33226+ *
33227+ * Revision 1.15 2002/08/13 19:01:25 mcr
33228+ * patches from kenb to permit compilation of FreeSWAN on ia64.
33229+ * des library patched to use proper DES_LONG type for ia64.
33230+ *
33231+ * Revision 1.14 2002/07/26 08:48:31 rgb
33232+ * Added SA ref table code.
33233+ *
33234+ * Revision 1.13 2002/07/24 18:44:54 rgb
33235+ * Type fiddling to tame ia64 compiler.
33236+ *
33237+ * Revision 1.12 2002/05/27 18:56:07 rgb
33238+ * Convert to dynamic ipsec device allocation.
33239+ *
33240+ * Revision 1.11 2002/05/23 07:14:50 rgb
33241+ * Added refcount code.
33242+ * Cleaned up %p variants to 0p%p for test suite cleanup.
33243+ * Convert "usecount" to "refcount" to remove ambiguity.
33244+ *
33245+ * Revision 1.10 2002/04/24 07:55:32 mcr
33246+ * #include patches and Makefiles for post-reorg compilation.
33247+ *
33248+ * Revision 1.9 2002/04/24 07:36:28 mcr
33249+ * Moved from ./klips/net/ipsec/ipsec_proc.c,v
33250+ *
33251+ * Revision 1.8 2002/01/29 17:17:55 mcr
33252+ * moved include of ipsec_param.h to after include of linux/kernel.h
33253+ * otherwise, it seems that some option that is set in ipsec_param.h
33254+ * screws up something subtle in the include path to kernel.h, and
33255+ * it complains on the snprintf() prototype.
33256+ *
33257+ * Revision 1.7 2002/01/29 04:00:52 mcr
33258+ * more excise of kversions.h header.
33259+ *
33260+ * Revision 1.6 2002/01/29 02:13:17 mcr
33261+ * introduction of ipsec_kversion.h means that include of
33262+ * ipsec_param.h must preceed any decisions about what files to
33263+ * include to deal with differences in kernel source.
33264+ *
33265+ * Revision 1.5 2002/01/12 02:54:30 mcr
33266+ * beginnings of /proc/net/ipsec dir.
33267+ *
33268+ * Revision 1.4 2001/12/11 02:21:05 rgb
33269+ * Don't include module version here, fixing 2.2 compile bug.
33270+ *
33271+ * Revision 1.3 2001/12/05 07:19:44 rgb
33272+ * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
33273+ *
33274+ * Revision 1.2 2001/11/26 09:16:14 rgb
33275+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
33276+ *
33277+ * Revision 1.74 2001/11/22 05:44:11 henry
33278+ * new version stuff
33279+ *
33280+ * Revision 1.1.2.1 2001/09/25 02:19:40 mcr
33281+ * /proc manipulation code moved to new ipsec_proc.c
33282+ *
33283+ *
33284+ * Local variables:
33285+ * c-file-style: "linux"
33286+ * End:
33287+ *
33288+ */
33289--- /dev/null Tue Mar 11 13:02:56 2003
33290+++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004
33291@@ -0,0 +1,889 @@
33292+/*
33293+ * Interface between the IPSEC code and the radix (radij) tree code
33294+ * Copyright (C) 1996, 1997 John Ioannidis.
33295+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
33296+ *
33297+ * This program is free software; you can redistribute it and/or modify it
33298+ * under the terms of the GNU General Public License as published by the
33299+ * Free Software Foundation; either version 2 of the License, or (at your
33300+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
33301+ *
33302+ * This program is distributed in the hope that it will be useful, but
33303+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
33304+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33305+ * for more details.
33306+ *
33307+ * RCSID $Id: ipsec_radij.c,v 1.73.2.1 2006/10/06 21:39:26 paul Exp $
33308+ */
33309+
33310+#ifndef AUTOCONF_INCLUDED
33311+#include <linux/config.h>
33312+#endif
33313+#include <linux/version.h>
33314+#include <linux/kernel.h> /* printk() */
33315+
33316+#include "openswan/ipsec_param.h"
33317+
33318+#ifdef MALLOC_SLAB
33319+# include <linux/slab.h> /* kmalloc() */
33320+#else /* MALLOC_SLAB */
33321+# include <linux/malloc.h> /* kmalloc() */
33322+#endif /* MALLOC_SLAB */
33323+#include <linux/errno.h> /* error codes */
33324+#include <linux/types.h> /* size_t */
33325+#include <linux/interrupt.h> /* mark_bh */
33326+
33327+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
33328+#include <linux/etherdevice.h> /* eth_type_trans */
33329+#include <linux/ip.h> /* struct iphdr */
33330+#include <linux/skbuff.h>
33331+#include <openswan.h>
33332+#ifdef SPINLOCK
33333+# ifdef SPINLOCK_23
33334+# include <linux/spinlock.h> /* *lock* */
33335+# else /* 23_SPINLOCK */
33336+# include <asm/spinlock.h> /* *lock* */
33337+# endif /* 23_SPINLOCK */
33338+#endif /* SPINLOCK */
33339+
33340+#include <net/ip.h>
33341+
33342+#include "openswan/ipsec_eroute.h"
33343+#include "openswan/ipsec_sa.h"
33344+
33345+#include "openswan/radij.h"
33346+#include "openswan/ipsec_encap.h"
33347+#include "openswan/radij.h"
33348+#include "openswan/ipsec_encap.h"
33349+#include "openswan/ipsec_radij.h"
33350+#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */
33351+#include "openswan/ipsec_xform.h"
33352+
33353+#include <pfkeyv2.h>
33354+#include <pfkey.h>
33355+
33356+#include "openswan/ipsec_proto.h"
33357+
33358+#ifdef CONFIG_KLIPS_DEBUG
33359+int debug_radij = 0;
33360+#endif /* CONFIG_KLIPS_DEBUG */
33361+
33362+struct radij_node_head *rnh = NULL;
33363+#ifdef SPINLOCK
33364+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
33365+#else /* SPINLOCK */
33366+spinlock_t eroute_lock;
33367+#endif /* SPINLOCK */
33368+
33369+int
33370+ipsec_radijinit(void)
33371+{
33372+ maj_keylen = sizeof (struct sockaddr_encap);
33373+
33374+ rj_init();
33375+
33376+ if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
33377+ return -1;
33378+ return 0;
33379+}
33380+
33381+int
33382+ipsec_radijcleanup(void)
33383+{
33384+ int error;
33385+
33386+ spin_lock_bh(&eroute_lock);
33387+
33388+ error = radijcleanup();
33389+
33390+ spin_unlock_bh(&eroute_lock);
33391+
33392+ return error;
33393+}
33394+
33395+int
33396+ipsec_cleareroutes(void)
33397+{
33398+ int error;
33399+
33400+ spin_lock_bh(&eroute_lock);
33401+
33402+ error = radijcleartree();
33403+
33404+ spin_unlock_bh(&eroute_lock);
33405+
33406+ return error;
33407+}
33408+
33409+int
33410+ipsec_breakroute(struct sockaddr_encap *eaddr,
33411+ struct sockaddr_encap *emask,
33412+ struct sk_buff **first,
33413+ struct sk_buff **last)
33414+{
33415+ struct eroute *ro;
33416+ struct radij_node *rn;
33417+ int error;
33418+#ifdef CONFIG_KLIPS_DEBUG
33419+
33420+ if (debug_eroute) {
33421+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33422+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33423+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33424+ KLIPS_PRINT(debug_eroute,
33425+ "klips_debug:ipsec_breakroute: "
33426+ "attempting to delete eroute for %s:%d->%s:%d %d\n",
33427+ buf1, ntohs(eaddr->sen_sport),
33428+ buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
33429+ }
33430+#endif /* CONFIG_KLIPS_DEBUG */
33431+
33432+ spin_lock_bh(&eroute_lock);
33433+
33434+ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
33435+ spin_unlock_bh(&eroute_lock);
33436+ KLIPS_PRINT(debug_eroute,
33437+ "klips_debug:ipsec_breakroute: "
33438+ "node not found, eroute delete failed.\n");
33439+ return error;
33440+ }
33441+
33442+ spin_unlock_bh(&eroute_lock);
33443+
33444+ ro = (struct eroute *)rn;
33445+
33446+ KLIPS_PRINT(debug_eroute,
33447+ "klips_debug:ipsec_breakroute: "
33448+ "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
33449+ ro,
33450+ ro->er_ident_s.data,
33451+ ro->er_ident_d.data,
33452+ ro->er_first,
33453+ ro->er_last);
33454+
33455+ if (ro->er_ident_s.data != NULL) {
33456+ kfree(ro->er_ident_s.data);
33457+ }
33458+ if (ro->er_ident_d.data != NULL) {
33459+ kfree(ro->er_ident_d.data);
33460+ }
33461+ if (ro->er_first != NULL) {
33462+#if 0
33463+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
33464+ stats->tx_dropped--;
33465+#endif
33466+ *first = ro->er_first;
33467+ }
33468+ if (ro->er_last != NULL) {
33469+#if 0
33470+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
33471+ stats->tx_dropped--;
33472+#endif
33473+ *last = ro->er_last;
33474+ }
33475+
33476+ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
33477+ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
33478+ memset((caddr_t)rn, 0, sizeof (struct eroute));
33479+ kfree(rn);
33480+
33481+ return 0;
33482+}
33483+
33484+int
33485+ipsec_makeroute(struct sockaddr_encap *eaddr,
33486+ struct sockaddr_encap *emask,
33487+ ip_said said,
33488+ uint32_t pid,
33489+ struct sk_buff *skb,
33490+ struct ident *ident_s,
33491+ struct ident *ident_d)
33492+{
33493+ struct eroute *retrt;
33494+ int error;
33495+ char sa[SATOT_BUF];
33496+ size_t sa_len;
33497+
33498+#ifdef CONFIG_KLIPS_DEBUG
33499+
33500+ if (debug_eroute) {
33501+
33502+ {
33503+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33504+
33505+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33506+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33507+ sa_len = satot(&said, 0, sa, sizeof(sa));
33508+ KLIPS_PRINT(debug_eroute,
33509+ "klips_debug:ipsec_makeroute: "
33510+ "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
33511+ (unsigned long) sizeof(struct eroute),
33512+ buf1,
33513+ buf2,
33514+ sa_len ? sa : " (error)",
33515+ pid,
33516+ skb,
33517+ (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
33518+ (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
33519+ }
33520+ {
33521+ char buf1[sizeof(struct sockaddr_encap)*2 + 1],
33522+ buf2[sizeof(struct sockaddr_encap)*2 + 1];
33523+ int i;
33524+ unsigned char *b1 = buf1,
33525+ *b2 = buf2,
33526+ *ea = (unsigned char *)eaddr,
33527+ *em = (unsigned char *)emask;
33528+
33529+
33530+ for (i=0; i<sizeof(struct sockaddr_encap); i++) {
33531+ sprintf(b1, "%02x", ea[i]);
33532+ sprintf(b2, "%02x", em[i]);
33533+ b1+=2;
33534+ b2+=2;
33535+ }
33536+ KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
33537+ }
33538+
33539+ }
33540+#endif /* CONFIG_KLIPS_DEBUG */
33541+
33542+ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
33543+ if (retrt == NULL) {
33544+ printk("klips_error:ipsec_makeroute: "
33545+ "not able to allocate kernel memory");
33546+ return -ENOMEM;
33547+ }
33548+ memset((caddr_t)retrt, 0, sizeof (struct eroute));
33549+
33550+ retrt->er_eaddr = *eaddr;
33551+ retrt->er_emask = *emask;
33552+ retrt->er_said = said;
33553+ retrt->er_pid = pid;
33554+ retrt->er_count = 0;
33555+ retrt->er_lasttime = jiffies/HZ;
33556+
33557+ {
33558+ /* this is because gcc 3. doesn't like cast's as lvalues */
33559+ struct rjtentry *rje = (struct rjtentry *)&(retrt->er_rjt);
33560+ caddr_t er = (caddr_t)&(retrt->er_eaddr);
33561+
33562+ rje->rd_nodes->rj_key= er;
33563+ }
33564+
33565+ if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
33566+ int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33567+
33568+ retrt->er_ident_s.type = ident_s->type;
33569+ retrt->er_ident_s.id = ident_s->id;
33570+ retrt->er_ident_s.len = ident_s->len;
33571+ if(data_len) {
33572+ KLIPS_PRINT(debug_eroute,
33573+ "klips_debug:ipsec_makeroute: "
33574+ "attempting to allocate %u bytes for ident_s.\n",
33575+ data_len);
33576+ if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
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_s.data, ident_s->data, data_len);
33582+ } else {
33583+ retrt->er_ident_s.data = NULL;
33584+ }
33585+ }
33586+
33587+ if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
33588+ int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33589+
33590+ retrt->er_ident_d.type = ident_d->type;
33591+ retrt->er_ident_d.id = ident_d->id;
33592+ retrt->er_ident_d.len = ident_d->len;
33593+ if(data_len) {
33594+ KLIPS_PRINT(debug_eroute,
33595+ "klips_debug:ipsec_makeroute: "
33596+ "attempting to allocate %u bytes for ident_d.\n",
33597+ data_len);
33598+ if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
33599+ if (retrt->er_ident_s.data)
33600+ kfree(retrt->er_ident_s.data);
33601+ kfree(retrt);
33602+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33603+ return ENOMEM;
33604+ }
33605+ memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
33606+ } else {
33607+ retrt->er_ident_d.data = NULL;
33608+ }
33609+ }
33610+ retrt->er_first = skb;
33611+ retrt->er_last = NULL;
33612+
33613+ KLIPS_PRINT(debug_eroute,
33614+ "klips_debug:ipsec_makeroute: "
33615+ "calling rj_addroute now\n");
33616+
33617+ spin_lock_bh(&eroute_lock);
33618+
33619+ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
33620+ rnh, retrt->er_rjt.rd_nodes);
33621+
33622+ spin_unlock_bh(&eroute_lock);
33623+
33624+ if(error) {
33625+ sa_len = satot(&said, 0, sa, sizeof(sa));
33626+ KLIPS_PRINT(debug_eroute,
33627+ "klips_debug:ipsec_makeroute: "
33628+ "rj_addroute not able to insert eroute for SA:%s (error:%d)\n",
33629+ sa_len ? sa : " (error)", error);
33630+ if (retrt->er_ident_s.data)
33631+ kfree(retrt->er_ident_s.data);
33632+ if (retrt->er_ident_d.data)
33633+ kfree(retrt->er_ident_d.data);
33634+
33635+ kfree(retrt);
33636+
33637+ return error;
33638+ }
33639+
33640+#ifdef CONFIG_KLIPS_DEBUG
33641+ if (debug_eroute) {
33642+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33643+/*
33644+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33645+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33646+*/
33647+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
33648+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
33649+ sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa));
33650+
33651+ KLIPS_PRINT(debug_eroute,
33652+ "klips_debug:ipsec_makeroute: "
33653+ "pid=%05d "
33654+ "count=%10d "
33655+ "lasttime=%6d "
33656+ "%-18s -> %-18s => %s\n",
33657+ retrt->er_pid,
33658+ retrt->er_count,
33659+ (int)(jiffies/HZ - retrt->er_lasttime),
33660+ buf1,
33661+ buf2,
33662+ sa_len ? sa : " (error)");
33663+ }
33664+#endif /* CONFIG_KLIPS_DEBUG */
33665+ KLIPS_PRINT(debug_eroute,
33666+ "klips_debug:ipsec_makeroute: "
33667+ "succeeded.\n");
33668+ return 0;
33669+}
33670+
33671+struct eroute *
33672+ipsec_findroute(struct sockaddr_encap *eaddr)
33673+{
33674+ struct radij_node *rn;
33675+#ifdef CONFIG_KLIPS_DEBUG
33676+ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
33677+
33678+ if (debug_radij & DB_RJ_FINDROUTE) {
33679+ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
33680+ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
33681+ KLIPS_PRINT(debug_eroute,
33682+ "klips_debug:ipsec_findroute: "
33683+ "%s:%d->%s:%d %d\n",
33684+ buf1, ntohs(eaddr->sen_sport),
33685+ buf2, ntohs(eaddr->sen_dport),
33686+ eaddr->sen_proto);
33687+ }
33688+#endif /* CONFIG_KLIPS_DEBUG */
33689+ rn = rj_match((caddr_t)eaddr, rnh);
33690+ if(rn) {
33691+ KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
33692+ "klips_debug:ipsec_findroute: "
33693+ "found, points to proto=%d, spi=%x, dst=%x.\n",
33694+ ((struct eroute*)rn)->er_said.proto,
33695+ ntohl(((struct eroute*)rn)->er_said.spi),
33696+ ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr));
33697+ }
33698+ return (struct eroute *)rn;
33699+}
33700+
33701+#ifdef CONFIG_PROC_FS
33702+/** ipsec_rj_walker_procprint: print one line of eroute table output.
33703+ *
33704+ * Theoretical BUG: if w->length is less than the length
33705+ * of some line we should produce, that line will never
33706+ * be finished. In effect, the "file" will stop part way
33707+ * through that line.
33708+ */
33709+int
33710+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
33711+{
33712+ struct eroute *ro = (struct eroute *)rn;
33713+ struct rjtentry *rd = (struct rjtentry *)rn;
33714+ struct wsbuf *w = (struct wsbuf *)w0;
33715+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33716+ char buf3[16];
33717+ char sa[SATOT_BUF];
33718+ size_t sa_len, buf_len;
33719+ struct sockaddr_encap *key, *mask;
33720+
33721+ KLIPS_PRINT(debug_radij,
33722+ "klips_debug:ipsec_rj_walker_procprint: "
33723+ "rn=0p%p, w0=0p%p\n",
33724+ rn,
33725+ w0);
33726+ if (rn->rj_b >= 0) {
33727+ return 0;
33728+ }
33729+
33730+ key = rd_key(rd);
33731+ mask = rd_mask(rd);
33732+
33733+ if (key == NULL || mask == NULL) {
33734+ return 0;
33735+ }
33736+
33737+ buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33738+ if(key->sen_sport != 0) {
33739+ sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
33740+ }
33741+
33742+ buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33743+ if(key->sen_dport != 0) {
33744+ sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
33745+ }
33746+
33747+ buf3[0]='\0';
33748+ if(key->sen_proto != 0) {
33749+ sprintf(buf3, ":%d", key->sen_proto);
33750+ }
33751+
33752+ sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa));
33753+ w->len += ipsec_snprintf(w->buffer + w->len,
33754+ w->length - w->len,
33755+ "%-10d "
33756+ "%-18s -> %-18s => %s%s\n",
33757+ ro->er_count,
33758+ buf1,
33759+ buf2,
33760+ sa_len ? sa : " (error)",
33761+ buf3);
33762+
33763+ {
33764+ /* snprintf can only fill the last character with NUL
33765+ * so the maximum useful character is w->length-1.
33766+ * However, if w->length == 0, we cannot go back.
33767+ * (w->length surely cannot be negative.)
33768+ */
33769+ int max_content = w->length > 0? w->length-1 : 0;
33770+
33771+ if (w->len >= max_content) {
33772+ /* we've done all that can fit -- stop treewalking */
33773+ w->len = max_content; /* truncate crap */
33774+ return -ENOBUFS;
33775+ } else {
33776+ const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
33777+
33778+ if (pos <= w->offset) {
33779+ /* all is before first interesting character:
33780+ * discard, but note where we are.
33781+ */
33782+ w->len = 0;
33783+ w->begin = pos;
33784+ }
33785+ return 0;
33786+ }
33787+ }
33788+}
33789+#endif /* CONFIG_PROC_FS */
33790+
33791+int
33792+ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
33793+{
33794+ struct eroute *ro;
33795+ struct rjtentry *rd = (struct rjtentry *)rn;
33796+ struct radij_node *rn2;
33797+ int error;
33798+ struct sockaddr_encap *key, *mask;
33799+
33800+ key = rd_key(rd);
33801+ mask = rd_mask(rd);
33802+
33803+ if(!key || !mask) {
33804+ return -ENODATA;
33805+ }
33806+#ifdef CONFIG_KLIPS_DEBUG
33807+ if(debug_radij) {
33808+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33809+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33810+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33811+ KLIPS_PRINT(debug_radij,
33812+ "klips_debug:ipsec_rj_walker_delete: "
33813+ "deleting: %s -> %s\n",
33814+ buf1,
33815+ buf2);
33816+ }
33817+#endif /* CONFIG_KLIPS_DEBUG */
33818+
33819+ if((error = rj_delete(key, mask, rnh, &rn2))) {
33820+ KLIPS_PRINT(debug_radij,
33821+ "klips_debug:ipsec_rj_walker_delete: "
33822+ "rj_delete failed with error=%d.\n", error);
33823+ return error;
33824+ }
33825+
33826+ if(rn2 != rn) {
33827+ printk("klips_debug:ipsec_rj_walker_delete: "
33828+ "tried to delete a different node?!? This should never happen!\n");
33829+ }
33830+
33831+ ro = (struct eroute *)rn;
33832+
33833+ if (ro->er_ident_s.data)
33834+ kfree(ro->er_ident_s.data);
33835+ if (ro->er_ident_d.data)
33836+ kfree(ro->er_ident_d.data);
33837+
33838+ memset((caddr_t)rn, 0, sizeof (struct eroute));
33839+ kfree(rn);
33840+
33841+ return 0;
33842+}
33843+
33844+/*
33845+ * $Log: ipsec_radij.c,v $
33846+ * Revision 1.73.2.1 2006/10/06 21:39:26 paul
33847+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
33848+ * set. This is defined through autoconf.h which is included through the
33849+ * linux kernel build macros.
33850+ *
33851+ * Revision 1.73 2005/04/29 05:10:22 mcr
33852+ * removed from extraenous includes to make unit testing easier.
33853+ *
33854+ * Revision 1.72 2004/12/03 21:25:57 mcr
33855+ * compile time fixes for running on 2.6.
33856+ * still experimental.
33857+ *
33858+ * Revision 1.71 2004/07/10 19:11:18 mcr
33859+ * CONFIG_IPSEC -> CONFIG_KLIPS.
33860+ *
33861+ * Revision 1.70 2004/04/25 21:10:52 ken
33862+ * Pull in dhr's changes from FreeS/WAN 2.06
33863+ *
33864+ * Revision 1.69 2004/04/06 02:49:26 mcr
33865+ * pullup of algo code from alg-branch.
33866+ *
33867+ * Revision 1.68 2004/03/28 20:27:20 paul
33868+ * Included tested and confirmed fixes mcr made and dhr verified for
33869+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
33870+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
33871+ * dhr. (thanks dhr!)
33872+ *
33873+ * Revision 1.67.4.1 2004/04/05 04:30:46 mcr
33874+ * patches for alg-branch to compile/work with 2.x openswan
33875+ *
33876+ * Revision 1.67 2003/10/31 02:27:55 mcr
33877+ * pulled up port-selector patches and sa_id elimination.
33878+ *
33879+ * Revision 1.66.24.2 2003/10/29 01:30:41 mcr
33880+ * elimited "struct sa_id".
33881+ *
33882+ * Revision 1.66.24.1 2003/09/21 13:59:56 mcr
33883+ * pre-liminary X.509 patch - does not yet pass tests.
33884+ *
33885+ * Revision 1.66 2002/10/12 23:11:53 dhr
33886+ *
33887+ * [KenB + DHR] more 64-bit cleanup
33888+ *
33889+ * Revision 1.65 2002/09/20 05:01:40 rgb
33890+ * Added memory allocation debugging.
33891+ *
33892+ * Revision 1.64 2002/05/31 01:46:05 mcr
33893+ * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute
33894+ * as requested in PR#14.
33895+ *
33896+ * Revision 1.63 2002/05/23 07:14:11 rgb
33897+ * Cleaned up %p variants to 0p%p for test suite cleanup.
33898+ *
33899+ * Revision 1.62 2002/04/24 07:55:32 mcr
33900+ * #include patches and Makefiles for post-reorg compilation.
33901+ *
33902+ * Revision 1.61 2002/04/24 07:36:29 mcr
33903+ * Moved from ./klips/net/ipsec/ipsec_radij.c,v
33904+ *
33905+ * Revision 1.60 2002/02/19 23:59:45 rgb
33906+ * Removed redundant compiler directives.
33907+ *
33908+ * Revision 1.59 2002/02/06 04:13:47 mcr
33909+ * missing #ifdef CONFIG_IPSEC_DEBUG.
33910+ *
33911+ * Revision 1.58 2002/01/29 17:17:56 mcr
33912+ * moved include of ipsec_param.h to after include of linux/kernel.h
33913+ * otherwise, it seems that some option that is set in ipsec_param.h
33914+ * screws up something subtle in the include path to kernel.h, and
33915+ * it complains on the snprintf() prototype.
33916+ *
33917+ * Revision 1.57 2002/01/29 04:00:52 mcr
33918+ * more excise of kversions.h header.
33919+ *
33920+ * Revision 1.56 2002/01/29 02:13:17 mcr
33921+ * introduction of ipsec_kversion.h means that include of
33922+ * ipsec_param.h must preceed any decisions about what files to
33923+ * include to deal with differences in kernel source.
33924+ *
33925+ * Revision 1.55 2001/11/26 09:23:48 rgb
33926+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
33927+ *
33928+ * Revision 1.53.2.1 2001/09/25 02:26:32 mcr
33929+ * headers adjusted for new usage.
33930+ *
33931+ * Revision 1.54 2001/10/18 04:45:20 rgb
33932+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
33933+ * lib/freeswan.h version macros moved to lib/kversions.h.
33934+ * Other compiler directive cleanups.
33935+ *
33936+ * Revision 1.53 2001/09/19 17:19:40 rgb
33937+ * Debug output bugfix for NetCelo's PF_KEY ident patch.
33938+ *
33939+ * Revision 1.52 2001/09/19 16:33:37 rgb
33940+ * Temporarily disable ident fields to /proc/net/ipsec_eroute.
33941+ *
33942+ * Revision 1.51 2001/09/15 16:24:04 rgb
33943+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
33944+ *
33945+ * Revision 1.50 2001/09/14 16:58:36 rgb
33946+ * Added support for storing the first and last packets through a HOLD.
33947+ *
33948+ * Revision 1.49 2001/09/08 21:13:32 rgb
33949+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
33950+ *
33951+ * Revision 1.48 2001/06/15 04:12:56 rgb
33952+ * Fixed kernel memory allocation error return code polarity bug.
33953+ *
33954+ * Revision 1.47 2001/06/14 19:35:09 rgb
33955+ * Update copyright date.
33956+ *
33957+ * Revision 1.46 2001/06/08 08:47:18 rgb
33958+ * Fixed for debug disabled.
33959+ *
33960+ * Revision 1.45 2001/05/27 06:12:11 rgb
33961+ * Added structures for pid, packet count and last access time to eroute.
33962+ * Added packet count to beginning of /proc/net/ipsec_eroute.
33963+ *
33964+ * Revision 1.44 2001/05/03 19:41:01 rgb
33965+ * Initialise error return variable.
33966+ * Use more appropriate return value for ipsec_rj_walker_delete().
33967+ *
33968+ * Revision 1.43 2001/02/27 22:24:54 rgb
33969+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
33970+ * Check for satoa() return codes.
33971+ *
33972+ * Revision 1.42 2001/02/27 06:21:57 rgb
33973+ * Added findroute success instrumentation.
33974+ *
33975+ * Revision 1.41 2000/11/06 04:32:08 rgb
33976+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
33977+ *
33978+ * Revision 1.40 2000/09/08 19:12:56 rgb
33979+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
33980+ *
33981+ * Revision 1.39 2000/08/30 05:25:20 rgb
33982+ * Correct debug text in ipsec_breakroute() from incorrect
33983+ * "ipsec_callback".
33984+ *
33985+ * Revision 1.38 2000/07/28 14:58:31 rgb
33986+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
33987+ *
33988+ * Revision 1.37 2000/03/16 14:02:50 rgb
33989+ * Fixed debug scope to enable compilation with debug off.
33990+ *
33991+ * Revision 1.36 2000/01/21 06:14:46 rgb
33992+ * Added debugging text to ipsec_rj_walker_delete().
33993+ * Set return code to negative for consistency.
33994+ *
33995+ * Revision 1.35 1999/11/23 23:05:24 rgb
33996+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
33997+ *
33998+ * Revision 1.34 1999/11/18 04:13:56 rgb
33999+ * Replaced all kernel version macros to shorter, readable form.
34000+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
34001+ *
34002+ * Revision 1.33 1999/11/17 15:53:39 rgb
34003+ * Changed all occurrences of #include "../../../lib/freeswan.h"
34004+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
34005+ * klips/net/ipsec/Makefile.
34006+ *
34007+ * Revision 1.32 1999/10/26 13:58:33 rgb
34008+ * Put spinlock flags variable declaration outside the debug compiler
34009+ * directive to enable compilation with debug shut off.
34010+ *
34011+ * Revision 1.31 1999/10/15 22:13:29 rgb
34012+ * Clean out cruft.
34013+ * Align /proc/net/ipsec_eroute output for easier readability.
34014+ * Fix double linefeed in radij debug output.
34015+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
34016+ *
34017+ * Revision 1.30 1999/10/08 18:37:33 rgb
34018+ * Fix end-of-line spacing to sate whining PHMs.
34019+ *
34020+ * Revision 1.29 1999/10/03 18:52:45 rgb
34021+ * Spinlock support for 2.0.xx.
34022+ * Dumb return code spin_unlock fix.
34023+ *
34024+ * Revision 1.28 1999/10/01 16:22:24 rgb
34025+ * Switch from assignment init. to functional init. of spinlocks.
34026+ *
34027+ * Revision 1.27 1999/10/01 15:44:53 rgb
34028+ * Move spinlock header include to 2.1> scope.
34029+ *
34030+ * Revision 1.26 1999/10/01 00:01:23 rgb
34031+ * Added eroute structure locking.
34032+ *
34033+ * Revision 1.25 1999/06/10 16:07:30 rgb
34034+ * Silence delete eroute on no debug.
34035+ *
34036+ * Revision 1.24 1999/05/09 03:25:36 rgb
34037+ * Fix bug introduced by 2.2 quick-and-dirty patch.
34038+ *
34039+ * Revision 1.23 1999/05/05 22:02:31 rgb
34040+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
34041+ *
34042+ * Revision 1.22 1999/04/29 15:17:23 rgb
34043+ * Add return values to init and cleanup functions.
34044+ * Add sanity checking for null pointer arguments.
34045+ *
34046+ * Revision 1.21 1999/04/11 00:28:58 henry
34047+ * GPL boilerplate
34048+ *
34049+ * Revision 1.20 1999/04/06 04:54:26 rgb
34050+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
34051+ * patch shell fixes.
34052+ *
34053+ * Revision 1.19 1999/02/17 16:50:35 rgb
34054+ * Clean out unused cruft.
34055+ * Consolidate for space and speed efficiency.
34056+ * Convert DEBUG_IPSEC to KLIPS_PRINT
34057+ *
34058+ * Revision 1.18 1999/01/22 06:22:06 rgb
34059+ * Cruft clean-out.
34060+ * 64-bit clean-up.
34061+ *
34062+ * Revision 1.17 1998/12/02 03:09:39 rgb
34063+ * Clean up debug printing conditionals to compile with debugging off.
34064+ *
34065+ * Revision 1.16 1998/12/01 13:49:39 rgb
34066+ * Wrap version info printing in debug switches.
34067+ *
34068+ * Revision 1.15 1998/11/30 13:22:54 rgb
34069+ * Rationalised all the klips kernel file headers. They are much shorter
34070+ * now and won't conflict under RH5.2.
34071+ *
34072+ * Revision 1.14 1998/10/31 06:48:17 rgb
34073+ * Fixed up comments in #endif directives.
34074+ *
34075+ * Revision 1.13 1998/10/27 13:48:09 rgb
34076+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
34077+ * Fixed less(1) truncated output bug.
34078+ * Code clean-up.
34079+ *
34080+ * Revision 1.12 1998/10/25 02:41:36 rgb
34081+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
34082+ * argument to be able to transmit more infomation about errors.
34083+ * Fix cut-and-paste debug statement identifier.
34084+ *
34085+ * Revision 1.11 1998/10/22 06:45:39 rgb
34086+ * Cleaned up cruft.
34087+ * Convert to use satoa for printk.
34088+ *
34089+ * Revision 1.10 1998/10/19 14:44:28 rgb
34090+ * Added inclusion of freeswan.h.
34091+ * sa_id structure implemented and used: now includes protocol.
34092+ *
34093+ * Revision 1.9 1998/10/09 04:30:52 rgb
34094+ * Added 'klips_debug' prefix to all klips printk debug statements.
34095+ * Deleted old commented out cruft.
34096+ *
34097+ * Revision 1.8 1998/08/06 17:24:23 rgb
34098+ * Fix addrtoa return code bug from stale manpage advice preventing packets
34099+ * from being erouted.
34100+ *
34101+ * Revision 1.7 1998/08/06 07:44:59 rgb
34102+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
34103+ * ended up in nothing being printed.
34104+ *
34105+ * Revision 1.6 1998/08/05 22:16:41 rgb
34106+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
34107+ *
34108+ * Revision 1.5 1998/07/29 20:38:44 rgb
34109+ * Debug and fix subnettoa and addrtoa output.
34110+ *
34111+ * Revision 1.4 1998/07/28 00:02:39 rgb
34112+ * Converting to exclusive use of addrtoa.
34113+ * Fix eroute delete.
34114+ *
34115+ * Revision 1.3 1998/07/14 18:21:26 rgb
34116+ * Add function to clear the eroute table.
34117+ *
34118+ * Revision 1.2 1998/06/23 02:59:14 rgb
34119+ * Added debugging output to eroute add/delete routines.
34120+ *
34121+ * Revision 1.9 1998/06/18 21:29:06 henry
34122+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
34123+ * build scripts happier in presence of symbolic links
34124+ *
34125+ * Revision 1.8 1998/06/05 02:32:26 rgb
34126+ * Fix spi ntoh kernel debug output.
34127+ *
34128+ * Revision 1.7 1998/05/25 20:30:37 rgb
34129+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
34130+ *
34131+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
34132+ * add ipsec_rj_walker_delete.
34133+ *
34134+ * Revision 1.6 1998/05/21 13:08:57 rgb
34135+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
34136+ * information is available for printout.
34137+ *
34138+ * Revision 1.5 1998/05/18 21:35:55 rgb
34139+ * Clean up output for numerical consistency and readability. Zero freed
34140+ * eroute memory.
34141+ *
34142+ * Revision 1.4 1998/04/21 21:28:58 rgb
34143+ * Rearrange debug switches to change on the fly debug output from user
34144+ * space. Only kernel changes checked in at this time. radij.c was also
34145+ * changed to temporarily remove buggy debugging code in rj_delete causing
34146+ * an OOPS and hence, netlink device open errors.
34147+ *
34148+ * Revision 1.3 1998/04/14 17:30:39 rgb
34149+ * Fix up compiling errors for radij tree memory reclamation.
34150+ *
34151+ * Revision 1.2 1998/04/12 22:03:23 rgb
34152+ * Updated ESP-3DES-HMAC-MD5-96,
34153+ * ESP-DES-HMAC-MD5-96,
34154+ * AH-HMAC-MD5-96,
34155+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
34156+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
34157+ *
34158+ * Fixed eroute references in /proc/net/ipsec*.
34159+ *
34160+ * Started to patch module unloading memory leaks in ipsec_netlink and
34161+ * radij tree unloading.
34162+ *
34163+ * Revision 1.1 1998/04/09 03:06:10 henry
34164+ * sources moved up from linux/net/ipsec
34165+ *
34166+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
34167+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
34168+ *
34169+ * Revision 0.4 1997/01/15 01:28:15 ji
34170+ * No changes.
34171+ *
34172+ * Revision 0.3 1996/11/20 14:39:04 ji
34173+ * Minor cleanups.
34174+ * Rationalized debugging code.
34175+ *
34176+ * Revision 0.2 1996/11/02 00:18:33 ji
34177+ * First limited release.
34178+ *
34179+ *
34180+ */
34181--- /dev/null Tue Mar 11 13:02:56 2003
34182+++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004
34183@@ -0,0 +1,2317 @@
34184+/*
34185+ * receive code
34186+ * Copyright (C) 1996, 1997 John Ioannidis.
34187+ * Copyright (C) 1998-2003 Richard Guy Briggs.
34188+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
34189+ *
34190+ * This program is free software; you can redistribute it and/or modify it
34191+ * under the terms of the GNU General Public License as published by the
34192+ * Free Software Foundation; either version 2 of the License, or (at your
34193+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
34194+ *
34195+ * This program is distributed in the hope that it will be useful, but
34196+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
34197+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34198+ * for more details.
34199+ */
34200+
34201+char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.171.2.11 2007/04/28 20:46:40 paul Exp $";
34202+
34203+#ifndef AUTOCONF_INCLUDED
34204+#include <linux/config.h>
34205+#endif
34206+#include <linux/version.h>
34207+
34208+#define __NO_VERSION__
34209+#include <linux/module.h>
34210+#include <linux/kernel.h> /* printk() */
34211+
34212+#include "openswan/ipsec_param.h"
34213+
34214+#ifdef MALLOC_SLAB
34215+# include <linux/slab.h> /* kmalloc() */
34216+#else /* MALLOC_SLAB */
34217+# include <linux/malloc.h> /* kmalloc() */
34218+#endif /* MALLOC_SLAB */
34219+#include <linux/errno.h> /* error codes */
34220+#include <linux/types.h> /* size_t */
34221+#include <linux/interrupt.h> /* mark_bh */
34222+
34223+#include <linux/netdevice.h> /* struct device, and other headers */
34224+#include <linux/etherdevice.h> /* eth_type_trans */
34225+#include <linux/ip.h> /* struct iphdr */
34226+
34227+#include <net/tcp.h>
34228+#include <net/udp.h>
34229+#include <linux/skbuff.h>
34230+#include <openswan.h>
34231+#ifdef SPINLOCK
34232+# ifdef SPINLOCK_23
34233+# include <linux/spinlock.h> /* *lock* */
34234+# else /* SPINLOCK_23 */
34235+# include <asm/spinlock.h> /* *lock* */
34236+# endif /* SPINLOCK_23 */
34237+#endif /* SPINLOCK */
34238+
34239+#include <net/ip.h>
34240+
34241+#include "openswan/ipsec_kern24.h"
34242+#include "openswan/radij.h"
34243+#include "openswan/ipsec_encap.h"
34244+#include "openswan/ipsec_sa.h"
34245+
34246+#include "openswan/ipsec_radij.h"
34247+#include "openswan/ipsec_xform.h"
34248+#include "openswan/ipsec_tunnel.h"
34249+#include "openswan/ipsec_rcv.h"
34250+
34251+#include "openswan/ipsec_auth.h"
34252+
34253+#include "openswan/ipsec_esp.h"
34254+
34255+#ifdef CONFIG_KLIPS_AH
34256+#include "openswan/ipsec_ah.h"
34257+#endif /* CONFIG_KLIPS_AH */
34258+
34259+#ifdef CONFIG_KLIPS_IPCOMP
34260+#include "openswan/ipsec_ipcomp.h"
34261+#endif /* CONFIG_KLIPS_COMP */
34262+
34263+#include <pfkeyv2.h>
34264+#include <pfkey.h>
34265+
34266+#include "openswan/ipsec_proto.h"
34267+#include "openswan/ipsec_alg.h"
34268+#include "openswan/ipsec_kern24.h"
34269+
34270+#ifdef CONFIG_KLIPS_DEBUG
34271+int debug_rcv = 0;
34272+#endif /* CONFIG_KLIPS_DEBUG */
34273+
34274+int sysctl_ipsec_inbound_policy_check = 1;
34275+
34276+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34277+#include <linux/udp.h>
34278+#endif
34279+
34280+/* This is a private use protocol, and AT&T should be ashamed. They should have
34281+ * used protocol # 59, which is "no next header" instead of 0xFE.
34282+ */
34283+#ifndef IPPROTO_ATT_HEARTBEAT
34284+#define IPPROTO_ATT_HEARTBEAT 0xFE
34285+#endif
34286+
34287+/*
34288+ * Check-replay-window routine, adapted from the original
34289+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
34290+ *
34291+ * This is a routine that implements a 64 packet window. This is intend-
34292+ * ed on being an implementation sample.
34293+ */
34294+
34295+DEBUG_NO_STATIC int
34296+ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
34297+{
34298+ __u32 diff;
34299+
34300+ if (ipsp->ips_replaywin == 0) /* replay shut off */
34301+ return 1;
34302+ if (seq == 0)
34303+ return 0; /* first == 0 or wrapped */
34304+
34305+ /* new larger sequence number */
34306+ if (seq > ipsp->ips_replaywin_lastseq) {
34307+ return 1; /* larger is good */
34308+ }
34309+ diff = ipsp->ips_replaywin_lastseq - seq;
34310+
34311+ /* too old or wrapped */ /* if wrapped, kill off SA? */
34312+ if (diff >= ipsp->ips_replaywin) {
34313+ return 0;
34314+ }
34315+ /* this packet already seen */
34316+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
34317+ return 0;
34318+ return 1; /* out of order but good */
34319+}
34320+
34321+DEBUG_NO_STATIC int
34322+ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
34323+{
34324+ __u32 diff;
34325+
34326+ if (ipsp->ips_replaywin == 0) /* replay shut off */
34327+ return 1;
34328+ if (seq == 0)
34329+ return 0; /* first == 0 or wrapped */
34330+
34331+ /* new larger sequence number */
34332+ if (seq > ipsp->ips_replaywin_lastseq) {
34333+ diff = seq - ipsp->ips_replaywin_lastseq;
34334+
34335+ /* In win, set bit for this pkt */
34336+ if (diff < ipsp->ips_replaywin)
34337+ ipsp->ips_replaywin_bitmap =
34338+ (ipsp->ips_replaywin_bitmap << diff) | 1;
34339+ else
34340+ /* This packet has way larger seq num */
34341+ ipsp->ips_replaywin_bitmap = 1;
34342+
34343+ if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
34344+ ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
34345+ }
34346+ ipsp->ips_replaywin_lastseq = seq;
34347+ return 1; /* larger is good */
34348+ }
34349+ diff = ipsp->ips_replaywin_lastseq - seq;
34350+
34351+ /* too old or wrapped */ /* if wrapped, kill off SA? */
34352+ if (diff >= ipsp->ips_replaywin) {
34353+/*
34354+ if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
34355+ ipsec_sa_delchain(ipsp);
34356+ }
34357+*/
34358+ return 0;
34359+ }
34360+ /* this packet already seen */
34361+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
34362+ return 0;
34363+ ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */
34364+ return 1; /* out of order but good */
34365+}
34366+
34367+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34368+struct auth_alg ipsec_rcv_md5[]={
34369+ {osMD5Init, osMD5Update, osMD5Final, AHMD596_ALEN}
34370+};
34371+
34372+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34373+
34374+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34375+struct auth_alg ipsec_rcv_sha1[]={
34376+ {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
34377+};
34378+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34379+
34380+/*
34381+ * decapsulate a single layer of the system
34382+ *
34383+ * the following things should be setup to enter this function.
34384+ *
34385+ * irs->stats == stats structure (or NULL)
34386+ * irs->ipp = IP header.
34387+ * irs->len = total length of packet
34388+ * skb->nh.iph = ipp;
34389+ * skb->h.raw = start of payload
34390+ * irs->ipsp = NULL.
34391+ * irs->iphlen = N/A = is recalculated.
34392+ * irs->ilen = 0;
34393+ * irs->authlen = 0;
34394+ * irs->authfuncs = NULL;
34395+ * irs->skb = the skb;
34396+ *
34397+ * proto_funcs should be from ipsec_esp.c, ipsec_ah.c or ipsec_ipcomp.c.
34398+ *
34399+ */
34400+enum ipsec_rcv_value
34401+ipsec_rcv_decap_once(struct ipsec_rcv_state *irs
34402+ , struct xform_functions *proto_funcs)
34403+{
34404+ int iphlen;
34405+ __u8 proto;
34406+ struct in_addr ipsaddr;
34407+ struct in_addr ipdaddr;
34408+ int replay = 0; /* replay value in AH or ESP packet */
34409+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
34410+ struct ipsec_sa *newipsp;
34411+ struct iphdr *ipp;
34412+ struct sk_buff *skb;
34413+ struct ipsec_alg_auth *ixt_a=NULL;
34414+
34415+ skb = irs->skb;
34416+ irs->len = skb->len;
34417+ ipp = irs->ipp;
34418+ proto = ipp->protocol;
34419+ ipsaddr.s_addr = ipp->saddr;
34420+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
34421+ ipdaddr.s_addr = ipp->daddr;
34422+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
34423+
34424+ iphlen = ipp->ihl << 2;
34425+ irs->iphlen=iphlen;
34426+ ipp->check = 0; /* we know the sum is good */
34427+
34428+ KLIPS_PRINT(debug_rcv,
34429+ "klips_debug:ipsec_rcv_decap_once: "
34430+ "decap (%d) from %s -> %s\n",
34431+ proto, irs->ipsaddr_txt, irs->ipdaddr_txt);
34432+
34433+ /*
34434+ * Find tunnel control block and (indirectly) call the
34435+ * appropriate tranform routine. The resulting sk_buf
34436+ * is a valid IP packet ready to go through input processing.
34437+ */
34438+
34439+ irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr;
34440+ irs->said.dst.u.v4.sin_family = AF_INET;
34441+
34442+ /* note: rcv_checks set up the said.spi value, if appropriate */
34443+ if(proto_funcs->rcv_checks) {
34444+ enum ipsec_rcv_value retval =
34445+ (*proto_funcs->rcv_checks)(irs, skb);
34446+
34447+ if(retval < 0) {
34448+ return retval;
34449+ }
34450+ }
34451+
34452+ irs->said.proto = proto;
34453+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
34454+ if(irs->sa_len == 0) {
34455+ strcpy(irs->sa, "(error)");
34456+ }
34457+
34458+ newipsp = ipsec_sa_getbyid(&irs->said);
34459+ if (newipsp == NULL) {
34460+ KLIPS_PRINT(debug_rcv,
34461+ "klips_debug:ipsec_rcv: "
34462+ "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
34463+ irs->sa_len ? irs->sa : " (error)");
34464+ if(irs->stats) {
34465+ irs->stats->rx_dropped++;
34466+ }
34467+ return IPSEC_RCV_SAIDNOTFOUND;
34468+ }
34469+
34470+ /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having
34471+ * incremented the refcount, why in the world would we decrement it
34472+ * here? */
34473+ /* ipsec_sa_put(irs->ipsp);*/ /* incomplete */
34474+
34475+ /* If it is in larval state, drop the packet, we cannot process yet. */
34476+ if(newipsp->ips_state == SADB_SASTATE_LARVAL) {
34477+ KLIPS_PRINT(debug_rcv,
34478+ "klips_debug:ipsec_rcv: "
34479+ "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
34480+ if(irs->stats) {
34481+ irs->stats->rx_dropped++;
34482+ }
34483+ ipsec_sa_put(newipsp);
34484+ return IPSEC_RCV_SAIDNOTLIVE;
34485+ }
34486+
34487+ if(newipsp->ips_state == SADB_SASTATE_DEAD) {
34488+ KLIPS_PRINT(debug_rcv,
34489+ "klips_debug:ipsec_rcv: "
34490+ "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
34491+ if(irs->stats) {
34492+ irs->stats->rx_dropped++;
34493+ }
34494+ ipsec_sa_put(newipsp);
34495+ return IPSEC_RCV_SAIDNOTLIVE;
34496+ }
34497+
34498+ if(sysctl_ipsec_inbound_policy_check) {
34499+ if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
34500+ KLIPS_PRINT(debug_rcv,
34501+ "klips_debug:ipsec_rcv: "
34502+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
34503+ irs->sa_len ? irs->sa : " (error)",
34504+ irs->ipsaddr_txt);
34505+ if(irs->stats) {
34506+ irs->stats->rx_dropped++;
34507+ }
34508+ ipsec_sa_put(newipsp);
34509+ return IPSEC_RCV_FAILEDINBOUND;
34510+ }
34511+
34512+ KLIPS_PRINT(debug_rcv,
34513+ "klips_debug:ipsec_rcv: "
34514+ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
34515+ irs->sa_len ? irs->sa : " (error)",
34516+ irs->ipsaddr_txt);
34517+
34518+ /*
34519+ * at this point, we have looked up a new SA, and we want to make sure that if this
34520+ * isn't the first SA in the list, that the previous SA actually points at this one.
34521+ */
34522+ if(irs->ipsp) {
34523+ if(irs->ipsp->ips_inext != newipsp) {
34524+ KLIPS_PRINT(debug_rcv,
34525+ "klips_debug:ipsec_rcv: "
34526+ "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
34527+ irs->sa_len ? irs->sa : " (error)");
34528+ if(irs->stats) {
34529+ irs->stats->rx_dropped++;
34530+ }
34531+ ipsec_sa_put(newipsp);
34532+ return IPSEC_RCV_FAILEDINBOUND;
34533+ }
34534+ KLIPS_PRINT(debug_rcv,
34535+ "klips_debug:ipsec_rcv: "
34536+ "SA:%s grouping from previous SA is OK.\n",
34537+ irs->sa_len ? irs->sa : " (error)");
34538+ } else {
34539+ KLIPS_PRINT(debug_rcv,
34540+ "klips_debug:ipsec_rcv: "
34541+ "SA:%s First SA in group.\n",
34542+ irs->sa_len ? irs->sa : " (error)");
34543+ }
34544+
34545+
34546+
34547+
34548+
34549+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34550+ if (proto == IPPROTO_ESP) {
34551+ KLIPS_PRINT(debug_rcv,
34552+ "klips_debug:ipsec_rcv: "
34553+ "natt_type=%u tdbp->ips_natt_type=%u : %s\n",
34554+ irs->natt_type, newipsp->ips_natt_type,
34555+ (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad");
34556+ if (irs->natt_type != newipsp->ips_natt_type) {
34557+ KLIPS_PRINT(debug_rcv,
34558+ "klips_debug:ipsec_rcv: "
34559+ "SA:%s does not agree with expected NAT-T policy.\n",
34560+ irs->sa_len ? irs->sa : " (error)");
34561+ if(irs->stats) {
34562+ irs->stats->rx_dropped++;
34563+ }
34564+ ipsec_sa_put(newipsp);
34565+ return IPSEC_RCV_FAILEDINBOUND;
34566+ }
34567+ }
34568+#endif
34569+ }
34570+
34571+ /* okay, SA checks out, so free any previous SA, and record a new one*/
34572+
34573+ if(irs->ipsp) {
34574+ ipsec_sa_put(irs->ipsp);
34575+ }
34576+ irs->ipsp=newipsp;
34577+
34578+ /* note that the outer code will free the irs->ipsp
34579+ if there is an error */
34580+
34581+
34582+ /* now check the lifetimes */
34583+ if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes",
34584+ irs->sa, ipsec_life_countbased, ipsec_incoming,
34585+ irs->ipsp) == ipsec_life_harddied ||
34586+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",
34587+ irs->sa, ipsec_life_timebased, ipsec_incoming,
34588+ irs->ipsp) == ipsec_life_harddied ||
34589+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",
34590+ irs->sa, ipsec_life_timebased, ipsec_incoming,
34591+ irs->ipsp) == ipsec_life_harddied ||
34592+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",
34593+ irs->sa, ipsec_life_countbased, ipsec_incoming,
34594+ irs->ipsp) == ipsec_life_harddied) {
34595+ ipsec_sa_delchain(irs->ipsp);
34596+ if(irs->stats) {
34597+ irs->stats->rx_dropped++;
34598+ }
34599+
34600+ KLIPS_PRINT(debug_rcv,
34601+ "klips_debug:ipsec_rcv_decap_once: "
34602+ "decap (%d) failed lifetime check\n",
34603+ proto);
34604+
34605+ return IPSEC_RCV_LIFETIMEFAILED;
34606+ }
34607+
34608+#if 0
34609+ /*
34610+ * This is removed for some reasons:
34611+ * 1) it needs to happen *after* authentication.
34612+ * 2) do we really care, if it authenticates, if it came
34613+ * from the wrong location?
34614+ * 3) the NAT_KA messages in IKE will also get to pluto
34615+ * and it will figure out that stuff has moved.
34616+ * 4) the 2.6 udp-esp encap function does not pass us
34617+ * the originating port number, and I can't tell
34618+ * if skb->sk is guaranteed to be valid here.
34619+ * 2005-04-16: mcr@xelerance.com
34620+ */
34621+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34622+ /*
34623+ *
34624+ * XXX we should ONLY update pluto if the SA passes all checks,
34625+ * which we clearly do not now.
34626+ */
34627+ if ((irs->natt_type) &&
34628+ ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) ||
34629+ (irs->natt_sport != newipsp->ips_natt_sport)
34630+ )) {
34631+ struct sockaddr sipaddr;
34632+ struct sockaddr_in *psin = (struct sockaddr_in*)(newipsp->ips_addr_s);
34633+
34634+ /** Advertise NAT-T addr change to pluto **/
34635+ sipaddr.sa_family = AF_INET;
34636+ ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr;
34637+ ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport);
34638+ pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport);
34639+
34640+ /**
34641+ * Then allow or block packet depending on
34642+ * sysctl_ipsec_inbound_policy_check.
34643+ *
34644+ * In all cases, pluto will update SA if new mapping is
34645+ * accepted.
34646+ */
34647+ if (sysctl_ipsec_inbound_policy_check) {
34648+ KLIPS_PRINT(debug_rcv,
34649+ "klips_debug:ipsec_rcv: "
34650+ "SA:%s, src=%s:%u of pkt does not agree with expected "
34651+ "SA source address [%08x:%u] (notifying pluto of change).\n",
34652+ irs->sa_len ? irs->sa : " (error)",
34653+ irs->ipsaddr_txt, irs->natt_sport,
34654+ psin->sin_addr.s_addr,
34655+ newipsp->ips_natt_sport);
34656+ if(irs->stats) {
34657+ irs->stats->rx_dropped++;
34658+ }
34659+ ipsec_sa_put(newipsp);
34660+ return IPSEC_RCV_FAILEDINBOUND;
34661+ }
34662+ }
34663+#endif
34664+#endif
34665+
34666+ irs->authfuncs=NULL;
34667+
34668+ /* authenticate, if required */
34669+ if ((ixt_a=irs->ipsp->ips_alg_auth)) {
34670+ irs->authlen = AHHMAC_HASHLEN;
34671+ irs->authfuncs = NULL;
34672+ irs->ictx = NULL;
34673+ irs->octx = NULL;
34674+ irs->ictx_len = 0;
34675+ irs->octx_len = 0;
34676+ KLIPS_PRINT(debug_rcv,
34677+ "klips_debug:ipsec_rcv: "
34678+ "authalg=%d authlen=%d\n",
34679+ irs->ipsp->ips_authalg,
34680+ irs->authlen);
34681+ } else
34682+ switch(irs->ipsp->ips_authalg) {
34683+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34684+ case AH_MD5:
34685+ irs->authlen = AHHMAC_HASHLEN;
34686+ irs->authfuncs = ipsec_rcv_md5;
34687+ irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
34688+ irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
34689+ irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
34690+ irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
34691+ break;
34692+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34693+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34694+ case AH_SHA:
34695+ irs->authlen = AHHMAC_HASHLEN;
34696+ irs->authfuncs = ipsec_rcv_sha1;
34697+ irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
34698+ irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
34699+ irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
34700+ irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
34701+ break;
34702+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
34703+ case AH_NONE:
34704+ irs->authlen = 0;
34705+ irs->authfuncs = NULL;
34706+ irs->ictx = NULL;
34707+ irs->octx = NULL;
34708+ irs->ictx_len = 0;
34709+ irs->octx_len = 0;
34710+ break;
34711+ default:
34712+ irs->ipsp->ips_errs.ips_alg_errs += 1;
34713+ if(irs->stats) {
34714+ irs->stats->rx_errors++;
34715+ }
34716+ return IPSEC_RCV_BADAUTH;
34717+ }
34718+
34719+ /* ilen counts number of bytes in ESP portion */
34720+ irs->ilen = ((skb->data + skb->len) - skb->h.raw) - irs->authlen;
34721+ if(irs->ilen <= 0) {
34722+ KLIPS_PRINT(debug_rcv,
34723+ "klips_debug:ipsec_rcv: "
34724+ "runt %s packet with no data, dropping.\n",
34725+ (proto == IPPROTO_ESP ? "esp" : "ah"));
34726+ if(irs->stats) {
34727+ irs->stats->rx_dropped++;
34728+ }
34729+ return IPSEC_RCV_BADLEN;
34730+ }
34731+
34732+ if(irs->authfuncs || ixt_a) {
34733+ unsigned char *authenticator = NULL;
34734+
34735+ if(proto_funcs->rcv_setup_auth) {
34736+ enum ipsec_rcv_value retval
34737+ = (*proto_funcs->rcv_setup_auth)(irs, skb,
34738+ &replay,
34739+ &authenticator);
34740+ if(retval < 0) {
34741+ return retval;
34742+ }
34743+ }
34744+
34745+ if(!authenticator) {
34746+ irs->ipsp->ips_errs.ips_auth_errs += 1;
34747+ if(irs->stats) {
34748+ irs->stats->rx_dropped++;
34749+ }
34750+ return IPSEC_RCV_BADAUTH;
34751+ }
34752+
34753+ if(!ipsec_checkreplaywindow(irs->ipsp, replay)) {
34754+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34755+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34756+ "klips_debug:ipsec_rcv: "
34757+ "duplicate frame from %s, packet dropped\n",
34758+ irs->ipsaddr_txt);
34759+ if(irs->stats) {
34760+ irs->stats->rx_dropped++;
34761+ }
34762+ return IPSEC_RCV_REPLAYFAILED;
34763+ }
34764+
34765+ /*
34766+ * verify authenticator
34767+ */
34768+
34769+ KLIPS_PRINT(debug_rcv,
34770+ "klips_debug:ipsec_rcv: "
34771+ "encalg = %d, authalg = %d.\n",
34772+ irs->ipsp->ips_encalg,
34773+ irs->ipsp->ips_authalg);
34774+
34775+ /* calculate authenticator */
34776+ if(proto_funcs->rcv_calc_auth == NULL) {
34777+ return IPSEC_RCV_BADAUTH;
34778+ }
34779+ (*proto_funcs->rcv_calc_auth)(irs, skb);
34780+
34781+ if (memcmp(irs->hash, authenticator, irs->authlen)) {
34782+ irs->ipsp->ips_errs.ips_auth_errs += 1;
34783+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
34784+ "klips_debug:ipsec_rcv: "
34785+ "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
34786+ irs->ipsaddr_txt,
34787+ ntohl(*(__u32*)&irs->hash[0]),
34788+ ntohl(*(__u32*)&irs->hash[4]),
34789+ ntohl(*(__u32*)&irs->hash[8]),
34790+ ntohl(*(__u32*)authenticator),
34791+ ntohl(*((__u32*)authenticator + 1)),
34792+ ntohl(*((__u32*)authenticator + 2)));
34793+ if(irs->stats) {
34794+ irs->stats->rx_dropped++;
34795+ }
34796+ return IPSEC_RCV_AUTHFAILED;
34797+ } else {
34798+ KLIPS_PRINT(debug_rcv,
34799+ "klips_debug:ipsec_rcv: "
34800+ "authentication successful.\n");
34801+ }
34802+
34803+ /* Crypto hygiene: clear memory used to calculate autheticator.
34804+ * The length varies with the algorithm.
34805+ */
34806+ memset(irs->hash, 0, irs->authlen);
34807+
34808+ /* If the sequence number == 0, expire SA, it had rolled */
34809+ if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) {
34810+ ipsec_sa_delchain(irs->ipsp);
34811+ KLIPS_PRINT(debug_rcv,
34812+ "klips_debug:ipsec_rcv: "
34813+ "replay window counter rolled, expiring SA.\n");
34814+ if(irs->stats) {
34815+ irs->stats->rx_dropped++;
34816+ }
34817+ return IPSEC_RCV_REPLAYROLLED;
34818+ }
34819+
34820+ /* now update the replay counter */
34821+ if (!ipsec_updatereplaywindow(irs->ipsp, replay)) {
34822+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34823+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34824+ "klips_debug:ipsec_rcv: "
34825+ "duplicate frame from %s, packet dropped\n",
34826+ irs->ipsaddr_txt);
34827+ if(irs->stats) {
34828+ irs->stats->rx_dropped++;
34829+ }
34830+ return IPSEC_RCV_REPLAYROLLED;
34831+ }
34832+ }
34833+
34834+ if(proto_funcs->rcv_decrypt) {
34835+ enum ipsec_rcv_value retval =
34836+ (*proto_funcs->rcv_decrypt)(irs);
34837+
34838+ if(retval != IPSEC_RCV_OK) {
34839+ return retval;
34840+ }
34841+ }
34842+
34843+ /*
34844+ * Adjust pointers
34845+ */
34846+ skb = irs->skb;
34847+ irs->len = skb->len;
34848+ ipp = irs->ipp = skb->nh.iph;
34849+ iphlen = ipp->ihl<<2;
34850+ skb->h.raw = skb->nh.raw + iphlen;
34851+
34852+ /* zero any options that there might be */
34853+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
34854+
34855+ ipsaddr.s_addr = ipp->saddr;
34856+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
34857+ ipdaddr.s_addr = ipp->daddr;
34858+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
34859+
34860+ /*
34861+ * Discard the original ESP/AH header
34862+ */
34863+ ipp->protocol = irs->next_header;
34864+
34865+ ipp->check = 0; /* NOTE: this will be included in checksum */
34866+ ipp->check = ip_fast_csum((unsigned char *)skb->nh.iph, iphlen >> 2);
34867+
34868+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34869+ "klips_debug:ipsec_rcv: "
34870+ "after <%s%s%s>, SA:%s:\n",
34871+ IPS_XFORM_NAME(irs->ipsp),
34872+ irs->sa_len ? irs->sa : " (error)");
34873+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
34874+
34875+ skb->protocol = htons(ETH_P_IP);
34876+ skb->ip_summed = 0;
34877+
34878+ ipsnext = irs->ipsp->ips_inext;
34879+ if(sysctl_ipsec_inbound_policy_check) {
34880+ if(ipsnext) {
34881+ if(
34882+ ipp->protocol != IPPROTO_AH
34883+ && ipp->protocol != IPPROTO_ESP
34884+#ifdef CONFIG_KLIPS_IPCOMP
34885+ && ipp->protocol != IPPROTO_COMP
34886+ && (ipsnext->ips_said.proto != IPPROTO_COMP
34887+ || ipsnext->ips_inext)
34888+#endif /* CONFIG_KLIPS_IPCOMP */
34889+ && ipp->protocol != IPPROTO_IPIP
34890+ && ipp->protocol != IPPROTO_ATT_HEARTBEAT /* heartbeats to AT&T SIG/GIG */
34891+ ) {
34892+ KLIPS_PRINT(debug_rcv,
34893+ "klips_debug:ipsec_rcv: "
34894+ "packet with incomplete policy dropped, last successful SA:%s.\n",
34895+ irs->sa_len ? irs->sa : " (error)");
34896+ if(irs->stats) {
34897+ irs->stats->rx_dropped++;
34898+ }
34899+ return IPSEC_RCV_FAILEDINBOUND;
34900+ }
34901+ KLIPS_PRINT(debug_rcv,
34902+ "klips_debug:ipsec_rcv: "
34903+ "SA:%s, Another IPSEC header to process.\n",
34904+ irs->sa_len ? irs->sa : " (error)");
34905+ } else {
34906+ KLIPS_PRINT(debug_rcv,
34907+ "klips_debug:ipsec_rcv: "
34908+ "No ips_inext from this SA:%s.\n",
34909+ irs->sa_len ? irs->sa : " (error)");
34910+ }
34911+ }
34912+
34913+#ifdef CONFIG_KLIPS_IPCOMP
34914+ /* update ipcomp ratio counters, even if no ipcomp packet is present */
34915+ if (ipsnext
34916+ && ipsnext->ips_said.proto == IPPROTO_COMP
34917+ && ipp->protocol != IPPROTO_COMP) {
34918+ ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
34919+ ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
34920+ }
34921+#endif /* CONFIG_KLIPS_IPCOMP */
34922+
34923+ irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
34924+ irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len;
34925+
34926+ if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
34927+ irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
34928+ }
34929+ irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
34930+ irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
34931+
34932+#ifdef CONFIG_NETFILTER
34933+ if(proto == IPPROTO_ESP || proto == IPPROTO_AH) {
34934+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
34935+ | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
34936+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34937+ "klips_debug:ipsec_rcv: "
34938+ "%s SA sets skb->nfmark=0x%x.\n",
34939+ proto == IPPROTO_ESP ? "ESP" : "AH",
34940+ (unsigned)skb->nfmark);
34941+ }
34942+#endif /* CONFIG_NETFILTER */
34943+
34944+ return IPSEC_RCV_OK;
34945+}
34946+
34947+
34948+/*
34949+ * core decapsulation loop for all protocols.
34950+ *
34951+ * the following things should be setup to enter this function.
34952+ *
34953+ * irs->stats == stats structure (or NULL)
34954+ * irs->ipp = IP header.
34955+ * irs->ipsp = NULL.
34956+ * irs->ilen = 0;
34957+ * irs->authlen = 0;
34958+ * irs->authfuncs = NULL;
34959+ * irs->skb = skb;
34960+ * skb->nh.iph = ipp;
34961+ * skb->h.raw = start of payload
34962+ *
34963+ */
34964+int ipsec_rcv_decap(struct ipsec_rcv_state *irs)
34965+{
34966+ struct ipsec_sa *ipsp = NULL;
34967+ struct ipsec_sa* ipsnext = NULL;
34968+ struct in_addr ipsaddr;
34969+ struct in_addr ipdaddr;
34970+ struct iphdr *ipp;
34971+ struct sk_buff *skb = NULL;
34972+
34973+ /* begin decapsulating loop here */
34974+
34975+ /*
34976+ The spinlock is to prevent any other process from
34977+ accessing or deleting the ipsec_sa hash table or any of the
34978+ ipsec_sa s while we are using and updating them.
34979+
34980+ This is not optimal, but was relatively straightforward
34981+ at the time. A better way to do it has been planned for
34982+ more than a year, to lock the hash table and put reference
34983+ counts on each ipsec_sa instead. This is not likely to happen
34984+ in KLIPS1 unless a volunteer contributes it, but will be
34985+ designed into KLIPS2.
34986+ */
34987+ spin_lock(&tdb_lock);
34988+
34989+ do {
34990+ int decap_stat;
34991+ struct xform_functions *proto_funcs;
34992+
34993+ switch(irs->ipp->protocol) {
34994+ case IPPROTO_ESP:
34995+ proto_funcs = esp_xform_funcs;
34996+ break;
34997+
34998+#ifdef CONFIG_KLIPS_AH
34999+ case IPPROTO_AH:
35000+ proto_funcs = ah_xform_funcs;
35001+ break;
35002+#endif /* !CONFIG_KLIPS_AH */
35003+
35004+#ifdef CONFIG_KLIPS_IPCOMP
35005+ case IPPROTO_COMP:
35006+ proto_funcs = ipcomp_xform_funcs;
35007+ break;
35008+#endif /* !CONFIG_KLIPS_IPCOMP */
35009+ default:
35010+ if(irs->stats) {
35011+ irs->stats->rx_errors++;
35012+ }
35013+ decap_stat = IPSEC_RCV_BADPROTO;
35014+ goto rcvleave;
35015+ }
35016+
35017+ decap_stat = ipsec_rcv_decap_once(irs, proto_funcs);
35018+
35019+ if(decap_stat != IPSEC_RCV_OK) {
35020+ spin_unlock(&tdb_lock);
35021+ KLIPS_PRINT(debug_rcv,
35022+ "klips_debug:ipsec_rcv: decap_once failed: %d\n",
35023+ decap_stat);
35024+
35025+ goto rcvleave;
35026+ }
35027+ /* end decapsulation loop here */
35028+ } while( (irs->ipp->protocol == IPPROTO_ESP )
35029+ || (irs->ipp->protocol == IPPROTO_AH )
35030+#ifdef CONFIG_KLIPS_IPCOMP
35031+ || (irs->ipp->protocol == IPPROTO_COMP)
35032+#endif /* CONFIG_KLIPS_IPCOMP */
35033+ );
35034+
35035+ /* set up for decap loop */
35036+ ipp =irs->ipp;
35037+ ipsp =irs->ipsp;
35038+ ipsnext = ipsp->ips_inext;
35039+ skb = irs->skb;
35040+
35041+ /* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
35042+ * then we can just skip it
35043+ */
35044+#ifdef CONFIG_KLIPS_IPCOMP
35045+ if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) {
35046+ ipsp = ipsnext;
35047+ ipsnext = ipsp->ips_inext;
35048+ }
35049+#endif /* CONFIG_KLIPS_IPCOMP */
35050+
35051+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35052+ if ((irs->natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
35053+ /**
35054+ * NAT-Traversal and Transport Mode:
35055+ * we need to correct TCP/UDP checksum
35056+ *
35057+ * If we've got NAT-OA, we can fix checksum without recalculation.
35058+ */
35059+ __u32 natt_oa = ipsp->ips_natt_oa ?
35060+ ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
35061+ __u16 pkt_len = skb->tail - (unsigned char *)ipp;
35062+ __u16 data_len = pkt_len - (ipp->ihl << 2);
35063+
35064+ switch (ipp->protocol) {
35065+ case IPPROTO_TCP:
35066+ if (data_len >= sizeof(struct tcphdr)) {
35067+ struct tcphdr *tcp = skb->h.th;
35068+ if (natt_oa) {
35069+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
35070+ KLIPS_PRINT(debug_rcv,
35071+ "klips_debug:ipsec_rcv: "
35072+ "NAT-T & TRANSPORT: "
35073+ "fix TCP checksum using NAT-OA\n");
35074+ tcp->check = csum_fold(
35075+ csum_partial((unsigned char *)buff, sizeof(buff),
35076+ tcp->check^0xffff));
35077+ }
35078+ else {
35079+ KLIPS_PRINT(debug_rcv,
35080+ "klips_debug:ipsec_rcv: "
35081+ "NAT-T & TRANSPORT: recalc TCP checksum\n");
35082+ if (pkt_len > (ntohs(ipp->tot_len)))
35083+ data_len -= (pkt_len - ntohs(ipp->tot_len));
35084+ tcp->check = 0;
35085+ tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr,
35086+ data_len, IPPROTO_TCP,
35087+ csum_partial((unsigned char *)tcp, data_len, 0));
35088+ }
35089+ }
35090+ else {
35091+ KLIPS_PRINT(debug_rcv,
35092+ "klips_debug:ipsec_rcv: "
35093+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
35094+ }
35095+ break;
35096+ case IPPROTO_UDP:
35097+ if (data_len >= sizeof(struct udphdr)) {
35098+ struct udphdr *udp = skb->h.uh;
35099+ if (udp->check == 0) {
35100+ KLIPS_PRINT(debug_rcv,
35101+ "klips_debug:ipsec_rcv: "
35102+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
35103+ }
35104+ else if (natt_oa) {
35105+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
35106+ KLIPS_PRINT(debug_rcv,
35107+ "klips_debug:ipsec_rcv: "
35108+ "NAT-T & TRANSPORT: "
35109+ "fix UDP checksum using NAT-OA\n");
35110+#ifdef DISABLE_UDP_CHECKSUM
35111+ udp->check=0
35112+ KLIPS_PRINT(debug_rcv,
35113+ "klips_debug:ipsec_rcv: "
35114+ "NAT-T & TRANSPORT: "
35115+ "UDP checksum using NAT-OA disabled at compile time\n");
35116+#else
35117+ udp->check = csum_fold(
35118+ csum_partial((unsigned char *)buff, sizeof(buff),
35119+ udp->check^0xffff));
35120+#endif
35121+ }
35122+ else {
35123+ KLIPS_PRINT(debug_rcv,
35124+ "klips_debug:ipsec_rcv: "
35125+ "NAT-T & TRANSPORT: zero UDP checksum\n");
35126+ udp->check = 0;
35127+ }
35128+ }
35129+ else {
35130+ KLIPS_PRINT(debug_rcv,
35131+ "klips_debug:ipsec_rcv: "
35132+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
35133+ }
35134+ break;
35135+ default:
35136+ KLIPS_PRINT(debug_rcv,
35137+ "klips_debug:ipsec_rcv: "
35138+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
35139+ break;
35140+ }
35141+ }
35142+#endif
35143+
35144+ /*
35145+ * XXX this needs to be locked from when it was first looked
35146+ * up in the decapsulation loop. Perhaps it is better to put
35147+ * the IPIP decap inside the loop.
35148+ */
35149+ if(ipsnext) {
35150+ ipsp = ipsnext;
35151+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
35152+ if((ipp->protocol != IPPROTO_IPIP) &&
35153+ (ipp->protocol != IPPROTO_ATT_HEARTBEAT)) { /* AT&T heartbeats to SIG/GIG */
35154+ spin_unlock(&tdb_lock);
35155+ KLIPS_PRINT(debug_rcv,
35156+ "klips_debug:ipsec_rcv: "
35157+ "SA:%s, Hey! How did this get through? Dropped.\n",
35158+ irs->sa_len ? irs->sa : " (error)");
35159+ if(irs->stats) {
35160+ irs->stats->rx_dropped++;
35161+ }
35162+ goto rcvleave;
35163+ }
35164+ if(sysctl_ipsec_inbound_policy_check) {
35165+ struct sockaddr_in *psin = (struct sockaddr_in*)(ipsp->ips_addr_s);
35166+ if((ipsnext = ipsp->ips_inext)) {
35167+ char sa2[SATOT_BUF];
35168+ size_t sa_len2;
35169+ sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2));
35170+ spin_unlock(&tdb_lock);
35171+ KLIPS_PRINT(debug_rcv,
35172+ "klips_debug:ipsec_rcv: "
35173+ "unexpected SA:%s after IPIP SA:%s\n",
35174+ sa_len2 ? sa2 : " (error)",
35175+ irs->sa_len ? irs->sa : " (error)");
35176+ if(irs->stats) {
35177+ irs->stats->rx_dropped++;
35178+ }
35179+ goto rcvleave;
35180+ }
35181+ if(ipp->saddr != psin->sin_addr.s_addr) {
35182+ spin_unlock(&tdb_lock);
35183+ KLIPS_PRINT(debug_rcv,
35184+ "klips_debug:ipsec_rcv: "
35185+ "SA:%s, src=%s(%08x) does match expected 0x%08x.\n",
35186+ irs->sa_len ? irs->sa : " (error)",
35187+ irs->ipsaddr_txt,
35188+ ipp->saddr, psin->sin_addr.s_addr);
35189+ if(irs->stats) {
35190+ irs->stats->rx_dropped++;
35191+ }
35192+ goto rcvleave;
35193+ }
35194+ }
35195+
35196+ if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */
35197+ {
35198+ /*
35199+ * XXX this needs to be locked from when it was first looked
35200+ * up in the decapsulation loop. Perhaps it is better to put
35201+ * the IPIP decap inside the loop.
35202+ */
35203+ ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
35204+ ipsp->ips_life.ipl_bytes.ipl_last = skb->len;
35205+
35206+ if(!ipsp->ips_life.ipl_usetime.ipl_count) {
35207+ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
35208+ }
35209+ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
35210+ ipsp->ips_life.ipl_packets.ipl_count += 1;
35211+
35212+ if(skb->len < irs->iphlen) {
35213+ spin_unlock(&tdb_lock);
35214+ printk(KERN_WARNING "klips_debug:ipsec_rcv: "
35215+ "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n",
35216+ irs->iphlen,
35217+ (int)(skb->len));
35218+
35219+ goto rcvleave;
35220+ }
35221+
35222+ /*
35223+ * we need to pull up by size of IP header,
35224+ * options, but also by any UDP/ESP encap there might
35225+ * have been, and this deals with all cases.
35226+ */
35227+ skb_pull(skb, (skb->h.raw - skb->nh.raw));
35228+
35229+ /* new L3 header is where L4 payload was */
35230+ skb->nh.raw = skb->h.raw;
35231+
35232+ /* now setup new L4 payload location */
35233+ ipp = (struct iphdr *)skb->nh.raw;
35234+ skb->h.raw = skb->nh.raw + (ipp->ihl << 2);
35235+
35236+
35237+ /* remove any saved options that we might have,
35238+ * since we have a new IP header.
35239+ */
35240+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
35241+
35242+#if 0
35243+ KLIPS_PRINT(debug_rcv, "csum: %d\n", ip_fast_csum((u8 *)ipp, ipp->ihl));
35244+#endif
35245+
35246+ /* re-do any strings for debugging */
35247+ ipsaddr.s_addr = ipp->saddr;
35248+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
35249+ ipdaddr.s_addr = ipp->daddr;
35250+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
35251+
35252+ skb->protocol = htons(ETH_P_IP);
35253+ skb->ip_summed = 0;
35254+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35255+ "klips_debug:ipsec_rcv: "
35256+ "IPIP tunnel stripped.\n");
35257+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
35258+ }
35259+
35260+ if(sysctl_ipsec_inbound_policy_check
35261+ /*
35262+ Note: "xor" (^) logically replaces "not equal"
35263+ (!=) and "bitwise or" (|) logically replaces
35264+ "boolean or" (||). This is done to speed up
35265+ execution by doing only bitwise operations and
35266+ no branch operations
35267+ */
35268+ && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
35269+ ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
35270+ | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
35271+ ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
35272+ {
35273+ char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
35274+
35275+ subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
35276+ ipsp->ips_mask_s.u.v4.sin_addr,
35277+ 0, sflow_txt, sizeof(sflow_txt));
35278+ subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
35279+ ipsp->ips_mask_d.u.v4.sin_addr,
35280+ 0, dflow_txt, sizeof(dflow_txt));
35281+ spin_unlock(&tdb_lock);
35282+ KLIPS_PRINT(debug_rcv,
35283+ "klips_debug:ipsec_rcv: "
35284+ "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
35285+ irs->sa_len ? irs->sa : " (error)",
35286+ sflow_txt,
35287+ dflow_txt,
35288+ irs->ipsaddr_txt,
35289+ irs->ipdaddr_txt);
35290+ if(irs->stats) {
35291+ irs->stats->rx_dropped++;
35292+ }
35293+ goto rcvleave;
35294+ }
35295+#ifdef CONFIG_NETFILTER
35296+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
35297+ | IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
35298+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35299+ "klips_debug:ipsec_rcv: "
35300+ "IPIP SA sets skb->nfmark=0x%x.\n",
35301+ (unsigned)skb->nfmark);
35302+#endif /* CONFIG_NETFILTER */
35303+ }
35304+
35305+ spin_unlock(&tdb_lock);
35306+
35307+ if(irs->stats) {
35308+ irs->stats->rx_bytes += skb->len;
35309+ }
35310+ if(skb->dst) {
35311+ dst_release(skb->dst);
35312+ skb->dst = NULL;
35313+ }
35314+ skb->pkt_type = PACKET_HOST;
35315+ if(irs->hard_header_len &&
35316+ (skb->mac.raw != (skb->nh.raw - irs->hard_header_len)) &&
35317+ (irs->hard_header_len <= skb_headroom(skb))) {
35318+ /* copy back original MAC header */
35319+ memmove(skb->nh.raw - irs->hard_header_len,
35320+ skb->mac.raw, irs->hard_header_len);
35321+ skb->mac.raw = skb->nh.raw - irs->hard_header_len;
35322+ }
35323+
35324+#ifdef CONFIG_KLIPS_IPCOMP
35325+ if(ipp->protocol == IPPROTO_COMP) {
35326+ unsigned int flags = 0;
35327+
35328+ if(sysctl_ipsec_inbound_policy_check) {
35329+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35330+ "klips_debug:ipsec_rcv: "
35331+ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
35332+ if (irs->stats) {
35333+ irs->stats->rx_errors++;
35334+ }
35335+ goto rcvleave;
35336+ }
35337+ /*
35338+ XXX need a ipsec_sa for updating ratio counters but it is not
35339+ following policy anyways so it is not a priority
35340+ */
35341+ skb = skb_decompress(skb, NULL, &flags);
35342+ if (!skb || flags) {
35343+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35344+ "klips_debug:ipsec_rcv: "
35345+ "skb_decompress() returned error flags: %d, dropped.\n",
35346+ flags);
35347+ if (irs->stats) {
35348+ irs->stats->rx_errors++;
35349+ }
35350+ goto rcvleave;
35351+ }
35352+ }
35353+#endif /* CONFIG_KLIPS_IPCOMP */
35354+
35355+ /*
35356+ * make sure that data now starts at IP header, since we are going
35357+ * to pass this back to ip_input (aka netif_rx). Rules for what the
35358+ * pointers wind up a different for 2.6 vs 2.4, so we just fudge it here.
35359+ */
35360+#ifdef NET_26
35361+ skb->data = skb_push(skb, skb->h.raw - skb->nh.raw);
35362+#else
35363+ skb->data = skb->nh.raw;
35364+ {
35365+ struct iphdr *iph = skb->nh.iph;
35366+ int len = ntohs(iph->tot_len);
35367+ skb->len = len;
35368+ }
35369+#endif
35370+
35371+#ifdef SKB_RESET_NFCT
35372+ nf_conntrack_put(skb->nfct);
35373+ skb->nfct = NULL;
35374+#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
35375+ skb->nf_debug = 0;
35376+#endif /* CONFIG_NETFILTER_DEBUG */
35377+#endif /* SKB_RESET_NFCT */
35378+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35379+ "klips_debug:ipsec_rcv: "
35380+ "netif_rx() called.\n");
35381+ netif_rx(skb);
35382+ skb=NULL;
35383+
35384+ rcvleave:
35385+ if(skb) {
35386+ ipsec_kfree_skb(skb);
35387+ }
35388+
35389+ /* KLIPS_DEC_USE; Artifact from refactor? bug # 454 */
35390+ return(0);
35391+}
35392+
35393+struct sk_buff *ipsec_rcv_unclone(struct sk_buff *skb,
35394+ struct ipsec_rcv_state *irs)
35395+{
35396+ /* if skb was cloned (most likely due to a packet sniffer such as
35397+ tcpdump being momentarily attached to the interface), make
35398+ a copy of our own to modify */
35399+ if(skb_cloned(skb)) {
35400+ /* include any mac header while copying.. */
35401+ if(skb_headroom(skb) < irs->hard_header_len) {
35402+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
35403+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
35404+ irs->hard_header_len,
35405+ skb_headroom(skb));
35406+ goto rcvleave;
35407+ }
35408+ skb_push(skb, irs->hard_header_len);
35409+ if
35410+#ifdef SKB_COW_NEW
35411+ (skb_cow(skb, skb_headroom(skb)) != 0)
35412+#else /* SKB_COW_NEW */
35413+ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
35414+#endif /* SKB_COW_NEW */
35415+ {
35416+ goto rcvleave;
35417+ }
35418+ if(skb->len < irs->hard_header_len) {
35419+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
35420+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
35421+ irs->hard_header_len,
35422+ skb->len);
35423+ goto rcvleave;
35424+ }
35425+ skb_pull(skb, irs->hard_header_len);
35426+ }
35427+ return skb;
35428+
35429+rcvleave:
35430+ ipsec_kfree_skb(skb);
35431+ return NULL;
35432+}
35433+
35434+
35435+#if !defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
35436+/*
35437+ * decapsulate a UDP encapsulated ESP packet
35438+ */
35439+struct sk_buff *ipsec_rcv_natt_decap(struct sk_buff *skb
35440+ , struct ipsec_rcv_state *irs
35441+ , int *udp_decap_ret_p)
35442+{
35443+ *udp_decap_ret_p = 0;
35444+ if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) {
35445+ /**
35446+ * Packet comes from udp_queue_rcv_skb so it is already defrag,
35447+ * checksum verified, ... (ie safe to use)
35448+ *
35449+ * If the packet is not for us, return -1 and udp_queue_rcv_skb
35450+ * will continue to handle it (do not kfree skb !!).
35451+ */
35452+
35453+#ifndef UDP_OPT_IN_SOCK
35454+ struct udp_opt {
35455+ __u32 esp_in_udp;
35456+ };
35457+ struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);
35458+#else
35459+ struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp);
35460+#endif
35461+
35462+ struct iphdr *ip = (struct iphdr *)skb->nh.iph;
35463+ struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
35464+ __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
35465+ __u32 *udpdata32 = (__u32 *)udpdata;
35466+
35467+ irs->natt_sport = ntohs(udp->source);
35468+ irs->natt_dport = ntohs(udp->dest);
35469+
35470+ KLIPS_PRINT(debug_rcv,
35471+ "klips_debug:ipsec_rcv: "
35472+ "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
35473+ tp->esp_in_udp);
35474+ KLIPS_IP_PRINT(debug_rcv, ip);
35475+
35476+ if (udpdata < skb->tail) {
35477+ unsigned int len = skb->tail - udpdata;
35478+ if ((len==1) && (udpdata[0]==0xff)) {
35479+ KLIPS_PRINT(debug_rcv,
35480+ "klips_debug:ipsec_rcv: "
35481+ /* not IPv6 compliant message */
35482+ "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
35483+ *udp_decap_ret_p = 0;
35484+ return NULL;
35485+ }
35486+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
35487+ (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&
35488+ (udpdata32[0]==0) && (udpdata32[1]==0) ) {
35489+ /* ESP Packet with Non-IKE header */
35490+ KLIPS_PRINT(debug_rcv,
35491+ "klips_debug:ipsec_rcv: "
35492+ "ESPinUDP pkt with Non-IKE - spi=0x%x\n",
35493+ ntohl(udpdata32[2]));
35494+ irs->natt_type = ESPINUDP_WITH_NON_IKE;
35495+ irs->natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
35496+ }
35497+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
35498+ (len > sizeof(struct esphdr)) &&
35499+ (udpdata32[0]!=0) ) {
35500+ /* ESP Packet without Non-ESP header */
35501+ irs->natt_type = ESPINUDP_WITH_NON_ESP;
35502+ irs->natt_len = sizeof(struct udphdr);
35503+ KLIPS_PRINT(debug_rcv,
35504+ "klips_debug:ipsec_rcv: "
35505+ "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
35506+ ntohl(udpdata32[0]));
35507+ }
35508+ else {
35509+ KLIPS_PRINT(debug_rcv,
35510+ "klips_debug:ipsec_rcv: "
35511+ "IKE packet - not handled here\n");
35512+ *udp_decap_ret_p = -1;
35513+ return NULL;
35514+ }
35515+ }
35516+ else {
35517+ return NULL;
35518+ }
35519+ }
35520+ return skb;
35521+}
35522+#endif
35523+
35524+
35525+int
35526+ipsec_rcv(struct sk_buff *skb
35527+#ifndef PROTO_HANDLER_SINGLE_PARM
35528+ unsigned short xlen
35529+#endif /* PROTO_HANDLER_SINGLE_PARM */
35530+ )
35531+{
35532+#ifdef CONFIG_KLIPS_DEBUG
35533+ struct net_device *dev = skb->dev;
35534+#endif /* CONFIG_KLIPS_DEBUG */
35535+ unsigned char protoc;
35536+ struct net_device_stats *stats = NULL; /* This device's statistics */
35537+ struct net_device *ipsecdev = NULL, *prvdev;
35538+ struct ipsecpriv *prv;
35539+ struct ipsec_rcv_state nirs, *irs = &nirs;
35540+ struct iphdr *ipp;
35541+ char name[9];
35542+ int i;
35543+
35544+ /* Don't unlink in the middle of a turnaround */
35545+ KLIPS_INC_USE;
35546+
35547+ memset(&nirs, 0, sizeof(struct ipsec_rcv_state));
35548+
35549+ if (skb == NULL) {
35550+ KLIPS_PRINT(debug_rcv,
35551+ "klips_debug:ipsec_rcv: "
35552+ "NULL skb passed in.\n");
35553+ goto rcvleave;
35554+ }
35555+
35556+ if (skb->data == NULL) {
35557+ KLIPS_PRINT(debug_rcv,
35558+ "klips_debug:ipsec_rcv: "
35559+ "NULL skb->data passed in, packet is bogus, dropping.\n");
35560+ goto rcvleave;
35561+ }
35562+
35563+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35564+ {
35565+ /* NET_26 NAT-T is handled by seperate function */
35566+ struct sk_buff *nskb;
35567+ int udp_decap_ret = 0;
35568+
35569+ nskb = ipsec_rcv_natt_decap(skb, irs, &udp_decap_ret);
35570+ if(nskb == NULL) {
35571+ /* return with non-zero, because UDP.c code
35572+ * need to send it upstream.
35573+ */
35574+ if(skb && udp_decap_ret == 0) {
35575+ ipsec_kfree_skb(skb);
35576+ }
35577+ KLIPS_DEC_USE;
35578+ return(udp_decap_ret);
35579+ }
35580+ skb = nskb;
35581+ }
35582+#endif /* NAT_T */
35583+
35584+ /* dev->hard_header_len is unreliable and should not be used */
35585+ irs->hard_header_len = skb->mac.raw ? (skb->nh.raw - skb->mac.raw) : 0;
35586+ if((irs->hard_header_len < 0) || (irs->hard_header_len > skb_headroom(skb)))
35587+ irs->hard_header_len = 0;
35588+
35589+ skb = ipsec_rcv_unclone(skb, irs);
35590+ if(skb == NULL) {
35591+ goto rcvleave;
35592+ }
35593+
35594+#if IP_FRAGMENT_LINEARIZE
35595+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
35596+ not assembled automatically to save TCP from having to copy
35597+ twice.
35598+ */
35599+ if (skb_is_nonlinear(skb)) {
35600+#ifdef HAVE_NEW_SKB_LINEARIZE
35601+ if (skb_linearize_cow(skb) != 0)
35602+#else
35603+ if (skb_linearize(skb, GFP_ATOMIC) != 0)
35604+#endif
35605+ {
35606+ goto rcvleave;
35607+ }
35608+ }
35609+#endif /* IP_FRAGMENT_LINEARIZE */
35610+
35611+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35612+ if (irs->natt_len) {
35613+ /**
35614+ * Now, we are sure packet is ESPinUDP, and we have a private
35615+ * copy that has been linearized, remove natt_len bytes
35616+ * from packet and modify protocol to ESP.
35617+ */
35618+ if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph)
35619+ && ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head))
35620+ {
35621+ unsigned int _len = (unsigned char *)skb->data -
35622+ (unsigned char *)skb->nh.iph;
35623+ KLIPS_PRINT(debug_rcv,
35624+ "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
35625+ _len);
35626+ skb_push(skb, _len);
35627+ }
35628+ KLIPS_PRINT(debug_rcv,
35629+ "klips_debug:ipsec_rcv: "
35630+ "removing %d bytes from ESPinUDP packet\n", irs->natt_len);
35631+ ipp = skb->nh.iph;
35632+ irs->iphlen = ipp->ihl << 2;
35633+ ipp->tot_len = htons(ntohs(ipp->tot_len) - irs->natt_len);
35634+ if (skb->len < irs->iphlen + irs->natt_len) {
35635+ printk(KERN_WARNING
35636+ "klips_error:ipsec_rcv: "
35637+ "ESPinUDP packet is too small (%d < %d+%d). "
35638+ "This should never happen, please report.\n",
35639+ (int)(skb->len), irs->iphlen, irs->natt_len);
35640+ goto rcvleave;
35641+ }
35642+
35643+ /* advance payload pointer to point past the UDP header */
35644+ skb->h.raw = skb->h.raw + irs->natt_len;
35645+
35646+ /* modify protocol */
35647+ ipp->protocol = IPPROTO_ESP;
35648+
35649+ skb->sk = NULL;
35650+
35651+ KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);
35652+ }
35653+#endif
35654+
35655+ ipp = skb->nh.iph;
35656+
35657+ {
35658+ struct in_addr ipsaddr;
35659+ struct in_addr ipdaddr;
35660+
35661+ ipsaddr.s_addr = ipp->saddr;
35662+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt
35663+ , sizeof(irs->ipsaddr_txt));
35664+ ipdaddr.s_addr = ipp->daddr;
35665+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt
35666+ , sizeof(irs->ipdaddr_txt));
35667+ }
35668+
35669+ irs->iphlen = ipp->ihl << 2;
35670+
35671+ KLIPS_PRINT(debug_rcv,
35672+ "klips_debug:ipsec_rcv: "
35673+ "<<< Info -- ");
35674+ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
35675+ skb->dev->name ? skb->dev->name : "NULL");
35676+ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
35677+ dev->name ? dev->name : "NULL");
35678+ KLIPS_PRINTMORE(debug_rcv, "\n");
35679+
35680+ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
35681+ "klips_debug:ipsec_rcv: "
35682+ "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
35683+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
35684+ dev ? (dev->name ? dev->name : "NULL") : "NULL");
35685+
35686+ protoc = ipp->protocol;
35687+#ifndef NET_21
35688+ if((!protocol) || (protocol->protocol != protoc)) {
35689+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35690+ "klips_debug:ipsec_rcv: "
35691+ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
35692+ }
35693+#endif /* !NET_21 */
35694+
35695+ if( (protoc != IPPROTO_AH) &&
35696+#ifdef CONFIG_KLIPS_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
35697+ (protoc != IPPROTO_COMP) &&
35698+#endif /* CONFIG_KLIPS_IPCOMP */
35699+ (protoc != IPPROTO_ESP) ) {
35700+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35701+ "klips_debug:ipsec_rcv: Why the hell is someone "
35702+ "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
35703+ protoc);
35704+ goto rcvleave;
35705+ }
35706+
35707+ if(skb->dev) {
35708+ for(i = 0; i < IPSEC_NUM_IF; i++) {
35709+ sprintf(name, IPSEC_DEV_FORMAT, i);
35710+ if(!strcmp(name, skb->dev->name)) {
35711+ prv = (struct ipsecpriv *)(skb->dev->priv);
35712+ if(prv) {
35713+ stats = (struct net_device_stats *) &(prv->mystats);
35714+ }
35715+ ipsecdev = skb->dev;
35716+ KLIPS_PRINT(debug_rcv,
35717+ "klips_debug:ipsec_rcv: "
35718+ "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
35719+ break;
35720+ }
35721+ if((ipsecdev = __ipsec_dev_get(name)) == NULL) {
35722+ KLIPS_PRINT(debug_rcv,
35723+ "klips_error:ipsec_rcv: "
35724+ "device %s does not exist\n",
35725+ name);
35726+ }
35727+ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
35728+ prvdev = prv ? (struct net_device *)(prv->dev) : NULL;
35729+
35730+#if 0
35731+ KLIPS_PRINT(debug_rcv && prvdev,
35732+ "klips_debug:ipsec_rcv: "
35733+ "physical device for device %s is %s\n",
35734+ name,
35735+ prvdev->name);
35736+#endif
35737+ if(prvdev && skb->dev &&
35738+ !strcmp(prvdev->name, skb->dev->name)) {
35739+ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
35740+ skb->dev = ipsecdev;
35741+ KLIPS_PRINT(debug_rcv && prvdev,
35742+ "klips_debug:ipsec_rcv: "
35743+ "assigning packet ownership to virtual device %s from physical device %s.\n",
35744+ name, prvdev->name);
35745+ if(stats) {
35746+ stats->rx_packets++;
35747+ }
35748+ break;
35749+ }
35750+ }
35751+ } else {
35752+ KLIPS_PRINT(debug_rcv,
35753+ "klips_debug:ipsec_rcv: "
35754+ "device supplied with skb is NULL\n");
35755+ }
35756+
35757+ if(stats == NULL) {
35758+ KLIPS_PRINT((debug_rcv),
35759+ "klips_error:ipsec_rcv: "
35760+ "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",
35761+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
35762+ }
35763+
35764+ KLIPS_IP_PRINT(debug_rcv, ipp);
35765+
35766+ /* set up for decap loop */
35767+ irs->stats= stats;
35768+ irs->ipp = ipp;
35769+ irs->ipsp = NULL;
35770+ irs->ilen = 0;
35771+ irs->authlen=0;
35772+ irs->authfuncs=NULL;
35773+ irs->skb = skb;
35774+
35775+ ipsec_rcv_decap(irs);
35776+ KLIPS_DEC_USE;
35777+ return(0);
35778+
35779+ rcvleave:
35780+ if(skb) {
35781+ ipsec_kfree_skb(skb);
35782+ }
35783+ KLIPS_DEC_USE;
35784+ return(0);
35785+
35786+}
35787+
35788+#ifdef NET_26
35789+/*
35790+ * this entry point is not a protocol entry point, so the entry
35791+ * is a bit different.
35792+ *
35793+ * skb->iph->tot_len has been byte-swapped, and reduced by the size of
35794+ * the IP header (and options).
35795+ *
35796+ * skb->h.raw has been pulled up the ESP header.
35797+ *
35798+ * skb->iph->protocol = 50 IPPROTO_ESP;
35799+ *
35800+ */
35801+int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type)
35802+{
35803+ struct ipsec_rcv_state nirs, *irs = &nirs;
35804+ struct iphdr *ipp;
35805+
35806+ /* Don't unlink in the middle of a turnaround */
35807+ KLIPS_INC_USE;
35808+
35809+ memset(irs, 0, sizeof(*irs));
35810+
35811+ /* XXX fudge it so that all nat-t stuff comes from ipsec0 */
35812+ /* eventually, the SA itself will determine which device
35813+ * it comes from
35814+ */
35815+ {
35816+ skb->dev = ipsec_get_device(0);
35817+ }
35818+
35819+ /* set up for decap loop */
35820+ irs->hard_header_len = skb->dev->hard_header_len;
35821+
35822+ skb = ipsec_rcv_unclone(skb, irs);
35823+
35824+#if IP_FRAGMENT_LINEARIZE
35825+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
35826+ not assembled automatically to save TCP from having to copy
35827+ twice.
35828+ */
35829+ if (skb_is_nonlinear(skb)) {
35830+#ifdef HAVE_NEW_SKB_LINEARIZE
35831+ if (skb_linearize_cow(skb) != 0)
35832+#else
35833+ if (skb_linearize(skb, GFP_ATOMIC) != 0)
35834+#endif
35835+ {
35836+ goto rcvleave;
35837+ }
35838+ }
35839+#endif /* IP_FRAGMENT_LINEARIZE */
35840+
35841+ ipp = skb->nh.iph;
35842+
35843+ {
35844+ struct in_addr ipsaddr;
35845+ struct in_addr ipdaddr;
35846+
35847+ ipsaddr.s_addr = ipp->saddr;
35848+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt
35849+ , sizeof(irs->ipsaddr_txt));
35850+ ipdaddr.s_addr = ipp->daddr;
35851+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt
35852+ , sizeof(irs->ipdaddr_txt));
35853+ }
35854+
35855+ irs->iphlen = ipp->ihl << 2;
35856+
35857+ KLIPS_IP_PRINT(debug_rcv, ipp);
35858+
35859+ irs->stats= NULL;
35860+ irs->ipp = ipp;
35861+ irs->ipsp = NULL;
35862+ irs->ilen = 0;
35863+ irs->authlen=0;
35864+ irs->authfuncs=NULL;
35865+ irs->skb = skb;
35866+
35867+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35868+ switch(encap_type) {
35869+ case UDP_ENCAP_ESPINUDP:
35870+ irs->natt_type = ESPINUDP_WITH_NON_ESP;
35871+ break;
35872+
35873+ case UDP_ENCAP_ESPINUDP_NON_IKE:
35874+ irs->natt_type = ESPINUDP_WITH_NON_IKE;
35875+ break;
35876+
35877+ default:
35878+ if(printk_ratelimit()) {
35879+ printk(KERN_INFO "KLIPS received unknown UDP-ESP encap type %u\n",
35880+ encap_type);
35881+ }
35882+ return -1;
35883+ }
35884+
35885+#endif
35886+ ipsec_rcv_decap(irs);
35887+ KLIPS_DEC_USE;
35888+ return 0;
35889+
35890+rcvleave:
35891+ if(skb) {
35892+ ipsec_kfree_skb(skb);
35893+ }
35894+ KLIPS_DEC_USE;
35895+ return 0;
35896+}
35897+#endif
35898+
35899+
35900+/*
35901+ * $Log: ipsec_rcv.c,v $
35902+ * Revision 1.171.2.11 2007/04/28 20:46:40 paul
35903+ * Added compile time switch for -DDISABLE_UDP_CHECKSUM that seems to be
35904+ * breaking IPsec+NAT+Transport mode with NAT-OA. Enabled this per default
35905+ * via Makefile.inc's USERCOMPILE flags.
35906+ *
35907+ * Revision 1.171.2.10 2006/10/06 21:39:26 paul
35908+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
35909+ * set. This is defined through autoconf.h which is included through the
35910+ * linux kernel build macros.
35911+ *
35912+ * Revision 1.171.2.9 2006/07/30 02:09:33 paul
35913+ * Author: Bart Trojanowski <bart@xelerance.com>
35914+ * This fixes a NATT+ESP bug in rcv path.
35915+ *
35916+ * We only want to test NATT policy on the ESP packet. Doing so on the
35917+ * bundled SA breaks because the next layer does not know anything about
35918+ * NATT.
35919+ *
35920+ * Fix just puts an if(proto == IPPROTO_ESP) around the NATT policy check.
35921+ *
35922+ * Revision 1.171.2.8 2006/07/29 05:03:04 paul
35923+ * Added check for new version of skb_linearize that only takes 1 argument,
35924+ * for 2.6.18+ kernels.
35925+ *
35926+ * Revision 1.171.2.7 2006/04/20 16:33:07 mcr
35927+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
35928+ * Fix in-kernel module compilation. Sub-makefiles do not work.
35929+ *
35930+ * Revision 1.171.2.6 2005/12/07 06:07:04 paul
35931+ * comment out KLIPS_DEC_USE in ipsec_rcv_decap. Likely an artifact from
35932+ * refactoring. http://bugs.xelerance.com/view.php?id=454
35933+ *
35934+ * Revision 1.171.2.5 2005/10/21 02:22:29 mcr
35935+ * pull up of another try at 2.4.x kernel fix
35936+ *
35937+ * Revision 1.171.2.4 2005/10/21 01:39:56 mcr
35938+ * nat-t fix is 2.4/2.6 specific
35939+ *
35940+ * Revision 1.178 2005/10/21 02:19:34 mcr
35941+ * on 2.4 systems, we have to fix up the length as well.
35942+ *
35943+ * Revision 1.177 2005/10/21 00:18:31 mcr
35944+ * nat-t fix is 2.4 specific.
35945+ *
35946+ * Revision 1.176 2005/10/20 21:06:11 mcr
35947+ * possible fix for nat-t problem on 2.4 kernels.
35948+ *
35949+ * Revision 1.175 2005/10/13 02:49:24 mcr
35950+ * tested UDP-encapsulated ESP packets that were not actually ESP,
35951+ * (but IKE) were being eaten.
35952+ *
35953+ * Revision 1.174 2005/10/13 01:25:22 mcr
35954+ * UDP-encapsulated ESP packets that were not actually ESP,
35955+ * (but IKE) were being eaten.
35956+ *
35957+ * Revision 1.173 2005/08/31 23:26:11 mcr
35958+ * fixes for 2.6.13
35959+ *
35960+ * Revision 1.172 2005/08/05 08:44:54 mcr
35961+ * ipsec_kern24.h (compat code for 2.4) must be include
35962+ * explicitely now.
35963+ *
35964+ * Revision 1.171 2005/07/08 23:56:06 ken
35965+ * #ifdef
35966+ *
35967+ * Revision 1.170 2005/07/08 23:50:05 ken
35968+ * Don't attempt to decapsulate if NAT-T isn't available in the code
35969+ *
35970+ * Revision 1.169 2005/06/06 00:27:31 mcr
35971+ * fix for making tcpdump (packet capture) work correctly for
35972+ * nat-t received packets.
35973+ *
35974+ * Revision 1.168 2005/06/04 16:06:06 mcr
35975+ * better patch for nat-t rcv-device code.
35976+ *
35977+ * Revision 1.167 2005/06/03 17:04:46 mcr
35978+ * nat-t packets are forced to arrive from ipsec0.
35979+ *
35980+ * Revision 1.166 2005/04/29 05:10:22 mcr
35981+ * removed from extraenous includes to make unit testing easier.
35982+ *
35983+ * Revision 1.165 2005/04/20 17:11:32 mcr
35984+ * fixed to compile on 2.4.
35985+ *
35986+ * Revision 1.164 2005/04/18 03:09:50 ken
35987+ * Fix typo
35988+ *
35989+ * Revision 1.163 2005/04/17 05:32:58 mcr
35990+ * remove extraneous debugging
35991+ * make sure to return success from klips26_encap_rcv().
35992+ *
35993+ * Revision 1.162 2005/04/17 04:37:01 mcr
35994+ * make sure that irs->ipp is still set.
35995+ *
35996+ * Revision 1.161 2005/04/17 03:51:52 mcr
35997+ * removed old comment about removed code.
35998+ * added translation from udp.c/2.6 to KLIPS NAT-ESP naming.
35999+ * comment about check for origin address/port for incoming NAT-ESP packets.
36000+ *
36001+ * Revision 1.160 2005/04/15 19:55:58 mcr
36002+ * adjustments to use proper skb fields for data.
36003+ *
36004+ * Revision 1.159 2005/04/10 22:58:20 mcr
36005+ * refactoring of receive functions to make it easier to
36006+ * call the ESP decap.
36007+ *
36008+ * Revision 1.158 2005/04/08 18:27:53 mcr
36009+ * refactored ipsec_rcv() into ipsec_rcv() and ipsec_rcv_decap().
36010+ *
36011+ * Revision 1.157 2004/12/28 23:13:09 mcr
36012+ * use consistent CONFIG_IPSEC_NAT_TRAVERSAL.
36013+ *
36014+ * Revision 1.156 2004/12/03 21:34:51 mcr
36015+ * mistype of KLIPS_USE_COUNT -> KLIPS_INC_USE;
36016+ *
36017+ * Revision 1.155 2004/12/03 21:25:57 mcr
36018+ * compile time fixes for running on 2.6.
36019+ * still experimental.
36020+ *
36021+ * Revision 1.154 2004/09/08 17:21:36 ken
36022+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
36023+ *
36024+ * Revision 1.153 2004/08/22 20:10:00 mcr
36025+ * removed check for incorrect setting of NET_26.
36026+ *
36027+ * Revision 1.152 2004/08/21 15:22:39 mcr
36028+ * added #defines for ATT heartbeat.
36029+ *
36030+ * Revision 1.151 2004/08/21 02:16:32 ken
36031+ * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support
36032+ *
36033+ * Revision 1.150 2004/08/21 00:44:48 mcr
36034+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
36035+ *
36036+ * Revision 1.149 2004/08/20 21:45:45 mcr
36037+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
36038+ * be 26sec compatible. But, some defines where changed.
36039+ *
36040+ * Revision 1.148 2004/08/17 03:27:23 mcr
36041+ * klips 2.6 edits.
36042+ *
36043+ * Revision 1.147 2004/08/05 23:29:27 mcr
36044+ * fixed nesting of #ifdef vs {} in ipsec_rcv().
36045+ *
36046+ * Revision 1.146 2004/08/04 15:57:07 mcr
36047+ * moved des .h files to include/des/ *
36048+ * included 2.6 protocol specific things
36049+ * started at NAT-T support, but it will require a kernel patch.
36050+ *
36051+ * Revision 1.145 2004/08/03 18:19:08 mcr
36052+ * in 2.6, use "net_device" instead of #define device->net_device.
36053+ * this probably breaks 2.0 compiles.
36054+ *
36055+ * Revision 1.144 2004/07/10 19:11:18 mcr
36056+ * CONFIG_IPSEC -> CONFIG_KLIPS.
36057+ *
36058+ * Revision 1.143 2004/05/10 22:27:00 mcr
36059+ * fix for ESP-3DES-noauth test case.
36060+ *
36061+ * Revision 1.142 2004/05/10 22:25:57 mcr
36062+ * reformat of calls to ipsec_lifetime_check().
36063+ *
36064+ * Revision 1.141 2004/04/06 02:49:26 mcr
36065+ * pullup of algo code from alg-branch.
36066+ *
36067+ * Revision 1.140 2004/02/03 03:12:53 mcr
36068+ * removed erroneously, double patched code.
36069+ *
36070+ * Revision 1.139 2004/01/05 23:21:29 mcr
36071+ * initialize sin_family in ipsec_rcv.c
36072+ *
36073+ * Revision 1.138 2003/12/24 19:46:52 mcr
36074+ * if sock.h patch has not been applied, then define appropriate
36075+ * structure so we can use it. This is serious inferior, and
36076+ * depends upon the concept that the structure in question is
36077+ * smaller than the other members of that union.
36078+ * getting rid of differing methods is a better solution.
36079+ *
36080+ * Revision 1.137 2003/12/22 19:40:57 mcr
36081+ * NAT-T patches 0.6c.
36082+ *
36083+ * Revision 1.136 2003/12/15 18:13:12 mcr
36084+ * when compiling with NAT traversal, don't assume that the
36085+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
36086+ * is set.
36087+ *
36088+ * Revision 1.135 2003/12/13 19:10:21 mcr
36089+ * refactored rcv and xmit code - same as FS 2.05.
36090+ *
36091+ * Revision 1.134.2.1 2003/12/22 15:25:52 jjo
36092+ * Merged algo-0.8.1-rc11-test1 into alg-branch
36093+ *
36094+ * Revision 1.134 2003/12/10 01:14:27 mcr
36095+ * NAT-traversal patches to KLIPS.
36096+ *
36097+ * Revision 1.133 2003/10/31 02:27:55 mcr
36098+ * pulled up port-selector patches and sa_id elimination.
36099+ *
36100+ * Revision 1.132.2.1 2003/10/29 01:30:41 mcr
36101+ * elimited "struct sa_id".
36102+ *
36103+ * Revision 1.132 2003/09/02 19:51:48 mcr
36104+ * fixes for PR#252.
36105+ *
36106+ * Revision 1.131 2003/07/31 22:47:16 mcr
36107+ * preliminary (untested by FS-team) 2.5 patches.
36108+ *
36109+ * Revision 1.130 2003/04/03 17:38:25 rgb
36110+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
36111+ * Clarified logic for non-connected devices.
36112+ *
36113+ * Revision 1.129 2003/02/06 02:21:34 rgb
36114+ *
36115+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
36116+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
36117+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
36118+ *
36119+ * Revision 1.128 2002/12/13 20:58:03 rgb
36120+ * Relegated MCR's recent "_dmp" routine to debug_verbose.
36121+ * Cleaned up printing of source and destination addresses in debug output.
36122+ *
36123+ * Revision 1.127 2002/12/04 16:00:16 rgb
36124+ *
36125+ * Fixed AH decapsulation pointer update bug and added some comments and
36126+ * debugging.
36127+ * This bug was caught by west-ah-0[12].
36128+ *
36129+ * Revision 1.126 2002/11/04 05:03:43 mcr
36130+ * fixes for IPCOMP. There were two problems:
36131+ * 1) the irs->ipp pointer was not being updated properly after
36132+ * the ESP descryption. The meant nothing for IPIP, as the
36133+ * later IP header overwrote the earlier one.
36134+ * 2) the more serious problem was that skb_decompress will
36135+ * usually allocate a new SKB, so we have to make sure that
36136+ * it doesn't get lost.
36137+ * #2 meant removing the skb argument from the ->decrypt routine
36138+ * and moving it to the irs->skb, so it could be value/result.
36139+ *
36140+ * Revision 1.125 2002/11/01 01:53:35 dhr
36141+ *
36142+ * fix typo
36143+ *
36144+ * Revision 1.124 2002/10/31 22:49:01 dhr
36145+ *
36146+ * - eliminate unused variable "hash"
36147+ * - reduce scope of variable "authenticator"
36148+ * - add comment on a couple of tricky bits
36149+ *
36150+ * Revision 1.123 2002/10/31 22:39:56 dhr
36151+ *
36152+ * use correct type for result of function calls
36153+ *
36154+ * Revision 1.122 2002/10/31 22:36:25 dhr
36155+ *
36156+ * simplify complex test
36157+ *
36158+ * Revision 1.121 2002/10/31 22:34:04 dhr
36159+ *
36160+ * ipsprev is never used: ditch it
36161+ *
36162+ * Revision 1.120 2002/10/31 22:30:21 dhr
36163+ *
36164+ * eliminate redundant assignments
36165+ *
36166+ * Revision 1.119 2002/10/31 22:27:43 dhr
36167+ *
36168+ * make whitespace canonical
36169+ *
36170+ * Revision 1.118 2002/10/30 05:47:17 rgb
36171+ * Fixed cut-and-paste error mis-identifying comp runt as ah.
36172+ *
36173+ * Revision 1.117 2002/10/17 16:37:45 rgb
36174+ * Remove compp intermediate variable and in-line its contents
36175+ * where used
36176+ *
36177+ * Revision 1.116 2002/10/12 23:11:53 dhr
36178+ *
36179+ * [KenB + DHR] more 64-bit cleanup
36180+ *
36181+ * Revision 1.115 2002/10/07 19:06:58 rgb
36182+ * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming.
36183+ *
36184+ * Revision 1.114 2002/10/07 18:31:31 rgb
36185+ * Set saref on incoming packets.
36186+ *
36187+ * Revision 1.113 2002/09/16 21:28:12 mcr
36188+ * adjust hash length for HMAC calculation - must look at whether
36189+ * it is MD5 or SHA1.
36190+ *
36191+ * Revision 1.112 2002/09/16 21:19:15 mcr
36192+ * fixes for west-ah-icmp-01 - length of AH header must be
36193+ * calculated properly, and next_header field properly copied.
36194+ *
36195+ * Revision 1.111 2002/09/10 02:45:56 mcr
36196+ * re-factored the ipsec_rcv function into several functions,
36197+ * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP.
36198+ * In addition, the MD5 and SHA1 functions are replaced with pointers.
36199+ *
36200+ * Revision 1.110 2002/08/30 06:34:33 rgb
36201+ * Fix scope of shift in AH header length check.
36202+ *
36203+ * Revision 1.109 2002/08/27 16:49:20 rgb
36204+ * Fixed ESP short packet DOS (and AH and IPCOMP).
36205+ *
36206+ * Revision 1.108 2002/07/24 18:44:54 rgb
36207+ * Type fiddling to tame ia64 compiler.
36208+ *
36209+ * Revision 1.107 2002/05/27 18:58:18 rgb
36210+ * Convert to dynamic ipsec device allocation.
36211+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
36212+ *
36213+ * Revision 1.106 2002/05/23 07:15:21 rgb
36214+ * Pointer clean-up.
36215+ * Added refcount code.
36216+ *
36217+ * Revision 1.105 2002/05/14 02:35:06 rgb
36218+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
36219+ * ipsec_sa or ipsec_sa.
36220+ * Change references to _TDB to _IPSA.
36221+ *
36222+ * Revision 1.104 2002/04/24 07:55:32 mcr
36223+ * #include patches and Makefiles for post-reorg compilation.
36224+ *
36225+ * Revision 1.103 2002/04/24 07:36:30 mcr
36226+ * Moved from ./klips/net/ipsec/ipsec_rcv.c,v
36227+ *
36228+ * Revision 1.102 2002/01/29 17:17:56 mcr
36229+ * moved include of ipsec_param.h to after include of linux/kernel.h
36230+ * otherwise, it seems that some option that is set in ipsec_param.h
36231+ * screws up something subtle in the include path to kernel.h, and
36232+ * it complains on the snprintf() prototype.
36233+ *
36234+ * Revision 1.101 2002/01/29 04:00:52 mcr
36235+ * more excise of kversions.h header.
36236+ *
36237+ * Revision 1.100 2002/01/29 02:13:17 mcr
36238+ * introduction of ipsec_kversion.h means that include of
36239+ * ipsec_param.h must preceed any decisions about what files to
36240+ * include to deal with differences in kernel source.
36241+ *
36242+ * Revision 1.99 2002/01/28 21:40:59 mcr
36243+ * should use #if to test boolean option rather than #ifdef.
36244+ *
36245+ * Revision 1.98 2002/01/20 20:19:36 mcr
36246+ * renamed option to IP_FRAGMENT_LINEARIZE.
36247+ *
36248+ * Revision 1.97 2002/01/12 02:55:36 mcr
36249+ * fix for post-2.4.4 to linearize skb's when ESP packet
36250+ * was assembled from fragments.
36251+ *
36252+ * Revision 1.96 2001/11/26 09:23:49 rgb
36253+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
36254+ *
36255+ * Revision 1.93.2.2 2001/10/22 20:54:07 mcr
36256+ * include des.h, removed phony prototypes and fixed calling
36257+ * conventions to match real prototypes.
36258+ *
36259+ * Revision 1.93.2.1 2001/09/25 02:22:22 mcr
36260+ * struct tdb -> struct ipsec_sa.
36261+ * lifetime checks moved to ipsec_life.c
36262+ * some sa(tdb) manipulation functions renamed.
36263+ *
36264+ * Revision 1.95 2001/11/06 19:49:07 rgb
36265+ * Added variable descriptions.
36266+ * Removed unauthenticated sequence==0 check to prevent DoS.
36267+ *
36268+ * Revision 1.94 2001/10/18 04:45:20 rgb
36269+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
36270+ * lib/freeswan.h version macros moved to lib/kversions.h.
36271+ * Other compiler directive cleanups.
36272+ *
36273+ * Revision 1.93 2001/09/07 22:17:24 rgb
36274+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
36275+ * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
36276+ *
36277+ * Revision 1.92 2001/08/27 19:44:41 rgb
36278+ * Fix error in comment.
36279+ *
36280+ * Revision 1.91 2001/07/20 19:31:48 dhr
36281+ * [DHR] fix source and destination subnets of policy in diagnostic
36282+ *
36283+ * Revision 1.90 2001/07/06 19:51:09 rgb
36284+ * Added inbound policy checking code for IPIP SAs.
36285+ * Renamed unused function argument for ease and intuitive naming.
36286+ *
36287+ * Revision 1.89 2001/06/22 19:35:23 rgb
36288+ * Disable ipcomp processing if we are handed a ipcomp packet with no esp
36289+ * or ah header.
36290+ * Print protocol if we are handed a non-ipsec packet.
36291+ *
36292+ * Revision 1.88 2001/06/20 06:30:47 rgb
36293+ * Fixed transport mode IPCOMP policy check bug.
36294+ *
36295+ * Revision 1.87 2001/06/13 20:58:40 rgb
36296+ * Added parentheses around assignment used as truth value to silence
36297+ * compiler.
36298+ *
36299+ * Revision 1.86 2001/06/07 22:25:23 rgb
36300+ * Added a source address policy check for tunnel mode. It still does
36301+ * not check client addresses and masks.
36302+ * Only decapsulate IPIP if it is expected.
36303+ *
36304+ * Revision 1.85 2001/05/30 08:14:02 rgb
36305+ * Removed vestiges of esp-null transforms.
36306+ *
36307+ * Revision 1.84 2001/05/27 06:12:11 rgb
36308+ * Added structures for pid, packet count and last access time to eroute.
36309+ * Added packet count to beginning of /proc/net/ipsec_eroute.
36310+ *
36311+ * Revision 1.83 2001/05/04 16:45:47 rgb
36312+ * Remove unneeded code. ipp is not used after this point.
36313+ *
36314+ * Revision 1.82 2001/05/04 16:36:00 rgb
36315+ * Fix skb_cow() call for 2.4.4. (SS)
36316+ *
36317+ * Revision 1.81 2001/05/02 14:46:53 rgb
36318+ * Fix typo for compiler directive to pull IPH back.
36319+ *
36320+ * Revision 1.80 2001/04/30 19:46:34 rgb
36321+ * Update for 2.4.4. We now receive the skb with skb->data pointing to
36322+ * h.raw.
36323+ *
36324+ * Revision 1.79 2001/04/23 15:01:15 rgb
36325+ * Added spin_lock() check to prevent double-locking for multiple
36326+ * transforms and hence kernel lock-ups with SMP kernels.
36327+ * Minor spin_unlock() adjustments to unlock before non-dependant prints
36328+ * and IPSEC device stats updates.
36329+ *
36330+ * Revision 1.78 2001/04/21 23:04:24 rgb
36331+ * Check if soft expire has already been sent before sending another to
36332+ * prevent ACQUIRE flooding.
36333+ *
36334+ * Revision 1.77 2001/03/16 07:35:20 rgb
36335+ * Ditch extra #if 1 around now permanent policy checking code.
36336+ *
36337+ * Revision 1.76 2001/02/27 22:24:54 rgb
36338+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
36339+ * Check for satoa() return codes.
36340+ *
36341+ * Revision 1.75 2001/02/19 22:28:30 rgb
36342+ * Minor change to virtual device discovery code to assert which I/F has
36343+ * been found.
36344+ *
36345+ * Revision 1.74 2000/11/25 03:50:36 rgb
36346+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
36347+ *
36348+ * Revision 1.73 2000/11/09 20:52:15 rgb
36349+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
36350+ * include ipcomp and prevent races, renaming some tdb variables that got
36351+ * forgotten, moving some unlocks to include tdbs and adding a missing
36352+ * unlock. Thanks to Svenning for some of these.
36353+ *
36354+ * Revision 1.72 2000/11/09 20:11:22 rgb
36355+ * Minor shuffles to fix non-standard kernel config option selection.
36356+ *
36357+ * Revision 1.71 2000/11/06 04:36:18 rgb
36358+ * Ditched spin_lock_irqsave in favour of spin_lock.
36359+ * Minor initial protocol check rewrite.
36360+ * Clean up debug printing.
36361+ * Clean up tdb handling on ipcomp.
36362+ * Fixed transport mode null pointer de-reference without ipcomp.
36363+ * Add Svenning's adaptive content compression.
36364+ * Disabled registration of ipcomp handler.
36365+ *
36366+ * Revision 1.70 2000/10/30 23:41:43 henry
36367+ * Hans-Joerg Hoexer's null-pointer fix
36368+ *
36369+ * Revision 1.69 2000/10/10 18:54:16 rgb
36370+ * Added a fix for incoming policy check with ipcomp enabled but
36371+ * uncompressible.
36372+ *
36373+ * Revision 1.68 2000/09/22 17:53:12 rgb
36374+ * Fixed ipcomp tdb pointers update for policy checking.
36375+ *
36376+ * Revision 1.67 2000/09/21 03:40:58 rgb
36377+ * Added more debugging to try and track down the cpi outward copy problem.
36378+ *
36379+ * Revision 1.66 2000/09/20 04:00:10 rgb
36380+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for
36381+ * debugging oopsen.
36382+ *
36383+ * Revision 1.65 2000/09/19 07:07:16 rgb
36384+ * Added debugging to inbound policy check for ipcomp.
36385+ * Added missing spin_unlocks (thanks Svenning!).
36386+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
36387+ * Protect ipcomp policy check following ipip decap with sysctl switch.
36388+ *
36389+ * Revision 1.64 2000/09/18 21:27:29 rgb
36390+ * 2.0 fixes.
36391+ *
36392+ * Revision 1.63 2000/09/18 02:35:50 rgb
36393+ * Added policy checking to ipcomp and re-enabled policy checking by
36394+ * default.
36395+ * Optimised satoa calls.
36396+ *
36397+ * Revision 1.62 2000/09/17 21:02:32 rgb
36398+ * Clean up debugging, removing slow timestamp debug code.
36399+ *
36400+ * Revision 1.61 2000/09/16 01:07:55 rgb
36401+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
36402+ *
36403+ * Revision 1.60 2000/09/15 11:37:01 rgb
36404+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
36405+ * IPCOMP zlib deflate code.
36406+ *
36407+ * Revision 1.59 2000/09/15 04:56:20 rgb
36408+ * Remove redundant satoa() call, reformat comment.
36409+ *
36410+ * Revision 1.58 2000/09/13 08:00:52 rgb
36411+ * Flick on inbound policy checking.
36412+ *
36413+ * Revision 1.57 2000/09/12 03:22:19 rgb
36414+ * Converted inbound_policy_check to sysctl.
36415+ * Re-enabled policy backcheck.
36416+ * Moved policy checks to top and within tdb lock.
36417+ *
36418+ * Revision 1.56 2000/09/08 19:12:56 rgb
36419+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
36420+ *
36421+ * Revision 1.55 2000/08/28 18:15:46 rgb
36422+ * Added MB's nf-debug reset patch.
36423+ *
36424+ * Revision 1.54 2000/08/27 01:41:26 rgb
36425+ * More minor tweaks to the bad padding debug code.
36426+ *
36427+ * Revision 1.53 2000/08/24 16:54:16 rgb
36428+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
36429+ * info.
36430+ * Tidied up device reporting at the start of ipsec_rcv.
36431+ * Tidied up bad padding debugging and processing.
36432+ *
36433+ * Revision 1.52 2000/08/20 21:36:03 rgb
36434+ * Activated pfkey_expire() calls.
36435+ * Added a hard/soft expiry parameter to pfkey_expire().
36436+ * Added sanity checking to avoid propagating zero or smaller-length skbs
36437+ * from a bogus decryption.
36438+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
36439+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
36440+ *
36441+ * Revision 1.51 2000/08/18 21:23:30 rgb
36442+ * Improve bad padding warning so that the printk buffer doesn't get
36443+ * trampled.
36444+ *
36445+ * Revision 1.50 2000/08/01 14:51:51 rgb
36446+ * Removed _all_ remaining traces of DES.
36447+ *
36448+ * Revision 1.49 2000/07/28 13:50:53 rgb
36449+ * Changed enet_statistics to net_device_stats and added back compatibility
36450+ * for pre-2.1.19.
36451+ *
36452+ * Revision 1.48 2000/05/10 19:14:40 rgb
36453+ * Only check usetime against soft and hard limits if the tdb has been
36454+ * used.
36455+ * Cast output of ntohl so that the broken prototype doesn't make our
36456+ * compile noisy.
36457+ *
36458+ * Revision 1.47 2000/05/09 17:45:43 rgb
36459+ * Fix replay bitmap corruption bug upon receipt of bogus packet
36460+ * with correct SPI. This was a DoS.
36461+ *
36462+ * Revision 1.46 2000/03/27 02:31:58 rgb
36463+ * Fixed authentication failure printout bug.
36464+ *
36465+ * Revision 1.45 2000/03/22 16:15:37 rgb
36466+ * Fixed renaming of dev_get (MB).
36467+ *
36468+ * Revision 1.44 2000/03/16 08:17:24 rgb
36469+ * Hardcode PF_KEYv2 support.
36470+ * Fixed minor bug checking AH header length.
36471+ *
36472+ * Revision 1.43 2000/03/14 12:26:59 rgb
36473+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
36474+ *
36475+ * Revision 1.42 2000/01/26 10:04:04 rgb
36476+ * Fixed inbound policy checking on transport mode bug.
36477+ * Fixed noisy 2.0 printk arguments.
36478+ *
36479+ * Revision 1.41 2000/01/24 20:58:02 rgb
36480+ * Improve debugging/reporting support for (disabled) inbound
36481+ * policy checking.
36482+ *
36483+ * Revision 1.40 2000/01/22 23:20:10 rgb
36484+ * Fixed up inboud policy checking code.
36485+ * Cleaned out unused crud.
36486+ *
36487+ * Revision 1.39 2000/01/21 06:15:29 rgb
36488+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
36489+ * Fixed cut-and-paste debug_tunnel to debug_rcv.
36490+ * Added inbound policy checking code, disabled.
36491+ * Simplified output code by updating ipp to post-IPIP decapsulation.
36492+ *
36493+ * elided pre-2000 comments. Use "cvs log"
36494+ *
36495+ *
36496+ * Local Variables:
36497+ * c-set-style: linux
36498+ * End:
36499+ *
36500+ */
36501--- /dev/null Tue Mar 11 13:02:56 2003
36502+++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004
36503@@ -0,0 +1,1870 @@
36504+/*
36505+ * Common routines for IPsec SA maintenance routines.
36506+ *
36507+ * Copyright (C) 1996, 1997 John Ioannidis.
36508+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
36509+ *
36510+ * This program is free software; you can redistribute it and/or modify it
36511+ * under the terms of the GNU General Public License as published by the
36512+ * Free Software Foundation; either version 2 of the License, or (at your
36513+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
36514+ *
36515+ * This program is distributed in the hope that it will be useful, but
36516+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
36517+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36518+ * for more details.
36519+ *
36520+ * RCSID $Id: ipsec_sa.c,v 1.30.2.2 2006/10/06 21:39:26 paul Exp $
36521+ *
36522+ * This is the file formerly known as "ipsec_xform.h"
36523+ *
36524+ */
36525+
36526+#ifndef AUTOCONF_INCLUDED
36527+#include <linux/config.h>
36528+#endif
36529+#include <linux/version.h>
36530+#include <linux/kernel.h> /* printk() */
36531+
36532+#include "openswan/ipsec_param.h"
36533+
36534+#ifdef MALLOC_SLAB
36535+# include <linux/slab.h> /* kmalloc() */
36536+#else /* MALLOC_SLAB */
36537+# include <linux/malloc.h> /* kmalloc() */
36538+#endif /* MALLOC_SLAB */
36539+#include <linux/vmalloc.h> /* vmalloc() */
36540+#include <linux/errno.h> /* error codes */
36541+#include <linux/types.h> /* size_t */
36542+#include <linux/interrupt.h> /* mark_bh */
36543+
36544+#include <linux/netdevice.h> /* struct device, and other headers */
36545+#include <linux/etherdevice.h> /* eth_type_trans */
36546+#include <linux/ip.h> /* struct iphdr */
36547+#include <linux/skbuff.h>
36548+#include <openswan.h>
36549+#ifdef SPINLOCK
36550+#ifdef SPINLOCK_23
36551+#include <linux/spinlock.h> /* *lock* */
36552+#else /* SPINLOCK_23 */
36553+#include <asm/spinlock.h> /* *lock* */
36554+#endif /* SPINLOCK_23 */
36555+#endif /* SPINLOCK */
36556+
36557+#include <net/ip.h>
36558+
36559+#include "openswan/radij.h"
36560+
36561+#include "openswan/ipsec_stats.h"
36562+#include "openswan/ipsec_life.h"
36563+#include "openswan/ipsec_sa.h"
36564+#include "openswan/ipsec_xform.h"
36565+
36566+#include "openswan/ipsec_encap.h"
36567+#include "openswan/ipsec_radij.h"
36568+#include "openswan/ipsec_xform.h"
36569+#include "openswan/ipsec_ipe4.h"
36570+#include "openswan/ipsec_ah.h"
36571+#include "openswan/ipsec_esp.h"
36572+
36573+#include <pfkeyv2.h>
36574+#include <pfkey.h>
36575+
36576+#include "openswan/ipsec_proto.h"
36577+#include "openswan/ipsec_alg.h"
36578+
36579+
36580+#ifdef CONFIG_KLIPS_DEBUG
36581+int debug_xform = 0;
36582+#endif /* CONFIG_KLIPS_DEBUG */
36583+
36584+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
36585+
36586+struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
36587+#ifdef SPINLOCK
36588+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
36589+#else /* SPINLOCK */
36590+spinlock_t tdb_lock;
36591+#endif /* SPINLOCK */
36592+
36593+struct ipsec_sadb ipsec_sadb;
36594+
36595+#if IPSEC_SA_REF_CODE
36596+
36597+/* the sub table must be narrower (or equal) in bits than the variable type
36598+ in the main table to count the number of unused entries in it. */
36599+typedef struct {
36600+ int testSizeOf_refSubTable :
36601+ ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
36602+} dummy;
36603+
36604+
36605+/* The field where the saref will be hosted in the skb must be wide enough to
36606+ accomodate the information it needs to store. */
36607+typedef struct {
36608+ int testSizeOf_refField :
36609+ (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
36610+} dummy2;
36611+
36612+
36613+#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
36614+
36615+
36616+void
36617+ipsec_SAtest(void)
36618+{
36619+ IPsecSAref_t SAref = 258;
36620+ struct ipsec_sa ips;
36621+ ips.ips_ref = 772;
36622+
36623+ printk("klips_debug:ipsec_SAtest: "
36624+ "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
36625+ "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
36626+ "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
36627+ "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
36628+ "IPSEC_SA_REF_TABLE_MASK=%x\n"
36629+ "IPSEC_SA_REF_ENTRY_MASK=%x\n"
36630+ "IPsecSAref2table(%d)=%u\n"
36631+ "IPsecSAref2entry(%d)=%u\n"
36632+ "IPsecSAref2NFmark(%d)=%u\n"
36633+ "IPsecSAref2SA(%d)=%p\n"
36634+ "IPsecSA2SAref(%p)=%d\n"
36635+ ,
36636+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36637+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
36638+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36639+ (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH,
36640+ IPSEC_SA_REF_TABLE_MASK,
36641+ IPSEC_SA_REF_ENTRY_MASK,
36642+ SAref, IPsecSAref2table(SAref),
36643+ SAref, IPsecSAref2entry(SAref),
36644+ SAref, IPsecSAref2NFmark(SAref),
36645+ SAref, IPsecSAref2SA(SAref),
36646+ (&ips), IPsecSA2SAref((&ips))
36647+ );
36648+ return;
36649+}
36650+
36651+int
36652+ipsec_SAref_recycle(void)
36653+{
36654+ int table;
36655+ int entry;
36656+ int error = 0;
36657+
36658+ ipsec_sadb.refFreeListHead = -1;
36659+ ipsec_sadb.refFreeListTail = -1;
36660+
36661+ if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
36662+ KLIPS_PRINT(debug_xform,
36663+ "klips_debug:ipsec_SAref_recycle: "
36664+ "end of table reached, continuing at start..\n");
36665+ ipsec_sadb.refFreeListCont = 0;
36666+ }
36667+
36668+ KLIPS_PRINT(debug_xform,
36669+ "klips_debug:ipsec_SAref_recycle: "
36670+ "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
36671+ ipsec_sadb.refFreeListCont,
36672+ (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
36673+ IPsecSAref2table(ipsec_sadb.refFreeListCont),
36674+ IPsecSAref2entry(ipsec_sadb.refFreeListCont));
36675+
36676+ for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
36677+ table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
36678+ table++) {
36679+ if(ipsec_sadb.refTable[table] == NULL) {
36680+ error = ipsec_SArefSubTable_alloc(table);
36681+ if(error) {
36682+ return error;
36683+ }
36684+ }
36685+ for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
36686+ entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
36687+ entry++) {
36688+ if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
36689+ ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
36690+ if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
36691+ ipsec_sadb.refFreeListHead = 0;
36692+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
36693+ KLIPS_PRINT(debug_xform,
36694+ "klips_debug:ipsec_SAref_recycle: "
36695+ "SArefFreeList refilled.\n");
36696+ return 0;
36697+ }
36698+ }
36699+ }
36700+ }
36701+
36702+ if(ipsec_sadb.refFreeListTail == -1) {
36703+ KLIPS_PRINT(debug_xform,
36704+ "klips_debug:ipsec_SAref_recycle: "
36705+ "out of room in the SArefTable.\n");
36706+
36707+ return(-ENOSPC);
36708+ }
36709+
36710+ ipsec_sadb.refFreeListHead = 0;
36711+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
36712+ KLIPS_PRINT(debug_xform,
36713+ "klips_debug:ipsec_SAref_recycle: "
36714+ "SArefFreeList partly refilled to %d of %d.\n",
36715+ ipsec_sadb.refFreeListTail,
36716+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36717+ return 0;
36718+}
36719+
36720+int
36721+ipsec_SArefSubTable_alloc(unsigned table)
36722+{
36723+ unsigned entry;
36724+ struct IPsecSArefSubTable* SArefsub;
36725+
36726+ KLIPS_PRINT(debug_xform,
36727+ "klips_debug:ipsec_SArefSubTable_alloc: "
36728+ "allocating %lu bytes for table %u of %u.\n",
36729+ (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
36730+ table,
36731+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36732+
36733+ /* allocate another sub-table */
36734+ SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
36735+ if(SArefsub == NULL) {
36736+ KLIPS_PRINT(debug_xform,
36737+ "klips_debug:ipsec_SArefSubTable_alloc: "
36738+ "error allocating memory for table %u of %u!\n",
36739+ table,
36740+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36741+ return -ENOMEM;
36742+ }
36743+
36744+ /* add this sub-table to the main table */
36745+ ipsec_sadb.refTable[table] = SArefsub;
36746+
36747+ /* initialise each element to NULL */
36748+ KLIPS_PRINT(debug_xform,
36749+ "klips_debug:ipsec_SArefSubTable_alloc: "
36750+ "initialising %u elements (2 ^ %u) of table %u.\n",
36751+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36752+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36753+ table);
36754+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36755+ SArefsub->entry[entry] = NULL;
36756+ }
36757+
36758+ return 0;
36759+}
36760+#endif /* IPSEC_SA_REF_CODE */
36761+
36762+int
36763+ipsec_saref_freelist_init(void)
36764+{
36765+ int i;
36766+
36767+ KLIPS_PRINT(debug_xform,
36768+ "klips_debug:ipsec_saref_freelist_init: "
36769+ "initialising %u elements of FreeList.\n",
36770+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36771+
36772+ for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
36773+ ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
36774+ }
36775+ ipsec_sadb.refFreeListHead = -1;
36776+ ipsec_sadb.refFreeListCont = 0;
36777+ ipsec_sadb.refFreeListTail = -1;
36778+
36779+ return 0;
36780+}
36781+
36782+int
36783+ipsec_sadb_init(void)
36784+{
36785+ int error = 0;
36786+ unsigned i;
36787+
36788+ for(i = 0; i < SADB_HASHMOD; i++) {
36789+ ipsec_sadb_hash[i] = NULL;
36790+ }
36791+ /* parts above are for the old style SADB hash table */
36792+
36793+
36794+#if IPSEC_SA_REF_CODE
36795+ /* initialise SA reference table */
36796+
36797+ /* initialise the main table */
36798+ KLIPS_PRINT(debug_xform,
36799+ "klips_debug:ipsec_sadb_init: "
36800+ "initialising main table of size %u (2 ^ %u).\n",
36801+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
36802+ IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
36803+ {
36804+ unsigned table;
36805+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
36806+ ipsec_sadb.refTable[table] = NULL;
36807+ }
36808+ }
36809+
36810+ /* allocate the first sub-table */
36811+ error = ipsec_SArefSubTable_alloc(0);
36812+ if(error) {
36813+ return error;
36814+ }
36815+
36816+ error = ipsec_saref_freelist_init();
36817+#endif /* IPSEC_SA_REF_CODE */
36818+ return error;
36819+}
36820+
36821+#if IPSEC_SA_REF_CODE
36822+IPsecSAref_t
36823+ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
36824+{
36825+ IPsecSAref_t SAref;
36826+
36827+ KLIPS_PRINT(debug_xform,
36828+ "klips_debug:ipsec_SAref_alloc: "
36829+ "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
36830+ ipsec_sadb.refFreeListHead,
36831+ ipsec_sadb.refFreeListCont,
36832+ ipsec_sadb.refFreeListTail,
36833+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36834+
36835+ if(ipsec_sadb.refFreeListHead == -1) {
36836+ KLIPS_PRINT(debug_xform,
36837+ "klips_debug:ipsec_SAref_alloc: "
36838+ "FreeList empty, recycling...\n");
36839+ *error = ipsec_SAref_recycle();
36840+ if(*error) {
36841+ return IPSEC_SAREF_NULL;
36842+ }
36843+ }
36844+
36845+ SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
36846+ if(SAref == IPSEC_SAREF_NULL) {
36847+ KLIPS_PRINT(debug_xform,
36848+ "klips_debug:ipsec_SAref_alloc: "
36849+ "unexpected error, refFreeListHead = %d points to invalid entry.\n",
36850+ ipsec_sadb.refFreeListHead);
36851+ *error = -ESPIPE;
36852+ return IPSEC_SAREF_NULL;
36853+ }
36854+
36855+ KLIPS_PRINT(debug_xform,
36856+ "klips_debug:ipsec_SAref_alloc: "
36857+ "allocating SAref=%d, table=%u, entry=%u of %u.\n",
36858+ SAref,
36859+ IPsecSAref2table(SAref),
36860+ IPsecSAref2entry(SAref),
36861+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
36862+
36863+ ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
36864+ ipsec_sadb.refFreeListHead++;
36865+ if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
36866+ KLIPS_PRINT(debug_xform,
36867+ "klips_debug:ipsec_SAref_alloc: "
36868+ "last FreeList entry allocated, resetting list head to empty.\n");
36869+ ipsec_sadb.refFreeListHead = -1;
36870+ }
36871+
36872+ return SAref;
36873+}
36874+#endif /* IPSEC_SA_REF_CODE */
36875+
36876+int
36877+ipsec_sa_print(struct ipsec_sa *ips)
36878+{
36879+ char sa[SATOT_BUF];
36880+ size_t sa_len;
36881+
36882+ printk(KERN_INFO "klips_debug: SA:");
36883+ if(ips == NULL) {
36884+ printk("NULL\n");
36885+ return -ENOENT;
36886+ }
36887+ printk(" ref=%d", ips->ips_ref);
36888+ printk(" refcount=%d", atomic_read(&ips->ips_refcount));
36889+ if(ips->ips_hnext != NULL) {
36890+ printk(" hnext=0p%p", ips->ips_hnext);
36891+ }
36892+ if(ips->ips_inext != NULL) {
36893+ printk(" inext=0p%p", ips->ips_inext);
36894+ }
36895+ if(ips->ips_onext != NULL) {
36896+ printk(" onext=0p%p", ips->ips_onext);
36897+ }
36898+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36899+ printk(" said=%s", sa_len ? sa : " (error)");
36900+ if(ips->ips_seq) {
36901+ printk(" seq=%u", ips->ips_seq);
36902+ }
36903+ if(ips->ips_pid) {
36904+ printk(" pid=%u", ips->ips_pid);
36905+ }
36906+ if(ips->ips_authalg) {
36907+ printk(" authalg=%u", ips->ips_authalg);
36908+ }
36909+ if(ips->ips_encalg) {
36910+ printk(" encalg=%u", ips->ips_encalg);
36911+ }
36912+ printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
36913+ if(ips->ips_replaywin) {
36914+ printk(" ooowin=%u", ips->ips_replaywin);
36915+ }
36916+ if(ips->ips_flags) {
36917+ printk(" flags=%u", ips->ips_flags);
36918+ }
36919+ if(ips->ips_addr_s) {
36920+ char buf[SUBNETTOA_BUF];
36921+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36922+ 0, buf, sizeof(buf));
36923+ printk(" src=%s", buf);
36924+ }
36925+ if(ips->ips_addr_d) {
36926+ char buf[SUBNETTOA_BUF];
36927+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36928+ 0, buf, sizeof(buf));
36929+ printk(" dst=%s", buf);
36930+ }
36931+ if(ips->ips_addr_p) {
36932+ char buf[SUBNETTOA_BUF];
36933+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
36934+ 0, buf, sizeof(buf));
36935+ printk(" proxy=%s", buf);
36936+ }
36937+ if(ips->ips_key_bits_a) {
36938+ printk(" key_bits_a=%u", ips->ips_key_bits_a);
36939+ }
36940+ if(ips->ips_key_bits_e) {
36941+ printk(" key_bits_e=%u", ips->ips_key_bits_e);
36942+ }
36943+
36944+ printk("\n");
36945+ return 0;
36946+}
36947+
36948+struct ipsec_sa*
36949+ipsec_sa_alloc(int*error) /* pass in error var by pointer */
36950+{
36951+ struct ipsec_sa* ips;
36952+
36953+ if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
36954+ KLIPS_PRINT(debug_xform,
36955+ "klips_debug:ipsec_sa_alloc: "
36956+ "memory allocation error\n");
36957+ *error = -ENOMEM;
36958+ return NULL;
36959+ }
36960+ memset((caddr_t)ips, 0, sizeof(*ips));
36961+#if IPSEC_SA_REF_CODE
36962+ ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */
36963+ KLIPS_PRINT(debug_xform,
36964+ "klips_debug:ipsec_sa_alloc: "
36965+ "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
36966+ (unsigned long) sizeof(*ips),
36967+ ips,
36968+ ips->ips_ref);
36969+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
36970+ kfree(ips);
36971+ KLIPS_PRINT(debug_xform,
36972+ "klips_debug:ipsec_sa_alloc: "
36973+ "SAref allocation error\n");
36974+ return NULL;
36975+ }
36976+
36977+ atomic_inc(&ips->ips_refcount);
36978+ IPsecSAref2SA(ips->ips_ref) = ips;
36979+#endif /* IPSEC_SA_REF_CODE */
36980+
36981+ *error = 0;
36982+ return(ips);
36983+}
36984+
36985+int
36986+ipsec_sa_free(struct ipsec_sa* ips)
36987+{
36988+ return ipsec_sa_wipe(ips);
36989+}
36990+
36991+struct ipsec_sa *
36992+ipsec_sa_getbyid(ip_said *said)
36993+{
36994+ int hashval;
36995+ struct ipsec_sa *ips;
36996+ char sa[SATOT_BUF];
36997+ size_t sa_len;
36998+
36999+ if(said == NULL) {
37000+ KLIPS_PRINT(debug_xform,
37001+ "klips_error:ipsec_sa_getbyid: "
37002+ "null pointer passed in!\n");
37003+ return NULL;
37004+ }
37005+
37006+ sa_len = satot(said, 0, sa, sizeof(sa));
37007+
37008+ hashval = IPS_HASH(said);
37009+
37010+ KLIPS_PRINT(debug_xform,
37011+ "klips_debug:ipsec_sa_getbyid: "
37012+ "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
37013+ hashval,
37014+ sa_len ? sa : " (error)");
37015+
37016+ if((ips = ipsec_sadb_hash[hashval]) == NULL) {
37017+ KLIPS_PRINT(debug_xform,
37018+ "klips_debug:ipsec_sa_getbyid: "
37019+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
37020+ hashval,
37021+ sa_len ? sa : " (error)");
37022+ return NULL;
37023+ }
37024+
37025+ for (; ips; ips = ips->ips_hnext) {
37026+ if ((ips->ips_said.spi == said->spi) &&
37027+ (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
37028+ (ips->ips_said.proto == said->proto)) {
37029+ atomic_inc(&ips->ips_refcount);
37030+ return ips;
37031+ }
37032+ }
37033+
37034+ KLIPS_PRINT(debug_xform,
37035+ "klips_debug:ipsec_sa_getbyid: "
37036+ "no entry in linked list for hash=%d of SA:%s.\n",
37037+ hashval,
37038+ sa_len ? sa : " (error)");
37039+ return NULL;
37040+}
37041+
37042+int
37043+ipsec_sa_put(struct ipsec_sa *ips)
37044+{
37045+ char sa[SATOT_BUF];
37046+ size_t sa_len;
37047+
37048+ if(ips == NULL) {
37049+ KLIPS_PRINT(debug_xform,
37050+ "klips_error:ipsec_sa_put: "
37051+ "null pointer passed in!\n");
37052+ return -1;
37053+ }
37054+
37055+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37056+
37057+ KLIPS_PRINT(debug_xform,
37058+ "klips_debug:ipsec_sa_put: "
37059+ "ipsec_sa SA:%s, ref:%d reference count decremented.\n",
37060+ sa_len ? sa : " (error)",
37061+ ips->ips_ref);
37062+
37063+ atomic_dec(&ips->ips_refcount);
37064+
37065+ return 0;
37066+}
37067+
37068+/*
37069+ The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
37070+*/
37071+int
37072+ipsec_sa_add(struct ipsec_sa *ips)
37073+{
37074+ int error = 0;
37075+ unsigned int hashval;
37076+
37077+ if(ips == NULL) {
37078+ KLIPS_PRINT(debug_xform,
37079+ "klips_error:ipsec_sa_add: "
37080+ "null pointer passed in!\n");
37081+ return -ENODATA;
37082+ }
37083+ hashval = IPS_HASH(&ips->ips_said);
37084+
37085+ atomic_inc(&ips->ips_refcount);
37086+ spin_lock_bh(&tdb_lock);
37087+
37088+ ips->ips_hnext = ipsec_sadb_hash[hashval];
37089+ ipsec_sadb_hash[hashval] = ips;
37090+
37091+ spin_unlock_bh(&tdb_lock);
37092+
37093+ return error;
37094+}
37095+
37096+/*
37097+ The ipsec_sa table better be locked before it is handed in, or races might happen
37098+*/
37099+int
37100+ipsec_sa_del(struct ipsec_sa *ips)
37101+{
37102+ unsigned int hashval;
37103+ struct ipsec_sa *ipstp;
37104+ char sa[SATOT_BUF];
37105+ size_t sa_len;
37106+
37107+ if(ips == NULL) {
37108+ KLIPS_PRINT(debug_xform,
37109+ "klips_error:ipsec_sa_del: "
37110+ "null pointer passed in!\n");
37111+ return -ENODATA;
37112+ }
37113+
37114+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37115+ if(ips->ips_inext || ips->ips_onext) {
37116+ KLIPS_PRINT(debug_xform,
37117+ "klips_error:ipsec_sa_del: "
37118+ "SA:%s still linked!\n",
37119+ sa_len ? sa : " (error)");
37120+ return -EMLINK;
37121+ }
37122+
37123+ hashval = IPS_HASH(&ips->ips_said);
37124+
37125+ KLIPS_PRINT(debug_xform,
37126+ "klips_debug:ipsec_sa_del: "
37127+ "deleting SA:%s, hashval=%d.\n",
37128+ sa_len ? sa : " (error)",
37129+ hashval);
37130+ if(ipsec_sadb_hash[hashval] == NULL) {
37131+ KLIPS_PRINT(debug_xform,
37132+ "klips_debug:ipsec_sa_del: "
37133+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
37134+ hashval,
37135+ sa_len ? sa : " (error)");
37136+ return -ENOENT;
37137+ }
37138+
37139+ if (ips == ipsec_sadb_hash[hashval]) {
37140+ ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
37141+ ips->ips_hnext = NULL;
37142+ atomic_dec(&ips->ips_refcount);
37143+ KLIPS_PRINT(debug_xform,
37144+ "klips_debug:ipsec_sa_del: "
37145+ "successfully deleted first ipsec_sa in chain.\n");
37146+ return 0;
37147+ } else {
37148+ for (ipstp = ipsec_sadb_hash[hashval];
37149+ ipstp;
37150+ ipstp = ipstp->ips_hnext) {
37151+ if (ipstp->ips_hnext == ips) {
37152+ ipstp->ips_hnext = ips->ips_hnext;
37153+ ips->ips_hnext = NULL;
37154+ atomic_dec(&ips->ips_refcount);
37155+ KLIPS_PRINT(debug_xform,
37156+ "klips_debug:ipsec_sa_del: "
37157+ "successfully deleted link in ipsec_sa chain.\n");
37158+ return 0;
37159+ }
37160+ }
37161+ }
37162+
37163+ KLIPS_PRINT(debug_xform,
37164+ "klips_debug:ipsec_sa_del: "
37165+ "no entries in linked list for hash=%d of SA:%s.\n",
37166+ hashval,
37167+ sa_len ? sa : " (error)");
37168+ return -ENOENT;
37169+}
37170+
37171+/*
37172+ The ipsec_sa table better be locked before it is handed in, or races
37173+ might happen
37174+*/
37175+int
37176+ipsec_sa_delchain(struct ipsec_sa *ips)
37177+{
37178+ struct ipsec_sa *ipsdel;
37179+ int error = 0;
37180+ char sa[SATOT_BUF];
37181+ size_t sa_len;
37182+
37183+ if(ips == NULL) {
37184+ KLIPS_PRINT(debug_xform,
37185+ "klips_error:ipsec_sa_delchain: "
37186+ "null pointer passed in!\n");
37187+ return -ENODATA;
37188+ }
37189+
37190+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37191+ KLIPS_PRINT(debug_xform,
37192+ "klips_debug:ipsec_sa_delchain: "
37193+ "passed SA:%s\n",
37194+ sa_len ? sa : " (error)");
37195+ while(ips->ips_onext != NULL) {
37196+ ips = ips->ips_onext;
37197+ }
37198+
37199+ while(ips) {
37200+ /* XXX send a pfkey message up to advise of deleted ipsec_sa */
37201+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37202+ KLIPS_PRINT(debug_xform,
37203+ "klips_debug:ipsec_sa_delchain: "
37204+ "unlinking and delting SA:%s",
37205+ sa_len ? sa : " (error)");
37206+ ipsdel = ips;
37207+ ips = ips->ips_inext;
37208+ if(ips != NULL) {
37209+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37210+ KLIPS_PRINT(debug_xform,
37211+ ", inext=%s",
37212+ sa_len ? sa : " (error)");
37213+ atomic_dec(&ipsdel->ips_refcount);
37214+ ipsdel->ips_inext = NULL;
37215+ atomic_dec(&ips->ips_refcount);
37216+ ips->ips_onext = NULL;
37217+ }
37218+ KLIPS_PRINT(debug_xform,
37219+ ".\n");
37220+ if((error = ipsec_sa_del(ipsdel))) {
37221+ KLIPS_PRINT(debug_xform,
37222+ "klips_debug:ipsec_sa_delchain: "
37223+ "ipsec_sa_del returned error %d.\n", -error);
37224+ return error;
37225+ }
37226+ if((error = ipsec_sa_wipe(ipsdel))) {
37227+ KLIPS_PRINT(debug_xform,
37228+ "klips_debug:ipsec_sa_delchain: "
37229+ "ipsec_sa_wipe returned error %d.\n", -error);
37230+ return error;
37231+ }
37232+ }
37233+ return error;
37234+}
37235+
37236+int
37237+ipsec_sadb_cleanup(__u8 proto)
37238+{
37239+ unsigned i;
37240+ int error = 0;
37241+ struct ipsec_sa *ips, **ipsprev, *ipsdel;
37242+ char sa[SATOT_BUF];
37243+ size_t sa_len;
37244+
37245+ KLIPS_PRINT(debug_xform,
37246+ "klips_debug:ipsec_sadb_cleanup: "
37247+ "cleaning up proto=%d.\n",
37248+ proto);
37249+
37250+ spin_lock_bh(&tdb_lock);
37251+
37252+ for (i = 0; i < SADB_HASHMOD; i++) {
37253+ ipsprev = &(ipsec_sadb_hash[i]);
37254+ ips = ipsec_sadb_hash[i];
37255+ if(ips != NULL) {
37256+ atomic_inc(&ips->ips_refcount);
37257+ }
37258+ for(; ips != NULL;) {
37259+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37260+ KLIPS_PRINT(debug_xform,
37261+ "klips_debug:ipsec_sadb_cleanup: "
37262+ "checking SA:%s, hash=%d, ref=%d",
37263+ sa_len ? sa : " (error)",
37264+ i,
37265+ ips->ips_ref);
37266+ ipsdel = ips;
37267+ ips = ipsdel->ips_hnext;
37268+ if(ips != NULL) {
37269+ atomic_inc(&ips->ips_refcount);
37270+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37271+ KLIPS_PRINT(debug_xform,
37272+ ", hnext=%s",
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) {
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+ if(proto == 0 || (proto == ipsdel->ips_said.proto)) {
37290+ sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa));
37291+ KLIPS_PRINT(debug_xform,
37292+ "klips_debug:ipsec_sadb_cleanup: "
37293+ "deleting SA chain:%s.\n",
37294+ sa_len ? sa : " (error)");
37295+ if((error = ipsec_sa_delchain(ipsdel))) {
37296+ SENDERR(-error);
37297+ }
37298+ ipsprev = &(ipsec_sadb_hash[i]);
37299+ ips = ipsec_sadb_hash[i];
37300+
37301+ KLIPS_PRINT(debug_xform,
37302+ "klips_debug:ipsec_sadb_cleanup: "
37303+ "deleted SA chain:%s",
37304+ sa_len ? sa : " (error)");
37305+ if(ips != NULL) {
37306+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37307+ KLIPS_PRINT(debug_xform,
37308+ ", ipsec_sadb_hash[%d]=%s",
37309+ i,
37310+ sa_len ? sa : " (error)");
37311+ }
37312+ if(*ipsprev != NULL) {
37313+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
37314+ KLIPS_PRINT(debug_xform,
37315+ ", *ipsprev=%s",
37316+ sa_len ? sa : " (error)");
37317+ if((*ipsprev)->ips_hnext != NULL) {
37318+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
37319+ KLIPS_PRINT(debug_xform,
37320+ ", *ipsprev->ips_hnext=%s",
37321+ sa_len ? sa : " (error)");
37322+ }
37323+ }
37324+ KLIPS_PRINT(debug_xform,
37325+ ".\n");
37326+ } else {
37327+ ipsprev = &ipsdel;
37328+ }
37329+ if(ipsdel != NULL) {
37330+ ipsec_sa_put(ipsdel);
37331+ }
37332+ }
37333+ }
37334+ errlab:
37335+
37336+ spin_unlock_bh(&tdb_lock);
37337+
37338+
37339+#if IPSEC_SA_REF_CODE
37340+ /* clean up SA reference table */
37341+
37342+ /* go through the ref table and clean out all the SAs */
37343+ KLIPS_PRINT(debug_xform,
37344+ "klips_debug:ipsec_sadb_cleanup: "
37345+ "removing SAref entries and tables.");
37346+ {
37347+ unsigned table, entry;
37348+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
37349+ KLIPS_PRINT(debug_xform,
37350+ "klips_debug:ipsec_sadb_cleanup: "
37351+ "cleaning SAref table=%u.\n",
37352+ table);
37353+ if(ipsec_sadb.refTable[table] == NULL) {
37354+ printk("\n");
37355+ KLIPS_PRINT(debug_xform,
37356+ "klips_debug:ipsec_sadb_cleanup: "
37357+ "cleaned %u used refTables.\n",
37358+ table);
37359+ break;
37360+ }
37361+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
37362+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
37363+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
37364+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
37365+ }
37366+ }
37367+ }
37368+ }
37369+#endif /* IPSEC_SA_REF_CODE */
37370+
37371+ return(error);
37372+}
37373+
37374+int
37375+ipsec_sadb_free(void)
37376+{
37377+ int error = 0;
37378+
37379+ KLIPS_PRINT(debug_xform,
37380+ "klips_debug:ipsec_sadb_free: "
37381+ "freeing SArefTable memory.\n");
37382+
37383+ /* clean up SA reference table */
37384+
37385+ /* go through the ref table and clean out all the SAs if any are
37386+ left and free table memory */
37387+ KLIPS_PRINT(debug_xform,
37388+ "klips_debug:ipsec_sadb_free: "
37389+ "removing SAref entries and tables.\n");
37390+ {
37391+ unsigned table, entry;
37392+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
37393+ KLIPS_PRINT(debug_xform,
37394+ "klips_debug:ipsec_sadb_free: "
37395+ "removing SAref table=%u.\n",
37396+ table);
37397+ if(ipsec_sadb.refTable[table] == NULL) {
37398+ KLIPS_PRINT(debug_xform,
37399+ "klips_debug:ipsec_sadb_free: "
37400+ "removed %u used refTables.\n",
37401+ table);
37402+ break;
37403+ }
37404+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
37405+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
37406+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
37407+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
37408+ }
37409+ }
37410+ vfree(ipsec_sadb.refTable[table]);
37411+ ipsec_sadb.refTable[table] = NULL;
37412+ }
37413+ }
37414+
37415+ return(error);
37416+}
37417+
37418+int
37419+ipsec_sa_wipe(struct ipsec_sa *ips)
37420+{
37421+ if(ips == NULL) {
37422+ return -ENODATA;
37423+ }
37424+
37425+ /* if(atomic_dec_and_test(ips)) {
37426+ }; */
37427+
37428+#if IPSEC_SA_REF_CODE
37429+ /* remove me from the SArefTable */
37430+ {
37431+ char sa[SATOT_BUF];
37432+ size_t sa_len;
37433+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37434+ KLIPS_PRINT(debug_xform,
37435+ "klips_debug:ipsec_sa_wipe: "
37436+ "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
37437+ sa_len ? sa : " (error)",
37438+ ips,
37439+ ips->ips_ref,
37440+ IPsecSAref2table(IPsecSA2SAref(ips)),
37441+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
37442+ IPsecSAref2entry(IPsecSA2SAref(ips)));
37443+ }
37444+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
37445+ KLIPS_PRINT(debug_xform,
37446+ "klips_debug:ipsec_sa_wipe: "
37447+ "why does this SA not have a valid SAref?.\n");
37448+ }
37449+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
37450+ ips->ips_ref = IPSEC_SAREF_NULL;
37451+ ipsec_sa_put(ips);
37452+#endif /* IPSEC_SA_REF_CODE */
37453+
37454+ /* paranoid clean up */
37455+ if(ips->ips_addr_s != NULL) {
37456+ memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
37457+ kfree(ips->ips_addr_s);
37458+ }
37459+ ips->ips_addr_s = NULL;
37460+
37461+ if(ips->ips_addr_d != NULL) {
37462+ memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
37463+ kfree(ips->ips_addr_d);
37464+ }
37465+ ips->ips_addr_d = NULL;
37466+
37467+ if(ips->ips_addr_p != NULL) {
37468+ memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
37469+ kfree(ips->ips_addr_p);
37470+ }
37471+ ips->ips_addr_p = NULL;
37472+
37473+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
37474+ if(ips->ips_natt_oa) {
37475+ memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
37476+ kfree(ips->ips_natt_oa);
37477+ }
37478+ ips->ips_natt_oa = NULL;
37479+#endif
37480+
37481+ if(ips->ips_key_a != NULL) {
37482+ memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
37483+ kfree(ips->ips_key_a);
37484+ }
37485+ ips->ips_key_a = NULL;
37486+
37487+ if(ips->ips_key_e != NULL) {
37488+ if (ips->ips_alg_enc &&
37489+ ips->ips_alg_enc->ixt_e_destroy_key)
37490+ {
37491+ ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
37492+ ips->ips_key_e);
37493+ } else
37494+ {
37495+ memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
37496+ kfree(ips->ips_key_e);
37497+ }
37498+ }
37499+ ips->ips_key_e = NULL;
37500+
37501+ if(ips->ips_iv != NULL) {
37502+ memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
37503+ kfree(ips->ips_iv);
37504+ }
37505+ ips->ips_iv = NULL;
37506+
37507+ if(ips->ips_ident_s.data != NULL) {
37508+ memset((caddr_t)(ips->ips_ident_s.data),
37509+ 0,
37510+ ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37511+ kfree(ips->ips_ident_s.data);
37512+ }
37513+ ips->ips_ident_s.data = NULL;
37514+
37515+ if(ips->ips_ident_d.data != NULL) {
37516+ memset((caddr_t)(ips->ips_ident_d.data),
37517+ 0,
37518+ ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37519+ kfree(ips->ips_ident_d.data);
37520+ }
37521+ ips->ips_ident_d.data = NULL;
37522+
37523+ if (ips->ips_alg_enc||ips->ips_alg_auth) {
37524+ ipsec_alg_sa_wipe(ips);
37525+ }
37526+
37527+ memset((caddr_t)ips, 0, sizeof(*ips));
37528+ kfree(ips);
37529+ ips = NULL;
37530+
37531+ return 0;
37532+}
37533+
37534+extern int sysctl_ipsec_debug_verbose;
37535+
37536+int ipsec_sa_init(struct ipsec_sa *ipsp)
37537+{
37538+ int i;
37539+ int error = 0;
37540+ char sa[SATOT_BUF];
37541+ size_t sa_len;
37542+ char ipaddr_txt[ADDRTOA_BUF];
37543+ char ipaddr2_txt[ADDRTOA_BUF];
37544+#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37545+ unsigned char kb[AHMD596_BLKLEN];
37546+#endif
37547+ struct ipsec_alg_enc *ixt_e = NULL;
37548+ struct ipsec_alg_auth *ixt_a = NULL;
37549+
37550+ if(ipsp == NULL) {
37551+ KLIPS_PRINT(debug_pfkey,
37552+ "ipsec_sa_init: "
37553+ "ipsp is NULL, fatal\n");
37554+ SENDERR(EINVAL);
37555+ }
37556+
37557+ sa_len = satot(&ipsp->ips_said, 0, sa, sizeof(sa));
37558+
37559+ KLIPS_PRINT(debug_pfkey,
37560+ "ipsec_sa_init: "
37561+ "(pfkey defined) called for SA:%s\n",
37562+ sa_len ? sa : " (error)");
37563+
37564+ KLIPS_PRINT(debug_pfkey,
37565+ "ipsec_sa_init: "
37566+ "calling init routine of %s%s%s\n",
37567+ IPS_XFORM_NAME(ipsp));
37568+
37569+ switch(ipsp->ips_said.proto) {
37570+
37571+#ifdef CONFIG_KLIPS_IPIP
37572+ case IPPROTO_IPIP: {
37573+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
37574+ 0,
37575+ ipaddr_txt, sizeof(ipaddr_txt));
37576+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
37577+ 0,
37578+ ipaddr2_txt, sizeof(ipaddr_txt));
37579+ KLIPS_PRINT(debug_pfkey,
37580+ "ipsec_sa_init: "
37581+ "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
37582+ ipaddr_txt,
37583+ ipaddr2_txt);
37584+ }
37585+ break;
37586+#endif /* !CONFIG_KLIPS_IPIP */
37587+
37588+#ifdef CONFIG_KLIPS_AH
37589+ case IPPROTO_AH:
37590+ switch(ipsp->ips_authalg) {
37591+# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37592+ case AH_MD5: {
37593+ unsigned char *akp;
37594+ unsigned int aks;
37595+ MD5_CTX *ictx;
37596+ MD5_CTX *octx;
37597+
37598+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37599+ KLIPS_PRINT(debug_pfkey,
37600+ "ipsec_sa_init: "
37601+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37602+ ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
37603+ SENDERR(EINVAL);
37604+ }
37605+
37606+# if KLIPS_DIVULGE_HMAC_KEY
37607+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37608+ "ipsec_sa_init: "
37609+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37610+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37611+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37612+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37613+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37614+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37615+
37616+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37617+
37618+ /* save the pointer to the key material */
37619+ akp = ipsp->ips_key_a;
37620+ aks = ipsp->ips_key_a_size;
37621+
37622+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37623+ "ipsec_sa_init: "
37624+ "allocating %lu bytes for md5_ctx.\n",
37625+ (unsigned long) sizeof(struct md5_ctx));
37626+ if((ipsp->ips_key_a = (caddr_t)
37627+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37628+ ipsp->ips_key_a = akp;
37629+ SENDERR(ENOMEM);
37630+ }
37631+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37632+
37633+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37634+ kb[i] = akp[i] ^ HMAC_IPAD;
37635+ }
37636+ for (; i < AHMD596_BLKLEN; i++) {
37637+ kb[i] = HMAC_IPAD;
37638+ }
37639+
37640+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37641+ osMD5Init(ictx);
37642+ osMD5Update(ictx, kb, AHMD596_BLKLEN);
37643+
37644+ for (i = 0; i < AHMD596_BLKLEN; i++) {
37645+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37646+ }
37647+
37648+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37649+ osMD5Init(octx);
37650+ osMD5Update(octx, kb, AHMD596_BLKLEN);
37651+
37652+# if KLIPS_DIVULGE_HMAC_KEY
37653+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37654+ "ipsec_sa_init: "
37655+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37656+ ((__u32*)ictx)[0],
37657+ ((__u32*)ictx)[1],
37658+ ((__u32*)ictx)[2],
37659+ ((__u32*)ictx)[3],
37660+ ((__u32*)octx)[0],
37661+ ((__u32*)octx)[1],
37662+ ((__u32*)octx)[2],
37663+ ((__u32*)octx)[3] );
37664+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37665+
37666+ /* zero key buffer -- paranoid */
37667+ memset(akp, 0, aks);
37668+ kfree(akp);
37669+ }
37670+ break;
37671+# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37672+# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37673+ case AH_SHA: {
37674+ unsigned char *akp;
37675+ unsigned int aks;
37676+ SHA1_CTX *ictx;
37677+ SHA1_CTX *octx;
37678+
37679+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37680+ KLIPS_PRINT(debug_pfkey,
37681+ "ipsec_sa_init: "
37682+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37683+ ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
37684+ SENDERR(EINVAL);
37685+ }
37686+
37687+# if KLIPS_DIVULGE_HMAC_KEY
37688+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37689+ "ipsec_sa_init: "
37690+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37691+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37692+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37693+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37694+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37695+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37696+
37697+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37698+
37699+ /* save the pointer to the key material */
37700+ akp = ipsp->ips_key_a;
37701+ aks = ipsp->ips_key_a_size;
37702+
37703+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37704+ "ipsec_sa_init: "
37705+ "allocating %lu bytes for sha1_ctx.\n",
37706+ (unsigned long) sizeof(struct sha1_ctx));
37707+ if((ipsp->ips_key_a = (caddr_t)
37708+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37709+ ipsp->ips_key_a = akp;
37710+ SENDERR(ENOMEM);
37711+ }
37712+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37713+
37714+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37715+ kb[i] = akp[i] ^ HMAC_IPAD;
37716+ }
37717+ for (; i < AHMD596_BLKLEN; i++) {
37718+ kb[i] = HMAC_IPAD;
37719+ }
37720+
37721+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37722+ SHA1Init(ictx);
37723+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37724+
37725+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
37726+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37727+ }
37728+
37729+ octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
37730+ SHA1Init(octx);
37731+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
37732+
37733+# if KLIPS_DIVULGE_HMAC_KEY
37734+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37735+ "ipsec_sa_init: "
37736+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37737+ ((__u32*)ictx)[0],
37738+ ((__u32*)ictx)[1],
37739+ ((__u32*)ictx)[2],
37740+ ((__u32*)ictx)[3],
37741+ ((__u32*)octx)[0],
37742+ ((__u32*)octx)[1],
37743+ ((__u32*)octx)[2],
37744+ ((__u32*)octx)[3] );
37745+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37746+ /* zero key buffer -- paranoid */
37747+ memset(akp, 0, aks);
37748+ kfree(akp);
37749+ }
37750+ break;
37751+# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37752+ default:
37753+ KLIPS_PRINT(debug_pfkey,
37754+ "ipsec_sa_init: "
37755+ "authalg=%d support not available in the kernel",
37756+ ipsp->ips_authalg);
37757+ SENDERR(EINVAL);
37758+ }
37759+ break;
37760+#endif /* CONFIG_KLIPS_AH */
37761+
37762+#ifdef CONFIG_KLIPS_ESP
37763+ case IPPROTO_ESP:
37764+ {
37765+#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37766+ unsigned char *akp;
37767+ unsigned int aks;
37768+#endif
37769+
37770+ ipsec_alg_sa_init(ipsp);
37771+ ixt_e=ipsp->ips_alg_enc;
37772+
37773+ if (ixt_e == NULL) {
37774+ if(printk_ratelimit()) {
37775+ printk(KERN_INFO
37776+ "ipsec_sa_init: "
37777+ "encalg=%d support not available in the kernel",
37778+ ipsp->ips_encalg);
37779+ }
37780+ SENDERR(ENOENT);
37781+ }
37782+
37783+ ipsp->ips_iv_size = ixt_e->ixt_common.ixt_support.ias_ivlen/8;
37784+
37785+ /* Create IV */
37786+ if (ipsp->ips_iv_size) {
37787+ if((ipsp->ips_iv = (caddr_t)
37788+ kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) {
37789+ SENDERR(ENOMEM);
37790+ }
37791+ prng_bytes(&ipsec_prng,
37792+ (char *)ipsp->ips_iv,
37793+ ipsp->ips_iv_size);
37794+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
37795+ }
37796+
37797+ if ((error=ipsec_alg_enc_key_create(ipsp)) < 0)
37798+ SENDERR(-error);
37799+
37800+ if ((ixt_a=ipsp->ips_alg_auth)) {
37801+ if ((error=ipsec_alg_auth_key_create(ipsp)) < 0)
37802+ SENDERR(-error);
37803+ } else
37804+
37805+ switch(ipsp->ips_authalg) {
37806+# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37807+ case AH_MD5: {
37808+ MD5_CTX *ictx;
37809+ MD5_CTX *octx;
37810+
37811+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37812+ KLIPS_PRINT(debug_pfkey,
37813+ "ipsec_sa_init: "
37814+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37815+ ipsp->ips_key_bits_a,
37816+ AHMD596_KLEN * 8);
37817+ SENDERR(EINVAL);
37818+ }
37819+
37820+# if KLIPS_DIVULGE_HMAC_KEY
37821+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37822+ "ipsec_sa_init: "
37823+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37824+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
37825+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
37826+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
37827+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
37828+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37829+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37830+
37831+ /* save the pointer to the key material */
37832+ akp = ipsp->ips_key_a;
37833+ aks = ipsp->ips_key_a_size;
37834+
37835+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37836+ "ipsec_sa_init: "
37837+ "allocating %lu bytes for md5_ctx.\n",
37838+ (unsigned long) sizeof(struct md5_ctx));
37839+ if((ipsp->ips_key_a = (caddr_t)
37840+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37841+ ipsp->ips_key_a = akp;
37842+ SENDERR(ENOMEM);
37843+ }
37844+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37845+
37846+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37847+ kb[i] = akp[i] ^ HMAC_IPAD;
37848+ }
37849+ for (; i < AHMD596_BLKLEN; i++) {
37850+ kb[i] = HMAC_IPAD;
37851+ }
37852+
37853+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37854+ osMD5Init(ictx);
37855+ osMD5Update(ictx, kb, AHMD596_BLKLEN);
37856+
37857+ for (i = 0; i < AHMD596_BLKLEN; i++) {
37858+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37859+ }
37860+
37861+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37862+ osMD5Init(octx);
37863+ osMD5Update(octx, kb, AHMD596_BLKLEN);
37864+
37865+# if KLIPS_DIVULGE_HMAC_KEY
37866+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37867+ "ipsec_sa_init: "
37868+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37869+ ((__u32*)ictx)[0],
37870+ ((__u32*)ictx)[1],
37871+ ((__u32*)ictx)[2],
37872+ ((__u32*)ictx)[3],
37873+ ((__u32*)octx)[0],
37874+ ((__u32*)octx)[1],
37875+ ((__u32*)octx)[2],
37876+ ((__u32*)octx)[3] );
37877+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37878+ /* paranoid */
37879+ memset(akp, 0, aks);
37880+ kfree(akp);
37881+ break;
37882+ }
37883+# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37884+# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37885+ case AH_SHA: {
37886+ SHA1_CTX *ictx;
37887+ SHA1_CTX *octx;
37888+
37889+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37890+ KLIPS_PRINT(debug_pfkey,
37891+ "ipsec_sa_init: "
37892+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37893+ ipsp->ips_key_bits_a,
37894+ AHSHA196_KLEN * 8);
37895+ SENDERR(EINVAL);
37896+ }
37897+
37898+# if KLIPS_DIVULGE_HMAC_KEY
37899+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37900+ "ipsec_sa_init: "
37901+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37902+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37903+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37904+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37905+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37906+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37907+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37908+
37909+ /* save the pointer to the key material */
37910+ akp = ipsp->ips_key_a;
37911+ aks = ipsp->ips_key_a_size;
37912+
37913+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37914+ "ipsec_sa_init: "
37915+ "allocating %lu bytes for sha1_ctx.\n",
37916+ (unsigned long) sizeof(struct sha1_ctx));
37917+ if((ipsp->ips_key_a = (caddr_t)
37918+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37919+ ipsp->ips_key_a = akp;
37920+ SENDERR(ENOMEM);
37921+ }
37922+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37923+
37924+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37925+ kb[i] = akp[i] ^ HMAC_IPAD;
37926+ }
37927+ for (; i < AHMD596_BLKLEN; i++) {
37928+ kb[i] = HMAC_IPAD;
37929+ }
37930+
37931+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37932+ SHA1Init(ictx);
37933+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37934+
37935+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
37936+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37937+ }
37938+
37939+ octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
37940+ SHA1Init(octx);
37941+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
37942+
37943+# if KLIPS_DIVULGE_HMAC_KEY
37944+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37945+ "ipsec_sa_init: "
37946+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37947+ ((__u32*)ictx)[0],
37948+ ((__u32*)ictx)[1],
37949+ ((__u32*)ictx)[2],
37950+ ((__u32*)ictx)[3],
37951+ ((__u32*)octx)[0],
37952+ ((__u32*)octx)[1],
37953+ ((__u32*)octx)[2],
37954+ ((__u32*)octx)[3] );
37955+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37956+ memset(akp, 0, aks);
37957+ kfree(akp);
37958+ break;
37959+ }
37960+# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37961+ case AH_NONE:
37962+ break;
37963+ default:
37964+ KLIPS_PRINT(debug_pfkey,
37965+ "ipsec_sa_init: "
37966+ "authalg=%d support not available in the kernel.\n",
37967+ ipsp->ips_authalg);
37968+ SENDERR(EINVAL);
37969+ }
37970+ }
37971+ break;
37972+#endif /* !CONFIG_KLIPS_ESP */
37973+#ifdef CONFIG_KLIPS_IPCOMP
37974+ case IPPROTO_COMP:
37975+ ipsp->ips_comp_adapt_tries = 0;
37976+ ipsp->ips_comp_adapt_skip = 0;
37977+ ipsp->ips_comp_ratio_cbytes = 0;
37978+ ipsp->ips_comp_ratio_dbytes = 0;
37979+ break;
37980+#endif /* CONFIG_KLIPS_IPCOMP */
37981+ default:
37982+ printk(KERN_ERR "KLIPS sa initialization: "
37983+ "proto=%d unknown.\n",
37984+ ipsp->ips_said.proto);
37985+ SENDERR(EINVAL);
37986+ }
37987+
37988+ errlab:
37989+ return(error);
37990+}
37991+
37992+
37993+
37994+/*
37995+ * $Log: ipsec_sa.c,v $
37996+ * Revision 1.30.2.2 2006/10/06 21:39:26 paul
37997+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
37998+ * set. This is defined through autoconf.h which is included through the
37999+ * linux kernel build macros.
38000+ *
38001+ * Revision 1.30.2.1 2006/04/20 16:33:07 mcr
38002+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
38003+ * Fix in-kernel module compilation. Sub-makefiles do not work.
38004+ *
38005+ * Revision 1.30 2005/05/24 01:02:35 mcr
38006+ * some refactoring/simplification of situation where alg
38007+ * is not found.
38008+ *
38009+ * Revision 1.29 2005/05/18 19:13:28 mcr
38010+ * rename debug messages. make sure that algo not found is not
38011+ * a debug message.
38012+ *
38013+ * Revision 1.28 2005/05/11 01:30:20 mcr
38014+ * removed "poor-man"s OOP in favour of proper C structures.
38015+ *
38016+ * Revision 1.27 2005/04/29 05:10:22 mcr
38017+ * removed from extraenous includes to make unit testing easier.
38018+ *
38019+ * Revision 1.26 2005/04/14 20:56:24 mcr
38020+ * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
38021+ *
38022+ * Revision 1.25 2004/08/22 20:12:16 mcr
38023+ * one more KLIPS_NAT->IPSEC_NAT.
38024+ *
38025+ * Revision 1.24 2004/07/10 19:11:18 mcr
38026+ * CONFIG_IPSEC -> CONFIG_KLIPS.
38027+ *
38028+ * Revision 1.23 2004/04/06 02:49:26 mcr
38029+ * pullup of algo code from alg-branch.
38030+ *
38031+ * Revision 1.22.2.1 2003/12/22 15:25:52 jjo
38032+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
38033+ *
38034+ * Revision 1.22 2003/12/10 01:14:27 mcr
38035+ * NAT-traversal patches to KLIPS.
38036+ *
38037+ * Revision 1.21 2003/10/31 02:27:55 mcr
38038+ * pulled up port-selector patches and sa_id elimination.
38039+ *
38040+ * Revision 1.20.4.1 2003/10/29 01:30:41 mcr
38041+ * elimited "struct sa_id".
38042+ *
38043+ * Revision 1.20 2003/02/06 01:50:34 rgb
38044+ * Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0.
38045+ *
38046+ * Revision 1.19 2003/01/30 02:32:22 rgb
38047+ *
38048+ * Rename SAref table macro names for clarity.
38049+ * Transmit error code through to caller from callee for better diagnosis of problems.
38050+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
38051+ *
38052+ * Revision 1.18 2002/10/12 23:11:53 dhr
38053+ *
38054+ * [KenB + DHR] more 64-bit cleanup
38055+ *
38056+ * Revision 1.17 2002/10/07 18:31:43 rgb
38057+ * Move field width sanity checks to ipsec_sa.c
38058+ *
38059+ * Revision 1.16 2002/09/20 15:41:02 rgb
38060+ * Re-wrote most of the SAref code to eliminate Entry pointers.
38061+ * Added SAref code compiler directive switch.
38062+ * Added a saref test function for testing macros.
38063+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
38064+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
38065+ * of freeing newly created structures when clearing the reftable upon startup
38066+ * to start from a known state.
38067+ * Place all ipsec sadb globals into one struct.
38068+ * Rework saref freelist.
38069+ * Added memory allocation debugging.
38070+ *
38071+ * Revision 1.15 2002/09/20 05:01:44 rgb
38072+ * Update copyright date.
38073+ *
38074+ * Revision 1.14 2002/08/13 19:01:25 mcr
38075+ * patches from kenb to permit compilation of FreeSWAN on ia64.
38076+ * des library patched to use proper DES_LONG type for ia64.
38077+ *
38078+ * Revision 1.13 2002/07/29 03:06:20 mcr
38079+ * get rid of variable not used warnings.
38080+ *
38081+ * Revision 1.12 2002/07/26 08:48:31 rgb
38082+ * Added SA ref table code.
38083+ *
38084+ * Revision 1.11 2002/06/04 16:48:49 rgb
38085+ * Tidied up pointer code for processor independance.
38086+ *
38087+ * Revision 1.10 2002/05/23 07:16:17 rgb
38088+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
38089+ * Pointer clean-up.
38090+ * Added refcount code.
38091+ * Convert "usecount" to "refcount" to remove ambiguity.
38092+ *
38093+ * Revision 1.9 2002/05/14 02:34:49 rgb
38094+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
38095+ * with "put" usage in the kernel.
38096+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
38097+ * ipsec_sa or ipsec_sa.
38098+ * Added some preliminary refcount code.
38099+ *
38100+ * Revision 1.8 2002/04/24 07:55:32 mcr
38101+ * #include patches and Makefiles for post-reorg compilation.
38102+ *
38103+ * Revision 1.7 2002/04/24 07:36:30 mcr
38104+ * Moved from ./klips/net/ipsec/ipsec_sa.c,v
38105+ *
38106+ * Revision 1.6 2002/04/20 00:12:25 rgb
38107+ * Added esp IV CBC attack fix, disabled.
38108+ *
38109+ * Revision 1.5 2002/01/29 17:17:56 mcr
38110+ * moved include of ipsec_param.h to after include of linux/kernel.h
38111+ * otherwise, it seems that some option that is set in ipsec_param.h
38112+ * screws up something subtle in the include path to kernel.h, and
38113+ * it complains on the snprintf() prototype.
38114+ *
38115+ * Revision 1.4 2002/01/29 04:00:52 mcr
38116+ * more excise of kversions.h header.
38117+ *
38118+ * Revision 1.3 2002/01/29 02:13:18 mcr
38119+ * introduction of ipsec_kversion.h means that include of
38120+ * ipsec_param.h must preceed any decisions about what files to
38121+ * include to deal with differences in kernel source.
38122+ *
38123+ * Revision 1.2 2001/11/26 09:16:15 rgb
38124+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
38125+ *
38126+ * Revision 1.1.2.2 2001/10/22 21:05:41 mcr
38127+ * removed phony prototype for des_set_key.
38128+ *
38129+ * Revision 1.1.2.1 2001/09/25 02:24:57 mcr
38130+ * struct tdb -> struct ipsec_sa.
38131+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
38132+ * ipsec_xform.c removed. header file still contains useful things.
38133+ *
38134+ *
38135+ *
38136+ * CLONED from ipsec_xform.c:
38137+ * Revision 1.53 2001/09/08 21:13:34 rgb
38138+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
38139+ *
38140+ * Revision 1.52 2001/06/14 19:35:11 rgb
38141+ * Update copyright date.
38142+ *
38143+ * Revision 1.51 2001/05/30 08:14:03 rgb
38144+ * Removed vestiges of esp-null transforms.
38145+ *
38146+ * Revision 1.50 2001/05/03 19:43:18 rgb
38147+ * Initialise error return variable.
38148+ * Update SENDERR macro.
38149+ * Fix sign of error return code for ipsec_tdbcleanup().
38150+ * Use more appropriate return code for ipsec_tdbwipe().
38151+ *
38152+ * Revision 1.49 2001/04/19 18:56:17 rgb
38153+ * Fixed tdb table locking comments.
38154+ *
38155+ * Revision 1.48 2001/02/27 22:24:55 rgb
38156+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
38157+ * Check for satoa() return codes.
38158+ *
38159+ * Revision 1.47 2000/11/06 04:32:08 rgb
38160+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
38161+ *
38162+ * Revision 1.46 2000/09/20 16:21:57 rgb
38163+ * Cleaned up ident string alloc/free.
38164+ *
38165+ * Revision 1.45 2000/09/08 19:16:51 rgb
38166+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
38167+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
38168+ *
38169+ * Revision 1.44 2000/08/30 05:29:04 rgb
38170+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
38171+ *
38172+ * Revision 1.43 2000/08/18 21:30:41 rgb
38173+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
38174+ *
38175+ * Revision 1.42 2000/08/01 14:51:51 rgb
38176+ * Removed _all_ remaining traces of DES.
38177+ *
38178+ * Revision 1.41 2000/07/28 14:58:31 rgb
38179+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
38180+ *
38181+ * Revision 1.40 2000/06/28 05:50:11 rgb
38182+ * Actually set iv_bits.
38183+ *
38184+ * Revision 1.39 2000/05/10 23:11:09 rgb
38185+ * Added netlink debugging output.
38186+ * Added a cast to quiet down the ntohl bug.
38187+ *
38188+ * Revision 1.38 2000/05/10 19:18:42 rgb
38189+ * Cast output of ntohl so that the broken prototype doesn't make our
38190+ * compile noisy.
38191+ *
38192+ * Revision 1.37 2000/03/16 14:04:59 rgb
38193+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
38194+ *
38195+ * Revision 1.36 2000/01/26 10:11:28 rgb
38196+ * Fixed spacing in error text causing run-in words.
38197+ *
38198+ * Revision 1.35 2000/01/21 06:17:16 rgb
38199+ * Tidied up compiler directive indentation for readability.
38200+ * Added ictx,octx vars for simplification.(kravietz)
38201+ * Added macros for HMAC padding magic numbers.(kravietz)
38202+ * Fixed missing key length reporting bug.
38203+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
38204+ *
38205+ * Revision 1.34 1999/12/08 00:04:19 rgb
38206+ * Fixed SA direction overwriting bug for netlink users.
38207+ *
38208+ * Revision 1.33 1999/12/01 22:16:44 rgb
38209+ * Minor formatting changes in ESP MD5 initialisation.
38210+ *
38211+ * Revision 1.32 1999/11/25 09:06:36 rgb
38212+ * Fixed error return messages, should be returning negative numbers.
38213+ * Implemented SENDERR macro for propagating error codes.
38214+ * Added debug message and separate error code for algorithms not compiled
38215+ * in.
38216+ *
38217+ * Revision 1.31 1999/11/23 23:06:26 rgb
38218+ * Sort out pfkey and freeswan headers, putting them in a library path.
38219+ *
38220+ * Revision 1.30 1999/11/18 04:09:20 rgb
38221+ * Replaced all kernel version macros to shorter, readable form.
38222+ *
38223+ * Revision 1.29 1999/11/17 15:53:40 rgb
38224+ * Changed all occurrences of #include "../../../lib/freeswan.h"
38225+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
38226+ * klips/net/ipsec/Makefile.
38227+ *
38228+ * Revision 1.28 1999/10/18 20:04:01 rgb
38229+ * Clean-out unused cruft.
38230+ *
38231+ * Revision 1.27 1999/10/03 19:01:03 rgb
38232+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
38233+ *
38234+ * Revision 1.26 1999/10/01 16:22:24 rgb
38235+ * Switch from assignment init. to functional init. of spinlocks.
38236+ *
38237+ * Revision 1.25 1999/10/01 15:44:54 rgb
38238+ * Move spinlock header include to 2.1> scope.
38239+ *
38240+ * Revision 1.24 1999/10/01 00:03:46 rgb
38241+ * Added tdb structure locking.
38242+ * Minor formatting changes.
38243+ * Add function to initialize tdb hash table.
38244+ *
38245+ * Revision 1.23 1999/05/25 22:42:12 rgb
38246+ * Add deltdbchain() debugging.
38247+ *
38248+ * Revision 1.22 1999/05/25 21:24:31 rgb
38249+ * Add debugging statements to deltdbchain().
38250+ *
38251+ * Revision 1.21 1999/05/25 03:51:48 rgb
38252+ * Refix error return code.
38253+ *
38254+ * Revision 1.20 1999/05/25 03:34:07 rgb
38255+ * Fix error return for flush.
38256+ *
38257+ * Revision 1.19 1999/05/09 03:25:37 rgb
38258+ * Fix bug introduced by 2.2 quick-and-dirty patch.
38259+ *
38260+ * Revision 1.18 1999/05/05 22:02:32 rgb
38261+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
38262+ *
38263+ * Revision 1.17 1999/04/29 15:20:16 rgb
38264+ * Change gettdb parameter to a pointer to reduce stack loading and
38265+ * facilitate parameter sanity checking.
38266+ * Add sanity checking for null pointer arguments.
38267+ * Add debugging instrumentation.
38268+ * Add function deltdbchain() which will take care of unlinking,
38269+ * zeroing and deleting a chain of tdbs.
38270+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
38271+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
38272+ * structures.
38273+ *
38274+ * Revision 1.16 1999/04/16 15:36:29 rgb
38275+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
38276+ *
38277+ * Revision 1.15 1999/04/11 00:29:01 henry
38278+ * GPL boilerplate
38279+ *
38280+ * Revision 1.14 1999/04/06 04:54:28 rgb
38281+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
38282+ * patch shell fixes.
38283+ *
38284+ * Revision 1.13 1999/02/19 18:23:01 rgb
38285+ * Nix debug off compile warning.
38286+ *
38287+ * Revision 1.12 1999/02/17 16:52:16 rgb
38288+ * Consolidate satoa()s for space and speed efficiency.
38289+ * Convert DEBUG_IPSEC to KLIPS_PRINT
38290+ * Clean out unused cruft.
38291+ * Ditch NET_IPIP dependancy.
38292+ * Loop for 3des key setting.
38293+ *
38294+ * Revision 1.11 1999/01/26 02:09:05 rgb
38295+ * Remove ah/esp/IPIP switching on include files.
38296+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
38297+ * Removed dead code.
38298+ * Clean up debug code when switched off.
38299+ * Remove references to INET_GET_PROTOCOL.
38300+ * Added code exclusion macros to reduce code from unused algorithms.
38301+ *
38302+ * Revision 1.10 1999/01/22 06:28:55 rgb
38303+ * Cruft clean-out.
38304+ * Put random IV generation in kernel.
38305+ * Added algorithm switch code.
38306+ * Enhanced debugging.
38307+ * 64-bit clean-up.
38308+ *
38309+ * Revision 1.9 1998/11/30 13:22:55 rgb
38310+ * Rationalised all the klips kernel file headers. They are much shorter
38311+ * now and won't conflict under RH5.2.
38312+ *
38313+ * Revision 1.8 1998/11/25 04:59:06 rgb
38314+ * Add conditionals for no IPIP tunnel code.
38315+ * Delete commented out code.
38316+ *
38317+ * Revision 1.7 1998/10/31 06:50:41 rgb
38318+ * Convert xform ASCII names to no spaces.
38319+ * Fixed up comments in #endif directives.
38320+ *
38321+ * Revision 1.6 1998/10/19 14:44:28 rgb
38322+ * Added inclusion of freeswan.h.
38323+ * sa_id structure implemented and used: now includes protocol.
38324+ *
38325+ * Revision 1.5 1998/10/09 04:32:19 rgb
38326+ * Added 'klips_debug' prefix to all klips printk debug statements.
38327+ *
38328+ * Revision 1.4 1998/08/12 00:11:31 rgb
38329+ * Added new xform functions to the xform table.
38330+ * Fixed minor debug output spelling error.
38331+ *
38332+ * Revision 1.3 1998/07/09 17:45:31 rgb
38333+ * Clarify algorithm not available message.
38334+ *
38335+ * Revision 1.2 1998/06/23 03:00:51 rgb
38336+ * Check for presence of IPIP protocol if it is setup one way (we don't
38337+ * know what has been set up the other way and can only assume it will be
38338+ * symmetrical with the exception of keys).
38339+ *
38340+ * Revision 1.1 1998/06/18 21:27:51 henry
38341+ * move sources from klips/src to klips/net/ipsec, to keep stupid
38342+ * kernel-build scripts happier in the presence of symlinks
38343+ *
38344+ * Revision 1.3 1998/06/11 05:54:59 rgb
38345+ * Added transform version string pointer to xformsw initialisations.
38346+ *
38347+ * Revision 1.2 1998/04/21 21:28:57 rgb
38348+ * Rearrange debug switches to change on the fly debug output from user
38349+ * space. Only kernel changes checked in at this time. radij.c was also
38350+ * changed to temporarily remove buggy debugging code in rj_delete causing
38351+ * an OOPS and hence, netlink device open errors.
38352+ *
38353+ * Revision 1.1 1998/04/09 03:06:13 henry
38354+ * sources moved up from linux/net/ipsec
38355+ *
38356+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
38357+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
38358+ *
38359+ * Revision 0.5 1997/06/03 04:24:48 ji
38360+ * Added ESP-3DES-MD5-96
38361+ *
38362+ * Revision 0.4 1997/01/15 01:28:15 ji
38363+ * Added new transforms.
38364+ *
38365+ * Revision 0.3 1996/11/20 14:39:04 ji
38366+ * Minor cleanups.
38367+ * Rationalized debugging code.
38368+ *
38369+ * Revision 0.2 1996/11/02 00:18:33 ji
38370+ * First limited release.
38371+ *
38372+ *
38373+ */
38374--- /dev/null Tue Mar 11 13:02:56 2003
38375+++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004
38376@@ -0,0 +1,219 @@
38377+/*
38378+ * RCSID $Id: ipsec_sha1.c,v 1.9 2004/04/06 02:49:26 mcr Exp $
38379+ */
38380+
38381+/*
38382+ * The rest of the code is derived from sha1.c by Steve Reid, which is
38383+ * public domain.
38384+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
38385+ */
38386+
38387+#include <asm/byteorder.h>
38388+#include <linux/string.h>
38389+
38390+#include "openswan/ipsec_sha1.h"
38391+
38392+#if defined(rol)
38393+#undef rol
38394+#endif
38395+
38396+#define SHA1HANDSOFF
38397+
38398+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
38399+
38400+/* blk0() and blk() perform the initial expand. */
38401+/* I got the idea of expanding during the round function from SSLeay */
38402+#ifdef __LITTLE_ENDIAN
38403+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
38404+ |(rol(block->l[i],8)&0x00FF00FF))
38405+#else
38406+#define blk0(i) block->l[i]
38407+#endif
38408+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
38409+ ^block->l[(i+2)&15]^block->l[i&15],1))
38410+
38411+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
38412+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
38413+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
38414+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
38415+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
38416+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
38417+
38418+
38419+/* Hash a single 512-bit block. This is the core of the algorithm. */
38420+
38421+void SHA1Transform(__u32 state[5], __u8 buffer[64])
38422+{
38423+__u32 a, b, c, d, e;
38424+typedef union {
38425+ unsigned char c[64];
38426+ __u32 l[16];
38427+} CHAR64LONG16;
38428+CHAR64LONG16* block;
38429+#ifdef SHA1HANDSOFF
38430+static unsigned char workspace[64];
38431+ block = (CHAR64LONG16*)workspace;
38432+ memcpy(block, buffer, 64);
38433+#else
38434+ block = (CHAR64LONG16*)buffer;
38435+#endif
38436+ /* Copy context->state[] to working vars */
38437+ a = state[0];
38438+ b = state[1];
38439+ c = state[2];
38440+ d = state[3];
38441+ e = state[4];
38442+ /* 4 rounds of 20 operations each. Loop unrolled. */
38443+ 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);
38444+ 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);
38445+ 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);
38446+ 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);
38447+ 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);
38448+ 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);
38449+ 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);
38450+ 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);
38451+ 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);
38452+ 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);
38453+ 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);
38454+ 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);
38455+ 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);
38456+ 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);
38457+ 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);
38458+ 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);
38459+ 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);
38460+ 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);
38461+ 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);
38462+ 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);
38463+ /* Add the working vars back into context.state[] */
38464+ state[0] += a;
38465+ state[1] += b;
38466+ state[2] += c;
38467+ state[3] += d;
38468+ state[4] += e;
38469+ /* Wipe variables */
38470+ a = b = c = d = e = 0;
38471+}
38472+
38473+
38474+/* SHA1Init - Initialize new context */
38475+
38476+void SHA1Init(void *vcontext)
38477+{
38478+ SHA1_CTX* context = vcontext;
38479+
38480+ /* SHA1 initialization constants */
38481+ context->state[0] = 0x67452301;
38482+ context->state[1] = 0xEFCDAB89;
38483+ context->state[2] = 0x98BADCFE;
38484+ context->state[3] = 0x10325476;
38485+ context->state[4] = 0xC3D2E1F0;
38486+ context->count[0] = context->count[1] = 0;
38487+}
38488+
38489+
38490+/* Run your data through this. */
38491+
38492+void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
38493+{
38494+ SHA1_CTX* context = vcontext;
38495+ __u32 i, j;
38496+
38497+ j = context->count[0];
38498+ if ((context->count[0] += len << 3) < j)
38499+ context->count[1]++;
38500+ context->count[1] += (len>>29);
38501+ j = (j >> 3) & 63;
38502+ if ((j + len) > 63) {
38503+ memcpy(&context->buffer[j], data, (i = 64-j));
38504+ SHA1Transform(context->state, context->buffer);
38505+ for ( ; i + 63 < len; i += 64) {
38506+ SHA1Transform(context->state, &data[i]);
38507+ }
38508+ j = 0;
38509+ }
38510+ else i = 0;
38511+ memcpy(&context->buffer[j], &data[i], len - i);
38512+}
38513+
38514+
38515+/* Add padding and return the message digest. */
38516+
38517+void SHA1Final(unsigned char digest[20], void *vcontext)
38518+{
38519+ __u32 i, j;
38520+ unsigned char finalcount[8];
38521+ SHA1_CTX* context = vcontext;
38522+
38523+ for (i = 0; i < 8; i++) {
38524+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
38525+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
38526+ }
38527+ SHA1Update(context, (unsigned char *)"\200", 1);
38528+ while ((context->count[0] & 504) != 448) {
38529+ SHA1Update(context, (unsigned char *)"\0", 1);
38530+ }
38531+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
38532+ for (i = 0; i < 20; i++) {
38533+ digest[i] = (unsigned char)
38534+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
38535+ }
38536+ /* Wipe variables */
38537+ i = j = 0;
38538+ memset(context->buffer, 0, 64);
38539+ memset(context->state, 0, 20);
38540+ memset(context->count, 0, 8);
38541+ memset(&finalcount, 0, 8);
38542+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
38543+ SHA1Transform(context->state, context->buffer);
38544+#endif
38545+}
38546+
38547+
38548+/*
38549+ * $Log: ipsec_sha1.c,v $
38550+ * Revision 1.9 2004/04/06 02:49:26 mcr
38551+ * pullup of algo code from alg-branch.
38552+ *
38553+ * Revision 1.8 2002/09/10 01:45:14 mcr
38554+ * changed type of MD5_CTX and SHA1_CTX to void * so that
38555+ * the function prototypes would match, and could be placed
38556+ * into a pointer to a function.
38557+ *
38558+ * Revision 1.7 2002/04/24 07:55:32 mcr
38559+ * #include patches and Makefiles for post-reorg compilation.
38560+ *
38561+ * Revision 1.6 2002/04/24 07:36:30 mcr
38562+ * Moved from ./klips/net/ipsec/ipsec_sha1.c,v
38563+ *
38564+ * Revision 1.5 1999/12/13 13:59:13 rgb
38565+ * Quick fix to argument size to Update bugs.
38566+ *
38567+ * Revision 1.4 1999/04/11 00:29:00 henry
38568+ * GPL boilerplate
38569+ *
38570+ * Revision 1.3 1999/04/06 04:54:27 rgb
38571+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
38572+ * patch shell fixes.
38573+ *
38574+ * Revision 1.2 1999/01/22 06:55:50 rgb
38575+ * 64-bit clean-up.
38576+ *
38577+ * Revision 1.1 1998/06/18 21:27:50 henry
38578+ * move sources from klips/src to klips/net/ipsec, to keep stupid
38579+ * kernel-build scripts happier in the presence of symlinks
38580+ *
38581+ * Revision 1.2 1998/04/23 20:54:04 rgb
38582+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
38583+ * verified.
38584+ *
38585+ * Revision 1.1 1998/04/09 03:06:11 henry
38586+ * sources moved up from linux/net/ipsec
38587+ *
38588+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
38589+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
38590+ *
38591+ * Revision 0.4 1997/01/15 01:28:15 ji
38592+ * New transform
38593+ *
38594+ *
38595+ */
38596--- /dev/null Tue Mar 11 13:02:56 2003
38597+++ linux/net/ipsec/ipsec_snprintf.c Mon Feb 9 13:51:03 2004
38598@@ -0,0 +1,135 @@
38599+/*
38600+ * @(#) ipsec_snprintf() function
38601+ *
38602+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
38603+ * 2001 Michael Richardson <mcr@freeswan.org>
38604+ * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
38605+ *
38606+ * This program is free software; you can redistribute it and/or modify it
38607+ * under the terms of the GNU General Public License as published by the
38608+ * Free Software Foundation; either version 2 of the License, or (at your
38609+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
38610+ *
38611+ * This program is distributed in the hope that it will be useful, but
38612+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
38613+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38614+ * for more details.
38615+ *
38616+ * Split out from ipsec_proc.c.
38617+ */
38618+
38619+#ifndef AUTOCONF_INCLUDED
38620+#include <linux/config.h>
38621+#endif
38622+#include <linux/version.h>
38623+#define __NO_VERSION__
38624+#include <linux/module.h>
38625+#include <linux/kernel.h> /* printk() */
38626+
38627+#include "openswan/ipsec_kversion.h"
38628+#include "openswan/ipsec_param.h"
38629+
38630+#include <net/ip.h>
38631+
38632+#include "openswan/radij.h"
38633+
38634+#include "openswan/ipsec_life.h"
38635+#include "openswan/ipsec_stats.h"
38636+#include "openswan/ipsec_sa.h"
38637+
38638+#include "openswan/ipsec_encap.h"
38639+#include "openswan/ipsec_radij.h"
38640+#include "openswan/ipsec_xform.h"
38641+#include "openswan/ipsec_tunnel.h"
38642+#include "openswan/ipsec_xmit.h"
38643+
38644+#include "openswan/ipsec_rcv.h"
38645+#include "openswan/ipsec_ah.h"
38646+#include "openswan/ipsec_esp.h"
38647+#include "openswan/ipsec_kern24.h"
38648+
38649+#ifdef CONFIG_KLIPS_IPCOMP
38650+#include "openswan/ipcomp.h"
38651+#endif /* CONFIG_KLIPS_IPCOMP */
38652+
38653+#include "openswan/ipsec_proto.h"
38654+
38655+#include <pfkeyv2.h>
38656+#include <pfkey.h>
38657+
38658+/* ipsec_snprintf: like snprintf except
38659+ * - size is signed and a negative value is treated as if it were 0
38660+ * - the returned result is never negative --
38661+ * an error generates a "?" or null output (depending on space).
38662+ * (Our callers are too lazy to check for an error return.)
38663+ *
38664+ * @param buf String buffer
38665+ * @param size Size of the string
38666+ * @param fmt printf string
38667+ * @param ... Variables to be displayed in fmt
38668+ * @return int Return code
38669+ */
38670+int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
38671+{
38672+ va_list args;
38673+ int i;
38674+ size_t possize = size < 0? 0 : size;
38675+ va_start(args, fmt);
38676+ i = vsnprintf(buf,possize,fmt,args);
38677+ va_end(args);
38678+ if (i < 0) {
38679+ /* create empty output in place of error */
38680+ i = 0;
38681+ if (size > 0) {
38682+ *buf = '\0';
38683+ }
38684+ }
38685+ return i;
38686+}
38687+
38688+
38689+void ipsec_dmp_block(char *s, caddr_t bb, int len)
38690+{
38691+ int i;
38692+ unsigned char *b = bb;
38693+
38694+ printk(KERN_INFO "klips_dmp: "
38695+ "at %s, len=%d:\n", s, len);
38696+
38697+ for(i = 0; i < len; i++ /*, c++*/) {
38698+ if(!(i % 16)) {
38699+ printk(KERN_INFO
38700+ "klips_debug: @%03x:",
38701+ i);
38702+ }
38703+ printk(" %02x", b[i]);
38704+ if(!((i + 1) % 16)) {
38705+ printk("\n");
38706+ }
38707+ }
38708+ if(i % 16) {
38709+ printk("\n");
38710+ }
38711+}
38712+
38713+/*
38714+ *
38715+ * $Log: ipsec_snprintf.c,v $
38716+ * Revision 1.3.2.1 2006/10/06 21:39:26 paul
38717+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
38718+ * set. This is defined through autoconf.h which is included through the
38719+ * linux kernel build macros.
38720+ *
38721+ * Revision 1.3 2005/04/29 05:10:22 mcr
38722+ * removed from extraenous includes to make unit testing easier.
38723+ *
38724+ * Revision 1.2 2005/04/15 00:32:01 mcr
38725+ * added ipsec_dmp_block routine.
38726+ *
38727+ *
38728+ * Local Variables:
38729+ * c-file-style: "linux"
38730+ * End:
38731+ *
38732+ */
38733+
38734--- /dev/null Tue Mar 11 13:02:56 2003
38735+++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004
38736@@ -0,0 +1,2878 @@
38737+/*
38738+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
38739+ * Copyright (C) 1996, 1997 John Ioannidis.
38740+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
38741+ *
38742+ * This program is free software; you can redistribute it and/or modify it
38743+ * under the terms of the GNU General Public License as published by the
38744+ * Free Software Foundation; either version 2 of the License, or (at your
38745+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
38746+ *
38747+ * This program is distributed in the hope that it will be useful, but
38748+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
38749+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38750+ * for more details.
38751+ */
38752+
38753+char ipsec_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.232.2.5 2006/10/06 21:39:26 paul Exp $";
38754+
38755+#define __NO_VERSION__
38756+#include <linux/module.h>
38757+#ifndef AUTOCONF_INCLUDED
38758+#include <linux/config.h>
38759+#endif /* for CONFIG_IP_FORWARD */
38760+#include <linux/version.h>
38761+#include <linux/kernel.h> /* printk() */
38762+
38763+#include "openswan/ipsec_param.h"
38764+
38765+#ifdef MALLOC_SLAB
38766+# include <linux/slab.h> /* kmalloc() */
38767+#else /* MALLOC_SLAB */
38768+# include <linux/malloc.h> /* kmalloc() */
38769+#endif /* MALLOC_SLAB */
38770+#include <linux/errno.h> /* error codes */
38771+#include <linux/types.h> /* size_t */
38772+#include <linux/interrupt.h> /* mark_bh */
38773+
38774+#include <net/tcp.h>
38775+#include <net/udp.h>
38776+#include <linux/skbuff.h>
38777+
38778+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
38779+#include <linux/etherdevice.h> /* eth_type_trans */
38780+#include <linux/ip.h> /* struct iphdr */
38781+#include <linux/skbuff.h>
38782+
38783+#include <openswan.h>
38784+
38785+#ifdef NET_21
38786+# include <linux/in6.h>
38787+# define ip_chk_addr inet_addr_type
38788+# define IS_MYADDR RTN_LOCAL
38789+# include <net/dst.h>
38790+# undef dev_kfree_skb
38791+# define dev_kfree_skb(a,b) kfree_skb(a)
38792+# define PHYSDEV_TYPE
38793+#endif /* NET_21 */
38794+
38795+#include <net/icmp.h> /* icmp_send() */
38796+#include <net/ip.h>
38797+#ifdef NETDEV_23
38798+# include <linux/netfilter_ipv4.h>
38799+#endif /* NETDEV_23 */
38800+
38801+#include <linux/if_arp.h>
38802+#include <net/arp.h>
38803+
38804+#include "openswan/ipsec_kversion.h"
38805+#include "openswan/radij.h"
38806+#include "openswan/ipsec_life.h"
38807+#include "openswan/ipsec_xform.h"
38808+#include "openswan/ipsec_eroute.h"
38809+#include "openswan/ipsec_encap.h"
38810+#include "openswan/ipsec_radij.h"
38811+#include "openswan/ipsec_sa.h"
38812+#include "openswan/ipsec_tunnel.h"
38813+#include "openswan/ipsec_xmit.h"
38814+#include "openswan/ipsec_ipe4.h"
38815+#include "openswan/ipsec_ah.h"
38816+#include "openswan/ipsec_esp.h"
38817+#include "openswan/ipsec_kern24.h"
38818+
38819+#include <pfkeyv2.h>
38820+#include <pfkey.h>
38821+
38822+#include "openswan/ipsec_proto.h"
38823+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
38824+#include <linux/udp.h>
38825+#endif
38826+
38827+static __u32 zeroes[64];
38828+
38829+#ifdef CONFIG_KLIPS_DEBUG
38830+int debug_tunnel = 0;
38831+#endif /* CONFIG_KLIPS_DEBUG */
38832+
38833+DEBUG_NO_STATIC int
38834+ipsec_tunnel_open(struct net_device *dev)
38835+{
38836+ struct ipsecpriv *prv = dev->priv;
38837+
38838+ /*
38839+ * Can't open until attached.
38840+ */
38841+
38842+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
38843+ "klips_debug:ipsec_tunnel_open: "
38844+ "dev = %s, prv->dev = %s\n",
38845+ dev->name, prv->dev?prv->dev->name:"NONE");
38846+
38847+ if (prv->dev == NULL)
38848+ return -ENODEV;
38849+
38850+ KLIPS_INC_USE;
38851+ return 0;
38852+}
38853+
38854+DEBUG_NO_STATIC int
38855+ipsec_tunnel_close(struct net_device *dev)
38856+{
38857+ KLIPS_DEC_USE;
38858+ return 0;
38859+}
38860+
38861+#ifdef NETDEV_23
38862+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
38863+{
38864+#ifdef NETDEV_25 /* 2.6 kernels */
38865+ return dst_output(skb);
38866+#else
38867+ return ip_send(skb);
38868+#endif
38869+}
38870+#endif /* NETDEV_23 */
38871+
38872+enum ipsec_xmit_value
38873+ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs)
38874+{
38875+ /* ixs->physdev->hard_header_len is unreliable and should not be used */
38876+ ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data;
38877+
38878+ if(ixs->hard_header_len < 0) {
38879+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38880+ "klips_error:ipsec_xmit_strip_hard_header: "
38881+ "Negative hard_header_len (%d)?!\n", ixs->hard_header_len);
38882+ ixs->stats->tx_dropped++;
38883+ return IPSEC_XMIT_BADHHLEN;
38884+ }
38885+
38886+ /* while ixs->physdev->hard_header_len is unreliable and
38887+ * should not be trusted, it accurate and required for ATM, GRE and
38888+ * some other interfaces to work. Thanks to Willy Tarreau
38889+ * <willy@w.ods.org>.
38890+ */
38891+ if(ixs->hard_header_len == 0) { /* no hard header present */
38892+ ixs->hard_header_stripped = 1;
38893+ ixs->hard_header_len = ixs->physdev->hard_header_len;
38894+ }
38895+
38896+#ifdef CONFIG_KLIPS_DEBUG
38897+ if (debug_tunnel & DB_TN_XMIT) {
38898+ int i;
38899+ char c;
38900+
38901+ printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: "
38902+ ">>> skb->len=%ld hard_header_len:%d",
38903+ (unsigned long int)ixs->skb->len, ixs->hard_header_len);
38904+ c = ' ';
38905+ for (i=0; i < ixs->hard_header_len; i++) {
38906+ printk("%c%02x", c, ixs->skb->data[i]);
38907+ c = ':';
38908+ }
38909+ printk(" \n");
38910+ }
38911+#endif /* CONFIG_KLIPS_DEBUG */
38912+
38913+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
38914+
38915+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
38916+ "klips_debug:ipsec_xmit_strip_hard_header: "
38917+ "Original head,tailroom: %d,%d\n",
38918+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
38919+
38920+ return IPSEC_XMIT_OK;
38921+}
38922+
38923+enum ipsec_xmit_value
38924+ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs)
38925+{
38926+ unsigned int bypass;
38927+
38928+ bypass = FALSE;
38929+
38930+ /*
38931+ * First things first -- look us up in the erouting tables.
38932+ */
38933+ ixs->matcher.sen_len = sizeof (struct sockaddr_encap);
38934+ ixs->matcher.sen_family = AF_ENCAP;
38935+ ixs->matcher.sen_type = SENT_IP4;
38936+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
38937+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
38938+ ixs->matcher.sen_proto = ixs->iph->protocol;
38939+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
38940+
38941+ /*
38942+ * The spinlock is to prevent any other process from accessing or deleting
38943+ * the eroute while we are using and updating it.
38944+ */
38945+ spin_lock(&eroute_lock);
38946+
38947+ ixs->eroute = ipsec_findroute(&ixs->matcher);
38948+
38949+ if(ixs->iph->protocol == IPPROTO_UDP) {
38950+ struct udphdr *t = NULL;
38951+
38952+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38953+ "klips_debug:udp port check: "
38954+ "fragoff: %d len: %d>%ld \n",
38955+ ntohs(ixs->iph->frag_off) & IP_OFFSET,
38956+ (ixs->skb->len - ixs->hard_header_len),
38957+ (unsigned long int) ((ixs->iph->ihl << 2) + sizeof(struct udphdr)));
38958+
38959+ if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
38960+ ((ixs->skb->len - ixs->hard_header_len) >=
38961+ ((ixs->iph->ihl << 2) + sizeof(struct udphdr))))
38962+ {
38963+ t =((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
38964+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38965+ "klips_debug:udp port in packet: "
38966+ "port %d -> %d\n",
38967+ ntohs(t->source), ntohs(t->dest));
38968+ }
38969+
38970+ ixs->sport=0; ixs->dport=0;
38971+
38972+ if(ixs->skb->sk) {
38973+#ifdef NET_26
38974+ struct udp_sock *us;
38975+
38976+ us = (struct udp_sock *)ixs->skb->sk;
38977+
38978+ ixs->sport = ntohs(us->inet.sport);
38979+ ixs->dport = ntohs(us->inet.dport);
38980+#else
38981+ ixs->sport = ntohs(ixs->skb->sk->sport);
38982+ ixs->dport = ntohs(ixs->skb->sk->dport);
38983+#endif
38984+
38985+ }
38986+
38987+ if(t != NULL) {
38988+ if(ixs->sport == 0) {
38989+ ixs->sport = ntohs(t->source);
38990+ }
38991+ if(ixs->dport == 0) {
38992+ ixs->dport = ntohs(t->dest);
38993+ }
38994+ }
38995+ }
38996+
38997+ /*
38998+ * practically identical to above, but let's be careful about
38999+ * tcp vs udp headers
39000+ */
39001+ if(ixs->iph->protocol == IPPROTO_TCP) {
39002+ struct tcphdr *t = NULL;
39003+
39004+ if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
39005+ ((ixs->skb->len - ixs->hard_header_len) >=
39006+ ((ixs->iph->ihl << 2) + sizeof(struct tcphdr)))) {
39007+ t =((struct tcphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
39008+ }
39009+
39010+ ixs->sport=0; ixs->dport=0;
39011+
39012+ if(ixs->skb->sk) {
39013+#ifdef NET_26
39014+#ifdef HAVE_INET_SK_SPORT
39015+ ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
39016+ ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
39017+#else
39018+ struct tcp_tw_bucket *tw;
39019+
39020+ tw = (struct tcp_tw_bucket *)ixs->skb->sk;
39021+
39022+ ixs->sport = ntohs(tw->tw_sport);
39023+ ixs->dport = ntohs(tw->tw_dport);
39024+#endif
39025+#else
39026+ ixs->sport = ntohs(ixs->skb->sk->sport);
39027+ ixs->dport = ntohs(ixs->skb->sk->dport);
39028+#endif
39029+ }
39030+
39031+ if(t != NULL) {
39032+ if(ixs->sport == 0) {
39033+ ixs->sport = ntohs(t->source);
39034+ }
39035+ if(ixs->dport == 0) {
39036+ ixs->dport = ntohs(t->dest);
39037+ }
39038+ }
39039+ }
39040+
39041+ /* default to a %drop eroute */
39042+ ixs->outgoing_said.proto = IPPROTO_INT;
39043+ ixs->outgoing_said.spi = htonl(SPI_DROP);
39044+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
39045+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39046+ "klips_debug:ipsec_xmit_SAlookup: "
39047+ "checking for local udp/500 IKE packet "
39048+ "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
39049+ ntohl((unsigned int)ixs->iph->saddr),
39050+ ixs->eroute,
39051+ ntohl((unsigned int)ixs->iph->daddr),
39052+ ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0,
39053+ ixs->iph->protocol,
39054+ ixs->sport,
39055+ ixs->dport);
39056+
39057+ /*
39058+ * cheat for now...are we udp/500? If so, let it through
39059+ * without interference since it is most likely an IKE packet.
39060+ */
39061+
39062+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
39063+ && (ixs->eroute==NULL
39064+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
39065+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
39066+ && (ixs->iph->protocol == IPPROTO_UDP &&
39067+ (ixs->sport == 500 || ixs->sport == 4500))) {
39068+ /* Whatever the eroute, this is an IKE message
39069+ * from us (i.e. not being forwarded).
39070+ * Furthermore, if there is a tunnel eroute,
39071+ * the destination is the peer for this eroute.
39072+ * So %pass the packet: modify the default %drop.
39073+ */
39074+
39075+ ixs->outgoing_said.spi = htonl(SPI_PASS);
39076+ if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) {
39077+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39078+ "klips_debug:ipsec_xmit_SAlookup: "
39079+ "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
39080+ }
39081+ bypass = TRUE;
39082+ }
39083+
39084+#ifdef KLIPS_EXCEPT_DNS53
39085+ /*
39086+ *
39087+ * if we are udp/53 or tcp/53, also let it through a %trap or %hold,
39088+ * since it is DNS, but *also* follow the %trap.
39089+ *
39090+ * we do not do this for tunnels, only %trap's and %hold's.
39091+ *
39092+ */
39093+
39094+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
39095+ && (ixs->eroute==NULL
39096+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
39097+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
39098+ && ((ixs->iph->protocol == IPPROTO_UDP
39099+ || ixs->iph->protocol == IPPROTO_TCP)
39100+ && ixs->dport == 53)) {
39101+
39102+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39103+ "klips_debug:ipsec_xmit_SAlookup: "
39104+ "possible DNS packet\n");
39105+
39106+ if(ixs->eroute)
39107+ {
39108+ if(ixs->eroute->er_said.spi == htonl(SPI_TRAP)
39109+ || ixs->eroute->er_said.spi == htonl(SPI_HOLD))
39110+ {
39111+ ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
39112+ bypass = TRUE;
39113+ }
39114+ }
39115+ else
39116+ {
39117+ ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
39118+ bypass = TRUE;
39119+ }
39120+
39121+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39122+ "klips_debug:ipsec_xmit_SAlookup: "
39123+ "bypass = %d\n", bypass);
39124+
39125+ if(bypass
39126+ && !(ixs->skb->sk)
39127+ && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0))
39128+ {
39129+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39130+ "klips_debug:ipsec_xmit_SAlookup: "
39131+ "local port 53 (probably DNS) passthrough:"
39132+ "base fragment, rest of fragments will "
39133+ "probably get filtered.\n");
39134+ }
39135+ }
39136+#endif
39137+
39138+ if (bypass==FALSE && ixs->eroute) {
39139+ ixs->eroute->er_count++;
39140+ ixs->eroute->er_lasttime = jiffies/HZ;
39141+ if(ixs->eroute->er_said.proto==IPPROTO_INT
39142+ && ixs->eroute->er_said.spi==htonl(SPI_HOLD))
39143+ {
39144+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39145+ "klips_debug:ipsec_xmit_SAlookup: "
39146+ "shunt SA of HOLD: skb stored in HOLD.\n");
39147+ if(ixs->eroute->er_last != NULL) {
39148+ kfree_skb(ixs->eroute->er_last);
39149+ }
39150+ ixs->eroute->er_last = ixs->skb;
39151+ ixs->skb = NULL;
39152+ ixs->stats->tx_dropped++;
39153+ spin_unlock(&eroute_lock);
39154+ return IPSEC_XMIT_STOLEN;
39155+ }
39156+ ixs->outgoing_said = ixs->eroute->er_said;
39157+ ixs->eroute_pid = ixs->eroute->er_pid;
39158+
39159+ /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
39160+ if(ixs->outgoing_said.proto==IPPROTO_INT
39161+ && (ixs->outgoing_said.spi==htonl(SPI_TRAP)
39162+ || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
39163+ int len;
39164+
39165+ ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type;
39166+ ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id;
39167+ ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len;
39168+ if (ixs->ips.ips_ident_s.len)
39169+ {
39170+ len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
39171+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39172+ "klips_debug:ipsec_xmit_SAlookup: "
39173+ "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
39174+ len);
39175+ if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
39176+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
39177+ "Failed, tried to allocate %d bytes for source ident.\n",
39178+ len);
39179+ ixs->stats->tx_dropped++;
39180+ spin_unlock(&eroute_lock);
39181+ return IPSEC_XMIT_ERRMEMALLOC;
39182+ }
39183+ memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len);
39184+ }
39185+ ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type;
39186+ ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id;
39187+ ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len;
39188+ if (ixs->ips.ips_ident_d.len)
39189+ {
39190+ len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
39191+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39192+ "klips_debug:ipsec_xmit_SAlookup: "
39193+ "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
39194+ len);
39195+ if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
39196+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
39197+ "Failed, tried to allocate %d bytes for dest ident.\n",
39198+ len);
39199+ ixs->stats->tx_dropped++;
39200+ spin_unlock(&eroute_lock);
39201+ return IPSEC_XMIT_ERRMEMALLOC;
39202+ }
39203+ memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len);
39204+ }
39205+ }
39206+ }
39207+
39208+ spin_unlock(&eroute_lock);
39209+ return IPSEC_XMIT_OK;
39210+}
39211+
39212+
39213+enum ipsec_xmit_value
39214+ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs)
39215+{
39216+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39217+ "klips_debug:ipsec_xmit_restore_hard_header: "
39218+ "After recursive xforms -- head,tailroom: %d,%d\n",
39219+ skb_headroom(ixs->skb),
39220+ skb_tailroom(ixs->skb));
39221+
39222+ if(ixs->saved_header) {
39223+ if(skb_headroom(ixs->skb) < ixs->hard_header_len) {
39224+ printk(KERN_WARNING
39225+ "klips_error:ipsec_xmit_restore_hard_header: "
39226+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
39227+ ixs->hard_header_len,
39228+ skb_headroom(ixs->skb));
39229+ ixs->stats->tx_errors++;
39230+ return IPSEC_XMIT_PUSHPULLERR;
39231+
39232+ }
39233+ skb_push(ixs->skb, ixs->hard_header_len);
39234+ {
39235+ int i;
39236+ for (i = 0; i < ixs->hard_header_len; i++) {
39237+ ixs->skb->data[i] = ixs->saved_header[i];
39238+ }
39239+ }
39240+ }
39241+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39242+ if (ixs->natt_type && ixs->natt_head) {
39243+ struct iphdr *ipp = ixs->skb->nh.iph;
39244+ struct udphdr *udp;
39245+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39246+ "klips_debug:ipsec_tunnel_start_xmit: "
39247+ "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
39248+ ixs->natt_type, ixs->natt_head);
39249+
39250+ ixs->iphlen = ipp->ihl << 2;
39251+ ipp->tot_len =
39252+ htons(ntohs(ipp->tot_len) + ixs->natt_head);
39253+ if(skb_tailroom(ixs->skb) < ixs->natt_head) {
39254+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
39255+ "tried to skb_put %d, %d available. "
39256+ "This should never happen, please report.\n",
39257+ ixs->natt_head,
39258+ skb_tailroom(ixs->skb));
39259+ ixs->stats->tx_errors++;
39260+ return IPSEC_XMIT_ESPUDP;
39261+ }
39262+ skb_put(ixs->skb, ixs->natt_head);
39263+
39264+ udp = (struct udphdr *)((char *)ipp + ixs->iphlen);
39265+
39266+ /* move ESP hdr after UDP hdr */
39267+ memmove((void *)((char *)udp + ixs->natt_head),
39268+ (void *)(udp),
39269+ ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head);
39270+
39271+ /* clear UDP & Non-IKE Markers (if any) */
39272+ memset(udp, 0, ixs->natt_head);
39273+
39274+ /* fill UDP with usefull informations ;-) */
39275+ udp->source = htons(ixs->natt_sport);
39276+ udp->dest = htons(ixs->natt_dport);
39277+ udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen);
39278+
39279+ /* set protocol */
39280+ ipp->protocol = IPPROTO_UDP;
39281+
39282+ /* fix IP checksum */
39283+ ipp->check = 0;
39284+ ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
39285+ }
39286+#endif
39287+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39288+ "klips_debug:ipsec_xmit_restore_hard_header: "
39289+ "With hard_header, final head,tailroom: %d,%d\n",
39290+ skb_headroom(ixs->skb),
39291+ skb_tailroom(ixs->skb));
39292+
39293+ return IPSEC_XMIT_OK;
39294+}
39295+
39296+enum ipsec_xmit_value
39297+ipsec_tunnel_send(struct ipsec_xmit_state*ixs)
39298+{
39299+#ifdef NETDEV_25
39300+ struct flowi fl;
39301+#endif
39302+
39303+#ifdef NET_21 /* 2.2 and 2.4 kernels */
39304+ /* new route/dst cache code from James Morris */
39305+ ixs->skb->dev = ixs->physdev;
39306+#ifdef NETDEV_25
39307+ memset (&fl, 0x0, sizeof (struct flowi));
39308+ fl.oif = ixs->physdev->iflink;
39309+ fl.nl_u.ip4_u.daddr = ixs->skb->nh.iph->daddr;
39310+ fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ixs->skb->nh.iph->saddr;
39311+ fl.nl_u.ip4_u.tos = RT_TOS(ixs->skb->nh.iph->tos);
39312+ fl.proto = ixs->skb->nh.iph->protocol;
39313+ if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) {
39314+#else
39315+ /*skb_orphan(ixs->skb);*/
39316+ if((ixs->error = ip_route_output(&ixs->route,
39317+ ixs->skb->nh.iph->daddr,
39318+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
39319+ RT_TOS(ixs->skb->nh.iph->tos),
39320+ /* mcr->rgb: should this be 0 instead? */
39321+ ixs->physdev->iflink))) {
39322+#endif
39323+ ixs->stats->tx_errors++;
39324+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39325+ "klips_debug:ipsec_xmit_send: "
39326+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
39327+ ixs->error,
39328+ ixs->route->u.dst.dev->name);
39329+ return IPSEC_XMIT_ROUTEERR;
39330+ }
39331+ if(ixs->dev == ixs->route->u.dst.dev) {
39332+ ip_rt_put(ixs->route);
39333+ /* This is recursion, drop it. */
39334+ ixs->stats->tx_errors++;
39335+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39336+ "klips_debug:ipsec_xmit_send: "
39337+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
39338+ ixs->dev->name);
39339+ return IPSEC_XMIT_RECURSDETECT;
39340+ }
39341+ dst_release(ixs->skb->dst);
39342+ ixs->skb->dst = &ixs->route->u.dst;
39343+ ixs->stats->tx_bytes += ixs->skb->len;
39344+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
39345+ ixs->stats->tx_errors++;
39346+ printk(KERN_WARNING
39347+ "klips_error:ipsec_xmit_send: "
39348+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
39349+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
39350+ ixs->skb->len);
39351+ return IPSEC_XMIT_PUSHPULLERR;
39352+ }
39353+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
39354+#ifdef SKB_RESET_NFCT
39355+ if(!ixs->pass) {
39356+ nf_conntrack_put(ixs->skb->nfct);
39357+ ixs->skb->nfct = NULL;
39358+ }
39359+#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
39360+ ixs->skb->nf_debug = 0;
39361+#endif /* CONFIG_NETFILTER_DEBUG */
39362+#endif /* SKB_RESET_NFCT */
39363+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39364+ "klips_debug:ipsec_xmit_send: "
39365+ "...done, calling ip_send() on device:%s\n",
39366+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
39367+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->skb->nh.iph);
39368+#ifdef NETDEV_23 /* 2.4 kernels */
39369+ {
39370+ int err;
39371+
39372+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
39373+ ipsec_tunnel_xmit2);
39374+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
39375+ if(net_ratelimit())
39376+ printk(KERN_ERR
39377+ "klips_error:ipsec_xmit_send: "
39378+ "ip_send() failed, err=%d\n",
39379+ -err);
39380+ ixs->stats->tx_errors++;
39381+ ixs->stats->tx_aborted_errors++;
39382+ ixs->skb = NULL;
39383+ return IPSEC_XMIT_IPSENDFAILURE;
39384+ }
39385+ }
39386+#else /* NETDEV_23 */ /* 2.2 kernels */
39387+ ip_send(ixs->skb);
39388+#endif /* NETDEV_23 */
39389+#else /* NET_21 */ /* 2.0 kernels */
39390+ ixs->skb->arp = 1;
39391+ /* ISDN/ASYNC PPP from Matjaz Godec. */
39392+ /* skb->protocol = htons(ETH_P_IP); */
39393+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39394+ "klips_debug:ipsec_xmit_send: "
39395+ "...done, calling dev_queue_xmit() or ip_fragment().\n");
39396+ IP_SEND(ixs->skb, ixs->physdev);
39397+#endif /* NET_21 */
39398+ ixs->stats->tx_packets++;
39399+
39400+ ixs->skb = NULL;
39401+
39402+ return IPSEC_XMIT_OK;
39403+}
39404+
39405+void
39406+ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs)
39407+{
39408+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
39409+ netif_wake_queue(ixs->dev);
39410+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
39411+ ixs->dev->tbusy = 0;
39412+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
39413+ if(ixs->saved_header) {
39414+ kfree(ixs->saved_header);
39415+ }
39416+ if(ixs->skb) {
39417+ dev_kfree_skb(ixs->skb, FREE_WRITE);
39418+ }
39419+ if(ixs->oskb) {
39420+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
39421+ }
39422+ if (ixs->ips.ips_ident_s.data) {
39423+ kfree(ixs->ips.ips_ident_s.data);
39424+ }
39425+ if (ixs->ips.ips_ident_d.data) {
39426+ kfree(ixs->ips.ips_ident_d.data);
39427+ }
39428+}
39429+
39430+/*
39431+ * This function assumes it is being called from dev_queue_xmit()
39432+ * and that skb is filled properly by that function.
39433+ */
39434+int
39435+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev)
39436+{
39437+ struct ipsec_xmit_state ixs_mem;
39438+ struct ipsec_xmit_state *ixs = &ixs_mem;
39439+ enum ipsec_xmit_value stat;
39440+
39441+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39442+ ixs->natt_type = 0, ixs->natt_head = 0;
39443+ ixs->natt_sport = 0, ixs->natt_dport = 0;
39444+#endif
39445+
39446+ memset((caddr_t)ixs, 0, sizeof(*ixs));
39447+ ixs->oskb = NULL;
39448+ ixs->saved_header = NULL; /* saved copy of the hard header */
39449+ ixs->route = NULL;
39450+ memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips));
39451+ ixs->dev = dev;
39452+ ixs->skb = skb;
39453+
39454+ stat = ipsec_xmit_sanity_check_dev(ixs);
39455+ if(stat != IPSEC_XMIT_OK) {
39456+ goto cleanup;
39457+ }
39458+
39459+ stat = ipsec_xmit_sanity_check_skb(ixs);
39460+ if(stat != IPSEC_XMIT_OK) {
39461+ goto cleanup;
39462+ }
39463+
39464+ stat = ipsec_tunnel_strip_hard_header(ixs);
39465+ if(stat != IPSEC_XMIT_OK) {
39466+ goto cleanup;
39467+ }
39468+
39469+ stat = ipsec_tunnel_SAlookup(ixs);
39470+ if(stat != IPSEC_XMIT_OK) {
39471+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39472+ "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n",
39473+ stat);
39474+ goto cleanup;
39475+ }
39476+
39477+ ixs->innersrc = ixs->iph->saddr;
39478+ /* start encapsulation loop here XXX */
39479+ do {
39480+ stat = ipsec_xmit_encap_bundle(ixs);
39481+ if(stat != IPSEC_XMIT_OK) {
39482+ if(stat == IPSEC_XMIT_PASS) {
39483+ goto bypass;
39484+ }
39485+
39486+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39487+ "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n",
39488+ stat);
39489+ goto cleanup;
39490+ }
39491+
39492+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
39493+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
39494+ ixs->matcher.sen_proto = ixs->iph->protocol;
39495+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
39496+
39497+ spin_lock(&eroute_lock);
39498+ ixs->eroute = ipsec_findroute(&ixs->matcher);
39499+ if(ixs->eroute) {
39500+ ixs->outgoing_said = ixs->eroute->er_said;
39501+ ixs->eroute_pid = ixs->eroute->er_pid;
39502+ ixs->eroute->er_count++;
39503+ ixs->eroute->er_lasttime = jiffies/HZ;
39504+ }
39505+ spin_unlock(&eroute_lock);
39506+
39507+ KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
39508+ /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */
39509+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
39510+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
39511+ ixs->eroute,
39512+ "klips_debug:ipsec_tunnel_start_xmit: "
39513+ "We are recursing here.\n");
39514+
39515+ } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/
39516+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
39517+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
39518+ ixs->eroute);
39519+
39520+ stat = ipsec_tunnel_restore_hard_header(ixs);
39521+ if(stat != IPSEC_XMIT_OK) {
39522+ goto cleanup;
39523+ }
39524+
39525+ bypass:
39526+ stat = ipsec_tunnel_send(ixs);
39527+
39528+ cleanup:
39529+ ipsec_tunnel_cleanup(ixs);
39530+
39531+ return 0;
39532+}
39533+
39534+DEBUG_NO_STATIC struct net_device_stats *
39535+ipsec_tunnel_get_stats(struct net_device *dev)
39536+{
39537+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
39538+}
39539+
39540+/*
39541+ * Revectored calls.
39542+ * For each of these calls, a field exists in our private structure.
39543+ */
39544+
39545+DEBUG_NO_STATIC int
39546+ipsec_tunnel_hard_header(struct sk_buff *skb, struct net_device *dev,
39547+ unsigned short type, void *daddr, void *saddr, unsigned len)
39548+{
39549+ struct ipsecpriv *prv = dev->priv;
39550+ struct net_device *tmp;
39551+ int ret;
39552+ struct net_device_stats *stats; /* This device's statistics */
39553+
39554+ if(skb == NULL) {
39555+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39556+ "klips_debug:ipsec_tunnel_hard_header: "
39557+ "no skb...\n");
39558+ return -ENODATA;
39559+ }
39560+
39561+ if(dev == NULL) {
39562+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39563+ "klips_debug:ipsec_tunnel_hard_header: "
39564+ "no device...\n");
39565+ return -ENODEV;
39566+ }
39567+
39568+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39569+ "klips_debug:ipsec_tunnel_hard_header: "
39570+ "skb->dev=%s dev=%s.\n",
39571+ skb->dev ? skb->dev->name : "NULL",
39572+ dev->name);
39573+
39574+ if(prv == NULL) {
39575+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39576+ "klips_debug:ipsec_tunnel_hard_header: "
39577+ "no private space associated with dev=%s\n",
39578+ dev->name ? dev->name : "NULL");
39579+ return -ENODEV;
39580+ }
39581+
39582+ stats = (struct net_device_stats *) &(prv->mystats);
39583+
39584+ if(prv->dev == NULL) {
39585+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39586+ "klips_debug:ipsec_tunnel_hard_header: "
39587+ "no physical device associated with dev=%s\n",
39588+ dev->name ? dev->name : "NULL");
39589+ stats->tx_dropped++;
39590+ return -ENODEV;
39591+ }
39592+
39593+ /* check if we have to send a IPv6 packet. It might be a Router
39594+ Solicitation, where the building of the packet happens in
39595+ reverse order:
39596+ 1. ll hdr,
39597+ 2. IPv6 hdr,
39598+ 3. ICMPv6 hdr
39599+ -> skb->nh.raw is still uninitialized when this function is
39600+ called!! If this is no IPv6 packet, we can print debugging
39601+ messages, otherwise we skip all debugging messages and just
39602+ build the ll header */
39603+ if(type != ETH_P_IPV6) {
39604+ /* execute this only, if we don't have to build the
39605+ header for a IPv6 packet */
39606+ if(!prv->hard_header) {
39607+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39608+ "klips_debug:ipsec_tunnel_hard_header: "
39609+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
39610+ saddr,
39611+ daddr,
39612+ len,
39613+ type,
39614+ dev->name);
39615+#ifdef NET_21
39616+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39617+ "ip=%08x->%08x\n",
39618+ (__u32)ntohl(skb->nh.iph->saddr),
39619+ (__u32)ntohl(skb->nh.iph->daddr) );
39620+#else /* NET_21 */
39621+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39622+ "ip=%08x->%08x\n",
39623+ (__u32)ntohl(skb->ip_hdr->saddr),
39624+ (__u32)ntohl(skb->ip_hdr->daddr) );
39625+#endif /* NET_21 */
39626+ stats->tx_dropped++;
39627+ return -ENODEV;
39628+ }
39629+
39630+#define da ((struct net_device *)(prv->dev))->dev_addr
39631+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39632+ "klips_debug:ipsec_tunnel_hard_header: "
39633+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
39634+ saddr,
39635+ daddr,
39636+ len,
39637+ type,
39638+ dev->name,
39639+ prv->dev->name,
39640+ da[0], da[1], da[2], da[3], da[4], da[5]);
39641+#ifdef NET_21
39642+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39643+ "ip=%08x->%08x\n",
39644+ (__u32)ntohl(skb->nh.iph->saddr),
39645+ (__u32)ntohl(skb->nh.iph->daddr) );
39646+#else /* NET_21 */
39647+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39648+ "ip=%08x->%08x\n",
39649+ (__u32)ntohl(skb->ip_hdr->saddr),
39650+ (__u32)ntohl(skb->ip_hdr->daddr) );
39651+#endif /* NET_21 */
39652+ } else {
39653+ KLIPS_PRINT(debug_tunnel,
39654+ "klips_debug:ipsec_tunnel_hard_header: "
39655+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
39656+ }
39657+ tmp = skb->dev;
39658+ skb->dev = prv->dev;
39659+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
39660+ skb->dev = tmp;
39661+ return ret;
39662+}
39663+
39664+DEBUG_NO_STATIC int
39665+#ifdef NET_21
39666+ipsec_tunnel_rebuild_header(struct sk_buff *skb)
39667+#else /* NET_21 */
39668+ipsec_tunnel_rebuild_header(void *buff, struct net_device *dev,
39669+ unsigned long raddr, struct sk_buff *skb)
39670+#endif /* NET_21 */
39671+{
39672+ struct ipsecpriv *prv = skb->dev->priv;
39673+ struct net_device *tmp;
39674+ int ret;
39675+ struct net_device_stats *stats; /* This device's statistics */
39676+
39677+ if(skb->dev == NULL) {
39678+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39679+ "klips_debug:ipsec_tunnel_rebuild_header: "
39680+ "no device...");
39681+ return -ENODEV;
39682+ }
39683+
39684+ if(prv == NULL) {
39685+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39686+ "klips_debug:ipsec_tunnel_rebuild_header: "
39687+ "no private space associated with dev=%s",
39688+ skb->dev->name ? skb->dev->name : "NULL");
39689+ return -ENODEV;
39690+ }
39691+
39692+ stats = (struct net_device_stats *) &(prv->mystats);
39693+
39694+ if(prv->dev == NULL) {
39695+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39696+ "klips_debug:ipsec_tunnel_rebuild_header: "
39697+ "no physical device associated with dev=%s",
39698+ skb->dev->name ? skb->dev->name : "NULL");
39699+ stats->tx_dropped++;
39700+ return -ENODEV;
39701+ }
39702+
39703+ if(!prv->rebuild_header) {
39704+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39705+ "klips_debug:ipsec_tunnel_rebuild_header: "
39706+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
39707+ skb->dev->name);
39708+#ifdef NET_21
39709+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39710+ "ip=%08x->%08x\n",
39711+ (__u32)ntohl(skb->nh.iph->saddr),
39712+ (__u32)ntohl(skb->nh.iph->daddr) );
39713+#else /* NET_21 */
39714+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39715+ "ip=%08x->%08x\n",
39716+ (__u32)ntohl(skb->ip_hdr->saddr),
39717+ (__u32)ntohl(skb->ip_hdr->daddr) );
39718+#endif /* NET_21 */
39719+ stats->tx_dropped++;
39720+ return -ENODEV;
39721+ }
39722+
39723+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39724+ "klips_debug:ipsec_tunnel: "
39725+ "Revectored rebuild_header dev=%s->%s ",
39726+ skb->dev->name, prv->dev->name);
39727+#ifdef NET_21
39728+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39729+ "ip=%08x->%08x\n",
39730+ (__u32)ntohl(skb->nh.iph->saddr),
39731+ (__u32)ntohl(skb->nh.iph->daddr) );
39732+#else /* NET_21 */
39733+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39734+ "ip=%08x->%08x\n",
39735+ (__u32)ntohl(skb->ip_hdr->saddr),
39736+ (__u32)ntohl(skb->ip_hdr->daddr) );
39737+#endif /* NET_21 */
39738+ tmp = skb->dev;
39739+ skb->dev = prv->dev;
39740+
39741+#ifdef NET_21
39742+ ret = prv->rebuild_header(skb);
39743+#else /* NET_21 */
39744+ ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
39745+#endif /* NET_21 */
39746+ skb->dev = tmp;
39747+ return ret;
39748+}
39749+
39750+DEBUG_NO_STATIC int
39751+ipsec_tunnel_set_mac_address(struct net_device *dev, void *addr)
39752+{
39753+ struct ipsecpriv *prv = dev->priv;
39754+
39755+ struct net_device_stats *stats; /* This device's statistics */
39756+
39757+ if(dev == NULL) {
39758+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39759+ "klips_debug:ipsec_tunnel_set_mac_address: "
39760+ "no device...");
39761+ return -ENODEV;
39762+ }
39763+
39764+ if(prv == NULL) {
39765+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39766+ "klips_debug:ipsec_tunnel_set_mac_address: "
39767+ "no private space associated with dev=%s",
39768+ dev->name ? dev->name : "NULL");
39769+ return -ENODEV;
39770+ }
39771+
39772+ stats = (struct net_device_stats *) &(prv->mystats);
39773+
39774+ if(prv->dev == NULL) {
39775+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39776+ "klips_debug:ipsec_tunnel_set_mac_address: "
39777+ "no physical device associated with dev=%s",
39778+ dev->name ? dev->name : "NULL");
39779+ stats->tx_dropped++;
39780+ return -ENODEV;
39781+ }
39782+
39783+ if(!prv->set_mac_address) {
39784+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39785+ "klips_debug:ipsec_tunnel_set_mac_address: "
39786+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39787+ dev->name);
39788+ return -ENODEV;
39789+ }
39790+
39791+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39792+ "klips_debug:ipsec_tunnel_set_mac_address: "
39793+ "Revectored dev=%s->%s addr=0p%p\n",
39794+ dev->name, prv->dev->name, addr);
39795+ return prv->set_mac_address(prv->dev, addr);
39796+
39797+}
39798+
39799+#ifndef NET_21
39800+DEBUG_NO_STATIC void
39801+ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct net_device *dev,
39802+ unsigned short htype, __u32 daddr)
39803+{
39804+ struct ipsecpriv *prv = dev->priv;
39805+
39806+ struct net_device_stats *stats; /* This device's statistics */
39807+
39808+ if(dev == NULL) {
39809+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39810+ "klips_debug:ipsec_tunnel_cache_bind: "
39811+ "no device...");
39812+ return;
39813+ }
39814+
39815+ if(prv == NULL) {
39816+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39817+ "klips_debug:ipsec_tunnel_cache_bind: "
39818+ "no private space associated with dev=%s",
39819+ dev->name ? dev->name : "NULL");
39820+ return;
39821+ }
39822+
39823+ stats = (struct net_device_stats *) &(prv->mystats);
39824+
39825+ if(prv->dev == NULL) {
39826+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39827+ "klips_debug:ipsec_tunnel_cache_bind: "
39828+ "no physical device associated with dev=%s",
39829+ dev->name ? dev->name : "NULL");
39830+ stats->tx_dropped++;
39831+ return;
39832+ }
39833+
39834+ if(!prv->header_cache_bind) {
39835+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39836+ "klips_debug:ipsec_tunnel_cache_bind: "
39837+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39838+ dev->name);
39839+ stats->tx_dropped++;
39840+ return;
39841+ }
39842+
39843+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39844+ "klips_debug:ipsec_tunnel_cache_bind: "
39845+ "Revectored \n");
39846+ prv->header_cache_bind(hhp, prv->dev, htype, daddr);
39847+ return;
39848+}
39849+#endif /* !NET_21 */
39850+
39851+
39852+DEBUG_NO_STATIC void
39853+ipsec_tunnel_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
39854+{
39855+ struct ipsecpriv *prv = dev->priv;
39856+
39857+ struct net_device_stats *stats; /* This device's statistics */
39858+
39859+ if(dev == NULL) {
39860+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39861+ "klips_debug:ipsec_tunnel_cache_update: "
39862+ "no device...");
39863+ return;
39864+ }
39865+
39866+ if(prv == NULL) {
39867+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39868+ "klips_debug:ipsec_tunnel_cache_update: "
39869+ "no private space associated with dev=%s",
39870+ dev->name ? dev->name : "NULL");
39871+ return;
39872+ }
39873+
39874+ stats = (struct net_device_stats *) &(prv->mystats);
39875+
39876+ if(prv->dev == NULL) {
39877+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39878+ "klips_debug:ipsec_tunnel_cache_update: "
39879+ "no physical device associated with dev=%s",
39880+ dev->name ? dev->name : "NULL");
39881+ stats->tx_dropped++;
39882+ return;
39883+ }
39884+
39885+ if(!prv->header_cache_update) {
39886+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39887+ "klips_debug:ipsec_tunnel_cache_update: "
39888+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39889+ dev->name);
39890+ return;
39891+ }
39892+
39893+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39894+ "klips_debug:ipsec_tunnel: "
39895+ "Revectored cache_update\n");
39896+ prv->header_cache_update(hh, prv->dev, haddr);
39897+ return;
39898+}
39899+
39900+#ifdef NET_21
39901+DEBUG_NO_STATIC int
39902+ipsec_tunnel_neigh_setup(struct neighbour *n)
39903+{
39904+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39905+ "klips_debug:ipsec_tunnel_neigh_setup:\n");
39906+
39907+ if (n->nud_state == NUD_NONE) {
39908+ n->ops = &arp_broken_ops;
39909+ n->output = n->ops->output;
39910+ }
39911+ return 0;
39912+}
39913+
39914+DEBUG_NO_STATIC int
39915+ipsec_tunnel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
39916+{
39917+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39918+ "klips_debug:ipsec_tunnel_neigh_setup_dev: "
39919+ "setting up %s\n",
39920+ dev ? dev->name : "NULL");
39921+
39922+ if (p->tbl->family == AF_INET) {
39923+ p->neigh_setup = ipsec_tunnel_neigh_setup;
39924+ p->ucast_probes = 0;
39925+ p->mcast_probes = 0;
39926+ }
39927+ return 0;
39928+}
39929+#endif /* NET_21 */
39930+
39931+/*
39932+ * We call the attach routine to attach another device.
39933+ */
39934+
39935+DEBUG_NO_STATIC int
39936+ipsec_tunnel_attach(struct net_device *dev, struct net_device *physdev)
39937+{
39938+ int i;
39939+ struct ipsecpriv *prv = dev->priv;
39940+
39941+ if(dev == NULL) {
39942+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39943+ "klips_debug:ipsec_tunnel_attach: "
39944+ "no device...");
39945+ return -ENODEV;
39946+ }
39947+
39948+ if(prv == NULL) {
39949+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39950+ "klips_debug:ipsec_tunnel_attach: "
39951+ "no private space associated with dev=%s",
39952+ dev->name ? dev->name : "NULL");
39953+ return -ENODATA;
39954+ }
39955+
39956+ prv->dev = physdev;
39957+ prv->hard_start_xmit = physdev->hard_start_xmit;
39958+ prv->get_stats = physdev->get_stats;
39959+
39960+ if (physdev->hard_header) {
39961+ prv->hard_header = physdev->hard_header;
39962+ dev->hard_header = ipsec_tunnel_hard_header;
39963+ } else
39964+ dev->hard_header = NULL;
39965+
39966+ if (physdev->rebuild_header) {
39967+ prv->rebuild_header = physdev->rebuild_header;
39968+ dev->rebuild_header = ipsec_tunnel_rebuild_header;
39969+ } else
39970+ dev->rebuild_header = NULL;
39971+
39972+ if (physdev->set_mac_address) {
39973+ prv->set_mac_address = physdev->set_mac_address;
39974+ dev->set_mac_address = ipsec_tunnel_set_mac_address;
39975+ } else
39976+ dev->set_mac_address = NULL;
39977+
39978+#ifndef NET_21
39979+ if (physdev->header_cache_bind) {
39980+ prv->header_cache_bind = physdev->header_cache_bind;
39981+ dev->header_cache_bind = ipsec_tunnel_cache_bind;
39982+ } else
39983+ dev->header_cache_bind = NULL;
39984+#endif /* !NET_21 */
39985+
39986+ if (physdev->header_cache_update) {
39987+ prv->header_cache_update = physdev->header_cache_update;
39988+ dev->header_cache_update = ipsec_tunnel_cache_update;
39989+ } else
39990+ dev->header_cache_update = NULL;
39991+
39992+ dev->hard_header_len = physdev->hard_header_len;
39993+
39994+#ifdef NET_21
39995+/* prv->neigh_setup = physdev->neigh_setup; */
39996+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
39997+#endif /* NET_21 */
39998+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
39999+ prv->mtu = physdev->mtu;
40000+
40001+#ifdef PHYSDEV_TYPE
40002+ dev->type = physdev->type; /* ARPHRD_TUNNEL; */
40003+#endif /* PHYSDEV_TYPE */
40004+
40005+ dev->addr_len = physdev->addr_len;
40006+ for (i=0; i<dev->addr_len; i++) {
40007+ dev->dev_addr[i] = physdev->dev_addr[i];
40008+ }
40009+#ifdef CONFIG_KLIPS_DEBUG
40010+ if(debug_tunnel & DB_TN_INIT) {
40011+ printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
40012+ "physical device %s being attached has HW address: %2x",
40013+ physdev->name, physdev->dev_addr[0]);
40014+ for (i=1; i < physdev->addr_len; i++) {
40015+ printk(":%02x", physdev->dev_addr[i]);
40016+ }
40017+ printk("\n");
40018+ }
40019+#endif /* CONFIG_KLIPS_DEBUG */
40020+
40021+ return 0;
40022+}
40023+
40024+/*
40025+ * We call the detach routine to detach the ipsec tunnel from another device.
40026+ */
40027+
40028+DEBUG_NO_STATIC int
40029+ipsec_tunnel_detach(struct net_device *dev)
40030+{
40031+ int i;
40032+ struct ipsecpriv *prv = dev->priv;
40033+
40034+ if(dev == NULL) {
40035+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40036+ "klips_debug:ipsec_tunnel_detach: "
40037+ "no device...");
40038+ return -ENODEV;
40039+ }
40040+
40041+ if(prv == NULL) {
40042+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40043+ "klips_debug:ipsec_tunnel_detach: "
40044+ "no private space associated with dev=%s",
40045+ dev->name ? dev->name : "NULL");
40046+ return -ENODATA;
40047+ }
40048+
40049+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40050+ "klips_debug:ipsec_tunnel_detach: "
40051+ "physical device %s being detached from virtual device %s\n",
40052+ prv->dev ? prv->dev->name : "NULL",
40053+ dev->name);
40054+
40055+ ipsec_dev_put(prv->dev);
40056+ prv->dev = NULL;
40057+ prv->hard_start_xmit = NULL;
40058+ prv->get_stats = NULL;
40059+
40060+ prv->hard_header = NULL;
40061+#ifdef DETACH_AND_DOWN
40062+ dev->hard_header = NULL;
40063+#endif /* DETACH_AND_DOWN */
40064+
40065+ prv->rebuild_header = NULL;
40066+#ifdef DETACH_AND_DOWN
40067+ dev->rebuild_header = NULL;
40068+#endif /* DETACH_AND_DOWN */
40069+
40070+ prv->set_mac_address = NULL;
40071+#ifdef DETACH_AND_DOWN
40072+ dev->set_mac_address = NULL;
40073+#endif /* DETACH_AND_DOWN */
40074+
40075+#ifndef NET_21
40076+ prv->header_cache_bind = NULL;
40077+#ifdef DETACH_AND_DOWN
40078+ dev->header_cache_bind = NULL;
40079+#endif /* DETACH_AND_DOWN */
40080+#endif /* !NET_21 */
40081+
40082+ prv->header_cache_update = NULL;
40083+#ifdef DETACH_AND_DOWN
40084+ dev->header_cache_update = NULL;
40085+#endif /* DETACH_AND_DOWN */
40086+
40087+#ifdef NET_21
40088+/* prv->neigh_setup = NULL; */
40089+#ifdef DETACH_AND_DOWN
40090+ dev->neigh_setup = NULL;
40091+#endif /* DETACH_AND_DOWN */
40092+#endif /* NET_21 */
40093+ dev->hard_header_len = 0;
40094+#ifdef DETACH_AND_DOWN
40095+ dev->mtu = 0;
40096+#endif /* DETACH_AND_DOWN */
40097+ prv->mtu = 0;
40098+ for (i=0; i<MAX_ADDR_LEN; i++) {
40099+ dev->dev_addr[i] = 0;
40100+ }
40101+ dev->addr_len = 0;
40102+#ifdef PHYSDEV_TYPE
40103+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
40104+#endif /* PHYSDEV_TYPE */
40105+
40106+ return 0;
40107+}
40108+
40109+/*
40110+ * We call the clear routine to detach all ipsec tunnels from other devices.
40111+ */
40112+DEBUG_NO_STATIC int
40113+ipsec_tunnel_clear(void)
40114+{
40115+ int i;
40116+ struct net_device *ipsecdev = NULL, *prvdev;
40117+ struct ipsecpriv *prv;
40118+ int ret;
40119+
40120+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40121+ "klips_debug:ipsec_tunnel_clear: .\n");
40122+
40123+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40124+ ipsecdev = ipsecdevices[i];
40125+ if(ipsecdev != NULL) {
40126+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
40127+ prvdev = (struct net_device *)(prv->dev);
40128+ if(prvdev) {
40129+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40130+ "klips_debug:ipsec_tunnel_clear: "
40131+ "physical device for device %s is %s\n",
40132+ ipsecdev->name, prvdev->name);
40133+ if((ret = ipsec_tunnel_detach(ipsecdev))) {
40134+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40135+ "klips_debug:ipsec_tunnel_clear: "
40136+ "error %d detatching device %s from device %s.\n",
40137+ ret, ipsecdev->name, prvdev->name);
40138+ return ret;
40139+ }
40140+ }
40141+ }
40142+ }
40143+ }
40144+ return 0;
40145+}
40146+
40147+DEBUG_NO_STATIC int
40148+ipsec_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
40149+{
40150+ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
40151+ struct ipsecpriv *prv = dev->priv;
40152+ struct net_device *them; /* physical device */
40153+#ifdef CONFIG_IP_ALIAS
40154+ char *colon;
40155+ char realphysname[IFNAMSIZ];
40156+#endif /* CONFIG_IP_ALIAS */
40157+
40158+ if(dev == NULL) {
40159+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40160+ "klips_debug:ipsec_tunnel_ioctl: "
40161+ "device not supplied.\n");
40162+ return -ENODEV;
40163+ }
40164+
40165+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40166+ "klips_debug:ipsec_tunnel_ioctl: "
40167+ "tncfg service call #%d for dev=%s\n",
40168+ cmd,
40169+ dev->name ? dev->name : "NULL");
40170+ switch (cmd) {
40171+ /* attach a virtual ipsec? device to a physical device */
40172+ case IPSEC_SET_DEV:
40173+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40174+ "klips_debug:ipsec_tunnel_ioctl: "
40175+ "calling ipsec_tunnel_attatch...\n");
40176+#ifdef CONFIG_IP_ALIAS
40177+ /* If this is an IP alias interface, get its real physical name */
40178+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
40179+ realphysname[IFNAMSIZ-1] = 0;
40180+ colon = strchr(realphysname, ':');
40181+ if (colon) *colon = 0;
40182+ them = ipsec_dev_get(realphysname);
40183+#else /* CONFIG_IP_ALIAS */
40184+ them = ipsec_dev_get(cf->cf_name);
40185+#endif /* CONFIG_IP_ALIAS */
40186+
40187+ if (them == NULL) {
40188+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40189+ "klips_debug:ipsec_tunnel_ioctl: "
40190+ "physical device %s requested is null\n",
40191+ cf->cf_name);
40192+ return -ENXIO;
40193+ }
40194+
40195+#if 0
40196+ if (them->flags & IFF_UP) {
40197+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40198+ "klips_debug:ipsec_tunnel_ioctl: "
40199+ "physical device %s requested is not up.\n",
40200+ cf->cf_name);
40201+ ipsec_dev_put(them);
40202+ return -ENXIO;
40203+ }
40204+#endif
40205+
40206+ if (prv && prv->dev) {
40207+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40208+ "klips_debug:ipsec_tunnel_ioctl: "
40209+ "virtual device is already connected to %s.\n",
40210+ prv->dev->name ? prv->dev->name : "NULL");
40211+ ipsec_dev_put(them);
40212+ return -EBUSY;
40213+ }
40214+ return ipsec_tunnel_attach(dev, them);
40215+
40216+ case IPSEC_DEL_DEV:
40217+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40218+ "klips_debug:ipsec_tunnel_ioctl: "
40219+ "calling ipsec_tunnel_detatch.\n");
40220+ if (! prv->dev) {
40221+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40222+ "klips_debug:ipsec_tunnel_ioctl: "
40223+ "physical device not connected.\n");
40224+ return -ENODEV;
40225+ }
40226+ return ipsec_tunnel_detach(dev);
40227+
40228+ case IPSEC_CLR_DEV:
40229+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40230+ "klips_debug:ipsec_tunnel_ioctl: "
40231+ "calling ipsec_tunnel_clear.\n");
40232+ return ipsec_tunnel_clear();
40233+
40234+ default:
40235+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40236+ "klips_debug:ipsec_tunnel_ioctl: "
40237+ "unknown command %d.\n",
40238+ cmd);
40239+ return -EOPNOTSUPP;
40240+ }
40241+}
40242+
40243+struct net_device *ipsec_get_device(int inst)
40244+{
40245+ struct net_device *ipsec_dev;
40246+
40247+ ipsec_dev = NULL;
40248+
40249+ if(inst < IPSEC_NUM_IF) {
40250+ ipsec_dev = ipsecdevices[inst];
40251+ }
40252+
40253+ return ipsec_dev;
40254+}
40255+
40256+int
40257+ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
40258+{
40259+ struct net_device *dev = ptr;
40260+ struct net_device *ipsec_dev;
40261+ struct ipsecpriv *priv;
40262+ int i;
40263+
40264+ if (dev == NULL) {
40265+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40266+ "klips_debug:ipsec_device_event: "
40267+ "dev=NULL for event type %ld.\n",
40268+ event);
40269+ return(NOTIFY_DONE);
40270+ }
40271+
40272+ /* check for loopback devices */
40273+ if (dev && (dev->flags & IFF_LOOPBACK)) {
40274+ return(NOTIFY_DONE);
40275+ }
40276+
40277+ switch (event) {
40278+ case NETDEV_DOWN:
40279+ /* look very carefully at the scope of these compiler
40280+ directives before changing anything... -- RGB */
40281+#ifdef NET_21
40282+ case NETDEV_UNREGISTER:
40283+ switch (event) {
40284+ case NETDEV_DOWN:
40285+#endif /* NET_21 */
40286+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40287+ "klips_debug:ipsec_device_event: "
40288+ "NETDEV_DOWN dev=%s flags=%x\n",
40289+ dev->name,
40290+ dev->flags);
40291+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
40292+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
40293+ dev->name);
40294+ }
40295+#ifdef NET_21
40296+ break;
40297+ case NETDEV_UNREGISTER:
40298+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40299+ "klips_debug:ipsec_device_event: "
40300+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
40301+ dev->name,
40302+ dev->flags);
40303+ break;
40304+ }
40305+#endif /* NET_21 */
40306+
40307+ /* find the attached physical device and detach it. */
40308+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40309+ ipsec_dev = ipsecdevices[i];
40310+
40311+ if(ipsec_dev) {
40312+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
40313+ if(priv) {
40314+ ;
40315+ if(((struct net_device *)(priv->dev)) == dev) {
40316+ /* dev_close(ipsec_dev); */
40317+ /* return */ ipsec_tunnel_detach(ipsec_dev);
40318+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40319+ "klips_debug:ipsec_device_event: "
40320+ "device '%s' has been detached.\n",
40321+ ipsec_dev->name);
40322+ break;
40323+ }
40324+ } else {
40325+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40326+ "klips_debug:ipsec_device_event: "
40327+ "device '%s' has no private data space!\n",
40328+ ipsec_dev->name);
40329+ }
40330+ }
40331+ }
40332+ break;
40333+ case NETDEV_UP:
40334+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40335+ "klips_debug:ipsec_device_event: "
40336+ "NETDEV_UP dev=%s\n",
40337+ dev->name);
40338+ break;
40339+#ifdef NET_21
40340+ case NETDEV_REBOOT:
40341+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40342+ "klips_debug:ipsec_device_event: "
40343+ "NETDEV_REBOOT dev=%s\n",
40344+ dev->name);
40345+ break;
40346+ case NETDEV_CHANGE:
40347+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40348+ "klips_debug:ipsec_device_event: "
40349+ "NETDEV_CHANGE dev=%s flags=%x\n",
40350+ dev->name,
40351+ dev->flags);
40352+ break;
40353+ case NETDEV_REGISTER:
40354+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40355+ "klips_debug:ipsec_device_event: "
40356+ "NETDEV_REGISTER dev=%s\n",
40357+ dev->name);
40358+ break;
40359+ case NETDEV_CHANGEMTU:
40360+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40361+ "klips_debug:ipsec_device_event: "
40362+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
40363+ dev->name,
40364+ dev->mtu);
40365+ break;
40366+ case NETDEV_CHANGEADDR:
40367+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40368+ "klips_debug:ipsec_device_event: "
40369+ "NETDEV_CHANGEADDR dev=%s\n",
40370+ dev->name);
40371+ break;
40372+ case NETDEV_GOING_DOWN:
40373+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40374+ "klips_debug:ipsec_device_event: "
40375+ "NETDEV_GOING_DOWN dev=%s\n",
40376+ dev->name);
40377+ break;
40378+ case NETDEV_CHANGENAME:
40379+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40380+ "klips_debug:ipsec_device_event: "
40381+ "NETDEV_CHANGENAME dev=%s\n",
40382+ dev->name);
40383+ break;
40384+#endif /* NET_21 */
40385+ default:
40386+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40387+ "klips_debug:ipsec_device_event: "
40388+ "event type %ld unrecognised for dev=%s\n",
40389+ event,
40390+ dev->name);
40391+ break;
40392+ }
40393+ return NOTIFY_DONE;
40394+}
40395+
40396+/*
40397+ * Called when an ipsec tunnel device is initialized.
40398+ * The ipsec tunnel device structure is passed to us.
40399+ */
40400+
40401+int
40402+ipsec_tunnel_init(struct net_device *dev)
40403+{
40404+ int i;
40405+
40406+ KLIPS_PRINT(debug_tunnel,
40407+ "klips_debug:ipsec_tunnel_init: "
40408+ "allocating %lu bytes initialising device: %s\n",
40409+ (unsigned long) sizeof(struct ipsecpriv),
40410+ dev->name ? dev->name : "NULL");
40411+
40412+ /* Add our tunnel functions to the device */
40413+ dev->open = ipsec_tunnel_open;
40414+ dev->stop = ipsec_tunnel_close;
40415+ dev->hard_start_xmit = ipsec_tunnel_start_xmit;
40416+ dev->get_stats = ipsec_tunnel_get_stats;
40417+
40418+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
40419+ if (dev->priv == NULL)
40420+ return -ENOMEM;
40421+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
40422+
40423+ for(i = 0; i < sizeof(zeroes); i++) {
40424+ ((__u8*)(zeroes))[i] = 0;
40425+ }
40426+
40427+#ifndef NET_21
40428+ /* Initialize the tunnel device structure */
40429+ for (i = 0; i < DEV_NUMBUFFS; i++)
40430+ skb_queue_head_init(&dev->buffs[i]);
40431+#endif /* !NET_21 */
40432+
40433+ dev->set_multicast_list = NULL;
40434+ dev->do_ioctl = ipsec_tunnel_ioctl;
40435+ dev->hard_header = NULL;
40436+ dev->rebuild_header = NULL;
40437+ dev->set_mac_address = NULL;
40438+#ifndef NET_21
40439+ dev->header_cache_bind = NULL;
40440+#endif /* !NET_21 */
40441+ dev->header_cache_update= NULL;
40442+
40443+#ifdef NET_21
40444+/* prv->neigh_setup = NULL; */
40445+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
40446+#endif /* NET_21 */
40447+ dev->hard_header_len = 0;
40448+ dev->mtu = 0;
40449+ dev->addr_len = 0;
40450+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
40451+ dev->tx_queue_len = 10; /* Small queue */
40452+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
40453+
40454+ /* New-style flags. */
40455+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
40456+
40457+#if 0
40458+#ifdef NET_21
40459+ dev_init_buffers(dev);
40460+#else /* NET_21 */
40461+ dev->family = AF_INET;
40462+ dev->pa_addr = 0;
40463+ dev->pa_brdaddr = 0;
40464+ dev->pa_mask = 0;
40465+ dev->pa_alen = 4;
40466+#endif /* NET_21 */
40467+#endif
40468+
40469+ /* We're done. Have I forgotten anything? */
40470+ return 0;
40471+}
40472+
40473+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40474+/* Module specific interface (but it links with the rest of IPSEC) */
40475+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40476+
40477+int
40478+ipsec_tunnel_probe(struct net_device *dev)
40479+{
40480+ ipsec_tunnel_init(dev);
40481+ return 0;
40482+}
40483+
40484+struct net_device *ipsecdevices[IPSEC_NUM_IF];
40485+
40486+int
40487+ipsec_tunnel_init_devices(void)
40488+{
40489+ int i;
40490+ char name[IFNAMSIZ];
40491+ struct net_device *dev_ipsec;
40492+
40493+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40494+ "klips_debug:ipsec_tunnel_init_devices: "
40495+ "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
40496+ IPSEC_NUM_IF,
40497+ (unsigned long) (sizeof(struct net_device) + IFNAMSIZ),
40498+ IFNAMSIZ);
40499+
40500+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40501+ sprintf(name, IPSEC_DEV_FORMAT, i);
40502+ dev_ipsec = (struct net_device*)kmalloc(sizeof(struct net_device), GFP_KERNEL);
40503+ if (dev_ipsec == NULL) {
40504+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40505+ "klips_debug:ipsec_tunnel_init_devices: "
40506+ "failed to allocate memory for device %s, quitting device init.\n",
40507+ name);
40508+ return -ENOMEM;
40509+ }
40510+ memset((caddr_t)dev_ipsec, 0, sizeof(struct net_device));
40511+#ifdef NETDEV_23
40512+ strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
40513+#else /* NETDEV_23 */
40514+ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
40515+ if (dev_ipsec->name == NULL) {
40516+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40517+ "klips_debug:ipsec_tunnel_init_devices: "
40518+ "failed to allocate memory for device %s name, quitting device init.\n",
40519+ name);
40520+ return -ENOMEM;
40521+ }
40522+ memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ);
40523+ strncpy(dev_ipsec->name, name, IFNAMSIZ);
40524+#endif /* NETDEV_23 */
40525+ dev_ipsec->next = NULL;
40526+ dev_ipsec->init = &ipsec_tunnel_probe;
40527+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40528+ "klips_debug:ipsec_tunnel_init_devices: "
40529+ "registering device %s\n",
40530+ dev_ipsec->name);
40531+
40532+ /* reference and hold the device reference */
40533+ dev_hold(dev_ipsec);
40534+ ipsecdevices[i]=dev_ipsec;
40535+
40536+ if (register_netdev(dev_ipsec) != 0) {
40537+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
40538+ "klips_debug:ipsec_tunnel_init_devices: "
40539+ "registering device %s failed, quitting device init.\n",
40540+ dev_ipsec->name);
40541+ return -EIO;
40542+ } else {
40543+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40544+ "klips_debug:ipsec_tunnel_init_devices: "
40545+ "registering device %s succeeded, continuing...\n",
40546+ dev_ipsec->name);
40547+ }
40548+ }
40549+ return 0;
40550+}
40551+
40552+/* void */
40553+int
40554+ipsec_tunnel_cleanup_devices(void)
40555+{
40556+ int error = 0;
40557+ int i;
40558+ struct net_device *dev_ipsec;
40559+
40560+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40561+ dev_ipsec = ipsecdevices[i];
40562+ if(dev_ipsec == NULL) {
40563+ continue;
40564+ }
40565+
40566+ /* release reference */
40567+ ipsecdevices[i]=NULL;
40568+ ipsec_dev_put(dev_ipsec);
40569+
40570+ KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
40571+ dev_ipsec->name,
40572+ atomic_read(&dev_ipsec->refcnt));
40573+ unregister_netdev(dev_ipsec);
40574+ KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", dev_ipsec->name);
40575+#ifndef NETDEV_23
40576+ kfree(dev_ipsec->name);
40577+ dev_ipsec->name=NULL;
40578+#endif /* !NETDEV_23 */
40579+ kfree(dev_ipsec->priv);
40580+ dev_ipsec->priv=NULL;
40581+ }
40582+ return error;
40583+}
40584+
40585+/*
40586+ * $Log: ipsec_tunnel.c,v $
40587+ * Revision 1.232.2.5 2006/10/06 21:39:26 paul
40588+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
40589+ * set. This is defined through autoconf.h which is included through the
40590+ * linux kernel build macros.
40591+ *
40592+ * Revision 1.232.2.4 2006/03/28 20:58:19 ken
40593+ * Fix for KLIPS on 2.6.16 - need to include <net/arp.h> now
40594+ *
40595+ * Revision 1.232.2.3 2006/02/15 05:14:12 paul
40596+ * 568: uninitialized struct in ipsec_tunnel.c coud break routing under 2.6 kernels
40597+ * ipsec_tunnel_send() calls the entry point function of routing subsystem
40598+ * (ip_route_output_key()) using a not fully initialized struct of type
40599+ * struct flowi.
40600+ * This will cause a failure in routing packets through an ipsec interface
40601+ * when patches for multipath routing from http://www.ssi.bg/~ja/
40602+ * are applied.
40603+ *
40604+ * Revision 1.232.2.2 2005/11/22 04:11:52 ken
40605+ * Backport fixes for 2.6.14 kernels from HEAD
40606+ *
40607+ * Revision 1.232.2.1 2005/09/21 22:57:43 paul
40608+ * pulled up compile fix for 2.6.13
40609+ *
40610+ * Revision 1.232 2005/06/04 16:06:06 mcr
40611+ * better patch for nat-t rcv-device code.
40612+ *
40613+ * Revision 1.231 2005/05/21 03:28:51 mcr
40614+ * make sure that port-500 hole is used for port-4500 as well.
40615+ *
40616+ * Revision 1.230 2005/05/11 01:42:04 mcr
40617+ * removal of debugging showed useless/wrong variables used.
40618+ *
40619+ * Revision 1.229 2005/04/29 05:10:22 mcr
40620+ * removed from extraenous includes to make unit testing easier.
40621+ *
40622+ * Revision 1.228 2005/01/26 00:50:35 mcr
40623+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
40624+ * and make sure that NAT_TRAVERSAL is set as well to match
40625+ * userspace compiles of code.
40626+ *
40627+ * Revision 1.227 2004/12/10 21:16:08 ken
40628+ * 64bit fixes from Opteron port of KLIPS 2.6
40629+ *
40630+ * Revision 1.226 2004/12/04 07:11:23 mcr
40631+ * fix for snmp SIOCPRIVATE use of snmpd.
40632+ * http://bugs.xelerance.com/view.php?id=144
40633+ *
40634+ * Revision 1.225 2004/12/03 21:25:57 mcr
40635+ * compile time fixes for running on 2.6.
40636+ * still experimental.
40637+ *
40638+ * Revision 1.224 2004/08/14 03:28:24 mcr
40639+ * fixed log comment to remove warning about embedded comment.
40640+ *
40641+ * Revision 1.223 2004/08/04 15:57:07 mcr
40642+ * moved des .h files to include/des/ *
40643+ * included 2.6 protocol specific things
40644+ * started at NAT-T support, but it will require a kernel patch.
40645+ *
40646+ * Revision 1.222 2004/08/03 18:19:08 mcr
40647+ * in 2.6, use "net_device" instead of #define device->net_device.
40648+ * this probably breaks 2.0 compiles.
40649+ *
40650+ * Revision 1.221 2004/07/10 19:11:18 mcr
40651+ * CONFIG_IPSEC -> CONFIG_KLIPS.
40652+ *
40653+ * Revision 1.220 2004/04/06 02:49:26 mcr
40654+ * pullup of algo code from alg-branch.
40655+ *
40656+ * Revision 1.219 2004/02/03 03:13:17 mcr
40657+ * minor edits for readability, and error reporting.
40658+ *
40659+ * Revision 1.218 2004/01/27 20:29:20 mcr
40660+ * fix for unregister_netdev() problem for underlying eth0.
40661+ *
40662+ * Revision 1.217 2003/12/10 01:14:27 mcr
40663+ * NAT-traversal patches to KLIPS.
40664+ *
40665+ * Revision 1.216 2003/12/04 23:01:17 mcr
40666+ * removed ipsec_netlink.h
40667+ *
40668+ * Revision 1.215 2003/12/04 16:35:16 ken
40669+ * Fix for ATM devices where physdev->hard_header_len *is* correct
40670+ *
40671+ * Revision 1.214 2003/11/25 23:52:37 mcr
40672+ * fix typo in patch - ixs-> needed.
40673+ *
40674+ * Revision 1.213 2003/11/24 18:25:49 mcr
40675+ * patch from willy@w.ods.org to fix problems with ATM interfaces.
40676+ *
40677+ * Revision 1.212 2003/10/31 02:27:55 mcr
40678+ * pulled up port-selector patches and sa_id elimination.
40679+ *
40680+ * Revision 1.211.2.2 2003/10/29 01:30:41 mcr
40681+ * elimited "struct sa_id".
40682+ *
40683+ * Revision 1.211.2.1 2003/09/21 13:59:56 mcr
40684+ * pre-liminary X.509 patch - does not yet pass tests.
40685+ *
40686+ * Revision 1.211 2003/09/10 16:46:30 mcr
40687+ * patches for 2.4 backport/2.6 existence.
40688+ *
40689+ * Revision 1.210 2003/07/31 22:47:16 mcr
40690+ * preliminary (untested by FS-team) 2.5 patches.
40691+ *
40692+ * Revision 1.209 2003/06/22 21:28:43 mcr
40693+ * inability to unload module was caused by calls to dev_get
40694+ * (ipsec_dev_get), to gather a device from a name. There is
40695+ * simply no reason to look the devices up - they should be kept
40696+ * in a nice array, ready for use.
40697+ *
40698+ * Revision 1.208 2003/06/22 21:25:07 mcr
40699+ * all staticly counted ipsecXXX device support removed.
40700+ *
40701+ * Revision 1.207 2003/04/02 20:15:37 mcr
40702+ * fix for PR#204 - do not clear connection tracking info if we
40703+ * the packet is being sent in the clear.
40704+ *
40705+ * Revision 1.206 2003/02/12 19:32:51 rgb
40706+ * Refactored file to:
40707+ * ipsec_xmit.c
40708+ * ipsec_xmit.h
40709+ * ipsec_mast.c
40710+ *
40711+ * Revision 1.205 2003/02/06 17:47:00 rgb
40712+ *
40713+ * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code.
40714+ * Refactor ipsec_tunnel_start_xmit() further into:
40715+ * ipsec_xmit_sanity_check_dev()
40716+ * ipsec_xmit_sanity_check_skb()
40717+ * ipsec_xmit_strip_hard_header()
40718+ * ipsec_xmit_restore_hard_header()
40719+ * ipsec_xmit_send()
40720+ * ipsec_xmit_cleanup()
40721+ * and start a skeletal ipsec_mast_start_xmit() .
40722+ *
40723+ * Revision 1.204 2003/02/06 06:43:46 rgb
40724+ *
40725+ * Refactor ipsec_tunnel_start_xmit, bringing out:
40726+ * ipsec_xmit_SAlookup
40727+ * ipsec_xmit_encap_once
40728+ * ipsec_xmit_encap_bundle
40729+ *
40730+ * Revision 1.203 2003/02/06 02:21:34 rgb
40731+ *
40732+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
40733+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
40734+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
40735+ *
40736+ * Revision 1.202 2003/01/03 07:38:01 rgb
40737+ *
40738+ * Start to refactor ipsec_tunnel_start_xmit() by putting local variables
40739+ * into struct ipsec_xmit_state and renaming a few variables to give more
40740+ * unique or searchable names.
40741+ *
40742+ * Revision 1.201 2003/01/03 00:31:28 rgb
40743+ *
40744+ * Clean up memset usage, including fixing 2 places where keys were not
40745+ * properly wiped.
40746+ *
40747+ * Revision 1.200 2002/12/06 02:24:02 mcr
40748+ * patches for compiling against SUSE 8.1 kernels. Requires
40749+ * an additional -DSUSE_LINUX_2_4_19_IS_STUPID.
40750+ *
40751+ * Revision 1.199 2002/10/12 23:11:53 dhr
40752+ *
40753+ * [KenB + DHR] more 64-bit cleanup
40754+ *
40755+ * Revision 1.198 2002/10/05 05:02:58 dhr
40756+ *
40757+ * C labels go on statements
40758+ *
40759+ * Revision 1.197 2002/09/20 05:01:50 rgb
40760+ * Added compiler directive to switch on IP options and fix IP options bug.
40761+ * Make ip->ihl treatment consistent using shifts rather than multiplications.
40762+ * Check for large enough packet before accessing udp header for IKE bypass.
40763+ * Added memory allocation debugging.
40764+ * Fixed potential memory allocation failure-induced oops.
40765+ *
40766+ * Revision 1.196 2002/07/24 18:44:54 rgb
40767+ * Type fiddling to tame ia64 compiler.
40768+ *
40769+ * Revision 1.195 2002/07/23 03:36:07 rgb
40770+ * Fixed 2.2 device initialisation hang.
40771+ *
40772+ * Revision 1.194 2002/05/27 21:40:34 rgb
40773+ * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2.
40774+ * Cleaned up intermediate step to dynamic device allocation.
40775+ *
40776+ * Revision 1.193 2002/05/27 19:31:36 rgb
40777+ * Convert to dynamic ipsec device allocation.
40778+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
40779+ *
40780+ * Revision 1.192 2002/05/23 07:14:28 rgb
40781+ * Added refcount code.
40782+ * Cleaned up %p variants to 0p%p for test suite cleanup.
40783+ *
40784+ * Revision 1.191 2002/05/14 02:34:37 rgb
40785+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
40786+ * ipsec_sa or ipsec_sa.
40787+ *
40788+ * Revision 1.190 2002/04/24 07:55:32 mcr
40789+ * #include patches and Makefiles for post-reorg compilation.
40790+ *
40791+ * Revision 1.189 2002/04/24 07:36:32 mcr
40792+ * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v
40793+ *
40794+ * Revision 1.188 2002/04/20 00:12:25 rgb
40795+ * Added esp IV CBC attack fix, disabled.
40796+ *
40797+ * Revision 1.187 2002/03/23 19:55:17 rgb
40798+ * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if
40799+ * iptraf or another pcap app is running.
40800+ *
40801+ * Revision 1.186 2002/03/19 03:26:22 rgb
40802+ * Applied DHR's tunnel patch to streamline IKE/specialSA processing.
40803+ *
40804+ * Revision 1.185 2002/02/20 04:13:05 rgb
40805+ * Send back ICMP_PKT_FILTERED upon %reject.
40806+ *
40807+ * Revision 1.184 2002/01/29 17:17:56 mcr
40808+ * moved include of ipsec_param.h to after include of linux/kernel.h
40809+ * otherwise, it seems that some option that is set in ipsec_param.h
40810+ * screws up something subtle in the include path to kernel.h, and
40811+ * it complains on the snprintf() prototype.
40812+ *
40813+ * Revision 1.183 2002/01/29 04:00:53 mcr
40814+ * more excise of kversions.h header.
40815+ *
40816+ * Revision 1.182 2002/01/29 02:13:18 mcr
40817+ * introduction of ipsec_kversion.h means that include of
40818+ * ipsec_param.h must preceed any decisions about what files to
40819+ * include to deal with differences in kernel source.
40820+ *
40821+ * Revision 1.181 2002/01/07 20:00:33 rgb
40822+ * Added IKE destination port debugging.
40823+ *
40824+ * Revision 1.180 2001/12/21 21:49:54 rgb
40825+ * Fixed bug as a result of moving IKE bypass above %trap/%hold code.
40826+ *
40827+ * Revision 1.179 2001/12/19 21:08:14 rgb
40828+ * Added transport protocol ports to ipsec_print_ip().
40829+ * Update eroute info for non-SA targets.
40830+ * Added obey DF code disabled.
40831+ * Fixed formatting bugs in ipsec_tunnel_hard_header().
40832+ *
40833+ * Revision 1.178 2001/12/05 09:36:10 rgb
40834+ * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid
40835+ * IKE packets being stolen by the %hold (and returned to the sending KMd
40836+ * in an ACQUIRE, ironically ;-).
40837+ *
40838+ * Revision 1.177 2001/11/26 09:23:50 rgb
40839+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
40840+ *
40841+ * Revision 1.170.2.1 2001/09/25 02:28:27 mcr
40842+ * struct tdb -> struct ipsec_sa.
40843+ * lifetime checks moved to common routines.
40844+ * cleaned up includes.
40845+ *
40846+ * Revision 1.170.2.2 2001/10/22 21:08:01 mcr
40847+ * include des.h, removed phony prototypes and fixed calling
40848+ * conventions to match real prototypes.
40849+ *
40850+ * Revision 1.176 2001/11/09 18:32:31 rgb
40851+ * Added Hans Schultz' fragmented UDP/500 IKE socket port selector.
40852+ *
40853+ * Revision 1.175 2001/11/06 20:47:00 rgb
40854+ * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling.
40855+ *
40856+ * Revision 1.174 2001/11/06 19:50:43 rgb
40857+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
40858+ * use also by pfkey_v2_parser.c
40859+ *
40860+ * Revision 1.173 2001/10/29 21:53:44 henry
40861+ * tone down the device-down message slightly, until we can make it smarter
40862+ *
40863+ * Revision 1.172 2001/10/26 04:59:37 rgb
40864+ * Added a critical level syslog message if an ipsec device goes down.
40865+ *
40866+ * Revision 1.171 2001/10/18 04:45:21 rgb
40867+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
40868+ * lib/freeswan.h version macros moved to lib/kversions.h.
40869+ * Other compiler directive cleanups.
40870+ *
40871+ * Revision 1.170 2001/09/25 00:09:50 rgb
40872+ * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a
40873+ * HOLD.
40874+ *
40875+ * Revision 1.169 2001/09/15 16:24:05 rgb
40876+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
40877+ *
40878+ * Revision 1.168 2001/09/14 16:58:37 rgb
40879+ * Added support for storing the first and last packets through a HOLD.
40880+ *
40881+ * Revision 1.167 2001/09/08 21:13:33 rgb
40882+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
40883+ *
40884+ * Revision 1.166 2001/08/27 19:47:59 rgb
40885+ * Clear tdb before usage.
40886+ * Added comment: clear IF before calling routing?
40887+ *
40888+ * Revision 1.165 2001/07/03 01:23:53 rgb
40889+ * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len >
40890+ * emtu, and don't drop.
40891+ *
40892+ * Revision 1.164 2001/06/14 19:35:10 rgb
40893+ * Update copyright date.
40894+ *
40895+ * Revision 1.163 2001/06/06 20:28:51 rgb
40896+ * Added sanity checks for NULL skbs and devices.
40897+ * Added more debugging output to various functions.
40898+ * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach().
40899+ * Renamed ipsec_tunnel_attach() virtual and physical device arguments.
40900+ * Corrected neigh_setup() device function assignment.
40901+ * Keep valid pointers to ipsec_tunnel_*() on detach.
40902+ * Set dev->type to the originally-initiallised value.
40903+ *
40904+ * Revision 1.162 2001/06/01 07:28:04 rgb
40905+ * Added sanity checks for detached devices. Don't down virtual devices
40906+ * to prevent packets going out in the clear if the detached device comes
40907+ * back up.
40908+ *
40909+ * Revision 1.161 2001/05/30 08:14:52 rgb
40910+ * Removed vestiges of esp-null transforms.
40911+ * NetDev Notifier instrumentation to track down disappearing devices.
40912+ *
40913+ * Revision 1.160 2001/05/29 05:15:12 rgb
40914+ * Added SS' PMTU patch which notifies sender if packet doesn't fit
40915+ * physical MTU (if it wasn't ICMP) and then drops it.
40916+ *
40917+ * Revision 1.159 2001/05/27 06:12:12 rgb
40918+ * Added structures for pid, packet count and last access time to eroute.
40919+ * Added packet count to beginning of /proc/net/ipsec_eroute.
40920+ *
40921+ * Revision 1.158 2001/05/24 05:39:33 rgb
40922+ * Applied source zeroing to 2.2 ip_route_output() call as well to enable
40923+ * PASS eroutes for opportunism.
40924+ *
40925+ * Revision 1.157 2001/05/23 22:35:28 rgb
40926+ * 2.4 source override simplification.
40927+ *
40928+ * Revision 1.156 2001/05/23 21:41:31 rgb
40929+ * Added error return code printing on ip_route_output().
40930+ *
40931+ * Revision 1.155 2001/05/23 05:09:13 rgb
40932+ * Fixed incorrect ip_route_output() failure message.
40933+ *
40934+ * Revision 1.154 2001/05/21 14:53:31 rgb
40935+ * Added debug statement for case when ip_route_output() fails, causing
40936+ * packet to be dropped, but log looked ok.
40937+ *
40938+ * Revision 1.153 2001/05/19 02:37:54 rgb
40939+ * Fixed missing comment termination.
40940+ *
40941+ * Revision 1.152 2001/05/19 02:35:50 rgb
40942+ * Debug code optimisation for non-debug speed.
40943+ * Kernel version compiler define comments.
40944+ * 2.2 and 2.4 kernel ip_send device and ip debug output added.
40945+ *
40946+ * Revision 1.151 2001/05/18 16:17:35 rgb
40947+ * Changed reference from "magic" to "shunt" SAs.
40948+ *
40949+ * Revision 1.150 2001/05/18 16:12:19 rgb
40950+ * Changed UDP/500 bypass test from 3 nested ifs to one anded if.
40951+ *
40952+ * Revision 1.149 2001/05/16 04:39:33 rgb
40953+ * Add default == eroute.dest to IKE bypass conditions for magic eroutes.
40954+ *
40955+ * Revision 1.148 2001/05/05 03:31:41 rgb
40956+ * IP frag debugging updates and enhancements.
40957+ *
40958+ * Revision 1.147 2001/05/03 19:41:40 rgb
40959+ * Added SS' skb_cow fix for 2.4.4.
40960+ *
40961+ * Revision 1.146 2001/04/30 19:28:16 rgb
40962+ * Update for 2.4.4. ip_select_ident() now has 3 args.
40963+ *
40964+ * Revision 1.145 2001/04/23 14:56:10 rgb
40965+ * Added spin_lock() check to prevent double-locking for multiple
40966+ * transforms and hence kernel lock-ups with SMP kernels.
40967+ *
40968+ * Revision 1.144 2001/04/21 23:04:45 rgb
40969+ * Define out skb->used for 2.4 kernels.
40970+ * Check if soft expire has already been sent before sending another to
40971+ * prevent ACQUIRE flooding.
40972+ *
40973+ * Revision 1.143 2001/03/16 07:37:21 rgb
40974+ * Added comments to all #endifs.
40975+ *
40976+ * Revision 1.142 2001/02/28 05:03:27 rgb
40977+ * Clean up and rationalise startup messages.
40978+ *
40979+ * Revision 1.141 2001/02/27 22:24:54 rgb
40980+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
40981+ * Check for satoa() return codes.
40982+ *
40983+ * Revision 1.140 2001/02/27 06:40:12 rgb
40984+ * Fixed TRAP->HOLD eroute byte order.
40985+ *
40986+ * Revision 1.139 2001/02/26 20:38:59 rgb
40987+ * Added compiler defines for 2.4.x-specific code.
40988+ *
40989+ * Revision 1.138 2001/02/26 19:57:27 rgb
40990+ * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
40991+ * of the new SPD and to support opportunistic.
40992+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
40993+ *
40994+ * Revision 1.137 2001/02/19 22:29:49 rgb
40995+ * Fixes for presence of active ipv6 segments which share ipsec physical
40996+ * device (gg).
40997+ *
40998+ * Revision 1.136 2001/01/29 22:30:38 rgb
40999+ * Fixed minor acquire debug printing bug.
41000+ *
41001+ * Revision 1.135 2001/01/29 22:19:45 rgb
41002+ * Zero source address for 2.4 bypass route lookup.
41003+ *
41004+ * Revision 1.134 2001/01/23 20:19:49 rgb
41005+ * 2.4 fix to remove removed is_clone member.
41006+ *
41007+ * Revision 1.133 2000/12/09 22:08:35 rgb
41008+ * Fix NET_23 bug, should be NETDEV_23.
41009+ *
41010+ * Revision 1.132 2000/12/01 06:54:50 rgb
41011+ * Fix for new 2.4 IP TTL default variable name.
41012+ *
41013+ * Revision 1.131 2000/11/09 20:52:15 rgb
41014+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
41015+ * include ipcomp and prevent races, renaming some tdb variables that got
41016+ * forgotten, moving some unlocks to include tdbs and adding a missing
41017+ * unlock. Thanks to Svenning for some of these.
41018+ *
41019+ * Revision 1.130 2000/11/09 20:11:22 rgb
41020+ * Minor shuffles to fix non-standard kernel config option selection.
41021+ *
41022+ * Revision 1.129 2000/11/06 04:32:49 rgb
41023+ * Clean up debug printing.
41024+ * Copy skb->protocol for all kernel versions.
41025+ * Ditched spin_lock_irqsave in favour of spin_lock.
41026+ * Disabled TTL decrement, done in ip_forward.
41027+ * Added debug printing before pfkey_acquire().
41028+ * Fixed printk-deltdbchain-spin_lock races (Svenning).
41029+ * Use defaultTTL for 2.1+ kernels.
41030+ * Add Svenning's adaptive content compression.
41031+ * Fix up debug display arguments.
41032+ *
41033+ * Revision 1.128 2000/09/28 00:58:57 rgb
41034+ * Moved the IKE passthrough check after the eroute lookup so we can pass
41035+ * IKE through intermediate tunnels.
41036+ *
41037+ * Revision 1.127 2000/09/22 17:52:11 rgb
41038+ * Fixed misleading ipcomp debug output.
41039+ *
41040+ * Revision 1.126 2000/09/22 04:22:56 rgb
41041+ * Fixed dumb spi->cpi conversion error.
41042+ *
41043+ * Revision 1.125 2000/09/21 04:34:48 rgb
41044+ * A few debug-specific things should be hidden under
41045+ * CONFIG_IPSEC_DEBUG.(MB)
41046+ * Improved ip_send() error handling.(MB)
41047+ *
41048+ * Revision 1.124 2000/09/21 03:40:58 rgb
41049+ * Added more debugging to try and track down the cpi outward copy problem.
41050+ *
41051+ * Revision 1.123 2000/09/19 07:08:49 rgb
41052+ * Added debugging to outgoing compression report.
41053+ *
41054+ * Revision 1.122 2000/09/18 19:21:26 henry
41055+ * RGB-supplied fix for RH5.2 problem
41056+ *
41057+ * Revision 1.121 2000/09/17 21:05:09 rgb
41058+ * Added tdb to skb_compress call to write in cpi.
41059+ *
41060+ * Revision 1.120 2000/09/17 16:57:16 rgb
41061+ * Added Svenning's patch to remove restriction of ipcomp to innermost
41062+ * transform.
41063+ *
41064+ * Revision 1.119 2000/09/15 11:37:01 rgb
41065+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
41066+ * IPCOMP zlib deflate code.
41067+ *
41068+ * Revision 1.118 2000/09/15 04:57:16 rgb
41069+ * Moved debug output after sanity check.
41070+ * Added tos copy sysctl.
41071+ *
41072+ * Revision 1.117 2000/09/12 03:22:51 rgb
41073+ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
41074+ * sysctl.
41075+ *
41076+ * Revision 1.116 2000/09/08 19:18:19 rgb
41077+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
41078+ * Added outgoing opportunistic hook, ifdef'ed out.
41079+ *
41080+ * Revision 1.115 2000/08/30 05:27:29 rgb
41081+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
41082+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
41083+ *
41084+ * Revision 1.114 2000/08/28 18:15:46 rgb
41085+ * Added MB's nf-debug reset patch.
41086+ *
41087+ * Revision 1.113 2000/08/27 02:26:40 rgb
41088+ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
41089+ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
41090+ *
41091+ * Revision 1.112 2000/08/20 21:37:33 rgb
41092+ * Activated pfkey_expire() calls.
41093+ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
41094+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
41095+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
41096+ *
41097+ * Revision 1.111 2000/08/01 14:51:51 rgb
41098+ * Removed _all_ remaining traces of DES.
41099+ *
41100+ * Revision 1.110 2000/07/28 14:58:31 rgb
41101+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
41102+ *
41103+ * Revision 1.109 2000/07/28 13:50:54 rgb
41104+ * Changed enet_statistics to net_device_stats and added back compatibility
41105+ * for pre-2.1.19.
41106+ *
41107+ * Revision 1.108 2000/05/16 03:03:11 rgb
41108+ * Updates for 2.3.99pre8 from MB.
41109+ *
41110+ * Revision 1.107 2000/05/10 23:08:21 rgb
41111+ * Print a debug warning about bogus packets received by the outgoing
41112+ * processing machinery only when klipsdebug is not set to none.
41113+ * Comment out the device initialisation informational messages.
41114+ *
41115+ * Revision 1.106 2000/05/10 19:17:14 rgb
41116+ * Define an IP_SEND macro, intending to have all packet passthroughs
41117+ * use fragmentation. This didn't quite work, but is a step in the
41118+ * right direction.
41119+ * Added buffer allocation debugging statements.
41120+ * Added configure option to shut off no eroute passthrough.
41121+ * Only check usetime against soft and hard limits if the tdb has been
41122+ * used.
41123+ * Cast output of ntohl so that the broken prototype doesn't make our
41124+ * compile noisy.
41125+ *
41126+ * Revision 1.105 2000/03/22 16:15:37 rgb
41127+ * Fixed renaming of dev_get (MB).
41128+ *
41129+ * Revision 1.104 2000/03/16 14:04:15 rgb
41130+ * Indented headers for readability.
41131+ * Fixed debug scope to enable compilation with debug off.
41132+ * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
41133+ *
41134+ * Revision 1.103 2000/03/16 07:11:07 rgb
41135+ * Hardcode PF_KEYv2 support.
41136+ * Fixed bug which allowed UDP/500 packet from another machine
41137+ * through in the clear.
41138+ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
41139+ *
41140+ * Revision 1.102 2000/03/14 12:26:59 rgb
41141+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
41142+ *
41143+ * Revision 1.101 2000/02/14 21:05:22 rgb
41144+ * Added MB's netif_queue fix for kernels 2.3.43+.
41145+ *
41146+ * Revision 1.100 2000/01/26 10:04:57 rgb
41147+ * Fixed noisy 2.0 printk arguments.
41148+ *
41149+ * Revision 1.99 2000/01/21 06:16:25 rgb
41150+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
41151+ * Switched to AF_ENCAP macro.
41152+ * Shortened debug output per packet and re-arranging debug_tunnel
41153+ * bitmap flags, while retaining necessary information to avoid
41154+ * trampling the kernel print ring buffer.
41155+ * Reformatted recursion switch code.
41156+ * Changed all references to tdb_proto to tdb_said.proto for clarity.
41157+ *
41158+ * Revision 1.98 2000/01/13 08:09:31 rgb
41159+ * Shuffled debug_tunnel switches to focus output.
41160+ * Fixed outgoing recursion bug, limiting to recursing only if the remote
41161+ * SG changes and if it is valid, ie. not passthrough.
41162+ * Clarified a number of debug messages.
41163+ *
41164+ * Revision 1.97 2000/01/10 16:37:16 rgb
41165+ * MB support for new ip_select_ident() upon disappearance of
41166+ * ip_id_count in 2.3.36+.
41167+ *
41168+ * Revision 1.96 1999/12/31 14:59:08 rgb
41169+ * MB fix to use new skb_copy_expand in kernel 2.3.35.
41170+ *
41171+ * Revision 1.95 1999/12/29 21:15:44 rgb
41172+ * Fix tncfg to aliased device bug.
41173+ *
41174+ * Revision 1.94 1999/12/22 04:26:06 rgb
41175+ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
41176+ * debugging by providing external labels to all functions with debugging
41177+ * turned on.
41178+ *
41179+ * Revision 1.93 1999/12/13 13:30:14 rgb
41180+ * Changed MTU reports and HW address reporting back to debug only.
41181+ *
41182+ * Revision 1.92 1999/12/07 18:57:56 rgb
41183+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
41184+ *
41185+ * Revision 1.91 1999/12/01 22:15:36 rgb
41186+ * Add checks for LARVAL and DEAD SAs.
41187+ * Change state of SA from MATURE to DYING when a soft lifetime is
41188+ * reached and print debug warning.
41189+ *
41190+ * Revision 1.90 1999/11/23 23:04:04 rgb
41191+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
41192+ * Sort out pfkey and freeswan headers, putting them in a library path.
41193+ *
41194+ * Revision 1.89 1999/11/18 18:50:59 rgb
41195+ * Changed all device registrations for static linking to
41196+ * dynamic to reduce the number and size of patches.
41197+ *
41198+ * Revision 1.88 1999/11/18 04:09:19 rgb
41199+ * Replaced all kernel version macros to shorter, readable form.
41200+ *
41201+ * Revision 1.87 1999/11/17 15:53:40 rgb
41202+ * Changed all occurrences of #include "../../../lib/freeswan.h"
41203+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
41204+ * klips/net/ipsec/Makefile.
41205+ *
41206+ * Revision 1.86 1999/10/16 18:25:37 rgb
41207+ * Moved SA lifetime expiry checks before packet processing.
41208+ * Expire SA on replay counter rollover.
41209+ *
41210+ * Revision 1.85 1999/10/16 04:24:31 rgb
41211+ * Add stats for time since last packet.
41212+ *
41213+ * Revision 1.84 1999/10/16 00:30:47 rgb
41214+ * Added SA lifetime counting.
41215+ *
41216+ * Revision 1.83 1999/10/15 22:15:57 rgb
41217+ * Clean out cruft.
41218+ * Add debugging.
41219+ *
41220+ * Revision 1.82 1999/10/08 18:26:19 rgb
41221+ * Fix 2.0.3x outgoing fragmented packet memory leak.
41222+ *
41223+ * Revision 1.81 1999/10/05 02:38:54 rgb
41224+ * Lower the default mtu of virtual devices to 16260.
41225+ *
41226+ * Revision 1.80 1999/10/03 18:56:41 rgb
41227+ * Spinlock support for 2.3.xx.
41228+ * Don't forget to undo spinlocks on error!
41229+ * Check for valid eroute before copying the structure.
41230+ *
41231+ * Revision 1.79 1999/10/01 15:44:53 rgb
41232+ * Move spinlock header include to 2.1> scope.
41233+ *
41234+ * Revision 1.78 1999/10/01 00:02:43 rgb
41235+ * Added tdb structure locking.
41236+ * Added eroute structure locking.
41237+ *
41238+ * Revision 1.77 1999/09/30 02:52:29 rgb
41239+ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
41240+ *
41241+ * Revision 1.76 1999/09/25 19:31:27 rgb
41242+ * Refine MSS hack to affect SYN, but not SYN+ACK packets.
41243+ *
41244+ * Revision 1.75 1999/09/24 22:52:38 rgb
41245+ * Fix two things broken in 2.0.38 by trying to fix network notifiers.
41246+ *
41247+ * Revision 1.74 1999/09/24 00:30:37 rgb
41248+ * Add test for changed source as well as destination to check for
41249+ * recursion.
41250+ *
41251+ * Revision 1.73 1999/09/23 20:52:24 rgb
41252+ * Add James Morris' MSS hack patch, disabled.
41253+ *
41254+ * Revision 1.72 1999/09/23 20:22:40 rgb
41255+ * Enable, tidy and fix network notifier code.
41256+ *
41257+ * Revision 1.71 1999/09/23 18:09:05 rgb
41258+ * Clean up 2.2.x fragmenting traces.
41259+ * Disable dev->type switching, forcing ARPHRD_TUNNEL.
41260+ *
41261+ * Revision 1.70 1999/09/22 14:14:24 rgb
41262+ * Add sanity checks for revectored calls to prevent calling a downed I/F.
41263+ *
41264+ * Revision 1.69 1999/09/21 15:00:57 rgb
41265+ * Add Marc Boucher's packet size check.
41266+ * Flesh out network device notifier code.
41267+ *
41268+ * Revision 1.68 1999/09/18 11:39:57 rgb
41269+ * Start to add (disabled) netdevice notifier code.
41270+ *
41271+ * Revision 1.67 1999/09/17 23:44:40 rgb
41272+ * Add a comment warning potential code hackers to stay away from mac.raw.
41273+ *
41274+ * Revision 1.66 1999/09/17 18:04:02 rgb
41275+ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
41276+ * Ditch TTL decrement in 2.2 (MB).
41277+ *
41278+ * Revision 1.65 1999/09/15 23:15:35 henry
41279+ * Marc Boucher's PPP fixes
41280+ *
41281+ * Revision 1.64 1999/09/07 13:40:53 rgb
41282+ * Ditch unreliable references to skb->mac.raw.
41283+ *
41284+ * Revision 1.63 1999/08/28 11:33:09 rgb
41285+ * Check for null skb->mac pointer.
41286+ *
41287+ * Revision 1.62 1999/08/28 02:02:30 rgb
41288+ * Add Marc Boucher's fix for properly dealing with skb->sk.
41289+ *
41290+ * Revision 1.61 1999/08/27 05:23:05 rgb
41291+ * Clean up skb->data/raw/nh/h manipulation.
41292+ * Add Marc Boucher's mods to aid tcpdump.
41293+ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
41294+ * Re-order hard_header stripping -- might be able to remove it...
41295+ *
41296+ * Revision 1.60 1999/08/26 20:01:02 rgb
41297+ * Tidy up compiler directives and macros.
41298+ * Re-enable ICMP for tunnels where inner_dst != outer_dst.
41299+ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
41300+ *
41301+ * Revision 1.59 1999/08/25 15:44:41 rgb
41302+ * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
41303+ *
41304+ * Revision 1.58 1999/08/25 15:00:54 rgb
41305+ * Add dst cache code for 2.2.xx.
41306+ * Add sanity check for skb packet header pointers.
41307+ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
41308+ * *_rebuild_header.
41309+ * Add neigh_* cache code.
41310+ * Change dev->type back to ARPHRD_TUNNEL.
41311+ *
41312+ * Revision 1.57 1999/08/17 21:50:23 rgb
41313+ * Fixed minor debug output bugs.
41314+ * Regrouped error recovery exit code.
41315+ * Added compiler directives to remove unwanted code and symbols.
41316+ * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
41317+ * Add debugging code for output function addresses.
41318+ * Fix minor bug in (possibly unused) header_cache_bind function.
41319+ * Add device neighbour caching code.
41320+ * Change dev->type from ARPHRD_TUNNEL to physdev->type.
41321+ *
41322+ * Revision 1.56 1999/08/03 17:22:56 rgb
41323+ * Debug output clarification using KERN_* macros. Other inactive changes
41324+ * added.
41325+ *
41326+ * Revision 1.55 1999/08/03 16:58:46 rgb
41327+ * Fix skb_copy_expand size bug. Was getting incorrect size.
41328+ *
41329+ * Revision 1.54 1999/07/14 19:32:38 rgb
41330+ * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
41331+ *
41332+ * Revision 1.53 1999/06/10 15:44:02 rgb
41333+ * Minor reformatting and clean-up.
41334+ *
41335+ * Revision 1.52 1999/05/09 03:25:36 rgb
41336+ * Fix bug introduced by 2.2 quick-and-dirty patch.
41337+ *
41338+ * Revision 1.51 1999/05/08 21:24:59 rgb
41339+ * Add casting to silence the 2.2.x compile.
41340+ *
41341+ * Revision 1.50 1999/05/05 22:02:32 rgb
41342+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
41343+ *
41344+ * Revision 1.49 1999/04/29 15:18:52 rgb
41345+ * Change gettdb parameter to a pointer to reduce stack loading and
41346+ * facilitate parameter sanity checking.
41347+ * Fix undetected bug that might have tried to access a null pointer.
41348+ * Eliminate unnessessary usage of tdb_xform member to further switch
41349+ * away from the transform switch to the algorithm switch.
41350+ * Add return values to init and cleanup functions.
41351+ *
41352+ * Revision 1.48 1999/04/16 15:38:00 rgb
41353+ * Minor rearrangement of freeing code to avoid memory leaks with impossible or
41354+ * rare situations.
41355+ *
41356+ * Revision 1.47 1999/04/15 15:37:25 rgb
41357+ * Forward check changes from POST1_00 branch.
41358+ *
41359+ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb
41360+ * Ditch 'things I wish I had known before...'.
41361+ *
41362+ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb
41363+ * Free skb after fragmentation.
41364+ * Use stats more effectively.
41365+ * Add I/F to mtu notch-down reporting.
41366+ *
41367+ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb
41368+ * Backcheck from HEAD, pre1.0.
41369+ *
41370+ * Revision 1.46 1999/04/11 00:29:00 henry
41371+ * GPL boilerplate
41372+ *
41373+ * Revision 1.45 1999/04/07 15:42:01 rgb
41374+ * Fix mtu/ping bug AGAIN!
41375+ *
41376+ * Revision 1.44 1999/04/06 04:54:27 rgb
41377+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
41378+ * patch shell fixes.
41379+ *
41380+ * Revision 1.43 1999/04/04 03:57:07 rgb
41381+ * ip_fragment() doesn't free the supplied skb. Freed.
41382+ *
41383+ * Revision 1.42 1999/04/01 23:27:15 rgb
41384+ * Preload size of virtual mtu.
41385+ *
41386+ * Revision 1.41 1999/04/01 09:31:23 rgb
41387+ * Invert meaning of ICMP PMTUD config option and clarify.
41388+ * Code clean-up.
41389+ *
41390+ * Revision 1.40 1999/04/01 04:37:17 rgb
41391+ * SSH stalling bug fix.
41392+ *
41393+ * Revision 1.39 1999/03/31 23:44:28 rgb
41394+ * Don't send ICMP on DF and frag_off.
41395+ *
41396+ * Revision 1.38 1999/03/31 15:20:10 rgb
41397+ * Quiet down debugging.
41398+ *
41399+ * Revision 1.37 1999/03/31 08:30:31 rgb
41400+ * Add switch to shut off ICMP PMTUD packets.
41401+ *
41402+ * Revision 1.36 1999/03/31 05:44:47 rgb
41403+ * Keep PMTU reduction private.
41404+ *
41405+ * Revision 1.35 1999/03/27 15:13:02 rgb
41406+ * PMTU/fragmentation bug fix.
41407+ *
41408+ * Revision 1.34 1999/03/17 21:19:26 rgb
41409+ * Fix kmalloc nonatomic bug.
41410+ *
41411+ * Revision 1.33 1999/03/17 15:38:42 rgb
41412+ * Code clean-up.
41413+ * ESP_NULL IV bug fix.
41414+ *
41415+ * Revision 1.32 1999/03/01 20:44:25 rgb
41416+ * Code clean-up.
41417+ * Memory leak bug fix.
41418+ *
41419+ * Revision 1.31 1999/02/27 00:02:09 rgb
41420+ * Tune to report the MTU reduction once, rather than after every recursion
41421+ * through the encapsulating code, preventing tcp stream stalling.
41422+ *
41423+ * Revision 1.30 1999/02/24 20:21:01 rgb
41424+ * Reformat debug printk's.
41425+ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
41426+ * Clean-up.
41427+ *
41428+ * Revision 1.29 1999/02/22 17:08:14 rgb
41429+ * Fix recursive encapsulation code.
41430+ *
41431+ * Revision 1.28 1999/02/19 18:27:02 rgb
41432+ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
41433+ *
41434+ * Revision 1.27 1999/02/17 16:51:37 rgb
41435+ * Clean out unused cruft.
41436+ * Temporarily tone down volume of debug output.
41437+ * Temporarily shut off fragment rejection.
41438+ * Disabled temporary failed recursive encapsulation loop.
41439+ *
41440+ * Revision 1.26 1999/02/12 21:21:26 rgb
41441+ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
41442+ *
41443+ * Revision 1.25 1999/02/11 19:38:27 rgb
41444+ * More clean-up.
41445+ * Add sanity checking for skb_copy_expand() to prevent kernel panics on
41446+ * skb_put() values out of range.
41447+ * Fix head/tailroom calculation causing skb_put() out-of-range values.
41448+ * Fix return values to prevent 'nonatomic alloc_skb' warnings.
41449+ * Allocate new skb iff needed.
41450+ * Added more debug statements.
41451+ * Make headroom depend on structure, not hard-coded values.
41452+ *
41453+ * Revision 1.24 1999/02/10 23:20:33 rgb
41454+ * Shut up annoying 'statement has no effect' compiler warnings with
41455+ * debugging compiled out.
41456+ *
41457+ * Revision 1.23 1999/02/10 22:36:30 rgb
41458+ * Clean-up obsolete, unused and messy code.
41459+ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
41460+ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
41461+ * original ipsec_tunnel_start_xmit.
41462+ * Send all packet with different inner and outer destinations directly to
41463+ * the attached physical device, rather than back through ip_forward,
41464+ * preventing disappearing routes problems.
41465+ * Do sanity checking before investing too much CPU in allocating new
41466+ * structures.
41467+ * Fail on IP header options: We cannot process them yet.
41468+ * Add some helpful comments.
41469+ * Use virtual device for parameters instead of physical device.
41470+ *
41471+ * Revision 1.22 1999/02/10 03:03:02 rgb
41472+ * Duh. Fixed the TTL bug: forgot to update the checksum.
41473+ *
41474+ * Revision 1.21 1999/02/09 23:17:53 rgb
41475+ * Add structure members to ipsec_print_ip debug function.
41476+ * Temporarily fix TTL bug preventing tunnel mode from functioning.
41477+ *
41478+ * Revision 1.20 1999/02/09 00:14:25 rgb
41479+ * Add KLIPSPRINT macro. (Not used yet, though.)
41480+ * Delete old ip_tunnel code (BADCODE).
41481+ * Decrement TTL in outgoing packet.
41482+ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
41483+ * Delete ethernet only feature and fix hard-coded hard_header_len.
41484+ *
41485+ * Revision 1.19 1999/01/29 17:56:22 rgb
41486+ * 64-bit re-fix submitted by Peter Onion.
41487+ *
41488+ * Revision 1.18 1999/01/28 22:43:24 rgb
41489+ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
41490+ *
41491+ * Revision 1.17 1999/01/26 02:08:16 rgb
41492+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
41493+ * Removed dead code.
41494+ *
41495+ * Revision 1.16 1999/01/22 06:25:26 rgb
41496+ * Cruft clean-out.
41497+ * Added algorithm switch code.
41498+ * 64-bit clean-up.
41499+ * Passthrough on IPIP protocol, spi 0x0 fix.
41500+ * Enhanced debugging.
41501+ *
41502+ * Revision 1.15 1998/12/01 13:22:04 rgb
41503+ * Added support for debug printing of version info.
41504+ *
41505+ * Revision 1.14 1998/11/30 13:22:55 rgb
41506+ * Rationalised all the klips kernel file headers. They are much shorter
41507+ * now and won't conflict under RH5.2.
41508+ *
41509+ * Revision 1.13 1998/11/17 21:13:52 rgb
41510+ * Put IKE port bypass debug output in user-switched debug statements.
41511+ *
41512+ * Revision 1.12 1998/11/13 13:20:25 rgb
41513+ * Fixed ntohs bug in udp/500 hole for IKE.
41514+ *
41515+ * Revision 1.11 1998/11/10 08:01:19 rgb
41516+ * Kill tcp/500 hole, keep udp/500 hole.
41517+ *
41518+ * Revision 1.10 1998/11/09 21:29:26 rgb
41519+ * If no eroute is found, discard packet and incr. tx_error.
41520+ *
41521+ * Revision 1.9 1998/10/31 06:50:00 rgb
41522+ * Add tcp/udp/500 bypass.
41523+ * Fixed up comments in #endif directives.
41524+ *
41525+ * Revision 1.8 1998/10/27 00:34:31 rgb
41526+ * Reformat debug output of IP headers.
41527+ * Newlines added before calls to ipsec_print_ip.
41528+ *
41529+ * Revision 1.7 1998/10/19 14:44:28 rgb
41530+ * Added inclusion of freeswan.h.
41531+ * sa_id structure implemented and used: now includes protocol.
41532+ *
41533+ * Revision 1.6 1998/10/09 04:31:35 rgb
41534+ * Added 'klips_debug' prefix to all klips printk debug statements.
41535+ *
41536+ * Revision 1.5 1998/08/28 03:09:51 rgb
41537+ * Prevent kernel log spam with default route through ipsec.
41538+ *
41539+ * Revision 1.4 1998/08/05 22:23:09 rgb
41540+ * Change setdev return code to ENXIO for a non-existant physical device.
41541+ *
41542+ * Revision 1.3 1998/07/29 20:41:11 rgb
41543+ * Add ipsec_tunnel_clear to clear all tunnel attachments.
41544+ *
41545+ * Revision 1.2 1998/06/25 20:00:33 rgb
41546+ * Clean up #endif comments.
41547+ * Rename dev_ipsec to dev_ipsec0 for consistency.
41548+ * Document ipsec device fields.
41549+ * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
41550+ * Get debugging report for *every* ipsec device initialisation.
41551+ * Comment out redundant code.
41552+ *
41553+ * Revision 1.1 1998/06/18 21:27:50 henry
41554+ * move sources from klips/src to klips/net/ipsec, to keep stupid
41555+ * kernel-build scripts happier in the presence of symlinks
41556+ *
41557+ * Revision 1.8 1998/06/14 23:49:40 rgb
41558+ * Clarify version reporting on module loading.
41559+ *
41560+ * Revision 1.7 1998/05/27 23:19:20 rgb
41561+ * Added version reporting.
41562+ *
41563+ * Revision 1.6 1998/05/18 21:56:23 rgb
41564+ * Clean up for numerical consistency of output and cleaning up debug code.
41565+ *
41566+ * Revision 1.5 1998/05/12 02:44:23 rgb
41567+ * Clarifying 'no e-route to host' message.
41568+ *
41569+ * Revision 1.4 1998/04/30 15:34:35 rgb
41570+ * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
41571+ *
41572+ * Revision 1.3 1998/04/21 21:28:54 rgb
41573+ * Rearrange debug switches to change on the fly debug output from user
41574+ * space. Only kernel changes checked in at this time. radij.c was also
41575+ * changed to temporarily remove buggy debugging code in rj_delete causing
41576+ * an OOPS and hence, netlink device open errors.
41577+ *
41578+ * Revision 1.2 1998/04/12 22:03:24 rgb
41579+ * Updated ESP-3DES-HMAC-MD5-96,
41580+ * ESP-DES-HMAC-MD5-96,
41581+ * AH-HMAC-MD5-96,
41582+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
41583+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
41584+ *
41585+ * Fixed eroute references in /proc/net/ipsec*.
41586+ *
41587+ * Started to patch module unloading memory leaks in ipsec_netlink and
41588+ * radij tree unloading.
41589+ *
41590+ * Revision 1.1 1998/04/09 03:06:12 henry
41591+ * sources moved up from linux/net/ipsec
41592+ *
41593+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
41594+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
41595+ *
41596+ * Revision 0.5 1997/06/03 04:24:48 ji
41597+ * Added transport mode.
41598+ * Changed the way routing is done.
41599+ * Lots of bug fixes.
41600+ *
41601+ * Revision 0.4 1997/01/15 01:28:15 ji
41602+ * No changes.
41603+ *
41604+ * Revision 0.3 1996/11/20 14:39:04 ji
41605+ * Minor cleanups.
41606+ * Rationalized debugging code.
41607+ *
41608+ * Revision 0.2 1996/11/02 00:18:33 ji
41609+ * First limited release.
41610+ *
41611+ * Local Variables:
41612+ * c-style: linux
41613+ * End:
41614+ */
41615--- /dev/null Tue Mar 11 13:02:56 2003
41616+++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004
41617@@ -0,0 +1,360 @@
41618+/*
41619+ * Common routines for IPSEC transformations.
41620+ * Copyright (C) 1996, 1997 John Ioannidis.
41621+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
41622+ *
41623+ * This program is free software; you can redistribute it and/or modify it
41624+ * under the terms of the GNU General Public License as published by the
41625+ * Free Software Foundation; either version 2 of the License, or (at your
41626+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
41627+ *
41628+ * This program is distributed in the hope that it will be useful, but
41629+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
41630+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41631+ * for more details.
41632+ *
41633+ * RCSID $Id: ipsec_xform.c,v 1.65.2.1 2006/10/06 21:39:26 paul Exp $
41634+ */
41635+
41636+#ifndef AUTOCONF_INCLUDED
41637+#include <linux/config.h>
41638+#endif
41639+#include <linux/version.h>
41640+#include <linux/kernel.h> /* printk() */
41641+
41642+#include "freeswan/ipsec_param.h"
41643+
41644+#ifdef MALLOC_SLAB
41645+# include <linux/slab.h> /* kmalloc() */
41646+#else /* MALLOC_SLAB */
41647+# include <linux/malloc.h> /* kmalloc() */
41648+#endif /* MALLOC_SLAB */
41649+#include <linux/errno.h> /* error codes */
41650+#include <linux/types.h> /* size_t */
41651+#include <linux/interrupt.h> /* mark_bh */
41652+
41653+#include <linux/netdevice.h> /* struct device, and other headers */
41654+#include <linux/etherdevice.h> /* eth_type_trans */
41655+#include <linux/ip.h> /* struct iphdr */
41656+#include <linux/skbuff.h>
41657+#include <linux/random.h> /* get_random_bytes() */
41658+#include <freeswan.h>
41659+#ifdef SPINLOCK
41660+# ifdef SPINLOCK_23
41661+# include <linux/spinlock.h> /* *lock* */
41662+# else /* SPINLOCK_23 */
41663+# include <asm/spinlock.h> /* *lock* */
41664+# endif /* SPINLOCK_23 */
41665+#endif /* SPINLOCK */
41666+
41667+#include <net/ip.h>
41668+
41669+#include "freeswan/radij.h"
41670+#include "freeswan/ipsec_encap.h"
41671+#include "freeswan/ipsec_radij.h"
41672+#include "freeswan/ipsec_xform.h"
41673+#include "freeswan/ipsec_ipe4.h"
41674+#include "freeswan/ipsec_ah.h"
41675+#include "freeswan/ipsec_esp.h"
41676+
41677+#include <pfkeyv2.h>
41678+#include <pfkey.h>
41679+
41680+#ifdef CONFIG_KLIPS_DEBUG
41681+int debug_xform = 0;
41682+#endif /* CONFIG_KLIPS_DEBUG */
41683+
41684+#ifdef SPINLOCK
41685+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
41686+#else /* SPINLOCK */
41687+spinlock_t tdb_lock;
41688+#endif /* SPINLOCK */
41689+
41690+/*
41691+ * $Log: ipsec_xform.c,v $
41692+ * Revision 1.65.2.1 2006/10/06 21:39:26 paul
41693+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
41694+ * set. This is defined through autoconf.h which is included through the
41695+ * linux kernel build macros.
41696+ *
41697+ * Revision 1.65 2005/04/29 05:10:22 mcr
41698+ * removed from extraenous includes to make unit testing easier.
41699+ *
41700+ * Revision 1.64 2004/07/10 19:11:18 mcr
41701+ * CONFIG_IPSEC -> CONFIG_KLIPS.
41702+ *
41703+ * Revision 1.63 2003/10/31 02:27:55 mcr
41704+ * pulled up port-selector patches and sa_id elimination.
41705+ *
41706+ * Revision 1.62.30.1 2003/10/29 01:30:41 mcr
41707+ * elimited "struct sa_id".
41708+ *
41709+ * Revision 1.62 2002/05/14 02:34:21 rgb
41710+ * Delete stale code.
41711+ *
41712+ * Revision 1.61 2002/04/24 07:55:32 mcr
41713+ * #include patches and Makefiles for post-reorg compilation.
41714+ *
41715+ * Revision 1.60 2002/04/24 07:36:33 mcr
41716+ * Moved from ./klips/net/ipsec/ipsec_xform.c,v
41717+ *
41718+ * Revision 1.59 2002/03/29 15:01:36 rgb
41719+ * Delete decommissioned code.
41720+ *
41721+ * Revision 1.58 2002/01/29 17:17:57 mcr
41722+ * moved include of ipsec_param.h to after include of linux/kernel.h
41723+ * otherwise, it seems that some option that is set in ipsec_param.h
41724+ * screws up something subtle in the include path to kernel.h, and
41725+ * it complains on the snprintf() prototype.
41726+ *
41727+ * Revision 1.57 2002/01/29 04:00:53 mcr
41728+ * more excise of kversions.h header.
41729+ *
41730+ * Revision 1.56 2001/11/27 05:17:22 mcr
41731+ * turn off the worst of the per-packet debugging.
41732+ *
41733+ * Revision 1.55 2001/11/26 09:23:50 rgb
41734+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
41735+ *
41736+ * Revision 1.54 2001/10/18 04:45:21 rgb
41737+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
41738+ * lib/freeswan.h version macros moved to lib/kversions.h.
41739+ * Other compiler directive cleanups.
41740+ *
41741+ * Revision 1.53 2001/09/08 21:13:34 rgb
41742+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
41743+ *
41744+ * Revision 1.52 2001/06/14 19:35:11 rgb
41745+ * Update copyright date.
41746+ *
41747+ * Revision 1.51 2001/05/30 08:14:03 rgb
41748+ * Removed vestiges of esp-null transforms.
41749+ *
41750+ * Revision 1.50 2001/05/03 19:43:18 rgb
41751+ * Initialise error return variable.
41752+ * Update SENDERR macro.
41753+ * Fix sign of error return code for ipsec_tdbcleanup().
41754+ * Use more appropriate return code for ipsec_tdbwipe().
41755+ *
41756+ * Revision 1.49 2001/04/19 18:56:17 rgb
41757+ * Fixed tdb table locking comments.
41758+ *
41759+ * Revision 1.48 2001/02/27 22:24:55 rgb
41760+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
41761+ * Check for satoa() return codes.
41762+ *
41763+ * Revision 1.47 2000/11/06 04:32:08 rgb
41764+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
41765+ *
41766+ * Revision 1.46 2000/09/20 16:21:57 rgb
41767+ * Cleaned up ident string alloc/free.
41768+ *
41769+ * Revision 1.45 2000/09/08 19:16:51 rgb
41770+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
41771+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
41772+ *
41773+ * Revision 1.44 2000/08/30 05:29:04 rgb
41774+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
41775+ *
41776+ * Revision 1.43 2000/08/18 21:30:41 rgb
41777+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
41778+ *
41779+ * Revision 1.42 2000/08/01 14:51:51 rgb
41780+ * Removed _all_ remaining traces of DES.
41781+ *
41782+ * Revision 1.41 2000/07/28 14:58:31 rgb
41783+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
41784+ *
41785+ * Revision 1.40 2000/06/28 05:50:11 rgb
41786+ * Actually set iv_bits.
41787+ *
41788+ * Revision 1.39 2000/05/10 23:11:09 rgb
41789+ * Added netlink debugging output.
41790+ * Added a cast to quiet down the ntohl bug.
41791+ *
41792+ * Revision 1.38 2000/05/10 19:18:42 rgb
41793+ * Cast output of ntohl so that the broken prototype doesn't make our
41794+ * compile noisy.
41795+ *
41796+ * Revision 1.37 2000/03/16 14:04:59 rgb
41797+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
41798+ *
41799+ * Revision 1.36 2000/01/26 10:11:28 rgb
41800+ * Fixed spacing in error text causing run-in words.
41801+ *
41802+ * Revision 1.35 2000/01/21 06:17:16 rgb
41803+ * Tidied up compiler directive indentation for readability.
41804+ * Added ictx,octx vars for simplification.(kravietz)
41805+ * Added macros for HMAC padding magic numbers.(kravietz)
41806+ * Fixed missing key length reporting bug.
41807+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
41808+ *
41809+ * Revision 1.34 1999/12/08 00:04:19 rgb
41810+ * Fixed SA direction overwriting bug for netlink users.
41811+ *
41812+ * Revision 1.33 1999/12/01 22:16:44 rgb
41813+ * Minor formatting changes in ESP MD5 initialisation.
41814+ *
41815+ * Revision 1.32 1999/11/25 09:06:36 rgb
41816+ * Fixed error return messages, should be returning negative numbers.
41817+ * Implemented SENDERR macro for propagating error codes.
41818+ * Added debug message and separate error code for algorithms not compiled
41819+ * in.
41820+ *
41821+ * Revision 1.31 1999/11/23 23:06:26 rgb
41822+ * Sort out pfkey and freeswan headers, putting them in a library path.
41823+ *
41824+ * Revision 1.30 1999/11/18 04:09:20 rgb
41825+ * Replaced all kernel version macros to shorter, readable form.
41826+ *
41827+ * Revision 1.29 1999/11/17 15:53:40 rgb
41828+ * Changed all occurrences of #include "../../../lib/freeswan.h"
41829+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
41830+ * klips/net/ipsec/Makefile.
41831+ *
41832+ * Revision 1.28 1999/10/18 20:04:01 rgb
41833+ * Clean-out unused cruft.
41834+ *
41835+ * Revision 1.27 1999/10/03 19:01:03 rgb
41836+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
41837+ *
41838+ * Revision 1.26 1999/10/01 16:22:24 rgb
41839+ * Switch from assignment init. to functional init. of spinlocks.
41840+ *
41841+ * Revision 1.25 1999/10/01 15:44:54 rgb
41842+ * Move spinlock header include to 2.1> scope.
41843+ *
41844+ * Revision 1.24 1999/10/01 00:03:46 rgb
41845+ * Added tdb structure locking.
41846+ * Minor formatting changes.
41847+ * Add function to initialize tdb hash table.
41848+ *
41849+ * Revision 1.23 1999/05/25 22:42:12 rgb
41850+ * Add deltdbchain() debugging.
41851+ *
41852+ * Revision 1.22 1999/05/25 21:24:31 rgb
41853+ * Add debugging statements to deltdbchain().
41854+ *
41855+ * Revision 1.21 1999/05/25 03:51:48 rgb
41856+ * Refix error return code.
41857+ *
41858+ * Revision 1.20 1999/05/25 03:34:07 rgb
41859+ * Fix error return for flush.
41860+ *
41861+ * Revision 1.19 1999/05/09 03:25:37 rgb
41862+ * Fix bug introduced by 2.2 quick-and-dirty patch.
41863+ *
41864+ * Revision 1.18 1999/05/05 22:02:32 rgb
41865+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
41866+ *
41867+ * Revision 1.17 1999/04/29 15:20:16 rgb
41868+ * Change gettdb parameter to a pointer to reduce stack loading and
41869+ * facilitate parameter sanity checking.
41870+ * Add sanity checking for null pointer arguments.
41871+ * Add debugging instrumentation.
41872+ * Add function deltdbchain() which will take care of unlinking,
41873+ * zeroing and deleting a chain of tdbs.
41874+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
41875+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
41876+ * structures.
41877+ *
41878+ * Revision 1.16 1999/04/16 15:36:29 rgb
41879+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
41880+ *
41881+ * Revision 1.15 1999/04/11 00:29:01 henry
41882+ * GPL boilerplate
41883+ *
41884+ * Revision 1.14 1999/04/06 04:54:28 rgb
41885+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
41886+ * patch shell fixes.
41887+ *
41888+ * Revision 1.13 1999/02/19 18:23:01 rgb
41889+ * Nix debug off compile warning.
41890+ *
41891+ * Revision 1.12 1999/02/17 16:52:16 rgb
41892+ * Consolidate satoa()s for space and speed efficiency.
41893+ * Convert DEBUG_IPSEC to KLIPS_PRINT
41894+ * Clean out unused cruft.
41895+ * Ditch NET_IPIP dependancy.
41896+ * Loop for 3des key setting.
41897+ *
41898+ * Revision 1.11 1999/01/26 02:09:05 rgb
41899+ * Remove ah/esp/IPIP switching on include files.
41900+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
41901+ * Removed dead code.
41902+ * Clean up debug code when switched off.
41903+ * Remove references to INET_GET_PROTOCOL.
41904+ * Added code exclusion macros to reduce code from unused algorithms.
41905+ *
41906+ * Revision 1.10 1999/01/22 06:28:55 rgb
41907+ * Cruft clean-out.
41908+ * Put random IV generation in kernel.
41909+ * Added algorithm switch code.
41910+ * Enhanced debugging.
41911+ * 64-bit clean-up.
41912+ *
41913+ * Revision 1.9 1998/11/30 13:22:55 rgb
41914+ * Rationalised all the klips kernel file headers. They are much shorter
41915+ * now and won't conflict under RH5.2.
41916+ *
41917+ * Revision 1.8 1998/11/25 04:59:06 rgb
41918+ * Add conditionals for no IPIP tunnel code.
41919+ * Delete commented out code.
41920+ *
41921+ * Revision 1.7 1998/10/31 06:50:41 rgb
41922+ * Convert xform ASCII names to no spaces.
41923+ * Fixed up comments in #endif directives.
41924+ *
41925+ * Revision 1.6 1998/10/19 14:44:28 rgb
41926+ * Added inclusion of freeswan.h.
41927+ * sa_id structure implemented and used: now includes protocol.
41928+ *
41929+ * Revision 1.5 1998/10/09 04:32:19 rgb
41930+ * Added 'klips_debug' prefix to all klips printk debug statements.
41931+ *
41932+ * Revision 1.4 1998/08/12 00:11:31 rgb
41933+ * Added new xform functions to the xform table.
41934+ * Fixed minor debug output spelling error.
41935+ *
41936+ * Revision 1.3 1998/07/09 17:45:31 rgb
41937+ * Clarify algorithm not available message.
41938+ *
41939+ * Revision 1.2 1998/06/23 03:00:51 rgb
41940+ * Check for presence of IPIP protocol if it is setup one way (we don't
41941+ * know what has been set up the other way and can only assume it will be
41942+ * symmetrical with the exception of keys).
41943+ *
41944+ * Revision 1.1 1998/06/18 21:27:51 henry
41945+ * move sources from klips/src to klips/net/ipsec, to keep stupid
41946+ * kernel-build scripts happier in the presence of symlinks
41947+ *
41948+ * Revision 1.3 1998/06/11 05:54:59 rgb
41949+ * Added transform version string pointer to xformsw initialisations.
41950+ *
41951+ * Revision 1.2 1998/04/21 21:28:57 rgb
41952+ * Rearrange debug switches to change on the fly debug output from user
41953+ * space. Only kernel changes checked in at this time. radij.c was also
41954+ * changed to temporarily remove buggy debugging code in rj_delete causing
41955+ * an OOPS and hence, netlink device open errors.
41956+ *
41957+ * Revision 1.1 1998/04/09 03:06:13 henry
41958+ * sources moved up from linux/net/ipsec
41959+ *
41960+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
41961+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
41962+ *
41963+ * Revision 0.5 1997/06/03 04:24:48 ji
41964+ * Added ESP-3DES-MD5-96
41965+ *
41966+ * Revision 0.4 1997/01/15 01:28:15 ji
41967+ * Added new transforms.
41968+ *
41969+ * Revision 0.3 1996/11/20 14:39:04 ji
41970+ * Minor cleanups.
41971+ * Rationalized debugging code.
41972+ *
41973+ * Revision 0.2 1996/11/02 00:18:33 ji
41974+ * First limited release.
41975+ *
41976+ *
41977+ */
41978--- /dev/null Tue Mar 11 13:02:56 2003
41979+++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004
4b871415 41980@@ -0,0 +1,1855 @@
b4f8d26c
MT
41981+/*
41982+ * IPSEC Transmit code.
41983+ * Copyright (C) 1996, 1997 John Ioannidis.
41984+ * Copyright (C) 1998-2003 Richard Guy Briggs.
41985+ * Copyright (C) 2004-2005 Michael Richardson <mcr@xelerance.com>
41986+ *
41987+ * This program is free software; you can redistribute it and/or modify it
41988+ * under the terms of the GNU General Public License as published by the
41989+ * Free Software Foundation; either version 2 of the License, or (at your
41990+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
41991+ *
41992+ * This program is distributed in the hope that it will be useful, but
41993+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
41994+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41995+ * for more details.
41996+ */
41997+
4b871415 41998+char ipsec_xmit_c_version[] = "RCSID $Id: ipsec_xmit.c,v 1.20.2.9 2007/07/06 17:18:43 paul Exp $";
b4f8d26c
MT
41999+
42000+#define __NO_VERSION__
42001+#include <linux/module.h>
42002+#ifndef AUTOCONF_INCLUDED
42003+#include <linux/config.h>
42004+#endif /* for CONFIG_IP_FORWARD */
42005+#include <linux/version.h>
42006+#include <linux/kernel.h> /* printk() */
42007+
42008+#include "openswan/ipsec_param.h"
42009+
42010+#ifdef MALLOC_SLAB
42011+# include <linux/slab.h> /* kmalloc() */
42012+#else /* MALLOC_SLAB */
42013+# include <linux/malloc.h> /* kmalloc() */
42014+#endif /* MALLOC_SLAB */
42015+#include <linux/errno.h> /* error codes */
42016+#include <linux/types.h> /* size_t */
42017+#include <linux/interrupt.h> /* mark_bh */
42018+
42019+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
42020+#include <linux/etherdevice.h> /* eth_type_trans */
42021+#include <linux/ip.h> /* struct iphdr */
42022+#include <linux/tcp.h> /* struct tcphdr */
42023+#include <linux/udp.h> /* struct udphdr */
42024+#include <linux/skbuff.h>
42025+#include <asm/uaccess.h>
42026+#include <asm/checksum.h>
42027+#include <openswan.h>
42028+#ifdef NET_21
42029+# define MSS_HACK_ /* experimental */
42030+# include <linux/in6.h>
42031+# include <net/dst.h>
42032+# define proto_priv cb
42033+#endif /* NET_21 */
42034+
42035+#include <net/icmp.h> /* icmp_send() */
42036+#include <net/ip.h>
42037+#ifdef NETDEV_23
42038+# include <linux/netfilter_ipv4.h>
42039+#endif /* NETDEV_23 */
42040+
42041+#include <linux/if_arp.h>
42042+#ifdef MSS_HACK
42043+# include <net/tcp.h> /* TCP options */
42044+#endif /* MSS_HACK */
42045+
42046+#include "openswan/radij.h"
42047+#include "openswan/ipsec_life.h"
42048+#include "openswan/ipsec_xform.h"
42049+#include "openswan/ipsec_eroute.h"
42050+#include "openswan/ipsec_encap.h"
42051+#include "openswan/ipsec_radij.h"
42052+#include "openswan/ipsec_xmit.h"
42053+#include "openswan/ipsec_sa.h"
42054+#include "openswan/ipsec_tunnel.h"
42055+#include "openswan/ipsec_ipe4.h"
42056+#include "openswan/ipsec_ah.h"
42057+#include "openswan/ipsec_esp.h"
42058+
42059+#ifdef CONFIG_KLIPS_IPCOMP
42060+#include "openswan/ipcomp.h"
42061+#endif /* CONFIG_KLIPS_IPCOMP */
42062+
42063+#include <pfkeyv2.h>
42064+#include <pfkey.h>
42065+
42066+#include "openswan/ipsec_proto.h"
42067+#include "openswan/ipsec_alg.h"
42068+
42069+
42070+/*
42071+ * Stupid kernel API differences in APIs. Not only do some
42072+ * kernels not have ip_select_ident, but some have differing APIs,
42073+ * and SuSE has one with one parameter, but no way of checking to
42074+ * see what is really what.
42075+ */
42076+
42077+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
42078+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
42079+#else
42080+
42081+/* simplest case, nothing */
42082+#if !defined(IP_SELECT_IDENT)
42083+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
42084+#endif
42085+
42086+/* kernels > 2.3.37-ish */
42087+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
42088+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
42089+#endif
42090+
42091+/* kernels > 2.4.2 */
42092+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
42093+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
42094+#endif
42095+
42096+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
42097+
42098+
42099+
42100+#if defined(CONFIG_KLIPS_AH)
42101+static __u32 zeroes[64];
42102+#endif
42103+
42104+#ifdef CONFIG_KLIPS_DEBUG
42105+int sysctl_ipsec_debug_verbose = 0;
42106+#endif /* CONFIG_KLIPS_DEBUG */
42107+
42108+int ipsec_xmit_trap_count = 0;
42109+int ipsec_xmit_trap_sendcount = 0;
42110+
42111+int sysctl_ipsec_icmp = 0;
42112+int sysctl_ipsec_tos = 0;
42113+
42114+#ifdef CONFIG_KLIPS_DEBUG
42115+#define dmp(_x,_y,_z) if(debug_tunnel) ipsec_dmp_block(_x,_y,_z)
42116+#else /* CONFIG_KLIPS_DEBUG */
42117+#define dmp(_x, _y, _z)
42118+#endif /* CONFIG_KLIPS_DEBUG */
42119+
42120+
42121+#if !defined(SKB_COPY_EXPAND) || defined(KLIPS_UNIT_TESTS)
42122+/*
42123+ * This is mostly skbuff.c:skb_copy().
42124+ */
42125+struct sk_buff *
42126+skb_copy_expand(const struct sk_buff *skb, int headroom,
42127+ int tailroom, int priority)
42128+{
42129+ struct sk_buff *n;
42130+ unsigned long offset;
42131+
42132+ /*
42133+ * Do sanity checking
42134+ */
42135+ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
42136+ printk(KERN_WARNING
42137+ "klips_error:skb_copy_expand: "
42138+ "Illegal negative head,tailroom %d,%d\n",
42139+ headroom,
42140+ tailroom);
42141+ return NULL;
42142+ }
42143+ /*
42144+ * Allocate the copy buffer
42145+ */
42146+
42147+#ifndef NET_21
42148+ IS_SKB(skb);
42149+#endif /* !NET_21 */
42150+
42151+
42152+ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
42153+
42154+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42155+ "klips_debug:skb_copy_expand: "
42156+ "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
42157+ skb->end - skb->head + headroom + tailroom,
42158+ skb->head,
42159+ skb->data,
42160+ skb->tail,
42161+ skb->end,
42162+ skb->end - skb->head,
42163+ skb->tail - skb->data);
42164+
42165+ if(n==NULL)
42166+ return NULL;
42167+
42168+ /*
42169+ * Shift between the two data areas in bytes
42170+ */
42171+
42172+ /* Set the data pointer */
42173+ skb_reserve(n,skb->data-skb->head+headroom);
42174+ /* Set the tail pointer and length */
42175+ if(skb_tailroom(n) < skb->len) {
42176+ printk(KERN_WARNING "klips_error:skb_copy_expand: "
42177+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
42178+ (unsigned long int)skb->len,
42179+ skb_tailroom(n));
42180+ ipsec_kfree_skb(n);
42181+ return NULL;
42182+ }
42183+ skb_put(n,skb->len);
42184+
42185+ offset=n->head + headroom - skb->head;
42186+
42187+ /* Copy the bytes */
42188+ memcpy(n->head + headroom, skb->head,skb->end-skb->head);
42189+#ifdef NET_21
42190+ n->csum=skb->csum;
42191+ n->priority=skb->priority;
42192+ n->dst=dst_clone(skb->dst);
42193+ if(skb->nh.raw)
42194+ n->nh.raw=skb->nh.raw+offset;
42195+#ifndef NETDEV_23
42196+ n->is_clone=0;
42197+#endif /* NETDEV_23 */
42198+ atomic_set(&n->users, 1);
42199+ n->destructor = NULL;
42200+#ifdef HAVE_SOCK_SECURITY
42201+ n->security=skb->security;
42202+#endif
42203+#else /* NET_21 */
42204+ n->link3=NULL;
42205+ n->when=skb->when;
42206+ if(skb->ip_hdr)
42207+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
42208+ n->saddr=skb->saddr;
42209+ n->daddr=skb->daddr;
42210+ n->raddr=skb->raddr;
42211+ n->seq=skb->seq;
42212+ n->end_seq=skb->end_seq;
42213+ n->ack_seq=skb->ack_seq;
42214+ n->acked=skb->acked;
42215+ n->free=1;
42216+ n->arp=skb->arp;
42217+ n->tries=0;
42218+ n->lock=0;
42219+ n->users=0;
42220+#endif /* NET_21 */
42221+ n->protocol=skb->protocol;
42222+ n->list=NULL;
42223+ n->sk=NULL;
42224+ n->dev=skb->dev;
42225+ if(skb->h.raw)
42226+ n->h.raw=skb->h.raw+offset;
42227+ if(skb->mac.raw)
42228+ n->mac.raw=skb->mac.raw+offset;
42229+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
42230+#ifndef NETDEV_23
42231+ n->used=skb->used;
42232+#endif /* !NETDEV_23 */
42233+ n->pkt_type=skb->pkt_type;
42234+ n->stamp=skb->stamp;
42235+
42236+#ifndef NET_21
42237+ IS_SKB(n);
42238+#endif /* !NET_21 */
42239+ return n;
42240+}
42241+#endif /* !SKB_COPY_EXPAND */
42242+
42243+#ifdef CONFIG_KLIPS_DEBUG
42244+void
42245+ipsec_print_ip(struct iphdr *ip)
42246+{
42247+ char buf[ADDRTOA_BUF];
42248+
42249+ printk(KERN_INFO "klips_debug: IP:");
42250+ printk(" ihl:%d", ip->ihl << 2);
42251+ printk(" ver:%d", ip->version);
42252+ printk(" tos:%d", ip->tos);
42253+ printk(" tlen:%d", ntohs(ip->tot_len));
42254+ printk(" id:%d", ntohs(ip->id));
42255+ printk(" %s%s%sfrag_off:%d",
42256+ ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
42257+ ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
42258+ ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
42259+ (ntohs(ip->frag_off) & IP_OFFSET) << 3);
42260+ printk(" ttl:%d", ip->ttl);
42261+ printk(" proto:%d", ip->protocol);
42262+ if(ip->protocol == IPPROTO_UDP)
42263+ printk(" (UDP)");
42264+ if(ip->protocol == IPPROTO_TCP)
42265+ printk(" (TCP)");
42266+ if(ip->protocol == IPPROTO_ICMP)
42267+ printk(" (ICMP)");
42268+ if(ip->protocol == IPPROTO_ESP)
42269+ printk(" (ESP)");
42270+ if(ip->protocol == IPPROTO_AH)
42271+ printk(" (AH)");
42272+ if(ip->protocol == IPPROTO_COMP)
42273+ printk(" (COMP)");
42274+ printk(" chk:%d", ntohs(ip->check));
42275+ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
42276+ printk(" saddr:%s", buf);
42277+ if(ip->protocol == IPPROTO_UDP)
42278+ printk(":%d",
42279+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
42280+ if(ip->protocol == IPPROTO_TCP)
42281+ printk(":%d",
42282+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
42283+ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
42284+ printk(" daddr:%s", buf);
42285+ if(ip->protocol == IPPROTO_UDP)
42286+ printk(":%d",
42287+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
42288+ if(ip->protocol == IPPROTO_TCP)
42289+ printk(":%d",
42290+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
42291+ if(ip->protocol == IPPROTO_ICMP)
42292+ printk(" type:code=%d:%d",
42293+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
42294+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
42295+ printk("\n");
42296+
42297+ if(sysctl_ipsec_debug_verbose) {
42298+ __u8 *c;
42299+ int len = ntohs(ip->tot_len) - ip->ihl*4;
42300+
42301+ c = ((__u8*)ip) + ip->ihl*4;
42302+ ipsec_dmp_block("ip_print", c, len);
42303+ }
42304+}
42305+#endif /* CONFIG_KLIPS_DEBUG */
42306+
42307+#ifdef MSS_HACK
42308+/*
42309+ * Issues:
42310+ * 1) Fragments arriving in the tunnel should probably be rejected.
42311+ * 2) How does this affect syncookies, mss_cache, dst cache ?
42312+ * 3) Path MTU discovery handling needs to be reviewed. For example,
42313+ * if we receive an ICMP 'packet too big' message from an intermediate
42314+ * router specifying it's next hop MTU, our stack may process this and
42315+ * adjust the MSS without taking our AH/ESP overheads into account.
42316+ */
42317+
42318+
42319+/*
42320+ * Recaclulate checksum using differences between changed datum,
42321+ * borrowed from netfilter.
42322+ */
42323+DEBUG_NO_STATIC u_int16_t
42324+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
42325+{
42326+ u_int32_t diffs[] = { oldvalinv, newval };
42327+ return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
42328+ oldcheck^0xFFFF));
42329+}
42330+
42331+/*
42332+ * Determine effective MSS.
42333+ *
42334+ * Note that we assume that there is always an MSS option for our own
42335+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
42336+ * This could change, and we should probably parse TCP options instead.
42337+ *
42338+ */
42339+DEBUG_NO_STATIC u_int8_t
42340+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
42341+{
42342+ u_int16_t oldmss, newmss;
42343+ u_int32_t *mssp;
42344+ struct sock *sk = skb->sk;
42345+
42346+ newmss = tcp_sync_mss(sk, mtu);
42347+ printk(KERN_INFO "klips: setting mss to %u\n", newmss);
42348+ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
42349+ oldmss = ntohl(*mssp) & 0x0000FFFF;
42350+ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
42351+ tcph->check = ipsec_fast_csum(htons(~oldmss),
42352+ htons(newmss), tcph->check);
42353+ return 1;
42354+}
42355+#endif /* MSS_HACK */
42356+
42357+/*
42358+ * Sanity checks
42359+ */
42360+enum ipsec_xmit_value
42361+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs)
42362+{
42363+
42364+ if (ixs->dev == NULL) {
42365+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42366+ "klips_error:ipsec_xmit_sanity_check_dev: "
42367+ "No device associated with skb!\n" );
42368+ return IPSEC_XMIT_NODEV;
42369+ }
42370+
42371+ ixs->prv = ixs->dev->priv;
42372+ if (ixs->prv == NULL) {
42373+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42374+ "klips_error:ipsec_xmit_sanity_check_dev: "
42375+ "Device has no private structure!\n" );
42376+ return IPSEC_XMIT_NOPRIVDEV;
42377+ }
42378+
42379+ ixs->physdev = ixs->prv->dev;
42380+ if (ixs->physdev == NULL) {
42381+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42382+ "klips_error:ipsec_xmit_sanity_check_dev: "
42383+ "Device is not attached to physical device!\n" );
42384+ return IPSEC_XMIT_NOPHYSDEV;
42385+ }
42386+
42387+ ixs->physmtu = ixs->physdev->mtu;
42388+ ixs->cur_mtu = ixs->physdev->mtu;
42389+ ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);
42390+
42391+ return IPSEC_XMIT_OK;
42392+}
42393+
42394+enum ipsec_xmit_value
42395+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs)
42396+{
42397+ /*
42398+ * Return if there is nothing to do. (Does this ever happen?) XXX
42399+ */
42400+ if (ixs->skb == NULL) {
42401+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42402+ "klips_error:ipsec_xmit_sanity_check_skb: "
42403+ "Nothing to do!\n" );
42404+ return IPSEC_XMIT_NOSKB;
42405+ }
42406+
42407+ /* if skb was cloned (most likely due to a packet sniffer such as
42408+ tcpdump being momentarily attached to the interface), make
42409+ a copy of our own to modify */
42410+ if(skb_cloned(ixs->skb)) {
42411+ if
42412+#ifdef SKB_COW_NEW
42413+ (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0)
42414+#else /* SKB_COW_NEW */
42415+ ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL)
42416+#endif /* SKB_COW_NEW */
42417+ {
42418+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42419+ "klips_error:ipsec_xmit_sanity_check_skb: "
42420+ "skb_cow failed to allocate buffer, dropping.\n" );
42421+ ixs->stats->tx_dropped++;
42422+ return IPSEC_XMIT_ERRSKBALLOC;
42423+ }
42424+ }
42425+
42426+ ixs->iph = ixs->skb->nh.iph;
42427+
42428+ /* sanity check for IP version as we can't handle IPv6 right now */
42429+ if (ixs->iph->version != 4) {
42430+ KLIPS_PRINT(debug_tunnel,
42431+ "klips_debug:ipsec_xmit_sanity_check_skb: "
42432+ "found IP Version %d but cannot process other IP versions than v4.\n",
42433+ ixs->iph->version); /* XXX */
42434+ ixs->stats->tx_dropped++;
42435+ return IPSEC_XMIT_NOIPV6;
42436+ }
42437+
42438+#if IPSEC_DISALLOW_IPOPTIONS
42439+ if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) {
42440+ KLIPS_PRINT(debug_tunnel,
42441+ "klips_debug:ipsec_xmit_sanity_check_skb: "
42442+ "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */
42443+ ixs->stats->tx_dropped++;
42444+ return IPSEC_XMIT_NOIPOPTIONS;
42445+ }
42446+#endif /* IPSEC_DISALLOW_IPOPTIONS */
42447+
42448+#ifndef NET_21
42449+ if (ixs->iph->ttl <= 0) {
42450+ /* Tell the sender its packet died... */
42451+ ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev);
42452+
42453+ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: "
42454+ "TTL=0, too many hops!\n");
42455+ ixs->stats->tx_dropped++;
42456+ return IPSEC_XMIT_TTLEXPIRED;
42457+ }
42458+#endif /* !NET_21 */
42459+
42460+ return IPSEC_XMIT_OK;
42461+}
42462+
42463+enum ipsec_xmit_value
42464+ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs)
42465+{
42466+#ifdef CONFIG_KLIPS_ESP
42467+ struct esphdr *espp;
42468+ unsigned char *idat, *pad;
42469+ int authlen = 0, padlen = 0, i;
42470+#endif /* !CONFIG_KLIPS_ESP */
42471+#ifdef CONFIG_KLIPS_AH
42472+ struct iphdr ipo;
42473+ struct ahhdr *ahp;
42474+#endif /* CONFIG_KLIPS_AH */
42475+#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
42476+ union {
42477+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42478+ MD5_CTX md5;
42479+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42480+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42481+ SHA1_CTX sha1;
42482+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42483+ } tctx;
42484+ __u8 hash[AH_AMAX];
42485+#endif /* defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMACn_SHA1) */
42486+ int headroom = 0, tailroom = 0, ilen = 0, len = 0;
42487+ unsigned char *dat;
42488+ int blocksize = 8; /* XXX: should be inside ixs --jjo */
42489+ struct ipsec_alg_enc *ixt_e = NULL;
42490+ struct ipsec_alg_auth *ixt_a = NULL;
42491+
42492+ ixs->iphlen = ixs->iph->ihl << 2;
42493+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
42494+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF);
42495+ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
42496+ "klips_debug:ipsec_xmit_encap_once: "
42497+ "calling output for <%s%s%s>, SA:%s\n",
42498+ IPS_XFORM_NAME(ixs->ipsp),
42499+ ixs->sa_len ? ixs->sa_txt : " (error)");
42500+
42501+ switch(ixs->ipsp->ips_said.proto) {
42502+#ifdef CONFIG_KLIPS_AH
42503+ case IPPROTO_AH:
42504+ headroom += sizeof(struct ahhdr);
42505+ break;
42506+#endif /* CONFIG_KLIPS_AH */
42507+
42508+#ifdef CONFIG_KLIPS_ESP
42509+ case IPPROTO_ESP:
42510+ ixt_e=ixs->ipsp->ips_alg_enc;
42511+ if (ixt_e) {
42512+ blocksize = ixt_e->ixt_common.ixt_blocksize;
42513+ headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
42514+ } else {
42515+ ixs->stats->tx_errors++;
42516+ return IPSEC_XMIT_ESP_BADALG;
42517+ }
42518+
42519+ ixt_a=ixs->ipsp->ips_alg_auth;
42520+ if (ixt_a) {
42521+ tailroom += AHHMAC_HASHLEN;
4b871415 42522+ authlen = AHHMAC_HASHLEN;
b4f8d26c
MT
42523+ } else
42524+ switch(ixs->ipsp->ips_authalg) {
42525+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42526+ case AH_MD5:
42527+ authlen = AHHMAC_HASHLEN;
42528+ break;
42529+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42530+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42531+ case AH_SHA:
42532+ authlen = AHHMAC_HASHLEN;
42533+ break;
42534+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42535+ case AH_NONE:
42536+ break;
42537+ default:
42538+ ixs->stats->tx_errors++;
42539+ return IPSEC_XMIT_ESP_BADALG;
42540+ }
42541+ tailroom += blocksize != 1 ?
42542+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
42543+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
42544+ tailroom += authlen;
42545+ break;
42546+#endif /* CONFIG_KLIPS_ESP */
42547+
42548+#ifdef CONFIG_KLIPS_IPIP
42549+ case IPPROTO_IPIP:
42550+ headroom += sizeof(struct iphdr);
42551+ ixs->iphlen = sizeof(struct iphdr);
42552+ break;
42553+#endif /* !CONFIG_KLIPS_IPIP */
42554+
42555+#ifdef CONFIG_KLIPS_IPCOMP
42556+ case IPPROTO_COMP:
42557+ break;
42558+#endif /* CONFIG_KLIPS_IPCOMP */
42559+
42560+ default:
42561+ ixs->stats->tx_errors++;
42562+ return IPSEC_XMIT_BADPROTO;
42563+ }
42564+
42565+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42566+ "klips_debug:ipsec_xmit_encap_once: "
42567+ "pushing %d bytes, putting %d, proto %d.\n",
42568+ headroom, tailroom, ixs->ipsp->ips_said.proto);
42569+ if(skb_headroom(ixs->skb) < headroom) {
42570+ printk(KERN_WARNING
42571+ "klips_error:ipsec_xmit_encap_once: "
42572+ "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n",
42573+ headroom, skb_headroom(ixs->skb));
42574+ ixs->stats->tx_errors++;
42575+ return IPSEC_XMIT_ESP_PUSHPULLERR;
42576+ }
42577+
42578+ dat = skb_push(ixs->skb, headroom);
42579+ ilen = ixs->skb->len - tailroom;
42580+ if(skb_tailroom(ixs->skb) < tailroom) {
42581+ printk(KERN_WARNING
42582+ "klips_error:ipsec_xmit_encap_once: "
42583+ "tried to skb_put %d, %d available. This should never happen, please report.\n",
42584+ tailroom, skb_tailroom(ixs->skb));
42585+ ixs->stats->tx_errors++;
42586+ return IPSEC_XMIT_ESP_PUSHPULLERR;
42587+ }
42588+ skb_put(ixs->skb, tailroom);
42589+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42590+ "klips_debug:ipsec_xmit_encap_once: "
42591+ "head,tailroom: %d,%d before xform.\n",
42592+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
42593+ len = ixs->skb->len;
42594+ if(len > 0xfff0) {
42595+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: "
42596+ "tot_len (%d) > 65520. This should never happen, please report.\n",
42597+ len);
42598+ ixs->stats->tx_errors++;
42599+ return IPSEC_XMIT_BADLEN;
42600+ }
42601+ memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen);
42602+ ixs->iph = (struct iphdr *)dat;
42603+ ixs->iph->tot_len = htons(ixs->skb->len);
42604+
42605+ switch(ixs->ipsp->ips_said.proto) {
42606+#ifdef CONFIG_KLIPS_ESP
42607+ case IPPROTO_ESP:
42608+ espp = (struct esphdr *)(dat + ixs->iphlen);
42609+ espp->esp_spi = ixs->ipsp->ips_said.spi;
42610+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
42611+
42612+ if (!ixt_e) {
42613+ ixs->stats->tx_errors++;
42614+ return IPSEC_XMIT_ESP_BADALG;
42615+ }
42616+
42617+ idat = dat + ixs->iphlen + headroom;
42618+ ilen = len - (ixs->iphlen + headroom + authlen);
42619+
42620+ /* Self-describing padding */
42621+ pad = &dat[len - tailroom];
42622+ padlen = tailroom - 2 - authlen;
42623+ for (i = 0; i < padlen; i++) {
42624+ pad[i] = i + 1;
42625+ }
42626+ dat[len - authlen - 2] = padlen;
42627+
42628+ dat[len - authlen - 1] = ixs->iph->protocol;
42629+ ixs->iph->protocol = IPPROTO_ESP;
42630+#ifdef CONFIG_KLIPS_DEBUG
42631+ if(debug_tunnel & DB_TN_ENCAP) {
42632+ dmp("pre-encrypt", dat, len);
42633+ }
42634+#endif
42635+
42636+ /*
42637+ * Do all operations here:
42638+ * copy IV->ESP, encrypt, update ips IV
42639+ *
42640+ */
42641+ {
42642+ int ret;
42643+ memcpy(espp->esp_iv,
42644+ ixs->ipsp->ips_iv,
42645+ ixs->ipsp->ips_iv_size);
42646+ ret=ipsec_alg_esp_encrypt(ixs->ipsp,
42647+ idat, ilen, espp->esp_iv,
42648+ IPSEC_ALG_ENCRYPT);
42649+
42650+ prng_bytes(&ipsec_prng,
42651+ (char *)ixs->ipsp->ips_iv,
42652+ ixs->ipsp->ips_iv_size);
42653+ }
42654+
42655+ if (ixt_a) {
42656+ ipsec_alg_sa_esp_hash(ixs->ipsp,
42657+ (caddr_t)espp, len - ixs->iphlen - authlen,
42658+ &(dat[len - authlen]), authlen);
42659+
42660+ } else
42661+ switch(ixs->ipsp->ips_authalg) {
42662+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42663+ case AH_MD5:
42664+ dmp("espp", (char*)espp, len - ixs->iphlen - authlen);
42665+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42666+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
42667+ osMD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen);
42668+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
42669+ osMD5Final(hash, &tctx.md5);
42670+ dmp("ictx hash", (char*)&hash, sizeof(hash));
42671+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
42672+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
42673+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
42674+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
42675+ osMD5Final(hash, &tctx.md5);
42676+ dmp("octx hash", (char*)&hash, sizeof(hash));
42677+ memcpy(&(dat[len - authlen]), hash, authlen);
42678+
42679+ /* paranoid */
42680+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
42681+ memset((caddr_t)hash, 0, sizeof(*hash));
42682+ break;
42683+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42684+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42685+ case AH_SHA:
42686+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42687+ SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen);
42688+ SHA1Final(hash, &tctx.sha1);
42689+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
42690+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
42691+ SHA1Final(hash, &tctx.sha1);
42692+ memcpy(&(dat[len - authlen]), hash, authlen);
42693+
42694+ /* paranoid */
42695+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
42696+ memset((caddr_t)hash, 0, sizeof(*hash));
42697+ break;
42698+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42699+ case AH_NONE:
42700+ break;
42701+ default:
42702+ ixs->stats->tx_errors++;
42703+ return IPSEC_XMIT_AH_BADALG;
42704+ }
42705+#ifdef NET_21
42706+ ixs->skb->h.raw = (unsigned char*)espp;
42707+#endif /* NET_21 */
42708+ break;
42709+#endif /* !CONFIG_KLIPS_ESP */
42710+#ifdef CONFIG_KLIPS_AH
42711+ case IPPROTO_AH:
42712+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
42713+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
42714+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
42715+ ahp->ah_rv = 0;
42716+ ahp->ah_nh = ixs->iph->protocol;
42717+ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
42718+ ixs->iph->protocol = IPPROTO_AH;
42719+ dmp("ahp", (char*)ahp, sizeof(*ahp));
42720+
42721+ ipo = *ixs->iph;
42722+ ipo.tos = 0;
42723+ ipo.frag_off = 0;
42724+ ipo.ttl = 0;
42725+ ipo.check = 0;
42726+ dmp("ipo", (char*)&ipo, sizeof(ipo));
42727+
42728+ switch(ixs->ipsp->ips_authalg) {
42729+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42730+ case AH_MD5:
42731+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42732+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
42733+ osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
42734+ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
42735+ osMD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
42736+ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
42737+ osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
42738+ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
42739+ osMD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
42740+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
42741+ osMD5Final(hash, &tctx.md5);
42742+ dmp("ictx hash", (char*)&hash, sizeof(hash));
42743+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
42744+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
42745+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
42746+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
42747+ osMD5Final(hash, &tctx.md5);
42748+ dmp("octx hash", (char*)&hash, sizeof(hash));
42749+
42750+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
42751+
42752+ /* paranoid */
42753+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
42754+ memset((caddr_t)hash, 0, sizeof(*hash));
42755+ break;
42756+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42757+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42758+ case AH_SHA:
42759+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42760+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
42761+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
42762+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
42763+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
42764+ SHA1Final(hash, &tctx.sha1);
42765+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
42766+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
42767+ SHA1Final(hash, &tctx.sha1);
42768+
42769+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
42770+
42771+ /* paranoid */
42772+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
42773+ memset((caddr_t)hash, 0, sizeof(*hash));
42774+ break;
42775+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42776+ default:
42777+ ixs->stats->tx_errors++;
42778+ return IPSEC_XMIT_AH_BADALG;
42779+ }
42780+#ifdef NET_21
42781+ ixs->skb->h.raw = (unsigned char*)ahp;
42782+#endif /* NET_21 */
42783+ break;
42784+#endif /* CONFIG_KLIPS_AH */
42785+#ifdef CONFIG_KLIPS_IPIP
42786+ case IPPROTO_IPIP:
42787+ ixs->iph->version = 4;
42788+ switch(sysctl_ipsec_tos) {
42789+ case 0:
42790+#ifdef NET_21
42791+ ixs->iph->tos = ixs->skb->nh.iph->tos;
42792+#else /* NET_21 */
42793+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
42794+#endif /* NET_21 */
42795+ break;
42796+ case 1:
42797+ ixs->iph->tos = 0;
42798+ break;
42799+ default:
42800+ break;
42801+ }
42802+ ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
42803+ ixs->iph->frag_off = 0;
42804+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
42805+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
42806+ ixs->iph->protocol = IPPROTO_IPIP;
42807+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
42808+
42809+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
42810+
42811+ ixs->newdst = (__u32)ixs->iph->daddr;
42812+ ixs->newsrc = (__u32)ixs->iph->saddr;
42813+
42814+#ifdef NET_21
42815+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
42816+#endif /* NET_21 */
42817+ break;
42818+#endif /* !CONFIG_KLIPS_IPIP */
42819+#ifdef CONFIG_KLIPS_IPCOMP
42820+ case IPPROTO_COMP:
42821+ {
42822+ unsigned int flags = 0;
42823+#ifdef CONFIG_KLIPS_DEBUG
42824+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
42825+#endif /* CONFIG_KLIPS_DEBUG */
42826+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
42827+
42828+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
42829+
42830+#ifdef NET_21
42831+ ixs->iph = ixs->skb->nh.iph;
42832+#else /* NET_21 */
42833+ ixs->iph = ixs->skb->ip_hdr;
42834+#endif /* NET_21 */
42835+
42836+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
42837+
42838+#ifdef CONFIG_KLIPS_DEBUG
42839+ if (debug_tunnel & DB_TN_CROUT)
42840+ {
42841+ if (old_tot_len > ntohs(ixs->iph->tot_len))
42842+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42843+ "klips_debug:ipsec_xmit_encap_once: "
42844+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
42845+ old_tot_len, ntohs(ixs->iph->tot_len),
42846+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
42847+ ntohl(ixs->ipsp->ips_said.spi),
42848+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
42849+ else
42850+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42851+ "klips_debug:ipsec_xmit_encap_once: "
42852+ "packet did not compress (flags = %d).\n",
42853+ flags);
42854+ }
42855+#endif /* CONFIG_KLIPS_DEBUG */
42856+ }
42857+ break;
42858+#endif /* CONFIG_KLIPS_IPCOMP */
42859+ default:
42860+ ixs->stats->tx_errors++;
42861+ return IPSEC_XMIT_BADPROTO;
42862+ }
42863+
42864+#ifdef NET_21
42865+ ixs->skb->nh.raw = ixs->skb->data;
42866+#else /* NET_21 */
42867+ ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data;
42868+#endif /* NET_21 */
42869+ ixs->iph->check = 0;
42870+ ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl);
42871+
42872+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42873+ "klips_debug:ipsec_xmit_encap_once: "
42874+ "after <%s%s%s>, SA:%s:\n",
42875+ IPS_XFORM_NAME(ixs->ipsp),
42876+ ixs->sa_len ? ixs->sa_txt : " (error)");
42877+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
42878+
42879+ ixs->ipsp->ips_life.ipl_bytes.ipl_count += len;
42880+ ixs->ipsp->ips_life.ipl_bytes.ipl_last = len;
42881+
42882+ if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) {
42883+ ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
42884+ }
42885+ ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
42886+ ixs->ipsp->ips_life.ipl_packets.ipl_count++;
42887+
42888+ ixs->ipsp = ixs->ipsp->ips_onext;
42889+
42890+ return IPSEC_XMIT_OK;
42891+}
42892+
42893+/*
42894+ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
42895+ * source and destination ports to those from the TCP/UDP header.
42896+ */
42897+void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
42898+{
42899+ struct udphdr *udp;
42900+
42901+ switch (iph->protocol) {
42902+ case IPPROTO_UDP:
42903+ case IPPROTO_TCP:
42904+ /*
42905+ * The ports are at the same offsets in a TCP and UDP
42906+ * header so hack it ...
42907+ */
42908+ udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
42909+ er->sen_sport = udp->source;
42910+ er->sen_dport = udp->dest;
42911+ break;
42912+ default:
42913+ er->sen_sport = 0;
42914+ er->sen_dport = 0;
42915+ break;
42916+ }
42917+}
42918+
42919+/*
42920+ * A TRAP eroute is installed and we want to replace it with a HOLD
42921+ * eroute.
42922+ */
42923+static int create_hold_eroute(struct eroute *origtrap,
42924+ struct sk_buff * skb, struct iphdr * iph,
42925+ uint32_t eroute_pid)
42926+{
42927+ struct eroute hold_eroute;
42928+ ip_said hold_said;
42929+ struct sk_buff *first, *last;
42930+ int error;
42931+
42932+ first = last = NULL;
42933+ memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
42934+ memset((caddr_t)&hold_said, 0, sizeof(hold_said));
42935+
42936+ hold_said.proto = IPPROTO_INT;
42937+ hold_said.spi = htonl(SPI_HOLD);
42938+ hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
42939+
42940+ hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
42941+ hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
42942+ hold_eroute.er_eaddr.sen_family = AF_ENCAP;
42943+ hold_eroute.er_emask.sen_family = AF_ENCAP;
42944+ hold_eroute.er_eaddr.sen_type = SENT_IP4;
42945+ hold_eroute.er_emask.sen_type = 255;
42946+
42947+ hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
42948+ hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
42949+ hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
42950+ hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
42951+ hold_eroute.er_emask.sen_sport = 0;
42952+ hold_eroute.er_emask.sen_dport = 0;
42953+ hold_eroute.er_pid = eroute_pid;
42954+ hold_eroute.er_count = 0;
42955+ hold_eroute.er_lasttime = jiffies/HZ;
42956+
42957+ /*
42958+ * if it wasn't captured by a wildcard, then don't record it as
42959+ * a wildcard.
42960+ */
42961+ if(origtrap->er_eaddr.sen_proto != 0) {
42962+ hold_eroute.er_eaddr.sen_proto = iph->protocol;
42963+
42964+ if((iph->protocol == IPPROTO_TCP ||
42965+ iph->protocol == IPPROTO_UDP) &&
42966+ (origtrap->er_eaddr.sen_sport != 0 ||
42967+ origtrap->er_eaddr.sen_dport != 0)) {
42968+
42969+ if(origtrap->er_eaddr.sen_sport != 0)
42970+ hold_eroute.er_emask.sen_sport = ~0;
42971+
42972+ if(origtrap->er_eaddr.sen_dport != 0)
42973+ hold_eroute.er_emask.sen_dport = ~0;
42974+
42975+ ipsec_extract_ports(iph, &hold_eroute.er_eaddr);
42976+ }
42977+ }
42978+
42979+#ifdef CONFIG_KLIPS_DEBUG
42980+ if (debug_pfkey) {
42981+ char buf1[64], buf2[64];
42982+ subnettoa(hold_eroute.er_eaddr.sen_ip_src,
42983+ hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
42984+ subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
42985+ hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
42986+ KLIPS_PRINT(debug_pfkey,
42987+ "klips_debug:ipsec_tunnel_start_xmit: "
42988+ "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
42989+ buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
42990+ buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
42991+ hold_eroute.er_eaddr.sen_proto);
42992+ }
42993+#endif /* CONFIG_KLIPS_DEBUG */
42994+
42995+ if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
42996+ &first, &last)) {
42997+ KLIPS_PRINT(debug_pfkey,
42998+ "klips_debug:ipsec_tunnel_start_xmit: "
42999+ "HOLD breakeroute found nothing.\n");
43000+ } else {
43001+ KLIPS_PRINT(debug_pfkey,
43002+ "klips_debug:ipsec_tunnel_start_xmit: "
43003+ "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
43004+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
43005+ ntohs(hold_eroute.er_eaddr.sen_sport),
43006+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
43007+ ntohs(hold_eroute.er_eaddr.sen_dport),
43008+ hold_eroute.er_eaddr.sen_proto);
43009+ }
43010+ if (first != NULL)
43011+ kfree_skb(first);
43012+ if (last != NULL)
43013+ kfree_skb(last);
43014+
43015+ error = ipsec_makeroute(&(hold_eroute.er_eaddr),
43016+ &(hold_eroute.er_emask),
43017+ hold_said, eroute_pid, skb, NULL, NULL);
43018+ if (error) {
43019+ KLIPS_PRINT(debug_pfkey,
43020+ "klips_debug:ipsec_tunnel_start_xmit: "
43021+ "HOLD makeroute returned %d, failed.\n", error);
43022+ } else {
43023+ KLIPS_PRINT(debug_pfkey,
43024+ "klips_debug:ipsec_tunnel_start_xmit: "
43025+ "HOLD makeroute call successful.\n");
43026+ }
43027+ return (error == 0);
43028+}
43029+
43030+/*
43031+ * upon entry to this function, ixs->skb should be setup
43032+ * as follows:
43033+ *
43034+ * data = beginning of IP packet <- differs from ipsec_rcv().
43035+ * nh.raw = beginning of IP packet.
43036+ * h.raw = data after the IP packet.
43037+ *
43038+ */
43039+enum ipsec_xmit_value
43040+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs)
43041+{
43042+ struct ipsec_alg_enc *ixt_e = NULL;
43043+ struct ipsec_alg_auth *ixt_a = NULL;
43044+ int blocksize = 8;
43045+ enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK;
43046+
43047+ ixs->newdst = ixs->orgdst = ixs->iph->daddr;
43048+ ixs->newsrc = ixs->orgsrc = ixs->iph->saddr;
43049+ ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr;
43050+ ixs->iphlen = ixs->iph->ihl << 2;
43051+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
43052+ ixs->max_headroom = ixs->max_tailroom = 0;
43053+
43054+ if (ixs->outgoing_said.proto == IPPROTO_INT) {
43055+ switch (ntohl(ixs->outgoing_said.spi)) {
43056+ case SPI_DROP:
43057+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43058+ "klips_debug:ipsec_xmit_encap_bundle: "
43059+ "shunt SA of DROP or no eroute: dropping.\n");
43060+ ixs->stats->tx_dropped++;
43061+ break;
43062+
43063+ case SPI_REJECT:
43064+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43065+ "klips_debug:ipsec_xmit_encap_bundle: "
43066+ "shunt SA of REJECT: notifying and dropping.\n");
43067+ ICMP_SEND(ixs->skb,
43068+ ICMP_DEST_UNREACH,
43069+ ICMP_PKT_FILTERED,
43070+ 0,
43071+ ixs->physdev);
43072+ ixs->stats->tx_dropped++;
43073+ break;
43074+
43075+ case SPI_PASS:
43076+#ifdef NET_21
43077+ ixs->pass = 1;
43078+#endif /* NET_21 */
43079+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43080+ "klips_debug:ipsec_xmit_encap_bundle: "
43081+ "PASS: calling dev_queue_xmit\n");
43082+ return IPSEC_XMIT_PASS;
43083+ goto cleanup;
43084+
43085+ case SPI_HOLD:
43086+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43087+ "klips_debug:ipsec_xmit_encap_bundle: "
43088+ "shunt SA of HOLD: this does not make sense here, dropping.\n");
43089+ ixs->stats->tx_dropped++;
43090+ break;
43091+
43092+ case SPI_TRAP:
43093+ case SPI_TRAPSUBNET:
43094+ {
43095+ struct sockaddr_in src, dst;
43096+#ifdef CONFIG_KLIPS_DEBUG
43097+ char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
43098+#endif /* CONFIG_KLIPS_DEBUG */
43099+
43100+ /* Signal all listening KMds with a PF_KEY ACQUIRE */
43101+
43102+ memset(&src, 0, sizeof(src));
43103+ memset(&dst, 0, sizeof(dst));
43104+ src.sin_family = AF_INET;
43105+ dst.sin_family = AF_INET;
43106+ src.sin_addr.s_addr = ixs->iph->saddr;
43107+ dst.sin_addr.s_addr = ixs->iph->daddr;
43108+
43109+ ixs->ips.ips_transport_protocol = 0;
43110+ src.sin_port = 0;
43111+ dst.sin_port = 0;
43112+
43113+ if(ixs->eroute->er_eaddr.sen_proto != 0) {
43114+ ixs->ips.ips_transport_protocol = ixs->iph->protocol;
43115+
43116+ if(ixs->eroute->er_eaddr.sen_sport != 0) {
43117+ src.sin_port =
43118+ (ixs->iph->protocol == IPPROTO_UDP
43119+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source
43120+ : (ixs->iph->protocol == IPPROTO_TCP
43121+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source
43122+ : 0));
43123+ }
43124+ if(ixs->eroute->er_eaddr.sen_dport != 0) {
43125+ dst.sin_port =
43126+ (ixs->iph->protocol == IPPROTO_UDP
43127+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest
43128+ : (ixs->iph->protocol == IPPROTO_TCP
43129+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest
43130+ : 0));
43131+ }
43132+ }
43133+
43134+ ixs->ips.ips_addr_s = (struct sockaddr*)(&src);
43135+ ixs->ips.ips_addr_d = (struct sockaddr*)(&dst);
43136+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43137+ "klips_debug:ipsec_xmit_encap_bundle: "
43138+ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
43139+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
43140+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port),
43141+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
43142+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port),
43143+ ixs->ips.ips_said.proto);
43144+
43145+ /* increment count of total traps needed */
43146+ ipsec_xmit_trap_count++;
43147+
43148+ if (pfkey_acquire(&ixs->ips) == 0) {
43149+
43150+ /* note that we succeeded */
43151+ ipsec_xmit_trap_sendcount++;
43152+
43153+ if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
43154+ /*
43155+ * The spinlock is to prevent any other
43156+ * process from accessing or deleting
43157+ * the eroute while we are using and
43158+ * updating it.
43159+ */
43160+ spin_lock(&eroute_lock);
43161+ ixs->eroute = ipsec_findroute(&ixs->matcher);
43162+ if(ixs->eroute) {
43163+ ixs->eroute->er_said.spi = htonl(SPI_HOLD);
43164+ ixs->eroute->er_first = ixs->skb;
43165+ ixs->skb = NULL;
43166+ }
43167+ spin_unlock(&eroute_lock);
43168+ } else if (create_hold_eroute(ixs->eroute,
43169+ ixs->skb,
43170+ ixs->iph,
43171+ ixs->eroute_pid)) {
43172+ ixs->skb = NULL;
43173+ }
43174+ /* whether or not the above succeeded, we continue */
43175+
43176+ }
43177+ ixs->stats->tx_dropped++;
43178+ }
43179+ default:
43180+ /* XXX what do we do with an unknown shunt spi? */
43181+ break;
43182+ } /* switch (ntohl(ixs->outgoing_said.spi)) */
43183+ return IPSEC_XMIT_STOLEN;
43184+ } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */
43185+
43186+ /*
43187+ The spinlock is to prevent any other process from
43188+ accessing or deleting the ipsec_sa hash table or any of the
43189+ ipsec_sa s while we are using and updating them.
43190+
43191+ This is not optimal, but was relatively straightforward
43192+ at the time. A better way to do it has been planned for
43193+ more than a year, to lock the hash table and put reference
43194+ counts on each ipsec_sa instead. This is not likely to happen
43195+ in KLIPS1 unless a volunteer contributes it, but will be
43196+ designed into KLIPS2.
43197+ */
43198+ spin_lock(&tdb_lock);
43199+
43200+ ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said);
43201+ ixs->sa_len = satot(&ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
43202+
43203+ if (ixs->ipsp == NULL) {
43204+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43205+ "klips_debug:ipsec_xmit_encap_bundle: "
43206+ "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
43207+ ixs->sa_len ? ixs->sa_txt : " (error)");
43208+ if(ixs->stats) {
43209+ ixs->stats->tx_dropped++;
43210+ }
43211+ bundle_stat = IPSEC_XMIT_SAIDNOTFOUND;
43212+ goto cleanup;
43213+ }
43214+
43215+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43216+ "klips_debug:ipsec_xmit_encap_bundle: "
43217+ "found ipsec_sa -- SA:<%s%s%s> %s\n",
43218+ IPS_XFORM_NAME(ixs->ipsp),
43219+ ixs->sa_len ? ixs->sa_txt : " (error)");
43220+
43221+ /*
43222+ * How much headroom do we need to be able to apply
43223+ * all the grouped transforms?
43224+ */
43225+ ixs->ipsq = ixs->ipsp; /* save the head of the ipsec_sa chain */
43226+ while (ixs->ipsp) {
43227+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
43228+ if(ixs->sa_len == 0) {
43229+ strcpy(ixs->sa_txt, "(error)");
43230+ }
43231+
43232+ /* If it is in larval state, drop the packet, we cannot process yet. */
43233+ if(ixs->ipsp->ips_state == SADB_SASTATE_LARVAL) {
43234+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43235+ "klips_debug:ipsec_xmit_encap_bundle: "
43236+ "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
43237+ IPS_XFORM_NAME(ixs->ipsp),
43238+ ixs->sa_len ? ixs->sa_txt : " (error)");
43239+ if(ixs->stats) {
43240+ ixs->stats->tx_errors++;
43241+ }
43242+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
43243+ goto cleanup;
43244+ }
43245+
43246+ if(ixs->ipsp->ips_state == SADB_SASTATE_DEAD) {
43247+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43248+ "klips_debug:ipsec_xmit_encap_bundle: "
43249+ "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
43250+ IPS_XFORM_NAME(ixs->ipsp),
43251+ ixs->sa_len ? ixs->sa_txt : " (error)");
43252+ ixs->stats->tx_errors++;
43253+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
43254+ goto cleanup;
43255+ }
43256+
43257+ /* If the replay window counter == -1, expire SA, it will roll */
43258+ if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) {
43259+ pfkey_expire(ixs->ipsp, 1);
43260+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43261+ "klips_debug:ipsec_xmit_encap_bundle: "
43262+ "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
43263+ IPS_XFORM_NAME(ixs->ipsp),
43264+ ixs->sa_len ? ixs->sa_txt : " (error)");
43265+ ipsec_sa_delchain(ixs->ipsp);
43266+ ixs->stats->tx_errors++;
43267+ bundle_stat = IPSEC_XMIT_REPLAYROLLED;
43268+ goto cleanup;
43269+ }
43270+
43271+ /*
43272+ * if this is the first time we are using this SA, mark start time,
43273+ * and offset hard/soft counters by "now" for later checking.
43274+ */
43275+#if 0
43276+ if(ixs->ipsp->ips_life.ipl_usetime.count == 0) {
43277+ ixs->ipsp->ips_life.ipl_usetime.count = jiffies;
43278+ ixs->ipsp->ips_life.ipl_usetime.hard += jiffies;
43279+ ixs->ipsp->ips_life.ipl_usetime.soft += jiffies;
43280+ }
43281+#endif
43282+
43283+
43284+ if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt,
43285+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43286+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt,
43287+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43288+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt,
43289+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43290+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt,
43291+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) {
43292+
43293+ ipsec_sa_delchain(ixs->ipsp);
43294+ ixs->stats->tx_errors++;
43295+ bundle_stat = IPSEC_XMIT_LIFETIMEFAILED;
43296+ goto cleanup;
43297+ }
43298+
43299+
43300+ ixs->headroom = ixs->tailroom = 0;
43301+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43302+ "klips_debug:ipsec_xmit_encap_bundle: "
43303+ "calling room for <%s%s%s>, SA:%s\n",
43304+ IPS_XFORM_NAME(ixs->ipsp),
43305+ ixs->sa_len ? ixs->sa_txt : " (error)");
43306+ switch(ixs->ipsp->ips_said.proto) {
43307+#ifdef CONFIG_KLIPS_AH
43308+ case IPPROTO_AH:
43309+ ixs->headroom += sizeof(struct ahhdr);
43310+ break;
43311+#endif /* CONFIG_KLIPS_AH */
43312+#ifdef CONFIG_KLIPS_ESP
43313+ case IPPROTO_ESP:
43314+ ixt_e=ixs->ipsp->ips_alg_enc;
43315+ if (ixt_e) {
43316+ blocksize = ixt_e->ixt_common.ixt_blocksize;
43317+ ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
43318+ }
43319+ else {
43320+ ixs->stats->tx_errors++;
43321+ bundle_stat = IPSEC_XMIT_ESP_BADALG;
43322+ goto cleanup;
43323+ }
43324+
43325+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
43326+ ixs->tailroom += AHHMAC_HASHLEN;
43327+ } else
43328+ switch(ixs->ipsp->ips_authalg) {
43329+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
43330+ case AH_MD5:
43331+ ixs->tailroom += AHHMAC_HASHLEN;
43332+ break;
43333+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
43334+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
43335+ case AH_SHA:
43336+ ixs->tailroom += AHHMAC_HASHLEN;
43337+ break;
43338+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
43339+ case AH_NONE:
43340+ break;
43341+ default:
43342+ ixs->stats->tx_errors++;
43343+ bundle_stat = IPSEC_XMIT_AH_BADALG;
43344+ goto cleanup;
43345+ }
43346+ ixs->tailroom += blocksize != 1 ?
43347+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
43348+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
43349+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
43350+ if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) {
43351+ ixs->natt_type = ixs->ipsp->ips_natt_type;
43352+ ixs->natt_sport = ixs->ipsp->ips_natt_sport;
43353+ ixs->natt_dport = ixs->ipsp->ips_natt_dport;
43354+ switch (ixs->natt_type) {
43355+ case ESPINUDP_WITH_NON_IKE:
43356+ ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32));
43357+ break;
43358+
43359+ case ESPINUDP_WITH_NON_ESP:
43360+ ixs->natt_head = sizeof(struct udphdr);
43361+ break;
43362+
43363+ default:
43364+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT
43365+ , "klips_xmit: invalid nat-t type %d"
43366+ , ixs->natt_type);
43367+ bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;
43368+ goto cleanup;
43369+
43370+ break;
43371+ }
43372+ ixs->tailroom += ixs->natt_head;
43373+ }
43374+#endif
43375+ break;
43376+#endif /* !CONFIG_KLIPS_ESP */
43377+#ifdef CONFIG_KLIPS_IPIP
43378+ case IPPROTO_IPIP:
43379+ ixs->headroom += sizeof(struct iphdr);
43380+ break;
43381+#endif /* !CONFIG_KLIPS_IPIP */
43382+ case IPPROTO_COMP:
43383+#ifdef CONFIG_KLIPS_IPCOMP
43384+ /*
43385+ We can't predict how much the packet will
43386+ shrink without doing the actual compression.
43387+ We could do it here, if we were the first
43388+ encapsulation in the chain. That might save
43389+ us a skb_copy_expand, since we might fit
43390+ into the existing skb then. However, this
43391+ would be a bit unclean (and this hack has
43392+ bit us once), so we better not do it. After
43393+ all, the skb_copy_expand is cheap in
43394+ comparison to the actual compression.
43395+ At least we know the packet will not grow.
43396+ */
43397+ break;
43398+#endif /* CONFIG_KLIPS_IPCOMP */
43399+ default:
43400+ ixs->stats->tx_errors++;
43401+ bundle_stat = IPSEC_XMIT_BADPROTO;
43402+ goto cleanup;
43403+ }
43404+ ixs->ipsp = ixs->ipsp->ips_onext;
43405+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43406+ "klips_debug:ipsec_xmit_encap_bundle: "
43407+ "Required head,tailroom: %d,%d\n",
43408+ ixs->headroom, ixs->tailroom);
43409+ ixs->max_headroom += ixs->headroom;
43410+ ixs->max_tailroom += ixs->tailroom;
43411+ ixs->pyldsz += (ixs->headroom + ixs->tailroom);
43412+ }
43413+ ixs->ipsp = ixs->ipsq; /* restore the head of the ipsec_sa chain */
43414+
43415+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43416+ "klips_debug:ipsec_xmit_encap_bundle: "
43417+ "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
43418+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb),
43419+ ixs->max_headroom, ixs->max_tailroom);
43420+
43421+ ixs->tot_headroom += ixs->max_headroom;
43422+ ixs->tot_tailroom += ixs->max_tailroom;
43423+
43424+ ixs->mtudiff = ixs->cur_mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;
43425+
43426+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43427+ "klips_debug:ipsec_xmit_encap_bundle: "
43428+ "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
43429+ ixs->cur_mtu, ixs->physmtu,
43430+ ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));
43431+ if(ixs->mtudiff > 0) {
43432+ int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);
43433+
43434+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43435+ "klips_info:ipsec_xmit_encap_bundle: "
43436+ "dev %s mtu of %d decreased by %d to %d\n",
43437+ ixs->dev ? ixs->dev->name : "ifX",
43438+ ixs->cur_mtu,
43439+ ixs->cur_mtu - newmtu,
43440+ newmtu);
43441+ ixs->cur_mtu = newmtu;
43442+
43443+ /* this would seem to adjust the MTU of the route as well */
43444+#if 0
43445+ ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */
43446+#endif /* 0 */
43447+ }
43448+
43449+ /*
43450+ If the sender is doing PMTU discovery, and the
43451+ packet doesn't fit within ixs->prv->mtu, notify him
43452+ (unless it was an ICMP packet, or it was not the
43453+ zero-offset packet) and send it anyways.
43454+
43455+ Note: buggy firewall configuration may prevent the
43456+ ICMP packet from getting back.
43457+ */
43458+ if(sysctl_ipsec_icmp
43459+ && ixs->cur_mtu < ntohs(ixs->iph->tot_len)
43460+ && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {
43461+ int notify = ixs->iph->protocol != IPPROTO_ICMP
43462+ && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
43463+
43464+#ifdef IPSEC_obey_DF
43465+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43466+ "klips_debug:ipsec_xmit_encap_bundle: "
43467+ "fragmentation needed and DF set; %sdropping packet\n",
43468+ notify ? "sending ICMP and " : "");
43469+ if (notify)
43470+ ICMP_SEND(ixs->skb,
43471+ ICMP_DEST_UNREACH,
43472+ ICMP_FRAG_NEEDED,
43473+ ixs->cur_mtu,
43474+ ixs->physdev);
43475+ ixs->stats->tx_errors++;
43476+ bundle_stat = IPSEC_XMIT_CANNOTFRAG;
43477+ goto cleanup;
43478+#else /* IPSEC_obey_DF */
43479+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43480+ "klips_debug:ipsec_xmit_encap_bundle: "
43481+ "fragmentation needed and DF set; %spassing packet\n",
43482+ notify ? "sending ICMP and " : "");
43483+ if (notify)
43484+ ICMP_SEND(ixs->skb,
43485+ ICMP_DEST_UNREACH,
43486+ ICMP_FRAG_NEEDED,
43487+ ixs->cur_mtu,
43488+ ixs->physdev);
43489+#endif /* IPSEC_obey_DF */
43490+ }
43491+
43492+#ifdef MSS_HACK
43493+ /*
43494+ * If this is a transport mode TCP packet with
43495+ * SYN set, determine an effective MSS based on
43496+ * AH/ESP overheads determined above.
43497+ */
43498+ if (ixs->iph->protocol == IPPROTO_TCP
43499+ && ixs->outgoing_said.proto != IPPROTO_IPIP) {
43500+ struct tcphdr *tcph = ixs->skb->h.th;
43501+ if (tcph->syn && !tcph->ack) {
43502+ if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->cur_mtu)) {
43503+ printk(KERN_WARNING
43504+ "klips_warning:ipsec_xmit_encap_bundle: "
43505+ "ipsec_adjust_mss() failed\n");
43506+ ixs->stats->tx_errors++;
43507+ bundle_stat = IPSEC_XMIT_MSSERR;
43508+ goto cleanup;
43509+ }
43510+ }
43511+ }
43512+#endif /* MSS_HACK */
43513+
43514+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
43515+ if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {
43516+ /**
43517+ * NAT-Traversal and Transport Mode:
43518+ * we need to correct TCP/UDP checksum
43519+ *
43520+ * If we've got NAT-OA, we can fix checksum without recalculation.
43521+ * If we don't we can zero udp checksum.
43522+ */
43523+ __u32 natt_oa = ixs->ipsp->ips_natt_oa ?
43524+ ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
43525+ __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph;
43526+ __u16 data_len = pkt_len - (ixs->iph->ihl << 2);
43527+ switch (ixs->iph->protocol) {
43528+ case IPPROTO_TCP:
43529+ if (data_len >= sizeof(struct tcphdr)) {
43530+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
43531+ if (natt_oa) {
43532+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
43533+ KLIPS_PRINT(debug_tunnel,
43534+ "klips_debug:ipsec_tunnel_start_xmit: "
43535+ "NAT-T & TRANSPORT: "
43536+ "fix TCP checksum using NAT-OA\n");
43537+ tcp->check = csum_fold(
43538+ csum_partial((unsigned char *)buff, sizeof(buff),
43539+ tcp->check^0xffff));
43540+ }
43541+ else {
43542+ KLIPS_PRINT(debug_tunnel,
43543+ "klips_debug:ipsec_tunnel_start_xmit: "
43544+ "NAT-T & TRANSPORT: do not recalc TCP checksum\n");
43545+ }
43546+ }
43547+ else {
43548+ KLIPS_PRINT(debug_tunnel,
43549+ "klips_debug:ipsec_tunnel_start_xmit: "
43550+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
43551+ }
43552+ break;
43553+ case IPPROTO_UDP:
43554+ if (data_len >= sizeof(struct udphdr)) {
43555+ struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
43556+ if (udp->check == 0) {
43557+ KLIPS_PRINT(debug_tunnel,
43558+ "klips_debug:ipsec_tunnel_start_xmit: "
43559+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
43560+ }
43561+ else if (natt_oa) {
43562+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
43563+ KLIPS_PRINT(debug_tunnel,
43564+ "klips_debug:ipsec_tunnel_start_xmit: "
43565+ "NAT-T & TRANSPORT: "
43566+ "fix UDP checksum using NAT-OA\n");
43567+ udp->check = csum_fold(
43568+ csum_partial((unsigned char *)buff, sizeof(buff),
43569+ udp->check^0xffff));
43570+ }
43571+ else {
43572+ KLIPS_PRINT(debug_tunnel,
43573+ "klips_debug:ipsec_tunnel_start_xmit: "
43574+ "NAT-T & TRANSPORT: zero UDP checksum\n");
43575+ udp->check = 0;
43576+ }
43577+ }
43578+ else {
43579+ KLIPS_PRINT(debug_tunnel,
43580+ "klips_debug:ipsec_tunnel_start_xmit: "
43581+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
43582+ }
43583+ break;
43584+ default:
43585+ KLIPS_PRINT(debug_tunnel,
43586+ "klips_debug:ipsec_tunnel_start_xmit: "
43587+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
43588+ break;
43589+ }
43590+ }
43591+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
43592+
43593+ if(!ixs->hard_header_stripped && ixs->hard_header_len>0) {
43594+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43595+ "klips_debug:ipsec_xmit_encap_bundle: "
43596+ "allocating %d bytes for hardheader.\n",
43597+ ixs->hard_header_len);
43598+ if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {
43599+ printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: "
43600+ "Failed, tried to allocate %d bytes for temp hard_header.\n",
43601+ ixs->hard_header_len);
43602+ ixs->stats->tx_errors++;
43603+ bundle_stat = IPSEC_XMIT_ERRMEMALLOC;
43604+ goto cleanup;
43605+ }
43606+ {
43607+ int i;
43608+ for (i = 0; i < ixs->hard_header_len; i++) {
43609+ ixs->saved_header[i] = ixs->skb->data[i];
43610+ }
43611+ }
43612+ if(ixs->skb->len < ixs->hard_header_len) {
43613+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: "
43614+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
43615+ ixs->hard_header_len, (int)(ixs->skb->len));
43616+ ixs->stats->tx_errors++;
43617+ bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;
43618+ goto cleanup;
43619+ }
43620+ skb_pull(ixs->skb, ixs->hard_header_len);
43621+ ixs->hard_header_stripped = 1;
43622+
43623+/* ixs->iph = (struct iphdr *) (ixs->skb->data); */
43624+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43625+ "klips_debug:ipsec_xmit_encap_bundle: "
43626+ "head,tailroom: %d,%d after hard_header stripped.\n",
43627+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
43628+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);
43629+ } else {
43630+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43631+ "klips_debug:ipsec_xmit_encap_bundle: "
43632+ "hard header already stripped.\n");
43633+ }
43634+
43635+ ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;
43636+
43637+ if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) &&
43638+ (skb_tailroom(ixs->skb) >= ixs->max_tailroom)
43639+#ifndef NET_21
43640+ && ixs->skb->free
43641+#endif /* !NET_21 */
43642+ ) {
43643+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43644+ "klips_debug:ipsec_xmit_encap_bundle: "
43645+ "data fits in existing skb\n");
43646+ } else {
43647+ struct sk_buff* tskb;
43648+
43649+ if(!ixs->oskb) {
43650+ ixs->oskb = ixs->skb;
43651+ }
43652+
43653+ tskb = skb_copy_expand(ixs->skb,
43654+ /* The need for 2 * link layer length here remains unexplained...RGB */
43655+ ixs->max_headroom + 2 * ixs->ll_headroom,
43656+ ixs->max_tailroom,
43657+ GFP_ATOMIC);
43658+
43659+ if(tskb && ixs->skb->sk) {
43660+ skb_set_owner_w(tskb, ixs->skb->sk);
43661+ }
43662+
43663+ if(ixs->skb != ixs->oskb) {
43664+ ipsec_kfree_skb(ixs->skb);
43665+ }
43666+ ixs->skb = tskb;
43667+ if (!ixs->skb) {
43668+ printk(KERN_WARNING
43669+ "klips_debug:ipsec_xmit_encap_bundle: "
43670+ "Failed, tried to allocate %d head and %d tailroom\n",
43671+ ixs->max_headroom, ixs->max_tailroom);
43672+ ixs->stats->tx_errors++;
43673+ bundle_stat = IPSEC_XMIT_ERRSKBALLOC;
43674+ goto cleanup;
43675+ }
43676+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43677+ "klips_debug:ipsec_xmit_encap_bundle: "
43678+ "head,tailroom: %d,%d after allocation\n",
43679+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
43680+ }
43681+#ifdef CONFIG_KLIPS_DEBUG
43682+ if(debug_tunnel & DB_TN_ENCAP) {
43683+ ipsec_print_ip(ixs->iph);
43684+ }
43685+#endif
43686+
43687+ /*
43688+ * Apply grouped transforms to packet
43689+ */
43690+ while (ixs->ipsp) {
43691+ enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK;
43692+
43693+ encap_stat = ipsec_xmit_encap_once(ixs);
43694+#ifdef CONFIG_KLIPS_DEBUG
43695+ if(debug_tunnel & DB_TN_ENCAP) {
43696+ ipsec_print_ip(ixs->iph);
43697+ }
43698+#endif
43699+
43700+ if(encap_stat != IPSEC_XMIT_OK) {
43701+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43702+ "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n",
43703+ encap_stat);
43704+
43705+ bundle_stat = IPSEC_XMIT_ENCAPFAIL;
43706+ goto cleanup;
43707+ }
43708+ }
43709+
43710+ /* we are done with this SA */
43711+ ipsec_sa_put(ixs->ipsp);
43712+
43713+ /* end encapsulation loop here XXX */
43714+ cleanup:
43715+ spin_unlock(&tdb_lock);
43716+ return bundle_stat;
43717+}
43718+
43719+/*
43720+ * $Log: ipsec_xmit.c,v $
4b871415
MT
43721+ * Revision 1.20.2.9 2007/07/06 17:18:43 paul
43722+ * Fix for authentication field on sent packets has size equals to zero when
43723+ * using custom auth algorithms. This is bug #811. Patch by "iamscared".
43724+ *
b4f8d26c
MT
43725+ * Revision 1.20.2.8 2006/10/06 21:39:26 paul
43726+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
43727+ * set. This is defined through autoconf.h which is included through the
43728+ * linux kernel build macros.
43729+ *
43730+ * Revision 1.20.2.7 2006/08/24 03:02:01 paul
43731+ * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
43732+ *
43733+ * Revision 1.20.2.6 2006/07/07 22:09:49 paul
43734+ * From: Bart Trojanowski <bart@xelerance.com>
43735+ * Removing a left over '#else' that split another '#if/#endif' block in two.
43736+ *
43737+ * Revision 1.20.2.5 2006/07/07 15:43:17 paul
43738+ * From: Bart Trojanowski <bart@xelerance.com>
43739+ * improved protocol detection in ipsec_print_ip() -- a debug aid.
43740+ *
43741+ * Revision 1.20.2.4 2006/04/20 16:33:07 mcr
43742+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
43743+ * Fix in-kernel module compilation. Sub-makefiles do not work.
43744+ *
43745+ * Revision 1.20.2.3 2005/11/29 21:52:57 ken
43746+ * Fix for #518 MTU issues
43747+ *
43748+ * Revision 1.20.2.2 2005/11/27 21:41:03 paul
43749+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"in for klips as module.
43750+ *
43751+ * Revision 1.20.2.1 2005/08/27 23:40:00 paul
43752+ * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
43753+ *
43754+ * Revision 1.20 2005/07/12 15:39:27 paul
43755+ * include asm/uaccess.h for VERIFY_WRITE
43756+ *
43757+ * Revision 1.19 2005/05/24 01:02:35 mcr
43758+ * some refactoring/simplification of situation where alg
43759+ * is not found.
43760+ *
43761+ * Revision 1.18 2005/05/23 23:52:33 mcr
43762+ * adjust comments, add additional debugging.
43763+ *
43764+ * Revision 1.17 2005/05/23 22:57:23 mcr
43765+ * removed explicit 3DES support.
43766+ *
43767+ * Revision 1.16 2005/05/21 03:29:15 mcr
43768+ * fixed warning about unused zeroes if AH is off.
43769+ *
43770+ * Revision 1.15 2005/05/20 16:47:59 mcr
43771+ * include asm/checksum.h to get ip_fast_csum macro.
43772+ *
43773+ * Revision 1.14 2005/05/11 01:43:03 mcr
43774+ * removed "poor-man"s OOP in favour of proper C structures.
43775+ *
43776+ * Revision 1.13 2005/04/29 05:10:22 mcr
43777+ * removed from extraenous includes to make unit testing easier.
43778+ *
43779+ * Revision 1.12 2005/04/15 01:28:34 mcr
43780+ * use ipsec_dmp_block.
43781+ *
43782+ * Revision 1.11 2005/01/26 00:50:35 mcr
43783+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
43784+ * and make sure that NAT_TRAVERSAL is set as well to match
43785+ * userspace compiles of code.
43786+ *
43787+ * Revision 1.10 2004/09/13 17:55:21 ken
43788+ * MD5* -> osMD5*
43789+ *
43790+ * Revision 1.9 2004/07/10 19:11:18 mcr
43791+ * CONFIG_IPSEC -> CONFIG_KLIPS.
43792+ *
43793+ * Revision 1.8 2004/04/06 02:49:26 mcr
43794+ * pullup of algo code from alg-branch.
43795+ *
43796+ * Revision 1.7 2004/02/03 03:13:41 mcr
43797+ * mark invalid encapsulation states.
43798+ *
43799+ * Revision 1.6.2.1 2003/12/22 15:25:52 jjo
43800+ * Merged algo-0.8.1-rc11-test1 into alg-branch
43801+ *
43802+ * Revision 1.6 2003/12/10 01:14:27 mcr
43803+ * NAT-traversal patches to KLIPS.
43804+ *
43805+ * Revision 1.5 2003/10/31 02:27:55 mcr
43806+ * pulled up port-selector patches and sa_id elimination.
43807+ *
43808+ * Revision 1.4.4.2 2003/10/29 01:37:39 mcr
43809+ * when creating %hold from %trap, only make the %hold as
43810+ * specific as the %trap was - so if the protocol and ports
43811+ * were wildcards, then the %hold will be too.
43812+ *
43813+ * Revision 1.4.4.1 2003/09/21 13:59:56 mcr
43814+ * pre-liminary X.509 patch - does not yet pass tests.
43815+ *
43816+ * Revision 1.4 2003/06/20 02:28:10 mcr
43817+ * misstype of variable name, not detected by module build.
43818+ *
43819+ * Revision 1.3 2003/06/20 01:42:21 mcr
43820+ * added counters to measure how many ACQUIREs we send to pluto,
43821+ * and how many are successfully sent.
43822+ *
43823+ * Revision 1.2 2003/04/03 17:38:35 rgb
43824+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
43825+ * Normalised coding style.
43826+ * Simplified logic and reduced duplication of code.
43827+ *
43828+ * Revision 1.1 2003/02/12 19:31:23 rgb
43829+ * Refactored from ipsec_tunnel.c
43830+ *
43831+ * Local Variables:
43832+ * c-file-style: "linux"
43833+ * End:
43834+ *
43835+ */
43836--- /dev/null Tue Mar 11 13:02:56 2003
43837+++ linux/net/ipsec/match586.S Mon Feb 9 13:51:03 2004
43838@@ -0,0 +1,357 @@
43839+/* match.s -- Pentium-optimized version of longest_match()
43840+ * Written for zlib 1.1.2
43841+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
43842+ *
43843+ * This is free software; you can redistribute it and/or modify it
43844+ * under the terms of the GNU General Public License.
43845+ */
43846+
43847+#ifndef NO_UNDERLINE
43848+#define match_init _ipcomp_match_init
43849+#define longest_match _ipcomp_longest_match
43850+#else
43851+#define match_init ipcomp_match_init
43852+#define longest_match ipcomp_longest_match
43853+#endif
43854+
43855+#define MAX_MATCH (258)
43856+#define MIN_MATCH (3)
43857+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
43858+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
43859+
43860+/* stack frame offsets */
43861+
43862+#define wmask 0 /* local copy of s->wmask */
43863+#define window 4 /* local copy of s->window */
43864+#define windowbestlen 8 /* s->window + bestlen */
43865+#define chainlenscanend 12 /* high word: current chain len */
43866+ /* low word: last bytes sought */
43867+#define scanstart 16 /* first two bytes of string */
43868+#define scanalign 20 /* dword-misalignment of string */
43869+#define nicematch 24 /* a good enough match size */
43870+#define bestlen 28 /* size of best match so far */
43871+#define scan 32 /* ptr to string wanting match */
43872+
43873+#define LocalVarsSize (36)
43874+/* saved ebx 36 */
43875+/* saved edi 40 */
43876+/* saved esi 44 */
43877+/* saved ebp 48 */
43878+/* return address 52 */
43879+#define deflatestate 56 /* the function arguments */
43880+#define curmatch 60
43881+
43882+/* Offsets for fields in the deflate_state structure. These numbers
43883+ * are calculated from the definition of deflate_state, with the
43884+ * assumption that the compiler will dword-align the fields. (Thus,
43885+ * changing the definition of deflate_state could easily cause this
43886+ * program to crash horribly, without so much as a warning at
43887+ * compile time. Sigh.)
43888+ */
43889+#define dsWSize 36
43890+#define dsWMask 44
43891+#define dsWindow 48
43892+#define dsPrev 56
43893+#define dsMatchLen 88
43894+#define dsPrevMatch 92
43895+#define dsStrStart 100
43896+#define dsMatchStart 104
43897+#define dsLookahead 108
43898+#define dsPrevLen 112
43899+#define dsMaxChainLen 116
43900+#define dsGoodMatch 132
43901+#define dsNiceMatch 136
43902+
43903+
43904+.file "match.S"
43905+
43906+.globl match_init, longest_match
43907+
43908+.text
43909+
43910+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
43911+
43912+longest_match:
43913+
43914+/* Save registers that the compiler may be using, and adjust %esp to */
43915+/* make room for our stack frame. */
43916+
43917+ pushl %ebp
43918+ pushl %edi
43919+ pushl %esi
43920+ pushl %ebx
43921+ subl $LocalVarsSize, %esp
43922+
43923+/* Retrieve the function arguments. %ecx will hold cur_match */
43924+/* throughout the entire function. %edx will hold the pointer to the */
43925+/* deflate_state structure during the function's setup (before */
43926+/* entering the main loop). */
43927+
43928+ movl deflatestate(%esp), %edx
43929+ movl curmatch(%esp), %ecx
43930+
43931+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
43932+
43933+ movl dsNiceMatch(%edx), %eax
43934+ movl dsLookahead(%edx), %ebx
43935+ cmpl %eax, %ebx
43936+ jl LookaheadLess
43937+ movl %eax, %ebx
43938+LookaheadLess: movl %ebx, nicematch(%esp)
43939+
43940+/* register Bytef *scan = s->window + s->strstart; */
43941+
43942+ movl dsWindow(%edx), %esi
43943+ movl %esi, window(%esp)
43944+ movl dsStrStart(%edx), %ebp
43945+ lea (%esi,%ebp), %edi
43946+ movl %edi, scan(%esp)
43947+
43948+/* Determine how many bytes the scan ptr is off from being */
43949+/* dword-aligned. */
43950+
43951+ movl %edi, %eax
43952+ negl %eax
43953+ andl $3, %eax
43954+ movl %eax, scanalign(%esp)
43955+
43956+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
43957+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
43958+
43959+ movl dsWSize(%edx), %eax
43960+ subl $MIN_LOOKAHEAD, %eax
43961+ subl %eax, %ebp
43962+ jg LimitPositive
43963+ xorl %ebp, %ebp
43964+LimitPositive:
43965+
43966+/* unsigned chain_length = s->max_chain_length; */
43967+/* if (s->prev_length >= s->good_match) { */
43968+/* chain_length >>= 2; */
43969+/* } */
43970+
43971+ movl dsPrevLen(%edx), %eax
43972+ movl dsGoodMatch(%edx), %ebx
43973+ cmpl %ebx, %eax
43974+ movl dsMaxChainLen(%edx), %ebx
43975+ jl LastMatchGood
43976+ shrl $2, %ebx
43977+LastMatchGood:
43978+
43979+/* chainlen is decremented once beforehand so that the function can */
43980+/* use the sign flag instead of the zero flag for the exit test. */
43981+/* It is then shifted into the high word, to make room for the scanend */
43982+/* scanend value, which it will always accompany. */
43983+
43984+ decl %ebx
43985+ shll $16, %ebx
43986+
43987+/* int best_len = s->prev_length; */
43988+
43989+ movl dsPrevLen(%edx), %eax
43990+ movl %eax, bestlen(%esp)
43991+
43992+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
43993+
43994+ addl %eax, %esi
43995+ movl %esi, windowbestlen(%esp)
43996+
43997+/* register ush scan_start = *(ushf*)scan; */
43998+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
43999+
44000+ movw (%edi), %bx
44001+ movw %bx, scanstart(%esp)
44002+ movw -1(%edi,%eax), %bx
44003+ movl %ebx, chainlenscanend(%esp)
44004+
44005+/* Posf *prev = s->prev; */
44006+/* uInt wmask = s->w_mask; */
44007+
44008+ movl dsPrev(%edx), %edi
44009+ movl dsWMask(%edx), %edx
44010+ mov %edx, wmask(%esp)
44011+
44012+/* Jump into the main loop. */
44013+
44014+ jmp LoopEntry
44015+
44016+.balign 16
44017+
44018+/* do {
44019+ * match = s->window + cur_match;
44020+ * if (*(ushf*)(match+best_len-1) != scan_end ||
44021+ * *(ushf*)match != scan_start) continue;
44022+ * [...]
44023+ * } while ((cur_match = prev[cur_match & wmask]) > limit
44024+ * && --chain_length != 0);
44025+ *
44026+ * Here is the inner loop of the function. The function will spend the
44027+ * majority of its time in this loop, and majority of that time will
44028+ * be spent in the first ten instructions.
44029+ *
44030+ * Within this loop:
44031+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
44032+ * %ecx = curmatch
44033+ * %edx = curmatch & wmask
44034+ * %esi = windowbestlen - i.e., (window + bestlen)
44035+ * %edi = prev
44036+ * %ebp = limit
44037+ *
44038+ * Two optimization notes on the choice of instructions:
44039+ *
44040+ * The first instruction uses a 16-bit address, which costs an extra,
44041+ * unpairable cycle. This is cheaper than doing a 32-bit access and
44042+ * zeroing the high word, due to the 3-cycle misalignment penalty which
44043+ * would occur half the time. This also turns out to be cheaper than
44044+ * doing two separate 8-bit accesses, as the memory is so rarely in the
44045+ * L1 cache.
44046+ *
44047+ * The window buffer, however, apparently spends a lot of time in the
44048+ * cache, and so it is faster to retrieve the word at the end of the
44049+ * match string with two 8-bit loads. The instructions that test the
44050+ * word at the beginning of the match string, however, are executed
44051+ * much less frequently, and there it was cheaper to use 16-bit
44052+ * instructions, which avoided the necessity of saving off and
44053+ * subsequently reloading one of the other registers.
44054+ */
44055+LookupLoop:
44056+ /* 1 U & V */
44057+ movw (%edi,%edx,2), %cx /* 2 U pipe */
44058+ movl wmask(%esp), %edx /* 2 V pipe */
44059+ cmpl %ebp, %ecx /* 3 U pipe */
44060+ jbe LeaveNow /* 3 V pipe */
44061+ subl $0x00010000, %ebx /* 4 U pipe */
44062+ js LeaveNow /* 4 V pipe */
44063+LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
44064+ andl %ecx, %edx /* 5 V pipe */
44065+ cmpb %bl, %al /* 6 U pipe */
44066+ jnz LookupLoop /* 6 V pipe */
44067+ movb (%esi,%ecx), %ah
44068+ cmpb %bh, %ah
44069+ jnz LookupLoop
44070+ movl window(%esp), %eax
44071+ movw (%eax,%ecx), %ax
44072+ cmpw scanstart(%esp), %ax
44073+ jnz LookupLoop
44074+
44075+/* Store the current value of chainlen. */
44076+
44077+ movl %ebx, chainlenscanend(%esp)
44078+
44079+/* Point %edi to the string under scrutiny, and %esi to the string we */
44080+/* are hoping to match it up with. In actuality, %esi and %edi are */
44081+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
44082+/* initialized to -(MAX_MATCH_8 - scanalign). */
44083+
44084+ movl window(%esp), %esi
44085+ movl scan(%esp), %edi
44086+ addl %ecx, %esi
44087+ movl scanalign(%esp), %eax
44088+ movl $(-MAX_MATCH_8), %edx
44089+ lea MAX_MATCH_8(%edi,%eax), %edi
44090+ lea MAX_MATCH_8(%esi,%eax), %esi
44091+
44092+/* Test the strings for equality, 8 bytes at a time. At the end,
44093+ * adjust %edx so that it is offset to the exact byte that mismatched.
44094+ *
44095+ * We already know at this point that the first three bytes of the
44096+ * strings match each other, and they can be safely passed over before
44097+ * starting the compare loop. So what this code does is skip over 0-3
44098+ * bytes, as much as necessary in order to dword-align the %edi
44099+ * pointer. (%esi will still be misaligned three times out of four.)
44100+ *
44101+ * It should be confessed that this loop usually does not represent
44102+ * much of the total running time. Replacing it with a more
44103+ * straightforward "rep cmpsb" would not drastically degrade
44104+ * performance.
44105+ */
44106+LoopCmps:
44107+ movl (%esi,%edx), %eax
44108+ movl (%edi,%edx), %ebx
44109+ xorl %ebx, %eax
44110+ jnz LeaveLoopCmps
44111+ movl 4(%esi,%edx), %eax
44112+ movl 4(%edi,%edx), %ebx
44113+ xorl %ebx, %eax
44114+ jnz LeaveLoopCmps4
44115+ addl $8, %edx
44116+ jnz LoopCmps
44117+ jmp LenMaximum
44118+LeaveLoopCmps4: addl $4, %edx
44119+LeaveLoopCmps: testl $0x0000FFFF, %eax
44120+ jnz LenLower
44121+ addl $2, %edx
44122+ shrl $16, %eax
44123+LenLower: subb $1, %al
44124+ adcl $0, %edx
44125+
44126+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
44127+/* then automatically accept it as the best possible match and leave. */
44128+
44129+ lea (%edi,%edx), %eax
44130+ movl scan(%esp), %edi
44131+ subl %edi, %eax
44132+ cmpl $MAX_MATCH, %eax
44133+ jge LenMaximum
44134+
44135+/* If the length of the match is not longer than the best match we */
44136+/* have so far, then forget it and return to the lookup loop. */
44137+
44138+ movl deflatestate(%esp), %edx
44139+ movl bestlen(%esp), %ebx
44140+ cmpl %ebx, %eax
44141+ jg LongerMatch
44142+ movl chainlenscanend(%esp), %ebx
44143+ movl windowbestlen(%esp), %esi
44144+ movl dsPrev(%edx), %edi
44145+ movl wmask(%esp), %edx
44146+ andl %ecx, %edx
44147+ jmp LookupLoop
44148+
44149+/* s->match_start = cur_match; */
44150+/* best_len = len; */
44151+/* if (len >= nice_match) break; */
44152+/* scan_end = *(ushf*)(scan+best_len-1); */
44153+
44154+LongerMatch: movl nicematch(%esp), %ebx
44155+ movl %eax, bestlen(%esp)
44156+ movl %ecx, dsMatchStart(%edx)
44157+ cmpl %ebx, %eax
44158+ jge LeaveNow
44159+ movl window(%esp), %esi
44160+ addl %eax, %esi
44161+ movl %esi, windowbestlen(%esp)
44162+ movl chainlenscanend(%esp), %ebx
44163+ movw -1(%edi,%eax), %bx
44164+ movl dsPrev(%edx), %edi
44165+ movl %ebx, chainlenscanend(%esp)
44166+ movl wmask(%esp), %edx
44167+ andl %ecx, %edx
44168+ jmp LookupLoop
44169+
44170+/* Accept the current string, with the maximum possible length. */
44171+
44172+LenMaximum: movl deflatestate(%esp), %edx
44173+ movl $MAX_MATCH, bestlen(%esp)
44174+ movl %ecx, dsMatchStart(%edx)
44175+
44176+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
44177+/* return s->lookahead; */
44178+
44179+LeaveNow:
44180+ movl deflatestate(%esp), %edx
44181+ movl bestlen(%esp), %ebx
44182+ movl dsLookahead(%edx), %eax
44183+ cmpl %eax, %ebx
44184+ jg LookaheadRet
44185+ movl %ebx, %eax
44186+LookaheadRet:
44187+
44188+/* Restore the stack and return from whence we came. */
44189+
44190+ addl $LocalVarsSize, %esp
44191+ popl %ebx
44192+ popl %esi
44193+ popl %edi
44194+ popl %ebp
44195+match_init: ret
44196--- /dev/null Tue Mar 11 13:02:56 2003
44197+++ linux/net/ipsec/match686.S Mon Feb 9 13:51:03 2004
44198@@ -0,0 +1,330 @@
44199+/* match.s -- Pentium-Pro-optimized version of longest_match()
44200+ * Written for zlib 1.1.2
44201+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
44202+ *
44203+ * This is free software; you can redistribute it and/or modify it
44204+ * under the terms of the GNU General Public License.
44205+ */
44206+
44207+#ifndef NO_UNDERLINE
44208+#define match_init _ipcomp_match_init
44209+#define longest_match _ipcomp_longest_match
44210+#else
44211+#define match_init ipcomp_match_init
44212+#define longest_match ipcomp_longest_match
44213+#endif
44214+
44215+#define MAX_MATCH (258)
44216+#define MIN_MATCH (3)
44217+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
44218+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
44219+
44220+/* stack frame offsets */
44221+
44222+#define chainlenwmask 0 /* high word: current chain len */
44223+ /* low word: s->wmask */
44224+#define window 4 /* local copy of s->window */
44225+#define windowbestlen 8 /* s->window + bestlen */
44226+#define scanstart 16 /* first two bytes of string */
44227+#define scanend 12 /* last two bytes of string */
44228+#define scanalign 20 /* dword-misalignment of string */
44229+#define nicematch 24 /* a good enough match size */
44230+#define bestlen 28 /* size of best match so far */
44231+#define scan 32 /* ptr to string wanting match */
44232+
44233+#define LocalVarsSize (36)
44234+/* saved ebx 36 */
44235+/* saved edi 40 */
44236+/* saved esi 44 */
44237+/* saved ebp 48 */
44238+/* return address 52 */
44239+#define deflatestate 56 /* the function arguments */
44240+#define curmatch 60
44241+
44242+/* Offsets for fields in the deflate_state structure. These numbers
44243+ * are calculated from the definition of deflate_state, with the
44244+ * assumption that the compiler will dword-align the fields. (Thus,
44245+ * changing the definition of deflate_state could easily cause this
44246+ * program to crash horribly, without so much as a warning at
44247+ * compile time. Sigh.)
44248+ */
44249+#define dsWSize 36
44250+#define dsWMask 44
44251+#define dsWindow 48
44252+#define dsPrev 56
44253+#define dsMatchLen 88
44254+#define dsPrevMatch 92
44255+#define dsStrStart 100
44256+#define dsMatchStart 104
44257+#define dsLookahead 108
44258+#define dsPrevLen 112
44259+#define dsMaxChainLen 116
44260+#define dsGoodMatch 132
44261+#define dsNiceMatch 136
44262+
44263+
44264+.file "match.S"
44265+
44266+.globl match_init, longest_match
44267+
44268+.text
44269+
44270+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
44271+
44272+longest_match:
44273+
44274+/* Save registers that the compiler may be using, and adjust %esp to */
44275+/* make room for our stack frame. */
44276+
44277+ pushl %ebp
44278+ pushl %edi
44279+ pushl %esi
44280+ pushl %ebx
44281+ subl $LocalVarsSize, %esp
44282+
44283+/* Retrieve the function arguments. %ecx will hold cur_match */
44284+/* throughout the entire function. %edx will hold the pointer to the */
44285+/* deflate_state structure during the function's setup (before */
44286+/* entering the main loop). */
44287+
44288+ movl deflatestate(%esp), %edx
44289+ movl curmatch(%esp), %ecx
44290+
44291+/* uInt wmask = s->w_mask; */
44292+/* unsigned chain_length = s->max_chain_length; */
44293+/* if (s->prev_length >= s->good_match) { */
44294+/* chain_length >>= 2; */
44295+/* } */
44296+
44297+ movl dsPrevLen(%edx), %eax
44298+ movl dsGoodMatch(%edx), %ebx
44299+ cmpl %ebx, %eax
44300+ movl dsWMask(%edx), %eax
44301+ movl dsMaxChainLen(%edx), %ebx
44302+ jl LastMatchGood
44303+ shrl $2, %ebx
44304+LastMatchGood:
44305+
44306+/* chainlen is decremented once beforehand so that the function can */
44307+/* use the sign flag instead of the zero flag for the exit test. */
44308+/* It is then shifted into the high word, to make room for the wmask */
44309+/* value, which it will always accompany. */
44310+
44311+ decl %ebx
44312+ shll $16, %ebx
44313+ orl %eax, %ebx
44314+ movl %ebx, chainlenwmask(%esp)
44315+
44316+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
44317+
44318+ movl dsNiceMatch(%edx), %eax
44319+ movl dsLookahead(%edx), %ebx
44320+ cmpl %eax, %ebx
44321+ jl LookaheadLess
44322+ movl %eax, %ebx
44323+LookaheadLess: movl %ebx, nicematch(%esp)
44324+
44325+/* register Bytef *scan = s->window + s->strstart; */
44326+
44327+ movl dsWindow(%edx), %esi
44328+ movl %esi, window(%esp)
44329+ movl dsStrStart(%edx), %ebp
44330+ lea (%esi,%ebp), %edi
44331+ movl %edi, scan(%esp)
44332+
44333+/* Determine how many bytes the scan ptr is off from being */
44334+/* dword-aligned. */
44335+
44336+ movl %edi, %eax
44337+ negl %eax
44338+ andl $3, %eax
44339+ movl %eax, scanalign(%esp)
44340+
44341+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
44342+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
44343+
44344+ movl dsWSize(%edx), %eax
44345+ subl $MIN_LOOKAHEAD, %eax
44346+ subl %eax, %ebp
44347+ jg LimitPositive
44348+ xorl %ebp, %ebp
44349+LimitPositive:
44350+
44351+/* int best_len = s->prev_length; */
44352+
44353+ movl dsPrevLen(%edx), %eax
44354+ movl %eax, bestlen(%esp)
44355+
44356+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
44357+
44358+ addl %eax, %esi
44359+ movl %esi, windowbestlen(%esp)
44360+
44361+/* register ush scan_start = *(ushf*)scan; */
44362+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
44363+/* Posf *prev = s->prev; */
44364+
44365+ movzwl (%edi), %ebx
44366+ movl %ebx, scanstart(%esp)
44367+ movzwl -1(%edi,%eax), %ebx
44368+ movl %ebx, scanend(%esp)
44369+ movl dsPrev(%edx), %edi
44370+
44371+/* Jump into the main loop. */
44372+
44373+ movl chainlenwmask(%esp), %edx
44374+ jmp LoopEntry
44375+
44376+.balign 16
44377+
44378+/* do {
44379+ * match = s->window + cur_match;
44380+ * if (*(ushf*)(match+best_len-1) != scan_end ||
44381+ * *(ushf*)match != scan_start) continue;
44382+ * [...]
44383+ * } while ((cur_match = prev[cur_match & wmask]) > limit
44384+ * && --chain_length != 0);
44385+ *
44386+ * Here is the inner loop of the function. The function will spend the
44387+ * majority of its time in this loop, and majority of that time will
44388+ * be spent in the first ten instructions.
44389+ *
44390+ * Within this loop:
44391+ * %ebx = scanend
44392+ * %ecx = curmatch
44393+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
44394+ * %esi = windowbestlen - i.e., (window + bestlen)
44395+ * %edi = prev
44396+ * %ebp = limit
44397+ */
44398+LookupLoop:
44399+ andl %edx, %ecx
44400+ movzwl (%edi,%ecx,2), %ecx
44401+ cmpl %ebp, %ecx
44402+ jbe LeaveNow
44403+ subl $0x00010000, %edx
44404+ js LeaveNow
44405+LoopEntry: movzwl -1(%esi,%ecx), %eax
44406+ cmpl %ebx, %eax
44407+ jnz LookupLoop
44408+ movl window(%esp), %eax
44409+ movzwl (%eax,%ecx), %eax
44410+ cmpl scanstart(%esp), %eax
44411+ jnz LookupLoop
44412+
44413+/* Store the current value of chainlen. */
44414+
44415+ movl %edx, chainlenwmask(%esp)
44416+
44417+/* Point %edi to the string under scrutiny, and %esi to the string we */
44418+/* are hoping to match it up with. In actuality, %esi and %edi are */
44419+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
44420+/* initialized to -(MAX_MATCH_8 - scanalign). */
44421+
44422+ movl window(%esp), %esi
44423+ movl scan(%esp), %edi
44424+ addl %ecx, %esi
44425+ movl scanalign(%esp), %eax
44426+ movl $(-MAX_MATCH_8), %edx
44427+ lea MAX_MATCH_8(%edi,%eax), %edi
44428+ lea MAX_MATCH_8(%esi,%eax), %esi
44429+
44430+/* Test the strings for equality, 8 bytes at a time. At the end,
44431+ * adjust %edx so that it is offset to the exact byte that mismatched.
44432+ *
44433+ * We already know at this point that the first three bytes of the
44434+ * strings match each other, and they can be safely passed over before
44435+ * starting the compare loop. So what this code does is skip over 0-3
44436+ * bytes, as much as necessary in order to dword-align the %edi
44437+ * pointer. (%esi will still be misaligned three times out of four.)
44438+ *
44439+ * It should be confessed that this loop usually does not represent
44440+ * much of the total running time. Replacing it with a more
44441+ * straightforward "rep cmpsb" would not drastically degrade
44442+ * performance.
44443+ */
44444+LoopCmps:
44445+ movl (%esi,%edx), %eax
44446+ xorl (%edi,%edx), %eax
44447+ jnz LeaveLoopCmps
44448+ movl 4(%esi,%edx), %eax
44449+ xorl 4(%edi,%edx), %eax
44450+ jnz LeaveLoopCmps4
44451+ addl $8, %edx
44452+ jnz LoopCmps
44453+ jmp LenMaximum
44454+LeaveLoopCmps4: addl $4, %edx
44455+LeaveLoopCmps: testl $0x0000FFFF, %eax
44456+ jnz LenLower
44457+ addl $2, %edx
44458+ shrl $16, %eax
44459+LenLower: subb $1, %al
44460+ adcl $0, %edx
44461+
44462+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
44463+/* then automatically accept it as the best possible match and leave. */
44464+
44465+ lea (%edi,%edx), %eax
44466+ movl scan(%esp), %edi
44467+ subl %edi, %eax
44468+ cmpl $MAX_MATCH, %eax
44469+ jge LenMaximum
44470+
44471+/* If the length of the match is not longer than the best match we */
44472+/* have so far, then forget it and return to the lookup loop. */
44473+
44474+ movl deflatestate(%esp), %edx
44475+ movl bestlen(%esp), %ebx
44476+ cmpl %ebx, %eax
44477+ jg LongerMatch
44478+ movl windowbestlen(%esp), %esi
44479+ movl dsPrev(%edx), %edi
44480+ movl scanend(%esp), %ebx
44481+ movl chainlenwmask(%esp), %edx
44482+ jmp LookupLoop
44483+
44484+/* s->match_start = cur_match; */
44485+/* best_len = len; */
44486+/* if (len >= nice_match) break; */
44487+/* scan_end = *(ushf*)(scan+best_len-1); */
44488+
44489+LongerMatch: movl nicematch(%esp), %ebx
44490+ movl %eax, bestlen(%esp)
44491+ movl %ecx, dsMatchStart(%edx)
44492+ cmpl %ebx, %eax
44493+ jge LeaveNow
44494+ movl window(%esp), %esi
44495+ addl %eax, %esi
44496+ movl %esi, windowbestlen(%esp)
44497+ movzwl -1(%edi,%eax), %ebx
44498+ movl dsPrev(%edx), %edi
44499+ movl %ebx, scanend(%esp)
44500+ movl chainlenwmask(%esp), %edx
44501+ jmp LookupLoop
44502+
44503+/* Accept the current string, with the maximum possible length. */
44504+
44505+LenMaximum: movl deflatestate(%esp), %edx
44506+ movl $MAX_MATCH, bestlen(%esp)
44507+ movl %ecx, dsMatchStart(%edx)
44508+
44509+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
44510+/* return s->lookahead; */
44511+
44512+LeaveNow:
44513+ movl deflatestate(%esp), %edx
44514+ movl bestlen(%esp), %ebx
44515+ movl dsLookahead(%edx), %eax
44516+ cmpl %eax, %ebx
44517+ jg LookaheadRet
44518+ movl %ebx, %eax
44519+LookaheadRet:
44520+
44521+/* Restore the stack and return from whence we came. */
44522+
44523+ addl $LocalVarsSize, %esp
44524+ popl %ebx
44525+ popl %esi
44526+ popl %edi
44527+ popl %ebp
44528+match_init: ret
44529--- /dev/null Tue Mar 11 13:02:56 2003
44530+++ linux/net/ipsec/null/ipsec_alg_null.c Mon Feb 9 13:51:03 2004
44531@@ -0,0 +1,145 @@
44532+/*
44533+ * ipsec_alg NULL cipher stubs
44534+ *
44535+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
44536+ *
44537+ * $Id: ipsec_alg_null.c,v 1.1.2.1 2006/10/11 18:14:33 paul Exp $
44538+ *
44539+ * This program is free software; you can redistribute it and/or modify it
44540+ * under the terms of the GNU General Public License as published by the
44541+ * Free Software Foundation; either version 2 of the License, or (at your
44542+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
44543+ *
44544+ * This program is distributed in the hope that it will be useful, but
44545+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
44546+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44547+ * for more details.
44548+ *
44549+ */
44550+#include <linux/config.h>
44551+#include <linux/version.h>
44552+
44553+/*
44554+ * special case: ipsec core modular with this static algo inside:
44555+ * must avoid MODULE magic for this file
44556+ */
44557+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_NULL)
44558+#undef MODULE
44559+#endif
44560+
44561+#include <linux/module.h>
44562+#include <linux/init.h>
44563+
44564+#include <linux/kernel.h> /* printk() */
44565+#include <linux/errno.h> /* error codes */
44566+#include <linux/types.h> /* size_t */
44567+#include <linux/string.h>
44568+
44569+/* Check if __exit is defined, if not null it */
44570+#ifndef __exit
44571+#define __exit
44572+#endif
44573+
44574+/* Low freeswan header coupling */
44575+#include "openswan/ipsec_alg.h"
44576+
44577+#define ESP_NULL 11 /* from ipsec drafts */
44578+#define ESP_NULL_BLK_LEN 1
44579+
44580+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
44581+static int debug_null=0;
44582+static int test_null=0;
44583+#ifdef module_param
44584+module_param(debug_null, int, 0600);
44585+module_param(test_null, int, 0600);
44586+#else
44587+MODULE_PARM(debug_null, "i");
44588+MODULE_PARM(test_null, "i");
44589+#endif
44590+
44591+typedef int null_context;
44592+
44593+struct null_eks{
44594+ null_context null_ctx;
44595+};
44596+static int _null_set_key(struct ipsec_alg_enc *alg,
44597+ __u8 * key_e, const __u8 * key,
44598+ size_t keysize) {
44599+ null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
44600+ if (debug_null > 0)
44601+ printk(KERN_DEBUG "klips_debug:_null_set_key:"
44602+ "key_e=%p key=%p keysize=%d\n",
44603+ key_e, key, keysize);
44604+ *ctx = 1;
44605+ return 0;
44606+}
44607+static int _null_cbc_encrypt(struct ipsec_alg_enc *alg,
44608+ __u8 * key_e, __u8 * in, int ilen, const __u8 * iv,
44609+ int encrypt) {
44610+ null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
44611+ if (debug_null > 0)
44612+ printk(KERN_DEBUG "klips_debug:_null_cbc_encrypt:"
44613+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
44614+ key_e, in, ilen, iv, encrypt);
44615+ (*ctx)++;
44616+ return ilen;
44617+}
44618+static struct ipsec_alg_enc ipsec_alg_NULL = {
44619+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
44620+ ixt_refcnt: ATOMIC_INIT(0),
44621+ ixt_name: "null",
44622+ ixt_blocksize: ESP_NULL_BLK_LEN,
44623+ ixt_support: {
44624+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
44625+ ias_id: ESP_NULL,
44626+ ias_ivlen: 0,
44627+ ias_keyminbits: 0,
44628+ ias_keymaxbits: 0,
44629+ },
44630+ },
44631+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44632+ ixt_module: THIS_MODULE,
44633+#endif
44634+ ixt_e_keylen: 0,
44635+ ixt_e_ctx_size: sizeof(null_context),
44636+ ixt_e_set_key: _null_set_key,
44637+ ixt_e_cbc_encrypt:_null_cbc_encrypt,
44638+};
44639+
44640+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44641+IPSEC_ALG_MODULE_INIT_MOD( ipsec_null_init )
44642+#else
44643+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_null_init )
44644+#endif
44645+{
44646+ int ret, test_ret;
44647+ ret=register_ipsec_alg_enc(&ipsec_alg_NULL);
44648+ printk("ipsec_null_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
44649+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44650+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44651+ ipsec_alg_NULL.ixt_common.ixt_name,
44652+ ret);
44653+ if (ret==0 && test_null) {
44654+ test_ret=ipsec_alg_test(
44655+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44656+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44657+ test_null);
44658+ printk("ipsec_null_init(alg_type=%d alg_id=%d): test_ret=%d\n",
44659+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44660+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44661+ test_ret);
44662+ }
44663+ return ret;
44664+}
44665+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44666+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_null_fini )
44667+#else
44668+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_null_fini )
44669+#endif
44670+{
44671+ unregister_ipsec_alg_enc(&ipsec_alg_NULL);
44672+ return;
44673+}
44674+#ifdef MODULE_LICENSE
44675+MODULE_LICENSE("GPL");
44676+#endif
44677--- /dev/null Tue Mar 11 13:02:56 2003
44678+++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004
44679@@ -0,0 +1,2022 @@
44680+/*
44681+ * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
44682+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
44683+ *
44684+ * This program is free software; you can redistribute it and/or modify it
44685+ * under the terms of the GNU General Public License as published by the
44686+ * Free Software Foundation; either version 2 of the License, or (at your
44687+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
44688+ *
44689+ * This program is distributed in the hope that it will be useful, but
44690+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
44691+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44692+ * for more details.
44693+ *
44694+ * RCSID $Id: pfkey_v2.c,v 1.97.2.12 2006/11/24 05:43:29 paul Exp $
44695+ */
44696+
44697+/*
44698+ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
44699+ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
44700+ */
44701+
44702+#define __NO_VERSION__
44703+#include <linux/module.h>
44704+#include <linux/version.h>
44705+#ifndef AUTOCONF_INCLUDED
44706+#include <linux/config.h>
44707+#endif
44708+#include <linux/kernel.h>
44709+
44710+#include "openswan/ipsec_param.h"
44711+
44712+#include <linux/major.h>
44713+#include <linux/signal.h>
44714+#include <linux/sched.h>
44715+#include <linux/errno.h>
44716+#include <linux/string.h>
44717+#include <linux/stat.h>
44718+#include <linux/socket.h>
44719+#include <linux/un.h>
44720+#include <linux/fcntl.h>
44721+#include <linux/termios.h>
44722+#include <linux/socket.h>
44723+#include <linux/sockios.h>
44724+#include <linux/net.h> /* struct socket */
44725+#include <linux/in.h>
44726+#include <linux/fs.h>
44727+#ifdef MALLOC_SLAB
44728+# include <linux/slab.h> /* kmalloc() */
44729+#else /* MALLOC_SLAB */
44730+# include <linux/malloc.h> /* kmalloc() */
44731+#endif /* MALLOC_SLAB */
44732+#include <asm/segment.h>
44733+#include <linux/skbuff.h>
44734+#include <linux/netdevice.h>
44735+#include <net/sock.h> /* struct sock */
44736+#include <net/protocol.h>
44737+/* #include <net/tcp.h> */
44738+#include <net/af_unix.h>
44739+#ifdef CONFIG_PROC_FS
44740+# include <linux/proc_fs.h>
44741+#endif /* CONFIG_PROC_FS */
44742+
44743+#include <linux/types.h>
44744+
44745+#include <openswan.h>
44746+
44747+#include "openswan/radij.h"
44748+#include "openswan/ipsec_encap.h"
44749+#include "openswan/ipsec_sa.h"
44750+
44751+#include <pfkeyv2.h>
44752+#include <pfkey.h>
44753+
44754+#include "openswan/ipsec_proto.h"
44755+#include "openswan/ipsec_kern24.h"
44756+
44757+#ifdef CONFIG_KLIPS_DEBUG
44758+int debug_pfkey = 0;
44759+extern int sysctl_ipsec_debug_verbose;
44760+#endif /* CONFIG_KLIPS_DEBUG */
44761+
44762+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
44763+
44764+#ifndef SOCKOPS_WRAPPED
44765+#define SOCKOPS_WRAPPED(name) name
44766+#endif /* SOCKOPS_WRAPPED */
44767+
44768+#ifdef NET_26
44769+static rwlock_t pfkey_sock_lock = RW_LOCK_UNLOCKED;
44770+HLIST_HEAD(pfkey_sock_list);
44771+static DECLARE_WAIT_QUEUE_HEAD(pfkey_sock_wait);
44772+static atomic_t pfkey_sock_users = ATOMIC_INIT(0);
44773+#else
44774+struct sock *pfkey_sock_list = NULL;
44775+#endif
44776+
44777+struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
44778+
44779+struct socket_list *pfkey_open_sockets = NULL;
44780+struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
44781+
44782+int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
44783+
44784+DEBUG_NO_STATIC int pfkey_create(struct socket *sock, int protocol);
44785+DEBUG_NO_STATIC int pfkey_shutdown(struct socket *sock, int mode);
44786+DEBUG_NO_STATIC int pfkey_release(struct socket *sock);
44787+
44788+#ifdef NET_26
44789+DEBUG_NO_STATIC int pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len);
44790+DEBUG_NO_STATIC int pfkey_recvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg
44791+ , size_t size, int flags);
44792+#else
44793+DEBUG_NO_STATIC int pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm);
44794+DEBUG_NO_STATIC int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm);
44795+#endif
44796+
44797+struct net_proto_family pfkey_family_ops = {
44798+#ifdef NETDEV_23
44799+ .family = PF_KEY,
44800+ .create = pfkey_create,
44801+#ifdef NET_26
44802+ .owner = THIS_MODULE,
44803+#endif
44804+#else
44805+ PF_KEY,
44806+ pfkey_create
44807+#endif
44808+};
44809+
44810+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
44811+#ifdef NETDEV_23
44812+ family: PF_KEY,
44813+#ifdef NET_26
44814+ owner: THIS_MODULE,
44815+#endif
44816+ release: pfkey_release,
44817+ bind: sock_no_bind,
44818+ connect: sock_no_connect,
44819+ socketpair: sock_no_socketpair,
44820+ accept: sock_no_accept,
44821+ getname: sock_no_getname,
44822+ poll: datagram_poll,
44823+ ioctl: sock_no_ioctl,
44824+ listen: sock_no_listen,
44825+ shutdown: pfkey_shutdown,
44826+ setsockopt: sock_no_setsockopt,
44827+ getsockopt: sock_no_getsockopt,
44828+ sendmsg: pfkey_sendmsg,
44829+ recvmsg: pfkey_recvmsg,
44830+ mmap: sock_no_mmap,
44831+#else /* NETDEV_23 */
44832+ PF_KEY,
44833+ sock_no_dup,
44834+ pfkey_release,
44835+ sock_no_bind,
44836+ sock_no_connect,
44837+ sock_no_socketpair,
44838+ sock_no_accept,
44839+ sock_no_getname,
44840+ datagram_poll,
44841+ sock_no_ioctl,
44842+ sock_no_listen,
44843+ pfkey_shutdown,
44844+ sock_no_setsockopt,
44845+ sock_no_getsockopt,
44846+ sock_no_fcntl,
44847+ pfkey_sendmsg,
44848+ pfkey_recvmsg
44849+#endif /* NETDEV_23 */
44850+};
44851+
44852+#ifdef NETDEV_23
44853+#include <linux/smp_lock.h>
44854+SOCKOPS_WRAP(pfkey, PF_KEY);
44855+#endif /* NETDEV_23 */
44856+
44857+#ifdef NET_26
44858+static void pfkey_sock_list_grab(void)
44859+{
44860+ write_lock_bh(&pfkey_sock_lock);
44861+
44862+ if (atomic_read(&pfkey_sock_users)) {
44863+ DECLARE_WAITQUEUE(wait, current);
44864+
44865+ add_wait_queue_exclusive(&pfkey_sock_wait, &wait);
44866+ for(;;) {
44867+ set_current_state(TASK_UNINTERRUPTIBLE);
44868+ if (atomic_read(&pfkey_sock_users) == 0)
44869+ break;
44870+ write_unlock_bh(&pfkey_sock_lock);
44871+ schedule();
44872+ write_lock_bh(&pfkey_sock_lock);
44873+ }
44874+
44875+ __set_current_state(TASK_RUNNING);
44876+ remove_wait_queue(&pfkey_sock_wait, &wait);
44877+ }
44878+}
44879+
44880+static __inline__ void pfkey_sock_list_ungrab(void)
44881+{
44882+ write_unlock_bh(&pfkey_sock_lock);
44883+ wake_up(&pfkey_sock_wait);
44884+}
44885+
44886+static __inline__ void pfkey_lock_sock_list(void)
44887+{
44888+ /* read_lock() synchronizes us to pfkey_table_grab */
44889+
44890+ read_lock(&pfkey_sock_lock);
44891+ atomic_inc(&pfkey_sock_users);
44892+ read_unlock(&pfkey_sock_lock);
44893+}
44894+
44895+static __inline__ void pfkey_unlock_sock_list(void)
44896+{
44897+ if (atomic_dec_and_test(&pfkey_sock_users))
44898+ wake_up(&pfkey_sock_wait);
44899+}
44900+#endif
44901+
44902+int
44903+pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
44904+{
44905+ struct socket_list *socket_listp,*prev;
44906+
44907+ if(!socketp) {
44908+ KLIPS_PRINT(debug_pfkey,
44909+ "klips_debug:pfkey_list_remove_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_remove_socket: "
44917+ "NULL sockets list handed in, failed.\n");
44918+ return -EINVAL;
44919+ }
44920+
44921+ socket_listp = *sockets;
44922+ prev = NULL;
44923+
44924+ KLIPS_PRINT(debug_pfkey,
44925+ "klips_debug:pfkey_list_remove_socket: "
44926+ "removing sock=0p%p\n",
44927+ socketp);
44928+
44929+ while(socket_listp != NULL) {
44930+ if(socket_listp->socketp == socketp) {
44931+ if(prev != NULL) {
44932+ prev->next = socket_listp->next;
44933+ } else {
44934+ *sockets = socket_listp->next;
44935+ }
44936+
44937+ kfree((void*)socket_listp);
44938+
44939+ break;
44940+ }
44941+ prev = socket_listp;
44942+ socket_listp = socket_listp->next;
44943+ }
44944+
44945+ return 0;
44946+}
44947+
44948+int
44949+pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
44950+{
44951+ struct socket_list *socket_listp;
44952+
44953+ if(!socketp) {
44954+ KLIPS_PRINT(debug_pfkey,
44955+ "klips_debug:pfkey_list_insert_socket: "
44956+ "NULL socketp handed in, failed.\n");
44957+ return -EINVAL;
44958+ }
44959+
44960+ if(!sockets) {
44961+ KLIPS_PRINT(debug_pfkey,
44962+ "klips_debug:pfkey_list_insert_socket: "
44963+ "NULL sockets list handed in, failed.\n");
44964+ return -EINVAL;
44965+ }
44966+
44967+ KLIPS_PRINT(debug_pfkey,
44968+ "klips_debug:pfkey_list_insert_socket: "
44969+ "allocating %lu bytes for socketp=0p%p\n",
44970+ (unsigned long) sizeof(struct socket_list),
44971+ socketp);
44972+
44973+ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
44974+ KLIPS_PRINT(debug_pfkey,
44975+ "klips_debug:pfkey_list_insert_socket: "
44976+ "memory allocation error.\n");
44977+ return -ENOMEM;
44978+ }
44979+
44980+ socket_listp->socketp = socketp;
44981+ socket_listp->next = *sockets;
44982+ *sockets = socket_listp;
44983+
44984+ return 0;
44985+}
44986+
44987+int
44988+pfkey_list_remove_supported(struct ipsec_alg_supported *supported, struct supported_list **supported_list)
44989+{
44990+ struct supported_list *supported_listp = *supported_list, *prev = NULL;
44991+
44992+ if(!supported) {
44993+ KLIPS_PRINT(debug_pfkey,
44994+ "klips_debug:pfkey_list_remove_supported: "
44995+ "NULL supported handed in, failed.\n");
44996+ return -EINVAL;
44997+ }
44998+
44999+ if(!supported_list) {
45000+ KLIPS_PRINT(debug_pfkey,
45001+ "klips_debug:pfkey_list_remove_supported: "
45002+ "NULL supported_list handed in, failed.\n");
45003+ return -EINVAL;
45004+ }
45005+
45006+ KLIPS_PRINT(debug_pfkey,
45007+ "klips_debug:pfkey_list_remove_supported: "
45008+ "removing supported=0p%p\n",
45009+ supported);
45010+
45011+ while(supported_listp != NULL) {
45012+ if(supported_listp->supportedp == supported) {
45013+ if(prev != NULL) {
45014+ prev->next = supported_listp->next;
45015+ } else {
45016+ *supported_list = supported_listp->next;
45017+ }
45018+
45019+ kfree((void*)supported_listp);
45020+
45021+ break;
45022+ }
45023+ prev = supported_listp;
45024+ supported_listp = supported_listp->next;
45025+ }
45026+
45027+ return 0;
45028+}
45029+
45030+int
45031+pfkey_list_insert_supported(struct ipsec_alg_supported *supported
45032+ , struct supported_list **supported_list)
45033+{
45034+ struct supported_list *supported_listp;
45035+
45036+ if(!supported) {
45037+ KLIPS_PRINT(debug_pfkey,
45038+ "klips_debug:pfkey_list_insert_supported: "
45039+ "NULL supported handed in, failed.\n");
45040+ return -EINVAL;
45041+ }
45042+
45043+ if(!supported_list) {
45044+ KLIPS_PRINT(debug_pfkey,
45045+ "klips_debug:pfkey_list_insert_supported: "
45046+ "NULL supported_list handed in, failed.\n");
45047+ return -EINVAL;
45048+ }
45049+
45050+ KLIPS_PRINT(debug_pfkey,
45051+ "klips_debug:pfkey_list_insert_supported: "
45052+ "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
45053+ (unsigned long) sizeof(struct supported_list),
45054+ supported,
45055+ supported_list);
45056+
45057+ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
45058+
45059+ if(supported_listp == NULL)
45060+ {
45061+ KLIPS_PRINT(debug_pfkey,
45062+ "klips_debug:pfkey_list_insert_supported: "
45063+ "memory allocation error.\n");
45064+ return -ENOMEM;
45065+ }
45066+
45067+ supported_listp->supportedp = supported;
45068+ supported_listp->next = *supported_list;
45069+ *supported_list = supported_listp;
45070+ KLIPS_PRINT(debug_pfkey,
45071+ "klips_debug:pfkey_list_insert_supported: "
45072+ "outgoing, supported=0p%p, supported_list=0p%p\n",
45073+ supported,
45074+ supported_list);
45075+
45076+ return 0;
45077+}
45078+
45079+#ifdef NET_26
45080+DEBUG_NO_STATIC void
45081+pfkey_insert_socket(struct sock *sk)
45082+{
45083+ KLIPS_PRINT(debug_pfkey,
45084+ "klips_debug:pfkey_insert_socket: "
45085+ "sk=0p%p\n",
45086+ sk);
45087+ pfkey_sock_list_grab();
45088+ sk_add_node(sk, &pfkey_sock_list);
45089+ pfkey_sock_list_ungrab();
45090+}
45091+
45092+DEBUG_NO_STATIC void
45093+pfkey_remove_socket(struct sock *sk)
45094+{
45095+ KLIPS_PRINT(debug_pfkey,
45096+ "klips_debug:pfkey_remove_socket: 0p%p\n", sk);
45097+ pfkey_sock_list_grab();
45098+ sk_del_node_init(sk);
45099+ pfkey_sock_list_ungrab();
45100+ return;
45101+}
45102+#else
45103+
45104+DEBUG_NO_STATIC void
45105+pfkey_insert_socket(struct sock *sk)
45106+{
45107+ KLIPS_PRINT(debug_pfkey,
45108+ "klips_debug:pfkey_insert_socket: "
45109+ "sk=0p%p\n",
45110+ sk);
45111+ cli();
45112+ sk->next=pfkey_sock_list;
45113+ pfkey_sock_list=sk;
45114+ sti();
45115+}
45116+DEBUG_NO_STATIC void
45117+pfkey_remove_socket(struct sock *sk)
45118+{
45119+ struct sock **s;
45120+
45121+ s = NULL;
45122+ KLIPS_PRINT(debug_pfkey,
45123+ "klips_debug:pfkey_remove_socket: .\n");
45124+
45125+ cli();
45126+ s=&pfkey_sock_list;
45127+
45128+ while(*s!=NULL) {
45129+ if(*s==sk) {
45130+ *s=sk->next;
45131+ sk->next=NULL;
45132+ sti();
45133+ KLIPS_PRINT(debug_pfkey,
45134+ "klips_debug:pfkey_remove_socket: "
45135+ "succeeded.\n");
45136+ return;
45137+ }
45138+ s=&((*s)->next);
45139+ }
45140+ sti();
45141+
45142+ KLIPS_PRINT(debug_pfkey,
45143+ "klips_debug:pfkey_remove_socket: "
45144+ "not found.\n");
45145+ return;
45146+}
45147+#endif
45148+
45149+DEBUG_NO_STATIC void
45150+pfkey_destroy_socket(struct sock *sk)
45151+{
45152+ struct sk_buff *skb;
45153+
45154+ KLIPS_PRINT(debug_pfkey,
45155+ "klips_debug:pfkey_destroy_socket: 0p%p\n",sk);
45156+ pfkey_remove_socket(sk);
45157+
45158+ KLIPS_PRINT(debug_pfkey,
45159+ "klips_debug:pfkey_destroy_socket: "
45160+ "pfkey_remove_socket called, sk=0p%p\n",sk);
45161+
45162+ KLIPS_PRINT(debug_pfkey,
45163+ "klips_debug:pfkey_destroy_socket: "
45164+ "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
45165+ sk,
45166+ &(sk->sk_receive_queue),
45167+ sk->sk_receive_queue.next,
45168+ sk->sk_receive_queue.prev);
45169+
45170+ while(sk && ((skb=skb_dequeue(&(sk->sk_receive_queue)))!=NULL)) {
45171+#ifdef CONFIG_KLIPS_DEBUG
45172+ if(debug_pfkey && sysctl_ipsec_debug_verbose) {
45173+ KLIPS_PRINT(debug_pfkey,
45174+ "klips_debug:pfkey_destroy_socket: "
45175+ "skb=0p%p dequeued.\n", skb);
45176+ printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
45177+ "pfkey_skb contents:");
45178+ printk(" next:0p%p", skb->next);
45179+ printk(" prev:0p%p", skb->prev);
45180+ printk(" sk:0p%p", skb->sk);
45181+ printk(" dev:0p%p", skb->dev);
45182+ if(skb->dev) {
45183+ if(skb->dev->name) {
45184+ printk(" dev->name:%s", skb->dev->name);
45185+ } else {
45186+ printk(" dev->name:NULL?");
45187+ }
45188+ } else {
45189+ printk(" dev:NULL");
45190+ }
45191+ printk(" h:0p%p", skb->h.raw);
45192+ printk(" nh:0p%p", skb->nh.raw);
45193+ printk(" mac:0p%p", skb->mac.raw);
45194+ printk(" dst:0p%p", skb->dst);
45195+ if(sysctl_ipsec_debug_verbose) {
45196+ int i;
45197+
45198+ printk(" cb");
45199+ for(i=0; i<48; i++) {
45200+ printk(":%2x", skb->cb[i]);
45201+ }
45202+ }
45203+ printk(" len:%d", skb->len);
45204+ printk(" csum:%d", skb->csum);
45205+#ifndef NETDEV_23
45206+ printk(" used:%d", skb->used);
45207+ printk(" is_clone:%d", skb->is_clone);
45208+#endif /* NETDEV_23 */
45209+ printk(" cloned:%d", skb->cloned);
45210+ printk(" pkt_type:%d", skb->pkt_type);
45211+ printk(" ip_summed:%d", skb->ip_summed);
45212+ printk(" priority:%d", skb->priority);
45213+ printk(" protocol:%d", skb->protocol);
45214+#ifdef HAVE_SOCK_SECURITY
45215+ printk(" security:%d", skb->security);
45216+#endif
45217+ printk(" truesize:%d", skb->truesize);
45218+ printk(" head:0p%p", skb->head);
45219+ printk(" data:0p%p", skb->data);
45220+ printk(" tail:0p%p", skb->tail);
45221+ printk(" end:0p%p", skb->end);
45222+ if(sysctl_ipsec_debug_verbose) {
45223+ unsigned char* i;
45224+ printk(" data");
45225+ for(i = skb->head; i < skb->end; i++) {
45226+ printk(":%2x", (unsigned char)(*(i)));
45227+ }
45228+ }
45229+ printk(" destructor:0p%p", skb->destructor);
45230+ printk("\n");
45231+ }
45232+#endif /* CONFIG_KLIPS_DEBUG */
45233+ KLIPS_PRINT(debug_pfkey,
45234+ "klips_debug:pfkey_destroy_socket: "
45235+ "skb=0p%p freed.\n",
45236+ skb);
45237+ ipsec_kfree_skb(skb);
45238+ }
45239+
45240+#ifdef NET_26
45241+ sock_set_flag(sk, SOCK_DEAD);
45242+#else
45243+ sk->dead = 1;
45244+#endif
45245+ sk_free(sk);
45246+
45247+ KLIPS_PRINT(debug_pfkey,
45248+ "klips_debug:pfkey_destroy_socket: destroyed.\n");
45249+}
45250+
45251+int
45252+pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
45253+{
45254+ int error = 0;
45255+ struct sk_buff * skb = NULL;
45256+ struct sock *sk;
45257+
45258+ if(sock == NULL) {
45259+ KLIPS_PRINT(debug_pfkey,
45260+ "klips_debug:pfkey_upmsg: "
45261+ "NULL socket passed in.\n");
45262+ return -EINVAL;
45263+ }
45264+
45265+ if(pfkey_msg == NULL) {
45266+ KLIPS_PRINT(debug_pfkey,
45267+ "klips_debug:pfkey_upmsg: "
45268+ "NULL pfkey_msg passed in.\n");
45269+ return -EINVAL;
45270+ }
45271+
45272+ sk = sock->sk;
45273+
45274+ if(sk == NULL) {
45275+ KLIPS_PRINT(debug_pfkey,
45276+ "klips_debug:pfkey_upmsg: "
45277+ "NULL sock passed in.\n");
45278+ return -EINVAL;
45279+ }
45280+
45281+ KLIPS_PRINT(debug_pfkey,
45282+ "klips_debug:pfkey_upmsg: "
45283+ "allocating %d bytes...\n",
45284+ (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
45285+ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
45286+ KLIPS_PRINT(debug_pfkey,
45287+ "klips_debug:pfkey_upmsg: "
45288+ "no buffers left to send up a message.\n");
45289+ return -ENOBUFS;
45290+ }
45291+ KLIPS_PRINT(debug_pfkey,
45292+ "klips_debug:pfkey_upmsg: "
45293+ "...allocated at 0p%p.\n",
45294+ skb);
45295+
45296+ skb->dev = NULL;
45297+
45298+ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
45299+ printk(KERN_WARNING "klips_error:pfkey_upmsg: "
45300+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
45301+ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
45302+ skb_tailroom(skb));
45303+ ipsec_kfree_skb(skb);
45304+ return -ENOBUFS;
45305+ }
45306+ skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
45307+ memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
45308+
45309+ if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
45310+ skb->sk=NULL;
45311+ KLIPS_PRINT(debug_pfkey,
45312+ "klips_debug:pfkey_upmsg: "
45313+ "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
45314+ error,
45315+ skb);
45316+ ipsec_kfree_skb(skb);
45317+ return error;
45318+ }
45319+ return error;
45320+}
45321+
45322+#ifdef NET_26_12_SKALLOC
45323+static struct proto key_proto = {
45324+ .name = "KEY",
45325+ .owner = THIS_MODULE,
45326+ .obj_size = sizeof(struct sock),
45327+
45328+};
45329+#endif
45330+
45331+DEBUG_NO_STATIC int
45332+pfkey_create(struct socket *sock, int protocol)
45333+{
45334+ struct sock *sk;
45335+
45336+ if(sock == NULL) {
45337+ KLIPS_PRINT(debug_pfkey,
45338+ "klips_debug:pfkey_create: "
45339+ "socket NULL.\n");
45340+ return -EINVAL;
45341+ }
45342+
45343+ KLIPS_PRINT(debug_pfkey,
45344+ "klips_debug:pfkey_create: "
45345+ "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
45346+ sock,
45347+ sock->type,
45348+ (unsigned int)(sock->state),
45349+ sock->flags, protocol);
45350+
45351+ if(sock->type != SOCK_RAW) {
45352+ KLIPS_PRINT(debug_pfkey,
45353+ "klips_debug:pfkey_create: "
45354+ "only SOCK_RAW supported.\n");
45355+ return -ESOCKTNOSUPPORT;
45356+ }
45357+
45358+ if(protocol != PF_KEY_V2) {
45359+ KLIPS_PRINT(debug_pfkey,
45360+ "klips_debug:pfkey_create: "
45361+ "protocol not PF_KEY_V2.\n");
45362+ return -EPROTONOSUPPORT;
45363+ }
45364+
45365+ if((current->uid != 0)) {
45366+ KLIPS_PRINT(debug_pfkey,
45367+ "klips_debug:pfkey_create: "
45368+ "must be root to open pfkey sockets.\n");
45369+ return -EACCES;
45370+ }
45371+
45372+ sock->state = SS_UNCONNECTED;
45373+
45374+ KLIPS_INC_USE;
45375+
45376+#ifdef NET_26
45377+#ifdef NET_26_12_SKALLOC
45378+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
45379+#else
45380+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);
45381+#endif
45382+#else
45383+ /* 2.4 interface */
45384+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1);
45385+#endif
45386+
45387+ if(sk == NULL)
45388+ {
45389+ KLIPS_PRINT(debug_pfkey,
45390+ "klips_debug:pfkey_create: "
45391+ "Out of memory trying to allocate.\n");
45392+ KLIPS_DEC_USE;
45393+ return -ENOMEM;
45394+ }
45395+
45396+ sock_init_data(sock, sk);
45397+
45398+ sk->sk_destruct = NULL;
45399+ sk->sk_reuse = 1;
45400+ sock->ops = &pfkey_ops;
45401+
45402+ sk->sk_family = PF_KEY;
45403+/* sk->num = protocol; */
45404+ sk->sk_protocol = protocol;
45405+ key_pid(sk) = current->pid;
45406+ KLIPS_PRINT(debug_pfkey,
45407+ "klips_debug:pfkey_create: "
45408+ "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
45409+ sock->fasync_list,
45410+ sk->sk_sleep);
45411+
45412+ pfkey_insert_socket(sk);
45413+ pfkey_list_insert_socket(sock, &pfkey_open_sockets);
45414+
45415+ KLIPS_PRINT(debug_pfkey,
45416+ "klips_debug:pfkey_create: "
45417+ "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
45418+ return 0;
45419+}
45420+
45421+DEBUG_NO_STATIC int
45422+#ifdef NETDEV_23
45423+pfkey_release(struct socket *sock)
45424+#else /* NETDEV_23 */
45425+pfkey_release(struct socket *sock, struct socket *peersock)
45426+#endif /* NETDEV_23 */
45427+{
45428+ struct sock *sk;
45429+ int i;
45430+
45431+ if(sock==NULL) {
45432+ KLIPS_PRINT(debug_pfkey,
45433+ "klips_debug:pfkey_release: "
45434+ "No socket attached.\n");
45435+ return 0; /* -EINVAL; */
45436+ }
45437+
45438+ sk=sock->sk;
45439+
45440+ /* May not have data attached */
45441+ if(sk==NULL) {
45442+ KLIPS_PRINT(debug_pfkey,
45443+ "klips_debug:pfkey_release: "
45444+ "No sk attached to sock=0p%p.\n", sock);
45445+ return 0; /* -EINVAL; */
45446+ }
45447+
45448+ KLIPS_PRINT(debug_pfkey,
45449+ "klips_debug:pfkey_release: "
45450+ "sock=0p%p sk=0p%p\n", sock, sk);
45451+
45452+ if(sock_flag(sk, SOCK_DEAD))
45453+ if(sk->sk_state_change) {
45454+ sk->sk_state_change(sk);
45455+ }
45456+
45457+ sock->sk = NULL;
45458+
45459+ /* Try to flush out this socket. Throw out buffers at least */
45460+ pfkey_destroy_socket(sk);
45461+ pfkey_list_remove_socket(sock, &pfkey_open_sockets);
45462+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
45463+ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
45464+ }
45465+
45466+ KLIPS_DEC_USE;
45467+ KLIPS_PRINT(debug_pfkey,
45468+ "klips_debug:pfkey_release: "
45469+ "succeeded.\n");
45470+
45471+ return 0;
45472+}
45473+
45474+DEBUG_NO_STATIC int
45475+pfkey_shutdown(struct socket *sock, int mode)
45476+{
45477+ struct sock *sk;
45478+
45479+ if(sock == NULL) {
45480+ KLIPS_PRINT(debug_pfkey,
45481+ "klips_debug:pfkey_shutdown: "
45482+ "NULL socket passed in.\n");
45483+ return -EINVAL;
45484+ }
45485+
45486+ sk=sock->sk;
45487+
45488+ if(sk == NULL) {
45489+ KLIPS_PRINT(debug_pfkey,
45490+ "klips_debug:pfkey_shutdown: "
45491+ "No sock attached to socket.\n");
45492+ return -EINVAL;
45493+ }
45494+
45495+ KLIPS_PRINT(debug_pfkey,
45496+ "klips_debug:pfkey_shutdown: "
45497+ "mode=%x.\n", mode);
45498+ mode++;
45499+
45500+ if(mode&SEND_SHUTDOWN) {
45501+ sk->sk_shutdown|=SEND_SHUTDOWN;
45502+ sk->sk_state_change(sk);
45503+ }
45504+
45505+ if(mode&RCV_SHUTDOWN) {
45506+ sk->sk_shutdown|=RCV_SHUTDOWN;
45507+ sk->sk_state_change(sk);
45508+ }
45509+ return 0;
45510+}
45511+
45512+/*
45513+ * Send PF_KEY data down.
45514+ */
45515+
45516+DEBUG_NO_STATIC int
45517+#ifdef NET_26
45518+pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
45519+#else
45520+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
45521+#endif
45522+{
45523+ struct sock *sk;
45524+ int error = 0;
45525+ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
45526+
45527+ if(sock == NULL) {
45528+ KLIPS_PRINT(debug_pfkey,
45529+ "klips_debug:pfkey_sendmsg: "
45530+ "Null socket passed in.\n");
45531+ SENDERR(EINVAL);
45532+ }
45533+
45534+ sk = sock->sk;
45535+
45536+ if(sk == NULL) {
45537+ KLIPS_PRINT(debug_pfkey,
45538+ "klips_debug:pfkey_sendmsg: "
45539+ "Null sock passed in.\n");
45540+ SENDERR(EINVAL);
45541+ }
45542+
45543+ if(msg == NULL) {
45544+ KLIPS_PRINT(debug_pfkey,
45545+ "klips_debug:pfkey_sendmsg: "
45546+ "Null msghdr passed in.\n");
45547+ SENDERR(EINVAL);
45548+ }
45549+
45550+ KLIPS_PRINT(debug_pfkey,
45551+ "klips_debug:pfkey_sendmsg: .\n");
45552+ if(sk->sk_err) {
45553+ error = sock_error(sk);
45554+ KLIPS_PRINT(debug_pfkey,
45555+ "klips_debug:pfkey_sendmsg: "
45556+ "sk->err is non-zero, returns %d.\n",
45557+ error);
45558+ SENDERR(-error);
45559+ }
45560+
45561+ if((current->uid != 0)) {
45562+ KLIPS_PRINT(debug_pfkey,
45563+ "klips_debug:pfkey_sendmsg: "
45564+ "must be root to send messages to pfkey sockets.\n");
45565+ SENDERR(EACCES);
45566+ }
45567+
45568+ if(msg->msg_control)
45569+ {
45570+ KLIPS_PRINT(debug_pfkey,
45571+ "klips_debug:pfkey_sendmsg: "
45572+ "can't set flags or set msg_control.\n");
45573+ SENDERR(EINVAL);
45574+ }
45575+
45576+ if(sk->sk_shutdown & SEND_SHUTDOWN) {
45577+ KLIPS_PRINT(debug_pfkey,
45578+ "klips_debug:pfkey_sendmsg: "
45579+ "shutdown.\n");
45580+ send_sig(SIGPIPE, current, 0);
45581+ SENDERR(EPIPE);
45582+ }
45583+
45584+ if(len < sizeof(struct sadb_msg)) {
45585+ KLIPS_PRINT(debug_pfkey,
45586+ "klips_debug:pfkey_sendmsg: "
45587+ "bogus msg len of %d, too small.\n", (int)len);
45588+ SENDERR(EMSGSIZE);
45589+ }
45590+
45591+ KLIPS_PRINT(debug_pfkey,
45592+ "klips_debug:pfkey_sendmsg: "
45593+ "allocating %d bytes for downward message.\n",
45594+ (int)len);
45595+ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
45596+ KLIPS_PRINT(debug_pfkey,
45597+ "klips_debug:pfkey_sendmsg: "
45598+ "memory allocation error.\n");
45599+ SENDERR(ENOBUFS);
45600+ }
45601+
45602+ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
45603+
45604+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
45605+ KLIPS_PRINT(1 || debug_pfkey,
45606+ "klips_debug:pfkey_sendmsg: "
45607+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
45608+ pfkey_msg->sadb_msg_version,
45609+ PF_KEY_V2);
45610+ kfree((void*)pfkey_msg);
45611+ return -EINVAL;
45612+ }
45613+
45614+ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
45615+ KLIPS_PRINT(debug_pfkey,
45616+ "klips_debug:pfkey_sendmsg: "
45617+ "bogus msg len of %d, not %d byte aligned.\n",
45618+ (int)len, (int)IPSEC_PFKEYv2_ALIGN);
45619+ SENDERR(EMSGSIZE);
45620+ }
45621+
45622+#if 0
45623+ /* This check is questionable, since a downward message could be
45624+ the result of an ACQUIRE either from kernel (PID==0) or
45625+ userspace (some other PID). */
45626+ /* check PID */
45627+ if(pfkey_msg->sadb_msg_pid != current->pid) {
45628+ KLIPS_PRINT(debug_pfkey,
45629+ "klips_debug:pfkey_sendmsg: "
45630+ "pid (%d) does not equal sending process pid (%d).\n",
45631+ pfkey_msg->sadb_msg_pid, current->pid);
45632+ SENDERR(EINVAL);
45633+ }
45634+#endif
45635+
45636+ if(pfkey_msg->sadb_msg_reserved) {
45637+ KLIPS_PRINT(debug_pfkey,
45638+ "klips_debug:pfkey_sendmsg: "
45639+ "reserved field must be zero, set to %d.\n",
45640+ pfkey_msg->sadb_msg_reserved);
45641+ SENDERR(EINVAL);
45642+ }
45643+
45644+ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
45645+ KLIPS_PRINT(debug_pfkey,
45646+ "klips_debug:pfkey_sendmsg: "
45647+ "msg type too large or small:%d.\n",
45648+ pfkey_msg->sadb_msg_type);
45649+ SENDERR(EINVAL);
45650+ }
45651+
45652+ KLIPS_PRINT(debug_pfkey,
45653+ "klips_debug:pfkey_sendmsg: "
45654+ "msg sent for parsing.\n");
45655+
45656+ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
45657+ struct socket_list *pfkey_socketsp;
45658+
45659+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45660+ "pfkey_msg_parse returns %d.\n",
45661+ error);
45662+
45663+ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
45664+ KLIPS_PRINT(debug_pfkey,
45665+ "klips_debug:pfkey_sendmsg: "
45666+ "memory allocation error.\n");
45667+ SENDERR(ENOBUFS);
45668+ }
45669+ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
45670+ pfkey_reply->sadb_msg_errno = -error;
45671+ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
45672+
45673+ for(pfkey_socketsp = pfkey_open_sockets;
45674+ pfkey_socketsp;
45675+ pfkey_socketsp = pfkey_socketsp->next) {
45676+ int error_upmsg = 0;
45677+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45678+ "sending up error=%d message=0p%p to socket=0p%p.\n",
45679+ error,
45680+ pfkey_reply,
45681+ pfkey_socketsp->socketp);
45682+ if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
45683+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45684+ "sending up error message to socket=0p%p failed with error=%d.\n",
45685+ pfkey_socketsp->socketp,
45686+ error_upmsg);
45687+ /* pfkey_msg_free(&pfkey_reply); */
45688+ /* SENDERR(-error); */
45689+ }
45690+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45691+ "sending up error message to socket=0p%p succeeded.\n",
45692+ pfkey_socketsp->socketp);
45693+ }
45694+
45695+ pfkey_msg_free(&pfkey_reply);
45696+
45697+ SENDERR(-error);
45698+ }
45699+
45700+ errlab:
45701+ if (pfkey_msg) {
45702+ kfree((void*)pfkey_msg);
45703+ }
45704+
45705+ if(error) {
45706+ return error;
45707+ } else {
45708+ return len;
45709+ }
45710+}
45711+
45712+/*
45713+ * Receive PF_KEY data up.
45714+ */
45715+
45716+DEBUG_NO_STATIC int
45717+#ifdef NET_26
45718+pfkey_recvmsg(struct kiocb *kiocb
45719+ , struct socket *sock
45720+ , struct msghdr *msg
45721+ , size_t size
45722+ , int flags)
45723+#else
45724+pfkey_recvmsg(struct socket *sock
45725+ , struct msghdr *msg
45726+ , int size, int flags
45727+ , struct scm_cookie *scm)
45728+#endif
45729+{
45730+ struct sock *sk;
45731+ int noblock = flags & MSG_DONTWAIT;
45732+ struct sk_buff *skb;
45733+ int error;
45734+
45735+ if(sock == NULL) {
45736+ KLIPS_PRINT(debug_pfkey,
45737+ "klips_debug:pfkey_recvmsg: "
45738+ "Null socket passed in.\n");
45739+ return -EINVAL;
45740+ }
45741+
45742+ sk = sock->sk;
45743+
45744+ if(sk == NULL) {
45745+ KLIPS_PRINT(debug_pfkey,
45746+ "klips_debug:pfkey_recvmsg: "
45747+ "Null sock passed in for sock=0p%p.\n", sock);
45748+ return -EINVAL;
45749+ }
45750+
45751+ if(msg == NULL) {
45752+ KLIPS_PRINT(debug_pfkey,
45753+ "klips_debug:pfkey_recvmsg: "
45754+ "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
45755+ sock, sk);
45756+ return -EINVAL;
45757+ }
45758+
45759+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
45760+ "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
45761+ sock, sk, msg, (int)size);
45762+ if(flags & ~MSG_PEEK) {
45763+ KLIPS_PRINT(debug_pfkey,
45764+ "klips_debug:pfkey_sendmsg: "
45765+ "flags (%d) other than MSG_PEEK not supported.\n",
45766+ flags);
45767+ return -EOPNOTSUPP;
45768+ }
45769+
45770+ msg->msg_namelen = 0; /* sizeof(*ska); */
45771+
45772+ if(sk->sk_err) {
45773+ KLIPS_PRINT(debug_pfkey,
45774+ "klips_debug:pfkey_sendmsg: "
45775+ "sk->sk_err=%d.\n", sk->sk_err);
45776+ return sock_error(sk);
45777+ }
45778+
45779+ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
45780+ return error;
45781+ }
45782+
45783+ if(size > skb->len) {
45784+ size = skb->len;
45785+ }
45786+ else if(size <skb->len) {
45787+ msg->msg_flags |= MSG_TRUNC;
45788+ }
45789+
45790+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
45791+#ifdef HAVE_TSTAMP
45792+ sk->sk_stamp.tv_sec = skb->tstamp.off_sec;
45793+ sk->sk_stamp.tv_usec = skb->tstamp.off_usec;
45794+#else
45795+ sk->sk_stamp=skb->stamp;
45796+#endif
45797+
45798+ skb_free_datagram(sk, skb);
45799+ return size;
45800+}
45801+
45802+#ifdef CONFIG_PROC_FS
45803+#ifndef PROC_FS_2325
45804+DEBUG_NO_STATIC
45805+#endif /* PROC_FS_2325 */
45806+int
45807+pfkey_get_info(char *buffer, char **start, off_t offset, int length
45808+#ifndef PROC_NO_DUMMY
45809+, int dummy
45810+#endif /* !PROC_NO_DUMMY */
45811+)
45812+{
45813+ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
45814+#ifdef NET_26
45815+ struct hlist_node *node;
45816+#endif
45817+ off_t begin=0;
45818+ int len=0;
45819+ struct sock *sk;
45820+
45821+#ifdef CONFIG_KLIPS_DEBUG
45822+ if(!sysctl_ipsec_debug_verbose) {
45823+#endif /* CONFIG_KLIPS_DEBUG */
45824+ len += ipsec_snprintf(buffer, length,
45825+ " sock pid socket next prev e n p sndbf Flags Type St\n");
45826+#ifdef CONFIG_KLIPS_DEBUG
45827+ } else {
45828+ len += ipsec_snprintf(buffer, length,
45829+ " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
45830+ }
45831+#endif /* CONFIG_KLIPS_DEBUG */
45832+
45833+ sk_for_each(sk, node, &pfkey_sock_list) {
45834+
45835+#ifdef CONFIG_KLIPS_DEBUG
45836+ if(!sysctl_ipsec_debug_verbose) {
45837+#endif /* CONFIG_KLIPS_DEBUG */
45838+ len += ipsec_snprintf(buffer+len, length-len,
45839+ "%8p %5d %8p %d %d %5d %08lX %8X %2X\n",
45840+ sk,
45841+ key_pid(sk),
45842+ sk->sk_socket,
45843+ sk->sk_err,
45844+ sk->sk_protocol,
45845+ sk->sk_sndbuf,
45846+ sk->sk_socket->flags,
45847+ sk->sk_socket->type,
45848+ sk->sk_socket->state);
45849+#ifdef CONFIG_KLIPS_DEBUG
45850+ } else {
45851+ len += ipsec_snprintf(buffer+len, length-len,
45852+ "%8p %5d %d %8p %8p %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
45853+ sk,
45854+ key_pid(sk),
45855+ sock_flag(sk, SOCK_DEAD),
45856+ sk->sk_sleep,
45857+ sk->sk_socket,
45858+ sk->sk_err,
45859+ sk->sk_reuse,
45860+#ifdef HAVE_SOCK_ZAPPED
45861+ sock_flag(sk, SOCK_ZAPPED),
45862+#else
45863+ sk->sk_zapped,
45864+#endif
45865+ sk->sk_protocol,
45866+ sk->sk_sndbuf,
45867+ (unsigned int)sk->sk_stamp.tv_sec,
45868+ (unsigned int)sk->sk_stamp.tv_usec,
45869+ sk->sk_socket->flags,
45870+ sk->sk_socket->type,
45871+ sk->sk_socket->state);
45872+ }
45873+#endif /* CONFIG_KLIPS_DEBUG */
45874+
45875+ if (len >= max_content) {
45876+ /* we've done all that can fit -- stop loop */
45877+ len = max_content; /* truncate crap */
45878+ break;
45879+ } else {
45880+ const off_t pos = begin + len; /* file position of end of what we've generated */
45881+
45882+ if (pos <= offset) {
45883+ /* all is before first interesting character:
45884+ * discard, but note where we are.
45885+ */
45886+ len = 0;
45887+ begin = pos;
45888+ }
45889+ }
45890+ }
45891+
45892+ *start = buffer + (offset - begin); /* Start of wanted data */
45893+ return len - (offset - begin);
45894+}
45895+
45896+#ifndef PROC_FS_2325
45897+DEBUG_NO_STATIC
45898+#endif /* PROC_FS_2325 */
45899+int
45900+pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
45901+#ifndef PROC_NO_DUMMY
45902+, int dummy
45903+#endif /* !PROC_NO_DUMMY */
45904+)
45905+{
45906+ /* limit of useful snprintf output */
45907+ const int max_content = length > 0? length-1 : 0;
45908+ off_t begin=0;
45909+ int len=0;
45910+ int satype;
45911+ struct supported_list *ps;
45912+
45913+ len += ipsec_snprintf(buffer, length,
45914+ "satype exttype alg_id ivlen minbits maxbits name\n");
45915+
45916+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
45917+ ps = pfkey_supported_list[satype];
45918+ while(ps) {
45919+ struct ipsec_alg_supported *alg = ps->supportedp;
45920+ unsigned char *n = alg->ias_name;
45921+ if(n == NULL) n = "unknown";
45922+
45923+ len += ipsec_snprintf(buffer+len, length-len,
45924+ " %2d %2d %2d %3d %3d %3d %20s\n",
45925+ satype,
45926+ alg->ias_exttype,
45927+ alg->ias_id,
45928+ alg->ias_ivlen,
45929+ alg->ias_keyminbits,
45930+ alg->ias_keymaxbits,
45931+ n);
45932+
45933+ if (len >= max_content) {
45934+ /* we've done all that can fit -- stop loop */
45935+ len = max_content; /* truncate crap */
45936+ break;
45937+ } else {
45938+ const off_t pos = begin + len; /* file position of end of what we've generated */
45939+
45940+ if (pos <= offset) {
45941+ /* all is before first interesting character:
45942+ * discard, but note where we are.
45943+ */
45944+ len = 0;
45945+ begin = pos;
45946+ }
45947+ }
45948+
45949+ ps = ps->next;
45950+ }
45951+ }
45952+ *start = buffer + (offset - begin); /* Start of wanted data */
45953+ return len - (offset - begin);
45954+}
45955+
45956+#ifndef PROC_FS_2325
45957+DEBUG_NO_STATIC
45958+#endif /* PROC_FS_2325 */
45959+int
45960+pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
45961+#ifndef PROC_NO_DUMMY
45962+, int dummy
45963+#endif /* !PROC_NO_DUMMY */
45964+)
45965+{
45966+ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
45967+ off_t begin=0;
45968+ int len=0;
45969+ int satype;
45970+ struct socket_list *pfkey_sockets;
45971+
45972+ len += ipsec_snprintf(buffer, length,
45973+ "satype socket pid sk\n");
45974+
45975+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
45976+ pfkey_sockets = pfkey_registered_sockets[satype];
45977+ while(pfkey_sockets) {
45978+ len += ipsec_snprintf(buffer+len, length-len,
45979+ " %2d %8p %5d %8p\n",
45980+ satype,
45981+ pfkey_sockets->socketp,
45982+ key_pid(pfkey_sockets->socketp->sk),
45983+ pfkey_sockets->socketp->sk);
45984+
45985+ if (len >= max_content) {
45986+ /* we've done all that can fit -- stop loop (could stop two) */
45987+ len = max_content; /* truncate crap */
45988+ break;
45989+ } else {
45990+ const off_t pos = begin + len; /* file position of end of what we've generated */
45991+
45992+ if (pos <= offset) {
45993+ /* all is before first interesting character:
45994+ * discard, but note where we are.
45995+ */
45996+ len = 0;
45997+ begin = pos;
45998+ }
45999+ }
46000+
46001+ pfkey_sockets = pfkey_sockets->next;
46002+ }
46003+ }
46004+ *start = buffer + (offset - begin); /* Start of wanted data */
46005+ return len - (offset - begin);
46006+}
46007+
46008+#ifndef PROC_FS_2325
46009+struct proc_dir_entry proc_net_pfkey =
46010+{
46011+ 0,
46012+ 6, "pf_key",
46013+ S_IFREG | S_IRUGO, 1, 0, 0,
46014+ 0, &proc_net_inode_operations,
46015+ pfkey_get_info
46016+};
46017+struct proc_dir_entry proc_net_pfkey_supported =
46018+{
46019+ 0,
46020+ 16, "pf_key_supported",
46021+ S_IFREG | S_IRUGO, 1, 0, 0,
46022+ 0, &proc_net_inode_operations,
46023+ pfkey_supported_get_info
46024+};
46025+struct proc_dir_entry proc_net_pfkey_registered =
46026+{
46027+ 0,
46028+ 17, "pf_key_registered",
46029+ S_IFREG | S_IRUGO, 1, 0, 0,
46030+ 0, &proc_net_inode_operations,
46031+ pfkey_registered_get_info
46032+};
46033+#endif /* !PROC_FS_2325 */
46034+#endif /* CONFIG_PROC_FS */
46035+
46036+DEBUG_NO_STATIC int
46037+supported_add_all(int satype, struct ipsec_alg_supported supported[], int size)
46038+{
46039+ int i;
46040+ int error = 0;
46041+
46042+ KLIPS_PRINT(debug_pfkey,
46043+ "klips_debug:init_pfkey: "
46044+ "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct ipsec_alg_supported)[%d]=%d.\n",
46045+ satype,
46046+ size,
46047+ (int)sizeof(struct ipsec_alg_supported),
46048+ (int)(size/sizeof(struct ipsec_alg_supported)));
46049+
46050+ for(i = 0; i < size / sizeof(struct ipsec_alg_supported); i++) {
46051+
46052+ unsigned char *n = supported[i].ias_name;
46053+ if(n == NULL) n="unknown";
46054+
46055+ KLIPS_PRINT(debug_pfkey,
46056+ "klips_debug:init_pfkey: "
46057+ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
46058+ i,
46059+ satype,
46060+ supported[i].ias_exttype,
46061+ supported[i].ias_id,
46062+ supported[i].ias_ivlen,
46063+ supported[i].ias_keyminbits,
46064+ supported[i].ias_keymaxbits,
46065+ n);
46066+
46067+ error |= pfkey_list_insert_supported(&(supported[i]),
46068+ &(pfkey_supported_list[satype]));
46069+ }
46070+ return error;
46071+}
46072+
46073+DEBUG_NO_STATIC int
46074+supported_remove_all(int satype)
46075+{
46076+ int error = 0;
46077+ struct ipsec_alg_supported*supportedp;
46078+
46079+ while(pfkey_supported_list[satype]) {
46080+ unsigned char *n;
46081+ supportedp = pfkey_supported_list[satype]->supportedp;
46082+
46083+ n = supportedp->ias_name;
46084+ if(n == NULL) n="unknown";
46085+
46086+ KLIPS_PRINT(debug_pfkey,
46087+ "klips_debug:init_pfkey: "
46088+ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
46089+ satype,
46090+ supportedp->ias_exttype,
46091+ supportedp->ias_id,
46092+ supportedp->ias_ivlen,
46093+ supportedp->ias_keyminbits,
46094+ supportedp->ias_keymaxbits, n);
46095+
46096+ error |= pfkey_list_remove_supported(supportedp,
46097+ &(pfkey_supported_list[satype]));
46098+ }
46099+ return error;
46100+}
46101+
46102+int
46103+pfkey_init(void)
46104+{
46105+ int error = 0;
46106+ int i;
46107+
46108+ static struct ipsec_alg_supported supported_init_ah[] = {
46109+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
46110+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
46111+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
46112+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
46113+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
46114+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
46115+ };
46116+ static struct ipsec_alg_supported supported_init_esp[] = {
46117+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
46118+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
46119+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
46120+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
46121+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
46122+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
46123+#ifdef CONFIG_KLIPS_ENC_3DES
46124+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168},
46125+#endif /* CONFIG_KLIPS_ENC_3DES */
46126+ };
46127+ static struct ipsec_alg_supported supported_init_ipip[] = {
46128+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
46129+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
46130+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
46131+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
46132+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
46133+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
46134+ };
46135+#ifdef CONFIG_KLIPS_IPCOMP
46136+ static struct ipsec_alg_supported supported_init_ipcomp[] = {
46137+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
46138+ };
46139+#endif /* CONFIG_KLIPS_IPCOMP */
46140+
46141+#if 0
46142+ printk(KERN_INFO
46143+ "klips_info:pfkey_init: "
46144+ "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
46145+#endif
46146+
46147+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
46148+ pfkey_registered_sockets[i] = NULL;
46149+ pfkey_supported_list[i] = NULL;
46150+ }
46151+
46152+ error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
46153+ error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
46154+#ifdef CONFIG_KLIPS_IPCOMP
46155+ error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
46156+#endif /* CONFIG_KLIPS_IPCOMP */
46157+ error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
46158+
46159+ error |= sock_register(&pfkey_family_ops);
46160+
46161+#ifdef CONFIG_PROC_FS
46162+# ifndef PROC_FS_2325
46163+# ifdef PROC_FS_21
46164+ error |= proc_register(proc_net, &proc_net_pfkey);
46165+ error |= proc_register(proc_net, &proc_net_pfkey_supported);
46166+ error |= proc_register(proc_net, &proc_net_pfkey_registered);
46167+# else /* PROC_FS_21 */
46168+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
46169+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
46170+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
46171+# endif /* PROC_FS_21 */
46172+# else /* !PROC_FS_2325 */
46173+ proc_net_create ("pf_key", 0, pfkey_get_info);
46174+ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
46175+ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
46176+# endif /* !PROC_FS_2325 */
46177+#endif /* CONFIG_PROC_FS */
46178+
46179+ return error;
46180+}
46181+
46182+int
46183+pfkey_cleanup(void)
46184+{
46185+ int error = 0;
46186+
46187+ printk(KERN_INFO "klips_info:pfkey_cleanup: "
46188+ "shutting down PF_KEY domain sockets.\n");
46189+ sock_unregister(PF_KEY);
46190+
46191+ error |= supported_remove_all(SADB_SATYPE_AH);
46192+ error |= supported_remove_all(SADB_SATYPE_ESP);
46193+#ifdef CONFIG_KLIPS_IPCOMP
46194+ error |= supported_remove_all(SADB_X_SATYPE_COMP);
46195+#endif /* CONFIG_KLIPS_IPCOMP */
46196+ error |= supported_remove_all(SADB_X_SATYPE_IPIP);
46197+
46198+#ifdef CONFIG_PROC_FS
46199+# ifndef PROC_FS_2325
46200+ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
46201+ printk("klips_debug:pfkey_cleanup: "
46202+ "cannot unregister /proc/net/pf_key\n");
46203+ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
46204+ printk("klips_debug:pfkey_cleanup: "
46205+ "cannot unregister /proc/net/pf_key_supported\n");
46206+ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
46207+ printk("klips_debug:pfkey_cleanup: "
46208+ "cannot unregister /proc/net/pf_key_registered\n");
46209+# else /* !PROC_FS_2325 */
46210+ proc_net_remove ("pf_key");
46211+ proc_net_remove ("pf_key_supported");
46212+ proc_net_remove ("pf_key_registered");
46213+# endif /* !PROC_FS_2325 */
46214+#endif /* CONFIG_PROC_FS */
46215+
46216+ /* other module unloading cleanup happens here */
46217+ return error;
46218+}
46219+
46220+#ifdef MODULE
46221+#if 0
46222+int
46223+init_module(void)
46224+{
46225+ pfkey_init();
46226+ return 0;
46227+}
46228+
46229+void
46230+cleanup_module(void)
46231+{
46232+ pfkey_cleanup();
46233+}
46234+#endif /* 0 */
46235+#else /* MODULE */
46236+struct net_protocol;
46237+void pfkey_proto_init(struct net_protocol *pro)
46238+{
46239+ pfkey_init();
46240+}
46241+#endif /* MODULE */
46242+
46243+/*
46244+ * $Log: pfkey_v2.c,v $
46245+ * Revision 1.97.2.12 2006/11/24 05:43:29 paul
46246+ * kernels after 2.6.18 do not return a code from unregister_socket()
46247+ * backport from git 41e54a2684dc809d7952e816860ea646a3194a72
46248+ *
46249+ * Revision 1.97.2.11 2006/11/15 16:05:57 paul
46250+ * fix for compiling on 2.4. kernels by Matthias Haas.
46251+ *
46252+ * Revision 1.97.2.10 2006/10/10 20:43:28 paul
46253+ * Add family/create/owner for pfkey_family_ops. This fixes bug #671
46254+ *
46255+ * Revision 1.97.2.9 2006/10/06 21:39:26 paul
46256+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
46257+ * set. This is defined through autoconf.h which is included through the
46258+ * linux kernel build macros.
46259+ *
46260+ * Revision 1.97.2.8 2006/07/10 15:56:11 paul
46261+ * Fix for bug #642 by Bart.
46262+ *
46263+ * Revision 1.97.2.7 2006/04/04 11:34:19 ken
46264+ * Backport SMP fixes + #ifdef cleanup from #public
46265+ *
46266+ * Revision 1.97.2.6 2006/02/15 05:00:20 paul
46267+ * Fix for crasher on 2.6.12+ with klips (mostly seen on redhat kernels)
46268+ *
46269+ * Revision 1.97.2.5 2005/11/22 04:11:52 ken
46270+ * Backport fixes for 2.6.14 kernels from HEAD
46271+ *
46272+ * Revision 1.97.2.4 2005/09/14 16:40:45 mcr
46273+ * pull up of compilation on 2.4
46274+ *
46275+ * Revision 1.97.2.3 2005/09/06 02:10:03 mcr
46276+ * pulled up possible SMP-related compilation fix
46277+ *
46278+ * Revision 1.97.2.2 2005/08/28 01:21:12 paul
46279+ * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on
46280+ * SMP kernels.
46281+ *
46282+ * Revision 1.97.2.1 2005/08/27 23:40:00 paul
46283+ * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
46284+ *
46285+ * Revision 1.102 2005/09/14 16:37:23 mcr
46286+ * fix to compile on 2.4.
46287+ *
46288+ * Revision 1.101 2005/09/06 01:42:25 mcr
46289+ * removed additional SOCKOPS_WRAPPED code
46290+ *
46291+ * Revision 1.100 2005/08/30 18:10:15 mcr
46292+ * remove SOCKOPS_WRAPPED() code, add proper locking to the
46293+ * pfkey code. (cross fingers)
46294+ *
46295+ * Revision 1.99 2005/08/28 01:53:37 paul
46296+ * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on SMP kernels.
46297+ *
46298+ * Revision 1.98 2005/08/27 23:07:21 paul
46299+ * Somewhere between 2.6.12 and 2.6.13rc7 the unused security memnber in sk_buff
46300+ * has been removed. This patch should fix compilation for both cases.
46301+ *
46302+ * Revision 1.97 2005/07/20 00:33:36 mcr
46303+ * fixed typo in #ifdef for SKALLOC.
46304+ *
46305+ * Revision 1.96 2005/07/19 20:02:15 mcr
46306+ * sk_alloc() interface change.
46307+ *
46308+ * Revision 1.95 2005/07/09 00:40:06 ken
46309+ * Fix for GCC4 - it doesn't like the potential for duplicate declaration
46310+ *
46311+ * Revision 1.94 2005/07/09 00:14:04 ken
46312+ * Casts for 64bit cleanliness
46313+ *
46314+ * Revision 1.93 2005/07/08 16:20:05 mcr
46315+ * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
46316+ *
46317+ * Revision 1.92 2005/05/21 03:29:39 mcr
46318+ * fixed missing prototype definition.
46319+ *
46320+ * Revision 1.91 2005/05/11 01:43:45 mcr
46321+ * removed "poor-man"s OOP in favour of proper C structures.
46322+ *
46323+ * Revision 1.90 2005/05/02 18:42:47 mcr
46324+ * fix for cut&paste error with pfkey_v2.c "supported_name"
46325+ *
46326+ * Revision 1.89 2005/05/01 03:12:31 mcr
46327+ * print name if it is available.
46328+ *
46329+ * Revision 1.88 2005/04/29 05:10:22 mcr
46330+ * removed from extraenous includes to make unit testing easier.
46331+ *
46332+ * Revision 1.87 2005/04/15 19:57:10 mcr
46333+ * make sure that address has 0p so that it will
46334+ * sanitized.
46335+ *
46336+ * Revision 1.86 2005/04/08 18:28:36 mcr
46337+ * some minor #ifdef simplification in pursuit of a possible bug.
46338+ *
46339+ * Revision 1.85 2004/12/03 21:25:57 mcr
46340+ * compile time fixes for running on 2.6.
46341+ * still experimental.
46342+ *
46343+ * Revision 1.84 2004/08/17 03:27:23 mcr
46344+ * klips 2.6 edits.
46345+ *
46346+ * Revision 1.83 2004/08/04 15:57:07 mcr
46347+ * moved des .h files to include/des/ *
46348+ * included 2.6 protocol specific things
46349+ * started at NAT-T support, but it will require a kernel patch.
46350+ *
46351+ * Revision 1.82 2004/07/10 19:11:18 mcr
46352+ * CONFIG_IPSEC -> CONFIG_KLIPS.
46353+ *
46354+ * Revision 1.81 2004/04/25 21:23:11 ken
46355+ * Pull in dhr's changes from FreeS/WAN 2.06
46356+ *
46357+ * Revision 1.80 2004/04/06 02:49:26 mcr
46358+ * pullup of algo code from alg-branch.
46359+ *
46360+ * Revision 1.79.4.1 2003/12/22 15:25:52 jjo
46361+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
46362+ *
46363+ * Revision 1.79 2003/10/31 02:27:55 mcr
46364+ * pulled up port-selector patches and sa_id elimination.
46365+ *
46366+ * Revision 1.78.4.1 2003/10/29 01:30:41 mcr
46367+ * elimited "struct sa_id".
46368+ *
46369+ * Revision 1.78 2003/04/03 17:38:09 rgb
46370+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
46371+ *
46372+ * Revision 1.77 2002/10/17 16:49:36 mcr
46373+ * sock->ops should reference the unwrapped options so that
46374+ * we get hacked in locking on SMP systems.
46375+ *
46376+ * Revision 1.76 2002/10/12 23:11:53 dhr
46377+ *
46378+ * [KenB + DHR] more 64-bit cleanup
46379+ *
46380+ * Revision 1.75 2002/09/20 05:01:57 rgb
46381+ * Added memory allocation debugging.
46382+ *
46383+ * Revision 1.74 2002/09/19 02:42:50 mcr
46384+ * do not define the pfkey_ops function for now.
46385+ *
46386+ * Revision 1.73 2002/09/17 17:29:23 mcr
46387+ * #if 0 out some dead code - pfkey_ops is never used as written.
46388+ *
46389+ * Revision 1.72 2002/07/24 18:44:54 rgb
46390+ * Type fiddling to tame ia64 compiler.
46391+ *
46392+ * Revision 1.71 2002/05/23 07:14:11 rgb
46393+ * Cleaned up %p variants to 0p%p for test suite cleanup.
46394+ *
46395+ * Revision 1.70 2002/04/24 07:55:32 mcr
46396+ * #include patches and Makefiles for post-reorg compilation.
46397+ *
46398+ * Revision 1.69 2002/04/24 07:36:33 mcr
46399+ * Moved from ./klips/net/ipsec/pfkey_v2.c,v
46400+ *
46401+ * Revision 1.68 2002/03/08 01:15:17 mcr
46402+ * put some internal structure only debug messages behind
46403+ * && sysctl_ipsec_debug_verbose.
46404+ *
46405+ * Revision 1.67 2002/01/29 17:17:57 mcr
46406+ * moved include of ipsec_param.h to after include of linux/kernel.h
46407+ * otherwise, it seems that some option that is set in ipsec_param.h
46408+ * screws up something subtle in the include path to kernel.h, and
46409+ * it complains on the snprintf() prototype.
46410+ *
46411+ * Revision 1.66 2002/01/29 04:00:54 mcr
46412+ * more excise of kversions.h header.
46413+ *
46414+ * Revision 1.65 2002/01/29 02:13:18 mcr
46415+ * introduction of ipsec_kversion.h means that include of
46416+ * ipsec_param.h must preceed any decisions about what files to
46417+ * include to deal with differences in kernel source.
46418+ *
46419+ * Revision 1.64 2001/11/26 09:23:51 rgb
46420+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
46421+ *
46422+ * Revision 1.61.2.1 2001/09/25 02:28:44 mcr
46423+ * cleaned up includes.
46424+ *
46425+ * Revision 1.63 2001/11/12 19:38:00 rgb
46426+ * Continue trying other sockets even if one fails and return only original
46427+ * error.
46428+ *
46429+ * Revision 1.62 2001/10/18 04:45:22 rgb
46430+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
46431+ * lib/freeswan.h version macros moved to lib/kversions.h.
46432+ * Other compiler directive cleanups.
46433+ *
46434+ * Revision 1.61 2001/09/20 15:32:59 rgb
46435+ * Min/max cleanup.
46436+ *
46437+ * Revision 1.60 2001/06/14 19:35:12 rgb
46438+ * Update copyright date.
46439+ *
46440+ * Revision 1.59 2001/06/13 15:35:48 rgb
46441+ * Fixed #endif comments.
46442+ *
46443+ * Revision 1.58 2001/05/04 16:37:24 rgb
46444+ * Remove erroneous checking of return codes for proc_net_* in 2.4.
46445+ *
46446+ * Revision 1.57 2001/05/03 19:43:36 rgb
46447+ * Initialise error return variable.
46448+ * Check error return codes in startup and shutdown.
46449+ * Standardise on SENDERR() macro.
46450+ *
46451+ * Revision 1.56 2001/04/21 23:05:07 rgb
46452+ * Define out skb->used for 2.4 kernels.
46453+ *
46454+ * Revision 1.55 2001/02/28 05:03:28 rgb
46455+ * Clean up and rationalise startup messages.
46456+ *
46457+ * Revision 1.54 2001/02/27 22:24:55 rgb
46458+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
46459+ * Check for satoa() return codes.
46460+ *
46461+ * Revision 1.53 2001/02/27 06:48:18 rgb
46462+ * Fixed pfkey socket unregister log message to reflect type and function.
46463+ *
46464+ * Revision 1.52 2001/02/26 22:34:38 rgb
46465+ * Fix error return code that was getting overwritten by the error return
46466+ * code of an upmsg.
46467+ *
46468+ * Revision 1.51 2001/01/30 23:42:47 rgb
46469+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
46470+ * and subsequent ADD or UDATE.
46471+ *
46472+ * Revision 1.50 2001/01/23 20:22:59 rgb
46473+ * 2.4 fix to remove removed is_clone member.
46474+ *
46475+ * Revision 1.49 2000/11/06 04:33:47 rgb
46476+ * Changed non-exported functions to DEBUG_NO_STATIC.
46477+ *
46478+ * Revision 1.48 2000/09/29 19:47:41 rgb
46479+ * Update copyright.
46480+ *
46481+ * Revision 1.47 2000/09/22 04:23:04 rgb
46482+ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
46483+ *
46484+ * Revision 1.46 2000/09/21 04:20:44 rgb
46485+ * Fixed array size off-by-one error. (Thanks Svenning!)
46486+ *
46487+ * Revision 1.45 2000/09/20 04:01:26 rgb
46488+ * Changed static functions to DEBUG_NO_STATIC for revealing function names
46489+ * in oopsen.
46490+ *
46491+ * Revision 1.44 2000/09/19 00:33:17 rgb
46492+ * 2.0 fixes.
46493+ *
46494+ * Revision 1.43 2000/09/16 01:28:13 rgb
46495+ * Fixed use of 0 in p format warning.
46496+ *
46497+ * Revision 1.42 2000/09/16 01:09:41 rgb
46498+ * Fixed debug format warning for pointers that was expecting ints.
46499+ *
46500+ * Revision 1.41 2000/09/13 15:54:00 rgb
46501+ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
46502+ * Moved supported algos add and remove to functions.
46503+ *
46504+ * Revision 1.40 2000/09/12 18:49:28 rgb
46505+ * Added IPIP tunnel and IPCOMP register support.
46506+ *
46507+ * Revision 1.39 2000/09/12 03:23:49 rgb
46508+ * Converted #if0 debugs to sysctl.
46509+ * Removed debug_pfkey initialisations that prevented no_debug loading or
46510+ * linking.
46511+ *
46512+ * Revision 1.38 2000/09/09 06:38:02 rgb
46513+ * Return positive errno in pfkey_reply error message.
46514+ *
46515+ * Revision 1.37 2000/09/08 19:19:09 rgb
46516+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
46517+ * Clean-up of long-unused crud...
46518+ * Create pfkey error message on on failure.
46519+ * Give pfkey_list_{insert,remove}_{socket,supported}() some error
46520+ * checking.
46521+ *
46522+ * Revision 1.36 2000/09/01 18:49:38 rgb
46523+ * Reap experimental NET_21_ bits.
46524+ * Turned registered sockets list into an array of one list per satype.
46525+ * Remove references to deprecated sklist_{insert,remove}_socket.
46526+ * Removed leaking socket debugging code.
46527+ * Removed duplicate pfkey_insert_socket in pfkey_create.
46528+ * Removed all references to pfkey msg->msg_name, since it is not used for
46529+ * pfkey.
46530+ * Added a supported algorithms array lists, one per satype and registered
46531+ * existing algorithms.
46532+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
46533+ * list.
46534+ * Only send pfkey_expire() messages to sockets registered for that satype.
46535+ *
46536+ * Revision 1.35 2000/08/24 17:03:00 rgb
46537+ * Corrected message size error return code for PF_KEYv2.
46538+ * Removed downward error prohibition.
46539+ *
46540+ * Revision 1.34 2000/08/21 16:32:26 rgb
46541+ * Re-formatted for cosmetic consistency and readability.
46542+ *
46543+ * Revision 1.33 2000/08/20 21:38:24 rgb
46544+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
46545+ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
46546+ *
46547+ * Revision 1.32 2000/07/28 14:58:31 rgb
46548+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
46549+ *
46550+ * Revision 1.31 2000/05/16 03:04:00 rgb
46551+ * Updates for 2.3.99pre8 from MB.
46552+ *
46553+ * Revision 1.30 2000/05/10 19:22:21 rgb
46554+ * Use sklist private functions for 2.3.xx compatibility.
46555+ *
46556+ * Revision 1.29 2000/03/22 16:17:03 rgb
46557+ * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
46558+ *
46559+ * Revision 1.28 2000/02/21 19:30:45 rgb
46560+ * Removed references to pkt_bridged for 2.3.47 compatibility.
46561+ *
46562+ * Revision 1.27 2000/02/14 21:07:00 rgb
46563+ * Fixed /proc/net/pf-key legend spacing.
46564+ *
46565+ * Revision 1.26 2000/01/22 03:46:59 rgb
46566+ * Fixed pfkey error return mechanism so that we are able to free the
46567+ * local copy of the pfkey_msg, plugging a memory leak and silencing
46568+ * the bad object free complaints.
46569+ *
46570+ * Revision 1.25 2000/01/21 06:19:44 rgb
46571+ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
46572+ * Added debugging to pfkey_upmsg.
46573+ *
46574+ * Revision 1.24 2000/01/10 16:38:23 rgb
46575+ * MB fixups for 2.3.x.
46576+ *
46577+ * Revision 1.23 1999/12/09 23:22:16 rgb
46578+ * Added more instrumentation for debugging 2.0 socket
46579+ * selection/reading.
46580+ * Removed erroneous 2.0 wait==NULL check bug in select.
46581+ *
46582+ * Revision 1.22 1999/12/08 20:32:16 rgb
46583+ * Tidied up 2.0.xx support, after major pfkey work, eliminating
46584+ * msg->msg_name twiddling in the process, since it is not defined
46585+ * for PF_KEYv2.
46586+ *
46587+ * Revision 1.21 1999/12/01 22:17:19 rgb
46588+ * Set skb->dev to zero on new skb in case it is a reused skb.
46589+ * Added check for skb_put overflow and freeing to avoid upmsg on error.
46590+ * Added check for wrong pfkey version and freeing to avoid upmsg on
46591+ * error.
46592+ * Shut off content dumping in pfkey_destroy.
46593+ * Added debugging message for size of buffer allocated for upmsg.
46594+ *
46595+ * Revision 1.20 1999/11/27 12:11:00 rgb
46596+ * Minor clean-up, enabling quiet operation of pfkey if desired.
46597+ *
46598+ * Revision 1.19 1999/11/25 19:04:21 rgb
46599+ * Update proc_fs code for pfkey to use dynamic registration.
46600+ *
46601+ * Revision 1.18 1999/11/25 09:07:17 rgb
46602+ * Implemented SENDERR macro for propagating error codes.
46603+ * Fixed error return code bug.
46604+ *
46605+ * Revision 1.17 1999/11/23 23:07:20 rgb
46606+ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
46607+ * parses. (PJO)
46608+ * Sort out pfkey and freeswan headers, putting them in a library path.
46609+ *
46610+ * Revision 1.16 1999/11/20 22:00:22 rgb
46611+ * Moved socketlist type declarations and prototypes for shared use.
46612+ * Renamed reformatted and generically extended for use by other socket
46613+ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
46614+ *
46615+ * Revision 1.15 1999/11/18 04:15:09 rgb
46616+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
46617+ * Clean up pfkey_destroy_socket() debugging statements.
46618+ * Add Peter Onion's code to send messages up to all listening sockets.
46619+ * Changed all occurrences of #include "../../../lib/freeswan.h"
46620+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
46621+ * klips/net/ipsec/Makefile.
46622+ * Replaced all kernel version macros to shorter, readable form.
46623+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
46624+ *
46625+ * Revision 1.14 1999/11/17 16:01:00 rgb
46626+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
46627+ * Clean up pfkey_destroy_socket() debugging statements.
46628+ * Add Peter Onion's code to send messages up to all listening sockets.
46629+ * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
46630+ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
46631+ *
46632+ * Revision 1.13 1999/10/27 19:59:51 rgb
46633+ * Removed af_unix comments that are no longer relevant.
46634+ * Added debug prink statements.
46635+ * Added to the /proc output in pfkey_get_info.
46636+ * Made most functions non-static to enable oops tracing.
46637+ * Re-enable skb dequeueing and freeing.
46638+ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
46639+ *
46640+ * Revision 1.12 1999/10/26 17:05:42 rgb
46641+ * Complete re-ordering based on proto_ops structure order.
46642+ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
46643+ * Simplification to use built-in socket ops where possible for 2.2.x.
46644+ * Add shorter macros for compiler directives to visually clean-up.
46645+ * Add lots of sk skb dequeueing debugging statements.
46646+ * Added to the /proc output in pfkey_get_info.
46647+ *
46648+ * Revision 1.11 1999/09/30 02:55:10 rgb
46649+ * Bogus skb detection.
46650+ * Fix incorrect /proc/net/ipsec-eroute printk message.
46651+ *
46652+ * Revision 1.10 1999/09/21 15:22:13 rgb
46653+ * Temporary fix while I figure out the right way to destroy sockets.
46654+ *
46655+ * Revision 1.9 1999/07/08 19:19:44 rgb
46656+ * Fix pointer format warning.
46657+ * Fix missing member error under 2.0.xx kernels.
46658+ *
46659+ * Revision 1.8 1999/06/13 07:24:04 rgb
46660+ * Add more debugging.
46661+ *
46662+ * Revision 1.7 1999/06/10 05:24:17 rgb
46663+ * Clarified compiler directives.
46664+ * Renamed variables to reduce confusion.
46665+ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
46666+ * Added lots of sanity checking.
46667+ *
46668+ * Revision 1.6 1999/06/03 18:59:50 rgb
46669+ * More updates to 2.2.x socket support. Almost works, oops at end of call.
46670+ *
46671+ * Revision 1.5 1999/05/25 22:44:05 rgb
46672+ * Start fixing 2.2 sockets.
46673+ *
46674+ * Revision 1.4 1999/04/29 15:21:34 rgb
46675+ * Move log to the end of the file.
46676+ * Eliminate min/max redefinition in #include <net/tcp.h>.
46677+ * Correct path for pfkey #includes
46678+ * Standardise an error return method.
46679+ * Add debugging instrumentation.
46680+ * Move message type checking to pfkey_msg_parse().
46681+ * Add check for errno incorrectly set.
46682+ * Add check for valid PID.
46683+ * Add check for reserved illegally set.
46684+ * Add check for message out of bounds.
46685+ *
46686+ * Revision 1.3 1999/04/15 17:58:07 rgb
46687+ * Add RCSID labels.
46688+ *
46689+ * Revision 1.2 1999/04/15 15:37:26 rgb
46690+ * Forward check changes from POST1_00 branch.
46691+ *
46692+ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
46693+ * Header Title correction.
46694+ *
46695+ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
46696+ * Add pfkeyv2 support to KLIPS.
46697+ *
46698+ *
46699+ * RFC 2367
46700+ * PF_KEY_v2 Key Management API
46701+ */
46702--- /dev/null Tue Mar 11 13:02:56 2003
46703+++ linux/net/ipsec/pfkey_v2_build.c Mon Feb 9 13:51:03 2004
46704@@ -0,0 +1,1581 @@
46705+/*
46706+ * RFC2367 PF_KEYv2 Key management API message parser
46707+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
46708+ *
46709+ * This program is free software; you can redistribute it and/or modify it
46710+ * under the terms of the GNU General Public License as published by the
46711+ * Free Software Foundation; either version 2 of the License, or (at your
46712+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
46713+ *
46714+ * This program is distributed in the hope that it will be useful, but
46715+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
46716+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
46717+ * for more details.
46718+ *
46719+ * RCSID $Id: pfkey_v2_build.c,v 1.51.8.1 2006/05/01 14:36:39 mcr Exp $
46720+ */
46721+
46722+/*
46723+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
46724+ */
46725+
46726+char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.51.8.1 2006/05/01 14:36:39 mcr Exp $";
46727+
46728+/*
46729+ * Some ugly stuff to allow consistent debugging code for use in the
46730+ * kernel and in user space
46731+*/
46732+
46733+#ifdef __KERNEL__
46734+
46735+# include <linux/kernel.h> /* for printk */
46736+
46737+# include "openswan/ipsec_kversion.h" /* for malloc switch */
46738+# ifdef MALLOC_SLAB
46739+# include <linux/slab.h> /* kmalloc() */
46740+# else /* MALLOC_SLAB */
46741+# include <linux/malloc.h> /* kmalloc() */
46742+# endif /* MALLOC_SLAB */
46743+# include <linux/errno.h> /* error codes */
46744+# include <linux/types.h> /* size_t */
46745+# include <linux/interrupt.h> /* mark_bh */
46746+
46747+# include <linux/netdevice.h> /* struct device, and other headers */
46748+# include <linux/etherdevice.h> /* eth_type_trans */
46749+# include <linux/ip.h> /* struct iphdr */
46750+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
46751+# include <linux/ipv6.h> /* struct ipv6hdr */
46752+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
46753+
46754+# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
46755+# define FREE(obj) kfree(obj)
46756+# include <openswan.h>
46757+#else /* __KERNEL__ */
46758+
46759+# include <sys/types.h>
46760+# include <linux/types.h>
46761+# include <linux/errno.h>
46762+# include <malloc.h>
46763+# include <string.h> /* memset */
46764+
46765+# include <openswan.h>
46766+
46767+#endif /* __KERNEL__ */
46768+
46769+#include <pfkeyv2.h>
46770+#include <pfkey.h>
46771+
46772+#ifdef __KERNEL__
46773+#include "openswan/radij.h" /* rd_nodes */
46774+#include "openswan/ipsec_encap.h" /* sockaddr_encap */
46775+#endif /* __KERNEL__ */
46776+
46777+
46778+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
46779+#include "openswan/pfkey_debug.h"
46780+
46781+
46782+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
46783+
46784+void
46785+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
46786+{
46787+ int i;
46788+
46789+ for (i = 0; i != SADB_EXT_MAX + 1; i++) {
46790+ extensions[i] = NULL;
46791+ }
46792+}
46793+
46794+void
46795+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
46796+{
46797+ int i;
46798+
46799+ if(!extensions) {
46800+ return;
46801+ }
46802+
46803+ if(extensions[0]) {
46804+ memset(extensions[0], 0, sizeof(struct sadb_msg));
46805+ FREE(extensions[0]);
46806+ extensions[0] = NULL;
46807+ }
46808+
46809+ for (i = 1; i != SADB_EXT_MAX + 1; i++) {
46810+ if(extensions[i]) {
46811+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
46812+ FREE(extensions[i]);
46813+ extensions[i] = NULL;
46814+ }
46815+ }
46816+}
46817+
46818+void
46819+pfkey_msg_free(struct sadb_msg **pfkey_msg)
46820+{
46821+ if(*pfkey_msg) {
46822+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
46823+ FREE(*pfkey_msg);
46824+ *pfkey_msg = NULL;
46825+ }
46826+}
46827+
46828+/* Default extension builders taken from the KLIPS code */
46829+
46830+int
46831+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
46832+ uint8_t msg_type,
46833+ uint8_t satype,
46834+ uint8_t msg_errno,
46835+ uint32_t seq,
46836+ uint32_t pid)
46837+{
46838+ int error = 0;
46839+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
46840+
46841+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46842+ "pfkey_msg_hdr_build:\n");
46843+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46844+ "pfkey_msg_hdr_build: "
46845+ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
46846+ &pfkey_ext,
46847+ pfkey_ext,
46848+ *pfkey_ext);
46849+ /* sanity checks... */
46850+ if(pfkey_msg) {
46851+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46852+ "pfkey_msg_hdr_build: "
46853+ "why is pfkey_msg already pointing to something?\n");
46854+ SENDERR(EINVAL);
46855+ }
46856+
46857+ if(!msg_type) {
46858+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46859+ "pfkey_msg_hdr_build: "
46860+ "msg type not set, must be non-zero..\n");
46861+ SENDERR(EINVAL);
46862+ }
46863+
46864+ if(msg_type > SADB_MAX) {
46865+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46866+ "pfkey_msg_hdr_build: "
46867+ "msg type too large:%d.\n",
46868+ msg_type);
46869+ SENDERR(EINVAL);
46870+ }
46871+
46872+ if(satype > SADB_SATYPE_MAX) {
46873+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46874+ "pfkey_msg_hdr_build: "
46875+ "satype %d > max %d\n",
46876+ satype, SADB_SATYPE_MAX);
46877+ SENDERR(EINVAL);
46878+ }
46879+
46880+ pfkey_msg = (struct sadb_msg*)MALLOC(sizeof(struct sadb_msg));
46881+ *pfkey_ext = (struct sadb_ext*)pfkey_msg;
46882+
46883+ if(pfkey_msg == NULL) {
46884+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46885+ "pfkey_msg_hdr_build: "
46886+ "memory allocation failed\n");
46887+ SENDERR(ENOMEM);
46888+ }
46889+ memset(pfkey_msg, 0, sizeof(struct sadb_msg));
46890+
46891+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
46892+
46893+ pfkey_msg->sadb_msg_type = msg_type;
46894+ pfkey_msg->sadb_msg_satype = satype;
46895+
46896+ pfkey_msg->sadb_msg_version = PF_KEY_V2;
46897+ pfkey_msg->sadb_msg_errno = msg_errno;
46898+ pfkey_msg->sadb_msg_reserved = 0;
46899+ pfkey_msg->sadb_msg_seq = seq;
46900+ pfkey_msg->sadb_msg_pid = pid;
46901+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46902+ "pfkey_msg_hdr_build: "
46903+ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
46904+ &pfkey_ext,
46905+ pfkey_ext,
46906+ *pfkey_ext);
46907+errlab:
46908+ return error;
46909+}
46910+
46911+int
46912+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
46913+ uint16_t exttype,
46914+ uint32_t spi,
46915+ uint8_t replay_window,
46916+ uint8_t sa_state,
46917+ uint8_t auth,
46918+ uint8_t encrypt,
46919+ uint32_t flags,
46920+ uint32_t/*IPsecSAref_t*/ ref)
46921+{
46922+ int error = 0;
46923+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
46924+
46925+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46926+ "pfkey_sa_build: "
46927+ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
46928+ ntohl(spi), /* in network order */
46929+ replay_window,
46930+ sa_state,
46931+ auth,
46932+ encrypt,
46933+ flags);
46934+ /* sanity checks... */
46935+ if(pfkey_sa) {
46936+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46937+ "pfkey_sa_build: "
46938+ "why is pfkey_sa already pointing to something?\n");
46939+ SENDERR(EINVAL);
46940+ }
46941+
46942+ if(exttype != SADB_EXT_SA &&
46943+ exttype != SADB_X_EXT_SA2) {
46944+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46945+ "pfkey_sa_build: "
46946+ "invalid exttype=%d.\n",
46947+ exttype);
46948+ SENDERR(EINVAL);
46949+ }
46950+
46951+ if(replay_window > 64) {
46952+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46953+ "pfkey_sa_build: "
46954+ "replay window size: %d -- must be 0 <= size <= 64\n",
46955+ replay_window);
46956+ SENDERR(EINVAL);
46957+ }
46958+
46959+ if(auth > SADB_AALG_MAX) {
46960+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46961+ "pfkey_sa_build: "
46962+ "auth=%d > SADB_AALG_MAX=%d.\n",
46963+ auth,
46964+ SADB_AALG_MAX);
46965+ SENDERR(EINVAL);
46966+ }
46967+
46968+#if SADB_EALG_MAX < 255
46969+ if(encrypt > SADB_EALG_MAX) {
46970+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46971+ "pfkey_sa_build: "
46972+ "encrypt=%d > SADB_EALG_MAX=%d.\n",
46973+ encrypt,
46974+ SADB_EALG_MAX);
46975+ SENDERR(EINVAL);
46976+ }
46977+#endif
46978+
46979+ if(sa_state > SADB_SASTATE_MAX) {
46980+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46981+ "pfkey_sa_build: "
46982+ "sa_state=%d exceeds MAX=%d.\n",
46983+ sa_state,
46984+ SADB_SASTATE_MAX);
46985+ SENDERR(EINVAL);
46986+ }
46987+
46988+ if(sa_state == SADB_SASTATE_DEAD) {
46989+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46990+ "pfkey_sa_build: "
46991+ "sa_state=%d is DEAD=%d is not allowed.\n",
46992+ sa_state,
46993+ SADB_SASTATE_DEAD);
46994+ SENDERR(EINVAL);
46995+ }
46996+
46997+ if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
46998+ DEBUGGING(PF_KEY_DEBUG_BUILD,
46999+ "pfkey_sa_build: "
47000+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
47001+ ref,
47002+ IPSEC_SAREF_NULL,
47003+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
47004+ SENDERR(EINVAL);
47005+ }
47006+
47007+ pfkey_sa = (struct sadb_sa*)MALLOC(sizeof(struct sadb_sa));
47008+ *pfkey_ext = (struct sadb_ext*)pfkey_sa;
47009+
47010+ if(pfkey_sa == NULL) {
47011+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47012+ "pfkey_sa_build: "
47013+ "memory allocation failed\n");
47014+ SENDERR(ENOMEM);
47015+ }
47016+ memset(pfkey_sa, 0, sizeof(struct sadb_sa));
47017+
47018+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
47019+ pfkey_sa->sadb_sa_exttype = exttype;
47020+ pfkey_sa->sadb_sa_spi = spi;
47021+ pfkey_sa->sadb_sa_replay = replay_window;
47022+ pfkey_sa->sadb_sa_state = sa_state;
47023+ pfkey_sa->sadb_sa_auth = auth;
47024+ pfkey_sa->sadb_sa_encrypt = encrypt;
47025+ pfkey_sa->sadb_sa_flags = flags;
47026+ pfkey_sa->sadb_x_sa_ref = ref;
47027+
47028+errlab:
47029+ return error;
47030+}
47031+
47032+int
47033+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
47034+ uint16_t exttype,
47035+ uint32_t spi,
47036+ uint8_t replay_window,
47037+ uint8_t sa_state,
47038+ uint8_t auth,
47039+ uint8_t encrypt,
47040+ uint32_t flags)
47041+{
47042+ return pfkey_sa_ref_build(pfkey_ext,
47043+ exttype,
47044+ spi,
47045+ replay_window,
47046+ sa_state,
47047+ auth,
47048+ encrypt,
47049+ flags,
47050+ IPSEC_SAREF_NULL);
47051+}
47052+
47053+int
47054+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
47055+ uint16_t exttype,
47056+ uint32_t allocations,
47057+ uint64_t bytes,
47058+ uint64_t addtime,
47059+ uint64_t usetime,
47060+ uint32_t packets)
47061+{
47062+ int error = 0;
47063+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
47064+
47065+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47066+ "pfkey_lifetime_build:\n");
47067+ /* sanity checks... */
47068+ if(pfkey_lifetime) {
47069+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47070+ "pfkey_lifetime_build: "
47071+ "why is pfkey_lifetime already pointing to something?\n");
47072+ SENDERR(EINVAL);
47073+ }
47074+
47075+ if(exttype != SADB_EXT_LIFETIME_CURRENT &&
47076+ exttype != SADB_EXT_LIFETIME_HARD &&
47077+ exttype != SADB_EXT_LIFETIME_SOFT) {
47078+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47079+ "pfkey_lifetime_build: "
47080+ "invalid exttype=%d.\n",
47081+ exttype);
47082+ SENDERR(EINVAL);
47083+ }
47084+
47085+ pfkey_lifetime = (struct sadb_lifetime*)MALLOC(sizeof(struct sadb_lifetime));
47086+ *pfkey_ext = (struct sadb_ext*) pfkey_lifetime;
47087+
47088+ if(pfkey_lifetime == NULL) {
47089+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47090+ "pfkey_lifetime_build: "
47091+ "memory allocation failed\n");
47092+ SENDERR(ENOMEM);
47093+ }
47094+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
47095+
47096+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
47097+ pfkey_lifetime->sadb_lifetime_exttype = exttype;
47098+ pfkey_lifetime->sadb_lifetime_allocations = allocations;
47099+ pfkey_lifetime->sadb_lifetime_bytes = bytes;
47100+ pfkey_lifetime->sadb_lifetime_addtime = addtime;
47101+ pfkey_lifetime->sadb_lifetime_usetime = usetime;
47102+ pfkey_lifetime->sadb_x_lifetime_packets = packets;
47103+
47104+errlab:
47105+ return error;
47106+}
47107+
47108+int
47109+pfkey_address_build(struct sadb_ext** pfkey_ext,
47110+ uint16_t exttype,
47111+ uint8_t proto,
47112+ uint8_t prefixlen,
47113+ struct sockaddr* address)
47114+{
47115+ int error = 0;
47116+ int saddr_len = 0;
47117+ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
47118+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
47119+
47120+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47121+ "pfkey_address_build: "
47122+ "exttype=%d proto=%d prefixlen=%d\n",
47123+ exttype,
47124+ proto,
47125+ prefixlen);
47126+ /* sanity checks... */
47127+ if(pfkey_address) {
47128+ ERROR("pfkey_address_build: "
47129+ "why is pfkey_address already pointing to something?\n");
47130+ SENDERR(EINVAL);
47131+ }
47132+
47133+ if (!address) {
47134+ ERROR("pfkey_address_build: " "address is NULL\n");
47135+ SENDERR(EINVAL);
47136+ }
47137+
47138+ switch(exttype) {
47139+ case SADB_EXT_ADDRESS_SRC:
47140+ case SADB_EXT_ADDRESS_DST:
47141+ case SADB_EXT_ADDRESS_PROXY:
47142+ case SADB_X_EXT_ADDRESS_DST2:
47143+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
47144+ case SADB_X_EXT_ADDRESS_DST_FLOW:
47145+ case SADB_X_EXT_ADDRESS_SRC_MASK:
47146+ case SADB_X_EXT_ADDRESS_DST_MASK:
47147+#ifdef NAT_TRAVERSAL
47148+ case SADB_X_EXT_NAT_T_OA:
47149+#endif
47150+ break;
47151+ default:
47152+ ERROR("pfkey_address_build: "
47153+ "unrecognised ext_type=%d.\n",
47154+ exttype);
47155+ SENDERR(EINVAL);
47156+ }
47157+
47158+ switch(address->sa_family) {
47159+ case AF_INET:
47160+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47161+ "pfkey_address_build: "
47162+ "found address family AF_INET.\n");
47163+ saddr_len = sizeof(struct sockaddr_in);
47164+ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
47165+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
47166+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
47167+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
47168+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
47169+ , ntohs(((struct sockaddr_in*)address)->sin_port));
47170+ break;
47171+ case AF_INET6:
47172+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47173+ "pfkey_address_build: "
47174+ "found address family AF_INET6.\n");
47175+ saddr_len = sizeof(struct sockaddr_in6);
47176+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
47177+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
47178+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
47179+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
47180+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
47181+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
47182+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
47183+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
47184+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
47185+ , ntohs(((struct sockaddr_in6*)address)->sin6_port));
47186+ break;
47187+ default:
47188+ ERROR("pfkey_address_build: "
47189+ "address->sa_family=%d not supported.\n",
47190+ address->sa_family);
47191+ SENDERR(EPFNOSUPPORT);
47192+ }
47193+
47194+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47195+ "pfkey_address_build: "
47196+ "found address=%s.\n",
47197+ ipaddr_txt);
47198+ if(prefixlen != 0) {
47199+ ERROR("pfkey_address_build: "
47200+ "address prefixes not supported yet.\n");
47201+ SENDERR(EAFNOSUPPORT); /* not supported yet */
47202+ }
47203+
47204+ /* allocate some memory for the extension */
47205+ pfkey_address = (struct sadb_address*)
47206+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
47207+ *pfkey_ext = (struct sadb_ext*)pfkey_address;
47208+
47209+ if(pfkey_address == NULL ) {
47210+ ERROR("pfkey_lifetime_build: "
47211+ "memory allocation failed\n");
47212+ SENDERR(ENOMEM);
47213+ }
47214+ memset(pfkey_address,
47215+ 0,
47216+ ALIGN_N(sizeof(struct sadb_address) + saddr_len,
47217+ IPSEC_PFKEYv2_ALIGN));
47218+
47219+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
47220+ IPSEC_PFKEYv2_ALIGN);
47221+
47222+ pfkey_address->sadb_address_exttype = exttype;
47223+ pfkey_address->sadb_address_proto = proto;
47224+ pfkey_address->sadb_address_prefixlen = prefixlen;
47225+ pfkey_address->sadb_address_reserved = 0;
47226+
47227+ memcpy((char*)pfkey_address + sizeof(struct sadb_address),
47228+ address,
47229+ saddr_len);
47230+
47231+#if 0
47232+ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
47233+ pfkey_address_s_ska.sin_zero[i] = 0;
47234+ }
47235+#endif
47236+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47237+ "pfkey_address_build: "
47238+ "successful created len: %d.\n", pfkey_address->sadb_address_len);
47239+
47240+ errlab:
47241+ return error;
47242+}
47243+
47244+int
47245+pfkey_key_build(struct sadb_ext** pfkey_ext,
47246+ uint16_t exttype,
47247+ uint16_t key_bits,
47248+ char* key)
47249+{
47250+ int error = 0;
47251+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
47252+
47253+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47254+ "pfkey_key_build:\n");
47255+ /* sanity checks... */
47256+ if(pfkey_key) {
47257+ ERROR("pfkey_key_build: "
47258+ "why is pfkey_key already pointing to something?\n");
47259+ SENDERR(EINVAL);
47260+ }
47261+
47262+ if(!key_bits) {
47263+ ERROR("pfkey_key_build: "
47264+ "key_bits is zero, it must be non-zero.\n");
47265+ SENDERR(EINVAL);
47266+ }
47267+
47268+ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
47269+ ERROR("pfkey_key_build: "
47270+ "unsupported extension type=%d.\n",
47271+ exttype);
47272+ SENDERR(EINVAL);
47273+ }
47274+
47275+ pfkey_key = (struct sadb_key*)
47276+ MALLOC(sizeof(struct sadb_key) +
47277+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
47278+
47279+ *pfkey_ext = (struct sadb_ext*)pfkey_key;
47280+
47281+ if(pfkey_key == NULL) {
47282+ ERROR("pfkey_key_build: "
47283+ "memory allocation failed\n");
47284+ SENDERR(ENOMEM);
47285+ }
47286+ memset(pfkey_key,
47287+ 0,
47288+ sizeof(struct sadb_key) +
47289+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
47290+
47291+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
47292+ 64);
47293+ pfkey_key->sadb_key_exttype = exttype;
47294+ pfkey_key->sadb_key_bits = key_bits;
47295+ pfkey_key->sadb_key_reserved = 0;
47296+ memcpy((char*)pfkey_key + sizeof(struct sadb_key),
47297+ key,
47298+ DIVUP(key_bits, 8));
47299+
47300+errlab:
47301+ return error;
47302+}
47303+
47304+int
47305+pfkey_ident_build(struct sadb_ext** pfkey_ext,
47306+ uint16_t exttype,
47307+ uint16_t ident_type,
47308+ uint64_t ident_id,
47309+ uint8_t ident_len,
47310+ char* ident_string)
47311+{
47312+ int error = 0;
47313+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
47314+ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
47315+
47316+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47317+ "pfkey_ident_build:\n");
47318+ /* sanity checks... */
47319+ if(pfkey_ident) {
47320+ ERROR("pfkey_ident_build: "
47321+ "why is pfkey_ident already pointing to something?\n");
47322+ SENDERR(EINVAL);
47323+ }
47324+
47325+ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
47326+ (exttype == SADB_EXT_IDENTITY_DST))) {
47327+ ERROR("pfkey_ident_build: "
47328+ "unsupported extension type=%d.\n",
47329+ exttype);
47330+ SENDERR(EINVAL);
47331+ }
47332+
47333+ if((ident_type == SADB_IDENTTYPE_RESERVED)) {
47334+ ERROR("pfkey_ident_build: "
47335+ "ident_type must be non-zero.\n");
47336+ SENDERR(EINVAL);
47337+ }
47338+
47339+ if(ident_type > SADB_IDENTTYPE_MAX) {
47340+ ERROR("pfkey_ident_build: "
47341+ "identtype=%d out of range.\n",
47342+ ident_type);
47343+ SENDERR(EINVAL);
47344+ }
47345+
47346+ if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
47347+ (ident_type == SADB_IDENTTYPE_FQDN)) &&
47348+ !ident_string) {
47349+ ERROR("pfkey_ident_build: "
47350+ "string required to allocate size of extension.\n");
47351+ SENDERR(EINVAL);
47352+ }
47353+
47354+#if 0
47355+ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
47356+ }
47357+#endif
47358+
47359+ pfkey_ident = (struct sadb_ident*)
47360+ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
47361+
47362+ *pfkey_ext = (struct sadb_ext*)pfkey_ident;
47363+
47364+ if(pfkey_ident == NULL) {
47365+ ERROR("pfkey_ident_build: "
47366+ "memory allocation failed\n");
47367+ SENDERR(ENOMEM);
47368+ }
47369+ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
47370+
47371+ pfkey_ident->sadb_ident_len = ident_len;
47372+ pfkey_ident->sadb_ident_exttype = exttype;
47373+ pfkey_ident->sadb_ident_type = ident_type;
47374+ pfkey_ident->sadb_ident_reserved = 0;
47375+ pfkey_ident->sadb_ident_id = ident_id;
47376+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
47377+ ident_string,
47378+ data_len);
47379+
47380+errlab:
47381+ return error;
47382+}
47383+
47384+int
47385+pfkey_sens_build(struct sadb_ext** pfkey_ext,
47386+ uint32_t dpd,
47387+ uint8_t sens_level,
47388+ uint8_t sens_len,
47389+ uint64_t* sens_bitmap,
47390+ uint8_t integ_level,
47391+ uint8_t integ_len,
47392+ uint64_t* integ_bitmap)
47393+{
47394+ int error = 0;
47395+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
47396+ int i;
47397+ uint64_t* bitmap;
47398+
47399+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47400+ "pfkey_sens_build:\n");
47401+ /* sanity checks... */
47402+ if(pfkey_sens) {
47403+ ERROR("pfkey_sens_build: "
47404+ "why is pfkey_sens already pointing to something?\n");
47405+ SENDERR(EINVAL);
47406+ }
47407+
47408+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47409+ "pfkey_sens_build: "
47410+ "Sorry, I can't build exttype=%d yet.\n",
47411+ (*pfkey_ext)->sadb_ext_type);
47412+ SENDERR(EINVAL); /* don't process these yet */
47413+
47414+ pfkey_sens = (struct sadb_sens*)
47415+ MALLOC(sizeof(struct sadb_sens) +
47416+ (sens_len + integ_len) * sizeof(uint64_t));
47417+
47418+ *pfkey_ext = (struct sadb_ext*)pfkey_sens;
47419+
47420+ if(pfkey_sens == NULL) {
47421+ ERROR("pfkey_sens_build: "
47422+ "memory allocation failed\n");
47423+ SENDERR(ENOMEM);
47424+ }
47425+ memset(pfkey_sens,
47426+ 0,
47427+ sizeof(struct sadb_sens) +
47428+ (sens_len + integ_len) * sizeof(uint64_t));
47429+
47430+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
47431+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
47432+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
47433+ pfkey_sens->sadb_sens_dpd = dpd;
47434+ pfkey_sens->sadb_sens_sens_level = sens_level;
47435+ pfkey_sens->sadb_sens_sens_len = sens_len;
47436+ pfkey_sens->sadb_sens_integ_level = integ_level;
47437+ pfkey_sens->sadb_sens_integ_len = integ_len;
47438+ pfkey_sens->sadb_sens_reserved = 0;
47439+
47440+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
47441+ for(i = 0; i < sens_len; i++) {
47442+ *bitmap = sens_bitmap[i];
47443+ bitmap++;
47444+ }
47445+ for(i = 0; i < integ_len; i++) {
47446+ *bitmap = integ_bitmap[i];
47447+ bitmap++;
47448+ }
47449+
47450+errlab:
47451+ return error;
47452+}
47453+
47454+int
47455+pfkey_prop_build(struct sadb_ext** pfkey_ext,
47456+ uint8_t replay,
47457+ unsigned int comb_num,
47458+ struct sadb_comb* comb)
47459+{
47460+ int error = 0;
47461+ int i;
47462+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
47463+ struct sadb_comb *combp;
47464+
47465+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47466+ "pfkey_prop_build:\n");
47467+ /* sanity checks... */
47468+ if(pfkey_prop) {
47469+ ERROR("pfkey_prop_build: "
47470+ "why is pfkey_prop already pointing to something?\n");
47471+ SENDERR(EINVAL);
47472+ }
47473+
47474+ pfkey_prop = (struct sadb_prop*)
47475+ MALLOC(sizeof(struct sadb_prop) +
47476+ comb_num * sizeof(struct sadb_comb));
47477+
47478+ *pfkey_ext = (struct sadb_ext*)pfkey_prop;
47479+
47480+ if(pfkey_prop == NULL) {
47481+ ERROR("pfkey_prop_build: "
47482+ "memory allocation failed\n");
47483+ SENDERR(ENOMEM);
47484+ }
47485+ memset(pfkey_prop,
47486+ 0,
47487+ sizeof(struct sadb_prop) +
47488+ comb_num * sizeof(struct sadb_comb));
47489+
47490+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
47491+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
47492+
47493+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
47494+ pfkey_prop->sadb_prop_replay = replay;
47495+
47496+ for(i=0; i<3; i++) {
47497+ pfkey_prop->sadb_prop_reserved[i] = 0;
47498+ }
47499+
47500+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
47501+ for(i = 0; i < comb_num; i++) {
47502+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
47503+ combp++;
47504+ }
47505+
47506+#if 0
47507+ uint8_t sadb_comb_auth;
47508+ uint8_t sadb_comb_encrypt;
47509+ uint16_t sadb_comb_flags;
47510+ uint16_t sadb_comb_auth_minbits;
47511+ uint16_t sadb_comb_auth_maxbits;
47512+ uint16_t sadb_comb_encrypt_minbits;
47513+ uint16_t sadb_comb_encrypt_maxbits;
47514+ uint32_t sadb_comb_reserved;
47515+ uint32_t sadb_comb_soft_allocations;
47516+ uint32_t sadb_comb_hard_allocations;
47517+ uint64_t sadb_comb_soft_bytes;
47518+ uint64_t sadb_comb_hard_bytes;
47519+ uint64_t sadb_comb_soft_addtime;
47520+ uint64_t sadb_comb_hard_addtime;
47521+ uint64_t sadb_comb_soft_usetime;
47522+ uint64_t sadb_comb_hard_usetime;
47523+ uint32_t sadb_comb_soft_packets;
47524+ uint32_t sadb_comb_hard_packets;
47525+#endif
47526+errlab:
47527+ return error;
47528+}
47529+
47530+int
47531+pfkey_supported_build(struct sadb_ext** pfkey_ext,
47532+ uint16_t exttype,
47533+ unsigned int alg_num,
47534+ struct sadb_alg* alg)
47535+{
47536+ int error = 0;
47537+ unsigned int i;
47538+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
47539+ struct sadb_alg *pfkey_alg;
47540+
47541+ /* sanity checks... */
47542+ if(pfkey_supported) {
47543+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47544+ "pfkey_supported_build: "
47545+ "why is pfkey_supported already pointing to something?\n");
47546+ SENDERR(EINVAL);
47547+ }
47548+
47549+ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
47550+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47551+ "pfkey_supported_build: "
47552+ "unsupported extension type=%d.\n",
47553+ exttype);
47554+ SENDERR(EINVAL);
47555+ }
47556+
47557+ pfkey_supported = (struct sadb_supported*)
47558+ MALLOC(sizeof(struct sadb_supported) +
47559+ alg_num *
47560+ sizeof(struct sadb_alg));
47561+
47562+ *pfkey_ext = (struct sadb_ext*)pfkey_supported;
47563+
47564+ if(pfkey_supported == NULL) {
47565+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47566+ "pfkey_supported_build: "
47567+ "memory allocation failed\n");
47568+ SENDERR(ENOMEM);
47569+ }
47570+ memset(pfkey_supported,
47571+ 0,
47572+ sizeof(struct sadb_supported) +
47573+ alg_num *
47574+ sizeof(struct sadb_alg));
47575+
47576+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
47577+ alg_num *
47578+ sizeof(struct sadb_alg)) /
47579+ IPSEC_PFKEYv2_ALIGN;
47580+ pfkey_supported->sadb_supported_exttype = exttype;
47581+ pfkey_supported->sadb_supported_reserved = 0;
47582+
47583+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
47584+ for(i = 0; i < alg_num; i++) {
47585+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
47586+ pfkey_alg->sadb_alg_reserved = 0;
47587+ pfkey_alg++;
47588+ }
47589+
47590+#if 0
47591+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47592+ "pfkey_supported_build: "
47593+ "Sorry, I can't build exttype=%d yet.\n",
47594+ (*pfkey_ext)->sadb_ext_type);
47595+ SENDERR(EINVAL); /* don't process these yet */
47596+
47597+ uint8_t sadb_alg_id;
47598+ uint8_t sadb_alg_ivlen;
47599+ uint16_t sadb_alg_minbits;
47600+ uint16_t sadb_alg_maxbits;
47601+ uint16_t sadb_alg_reserved;
47602+#endif
47603+errlab:
47604+ return error;
47605+}
47606+
47607+int
47608+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
47609+ uint16_t exttype,
47610+ uint32_t min, /* in network order */
47611+ uint32_t max) /* in network order */
47612+{
47613+ int error = 0;
47614+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
47615+
47616+ /* sanity checks... */
47617+ if(pfkey_spirange) {
47618+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47619+ "pfkey_spirange_build: "
47620+ "why is pfkey_spirange already pointing to something?\n");
47621+ SENDERR(EINVAL);
47622+ }
47623+
47624+ if(ntohl(max) < ntohl(min)) {
47625+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47626+ "pfkey_spirange_build: "
47627+ "minspi=%08x must be < maxspi=%08x.\n",
47628+ ntohl(min),
47629+ ntohl(max));
47630+ SENDERR(EINVAL);
47631+ }
47632+
47633+ if(ntohl(min) <= 255) {
47634+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47635+ "pfkey_spirange_build: "
47636+ "minspi=%08x must be > 255.\n",
47637+ ntohl(min));
47638+ SENDERR(EEXIST);
47639+ }
47640+
47641+ pfkey_spirange = (struct sadb_spirange*)
47642+ MALLOC(sizeof(struct sadb_spirange));
47643+
47644+ *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
47645+
47646+ if(pfkey_spirange == NULL) {
47647+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47648+ "pfkey_spirange_build: "
47649+ "memory allocation failed\n");
47650+ SENDERR(ENOMEM);
47651+ }
47652+ memset(pfkey_spirange,
47653+ 0,
47654+ sizeof(struct sadb_spirange));
47655+
47656+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
47657+
47658+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
47659+ pfkey_spirange->sadb_spirange_min = min;
47660+ pfkey_spirange->sadb_spirange_max = max;
47661+ pfkey_spirange->sadb_spirange_reserved = 0;
47662+ errlab:
47663+ return error;
47664+}
47665+
47666+int
47667+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
47668+{
47669+ int error = 0;
47670+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
47671+
47672+ /* sanity checks... */
47673+ if(pfkey_x_kmprivate) {
47674+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47675+ "pfkey_x_kmprivate_build: "
47676+ "why is pfkey_x_kmprivate already pointing to something?\n");
47677+ SENDERR(EINVAL);
47678+ }
47679+
47680+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
47681+
47682+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47683+ "pfkey_x_kmprivate_build: "
47684+ "Sorry, I can't build exttype=%d yet.\n",
47685+ (*pfkey_ext)->sadb_ext_type);
47686+ SENDERR(EINVAL); /* don't process these yet */
47687+
47688+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
47689+ MALLOC(sizeof(struct sadb_x_kmprivate));
47690+
47691+ *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
47692+
47693+ if(pfkey_x_kmprivate == NULL) {
47694+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47695+ "pfkey_x_kmprivate_build: "
47696+ "memory allocation failed\n");
47697+ SENDERR(ENOMEM);
47698+ }
47699+ memset(pfkey_x_kmprivate,
47700+ 0,
47701+ sizeof(struct sadb_x_kmprivate));
47702+
47703+ pfkey_x_kmprivate->sadb_x_kmprivate_len =
47704+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
47705+
47706+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
47707+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
47708+errlab:
47709+ return error;
47710+}
47711+
47712+int
47713+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
47714+ uint8_t satype)
47715+{
47716+ int error = 0;
47717+ int i;
47718+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
47719+
47720+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47721+ "pfkey_x_satype_build:\n");
47722+ /* sanity checks... */
47723+ if(pfkey_x_satype) {
47724+ ERROR("pfkey_x_satype_build: "
47725+ "why is pfkey_x_satype already pointing to something?\n");
47726+ SENDERR(EINVAL);
47727+ }
47728+
47729+ if(!satype) {
47730+ ERROR("pfkey_x_satype_build: "
47731+ "SA type not set, must be non-zero.\n");
47732+ SENDERR(EINVAL);
47733+ }
47734+
47735+ if(satype > SADB_SATYPE_MAX) {
47736+ ERROR("pfkey_x_satype_build: "
47737+ "satype %d > max %d\n",
47738+ satype, SADB_SATYPE_MAX);
47739+ SENDERR(EINVAL);
47740+ }
47741+
47742+ pfkey_x_satype = (struct sadb_x_satype*)
47743+ MALLOC(sizeof(struct sadb_x_satype));
47744+
47745+ *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
47746+ if(pfkey_x_satype == NULL) {
47747+ ERROR("pfkey_x_satype_build: "
47748+ "memory allocation failed\n");
47749+ SENDERR(ENOMEM);
47750+ }
47751+ memset(pfkey_x_satype,
47752+ 0,
47753+ sizeof(struct sadb_x_satype));
47754+
47755+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
47756+
47757+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
47758+ pfkey_x_satype->sadb_x_satype_satype = satype;
47759+ for(i=0; i<3; i++) {
47760+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
47761+ }
47762+
47763+errlab:
47764+ return error;
47765+}
47766+
47767+int
47768+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
47769+ uint32_t tunnel,
47770+ uint32_t netlink,
47771+ uint32_t xform,
47772+ uint32_t eroute,
47773+ uint32_t spi,
47774+ uint32_t radij,
47775+ uint32_t esp,
47776+ uint32_t ah,
47777+ uint32_t rcv,
47778+ uint32_t pfkey,
47779+ uint32_t ipcomp,
47780+ uint32_t verbose)
47781+{
47782+ int error = 0;
47783+ int i;
47784+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
47785+
47786+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47787+ "pfkey_x_debug_build:\n");
47788+ /* sanity checks... */
47789+ if(pfkey_x_debug) {
47790+ ERROR("pfkey_x_debug_build: "
47791+ "why is pfkey_x_debug already pointing to something?\n");
47792+ SENDERR(EINVAL);
47793+ }
47794+
47795+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47796+ "pfkey_x_debug_build: "
47797+ "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",
47798+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
47799+
47800+ pfkey_x_debug = (struct sadb_x_debug*)
47801+ MALLOC(sizeof(struct sadb_x_debug));
47802+
47803+ *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
47804+
47805+ if(pfkey_x_debug == NULL) {
47806+ ERROR("pfkey_x_debug_build: "
47807+ "memory allocation failed\n");
47808+ SENDERR(ENOMEM);
47809+ }
47810+#if 0
47811+ memset(pfkey_x_debug,
47812+ 0,
47813+ sizeof(struct sadb_x_debug));
47814+#endif
47815+
47816+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
47817+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
47818+
47819+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
47820+ pfkey_x_debug->sadb_x_debug_netlink = netlink;
47821+ pfkey_x_debug->sadb_x_debug_xform = xform;
47822+ pfkey_x_debug->sadb_x_debug_eroute = eroute;
47823+ pfkey_x_debug->sadb_x_debug_spi = spi;
47824+ pfkey_x_debug->sadb_x_debug_radij = radij;
47825+ pfkey_x_debug->sadb_x_debug_esp = esp;
47826+ pfkey_x_debug->sadb_x_debug_ah = ah;
47827+ pfkey_x_debug->sadb_x_debug_rcv = rcv;
47828+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
47829+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
47830+ pfkey_x_debug->sadb_x_debug_verbose = verbose;
47831+
47832+ for(i=0; i<4; i++) {
47833+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
47834+ }
47835+
47836+errlab:
47837+ return error;
47838+}
47839+
47840+int
47841+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
47842+ uint8_t type)
47843+{
47844+ int error = 0;
47845+ int i;
47846+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
47847+
47848+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47849+ "pfkey_x_nat_t_type_build:\n");
47850+ /* sanity checks... */
47851+ if(pfkey_x_nat_t_type) {
47852+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47853+ "pfkey_x_nat_t_type_build: "
47854+ "why is pfkey_x_nat_t_type already pointing to something?\n");
47855+ SENDERR(EINVAL);
47856+ }
47857+
47858+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47859+ "pfkey_x_nat_t_type_build: "
47860+ "type=%d\n", type);
47861+
47862+ pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
47863+ MALLOC(sizeof(struct sadb_x_nat_t_type));
47864+
47865+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
47866+
47867+ if(pfkey_x_nat_t_type == NULL) {
47868+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47869+ "pfkey_x_nat_t_type_build: "
47870+ "memory allocation failed\n");
47871+ SENDERR(ENOMEM);
47872+ }
47873+
47874+ pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
47875+ pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
47876+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
47877+ for(i=0; i<3; i++) {
47878+ pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
47879+ }
47880+
47881+errlab:
47882+ return error;
47883+}
47884+int
47885+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
47886+ uint16_t exttype,
47887+ uint16_t port)
47888+{
47889+ int error = 0;
47890+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
47891+
47892+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47893+ "pfkey_x_nat_t_port_build:\n");
47894+ /* sanity checks... */
47895+ if(pfkey_x_nat_t_port) {
47896+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47897+ "pfkey_x_nat_t_port_build: "
47898+ "why is pfkey_x_nat_t_port already pointing to something?\n");
47899+ SENDERR(EINVAL);
47900+ }
47901+
47902+ switch(exttype) {
47903+ case SADB_X_EXT_NAT_T_SPORT:
47904+ case SADB_X_EXT_NAT_T_DPORT:
47905+ break;
47906+ default:
47907+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47908+ "pfkey_nat_t_port_build: "
47909+ "unrecognised ext_type=%d.\n",
47910+ exttype);
47911+ SENDERR(EINVAL);
47912+ }
47913+
47914+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47915+ "pfkey_x_nat_t_port_build: "
47916+ "ext=%d, port=%d\n", exttype, port);
47917+
47918+ pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
47919+ MALLOC(sizeof(struct sadb_x_nat_t_port));
47920+
47921+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
47922+
47923+ if(pfkey_x_nat_t_port == NULL) {
47924+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47925+ "pfkey_x_nat_t_port_build: "
47926+ "memory allocation failed\n");
47927+ SENDERR(ENOMEM);
47928+ }
47929+
47930+ pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
47931+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
47932+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
47933+ pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
47934+
47935+errlab:
47936+ return error;
47937+}
47938+
47939+int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
47940+ uint8_t protocol)
47941+{
47942+ int error = 0;
47943+ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
47944+ DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol);
47945+ /* sanity checks... */
47946+ if (p != 0) {
47947+ ERROR("pfkey_x_protocol_build: bogus protocol pointer\n");
47948+ SENDERR(EINVAL);
47949+ }
47950+ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
47951+ ERROR("pfkey_build: memory allocation failed\n");
47952+ SENDERR(ENOMEM);
47953+ }
47954+ *pfkey_ext = (struct sadb_ext *)p;
47955+ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
47956+ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
47957+ p->sadb_protocol_proto = protocol;
47958+ p->sadb_protocol_flags = 0;
47959+ p->sadb_protocol_reserved2 = 0;
47960+ errlab:
47961+ return error;
47962+}
47963+
47964+int
47965+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
47966+{
47967+ int error = 0;
47968+ unsigned ext;
47969+ unsigned total_size;
47970+ struct sadb_ext *pfkey_ext;
47971+ int extensions_seen = 0;
47972+#ifndef __KERNEL__
47973+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
47974+#endif
47975+
47976+ if(!extensions[0]) {
47977+ ERROR("pfkey_msg_build: "
47978+ "extensions[0] must be specified (struct sadb_msg).\n");
47979+ SENDERR(EINVAL);
47980+ }
47981+
47982+ /* figure out the total size for all the requested extensions */
47983+ total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
47984+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
47985+ if(extensions[ext]) {
47986+ total_size += (extensions[ext])->sadb_ext_len;
47987+ }
47988+ }
47989+
47990+ /* allocate that much space */
47991+ *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN);
47992+ if(*pfkey_msg == NULL) {
47993+ ERROR("pfkey_msg_build: "
47994+ "memory allocation failed\n");
47995+ SENDERR(ENOMEM);
47996+ }
47997+
47998+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47999+ "pfkey_msg_build: "
48000+ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
48001+ *pfkey_msg,
48002+ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
48003+ &(extensions[0]));
48004+
48005+ memcpy(*pfkey_msg,
48006+ extensions[0],
48007+ sizeof(struct sadb_msg));
48008+ (*pfkey_msg)->sadb_msg_len = total_size;
48009+ (*pfkey_msg)->sadb_msg_reserved = 0;
48010+ extensions_seen = 1 ;
48011+
48012+ /*
48013+ * point pfkey_ext to immediately after the space for the header,
48014+ * i.e. at the first extension location.
48015+ */
48016+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
48017+
48018+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
48019+ /* copy from extension[ext] to buffer */
48020+ if(extensions[ext]) {
48021+ /* Is this type of extension permitted for this type of message? */
48022+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
48023+ 1<<ext)) {
48024+ ERROR("pfkey_msg_build: "
48025+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
48026+ ext,
48027+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
48028+ 1<<ext);
48029+ SENDERR(EINVAL);
48030+ }
48031+
48032+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48033+ "pfkey_msg_build: "
48034+ "copying %lu bytes from extensions[%u] (type=%d)\n",
48035+ (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
48036+ ext,
48037+ extensions[ext]->sadb_ext_type);
48038+
48039+ memcpy(pfkey_ext,
48040+ extensions[ext],
48041+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
48042+ {
48043+ char *pfkey_ext_c = (char *)pfkey_ext;
48044+
48045+ pfkey_ext_c += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
48046+ pfkey_ext = (struct sadb_ext *)pfkey_ext_c;
48047+ }
48048+
48049+ /* Mark that we have seen this extension and remember the header location */
48050+ extensions_seen |= ( 1 << ext );
48051+ }
48052+ }
48053+
48054+ /* check required extensions */
48055+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48056+ "pfkey_msg_build: "
48057+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
48058+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
48059+ extensions_seen,
48060+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
48061+
48062+ if((extensions_seen &
48063+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
48064+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
48065+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48066+ "pfkey_msg_build: "
48067+ "required extensions missing:%08x.\n",
48068+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
48069+ (extensions_seen &
48070+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
48071+ SENDERR(EINVAL);
48072+ }
48073+
48074+#ifndef __KERNEL__
48075+/*
48076+ * this is silly, there is no need to reparse the message that we just built.
48077+ *
48078+ */
48079+ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
48080+ ERROR(
48081+ "pfkey_msg_build: "
48082+ "Trouble parsing newly built pfkey message, error=%d.\n",
48083+ error);
48084+ SENDERR(-error);
48085+ }
48086+#endif
48087+
48088+errlab:
48089+
48090+ return error;
48091+}
48092+
48093+/*
48094+ * $Log: pfkey_v2_build.c,v $
48095+ * Revision 1.51.8.1 2006/05/01 14:36:39 mcr
48096+ * get rid of dead code.
48097+ *
48098+ * Revision 1.51 2004/10/03 01:26:36 mcr
48099+ * fixes for gcc 3.4 compilation.
48100+ *
48101+ * Revision 1.50 2004/07/10 07:48:35 mcr
48102+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
48103+ *
48104+ * Revision 1.49 2004/04/12 02:59:06 mcr
48105+ * erroneously moved pfkey_v2_build.c
48106+ *
48107+ * Revision 1.48 2004/04/09 18:00:40 mcr
48108+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
48109+ *
48110+ * Revision 1.47 2004/03/08 01:59:08 ken
48111+ * freeswan.h -> openswan.h
48112+ *
48113+ * Revision 1.46 2003/12/10 01:20:19 mcr
48114+ * NAT-traversal patches to KLIPS.
48115+ *
48116+ * Revision 1.45 2003/12/04 23:01:12 mcr
48117+ * removed ipsec_netlink.h
48118+ *
48119+ * Revision 1.44 2003/10/31 02:27:12 mcr
48120+ * pulled up port-selector patches and sa_id elimination.
48121+ *
48122+ * Revision 1.43.4.2 2003/10/29 01:11:32 mcr
48123+ * added debugging for pfkey library.
48124+ *
48125+ * Revision 1.43.4.1 2003/09/21 13:59:44 mcr
48126+ * pre-liminary X.509 patch - does not yet pass tests.
48127+ *
48128+ * Revision 1.43 2003/05/07 17:29:17 mcr
48129+ * new function pfkey_debug_func added for us in debugging from
48130+ * pfkey library.
48131+ *
48132+ * Revision 1.42 2003/01/30 02:32:09 rgb
48133+ *
48134+ * Rename SAref table macro names for clarity.
48135+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
48136+ *
48137+ * Revision 1.41 2002/12/13 18:16:02 mcr
48138+ * restored sa_ref code
48139+ *
48140+ * Revision 1.40 2002/12/13 18:06:52 mcr
48141+ * temporarily removed sadb_x_sa_ref reference for 2.xx
48142+ *
48143+ * Revision 1.39 2002/12/13 17:43:28 mcr
48144+ * commented out access to sadb_x_sa_ref for 2.xx branch
48145+ *
48146+ * Revision 1.38 2002/10/09 03:12:05 dhr
48147+ *
48148+ * [kenb+dhr] 64-bit fixes
48149+ *
48150+ * Revision 1.37 2002/09/20 15:40:39 rgb
48151+ * Added new function pfkey_sa_ref_build() to accomodate saref parameter.
48152+ *
48153+ * Revision 1.36 2002/09/20 05:01:22 rgb
48154+ * Generalise for platform independance: fix (ia64) using unsigned for sizes.
48155+ *
48156+ * Revision 1.35 2002/07/24 18:44:54 rgb
48157+ * Type fiddling to tame ia64 compiler.
48158+ *
48159+ * Revision 1.34 2002/05/23 07:14:11 rgb
48160+ * Cleaned up %p variants to 0p%p for test suite cleanup.
48161+ *
48162+ * Revision 1.33 2002/04/24 07:55:32 mcr
48163+ * #include patches and Makefiles for post-reorg compilation.
48164+ *
48165+ * Revision 1.32 2002/04/24 07:36:40 mcr
48166+ * Moved from ./lib/pfkey_v2_build.c,v
48167+ *
48168+ * Revision 1.31 2002/01/29 22:25:35 rgb
48169+ * Re-add ipsec_kversion.h to keep MALLOC happy.
48170+ *
48171+ * Revision 1.30 2002/01/29 01:59:09 mcr
48172+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
48173+ * updating of IPv6 structures to match latest in6.h version.
48174+ * removed dead code from openswan.h that also duplicated kversions.h
48175+ * code.
48176+ *
48177+ * Revision 1.29 2001/12/19 21:06:09 rgb
48178+ * Added port numbers to pfkey_address_build() debugging.
48179+ *
48180+ * Revision 1.28 2001/11/06 19:47:47 rgb
48181+ * Added packet parameter to lifetime and comb structures.
48182+ *
48183+ * Revision 1.27 2001/10/18 04:45:24 rgb
48184+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
48185+ * lib/openswan.h version macros moved to lib/kversions.h.
48186+ * Other compiler directive cleanups.
48187+ *
48188+ * Revision 1.26 2001/09/08 21:13:34 rgb
48189+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
48190+ *
48191+ * Revision 1.25 2001/06/14 19:35:16 rgb
48192+ * Update copyright date.
48193+ *
48194+ * Revision 1.24 2001/03/20 03:49:45 rgb
48195+ * Ditch superfluous debug_pfkey declaration.
48196+ * Move misplaced openswan.h inclusion for kernel case.
48197+ *
48198+ * Revision 1.23 2001/03/16 07:41:50 rgb
48199+ * Put openswan.h include before pluto includes.
48200+ *
48201+ * Revision 1.22 2001/02/27 22:24:56 rgb
48202+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
48203+ * Check for satoa() return codes.
48204+ *
48205+ * Revision 1.21 2000/11/17 18:10:30 rgb
48206+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
48207+ * network byte order since this is the way PF_KEYv2 stored spis.
48208+ *
48209+ * Revision 1.20 2000/10/12 00:02:39 rgb
48210+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
48211+ *
48212+ * Revision 1.19 2000/10/10 20:10:20 rgb
48213+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
48214+ *
48215+ * Revision 1.18 2000/09/12 18:59:54 rgb
48216+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
48217+ *
48218+ * Revision 1.17 2000/09/12 03:27:00 rgb
48219+ * Moved DEBUGGING definition to compile kernel with debug off.
48220+ *
48221+ * Revision 1.16 2000/09/08 19:22:12 rgb
48222+ * Fixed pfkey_prop_build() parameter to be only single indirection.
48223+ * Fixed struct alg copy.
48224+ *
48225+ * Revision 1.15 2000/08/20 21:40:01 rgb
48226+ * Added an address parameter sanity check to pfkey_address_build().
48227+ *
48228+ * Revision 1.14 2000/08/15 17:29:23 rgb
48229+ * Fixes from SZI to untested pfkey_prop_build().
48230+ *
48231+ * Revision 1.13 2000/06/02 22:54:14 rgb
48232+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
48233+ *
48234+ * Revision 1.12 2000/05/10 19:24:01 rgb
48235+ * Fleshed out sensitivity, proposal and supported extensions.
48236+ *
48237+ * Revision 1.11 2000/03/16 14:07:23 rgb
48238+ * Renamed ALIGN macro to avoid fighting with others in kernel.
48239+ *
48240+ * Revision 1.10 2000/01/24 21:14:35 rgb
48241+ * Added disabled pluto pfkey lib debug flag.
48242+ *
48243+ * Revision 1.9 2000/01/21 06:27:32 rgb
48244+ * Added address cases for eroute flows.
48245+ * Removed unused code.
48246+ * Dropped unused argument to pfkey_x_satype_build().
48247+ * Indented compiler directives for readability.
48248+ * Added klipsdebug switching capability.
48249+ * Fixed SADB_EXT_MAX bug not permitting last extension access.
48250+ *
48251+ * Revision 1.8 1999/12/29 21:17:41 rgb
48252+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
48253+ * parameter for cleaner manipulation of extensions[] and to guard
48254+ * against potential memory leaks.
48255+ * Changed the I/F to pfkey_msg_free() for the same reason.
48256+ *
48257+ * Revision 1.7 1999/12/09 23:12:20 rgb
48258+ * Removed unused cruft.
48259+ * Added argument to pfkey_sa_build() to do eroutes.
48260+ * Fixed exttype check in as yet unused pfkey_lifetime_build().
48261+ *
48262+ * Revision 1.6 1999/12/07 19:54:29 rgb
48263+ * Removed static pluto debug flag.
48264+ * Added functions for pfkey message and extensions initialisation
48265+ * and cleanup.
48266+ *
48267+ * Revision 1.5 1999/12/01 22:20:06 rgb
48268+ * Changed pfkey_sa_build to accept an SPI in network byte order.
48269+ * Added <string.h> to quiet userspace compiler.
48270+ * Moved pfkey_lib_debug variable into the library.
48271+ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
48272+ * Added extension assembly debugging.
48273+ * Isolated assignment with brackets to be sure of scope.
48274+ *
48275+ * Revision 1.4 1999/11/27 11:57:35 rgb
48276+ * Added ipv6 headers.
48277+ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
48278+ * Debugging error messages added.
48279+ * Fixed missing auth and encrypt assignment bug.
48280+ * Add argument to pfkey_msg_parse() for direction.
48281+ * Move parse-after-build check inside pfkey_msg_build().
48282+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
48283+ * Add CVS log entry to bottom of file.
48284+ *
48285+ */
48286--- /dev/null Tue Mar 11 13:02:56 2003
48287+++ linux/net/ipsec/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004
48288@@ -0,0 +1,181 @@
48289+/*
48290+ * @(#) pfkey version 2 debugging messages
48291+ *
48292+ * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org>
48293+ * and Michael Richardson <mcr@openswan.org>
48294+ *
48295+ * This program is free software; you can redistribute it and/or modify it
48296+ * under the terms of the GNU General Public License as published by the
48297+ * Free Software Foundation; either version 2 of the License, or (at your
48298+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
48299+ *
48300+ * This program is distributed in the hope that it will be useful, but
48301+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48302+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48303+ * for more details.
48304+ *
48305+ * RCSID $Id: pfkey_v2_debug.c,v 1.11 2005/04/06 17:45:16 mcr Exp $
48306+ *
48307+ */
48308+
48309+#ifdef __KERNEL__
48310+
48311+# include <linux/kernel.h> /* for printk */
48312+
48313+# include "openswan/ipsec_kversion.h" /* for malloc switch */
48314+# ifdef MALLOC_SLAB
48315+# include <linux/slab.h> /* kmalloc() */
48316+# else /* MALLOC_SLAB */
48317+# include <linux/malloc.h> /* kmalloc() */
48318+# endif /* MALLOC_SLAB */
48319+# include <linux/errno.h> /* error codes */
48320+# include <linux/types.h> /* size_t */
48321+# include <linux/interrupt.h> /* mark_bh */
48322+
48323+# include <linux/netdevice.h> /* struct device, and other headers */
48324+# include <linux/etherdevice.h> /* eth_type_trans */
48325+extern int debug_pfkey;
48326+
48327+#else /* __KERNEL__ */
48328+
48329+# include <sys/types.h>
48330+# include <linux/types.h>
48331+# include <linux/errno.h>
48332+
48333+#endif /* __KERNEL__ */
48334+
48335+#include "openswan.h"
48336+#include "pfkeyv2.h"
48337+#include "pfkey.h"
48338+
48339+/*
48340+ * This file provides ASCII translations of PF_KEY magic numbers.
48341+ *
48342+ */
48343+
48344+static char *pfkey_sadb_ext_strings[]={
48345+ "reserved", /* SADB_EXT_RESERVED 0 */
48346+ "security-association", /* SADB_EXT_SA 1 */
48347+ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */
48348+ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */
48349+ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */
48350+ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */
48351+ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */
48352+ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */
48353+ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */
48354+ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */
48355+ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */
48356+ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */
48357+ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */
48358+ "proposal", /* SADB_EXT_PROPOSAL 13 */
48359+ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */
48360+ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */
48361+ "spi-range", /* SADB_EXT_SPIRANGE 16 */
48362+ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */
48363+ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */
48364+ "X-security-association", /* SADB_X_EXT_SA2 19 */
48365+ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */
48366+ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
48367+ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */
48368+ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */
48369+ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */
48370+ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */
48371+ /* NAT_TRAVERSAL */
48372+ "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */
48373+ "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */
48374+ "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */
48375+ "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */
48376+};
48377+
48378+const char *
48379+pfkey_v2_sadb_ext_string(int ext)
48380+{
48381+ if(ext <= SADB_EXT_MAX) {
48382+ return pfkey_sadb_ext_strings[ext];
48383+ } else {
48384+ return "unknown-ext";
48385+ }
48386+}
48387+
48388+
48389+static char *pfkey_sadb_type_strings[]={
48390+ "reserved", /* SADB_RESERVED */
48391+ "getspi", /* SADB_GETSPI */
48392+ "update", /* SADB_UPDATE */
48393+ "add", /* SADB_ADD */
48394+ "delete", /* SADB_DELETE */
48395+ "get", /* SADB_GET */
48396+ "acquire", /* SADB_ACQUIRE */
48397+ "register", /* SADB_REGISTER */
48398+ "expire", /* SADB_EXPIRE */
48399+ "flush", /* SADB_FLUSH */
48400+ "dump", /* SADB_DUMP */
48401+ "x-promisc", /* SADB_X_PROMISC */
48402+ "x-pchange", /* SADB_X_PCHANGE */
48403+ "x-groupsa", /* SADB_X_GRPSA */
48404+ "x-addflow(eroute)", /* SADB_X_ADDFLOW */
48405+ "x-delflow(eroute)", /* SADB_X_DELFLOW */
48406+ "x-debug", /* SADB_X_DEBUG */
48407+};
48408+
48409+const char *
48410+pfkey_v2_sadb_type_string(int sadb_type)
48411+{
48412+ if(sadb_type <= SADB_MAX) {
48413+ return pfkey_sadb_type_strings[sadb_type];
48414+ } else {
48415+ return "unknown-sadb-type";
48416+ }
48417+}
48418+
48419+
48420+
48421+
48422+/*
48423+ * $Log: pfkey_v2_debug.c,v $
48424+ * Revision 1.11 2005/04/06 17:45:16 mcr
48425+ * always include NAT-T names.
48426+ *
48427+ * Revision 1.10 2004/07/10 07:48:35 mcr
48428+ * Moved from linux/lib/libfreeswan/pfkey_v2_debug.c,v
48429+ *
48430+ * Revision 1.9 2004/03/08 01:59:08 ken
48431+ * freeswan.h -> openswan.h
48432+ *
48433+ * Revision 1.8 2003/12/10 01:20:19 mcr
48434+ * NAT-traversal patches to KLIPS.
48435+ *
48436+ * Revision 1.7 2002/09/20 05:01:26 rgb
48437+ * Fixed limit inclusion error in both type and ext string conversion.
48438+ *
48439+ * Revision 1.6 2002/04/24 07:55:32 mcr
48440+ * #include patches and Makefiles for post-reorg compilation.
48441+ *
48442+ * Revision 1.5 2002/04/24 07:36:40 mcr
48443+ * Moved from ./lib/pfkey_v2_debug.c,v
48444+ *
48445+ * Revision 1.4 2002/01/29 22:25:36 rgb
48446+ * Re-add ipsec_kversion.h to keep MALLOC happy.
48447+ *
48448+ * Revision 1.3 2002/01/29 01:59:09 mcr
48449+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
48450+ * updating of IPv6 structures to match latest in6.h version.
48451+ * removed dead code from openswan.h that also duplicated kversions.h
48452+ * code.
48453+ *
48454+ * Revision 1.2 2002/01/20 20:34:50 mcr
48455+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
48456+ *
48457+ * Revision 1.1 2001/11/27 05:30:06 mcr
48458+ * initial set of debug strings for pfkey debugging.
48459+ * this will eventually only be included for debug builds.
48460+ *
48461+ * Revision 1.1 2001/09/21 04:12:03 mcr
48462+ * first compilable version.
48463+ *
48464+ *
48465+ * Local variables:
48466+ * c-file-style: "linux"
48467+ * End:
48468+ *
48469+ */
48470--- /dev/null Tue Mar 11 13:02:56 2003
48471+++ linux/net/ipsec/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004
48472@@ -0,0 +1,814 @@
48473+/*
48474+ * RFC2367 PF_KEYv2 Key management API message parser
48475+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
48476+ *
48477+ * This program is free software; you can redistribute it and/or modify it
48478+ * under the terms of the GNU General Public License as published by the
48479+ * Free Software Foundation; either version 2 of the License, or (at your
48480+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
48481+ *
48482+ * This program is distributed in the hope that it will be useful, but
48483+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48484+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48485+ * for more details.
48486+ *
48487+ * RCSID $Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $
48488+ */
48489+
48490+/*
48491+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
48492+ */
48493+
48494+char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $";
48495+
48496+/*
48497+ * Some ugly stuff to allow consistent debugging code for use in the
48498+ * kernel and in user space
48499+*/
48500+
48501+#ifdef __KERNEL__
48502+
48503+# include <linux/kernel.h> /* for printk */
48504+
48505+# include "openswan/ipsec_kversion.h" /* for malloc switch */
48506+# ifdef MALLOC_SLAB
48507+# include <linux/slab.h> /* kmalloc() */
48508+# else /* MALLOC_SLAB */
48509+# include <linux/malloc.h> /* kmalloc() */
48510+# endif /* MALLOC_SLAB */
48511+# include <linux/errno.h> /* error codes */
48512+# include <linux/types.h> /* size_t */
48513+# include <linux/interrupt.h> /* mark_bh */
48514+
48515+# include <linux/netdevice.h> /* struct device, and other headers */
48516+# include <linux/etherdevice.h> /* eth_type_trans */
48517+# include <linux/ip.h> /* struct iphdr */
48518+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
48519+# include <linux/ipv6.h>
48520+# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
48521+
48522+#else /* __KERNEL__ */
48523+
48524+# include <sys/types.h>
48525+# include <linux/types.h>
48526+# include <linux/errno.h>
48527+#endif
48528+
48529+#include <openswan.h>
48530+#include <pfkeyv2.h>
48531+#include <pfkey.h>
48532+
48533+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX] = {
48534+
48535+/* INBOUND EXTENSIONS */
48536+{
48537+
48538+/* PERMITTED IN */
48539+{
48540+/* SADB_RESERVED */
48541+0
48542+,
48543+/* SADB_GETSPI */
48544+1<<SADB_EXT_RESERVED
48545+| 1<<SADB_EXT_ADDRESS_SRC
48546+| 1<<SADB_EXT_ADDRESS_DST
48547+| 1<<SADB_EXT_ADDRESS_PROXY
48548+| 1<<SADB_EXT_SPIRANGE
48549+,
48550+/* SADB_UPDATE */
48551+1<<SADB_EXT_RESERVED
48552+| 1<<SADB_EXT_SA
48553+| 1<<SADB_EXT_LIFETIME_CURRENT
48554+| 1<<SADB_EXT_LIFETIME_HARD
48555+| 1<<SADB_EXT_LIFETIME_SOFT
48556+| 1<<SADB_EXT_ADDRESS_SRC
48557+| 1<<SADB_EXT_ADDRESS_DST
48558+| 1<<SADB_EXT_ADDRESS_PROXY
48559+| 1<<SADB_EXT_KEY_AUTH
48560+| 1<<SADB_EXT_KEY_ENCRYPT
48561+| 1<<SADB_EXT_IDENTITY_SRC
48562+| 1<<SADB_EXT_IDENTITY_DST
48563+| 1<<SADB_EXT_SENSITIVITY
48564+| 1<<SADB_X_EXT_NAT_T_SPORT
48565+| 1<<SADB_X_EXT_NAT_T_DPORT
48566+,
48567+/* SADB_ADD */
48568+1<<SADB_EXT_RESERVED
48569+| 1<<SADB_EXT_SA
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_X_EXT_NAT_T_TYPE
48581+| 1<<SADB_X_EXT_NAT_T_SPORT
48582+| 1<<SADB_X_EXT_NAT_T_DPORT
48583+| 1<<SADB_X_EXT_NAT_T_OA
48584+,
48585+/* SADB_DELETE */
48586+1<<SADB_EXT_RESERVED
48587+| 1<<SADB_EXT_SA
48588+| 1<<SADB_EXT_ADDRESS_SRC
48589+| 1<<SADB_EXT_ADDRESS_DST
48590+,
48591+/* SADB_GET */
48592+1<<SADB_EXT_RESERVED
48593+| 1<<SADB_EXT_SA
48594+| 1<<SADB_EXT_ADDRESS_SRC
48595+| 1<<SADB_EXT_ADDRESS_DST
48596+,
48597+/* SADB_ACQUIRE */
48598+1<<SADB_EXT_RESERVED
48599+| 1<<SADB_EXT_ADDRESS_SRC
48600+| 1<<SADB_EXT_ADDRESS_DST
48601+| 1<<SADB_EXT_ADDRESS_PROXY
48602+| 1<<SADB_EXT_IDENTITY_SRC
48603+| 1<<SADB_EXT_IDENTITY_DST
48604+| 1<<SADB_EXT_SENSITIVITY
48605+| 1<<SADB_EXT_PROPOSAL
48606+,
48607+/* SADB_REGISTER */
48608+1<<SADB_EXT_RESERVED
48609+,
48610+/* SADB_EXPIRE */
48611+0
48612+,
48613+/* SADB_FLUSH */
48614+1<<SADB_EXT_RESERVED
48615+,
48616+/* SADB_DUMP */
48617+1<<SADB_EXT_RESERVED
48618+,
48619+/* SADB_X_PROMISC */
48620+1<<SADB_EXT_RESERVED
48621+| 1<<SADB_EXT_SA
48622+| 1<<SADB_EXT_LIFETIME_CURRENT
48623+| 1<<SADB_EXT_LIFETIME_HARD
48624+| 1<<SADB_EXT_LIFETIME_SOFT
48625+| 1<<SADB_EXT_ADDRESS_SRC
48626+| 1<<SADB_EXT_ADDRESS_DST
48627+| 1<<SADB_EXT_ADDRESS_PROXY
48628+| 1<<SADB_EXT_KEY_AUTH
48629+| 1<<SADB_EXT_KEY_ENCRYPT
48630+| 1<<SADB_EXT_IDENTITY_SRC
48631+| 1<<SADB_EXT_IDENTITY_DST
48632+| 1<<SADB_EXT_SENSITIVITY
48633+| 1<<SADB_EXT_PROPOSAL
48634+| 1<<SADB_EXT_SUPPORTED_AUTH
48635+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48636+| 1<<SADB_EXT_SPIRANGE
48637+| 1<<SADB_X_EXT_KMPRIVATE
48638+| 1<<SADB_X_EXT_SATYPE2
48639+| 1<<SADB_X_EXT_SA2
48640+| 1<<SADB_X_EXT_ADDRESS_DST2
48641+,
48642+/* SADB_X_PCHANGE */
48643+1<<SADB_EXT_RESERVED
48644+| 1<<SADB_EXT_SA
48645+| 1<<SADB_EXT_LIFETIME_CURRENT
48646+| 1<<SADB_EXT_LIFETIME_HARD
48647+| 1<<SADB_EXT_LIFETIME_SOFT
48648+| 1<<SADB_EXT_ADDRESS_SRC
48649+| 1<<SADB_EXT_ADDRESS_DST
48650+| 1<<SADB_EXT_ADDRESS_PROXY
48651+| 1<<SADB_EXT_KEY_AUTH
48652+| 1<<SADB_EXT_KEY_ENCRYPT
48653+| 1<<SADB_EXT_IDENTITY_SRC
48654+| 1<<SADB_EXT_IDENTITY_DST
48655+| 1<<SADB_EXT_SENSITIVITY
48656+| 1<<SADB_EXT_PROPOSAL
48657+| 1<<SADB_EXT_SUPPORTED_AUTH
48658+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48659+| 1<<SADB_EXT_SPIRANGE
48660+| 1<<SADB_X_EXT_KMPRIVATE
48661+| 1<<SADB_X_EXT_SATYPE2
48662+| 1<<SADB_X_EXT_SA2
48663+| 1<<SADB_X_EXT_ADDRESS_DST2
48664+,
48665+/* SADB_X_GRPSA */
48666+1<<SADB_EXT_RESERVED
48667+| 1<<SADB_EXT_SA
48668+| 1<<SADB_EXT_ADDRESS_DST
48669+| 1<<SADB_X_EXT_SATYPE2
48670+| 1<<SADB_X_EXT_SA2
48671+| 1<<SADB_X_EXT_ADDRESS_DST2
48672+,
48673+/* SADB_X_ADDFLOW */
48674+1<<SADB_EXT_RESERVED
48675+| 1<<SADB_EXT_SA
48676+| 1<<SADB_EXT_ADDRESS_SRC
48677+| 1<<SADB_EXT_ADDRESS_DST
48678+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48679+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48680+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48681+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48682+| 1<<SADB_EXT_IDENTITY_SRC
48683+| 1<<SADB_EXT_IDENTITY_DST
48684+| 1<<SADB_X_EXT_PROTOCOL
48685+,
48686+/* SADB_X_DELFLOW */
48687+1<<SADB_EXT_RESERVED
48688+| 1<<SADB_EXT_SA
48689+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48690+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48691+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48692+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48693+| 1<<SADB_EXT_IDENTITY_SRC
48694+| 1<<SADB_EXT_IDENTITY_DST
48695+| 1<<SADB_X_EXT_PROTOCOL
48696+,
48697+/* SADB_X_DEBUG */
48698+1<<SADB_EXT_RESERVED
48699+| 1<<SADB_X_EXT_DEBUG
48700+,
48701+/* SADB_X_NAT_T_NEW_MAPPING */
48702+1<<SADB_EXT_RESERVED
48703+| 1<<SADB_EXT_SA
48704+| 1<<SADB_EXT_ADDRESS_SRC
48705+| 1<<SADB_EXT_ADDRESS_DST
48706+| 1<<SADB_X_EXT_NAT_T_SPORT
48707+| 1<<SADB_X_EXT_NAT_T_DPORT
48708+},
48709+
48710+/* REQUIRED IN */
48711+{
48712+/* SADB_RESERVED */
48713+0
48714+,
48715+/* SADB_GETSPI */
48716+1<<SADB_EXT_RESERVED
48717+| 1<<SADB_EXT_ADDRESS_SRC
48718+| 1<<SADB_EXT_ADDRESS_DST
48719+| 1<<SADB_EXT_SPIRANGE
48720+,
48721+/* SADB_UPDATE */
48722+1<<SADB_EXT_RESERVED
48723+| 1<<SADB_EXT_SA
48724+| 1<<SADB_EXT_ADDRESS_SRC
48725+| 1<<SADB_EXT_ADDRESS_DST
48726+/*| 1<<SADB_EXT_KEY_AUTH*/
48727+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
48728+,
48729+/* SADB_ADD */
48730+1<<SADB_EXT_RESERVED
48731+| 1<<SADB_EXT_SA
48732+| 1<<SADB_EXT_ADDRESS_SRC
48733+| 1<<SADB_EXT_ADDRESS_DST
48734+/*| 1<<SADB_EXT_KEY_AUTH*/
48735+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
48736+,
48737+/* SADB_DELETE */
48738+1<<SADB_EXT_RESERVED
48739+| 1<<SADB_EXT_SA
48740+| 1<<SADB_EXT_ADDRESS_SRC
48741+| 1<<SADB_EXT_ADDRESS_DST
48742+,
48743+/* SADB_GET */
48744+1<<SADB_EXT_RESERVED
48745+| 1<<SADB_EXT_SA
48746+| 1<<SADB_EXT_ADDRESS_SRC
48747+| 1<<SADB_EXT_ADDRESS_DST
48748+,
48749+/* SADB_ACQUIRE */
48750+1<<SADB_EXT_RESERVED
48751+| 1<<SADB_EXT_ADDRESS_SRC
48752+| 1<<SADB_EXT_ADDRESS_DST
48753+| 1<<SADB_EXT_PROPOSAL
48754+,
48755+/* SADB_REGISTER */
48756+1<<SADB_EXT_RESERVED
48757+,
48758+/* SADB_EXPIRE */
48759+0
48760+,
48761+/* SADB_FLUSH */
48762+1<<SADB_EXT_RESERVED
48763+,
48764+/* SADB_DUMP */
48765+1<<SADB_EXT_RESERVED
48766+,
48767+/* SADB_X_PROMISC */
48768+1<<SADB_EXT_RESERVED
48769+| 1<<SADB_EXT_SA
48770+| 1<<SADB_EXT_LIFETIME_CURRENT
48771+| 1<<SADB_EXT_LIFETIME_HARD
48772+| 1<<SADB_EXT_LIFETIME_SOFT
48773+| 1<<SADB_EXT_ADDRESS_SRC
48774+| 1<<SADB_EXT_ADDRESS_DST
48775+| 1<<SADB_EXT_ADDRESS_PROXY
48776+| 1<<SADB_EXT_KEY_AUTH
48777+| 1<<SADB_EXT_KEY_ENCRYPT
48778+| 1<<SADB_EXT_IDENTITY_SRC
48779+| 1<<SADB_EXT_IDENTITY_DST
48780+| 1<<SADB_EXT_SENSITIVITY
48781+| 1<<SADB_EXT_PROPOSAL
48782+| 1<<SADB_EXT_SUPPORTED_AUTH
48783+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48784+| 1<<SADB_EXT_SPIRANGE
48785+| 1<<SADB_X_EXT_KMPRIVATE
48786+| 1<<SADB_X_EXT_SATYPE2
48787+| 1<<SADB_X_EXT_SA2
48788+| 1<<SADB_X_EXT_ADDRESS_DST2
48789+,
48790+/* SADB_X_PCHANGE */
48791+1<<SADB_EXT_RESERVED
48792+| 1<<SADB_EXT_SA
48793+| 1<<SADB_EXT_LIFETIME_CURRENT
48794+| 1<<SADB_EXT_LIFETIME_HARD
48795+| 1<<SADB_EXT_LIFETIME_SOFT
48796+| 1<<SADB_EXT_ADDRESS_SRC
48797+| 1<<SADB_EXT_ADDRESS_DST
48798+| 1<<SADB_EXT_ADDRESS_PROXY
48799+| 1<<SADB_EXT_KEY_AUTH
48800+| 1<<SADB_EXT_KEY_ENCRYPT
48801+| 1<<SADB_EXT_IDENTITY_SRC
48802+| 1<<SADB_EXT_IDENTITY_DST
48803+| 1<<SADB_EXT_SENSITIVITY
48804+| 1<<SADB_EXT_PROPOSAL
48805+| 1<<SADB_EXT_SUPPORTED_AUTH
48806+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48807+| 1<<SADB_EXT_SPIRANGE
48808+| 1<<SADB_X_EXT_KMPRIVATE
48809+| 1<<SADB_X_EXT_SATYPE2
48810+| 1<<SADB_X_EXT_SA2
48811+| 1<<SADB_X_EXT_ADDRESS_DST2
48812+,
48813+/* SADB_X_GRPSA */
48814+1<<SADB_EXT_RESERVED
48815+| 1<<SADB_EXT_SA
48816+| 1<<SADB_EXT_ADDRESS_DST
48817+/*| 1<<SADB_X_EXT_SATYPE2*/
48818+/*| 1<<SADB_X_EXT_SA2*/
48819+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
48820+,
48821+/* SADB_X_ADDFLOW */
48822+1<<SADB_EXT_RESERVED
48823+| 1<<SADB_EXT_SA
48824+| 1<<SADB_EXT_ADDRESS_DST
48825+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48826+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48827+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48828+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48829+,
48830+/* SADB_X_DELFLOW */
48831+1<<SADB_EXT_RESERVED
48832+/*| 1<<SADB_EXT_SA*/
48833+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
48834+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48835+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48836+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48837+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48838+#endif
48839+,
48840+/* SADB_X_DEBUG */
48841+1<<SADB_EXT_RESERVED
48842+| 1<<SADB_X_EXT_DEBUG
48843+,
48844+/* SADB_X_NAT_T_NEW_MAPPING */
48845+1<<SADB_EXT_RESERVED
48846+| 1<<SADB_EXT_SA
48847+| 1<<SADB_EXT_ADDRESS_SRC
48848+| 1<<SADB_EXT_ADDRESS_DST
48849+| 1<<SADB_X_EXT_NAT_T_SPORT
48850+| 1<<SADB_X_EXT_NAT_T_DPORT
48851+}
48852+
48853+},
48854+
48855+/* OUTBOUND EXTENSIONS */
48856+{
48857+
48858+/* PERMITTED OUT */
48859+{
48860+/* SADB_RESERVED */
48861+0
48862+,
48863+/* SADB_GETSPI */
48864+1<<SADB_EXT_RESERVED
48865+| 1<<SADB_EXT_SA
48866+| 1<<SADB_EXT_ADDRESS_SRC
48867+| 1<<SADB_EXT_ADDRESS_DST
48868+,
48869+/* SADB_UPDATE */
48870+1<<SADB_EXT_RESERVED
48871+| 1<<SADB_EXT_SA
48872+| 1<<SADB_EXT_LIFETIME_CURRENT
48873+| 1<<SADB_EXT_LIFETIME_HARD
48874+| 1<<SADB_EXT_LIFETIME_SOFT
48875+| 1<<SADB_EXT_ADDRESS_SRC
48876+| 1<<SADB_EXT_ADDRESS_DST
48877+| 1<<SADB_EXT_ADDRESS_PROXY
48878+| 1<<SADB_EXT_IDENTITY_SRC
48879+| 1<<SADB_EXT_IDENTITY_DST
48880+| 1<<SADB_EXT_SENSITIVITY
48881+| 1<<SADB_X_EXT_NAT_T_SPORT
48882+| 1<<SADB_X_EXT_NAT_T_DPORT
48883+,
48884+/* SADB_ADD */
48885+1<<SADB_EXT_RESERVED
48886+| 1<<SADB_EXT_SA
48887+| 1<<SADB_EXT_LIFETIME_HARD
48888+| 1<<SADB_EXT_LIFETIME_SOFT
48889+| 1<<SADB_EXT_ADDRESS_SRC
48890+| 1<<SADB_EXT_ADDRESS_DST
48891+| 1<<SADB_EXT_IDENTITY_SRC
48892+| 1<<SADB_EXT_IDENTITY_DST
48893+| 1<<SADB_EXT_SENSITIVITY
48894+| 1<<SADB_X_EXT_NAT_T_TYPE
48895+| 1<<SADB_X_EXT_NAT_T_SPORT
48896+| 1<<SADB_X_EXT_NAT_T_DPORT
48897+| 1<<SADB_X_EXT_NAT_T_OA
48898+,
48899+/* SADB_DELETE */
48900+1<<SADB_EXT_RESERVED
48901+| 1<<SADB_EXT_SA
48902+| 1<<SADB_EXT_ADDRESS_SRC
48903+| 1<<SADB_EXT_ADDRESS_DST
48904+,
48905+/* SADB_GET */
48906+1<<SADB_EXT_RESERVED
48907+| 1<<SADB_EXT_SA
48908+| 1<<SADB_EXT_LIFETIME_CURRENT
48909+| 1<<SADB_EXT_LIFETIME_HARD
48910+| 1<<SADB_EXT_LIFETIME_SOFT
48911+| 1<<SADB_EXT_ADDRESS_SRC
48912+| 1<<SADB_EXT_ADDRESS_DST
48913+| 1<<SADB_EXT_ADDRESS_PROXY
48914+| 1<<SADB_EXT_KEY_AUTH
48915+| 1<<SADB_EXT_KEY_ENCRYPT
48916+| 1<<SADB_EXT_IDENTITY_SRC
48917+| 1<<SADB_EXT_IDENTITY_DST
48918+| 1<<SADB_EXT_SENSITIVITY
48919+| 1<<SADB_X_EXT_NAT_T_TYPE
48920+| 1<<SADB_X_EXT_NAT_T_SPORT
48921+| 1<<SADB_X_EXT_NAT_T_DPORT
48922+| 1<<SADB_X_EXT_NAT_T_OA
48923+,
48924+/* SADB_ACQUIRE */
48925+1<<SADB_EXT_RESERVED
48926+| 1<<SADB_EXT_ADDRESS_SRC
48927+| 1<<SADB_EXT_ADDRESS_DST
48928+| 1<<SADB_EXT_ADDRESS_PROXY
48929+| 1<<SADB_EXT_IDENTITY_SRC
48930+| 1<<SADB_EXT_IDENTITY_DST
48931+| 1<<SADB_EXT_SENSITIVITY
48932+| 1<<SADB_EXT_PROPOSAL
48933+,
48934+/* SADB_REGISTER */
48935+1<<SADB_EXT_RESERVED
48936+| 1<<SADB_EXT_SUPPORTED_AUTH
48937+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48938+,
48939+/* SADB_EXPIRE */
48940+1<<SADB_EXT_RESERVED
48941+| 1<<SADB_EXT_SA
48942+| 1<<SADB_EXT_LIFETIME_CURRENT
48943+| 1<<SADB_EXT_LIFETIME_HARD
48944+| 1<<SADB_EXT_LIFETIME_SOFT
48945+| 1<<SADB_EXT_ADDRESS_SRC
48946+| 1<<SADB_EXT_ADDRESS_DST
48947+,
48948+/* SADB_FLUSH */
48949+1<<SADB_EXT_RESERVED
48950+,
48951+/* SADB_DUMP */
48952+1<<SADB_EXT_RESERVED
48953+| 1<<SADB_EXT_SA
48954+| 1<<SADB_EXT_LIFETIME_CURRENT
48955+| 1<<SADB_EXT_LIFETIME_HARD
48956+| 1<<SADB_EXT_LIFETIME_SOFT
48957+| 1<<SADB_EXT_ADDRESS_SRC
48958+| 1<<SADB_EXT_ADDRESS_DST
48959+| 1<<SADB_EXT_ADDRESS_PROXY
48960+| 1<<SADB_EXT_KEY_AUTH
48961+| 1<<SADB_EXT_KEY_ENCRYPT
48962+| 1<<SADB_EXT_IDENTITY_SRC
48963+| 1<<SADB_EXT_IDENTITY_DST
48964+| 1<<SADB_EXT_SENSITIVITY
48965+| 1<<SADB_X_EXT_NAT_T_TYPE
48966+| 1<<SADB_X_EXT_NAT_T_SPORT
48967+| 1<<SADB_X_EXT_NAT_T_DPORT
48968+| 1<<SADB_X_EXT_NAT_T_OA
48969+,
48970+/* SADB_X_PROMISC */
48971+1<<SADB_EXT_RESERVED
48972+| 1<<SADB_EXT_SA
48973+| 1<<SADB_EXT_LIFETIME_CURRENT
48974+| 1<<SADB_EXT_LIFETIME_HARD
48975+| 1<<SADB_EXT_LIFETIME_SOFT
48976+| 1<<SADB_EXT_ADDRESS_SRC
48977+| 1<<SADB_EXT_ADDRESS_DST
48978+| 1<<SADB_EXT_ADDRESS_PROXY
48979+| 1<<SADB_EXT_KEY_AUTH
48980+| 1<<SADB_EXT_KEY_ENCRYPT
48981+| 1<<SADB_EXT_IDENTITY_SRC
48982+| 1<<SADB_EXT_IDENTITY_DST
48983+| 1<<SADB_EXT_SENSITIVITY
48984+| 1<<SADB_EXT_PROPOSAL
48985+| 1<<SADB_EXT_SUPPORTED_AUTH
48986+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48987+| 1<<SADB_EXT_SPIRANGE
48988+| 1<<SADB_X_EXT_KMPRIVATE
48989+| 1<<SADB_X_EXT_SATYPE2
48990+| 1<<SADB_X_EXT_SA2
48991+| 1<<SADB_X_EXT_ADDRESS_DST2
48992+,
48993+/* SADB_X_PCHANGE */
48994+1<<SADB_EXT_RESERVED
48995+| 1<<SADB_EXT_SA
48996+| 1<<SADB_EXT_LIFETIME_CURRENT
48997+| 1<<SADB_EXT_LIFETIME_HARD
48998+| 1<<SADB_EXT_LIFETIME_SOFT
48999+| 1<<SADB_EXT_ADDRESS_SRC
49000+| 1<<SADB_EXT_ADDRESS_DST
49001+| 1<<SADB_EXT_ADDRESS_PROXY
49002+| 1<<SADB_EXT_KEY_AUTH
49003+| 1<<SADB_EXT_KEY_ENCRYPT
49004+| 1<<SADB_EXT_IDENTITY_SRC
49005+| 1<<SADB_EXT_IDENTITY_DST
49006+| 1<<SADB_EXT_SENSITIVITY
49007+| 1<<SADB_EXT_PROPOSAL
49008+| 1<<SADB_EXT_SUPPORTED_AUTH
49009+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49010+| 1<<SADB_EXT_SPIRANGE
49011+| 1<<SADB_X_EXT_KMPRIVATE
49012+| 1<<SADB_X_EXT_SATYPE2
49013+| 1<<SADB_X_EXT_SA2
49014+| 1<<SADB_X_EXT_ADDRESS_DST2
49015+,
49016+/* SADB_X_GRPSA */
49017+1<<SADB_EXT_RESERVED
49018+| 1<<SADB_EXT_SA
49019+| 1<<SADB_EXT_ADDRESS_DST
49020+| 1<<SADB_X_EXT_SATYPE2
49021+| 1<<SADB_X_EXT_SA2
49022+| 1<<SADB_X_EXT_ADDRESS_DST2
49023+,
49024+/* SADB_X_ADDFLOW */
49025+1<<SADB_EXT_RESERVED
49026+| 1<<SADB_EXT_SA
49027+| 1<<SADB_EXT_ADDRESS_SRC
49028+| 1<<SADB_EXT_ADDRESS_DST
49029+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49030+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49031+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49032+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49033+| 1<<SADB_X_EXT_PROTOCOL
49034+,
49035+/* SADB_X_DELFLOW */
49036+1<<SADB_EXT_RESERVED
49037+| 1<<SADB_EXT_SA
49038+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49039+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49040+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49041+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49042+| 1<<SADB_X_EXT_PROTOCOL
49043+,
49044+/* SADB_X_DEBUG */
49045+1<<SADB_EXT_RESERVED
49046+| 1<<SADB_X_EXT_DEBUG
49047+,
49048+/* SADB_X_NAT_T_NEW_MAPPING */
49049+1<<SADB_EXT_RESERVED
49050+| 1<<SADB_EXT_SA
49051+| 1<<SADB_EXT_ADDRESS_SRC
49052+| 1<<SADB_EXT_ADDRESS_DST
49053+| 1<<SADB_X_EXT_NAT_T_SPORT
49054+| 1<<SADB_X_EXT_NAT_T_DPORT
49055+},
49056+
49057+/* REQUIRED OUT */
49058+{
49059+/* SADB_RESERVED */
49060+0
49061+,
49062+/* SADB_GETSPI */
49063+1<<SADB_EXT_RESERVED
49064+| 1<<SADB_EXT_SA
49065+| 1<<SADB_EXT_ADDRESS_SRC
49066+| 1<<SADB_EXT_ADDRESS_DST
49067+,
49068+/* SADB_UPDATE */
49069+1<<SADB_EXT_RESERVED
49070+| 1<<SADB_EXT_SA
49071+| 1<<SADB_EXT_ADDRESS_SRC
49072+| 1<<SADB_EXT_ADDRESS_DST
49073+,
49074+/* SADB_ADD */
49075+1<<SADB_EXT_RESERVED
49076+| 1<<SADB_EXT_SA
49077+| 1<<SADB_EXT_ADDRESS_SRC
49078+| 1<<SADB_EXT_ADDRESS_DST
49079+,
49080+/* SADB_DELETE */
49081+1<<SADB_EXT_RESERVED
49082+| 1<<SADB_EXT_SA
49083+| 1<<SADB_EXT_ADDRESS_SRC
49084+| 1<<SADB_EXT_ADDRESS_DST
49085+,
49086+/* SADB_GET */
49087+1<<SADB_EXT_RESERVED
49088+| 1<<SADB_EXT_SA
49089+| 1<<SADB_EXT_ADDRESS_SRC
49090+| 1<<SADB_EXT_ADDRESS_DST
49091+/* | 1<<SADB_EXT_KEY_AUTH */
49092+/* | 1<<SADB_EXT_KEY_ENCRYPT */
49093+,
49094+/* SADB_ACQUIRE */
49095+1<<SADB_EXT_RESERVED
49096+| 1<<SADB_EXT_ADDRESS_SRC
49097+| 1<<SADB_EXT_ADDRESS_DST
49098+| 1<<SADB_EXT_PROPOSAL
49099+,
49100+/* SADB_REGISTER */
49101+1<<SADB_EXT_RESERVED
49102+/* | 1<<SADB_EXT_SUPPORTED_AUTH
49103+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
49104+,
49105+/* SADB_EXPIRE */
49106+1<<SADB_EXT_RESERVED
49107+| 1<<SADB_EXT_SA
49108+| 1<<SADB_EXT_LIFETIME_CURRENT
49109+/* | 1<<SADB_EXT_LIFETIME_HARD
49110+ | 1<<SADB_EXT_LIFETIME_SOFT */
49111+| 1<<SADB_EXT_ADDRESS_SRC
49112+| 1<<SADB_EXT_ADDRESS_DST
49113+,
49114+/* SADB_FLUSH */
49115+1<<SADB_EXT_RESERVED
49116+,
49117+/* SADB_DUMP */
49118+1<<SADB_EXT_RESERVED
49119+| 1<<SADB_EXT_SA
49120+| 1<<SADB_EXT_ADDRESS_SRC
49121+| 1<<SADB_EXT_ADDRESS_DST
49122+| 1<<SADB_EXT_KEY_AUTH
49123+| 1<<SADB_EXT_KEY_ENCRYPT
49124+,
49125+/* SADB_X_PROMISC */
49126+1<<SADB_EXT_RESERVED
49127+| 1<<SADB_EXT_SA
49128+| 1<<SADB_EXT_LIFETIME_CURRENT
49129+| 1<<SADB_EXT_LIFETIME_HARD
49130+| 1<<SADB_EXT_LIFETIME_SOFT
49131+| 1<<SADB_EXT_ADDRESS_SRC
49132+| 1<<SADB_EXT_ADDRESS_DST
49133+| 1<<SADB_EXT_ADDRESS_PROXY
49134+| 1<<SADB_EXT_KEY_AUTH
49135+| 1<<SADB_EXT_KEY_ENCRYPT
49136+| 1<<SADB_EXT_IDENTITY_SRC
49137+| 1<<SADB_EXT_IDENTITY_DST
49138+| 1<<SADB_EXT_SENSITIVITY
49139+| 1<<SADB_EXT_PROPOSAL
49140+| 1<<SADB_EXT_SUPPORTED_AUTH
49141+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49142+| 1<<SADB_EXT_SPIRANGE
49143+| 1<<SADB_X_EXT_KMPRIVATE
49144+| 1<<SADB_X_EXT_SATYPE2
49145+| 1<<SADB_X_EXT_SA2
49146+| 1<<SADB_X_EXT_ADDRESS_DST2
49147+,
49148+/* SADB_X_PCHANGE */
49149+1<<SADB_EXT_RESERVED
49150+| 1<<SADB_EXT_SA
49151+| 1<<SADB_EXT_LIFETIME_CURRENT
49152+| 1<<SADB_EXT_LIFETIME_HARD
49153+| 1<<SADB_EXT_LIFETIME_SOFT
49154+| 1<<SADB_EXT_ADDRESS_SRC
49155+| 1<<SADB_EXT_ADDRESS_DST
49156+| 1<<SADB_EXT_ADDRESS_PROXY
49157+| 1<<SADB_EXT_KEY_AUTH
49158+| 1<<SADB_EXT_KEY_ENCRYPT
49159+| 1<<SADB_EXT_IDENTITY_SRC
49160+| 1<<SADB_EXT_IDENTITY_DST
49161+| 1<<SADB_EXT_SENSITIVITY
49162+| 1<<SADB_EXT_PROPOSAL
49163+| 1<<SADB_EXT_SUPPORTED_AUTH
49164+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49165+| 1<<SADB_EXT_SPIRANGE
49166+| 1<<SADB_X_EXT_KMPRIVATE
49167+| 1<<SADB_X_EXT_SATYPE2
49168+| 1<<SADB_X_EXT_SA2
49169+| 1<<SADB_X_EXT_ADDRESS_DST2
49170+,
49171+/* SADB_X_GRPSA */
49172+1<<SADB_EXT_RESERVED
49173+| 1<<SADB_EXT_SA
49174+| 1<<SADB_EXT_ADDRESS_DST
49175+,
49176+/* SADB_X_ADDFLOW */
49177+1<<SADB_EXT_RESERVED
49178+| 1<<SADB_EXT_SA
49179+| 1<<SADB_EXT_ADDRESS_DST
49180+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49181+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49182+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49183+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49184+,
49185+/* SADB_X_DELFLOW */
49186+1<<SADB_EXT_RESERVED
49187+/*| 1<<SADB_EXT_SA*/
49188+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49189+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49190+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49191+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49192+,
49193+/* SADB_X_DEBUG */
49194+1<<SADB_EXT_RESERVED
49195+| 1<<SADB_X_EXT_DEBUG
49196+,
49197+/* SADB_X_NAT_T_NEW_MAPPING */
49198+1<<SADB_EXT_RESERVED
49199+| 1<<SADB_EXT_SA
49200+| 1<<SADB_EXT_ADDRESS_SRC
49201+| 1<<SADB_EXT_ADDRESS_DST
49202+| 1<<SADB_X_EXT_NAT_T_SPORT
49203+| 1<<SADB_X_EXT_NAT_T_DPORT
49204+}
49205+}
49206+};
49207+
49208+/*
49209+ * $Log: pfkey_v2_ext_bits.c,v $
49210+ * Revision 1.22 2005/05/11 01:45:31 mcr
49211+ * make pfkey.h standalone.
49212+ *
49213+ * Revision 1.21 2004/07/10 07:48:36 mcr
49214+ * Moved from linux/lib/libfreeswan/pfkey_v2_ext_bits.c,v
49215+ *
49216+ * Revision 1.20 2004/03/08 01:59:08 ken
49217+ * freeswan.h -> openswan.h
49218+ *
49219+ * Revision 1.19 2003/12/22 21:38:13 mcr
49220+ * removed extraenous #endif.
49221+ *
49222+ * Revision 1.18 2003/12/22 19:34:41 mcr
49223+ * added 0.6c NAT-T patch.
49224+ *
49225+ * Revision 1.17 2003/12/10 01:20:19 mcr
49226+ * NAT-traversal patches to KLIPS.
49227+ *
49228+ * Revision 1.16 2003/10/31 02:27:12 mcr
49229+ * pulled up port-selector patches and sa_id elimination.
49230+ *
49231+ * Revision 1.15.30.1 2003/09/21 13:59:44 mcr
49232+ * pre-liminary X.509 patch - does not yet pass tests.
49233+ *
49234+ * Revision 1.15 2002/04/24 07:55:32 mcr
49235+ * #include patches and Makefiles for post-reorg compilation.
49236+ *
49237+ * Revision 1.14 2002/04/24 07:36:40 mcr
49238+ * Moved from ./lib/pfkey_v2_ext_bits.c,v
49239+ *
49240+ * Revision 1.13 2002/01/29 22:25:36 rgb
49241+ * Re-add ipsec_kversion.h to keep MALLOC happy.
49242+ *
49243+ * Revision 1.12 2002/01/29 01:59:10 mcr
49244+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
49245+ * updating of IPv6 structures to match latest in6.h version.
49246+ * removed dead code from openswan.h that also duplicated kversions.h
49247+ * code.
49248+ *
49249+ * Revision 1.11 2001/10/18 04:45:24 rgb
49250+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
49251+ * lib/openswan.h version macros moved to lib/kversions.h.
49252+ * Other compiler directive cleanups.
49253+ *
49254+ * Revision 1.10 2001/09/08 21:13:35 rgb
49255+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
49256+ *
49257+ * Revision 1.9 2001/06/14 19:35:16 rgb
49258+ * Update copyright date.
49259+ *
49260+ * Revision 1.8 2001/03/26 23:07:36 rgb
49261+ * Remove requirement for auth and enc key from UPDATE.
49262+ *
49263+ * Revision 1.7 2000/09/12 22:35:37 rgb
49264+ * Restructured to remove unused extensions from CLEARFLOW messages.
49265+ *
49266+ * Revision 1.6 2000/09/09 06:39:01 rgb
49267+ * Added comments for clarity.
49268+ *
49269+ * Revision 1.5 2000/06/02 22:54:14 rgb
49270+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
49271+ *
49272+ * Revision 1.4 2000/01/21 06:27:56 rgb
49273+ * Added address cases for eroute flows.
49274+ * Added comments for each message type.
49275+ * Added klipsdebug switching capability.
49276+ * Fixed GRPSA bitfields.
49277+ *
49278+ * Revision 1.3 1999/12/01 22:20:27 rgb
49279+ * Remove requirement for a proxy address in an incoming getspi message.
49280+ *
49281+ * Revision 1.2 1999/11/27 11:57:06 rgb
49282+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
49283+ * Add CVS log entry to bottom of file.
49284+ * Cleaned out unused bits.
49285+ *
49286+ */
49287--- /dev/null Tue Mar 11 13:02:56 2003
49288+++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004
49289@@ -0,0 +1,951 @@
49290+/*
49291+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
49292+ * Copyright (C) 1998-2003 Richard Guy Briggs.
49293+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
49294+ *
49295+ * This program is free software; you can redistribute it and/or modify it
49296+ * under the terms of the GNU General Public License as published by the
49297+ * Free Software Foundation; either version 2 of the License, or (at your
49298+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
49299+ *
49300+ * This program is distributed in the hope that it will be useful, but
49301+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
49302+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49303+ * for more details.
49304+ *
49305+ * RCSID $Id: pfkey_v2_ext_process.c,v 1.20.2.2 2006/10/06 21:39:26 paul Exp $
49306+ */
49307+
49308+/*
49309+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
49310+ */
49311+
49312+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 $";
49313+
49314+#ifndef AUTOCONF_INCLUDED
49315+#include <linux/config.h>
49316+#endif
49317+#include <linux/version.h>
49318+#include <linux/kernel.h> /* printk() */
49319+
49320+#include "openswan/ipsec_param.h"
49321+
49322+#ifdef MALLOC_SLAB
49323+# include <linux/slab.h> /* kmalloc() */
49324+#else /* MALLOC_SLAB */
49325+# include <linux/malloc.h> /* kmalloc() */
49326+#endif /* MALLOC_SLAB */
49327+#include <linux/errno.h> /* error codes */
49328+#include <linux/types.h> /* size_t */
49329+#include <linux/interrupt.h> /* mark_bh */
49330+
49331+#include <linux/netdevice.h> /* struct device, and other headers */
49332+#include <linux/etherdevice.h> /* eth_type_trans */
49333+#include <linux/ip.h> /* struct iphdr */
49334+#include <linux/skbuff.h>
49335+
49336+#include <openswan.h>
49337+
49338+#include <crypto/des.h>
49339+
49340+#ifdef SPINLOCK
49341+# ifdef SPINLOCK_23
49342+# include <linux/spinlock.h> /* *lock* */
49343+# else /* SPINLOCK_23 */
49344+# include <asm/spinlock.h> /* *lock* */
49345+# endif /* SPINLOCK_23 */
49346+#endif /* SPINLOCK */
49347+#ifdef NET_21
49348+# include <linux/in6.h>
49349+# define ip_chk_addr inet_addr_type
49350+# define IS_MYADDR RTN_LOCAL
49351+#endif
49352+
49353+#include <net/ip.h>
49354+#ifdef NETLINK_SOCK
49355+# include <linux/netlink.h>
49356+#else
49357+# include <net/netlink.h>
49358+#endif
49359+
49360+#include <linux/random.h> /* get_random_bytes() */
49361+
49362+#include "openswan/radij.h"
49363+#include "openswan/ipsec_encap.h"
49364+#include "openswan/ipsec_sa.h"
49365+
49366+#include "openswan/ipsec_radij.h"
49367+#include "openswan/ipsec_xform.h"
49368+#include "openswan/ipsec_ah.h"
49369+#include "openswan/ipsec_esp.h"
49370+#include "openswan/ipsec_tunnel.h"
49371+#include "openswan/ipsec_rcv.h"
49372+#include "openswan/ipcomp.h"
49373+
49374+#include <pfkeyv2.h>
49375+#include <pfkey.h>
49376+
49377+#include "openswan/ipsec_proto.h"
49378+#include "openswan/ipsec_alg.h"
49379+
49380+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
49381+
49382+int
49383+pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49384+{
49385+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
49386+ int error = 0;
49387+ struct ipsec_sa* ipsp;
49388+
49389+ KLIPS_PRINT(debug_pfkey,
49390+ "klips_debug:pfkey_sa_process: .\n");
49391+
49392+ if(!extr || !extr->ips) {
49393+ KLIPS_PRINT(debug_pfkey,
49394+ "klips_debug:pfkey_sa_process: "
49395+ "extr or extr->ips is NULL, fatal\n");
49396+ SENDERR(EINVAL);
49397+ }
49398+
49399+ switch(pfkey_ext->sadb_ext_type) {
49400+ case SADB_EXT_SA:
49401+ ipsp = extr->ips;
49402+ break;
49403+ case SADB_X_EXT_SA2:
49404+ if(extr->ips2 == NULL) {
49405+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49406+ }
49407+ if(extr->ips2 == NULL) {
49408+ SENDERR(-error);
49409+ }
49410+ ipsp = extr->ips2;
49411+ break;
49412+ default:
49413+ KLIPS_PRINT(debug_pfkey,
49414+ "klips_debug:pfkey_sa_process: "
49415+ "invalid exttype=%d.\n",
49416+ pfkey_ext->sadb_ext_type);
49417+ SENDERR(EINVAL);
49418+ }
49419+
49420+ ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
49421+ ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
49422+ ipsp->ips_state = pfkey_sa->sadb_sa_state;
49423+ ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
49424+ ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
49425+ ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref;
49426+
49427+ switch(ipsp->ips_said.proto) {
49428+ case IPPROTO_AH:
49429+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
49430+ ipsp->ips_encalg = SADB_EALG_NONE;
49431+ break;
49432+ case IPPROTO_ESP:
49433+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
49434+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
49435+ ipsec_alg_sa_init(ipsp);
49436+ break;
49437+ case IPPROTO_IPIP:
49438+ ipsp->ips_authalg = AH_NONE;
49439+ ipsp->ips_encalg = ESP_NONE;
49440+ break;
49441+#ifdef CONFIG_KLIPS_IPCOMP
49442+ case IPPROTO_COMP:
49443+ ipsp->ips_authalg = AH_NONE;
49444+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
49445+ break;
49446+#endif /* CONFIG_KLIPS_IPCOMP */
49447+ case IPPROTO_INT:
49448+ ipsp->ips_authalg = AH_NONE;
49449+ ipsp->ips_encalg = ESP_NONE;
49450+ break;
49451+ case 0:
49452+ break;
49453+ default:
49454+ KLIPS_PRINT(debug_pfkey,
49455+ "klips_debug:pfkey_sa_process: "
49456+ "unknown proto=%d.\n",
49457+ ipsp->ips_said.proto);
49458+ SENDERR(EINVAL);
49459+ }
49460+
49461+errlab:
49462+ return error;
49463+}
49464+
49465+int
49466+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49467+{
49468+ int error = 0;
49469+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
49470+
49471+ KLIPS_PRINT(debug_pfkey,
49472+ "klips_debug:pfkey_lifetime_process: .\n");
49473+
49474+ if(!extr || !extr->ips) {
49475+ KLIPS_PRINT(debug_pfkey,
49476+ "klips_debug:pfkey_lifetime_process: "
49477+ "extr or extr->ips is NULL, fatal\n");
49478+ SENDERR(EINVAL);
49479+ }
49480+
49481+ switch(pfkey_lifetime->sadb_lifetime_exttype) {
49482+ case SADB_EXT_LIFETIME_CURRENT:
49483+ KLIPS_PRINT(debug_pfkey,
49484+ "klips_debug:pfkey_lifetime_process: "
49485+ "lifetime_current not supported yet.\n");
49486+ SENDERR(EINVAL);
49487+ break;
49488+ case SADB_EXT_LIFETIME_HARD:
49489+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
49490+ pfkey_lifetime->sadb_lifetime_allocations);
49491+
49492+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
49493+ pfkey_lifetime->sadb_lifetime_bytes);
49494+
49495+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
49496+ pfkey_lifetime->sadb_lifetime_addtime);
49497+
49498+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
49499+ pfkey_lifetime->sadb_lifetime_usetime);
49500+
49501+ break;
49502+
49503+ case SADB_EXT_LIFETIME_SOFT:
49504+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
49505+ pfkey_lifetime->sadb_lifetime_allocations);
49506+
49507+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
49508+ pfkey_lifetime->sadb_lifetime_bytes);
49509+
49510+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
49511+ pfkey_lifetime->sadb_lifetime_addtime);
49512+
49513+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
49514+ pfkey_lifetime->sadb_lifetime_usetime);
49515+
49516+ break;
49517+ default:
49518+ KLIPS_PRINT(debug_pfkey,
49519+ "klips_debug:pfkey_lifetime_process: "
49520+ "invalid exttype=%d.\n",
49521+ pfkey_ext->sadb_ext_type);
49522+ SENDERR(EINVAL);
49523+ }
49524+
49525+errlab:
49526+ return error;
49527+}
49528+
49529+int
49530+pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49531+{
49532+ int error = 0;
49533+ int saddr_len = 0;
49534+ char ipaddr_txt[ADDRTOA_BUF];
49535+ unsigned char **sap;
49536+ unsigned short * portp = 0;
49537+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
49538+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
49539+ struct ipsec_sa* ipsp;
49540+
49541+ KLIPS_PRINT(debug_pfkey,
49542+ "klips_debug:pfkey_address_process:\n");
49543+
49544+ if(!extr || !extr->ips) {
49545+ KLIPS_PRINT(debug_pfkey,
49546+ "klips_debug:pfkey_address_process: "
49547+ "extr or extr->ips is NULL, fatal\n");
49548+ SENDERR(EINVAL);
49549+ }
49550+
49551+ switch(s->sa_family) {
49552+ case AF_INET:
49553+ saddr_len = sizeof(struct sockaddr_in);
49554+ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
49555+ KLIPS_PRINT(debug_pfkey,
49556+ "klips_debug:pfkey_address_process: "
49557+ "found address family=%d, AF_INET, %s.\n",
49558+ s->sa_family,
49559+ ipaddr_txt);
49560+ break;
49561+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
49562+ case AF_INET6:
49563+ saddr_len = sizeof(struct sockaddr_in6);
49564+ break;
49565+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
49566+ default:
49567+ KLIPS_PRINT(debug_pfkey,
49568+ "klips_debug:pfkey_address_process: "
49569+ "s->sa_family=%d not supported.\n",
49570+ s->sa_family);
49571+ SENDERR(EPFNOSUPPORT);
49572+ }
49573+
49574+ switch(pfkey_address->sadb_address_exttype) {
49575+ case SADB_EXT_ADDRESS_SRC:
49576+ KLIPS_PRINT(debug_pfkey,
49577+ "klips_debug:pfkey_address_process: "
49578+ "found src address.\n");
49579+ sap = (unsigned char **)&(extr->ips->ips_addr_s);
49580+ extr->ips->ips_addr_s_size = saddr_len;
49581+ break;
49582+ case SADB_EXT_ADDRESS_DST:
49583+ KLIPS_PRINT(debug_pfkey,
49584+ "klips_debug:pfkey_address_process: "
49585+ "found dst address.\n");
49586+ sap = (unsigned char **)&(extr->ips->ips_addr_d);
49587+ extr->ips->ips_addr_d_size = saddr_len;
49588+ break;
49589+ case SADB_EXT_ADDRESS_PROXY:
49590+ KLIPS_PRINT(debug_pfkey,
49591+ "klips_debug:pfkey_address_process: "
49592+ "found proxy address.\n");
49593+ sap = (unsigned char **)&(extr->ips->ips_addr_p);
49594+ extr->ips->ips_addr_p_size = saddr_len;
49595+ break;
49596+ case SADB_X_EXT_ADDRESS_DST2:
49597+ KLIPS_PRINT(debug_pfkey,
49598+ "klips_debug:pfkey_address_process: "
49599+ "found 2nd dst address.\n");
49600+ if(extr->ips2 == NULL) {
49601+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49602+ }
49603+ if(extr->ips2 == NULL) {
49604+ SENDERR(-error);
49605+ }
49606+ sap = (unsigned char **)&(extr->ips2->ips_addr_d);
49607+ extr->ips2->ips_addr_d_size = saddr_len;
49608+ break;
49609+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
49610+ KLIPS_PRINT(debug_pfkey,
49611+ "klips_debug:pfkey_address_process: "
49612+ "found src flow address.\n");
49613+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49614+ SENDERR(ENOMEM);
49615+ }
49616+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
49617+ portp = &(extr->eroute->er_eaddr.sen_sport);
49618+ break;
49619+ case SADB_X_EXT_ADDRESS_DST_FLOW:
49620+ KLIPS_PRINT(debug_pfkey,
49621+ "klips_debug:pfkey_address_process: "
49622+ "found dst flow address.\n");
49623+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49624+ SENDERR(ENOMEM);
49625+ }
49626+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
49627+ portp = &(extr->eroute->er_eaddr.sen_dport);
49628+ break;
49629+ case SADB_X_EXT_ADDRESS_SRC_MASK:
49630+ KLIPS_PRINT(debug_pfkey,
49631+ "klips_debug:pfkey_address_process: "
49632+ "found src mask address.\n");
49633+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49634+ SENDERR(ENOMEM);
49635+ }
49636+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
49637+ portp = &(extr->eroute->er_emask.sen_sport);
49638+ break;
49639+ case SADB_X_EXT_ADDRESS_DST_MASK:
49640+ KLIPS_PRINT(debug_pfkey,
49641+ "klips_debug:pfkey_address_process: "
49642+ "found dst mask address.\n");
49643+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49644+ SENDERR(ENOMEM);
49645+ }
49646+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
49647+ portp = &(extr->eroute->er_emask.sen_dport);
49648+ break;
49649+#ifdef NAT_TRAVERSAL
49650+ case SADB_X_EXT_NAT_T_OA:
49651+ KLIPS_PRINT(debug_pfkey,
49652+ "klips_debug:pfkey_address_process: "
49653+ "found NAT-OA address.\n");
49654+ sap = (unsigned char **)&(extr->ips->ips_natt_oa);
49655+ extr->ips->ips_natt_oa_size = saddr_len;
49656+ break;
49657+#endif
49658+ default:
49659+ KLIPS_PRINT(debug_pfkey,
49660+ "klips_debug:pfkey_address_process: "
49661+ "unrecognised ext_type=%d.\n",
49662+ pfkey_address->sadb_address_exttype);
49663+ SENDERR(EINVAL);
49664+ }
49665+
49666+ switch(pfkey_address->sadb_address_exttype) {
49667+ case SADB_EXT_ADDRESS_SRC:
49668+ case SADB_EXT_ADDRESS_DST:
49669+ case SADB_EXT_ADDRESS_PROXY:
49670+ case SADB_X_EXT_ADDRESS_DST2:
49671+#ifdef NAT_TRAVERSAL
49672+ case SADB_X_EXT_NAT_T_OA:
49673+#endif
49674+ KLIPS_PRINT(debug_pfkey,
49675+ "klips_debug:pfkey_address_process: "
49676+ "allocating %d bytes for saddr.\n",
49677+ saddr_len);
49678+ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
49679+ SENDERR(ENOMEM);
49680+ }
49681+ memcpy(*sap, s, saddr_len);
49682+ break;
49683+ default:
49684+ if(s->sa_family != AF_INET) {
49685+ KLIPS_PRINT(debug_pfkey,
49686+ "klips_debug:pfkey_address_process: "
49687+ "s->sa_family=%d not supported.\n",
49688+ s->sa_family);
49689+ SENDERR(EPFNOSUPPORT);
49690+ }
49691+ {
49692+ unsigned long *ulsap = (unsigned long *)sap;
49693+ *ulsap = ((struct sockaddr_in*)s)->sin_addr.s_addr;
49694+ }
49695+
49696+ if (portp != 0)
49697+ *portp = ((struct sockaddr_in*)s)->sin_port;
49698+#ifdef CONFIG_KLIPS_DEBUG
49699+ if(extr->eroute) {
49700+ char buf1[64], buf2[64];
49701+ if (debug_pfkey) {
49702+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
49703+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
49704+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
49705+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
49706+ KLIPS_PRINT(debug_pfkey,
49707+ "klips_debug:pfkey_address_parse: "
49708+ "extr->eroute set to %s:%d->%s:%d\n",
49709+ buf1,
49710+ ntohs(extr->eroute->er_eaddr.sen_sport),
49711+ buf2,
49712+ ntohs(extr->eroute->er_eaddr.sen_dport));
49713+ }
49714+ }
49715+#endif /* CONFIG_KLIPS_DEBUG */
49716+ }
49717+
49718+ ipsp = extr->ips;
49719+ switch(pfkey_address->sadb_address_exttype) {
49720+ case SADB_X_EXT_ADDRESS_DST2:
49721+ ipsp = extr->ips2;
49722+ case SADB_EXT_ADDRESS_DST:
49723+ if(s->sa_family == AF_INET) {
49724+ ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
49725+ ipsp->ips_said.dst.u.v4.sin_family = AF_INET;
49726+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
49727+ 0,
49728+ ipaddr_txt,
49729+ sizeof(ipaddr_txt));
49730+ KLIPS_PRINT(debug_pfkey,
49731+ "klips_debug:pfkey_address_process: "
49732+ "ips_said.dst set to %s.\n",
49733+ ipaddr_txt);
49734+ } else {
49735+ KLIPS_PRINT(debug_pfkey,
49736+ "klips_debug:pfkey_address_process: "
49737+ "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
49738+ s->sa_family);
49739+ }
49740+ default:
49741+ break;
49742+ }
49743+
49744+ /* XXX check if port!=0 */
49745+
49746+ KLIPS_PRINT(debug_pfkey,
49747+ "klips_debug:pfkey_address_process: successful.\n");
49748+ errlab:
49749+ return error;
49750+}
49751+
49752+int
49753+pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49754+{
49755+ int error = 0;
49756+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
49757+
49758+ KLIPS_PRINT(debug_pfkey,
49759+ "klips_debug:pfkey_key_process: .\n");
49760+
49761+ if(!extr || !extr->ips) {
49762+ KLIPS_PRINT(debug_pfkey,
49763+ "klips_debug:pfkey_key_process: "
49764+ "extr or extr->ips is NULL, fatal\n");
49765+ SENDERR(EINVAL);
49766+ }
49767+
49768+ switch(pfkey_key->sadb_key_exttype) {
49769+ case SADB_EXT_KEY_AUTH:
49770+ KLIPS_PRINT(debug_pfkey,
49771+ "klips_debug:pfkey_key_process: "
49772+ "allocating %d bytes for authkey.\n",
49773+ DIVUP(pfkey_key->sadb_key_bits, 8));
49774+ if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
49775+ KLIPS_PRINT(debug_pfkey,
49776+ "klips_debug:pfkey_key_process: "
49777+ "memory allocation error.\n");
49778+ SENDERR(ENOMEM);
49779+ }
49780+ extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
49781+ extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
49782+ memcpy(extr->ips->ips_key_a,
49783+ (char*)pfkey_key + sizeof(struct sadb_key),
49784+ extr->ips->ips_key_a_size);
49785+ break;
49786+ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
49787+ KLIPS_PRINT(debug_pfkey,
49788+ "klips_debug:pfkey_key_process: "
49789+ "allocating %d bytes for enckey.\n",
49790+ DIVUP(pfkey_key->sadb_key_bits, 8));
49791+ if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
49792+ KLIPS_PRINT(debug_pfkey,
49793+ "klips_debug:pfkey_key_process: "
49794+ "memory allocation error.\n");
49795+ SENDERR(ENOMEM);
49796+ }
49797+ extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
49798+ extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
49799+ memcpy(extr->ips->ips_key_e,
49800+ (char*)pfkey_key + sizeof(struct sadb_key),
49801+ extr->ips->ips_key_e_size);
49802+ break;
49803+ default:
49804+ SENDERR(EINVAL);
49805+ }
49806+
49807+ KLIPS_PRINT(debug_pfkey,
49808+ "klips_debug:pfkey_key_process: "
49809+ "success.\n");
49810+errlab:
49811+ return error;
49812+}
49813+
49814+int
49815+pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49816+{
49817+ int error = 0;
49818+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
49819+ int data_len;
49820+
49821+ KLIPS_PRINT(debug_pfkey,
49822+ "klips_debug:pfkey_ident_process: .\n");
49823+
49824+ if(!extr || !extr->ips) {
49825+ KLIPS_PRINT(debug_pfkey,
49826+ "klips_debug:pfkey_ident_process: "
49827+ "extr or extr->ips is NULL, fatal\n");
49828+ SENDERR(EINVAL);
49829+ }
49830+
49831+ switch(pfkey_ident->sadb_ident_exttype) {
49832+ case SADB_EXT_IDENTITY_SRC:
49833+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
49834+
49835+ extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
49836+ extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
49837+ extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
49838+ if(data_len) {
49839+ KLIPS_PRINT(debug_pfkey,
49840+ "klips_debug:pfkey_ident_process: "
49841+ "allocating %d bytes for ident_s.\n",
49842+ data_len);
49843+ if(!(extr->ips->ips_ident_s.data
49844+ = kmalloc(data_len, GFP_KERNEL))) {
49845+ SENDERR(ENOMEM);
49846+ }
49847+ memcpy(extr->ips->ips_ident_s.data,
49848+ (char*)pfkey_ident + sizeof(struct sadb_ident),
49849+ data_len);
49850+ } else {
49851+ extr->ips->ips_ident_s.data = NULL;
49852+ }
49853+ break;
49854+ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
49855+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
49856+
49857+ extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
49858+ extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
49859+ extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
49860+ if(data_len) {
49861+ KLIPS_PRINT(debug_pfkey,
49862+ "klips_debug:pfkey_ident_process: "
49863+ "allocating %d bytes for ident_d.\n",
49864+ data_len);
49865+ if(!(extr->ips->ips_ident_d.data
49866+ = kmalloc(data_len, GFP_KERNEL))) {
49867+ SENDERR(ENOMEM);
49868+ }
49869+ memcpy(extr->ips->ips_ident_d.data,
49870+ (char*)pfkey_ident + sizeof(struct sadb_ident),
49871+ data_len);
49872+ } else {
49873+ extr->ips->ips_ident_d.data = NULL;
49874+ }
49875+ break;
49876+ default:
49877+ SENDERR(EINVAL);
49878+ }
49879+errlab:
49880+ return error;
49881+}
49882+
49883+int
49884+pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49885+{
49886+ int error = 0;
49887+
49888+ KLIPS_PRINT(debug_pfkey,
49889+ "klips_debug:pfkey_sens_process: "
49890+ "Sorry, I can't process exttype=%d yet.\n",
49891+ pfkey_ext->sadb_ext_type);
49892+ SENDERR(EINVAL); /* don't process these yet */
49893+ errlab:
49894+ return error;
49895+}
49896+
49897+int
49898+pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49899+{
49900+ int error = 0;
49901+
49902+ KLIPS_PRINT(debug_pfkey,
49903+ "klips_debug:pfkey_prop_process: "
49904+ "Sorry, I can't process exttype=%d yet.\n",
49905+ pfkey_ext->sadb_ext_type);
49906+ SENDERR(EINVAL); /* don't process these yet */
49907+
49908+ errlab:
49909+ return error;
49910+}
49911+
49912+int
49913+pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49914+{
49915+ int error = 0;
49916+
49917+ KLIPS_PRINT(debug_pfkey,
49918+ "klips_debug:pfkey_supported_process: "
49919+ "Sorry, I can't process exttype=%d yet.\n",
49920+ pfkey_ext->sadb_ext_type);
49921+ SENDERR(EINVAL); /* don't process these yet */
49922+
49923+errlab:
49924+ return error;
49925+}
49926+
49927+int
49928+pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49929+{
49930+ int error = 0;
49931+
49932+ KLIPS_PRINT(debug_pfkey,
49933+ "klips_debug:pfkey_spirange_process: .\n");
49934+/* errlab: */
49935+ return error;
49936+}
49937+
49938+int
49939+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49940+{
49941+ int error = 0;
49942+
49943+ KLIPS_PRINT(debug_pfkey,
49944+ "klips_debug:pfkey_x_kmprivate_process: "
49945+ "Sorry, I can't process exttype=%d yet.\n",
49946+ pfkey_ext->sadb_ext_type);
49947+ SENDERR(EINVAL); /* don't process these yet */
49948+
49949+errlab:
49950+ return error;
49951+}
49952+
49953+int
49954+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49955+{
49956+ int error = 0;
49957+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
49958+
49959+ KLIPS_PRINT(debug_pfkey,
49960+ "klips_debug:pfkey_x_satype_process: .\n");
49961+
49962+ if(!extr || !extr->ips) {
49963+ KLIPS_PRINT(debug_pfkey,
49964+ "klips_debug:pfkey_x_satype_process: "
49965+ "extr or extr->ips is NULL, fatal\n");
49966+ SENDERR(EINVAL);
49967+ }
49968+
49969+ if(extr->ips2 == NULL) {
49970+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49971+ }
49972+ if(extr->ips2 == NULL) {
49973+ SENDERR(-error);
49974+ }
49975+ if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
49976+ KLIPS_PRINT(debug_pfkey,
49977+ "klips_debug:pfkey_x_satype_process: "
49978+ "proto lookup from satype=%d failed.\n",
49979+ pfkey_x_satype->sadb_x_satype_satype);
49980+ SENDERR(EINVAL);
49981+ }
49982+ KLIPS_PRINT(debug_pfkey,
49983+ "klips_debug:pfkey_x_satype_process: "
49984+ "protocol==%d decoded from satype==%d(%s).\n",
49985+ extr->ips2->ips_said.proto,
49986+ pfkey_x_satype->sadb_x_satype_satype,
49987+ satype2name(pfkey_x_satype->sadb_x_satype_satype));
49988+
49989+errlab:
49990+ return error;
49991+}
49992+
49993+
49994+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
49995+int
49996+pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49997+{
49998+ int error = 0;
49999+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
50000+
50001+ if(!pfkey_x_nat_t_type) {
50002+ printk("klips_debug:pfkey_x_nat_t_type_process: "
50003+ "null pointer passed in\n");
50004+ SENDERR(EINVAL);
50005+ }
50006+
50007+ KLIPS_PRINT(debug_pfkey,
50008+ "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
50009+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
50010+
50011+ if(!extr || !extr->ips) {
50012+ KLIPS_PRINT(debug_pfkey,
50013+ "klips_debug:pfkey_nat_t_type_process: "
50014+ "extr or extr->ips is NULL, fatal\n");
50015+ SENDERR(EINVAL);
50016+ }
50017+
50018+ switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
50019+ case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */
50020+ case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
50021+
50022+ extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
50023+ break;
50024+ default:
50025+ KLIPS_PRINT(debug_pfkey,
50026+ "klips_debug:pfkey_x_nat_t_type_process: "
50027+ "unknown type %d.\n",
50028+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
50029+ SENDERR(EINVAL);
50030+ break;
50031+ }
50032+
50033+errlab:
50034+ return error;
50035+}
50036+
50037+int
50038+pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50039+{
50040+ int error = 0;
50041+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
50042+
50043+ if(!pfkey_x_nat_t_port) {
50044+ printk("klips_debug:pfkey_x_nat_t_port_process: "
50045+ "null pointer passed in\n");
50046+ SENDERR(EINVAL);
50047+ }
50048+
50049+ KLIPS_PRINT(debug_pfkey,
50050+ "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
50051+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
50052+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
50053+
50054+ if(!extr || !extr->ips) {
50055+ KLIPS_PRINT(debug_pfkey,
50056+ "klips_debug:pfkey_nat_t_type_process: "
50057+ "extr or extr->ips is NULL, fatal\n");
50058+ SENDERR(EINVAL);
50059+ }
50060+
50061+ switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
50062+ case SADB_X_EXT_NAT_T_SPORT:
50063+ extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
50064+ break;
50065+ case SADB_X_EXT_NAT_T_DPORT:
50066+ extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
50067+ break;
50068+ default:
50069+ KLIPS_PRINT(debug_pfkey,
50070+ "klips_debug:pfkey_x_nat_t_port_process: "
50071+ "unknown exttype %d.\n",
50072+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
50073+ SENDERR(EINVAL);
50074+ break;
50075+ }
50076+
50077+errlab:
50078+ return error;
50079+}
50080+#endif
50081+
50082+int
50083+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50084+{
50085+ int error = 0;
50086+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
50087+
50088+ if(!pfkey_x_debug) {
50089+ printk("klips_debug:pfkey_x_debug_process: "
50090+ "null pointer passed in\n");
50091+ SENDERR(EINVAL);
50092+ }
50093+
50094+ KLIPS_PRINT(debug_pfkey,
50095+ "klips_debug:pfkey_x_debug_process: .\n");
50096+
50097+#ifdef CONFIG_KLIPS_DEBUG
50098+ if(pfkey_x_debug->sadb_x_debug_netlink >>
50099+ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
50100+ pfkey_x_debug->sadb_x_debug_netlink &=
50101+ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
50102+ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
50103+ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
50104+ debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
50105+ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
50106+ debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
50107+ debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
50108+ debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
50109+ debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
50110+ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
50111+ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
50112+#ifdef CONFIG_KLIPS_IPCOMP
50113+ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
50114+#endif /* CONFIG_KLIPS_IPCOMP */
50115+ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
50116+ KLIPS_PRINT(debug_pfkey,
50117+ "klips_debug:pfkey_x_debug_process: "
50118+ "set\n");
50119+ } else {
50120+ KLIPS_PRINT(debug_pfkey,
50121+ "klips_debug:pfkey_x_debug_process: "
50122+ "unset\n");
50123+ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
50124+ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
50125+ debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
50126+ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
50127+ debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
50128+ debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
50129+ debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
50130+ debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
50131+ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
50132+ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
50133+#ifdef CONFIG_KLIPS_IPCOMP
50134+ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
50135+#endif /* CONFIG_KLIPS_IPCOMP */
50136+ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
50137+ }
50138+#else /* CONFIG_KLIPS_DEBUG */
50139+ printk("klips_debug:pfkey_x_debug_process: "
50140+ "debugging not enabled\n");
50141+ SENDERR(EINVAL);
50142+#endif /* CONFIG_KLIPS_DEBUG */
50143+
50144+errlab:
50145+ return error;
50146+}
50147+
50148+/*
50149+ * $Log: pfkey_v2_ext_process.c,v $
50150+ * Revision 1.20.2.2 2006/10/06 21:39:26 paul
50151+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
50152+ * set. This is defined through autoconf.h which is included through the
50153+ * linux kernel build macros.
50154+ *
50155+ * Revision 1.20.2.1 2006/04/20 16:33:07 mcr
50156+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
50157+ * Fix in-kernel module compilation. Sub-makefiles do not work.
50158+ *
50159+ * Revision 1.20 2005/04/29 05:10:22 mcr
50160+ * removed from extraenous includes to make unit testing easier.
50161+ *
50162+ * Revision 1.19 2004/12/04 07:14:18 mcr
50163+ * resolution to gcc3-ism was wrong. fixed to assign correct
50164+ * variable.
50165+ *
50166+ * Revision 1.18 2004/12/03 21:25:57 mcr
50167+ * compile time fixes for running on 2.6.
50168+ * still experimental.
50169+ *
50170+ * Revision 1.17 2004/08/21 00:45:04 mcr
50171+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
50172+ *
50173+ * Revision 1.16 2004/07/10 19:11:18 mcr
50174+ * CONFIG_IPSEC -> CONFIG_KLIPS.
50175+ *
50176+ * Revision 1.15 2004/04/06 02:49:26 mcr
50177+ * pullup of algo code from alg-branch.
50178+ *
50179+ * Revision 1.14 2004/02/03 03:13:59 mcr
50180+ * no longer #ifdef out NON_ESP mode. That was a mistake.
50181+ *
50182+ * Revision 1.13 2003/12/15 18:13:12 mcr
50183+ * when compiling with NAT traversal, don't assume that the
50184+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
50185+ * is set.
50186+ *
50187+ * Revision 1.12.2.1 2003/12/22 15:25:52 jjo
50188+ * Merged algo-0.8.1-rc11-test1 into alg-branch
50189+ *
50190+ * Revision 1.12 2003/12/10 01:14:27 mcr
50191+ * NAT-traversal patches to KLIPS.
50192+ *
50193+ * Revision 1.11 2003/10/31 02:27:55 mcr
50194+ * pulled up port-selector patches and sa_id elimination.
50195+ *
50196+ * Revision 1.10.4.2 2003/10/29 01:30:41 mcr
50197+ * elimited "struct sa_id".
50198+ *
50199+ * Revision 1.10.4.1 2003/09/21 13:59:56 mcr
50200+ * pre-liminary X.509 patch - does not yet pass tests.
50201+ *
50202+ * Revision 1.10 2003/02/06 01:51:41 rgb
50203+ * Removed no longer relevant comment
50204+ *
50205+ * Revision 1.9 2003/01/30 02:32:44 rgb
50206+ *
50207+ * Transmit error code through to caller from callee for better diagnosis of problems.
50208+ *
50209+ * Revision 1.8 2002/12/13 22:42:22 mcr
50210+ * restored sa_ref code
50211+ *
50212+ * Revision 1.7 2002/12/13 22:40:48 mcr
50213+ * temporarily removed sadb_x_sa_ref reference for 2.xx
50214+ *
50215+ * Revision 1.6 2002/10/05 05:02:58 dhr
50216+ *
50217+ * C labels go on statements
50218+ *
50219+ * Revision 1.5 2002/09/20 15:41:08 rgb
50220+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
50221+ * Added sadb_x_sa_ref to struct sadb_sa.
50222+ *
50223+ * Revision 1.4 2002/09/20 05:02:02 rgb
50224+ * Added memory allocation debugging.
50225+ *
50226+ * Revision 1.3 2002/07/24 18:44:54 rgb
50227+ * Type fiddling to tame ia64 compiler.
50228+ *
50229+ * Revision 1.2 2002/05/27 18:55:03 rgb
50230+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
50231+ *
50232+ * Revision 1.1 2002/05/14 02:33:51 rgb
50233+ * Moved all the extension processing functions to pfkey_v2_ext_process.c.
50234+ *
50235+ *
50236+ * Local variables:
50237+ * c-file-style: "linux"
50238+ * End:
50239+ *
50240+ */
50241--- /dev/null Tue Mar 11 13:02:56 2003
50242+++ linux/net/ipsec/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004
50243@@ -0,0 +1,1846 @@
50244+/*
50245+ * RFC2367 PF_KEYv2 Key management API message parser
50246+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
50247+ *
50248+ * This program is free software; you can redistribute it and/or modify it
50249+ * under the terms of the GNU General Public License as published by the
50250+ * Free Software Foundation; either version 2 of the License, or (at your
50251+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
50252+ *
50253+ * This program is distributed in the hope that it will be useful, but
50254+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
50255+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50256+ * for more details.
50257+ *
50258+ * RCSID $Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $
50259+ */
50260+
50261+/*
50262+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
50263+ */
50264+
50265+char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $";
50266+
50267+/*
50268+ * Some ugly stuff to allow consistent debugging code for use in the
50269+ * kernel and in user space
50270+*/
50271+
50272+#ifdef __KERNEL__
50273+
50274+# include <linux/kernel.h> /* for printk */
50275+
50276+#include "openswan/ipsec_kversion.h" /* for malloc switch */
50277+
50278+# ifdef MALLOC_SLAB
50279+# include <linux/slab.h> /* kmalloc() */
50280+# else /* MALLOC_SLAB */
50281+# include <linux/malloc.h> /* kmalloc() */
50282+# endif /* MALLOC_SLAB */
50283+# include <linux/errno.h> /* error codes */
50284+# include <linux/types.h> /* size_t */
50285+# include <linux/interrupt.h> /* mark_bh */
50286+
50287+# include <linux/netdevice.h> /* struct device, and other headers */
50288+# include <linux/etherdevice.h> /* eth_type_trans */
50289+# include <linux/ip.h> /* struct iphdr */
50290+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
50291+# include <linux/ipv6.h> /* struct ipv6hdr */
50292+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
50293+extern int debug_pfkey;
50294+
50295+# include <openswan.h>
50296+
50297+#include "openswan/ipsec_encap.h"
50298+
50299+#else /* __KERNEL__ */
50300+
50301+# include <sys/types.h>
50302+# include <linux/types.h>
50303+# include <linux/errno.h>
50304+
50305+# include <openswan.h>
50306+# include "constants.h"
50307+# include "programs/pluto/defs.h" /* for PRINTF_LIKE */
50308+
50309+#endif /* __KERNEL__ */
50310+
50311+
50312+#include <pfkeyv2.h>
50313+#include <pfkey.h>
50314+
50315+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
50316+
50317+/*
50318+ * how to handle debugging for pfkey.
50319+ */
50320+#include <openswan/pfkey_debug.h>
50321+
50322+unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;
50323+void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
50324+void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
50325+
50326+
50327+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
50328+
50329+struct satype_tbl {
50330+ uint8_t proto;
50331+ uint8_t satype;
50332+ char* name;
50333+} static satype_tbl[] = {
50334+#ifdef __KERNEL__
50335+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
50336+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
50337+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
50338+#ifdef CONFIG_KLIPS_IPCOMP
50339+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
50340+#endif /* CONFIG_KLIPS_IPCOMP */
50341+ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
50342+#else /* __KERNEL__ */
50343+ { SA_ESP, SADB_SATYPE_ESP, "ESP" },
50344+ { SA_AH, SADB_SATYPE_AH, "AH" },
50345+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
50346+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
50347+ { SA_INT, SADB_X_SATYPE_INT, "INT" },
50348+#endif /* __KERNEL__ */
50349+ { 0, 0, "UNKNOWN" }
50350+};
50351+
50352+uint8_t
50353+satype2proto(uint8_t satype)
50354+{
50355+ int i =0;
50356+
50357+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
50358+ i++;
50359+ }
50360+ return satype_tbl[i].proto;
50361+}
50362+
50363+uint8_t
50364+proto2satype(uint8_t proto)
50365+{
50366+ int i = 0;
50367+
50368+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
50369+ i++;
50370+ }
50371+ return satype_tbl[i].satype;
50372+}
50373+
50374+char*
50375+satype2name(uint8_t satype)
50376+{
50377+ int i = 0;
50378+
50379+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
50380+ i++;
50381+ }
50382+ return satype_tbl[i].name;
50383+}
50384+
50385+char*
50386+proto2name(uint8_t proto)
50387+{
50388+ int i = 0;
50389+
50390+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
50391+ i++;
50392+ }
50393+ return satype_tbl[i].name;
50394+}
50395+
50396+/* Default extension parsers taken from the KLIPS code */
50397+
50398+DEBUG_NO_STATIC int
50399+pfkey_sa_parse(struct sadb_ext *pfkey_ext)
50400+{
50401+ int error = 0;
50402+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
50403+#if 0
50404+ struct sadb_sa sav2;
50405+#endif
50406+
50407+ /* sanity checks... */
50408+ if(!pfkey_sa) {
50409+ ERROR("pfkey_sa_parse: "
50410+ "NULL pointer passed in.\n");
50411+ SENDERR(EINVAL);
50412+ }
50413+
50414+#if 0
50415+ /* check if this structure is short, and if so, fix it up.
50416+ * XXX this is NOT the way to do things.
50417+ */
50418+ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
50419+
50420+ /* yes, so clear out a temporary structure, and copy first */
50421+ memset(&sav2, 0, sizeof(sav2));
50422+ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
50423+ sav2.sadb_x_sa_ref=-1;
50424+ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
50425+
50426+ pfkey_sa = &sav2;
50427+ }
50428+#endif
50429+
50430+
50431+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
50432+ ERROR(
50433+ "pfkey_sa_parse: "
50434+ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
50435+ pfkey_sa->sadb_sa_len,
50436+ (int)sizeof(struct sadb_sa));
50437+ SENDERR(EINVAL);
50438+ }
50439+
50440+#if SADB_EALG_MAX < 255
50441+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
50442+ ERROR(
50443+ "pfkey_sa_parse: "
50444+ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
50445+ pfkey_sa->sadb_sa_encrypt,
50446+ SADB_EALG_MAX);
50447+ SENDERR(EINVAL);
50448+ }
50449+#endif
50450+
50451+#if SADB_AALG_MAX < 255
50452+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
50453+ ERROR(
50454+ "pfkey_sa_parse: "
50455+ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
50456+ pfkey_sa->sadb_sa_auth,
50457+ SADB_AALG_MAX);
50458+ SENDERR(EINVAL);
50459+ }
50460+#endif
50461+
50462+#if SADB_SASTATE_MAX < 255
50463+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
50464+ ERROR(
50465+ "pfkey_sa_parse: "
50466+ "state=%d exceeds MAX=%d.\n",
50467+ pfkey_sa->sadb_sa_state,
50468+ SADB_SASTATE_MAX);
50469+ SENDERR(EINVAL);
50470+ }
50471+#endif
50472+
50473+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
50474+ ERROR(
50475+ "pfkey_sa_parse: "
50476+ "state=%d is DEAD=%d.\n",
50477+ pfkey_sa->sadb_sa_state,
50478+ SADB_SASTATE_DEAD);
50479+ SENDERR(EINVAL);
50480+ }
50481+
50482+ if(pfkey_sa->sadb_sa_replay > 64) {
50483+ ERROR(
50484+ "pfkey_sa_parse: "
50485+ "replay window size: %d -- must be 0 <= size <= 64\n",
50486+ pfkey_sa->sadb_sa_replay);
50487+ SENDERR(EINVAL);
50488+ }
50489+
50490+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
50491+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
50492+ {
50493+ ERROR(
50494+ "pfkey_sa_parse: "
50495+ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
50496+ pfkey_sa->sadb_sa_exttype,
50497+ SADB_EXT_SA,
50498+ SADB_X_EXT_SA2);
50499+ SENDERR(EINVAL);
50500+ }
50501+
50502+ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
50503+ ERROR(
50504+ "pfkey_sa_parse: "
50505+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
50506+ pfkey_sa->sadb_x_sa_ref,
50507+ IPSEC_SAREF_NULL,
50508+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
50509+ SENDERR(EINVAL);
50510+ }
50511+
50512+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50513+ "pfkey_sa_parse: "
50514+ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
50515+ pfkey_sa->sadb_sa_len,
50516+ pfkey_sa->sadb_sa_exttype,
50517+ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
50518+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
50519+ pfkey_sa->sadb_sa_replay,
50520+ pfkey_sa->sadb_sa_state,
50521+ pfkey_sa->sadb_sa_auth,
50522+ pfkey_sa->sadb_sa_encrypt,
50523+ pfkey_sa->sadb_sa_flags,
50524+ pfkey_sa->sadb_x_sa_ref);
50525+
50526+ errlab:
50527+ return error;
50528+}
50529+
50530+DEBUG_NO_STATIC int
50531+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
50532+{
50533+ int error = 0;
50534+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
50535+
50536+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50537+ "pfkey_lifetime_parse:enter\n");
50538+ /* sanity checks... */
50539+ if(!pfkey_lifetime) {
50540+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50541+ "pfkey_lifetime_parse: "
50542+ "NULL pointer passed in.\n");
50543+ SENDERR(EINVAL);
50544+ }
50545+
50546+ if(pfkey_lifetime->sadb_lifetime_len !=
50547+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
50548+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50549+ "pfkey_lifetime_parse: "
50550+ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
50551+ pfkey_lifetime->sadb_lifetime_len,
50552+ (int)sizeof(struct sadb_lifetime));
50553+ SENDERR(EINVAL);
50554+ }
50555+
50556+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
50557+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
50558+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
50559+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50560+ "pfkey_lifetime_parse: "
50561+ "unexpected ext_type=%d.\n",
50562+ pfkey_lifetime->sadb_lifetime_exttype);
50563+ SENDERR(EINVAL);
50564+ }
50565+
50566+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50567+ "pfkey_lifetime_parse: "
50568+ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n",
50569+ pfkey_lifetime->sadb_lifetime_exttype,
50570+ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
50571+ pfkey_lifetime->sadb_lifetime_allocations,
50572+ (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
50573+ (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
50574+ (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
50575+ pfkey_lifetime->sadb_x_lifetime_packets);
50576+errlab:
50577+ return error;
50578+}
50579+
50580+DEBUG_NO_STATIC int
50581+pfkey_address_parse(struct sadb_ext *pfkey_ext)
50582+{
50583+ int error = 0;
50584+ int saddr_len = 0;
50585+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
50586+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
50587+ char ipaddr_txt[ADDRTOT_BUF];
50588+
50589+ /* sanity checks... */
50590+ if(!pfkey_address) {
50591+ ERROR(
50592+ "pfkey_address_parse: "
50593+ "NULL pointer passed in.\n");
50594+ SENDERR(EINVAL);
50595+ }
50596+
50597+ if(pfkey_address->sadb_address_len <
50598+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
50599+ IPSEC_PFKEYv2_ALIGN) {
50600+ ERROR("pfkey_address_parse: "
50601+ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
50602+ pfkey_address->sadb_address_len,
50603+ (int)sizeof(struct sadb_address),
50604+ (int)sizeof(struct sockaddr));
50605+ SENDERR(EINVAL);
50606+ }
50607+
50608+ if(pfkey_address->sadb_address_reserved) {
50609+ ERROR("pfkey_address_parse: "
50610+ "res=%d, must be zero.\n",
50611+ pfkey_address->sadb_address_reserved);
50612+ SENDERR(EINVAL);
50613+ }
50614+
50615+ switch(pfkey_address->sadb_address_exttype) {
50616+ case SADB_EXT_ADDRESS_SRC:
50617+ case SADB_EXT_ADDRESS_DST:
50618+ case SADB_EXT_ADDRESS_PROXY:
50619+ case SADB_X_EXT_ADDRESS_DST2:
50620+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
50621+ case SADB_X_EXT_ADDRESS_DST_FLOW:
50622+ case SADB_X_EXT_ADDRESS_SRC_MASK:
50623+ case SADB_X_EXT_ADDRESS_DST_MASK:
50624+#ifdef NAT_TRAVERSAL
50625+ case SADB_X_EXT_NAT_T_OA:
50626+#endif
50627+ break;
50628+ default:
50629+ ERROR(
50630+ "pfkey_address_parse: "
50631+ "unexpected ext_type=%d.\n",
50632+ pfkey_address->sadb_address_exttype);
50633+ SENDERR(ENOPKG);
50634+ }
50635+
50636+ switch(s->sa_family) {
50637+ case AF_INET:
50638+ saddr_len = sizeof(struct sockaddr_in);
50639+ sprintf(ipaddr_txt, "%d.%d.%d.%d"
50640+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
50641+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
50642+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
50643+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
50644+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50645+ "pfkey_address_parse: "
50646+ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
50647+ pfkey_address->sadb_address_exttype,
50648+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
50649+ s->sa_family,
50650+ ipaddr_txt,
50651+ pfkey_address->sadb_address_proto,
50652+ ntohs(((struct sockaddr_in*)s)->sin_port));
50653+ break;
50654+ case AF_INET6:
50655+ saddr_len = sizeof(struct sockaddr_in6);
50656+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
50657+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
50658+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
50659+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
50660+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
50661+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
50662+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
50663+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
50664+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
50665+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50666+ "pfkey_address_parse: "
50667+ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
50668+ pfkey_address->sadb_address_exttype,
50669+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
50670+ s->sa_family,
50671+ ipaddr_txt,
50672+ pfkey_address->sadb_address_proto,
50673+ ((struct sockaddr_in6*)s)->sin6_port);
50674+ break;
50675+ default:
50676+ ERROR(
50677+ "pfkey_address_parse: "
50678+ "s->sa_family=%d not supported.\n",
50679+ s->sa_family);
50680+ SENDERR(EPFNOSUPPORT);
50681+ }
50682+
50683+ if(pfkey_address->sadb_address_len !=
50684+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
50685+ ERROR(
50686+ "pfkey_address_parse: "
50687+ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
50688+ pfkey_address->sadb_address_len,
50689+ (int)sizeof(struct sadb_address),
50690+ saddr_len);
50691+ SENDERR(EINVAL);
50692+ }
50693+
50694+ if(pfkey_address->sadb_address_prefixlen != 0) {
50695+ ERROR(
50696+ "pfkey_address_parse: "
50697+ "address prefixes not supported yet.\n");
50698+ SENDERR(EAFNOSUPPORT); /* not supported yet */
50699+ }
50700+
50701+ /* XXX check if port!=0 */
50702+
50703+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50704+ "pfkey_address_parse: successful.\n");
50705+ errlab:
50706+ return error;
50707+}
50708+
50709+DEBUG_NO_STATIC int
50710+pfkey_key_parse(struct sadb_ext *pfkey_ext)
50711+{
50712+ int error = 0;
50713+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
50714+
50715+ /* sanity checks... */
50716+
50717+ if(!pfkey_key) {
50718+ ERROR(
50719+ "pfkey_key_parse: "
50720+ "NULL pointer passed in.\n");
50721+ SENDERR(EINVAL);
50722+ }
50723+
50724+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
50725+ ERROR(
50726+ "pfkey_key_parse: "
50727+ "size wrong ext_len=%d, key_ext_len=%d.\n",
50728+ pfkey_key->sadb_key_len,
50729+ (int)sizeof(struct sadb_key));
50730+ SENDERR(EINVAL);
50731+ }
50732+
50733+ if(!pfkey_key->sadb_key_bits) {
50734+ ERROR(
50735+ "pfkey_key_parse: "
50736+ "key length set to zero, must be non-zero.\n");
50737+ SENDERR(EINVAL);
50738+ }
50739+
50740+ if(pfkey_key->sadb_key_len !=
50741+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
50742+ PFKEYBITS)) {
50743+ ERROR(
50744+ "pfkey_key_parse: "
50745+ "key length=%d does not agree with extension length=%d.\n",
50746+ pfkey_key->sadb_key_bits,
50747+ pfkey_key->sadb_key_len);
50748+ SENDERR(EINVAL);
50749+ }
50750+
50751+ if(pfkey_key->sadb_key_reserved) {
50752+ ERROR(
50753+ "pfkey_key_parse: "
50754+ "res=%d, must be zero.\n",
50755+ pfkey_key->sadb_key_reserved);
50756+ SENDERR(EINVAL);
50757+ }
50758+
50759+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
50760+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
50761+ ERROR(
50762+ "pfkey_key_parse: "
50763+ "expecting extension type AUTH or ENCRYPT, got %d.\n",
50764+ pfkey_key->sadb_key_exttype);
50765+ SENDERR(EINVAL);
50766+ }
50767+
50768+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50769+ "pfkey_key_parse: "
50770+ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
50771+ pfkey_key->sadb_key_len,
50772+ pfkey_key->sadb_key_exttype,
50773+ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
50774+ pfkey_key->sadb_key_bits,
50775+ pfkey_key->sadb_key_reserved);
50776+
50777+errlab:
50778+ return error;
50779+}
50780+
50781+DEBUG_NO_STATIC int
50782+pfkey_ident_parse(struct sadb_ext *pfkey_ext)
50783+{
50784+ int error = 0;
50785+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
50786+
50787+ /* sanity checks... */
50788+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
50789+ ERROR(
50790+ "pfkey_ident_parse: "
50791+ "size wrong ext_len=%d, key_ext_len=%d.\n",
50792+ pfkey_ident->sadb_ident_len,
50793+ (int)sizeof(struct sadb_ident));
50794+ SENDERR(EINVAL);
50795+ }
50796+
50797+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
50798+ ERROR(
50799+ "pfkey_ident_parse: "
50800+ "ident_type=%d out of range, must be less than %d.\n",
50801+ pfkey_ident->sadb_ident_type,
50802+ SADB_IDENTTYPE_MAX);
50803+ SENDERR(EINVAL);
50804+ }
50805+
50806+ if(pfkey_ident->sadb_ident_reserved) {
50807+ ERROR(
50808+ "pfkey_ident_parse: "
50809+ "res=%d, must be zero.\n",
50810+ pfkey_ident->sadb_ident_reserved);
50811+ SENDERR(EINVAL);
50812+ }
50813+
50814+ /* string terminator/padding must be zero */
50815+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
50816+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
50817+ ERROR(
50818+ "pfkey_ident_parse: "
50819+ "string padding must be zero, last is 0x%02x.\n",
50820+ *((char*)pfkey_ident +
50821+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
50822+ SENDERR(EINVAL);
50823+ }
50824+ }
50825+
50826+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
50827+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
50828+ ERROR(
50829+ "pfkey_key_parse: "
50830+ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
50831+ pfkey_ident->sadb_ident_exttype);
50832+ SENDERR(EINVAL);
50833+ }
50834+
50835+errlab:
50836+ return error;
50837+}
50838+
50839+DEBUG_NO_STATIC int
50840+pfkey_sens_parse(struct sadb_ext *pfkey_ext)
50841+{
50842+ int error = 0;
50843+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
50844+
50845+ /* sanity checks... */
50846+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
50847+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50848+ "pfkey_sens_parse: "
50849+ "size wrong ext_len=%d, key_ext_len=%d.\n",
50850+ pfkey_sens->sadb_sens_len,
50851+ (int)sizeof(struct sadb_sens));
50852+ SENDERR(EINVAL);
50853+ }
50854+
50855+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50856+ "pfkey_sens_parse: "
50857+ "Sorry, I can't parse exttype=%d yet.\n",
50858+ pfkey_ext->sadb_ext_type);
50859+#if 0
50860+ SENDERR(EINVAL); /* don't process these yet */
50861+#endif
50862+
50863+errlab:
50864+ return error;
50865+}
50866+
50867+DEBUG_NO_STATIC int
50868+pfkey_prop_parse(struct sadb_ext *pfkey_ext)
50869+{
50870+ int error = 0;
50871+ int i, num_comb;
50872+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
50873+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
50874+
50875+ /* sanity checks... */
50876+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
50877+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
50878+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50879+ "pfkey_prop_parse: "
50880+ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
50881+ pfkey_prop->sadb_prop_len,
50882+ (int)sizeof(struct sadb_prop),
50883+ (int)sizeof(struct sadb_comb));
50884+ SENDERR(EINVAL);
50885+ }
50886+
50887+ if(pfkey_prop->sadb_prop_replay > 64) {
50888+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50889+ "pfkey_prop_parse: "
50890+ "replay window size: %d -- must be 0 <= size <= 64\n",
50891+ pfkey_prop->sadb_prop_replay);
50892+ SENDERR(EINVAL);
50893+ }
50894+
50895+ for(i=0; i<3; i++) {
50896+ if(pfkey_prop->sadb_prop_reserved[i]) {
50897+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50898+ "pfkey_prop_parse: "
50899+ "res[%d]=%d, must be zero.\n",
50900+ i, pfkey_prop->sadb_prop_reserved[i]);
50901+ SENDERR(EINVAL);
50902+ }
50903+ }
50904+
50905+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
50906+
50907+ for(i = 0; i < num_comb; i++) {
50908+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
50909+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50910+ "pfkey_prop_parse: "
50911+ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
50912+ i,
50913+ pfkey_comb->sadb_comb_auth,
50914+ SADB_AALG_MAX);
50915+ SENDERR(EINVAL);
50916+ }
50917+
50918+ if(pfkey_comb->sadb_comb_auth) {
50919+ if(!pfkey_comb->sadb_comb_auth_minbits) {
50920+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50921+ "pfkey_prop_parse: "
50922+ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
50923+ i);
50924+ SENDERR(EINVAL);
50925+ }
50926+ if(!pfkey_comb->sadb_comb_auth_maxbits) {
50927+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50928+ "pfkey_prop_parse: "
50929+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
50930+ i);
50931+ SENDERR(EINVAL);
50932+ }
50933+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
50934+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50935+ "pfkey_prop_parse: "
50936+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
50937+ i,
50938+ pfkey_comb->sadb_comb_auth_minbits,
50939+ pfkey_comb->sadb_comb_auth_maxbits);
50940+ SENDERR(EINVAL);
50941+ }
50942+ } else {
50943+ if(pfkey_comb->sadb_comb_auth_minbits) {
50944+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50945+ "pfkey_prop_parse: "
50946+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
50947+ i,
50948+ pfkey_comb->sadb_comb_auth_minbits);
50949+ SENDERR(EINVAL);
50950+ }
50951+ if(pfkey_comb->sadb_comb_auth_maxbits) {
50952+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50953+ "pfkey_prop_parse: "
50954+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
50955+ i,
50956+ pfkey_comb->sadb_comb_auth_maxbits);
50957+ SENDERR(EINVAL);
50958+ }
50959+ }
50960+
50961+#if SADB_EALG_MAX < 255
50962+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
50963+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50964+ "pfkey_comb_parse: "
50965+ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
50966+ i,
50967+ pfkey_comb->sadb_comb_encrypt,
50968+ SADB_EALG_MAX);
50969+ SENDERR(EINVAL);
50970+ }
50971+#endif
50972+
50973+ if(pfkey_comb->sadb_comb_encrypt) {
50974+ if(!pfkey_comb->sadb_comb_encrypt_minbits) {
50975+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50976+ "pfkey_prop_parse: "
50977+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
50978+ i);
50979+ SENDERR(EINVAL);
50980+ }
50981+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
50982+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50983+ "pfkey_prop_parse: "
50984+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
50985+ i);
50986+ SENDERR(EINVAL);
50987+ }
50988+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
50989+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50990+ "pfkey_prop_parse: "
50991+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
50992+ i,
50993+ pfkey_comb->sadb_comb_encrypt_minbits,
50994+ pfkey_comb->sadb_comb_encrypt_maxbits);
50995+ SENDERR(EINVAL);
50996+ }
50997+ } else {
50998+ if(pfkey_comb->sadb_comb_encrypt_minbits) {
50999+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51000+ "pfkey_prop_parse: "
51001+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
51002+ i,
51003+ pfkey_comb->sadb_comb_encrypt_minbits);
51004+ SENDERR(EINVAL);
51005+ }
51006+ if(pfkey_comb->sadb_comb_encrypt_maxbits) {
51007+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51008+ "pfkey_prop_parse: "
51009+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
51010+ i,
51011+ pfkey_comb->sadb_comb_encrypt_maxbits);
51012+ SENDERR(EINVAL);
51013+ }
51014+ }
51015+
51016+ /* XXX do sanity check on flags */
51017+
51018+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
51019+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51020+ "pfkey_prop_parse: "
51021+ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
51022+ i,
51023+ pfkey_comb->sadb_comb_soft_allocations,
51024+ pfkey_comb->sadb_comb_hard_allocations);
51025+ SENDERR(EINVAL);
51026+ }
51027+
51028+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
51029+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51030+ "pfkey_prop_parse: "
51031+ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
51032+ i,
51033+ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
51034+ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
51035+ SENDERR(EINVAL);
51036+ }
51037+
51038+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
51039+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51040+ "pfkey_prop_parse: "
51041+ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
51042+ i,
51043+ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
51044+ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
51045+ SENDERR(EINVAL);
51046+ }
51047+
51048+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
51049+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51050+ "pfkey_prop_parse: "
51051+ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
51052+ i,
51053+ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
51054+ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
51055+ SENDERR(EINVAL);
51056+ }
51057+
51058+ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
51059+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51060+ "pfkey_prop_parse: "
51061+ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
51062+ i,
51063+ pfkey_comb->sadb_x_comb_soft_packets,
51064+ pfkey_comb->sadb_x_comb_hard_packets);
51065+ SENDERR(EINVAL);
51066+ }
51067+
51068+ if(pfkey_comb->sadb_comb_reserved) {
51069+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51070+ "pfkey_prop_parse: "
51071+ "comb[%d].res=%d, must be zero.\n",
51072+ i,
51073+ pfkey_comb->sadb_comb_reserved);
51074+ SENDERR(EINVAL);
51075+ }
51076+ pfkey_comb++;
51077+ }
51078+
51079+errlab:
51080+ return error;
51081+}
51082+
51083+DEBUG_NO_STATIC int
51084+pfkey_supported_parse(struct sadb_ext *pfkey_ext)
51085+{
51086+ int error = 0;
51087+ unsigned int i, num_alg;
51088+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
51089+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
51090+
51091+ /* sanity checks... */
51092+ if((pfkey_supported->sadb_supported_len <
51093+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
51094+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
51095+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
51096+
51097+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51098+ "pfkey_supported_parse: "
51099+ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
51100+ pfkey_supported->sadb_supported_len,
51101+ (int)sizeof(struct sadb_supported),
51102+ (int)sizeof(struct sadb_alg));
51103+ SENDERR(EINVAL);
51104+ }
51105+
51106+ if(pfkey_supported->sadb_supported_reserved) {
51107+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51108+ "pfkey_supported_parse: "
51109+ "res=%d, must be zero.\n",
51110+ pfkey_supported->sadb_supported_reserved);
51111+ SENDERR(EINVAL);
51112+ }
51113+
51114+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
51115+
51116+ for(i = 0; i < num_alg; i++) {
51117+ /* process algo description */
51118+ if(pfkey_alg->sadb_alg_reserved) {
51119+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51120+ "pfkey_supported_parse: "
51121+ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
51122+ i,
51123+ pfkey_alg->sadb_alg_id,
51124+ pfkey_alg->sadb_alg_ivlen,
51125+ pfkey_alg->sadb_alg_minbits,
51126+ pfkey_alg->sadb_alg_maxbits,
51127+ pfkey_alg->sadb_alg_reserved);
51128+ SENDERR(EINVAL);
51129+ }
51130+
51131+ /* XXX can alg_id auth/enc be determined from info given?
51132+ Yes, but OpenBSD's method does not iteroperate with rfc2367.
51133+ rgb, 2000-04-06 */
51134+
51135+ switch(pfkey_supported->sadb_supported_exttype) {
51136+ case SADB_EXT_SUPPORTED_AUTH:
51137+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
51138+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51139+ "pfkey_supported_parse: "
51140+ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
51141+ i,
51142+ pfkey_alg->sadb_alg_id,
51143+ SADB_AALG_MAX);
51144+ SENDERR(EINVAL);
51145+ }
51146+ break;
51147+ case SADB_EXT_SUPPORTED_ENCRYPT:
51148+#if SADB_EALG_MAX < 255
51149+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
51150+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51151+ "pfkey_supported_parse: "
51152+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
51153+ i,
51154+ pfkey_alg->sadb_alg_id,
51155+ SADB_EALG_MAX);
51156+ SENDERR(EINVAL);
51157+ }
51158+#endif
51159+ break;
51160+ default:
51161+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51162+ "pfkey_supported_parse: "
51163+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
51164+ i,
51165+ pfkey_alg->sadb_alg_id,
51166+ SADB_EALG_MAX);
51167+ SENDERR(EINVAL);
51168+ }
51169+ pfkey_alg++;
51170+ }
51171+
51172+ errlab:
51173+ return error;
51174+}
51175+
51176+DEBUG_NO_STATIC int
51177+pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
51178+{
51179+ int error = 0;
51180+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
51181+
51182+ /* sanity checks... */
51183+ if(pfkey_spirange->sadb_spirange_len !=
51184+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
51185+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51186+ "pfkey_spirange_parse: "
51187+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51188+ pfkey_spirange->sadb_spirange_len,
51189+ (int)sizeof(struct sadb_spirange));
51190+ SENDERR(EINVAL);
51191+ }
51192+
51193+ if(pfkey_spirange->sadb_spirange_reserved) {
51194+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51195+ "pfkey_spirange_parse: "
51196+ "reserved=%d must be set to zero.\n",
51197+ pfkey_spirange->sadb_spirange_reserved);
51198+ SENDERR(EINVAL);
51199+ }
51200+
51201+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
51202+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51203+ "pfkey_spirange_parse: "
51204+ "minspi=%08x must be < maxspi=%08x.\n",
51205+ ntohl(pfkey_spirange->sadb_spirange_min),
51206+ ntohl(pfkey_spirange->sadb_spirange_max));
51207+ SENDERR(EINVAL);
51208+ }
51209+
51210+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
51211+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51212+ "pfkey_spirange_parse: "
51213+ "minspi=%08x must be > 255.\n",
51214+ ntohl(pfkey_spirange->sadb_spirange_min));
51215+ SENDERR(EEXIST);
51216+ }
51217+
51218+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51219+ "pfkey_spirange_parse: "
51220+ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
51221+ pfkey_spirange->sadb_spirange_len,
51222+ pfkey_spirange->sadb_spirange_exttype,
51223+ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
51224+ pfkey_spirange->sadb_spirange_min,
51225+ pfkey_spirange->sadb_spirange_max,
51226+ pfkey_spirange->sadb_spirange_reserved);
51227+ errlab:
51228+ return error;
51229+}
51230+
51231+DEBUG_NO_STATIC int
51232+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
51233+{
51234+ int error = 0;
51235+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
51236+
51237+ /* sanity checks... */
51238+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
51239+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
51240+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51241+ "pfkey_x_kmprivate_parse: "
51242+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51243+ pfkey_x_kmprivate->sadb_x_kmprivate_len,
51244+ (int)sizeof(struct sadb_x_kmprivate));
51245+ SENDERR(EINVAL);
51246+ }
51247+
51248+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
51249+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51250+ "pfkey_x_kmprivate_parse: "
51251+ "reserved=%d must be set to zero.\n",
51252+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
51253+ SENDERR(EINVAL);
51254+ }
51255+
51256+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51257+ "pfkey_x_kmprivate_parse: "
51258+ "Sorry, I can't parse exttype=%d yet.\n",
51259+ pfkey_ext->sadb_ext_type);
51260+ SENDERR(EINVAL); /* don't process these yet */
51261+
51262+errlab:
51263+ return error;
51264+}
51265+
51266+DEBUG_NO_STATIC int
51267+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
51268+{
51269+ int error = 0;
51270+ int i;
51271+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
51272+
51273+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51274+ "pfkey_x_satype_parse: enter\n");
51275+ /* sanity checks... */
51276+ if(pfkey_x_satype->sadb_x_satype_len !=
51277+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
51278+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51279+ "pfkey_x_satype_parse: "
51280+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51281+ pfkey_x_satype->sadb_x_satype_len,
51282+ (int)sizeof(struct sadb_x_satype));
51283+ SENDERR(EINVAL);
51284+ }
51285+
51286+ if(!pfkey_x_satype->sadb_x_satype_satype) {
51287+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51288+ "pfkey_x_satype_parse: "
51289+ "satype is zero, must be non-zero.\n");
51290+ SENDERR(EINVAL);
51291+ }
51292+
51293+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
51294+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51295+ "pfkey_x_satype_parse: "
51296+ "satype %d > max %d, invalid.\n",
51297+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
51298+ SENDERR(EINVAL);
51299+ }
51300+
51301+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
51302+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51303+ "pfkey_x_satype_parse: "
51304+ "proto lookup from satype=%d failed.\n",
51305+ pfkey_x_satype->sadb_x_satype_satype);
51306+ SENDERR(EINVAL);
51307+ }
51308+
51309+ for(i = 0; i < 3; i++) {
51310+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
51311+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51312+ "pfkey_x_satype_parse: "
51313+ "reserved[%d]=%d must be set to zero.\n",
51314+ i, pfkey_x_satype->sadb_x_satype_reserved[i]);
51315+ SENDERR(EINVAL);
51316+ }
51317+ }
51318+
51319+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51320+ "pfkey_x_satype_parse: "
51321+ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
51322+ pfkey_x_satype->sadb_x_satype_len,
51323+ pfkey_x_satype->sadb_x_satype_exttype,
51324+ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
51325+ pfkey_x_satype->sadb_x_satype_satype,
51326+ satype2name(pfkey_x_satype->sadb_x_satype_satype),
51327+ pfkey_x_satype->sadb_x_satype_reserved[0],
51328+ pfkey_x_satype->sadb_x_satype_reserved[1],
51329+ pfkey_x_satype->sadb_x_satype_reserved[2]);
51330+errlab:
51331+ return error;
51332+}
51333+
51334+DEBUG_NO_STATIC int
51335+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
51336+{
51337+ int error = 0;
51338+ int i;
51339+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
51340+
51341+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51342+ "pfkey_x_debug_parse: enter\n");
51343+ /* sanity checks... */
51344+ if(pfkey_x_debug->sadb_x_debug_len !=
51345+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
51346+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51347+ "pfkey_x_debug_parse: "
51348+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51349+ pfkey_x_debug->sadb_x_debug_len,
51350+ (int)sizeof(struct sadb_x_debug));
51351+ SENDERR(EINVAL);
51352+ }
51353+
51354+ for(i = 0; i < 4; i++) {
51355+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
51356+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51357+ "pfkey_x_debug_parse: "
51358+ "reserved[%d]=%d must be set to zero.\n",
51359+ i, pfkey_x_debug->sadb_x_debug_reserved[i]);
51360+ SENDERR(EINVAL);
51361+ }
51362+ }
51363+
51364+errlab:
51365+ return error;
51366+}
51367+
51368+DEBUG_NO_STATIC int
51369+pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
51370+{
51371+ int error = 0;
51372+ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
51373+
51374+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
51375+ /* sanity checks... */
51376+
51377+ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
51378+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51379+ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
51380+ p->sadb_protocol_len, (int)sizeof(*p));
51381+ SENDERR(EINVAL);
51382+ }
51383+
51384+ if (p->sadb_protocol_reserved2 != 0) {
51385+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51386+ "pfkey_protocol_parse: res=%d, must be zero.\n",
51387+ p->sadb_protocol_reserved2);
51388+ SENDERR(EINVAL);
51389+ }
51390+
51391+ errlab:
51392+ return error;
51393+}
51394+
51395+#ifdef NAT_TRAVERSAL
51396+DEBUG_NO_STATIC int
51397+pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
51398+{
51399+ return 0;
51400+}
51401+DEBUG_NO_STATIC int
51402+pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
51403+{
51404+ return 0;
51405+}
51406+#endif
51407+
51408+#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
51409+
51410+DEFINEPARSER(pfkey_sa_parse);
51411+DEFINEPARSER(pfkey_lifetime_parse);
51412+DEFINEPARSER(pfkey_address_parse);
51413+DEFINEPARSER(pfkey_key_parse);
51414+DEFINEPARSER(pfkey_ident_parse);
51415+DEFINEPARSER(pfkey_sens_parse);
51416+DEFINEPARSER(pfkey_prop_parse);
51417+DEFINEPARSER(pfkey_supported_parse);
51418+DEFINEPARSER(pfkey_spirange_parse);
51419+DEFINEPARSER(pfkey_x_kmprivate_parse);
51420+DEFINEPARSER(pfkey_x_satype_parse);
51421+DEFINEPARSER(pfkey_x_ext_debug_parse);
51422+DEFINEPARSER(pfkey_x_ext_protocol_parse);
51423+#ifdef NAT_TRAVERSAL
51424+DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
51425+DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
51426+#endif
51427+
51428+struct pf_key_ext_parsers_def *ext_default_parsers[]=
51429+{
51430+ NULL, /* pfkey_msg_parse, */
51431+ &pfkey_sa_parse_def,
51432+ &pfkey_lifetime_parse_def,
51433+ &pfkey_lifetime_parse_def,
51434+ &pfkey_lifetime_parse_def,
51435+ &pfkey_address_parse_def,
51436+ &pfkey_address_parse_def,
51437+ &pfkey_address_parse_def,
51438+ &pfkey_key_parse_def,
51439+ &pfkey_key_parse_def,
51440+ &pfkey_ident_parse_def,
51441+ &pfkey_ident_parse_def,
51442+ &pfkey_sens_parse_def,
51443+ &pfkey_prop_parse_def,
51444+ &pfkey_supported_parse_def,
51445+ &pfkey_supported_parse_def,
51446+ &pfkey_spirange_parse_def,
51447+ &pfkey_x_kmprivate_parse_def,
51448+ &pfkey_x_satype_parse_def,
51449+ &pfkey_sa_parse_def,
51450+ &pfkey_address_parse_def,
51451+ &pfkey_address_parse_def,
51452+ &pfkey_address_parse_def,
51453+ &pfkey_address_parse_def,
51454+ &pfkey_address_parse_def,
51455+ &pfkey_x_ext_debug_parse_def,
51456+ &pfkey_x_ext_protocol_parse_def
51457+#ifdef NAT_TRAVERSAL
51458+ ,
51459+ &pfkey_x_ext_nat_t_type_parse_def,
51460+ &pfkey_x_ext_nat_t_port_parse_def,
51461+ &pfkey_x_ext_nat_t_port_parse_def,
51462+ &pfkey_address_parse_def
51463+#endif
51464+};
51465+
51466+int
51467+pfkey_msg_parse(struct sadb_msg *pfkey_msg,
51468+ struct pf_key_ext_parsers_def *ext_parsers[],
51469+ struct sadb_ext *extensions[],
51470+ int dir)
51471+{
51472+ int error = 0;
51473+ int remain;
51474+ struct sadb_ext *pfkey_ext;
51475+ int extensions_seen = 0;
51476+
51477+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51478+ "pfkey_msg_parse: "
51479+ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
51480+ pfkey_msg->sadb_msg_version,
51481+ pfkey_msg->sadb_msg_type,
51482+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
51483+ pfkey_msg->sadb_msg_errno,
51484+ pfkey_msg->sadb_msg_satype,
51485+ satype2name(pfkey_msg->sadb_msg_satype),
51486+ pfkey_msg->sadb_msg_len,
51487+ pfkey_msg->sadb_msg_reserved,
51488+ pfkey_msg->sadb_msg_seq,
51489+ pfkey_msg->sadb_msg_pid);
51490+
51491+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
51492+
51493+ pfkey_extensions_init(extensions);
51494+
51495+ remain = pfkey_msg->sadb_msg_len;
51496+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
51497+
51498+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
51499+ sizeof(struct sadb_msg));
51500+
51501+ extensions[0] = (struct sadb_ext *) pfkey_msg;
51502+
51503+
51504+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
51505+ ERROR("pfkey_msg_parse: "
51506+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
51507+ pfkey_msg->sadb_msg_version,
51508+ PF_KEY_V2);
51509+ SENDERR(EINVAL);
51510+ }
51511+
51512+ if(!pfkey_msg->sadb_msg_type) {
51513+ ERROR("pfkey_msg_parse: "
51514+ "msg type not set, must be non-zero..\n");
51515+ SENDERR(EINVAL);
51516+ }
51517+
51518+ if(pfkey_msg->sadb_msg_type > SADB_MAX) {
51519+ ERROR("pfkey_msg_parse: "
51520+ "msg type=%d > max=%d.\n",
51521+ pfkey_msg->sadb_msg_type,
51522+ SADB_MAX);
51523+ SENDERR(EINVAL);
51524+ }
51525+
51526+ switch(pfkey_msg->sadb_msg_type) {
51527+ case SADB_GETSPI:
51528+ case SADB_UPDATE:
51529+ case SADB_ADD:
51530+ case SADB_DELETE:
51531+ case SADB_GET:
51532+ case SADB_X_GRPSA:
51533+ case SADB_X_ADDFLOW:
51534+ if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
51535+ ERROR("pfkey_msg_parse: "
51536+ "satype %d conversion to proto failed for msg_type %d (%s).\n",
51537+ pfkey_msg->sadb_msg_satype,
51538+ pfkey_msg->sadb_msg_type,
51539+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51540+ SENDERR(EINVAL);
51541+ } else {
51542+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51543+ "pfkey_msg_parse: "
51544+ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
51545+ pfkey_msg->sadb_msg_satype,
51546+ satype2name(pfkey_msg->sadb_msg_satype),
51547+ satype2proto(pfkey_msg->sadb_msg_satype),
51548+ pfkey_msg->sadb_msg_type,
51549+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51550+ }
51551+ case SADB_ACQUIRE:
51552+ case SADB_REGISTER:
51553+ case SADB_EXPIRE:
51554+ if(!pfkey_msg->sadb_msg_satype) {
51555+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51556+ "pfkey_msg_parse: "
51557+ "satype is zero, must be non-zero for msg_type %d(%s).\n",
51558+ pfkey_msg->sadb_msg_type,
51559+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51560+ SENDERR(EINVAL);
51561+ }
51562+ default:
51563+ break;
51564+ }
51565+
51566+ /* errno must not be set in downward messages */
51567+ /* this is not entirely true... a response to an ACQUIRE could return an error */
51568+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
51569+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51570+ "pfkey_msg_parse: "
51571+ "errno set to %d.\n",
51572+ pfkey_msg->sadb_msg_errno);
51573+ SENDERR(EINVAL);
51574+ }
51575+
51576+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51577+ "pfkey_msg_parse: "
51578+ "remain=%d\n",
51579+ remain
51580+ );
51581+
51582+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51583+ "pfkey_msg_parse: "
51584+ "extensions permitted=%08x, required=%08x.\n",
51585+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51586+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
51587+
51588+ extensions_seen = 1;
51589+
51590+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
51591+ /* Is there enough message left to support another extension header? */
51592+ if(remain < pfkey_ext->sadb_ext_len) {
51593+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51594+ "pfkey_msg_parse: "
51595+ "remain %d less than ext len %d.\n",
51596+ remain, pfkey_ext->sadb_ext_len);
51597+ SENDERR(EINVAL);
51598+ }
51599+
51600+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51601+ "pfkey_msg_parse: "
51602+ "parsing ext type=%d(%s) remain=%d.\n",
51603+ pfkey_ext->sadb_ext_type,
51604+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51605+ remain);
51606+
51607+ /* Is the extension header type valid? */
51608+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
51609+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51610+ "pfkey_msg_parse: "
51611+ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
51612+ pfkey_ext->sadb_ext_type,
51613+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51614+ SADB_EXT_MAX);
51615+ SENDERR(EINVAL);
51616+ }
51617+
51618+ /* Have we already seen this type of extension? */
51619+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
51620+ {
51621+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51622+ "pfkey_msg_parse: "
51623+ "ext type %d(%s) already seen.\n",
51624+ pfkey_ext->sadb_ext_type,
51625+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51626+ SENDERR(EINVAL);
51627+ }
51628+
51629+ /* Do I even know about this type of extension? */
51630+ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
51631+ ERROR("pfkey_msg_parse: "
51632+ "ext type %d(%s) unknown, ignoring.\n",
51633+ pfkey_ext->sadb_ext_type,
51634+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51635+ goto next_ext;
51636+ }
51637+
51638+ /* Is this type of extension permitted for this type of message? */
51639+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
51640+ 1<<pfkey_ext->sadb_ext_type)) {
51641+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51642+ "pfkey_msg_parse: "
51643+ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
51644+ pfkey_ext->sadb_ext_type,
51645+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51646+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51647+ 1<<pfkey_ext->sadb_ext_type);
51648+ SENDERR(EINVAL);
51649+ }
51650+
51651+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51652+ "pfkey_msg_parse: "
51653+ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
51654+ remain,
51655+ pfkey_ext->sadb_ext_type,
51656+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51657+ pfkey_ext->sadb_ext_len,
51658+ pfkey_ext,
51659+ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
51660+
51661+ /* Parse the extension */
51662+ if((error =
51663+ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
51664+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51665+ "pfkey_msg_parse: "
51666+ "extension parsing for type %d(%s) failed with error %d.\n",
51667+ pfkey_ext->sadb_ext_type,
51668+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51669+ error);
51670+ SENDERR(-error);
51671+ }
51672+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51673+ "pfkey_msg_parse: "
51674+ "Extension %d(%s) parsed.\n",
51675+ pfkey_ext->sadb_ext_type,
51676+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51677+
51678+ /* Mark that we have seen this extension and remember the header location */
51679+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
51680+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
51681+
51682+ next_ext:
51683+ /* Calculate how much message remains */
51684+ remain -= pfkey_ext->sadb_ext_len;
51685+
51686+ if(!remain) {
51687+ break;
51688+ }
51689+ /* Find the next extension header */
51690+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
51691+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
51692+ }
51693+
51694+ if(remain) {
51695+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51696+ "pfkey_msg_parse: "
51697+ "unexpected remainder of %d.\n",
51698+ remain);
51699+ /* why is there still something remaining? */
51700+ SENDERR(EINVAL);
51701+ }
51702+
51703+ /* check required extensions */
51704+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51705+ "pfkey_msg_parse: "
51706+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
51707+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51708+ extensions_seen,
51709+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
51710+
51711+ /* don't check further if it is an error return message since it
51712+ may not have a body */
51713+ if(pfkey_msg->sadb_msg_errno) {
51714+ SENDERR(-error);
51715+ }
51716+
51717+ if((extensions_seen &
51718+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
51719+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
51720+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51721+ "pfkey_msg_parse: "
51722+ "required extensions missing:%08x.\n",
51723+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
51724+ (extensions_seen &
51725+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
51726+ SENDERR(EINVAL);
51727+ }
51728+
51729+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
51730+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
51731+ != SADB_X_EXT_ADDRESS_DELFLOW)
51732+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
51733+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
51734+ & SADB_X_SAFLAGS_CLEARFLOW)
51735+ != SADB_X_SAFLAGS_CLEARFLOW))) {
51736+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51737+ "pfkey_msg_parse: "
51738+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
51739+ SADB_X_EXT_ADDRESS_DELFLOW
51740+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
51741+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
51742+ SENDERR(EINVAL);
51743+ }
51744+
51745+ switch(pfkey_msg->sadb_msg_type) {
51746+ case SADB_ADD:
51747+ case SADB_UPDATE:
51748+ /* check maturity */
51749+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
51750+ SADB_SASTATE_MATURE) {
51751+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51752+ "pfkey_msg_parse: "
51753+ "state=%d for add or update should be MATURE=%d.\n",
51754+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
51755+ SADB_SASTATE_MATURE);
51756+ SENDERR(EINVAL);
51757+ }
51758+
51759+ /* check AH and ESP */
51760+ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
51761+ case SADB_SATYPE_AH:
51762+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
51763+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
51764+ SADB_AALG_NONE)) {
51765+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51766+ "pfkey_msg_parse: "
51767+ "auth alg is zero, must be non-zero for AH SAs.\n");
51768+ SENDERR(EINVAL);
51769+ }
51770+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
51771+ SADB_EALG_NONE) {
51772+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51773+ "pfkey_msg_parse: "
51774+ "AH handed encalg=%d, must be zero.\n",
51775+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
51776+ SENDERR(EINVAL);
51777+ }
51778+ break;
51779+ case SADB_SATYPE_ESP:
51780+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
51781+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
51782+ SADB_EALG_NONE)) {
51783+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51784+ "pfkey_msg_parse: "
51785+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
51786+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
51787+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
51788+ SENDERR(EINVAL);
51789+ }
51790+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
51791+ SADB_EALG_NULL) &&
51792+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
51793+ SADB_AALG_NONE) ) {
51794+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51795+ "pfkey_msg_parse: "
51796+ "ESP handed encNULL+authNONE, illegal combination.\n");
51797+ SENDERR(EINVAL);
51798+ }
51799+ break;
51800+ case SADB_X_SATYPE_COMP:
51801+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
51802+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
51803+ SADB_EALG_NONE)) {
51804+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51805+ "pfkey_msg_parse: "
51806+ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
51807+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
51808+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
51809+ SENDERR(EINVAL);
51810+ }
51811+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
51812+ SADB_AALG_NONE) {
51813+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51814+ "pfkey_msg_parse: "
51815+ "COMP handed auth=%d, must be zero.\n",
51816+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
51817+ SENDERR(EINVAL);
51818+ }
51819+ break;
51820+ default:
51821+ break;
51822+ }
51823+ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
51824+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51825+ "pfkey_msg_parse: "
51826+ "spi=%08x must be > 255.\n",
51827+ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
51828+ SENDERR(EINVAL);
51829+ }
51830+ default:
51831+ break;
51832+ }
51833+errlab:
51834+
51835+ return error;
51836+}
51837+
51838+/*
51839+ * $Log: pfkey_v2_parse.c,v $
51840+ * Revision 1.65 2005/04/06 17:46:05 mcr
51841+ * failure to recognize an extension is considered an error.
51842+ * This could be a problem in the future, but we need some kind
51843+ * of logging. This should be rate limited, probably.
51844+ *
51845+ * Revision 1.64 2005/01/26 00:50:35 mcr
51846+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
51847+ * and make sure that NAT_TRAVERSAL is set as well to match
51848+ * userspace compiles of code.
51849+ *
51850+ * Revision 1.63 2004/10/28 22:54:10 mcr
51851+ * results from valgrind, thanks to: Harald Hoyer <harald@redhat.com>
51852+ *
51853+ * Revision 1.62 2004/10/03 01:26:36 mcr
51854+ * fixes for gcc 3.4 compilation.
51855+ *
51856+ * Revision 1.61 2004/07/10 19:11:18 mcr
51857+ * CONFIG_IPSEC -> CONFIG_KLIPS.
51858+ *
51859+ * Revision 1.59 2004/04/18 03:03:49 mcr
51860+ * renamed common include files from pluto directory.
51861+ *
51862+ * Revision 1.58 2004/03/08 01:59:08 ken
51863+ * freeswan.h -> openswan.h
51864+ *
51865+ * Revision 1.57 2003/12/10 01:20:19 mcr
51866+ * NAT-traversal patches to KLIPS.
51867+ *
51868+ * Revision 1.56 2003/12/04 23:01:12 mcr
51869+ * removed ipsec_netlink.h
51870+ *
51871+ * Revision 1.55 2003/11/07 01:30:37 ken
51872+ * Cast sizeof() to int to keep things 64bit clean
51873+ *
51874+ * Revision 1.54 2003/10/31 02:27:12 mcr
51875+ * pulled up port-selector patches and sa_id elimination.
51876+ *
51877+ * Revision 1.53.20.2 2003/10/29 01:11:32 mcr
51878+ * added debugging for pfkey library.
51879+ *
51880+ * Revision 1.53.20.1 2003/09/21 13:59:44 mcr
51881+ * pre-liminary X.509 patch - does not yet pass tests.
51882+ *
51883+ * Revision 1.53 2003/01/30 02:32:09 rgb
51884+ *
51885+ * Rename SAref table macro names for clarity.
51886+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
51887+ *
51888+ * Revision 1.52 2002/12/30 06:53:07 mcr
51889+ * deal with short SA structures... #if 0 out for now. Probably
51890+ * not quite the right way.
51891+ *
51892+ * Revision 1.51 2002/12/13 18:16:02 mcr
51893+ * restored sa_ref code
51894+ *
51895+ * Revision 1.50 2002/12/13 18:06:52 mcr
51896+ * temporarily removed sadb_x_sa_ref reference for 2.xx
51897+ *
51898+ * Revision 1.49 2002/10/05 05:02:58 dhr
51899+ *
51900+ * C labels go on statements
51901+ *
51902+ * Revision 1.48 2002/09/20 15:40:45 rgb
51903+ * Added sadb_x_sa_ref to struct sadb_sa.
51904+ *
51905+ * Revision 1.47 2002/09/20 05:01:31 rgb
51906+ * Fixed usage of pfkey_lib_debug.
51907+ * Format for function declaration style consistency.
51908+ * Added text labels to elucidate numeric values presented.
51909+ * Re-organised debug output to reduce noise in output.
51910+ *
51911+ * Revision 1.46 2002/07/24 18:44:54 rgb
51912+ * Type fiddling to tame ia64 compiler.
51913+ *
51914+ * Revision 1.45 2002/05/23 07:14:11 rgb
51915+ * Cleaned up %p variants to 0p%p for test suite cleanup.
51916+ *
51917+ * Revision 1.44 2002/04/24 07:55:32 mcr
51918+ * #include patches and Makefiles for post-reorg compilation.
51919+ *
51920+ * Revision 1.43 2002/04/24 07:36:40 mcr
51921+ * Moved from ./lib/pfkey_v2_parse.c,v
51922+ *
51923+ * Revision 1.42 2002/01/29 22:25:36 rgb
51924+ * Re-add ipsec_kversion.h to keep MALLOC happy.
51925+ *
51926+ * Revision 1.41 2002/01/29 01:59:10 mcr
51927+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
51928+ * updating of IPv6 structures to match latest in6.h version.
51929+ * removed dead code from openswan.h that also duplicated kversions.h
51930+ * code.
51931+ *
51932+ * Revision 1.40 2002/01/20 20:34:50 mcr
51933+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
51934+ *
51935+ * Revision 1.39 2001/11/27 05:29:22 mcr
51936+ * pfkey parses are now maintained by a structure
51937+ * that includes their name for debug purposes.
51938+ * DEBUGGING() macro changed so that it takes a debug
51939+ * level so that pf_key() can use this to decode the
51940+ * structures without innundanting humans.
51941+ * Also uses pfkey_v2_sadb_ext_string() in messages.
51942+ *
51943+ * Revision 1.38 2001/11/06 19:47:47 rgb
51944+ * Added packet parameter to lifetime and comb structures.
51945+ *
51946+ * Revision 1.37 2001/10/18 04:45:24 rgb
51947+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
51948+ * lib/openswan.h version macros moved to lib/kversions.h.
51949+ * Other compiler directive cleanups.
51950+ *
51951+ * Revision 1.36 2001/06/14 19:35:16 rgb
51952+ * Update copyright date.
51953+ *
51954+ * Revision 1.35 2001/05/03 19:44:51 rgb
51955+ * Standardise on SENDERR() macro.
51956+ *
51957+ * Revision 1.34 2001/03/16 07:41:51 rgb
51958+ * Put openswan.h include before pluto includes.
51959+ *
51960+ * Revision 1.33 2001/02/27 07:13:51 rgb
51961+ * Added satype2name() function.
51962+ * Added text to default satype_tbl entry.
51963+ * Added satype2name() conversions for most satype debug output.
51964+ *
51965+ * Revision 1.32 2001/02/26 20:01:09 rgb
51966+ * Added internal IP protocol 61 for magic SAs.
51967+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
51968+ * Re-formatted debug output (split lines, consistent spacing).
51969+ * Removed acquire, register and expire requirements for a known satype.
51970+ * Changed message type checking to a switch structure.
51971+ * Verify expected NULL auth for IPCOMP.
51972+ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for
51973+ * appropriate message types.
51974+ *
51975+ * Revision 1.31 2000/12/01 07:09:00 rgb
51976+ * Added ipcomp sanity check to require encalgo is set.
51977+ *
51978+ * Revision 1.30 2000/11/17 18:10:30 rgb
51979+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
51980+ * network byte order since this is the way PF_KEYv2 stored spis.
51981+ *
51982+ * Revision 1.29 2000/10/12 00:02:39 rgb
51983+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
51984+ *
51985+ * Revision 1.28 2000/09/20 16:23:04 rgb
51986+ * Remove over-paranoid extension check in the presence of sadb_msg_errno.
51987+ *
51988+ * Revision 1.27 2000/09/20 04:04:21 rgb
51989+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
51990+ * oopsen.
51991+ *
51992+ * Revision 1.26 2000/09/15 11:37:02 rgb
51993+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
51994+ * IPCOMP zlib deflate code.
51995+ *
51996+ * Revision 1.25 2000/09/12 22:35:37 rgb
51997+ * Restructured to remove unused extensions from CLEARFLOW messages.
51998+ *
51999+ * Revision 1.24 2000/09/12 18:59:54 rgb
52000+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
52001+ *
52002+ * Revision 1.23 2000/09/12 03:27:00 rgb
52003+ * Moved DEBUGGING definition to compile kernel with debug off.
52004+ *
52005+ * Revision 1.22 2000/09/09 06:39:27 rgb
52006+ * Restrict pfkey errno check to downward messages only.
52007+ *
52008+ * Revision 1.21 2000/09/08 19:22:34 rgb
52009+ * Enabled pfkey_sens_parse().
52010+ * Added check for errno on downward acquire messages only.
52011+ *
52012+ * Revision 1.20 2000/09/01 18:48:23 rgb
52013+ * Fixed reserved check bug and added debug output in
52014+ * pfkey_supported_parse().
52015+ * Fixed debug output label bug in pfkey_ident_parse().
52016+ *
52017+ * Revision 1.19 2000/08/27 01:55:26 rgb
52018+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
52019+ *
52020+ * Revision 1.18 2000/08/24 17:00:36 rgb
52021+ * Ignore unknown extensions instead of failing.
52022+ *
52023+ * Revision 1.17 2000/06/02 22:54:14 rgb
52024+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
52025+ *
52026+ * Revision 1.16 2000/05/10 19:25:11 rgb
52027+ * Fleshed out proposal and supported extensions.
52028+ *
52029+ * Revision 1.15 2000/01/24 21:15:31 rgb
52030+ * Added disabled pluto pfkey lib debug flag.
52031+ * Added algo debugging reporting.
52032+ *
52033+ * Revision 1.14 2000/01/22 23:24:29 rgb
52034+ * Added new functions proto2satype() and satype2proto() and lookup
52035+ * table satype_tbl. Also added proto2name() since it was easy.
52036+ *
52037+ * Revision 1.13 2000/01/21 09:43:59 rgb
52038+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
52039+ *
52040+ * Revision 1.12 2000/01/21 06:28:19 rgb
52041+ * Added address cases for eroute flows.
52042+ * Indented compiler directives for readability.
52043+ * Added klipsdebug switching capability.
52044+ *
52045+ * Revision 1.11 1999/12/29 21:14:59 rgb
52046+ * Fixed debug text cut and paste typo.
52047+ *
52048+ * Revision 1.10 1999/12/10 17:45:24 rgb
52049+ * Added address debugging.
52050+ *
52051+ * Revision 1.9 1999/12/09 23:11:42 rgb
52052+ * Ditched <string.h> include since we no longer use memset().
52053+ * Use new pfkey_extensions_init() instead of memset().
52054+ * Added check for SATYPE in pfkey_msg_build().
52055+ * Tidy up comments and debugging comments.
52056+ *
52057+ * Revision 1.8 1999/12/07 19:55:26 rgb
52058+ * Removed unused first argument from extension parsers.
52059+ * Removed static pluto debug flag.
52060+ * Moved message type and state checking to pfkey_msg_parse().
52061+ * Changed print[fk] type from lx to x to quiet compiler.
52062+ * Removed redundant remain check.
52063+ * Changed __u* types to uint* to avoid use of asm/types.h and
52064+ * sys/types.h in userspace code.
52065+ *
52066+ * Revision 1.7 1999/12/01 22:20:51 rgb
52067+ * Moved pfkey_lib_debug variable into the library.
52068+ * Added pfkey version check into header parsing.
52069+ * Added check for SATYPE only for those extensions that require a
52070+ * non-zero value.
52071+ *
52072+ * Revision 1.6 1999/11/27 11:58:05 rgb
52073+ * Added ipv6 headers.
52074+ * Moved sadb_satype2proto protocol lookup table from
52075+ * klips/net/ipsec/pfkey_v2_parser.c.
52076+ * Enable lifetime_current checking.
52077+ * Debugging error messages added.
52078+ * Add argument to pfkey_msg_parse() for direction.
52079+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
52080+ * Add CVS log entry to bottom of file.
52081+ * Moved auth and enc alg check to pfkey_msg_parse().
52082+ * Enable accidentally disabled spirange parsing.
52083+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
52084+ *
52085+ * Local variables:
52086+ * c-file-style: "linux"
52087+ * End:
52088+ *
52089+ */
52090--- /dev/null Tue Mar 11 13:02:56 2003
52091+++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004
52092@@ -0,0 +1,3520 @@
52093+/*
52094+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
52095+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
52096+ *
52097+ * This program is free software; you can redistribute it and/or modify it
52098+ * under the terms of the GNU General Public License as published by the
52099+ * Free Software Foundation; either version 2 of the License, or (at your
52100+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
52101+ *
52102+ * This program is distributed in the hope that it will be useful, but
52103+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
52104+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
52105+ * for more details.
52106+ *
52107+ * RCSID $Id: pfkey_v2_parser.c,v 1.134.2.2 2006/10/06 21:39:26 paul Exp $
52108+ */
52109+
52110+/*
52111+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
52112+ */
52113+
52114+char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.134.2.2 2006/10/06 21:39:26 paul Exp $";
52115+
52116+#ifndef AUTOCONF_INCLUDED
52117+#include <linux/config.h>
52118+#endif
52119+#include <linux/version.h>
52120+#include <linux/kernel.h> /* printk() */
52121+
52122+#include "openswan/ipsec_param.h"
52123+
52124+#ifdef MALLOC_SLAB
52125+# include <linux/slab.h> /* kmalloc() */
52126+#else /* MALLOC_SLAB */
52127+# include <linux/malloc.h> /* kmalloc() */
52128+#endif /* MALLOC_SLAB */
52129+#include <linux/errno.h> /* error codes */
52130+#include <linux/types.h> /* size_t */
52131+#include <linux/interrupt.h> /* mark_bh */
52132+
52133+#include <linux/netdevice.h> /* struct device, and other headers */
52134+#include <linux/etherdevice.h> /* eth_type_trans */
52135+#include <linux/ip.h> /* struct iphdr */
52136+#include <linux/skbuff.h>
52137+
52138+#include <openswan.h>
52139+
52140+#include <crypto/des.h>
52141+
52142+#ifdef SPINLOCK
52143+# ifdef SPINLOCK_23
52144+# include <linux/spinlock.h> /* *lock* */
52145+# else /* SPINLOCK_23 */
52146+# include <asm/spinlock.h> /* *lock* */
52147+# endif /* SPINLOCK_23 */
52148+#endif /* SPINLOCK */
52149+
52150+#include <linux/in6.h>
52151+#include <net/route.h>
52152+
52153+#include <net/ip.h>
52154+#ifdef NETLINK_SOCK
52155+# include <linux/netlink.h>
52156+#else
52157+# include <net/netlink.h>
52158+#endif
52159+
52160+#include <linux/random.h> /* get_random_bytes() */
52161+
52162+#include "openswan/radij.h"
52163+#include "openswan/ipsec_encap.h"
52164+#include "openswan/ipsec_sa.h"
52165+
52166+#include "openswan/ipsec_radij.h"
52167+#include "openswan/ipsec_xform.h"
52168+#include "openswan/ipsec_ah.h"
52169+#include "openswan/ipsec_esp.h"
52170+#include "openswan/ipsec_tunnel.h"
52171+#include "openswan/ipsec_rcv.h"
52172+#include "openswan/ipcomp.h"
52173+
52174+#include <pfkeyv2.h>
52175+#include <pfkey.h>
52176+
52177+#include "openswan/ipsec_proto.h"
52178+#include "openswan/ipsec_alg.h"
52179+
52180+#include "openswan/ipsec_kern24.h"
52181+
52182+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
52183+
52184+struct sklist_t {
52185+ struct socket *sk;
52186+ struct sklist_t* next;
52187+} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
52188+
52189+__u32 pfkey_msg_seq = 0;
52190+
52191+
52192+#if 0
52193+#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)
52194+#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)
52195+static void dump_said(ip_said *s, int line)
52196+{
52197+ char msa[SATOT_BUF];
52198+ size_t msa_len;
52199+
52200+ msa_len = satot(s, 0, msa, sizeof(msa));
52201+
52202+ printk("line: %d msa: %s\n", line, msa);
52203+}
52204+#endif
52205+
52206+
52207+int
52208+pfkey_alloc_eroute(struct eroute** eroute)
52209+{
52210+ int error = 0;
52211+ if(*eroute) {
52212+ KLIPS_PRINT(debug_pfkey,
52213+ "klips_debug:pfkey_alloc_eroute: "
52214+ "eroute struct already allocated\n");
52215+ SENDERR(EEXIST);
52216+ }
52217+
52218+ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
52219+ KLIPS_PRINT(debug_pfkey,
52220+ "klips_debug:pfkey_alloc_eroute: "
52221+ "memory allocation error\n");
52222+ SENDERR(ENOMEM);
52223+ }
52224+
52225+ KLIPS_PRINT(debug_pfkey,
52226+ "klips_debug:pfkey_alloc_eroute: "
52227+ "allocating %lu bytes for an eroute at 0p%p\n",
52228+ (unsigned long) sizeof(**eroute), *eroute);
52229+
52230+ memset((caddr_t)*eroute, 0, sizeof(**eroute));
52231+ (*eroute)->er_eaddr.sen_len =
52232+ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
52233+ (*eroute)->er_eaddr.sen_family =
52234+ (*eroute)->er_emask.sen_family = AF_ENCAP;
52235+ (*eroute)->er_eaddr.sen_type = SENT_IP4;
52236+ (*eroute)->er_emask.sen_type = 255;
52237+ (*eroute)->er_pid = 0;
52238+ (*eroute)->er_count = 0;
52239+ (*eroute)->er_lasttime = jiffies/HZ;
52240+
52241+ errlab:
52242+ return(error);
52243+}
52244+
52245+DEBUG_NO_STATIC int
52246+pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
52247+ struct pfkey_extracted_data *extr)
52248+{
52249+ int error = 0;
52250+ struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
52251+
52252+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
52253+
52254+ if (extr == 0) {
52255+ KLIPS_PRINT(debug_pfkey,
52256+ "klips_debug:pfkey_x_protocol_process:"
52257+ "extr is NULL, fatal\n");
52258+ SENDERR(EINVAL);
52259+ }
52260+ if (extr->eroute == 0) {
52261+ KLIPS_PRINT(debug_pfkey,
52262+ "klips_debug:pfkey_x_protocol_process:"
52263+ "extr->eroute is NULL, fatal\n");
52264+ SENDERR(EINVAL);
52265+ }
52266+
52267+ extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
52268+ extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
52269+ KLIPS_PRINT(debug_pfkey,
52270+ "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
52271+ p->sadb_protocol_proto);
52272+ errlab:
52273+ return error;
52274+}
52275+
52276+DEBUG_NO_STATIC int
52277+pfkey_ipsec_sa_init(struct ipsec_sa *ipsp)
52278+{
52279+
52280+ return ipsec_sa_init(ipsp);
52281+}
52282+
52283+int
52284+pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
52285+{
52286+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
52287+ "error=%d\n",
52288+ error);
52289+ if (!error) {
52290+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
52291+ "success.\n");
52292+ return 1;
52293+ } else {
52294+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
52295+ "caught error %d\n",
52296+ error);
52297+ pfkey_extensions_free(extensions);
52298+ return 0;
52299+ }
52300+}
52301+
52302+
52303+DEBUG_NO_STATIC int
52304+pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52305+{
52306+ int error = 0;
52307+ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
52308+ int found_avail = 0;
52309+ struct ipsec_sa *ipsq;
52310+ char sa[SATOT_BUF];
52311+ size_t sa_len;
52312+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52313+ struct sadb_msg *pfkey_reply = NULL;
52314+ struct socket_list *pfkey_socketsp;
52315+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52316+
52317+ KLIPS_PRINT(debug_pfkey,
52318+ "klips_debug:pfkey_getspi_parse: .\n");
52319+
52320+ pfkey_extensions_init(extensions_reply);
52321+
52322+ if(extr == NULL || extr->ips == NULL) {
52323+ KLIPS_PRINT(debug_pfkey,
52324+ "klips_debug:pfkey_getspi_parse: "
52325+ "error, extr or extr->ipsec_sa pointer NULL\n");
52326+ SENDERR(EINVAL);
52327+ }
52328+
52329+ if(extensions[SADB_EXT_SPIRANGE]) {
52330+ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
52331+ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
52332+ }
52333+
52334+ if(maxspi == minspi) {
52335+ extr->ips->ips_said.spi = maxspi;
52336+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52337+ if(ipsq != NULL) {
52338+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52339+ ipsec_sa_put(ipsq);
52340+ KLIPS_PRINT(debug_pfkey,
52341+ "klips_debug:pfkey_getspi_parse: "
52342+ "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
52343+ sa_len ? sa : " (error)");
52344+ SENDERR(EEXIST);
52345+ } else {
52346+ found_avail = 1;
52347+ }
52348+ } else {
52349+ int i = 0;
52350+ __u32 rand_val;
52351+ __u32 spi_diff;
52352+ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
52353+ prng_bytes(&ipsec_prng, (char *) &(rand_val),
52354+ ( (spi_diff < (2^8)) ? 1 :
52355+ ( (spi_diff < (2^16)) ? 2 :
52356+ ( (spi_diff < (2^24)) ? 3 :
52357+ 4 ) ) ) );
52358+ extr->ips->ips_said.spi = htonl(ntohl(minspi) +
52359+ (rand_val %
52360+ (spi_diff + 1)));
52361+ i++;
52362+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52363+ if(ipsq == NULL) {
52364+ found_avail = 1;
52365+ } else {
52366+ ipsec_sa_put(ipsq);
52367+ }
52368+ }
52369+ }
52370+
52371+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52372+
52373+ if (!found_avail) {
52374+ KLIPS_PRINT(debug_pfkey,
52375+ "klips_debug:pfkey_getspi_parse: "
52376+ "found an old ipsec_sa for SA: %s, delete it first.\n",
52377+ sa_len ? sa : " (error)");
52378+ SENDERR(EEXIST);
52379+ }
52380+
52381+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52382+ extr->ips->ips_flags |= EMT_INBOUND;
52383+ }
52384+
52385+ KLIPS_PRINT(debug_pfkey,
52386+ "klips_debug:pfkey_getspi_parse: "
52387+ "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
52388+ sa_len ? sa : " (error)",
52389+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52390+
52391+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52392+ extr->ips->ips_rcvif = NULL;
52393+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
52394+
52395+ extr->ips->ips_state = SADB_SASTATE_LARVAL;
52396+
52397+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
52398+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
52399+ }
52400+
52401+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52402+ SADB_GETSPI,
52403+ satype,
52404+ 0,
52405+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52406+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52407+ extensions_reply)
52408+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52409+ SADB_EXT_SA,
52410+ extr->ips->ips_said.spi,
52411+ 0,
52412+ SADB_SASTATE_LARVAL,
52413+ 0,
52414+ 0,
52415+ 0,
52416+ extr->ips->ips_ref),
52417+ extensions_reply)
52418+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52419+ SADB_EXT_ADDRESS_SRC,
52420+ 0, /*extr->ips->ips_said.proto,*/
52421+ 0,
52422+ extr->ips->ips_addr_s),
52423+ extensions_reply)
52424+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52425+ SADB_EXT_ADDRESS_DST,
52426+ 0, /*extr->ips->ips_said.proto,*/
52427+ 0,
52428+ extr->ips->ips_addr_d),
52429+ extensions_reply) )) {
52430+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52431+ "failed to build the getspi reply message extensions\n");
52432+ goto errlab;
52433+ }
52434+
52435+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52436+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52437+ "failed to build the getspi reply message\n");
52438+ SENDERR(-error);
52439+ }
52440+ for(pfkey_socketsp = pfkey_open_sockets;
52441+ pfkey_socketsp;
52442+ pfkey_socketsp = pfkey_socketsp->next) {
52443+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52444+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52445+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52446+ satype,
52447+ satype2name(satype),
52448+ pfkey_socketsp->socketp,
52449+ error);
52450+ SENDERR(-error);
52451+ }
52452+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52453+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52454+ satype,
52455+ satype2name(satype),
52456+ pfkey_socketsp->socketp);
52457+ }
52458+
52459+ if((error = ipsec_sa_add(extr->ips))) {
52460+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52461+ "failed to add the larval SA=%s with error=%d.\n",
52462+ sa_len ? sa : " (error)",
52463+ error);
52464+ SENDERR(-error);
52465+ }
52466+ extr->ips = NULL;
52467+
52468+ KLIPS_PRINT(debug_pfkey,
52469+ "klips_debug:pfkey_getspi_parse: "
52470+ "successful for SA: %s\n",
52471+ sa_len ? sa : " (error)");
52472+
52473+ errlab:
52474+ if (pfkey_reply) {
52475+ pfkey_msg_free(&pfkey_reply);
52476+ }
52477+ pfkey_extensions_free(extensions_reply);
52478+ return error;
52479+}
52480+
52481+DEBUG_NO_STATIC int
52482+pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52483+{
52484+ int error = 0;
52485+ struct ipsec_sa* ipsq;
52486+ char sa[SATOT_BUF];
52487+ size_t sa_len;
52488+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52489+ struct sadb_msg *pfkey_reply = NULL;
52490+ struct socket_list *pfkey_socketsp;
52491+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52492+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52493+ struct ipsec_sa *nat_t_ips_saved = NULL;
52494+#endif
52495+ KLIPS_PRINT(debug_pfkey,
52496+ "klips_debug:pfkey_update_parse: .\n");
52497+
52498+ pfkey_extensions_init(extensions_reply);
52499+
52500+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
52501+ KLIPS_PRINT(debug_pfkey,
52502+ "klips_debug:pfkey_update_parse: "
52503+ "error, sa_state=%d must be MATURE=%d\n",
52504+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
52505+ SADB_SASTATE_MATURE);
52506+ SENDERR(EINVAL);
52507+ }
52508+
52509+ if(extr == NULL || extr->ips == NULL) {
52510+ KLIPS_PRINT(debug_pfkey,
52511+ "klips_debug:pfkey_update_parse: "
52512+ "error, extr or extr->ips pointer NULL\n");
52513+ SENDERR(EINVAL);
52514+ }
52515+
52516+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52517+
52518+ spin_lock_bh(&tdb_lock);
52519+
52520+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52521+ if (ipsq == NULL) {
52522+ spin_unlock_bh(&tdb_lock);
52523+ KLIPS_PRINT(debug_pfkey,
52524+ "klips_debug:pfkey_update_parse: "
52525+ "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n",
52526+ sa_len ? sa : " (error)");
52527+ SENDERR(ENOENT);
52528+ }
52529+
52530+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52531+ extr->ips->ips_flags |= EMT_INBOUND;
52532+ }
52533+
52534+ KLIPS_PRINT(debug_pfkey,
52535+ "klips_debug:pfkey_update_parse: "
52536+ "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
52537+ sa_len ? sa : " (error)",
52538+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52539+
52540+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52541+ if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) {
52542+ KLIPS_PRINT(debug_pfkey,
52543+ "klips_debug:pfkey_update_parse: only updating NAT-T ports "
52544+ "(%u:%u -> %u:%u)\n",
52545+ ipsq->ips_natt_sport, ipsq->ips_natt_dport,
52546+ extr->ips->ips_natt_sport, extr->ips->ips_natt_dport);
52547+
52548+ if (extr->ips->ips_natt_sport) {
52549+ ipsq->ips_natt_sport = extr->ips->ips_natt_sport;
52550+ if (ipsq->ips_addr_s->sa_family == AF_INET) {
52551+ ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport);
52552+ }
52553+ }
52554+
52555+ if (extr->ips->ips_natt_dport) {
52556+ ipsq->ips_natt_dport = extr->ips->ips_natt_dport;
52557+ if (ipsq->ips_addr_d->sa_family == AF_INET) {
52558+ ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport);
52559+ }
52560+ }
52561+
52562+ nat_t_ips_saved = extr->ips;
52563+ extr->ips = ipsq;
52564+ }
52565+ else {
52566+#endif
52567+
52568+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52569+ extr->ips->ips_rcvif = NULL;
52570+ if ((error = pfkey_ipsec_sa_init(extr->ips))) {
52571+ ipsec_sa_put(ipsq);
52572+ spin_unlock_bh(&tdb_lock);
52573+ KLIPS_PRINT(debug_pfkey,
52574+ "klips_debug:pfkey_update_parse: "
52575+ "not successful for SA: %s, deleting.\n",
52576+ sa_len ? sa : " (error)");
52577+ SENDERR(-error);
52578+ }
52579+
52580+ extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
52581+ ipsec_sa_put(ipsq);
52582+ if((error = ipsec_sa_delchain(ipsq))) {
52583+ spin_unlock_bh(&tdb_lock);
52584+ KLIPS_PRINT(debug_pfkey,
52585+ "klips_debug:pfkey_update_parse: "
52586+ "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n",
52587+ error,
52588+ sa_len ? sa : " (error)");
52589+ SENDERR(-error);
52590+ }
52591+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52592+ }
52593+#endif
52594+
52595+ spin_unlock_bh(&tdb_lock);
52596+
52597+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52598+ SADB_UPDATE,
52599+ satype,
52600+ 0,
52601+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52602+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52603+ extensions_reply)
52604+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52605+ SADB_EXT_SA,
52606+ extr->ips->ips_said.spi,
52607+ extr->ips->ips_replaywin,
52608+ extr->ips->ips_state,
52609+ extr->ips->ips_authalg,
52610+ extr->ips->ips_encalg,
52611+ extr->ips->ips_flags,
52612+ extr->ips->ips_ref),
52613+ extensions_reply)
52614+ /* The 3 lifetime extentions should only be sent if non-zero. */
52615+ && (extensions[SADB_EXT_LIFETIME_HARD]
52616+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
52617+ SADB_EXT_LIFETIME_HARD,
52618+ extr->ips->ips_life.ipl_allocations.ipl_hard,
52619+ extr->ips->ips_life.ipl_bytes.ipl_hard,
52620+ extr->ips->ips_life.ipl_addtime.ipl_hard,
52621+ extr->ips->ips_life.ipl_usetime.ipl_hard,
52622+ extr->ips->ips_life.ipl_packets.ipl_hard),
52623+ extensions_reply) : 1)
52624+ && (extensions[SADB_EXT_LIFETIME_SOFT]
52625+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
52626+ SADB_EXT_LIFETIME_SOFT,
52627+ extr->ips->ips_life.ipl_allocations.ipl_count,
52628+ extr->ips->ips_life.ipl_bytes.ipl_count,
52629+ extr->ips->ips_life.ipl_addtime.ipl_count,
52630+ extr->ips->ips_life.ipl_usetime.ipl_count,
52631+ extr->ips->ips_life.ipl_packets.ipl_count),
52632+ extensions_reply) : 1)
52633+ && (extr->ips->ips_life.ipl_allocations.ipl_count
52634+ || extr->ips->ips_life.ipl_bytes.ipl_count
52635+ || extr->ips->ips_life.ipl_addtime.ipl_count
52636+ || extr->ips->ips_life.ipl_usetime.ipl_count
52637+ || extr->ips->ips_life.ipl_packets.ipl_count
52638+
52639+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
52640+ SADB_EXT_LIFETIME_CURRENT,
52641+ extr->ips->ips_life.ipl_allocations.ipl_count,
52642+ extr->ips->ips_life.ipl_bytes.ipl_count,
52643+ extr->ips->ips_life.ipl_addtime.ipl_count,
52644+ extr->ips->ips_life.ipl_usetime.ipl_count,
52645+ extr->ips->ips_life.ipl_packets.ipl_count),
52646+ extensions_reply) : 1)
52647+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52648+ SADB_EXT_ADDRESS_SRC,
52649+ 0, /*extr->ips->ips_said.proto,*/
52650+ 0,
52651+ extr->ips->ips_addr_s),
52652+ extensions_reply)
52653+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52654+ SADB_EXT_ADDRESS_DST,
52655+ 0, /*extr->ips->ips_said.proto,*/
52656+ 0,
52657+ extr->ips->ips_addr_d),
52658+ extensions_reply)
52659+ && (extr->ips->ips_ident_s.data
52660+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
52661+ SADB_EXT_IDENTITY_SRC,
52662+ extr->ips->ips_ident_s.type,
52663+ extr->ips->ips_ident_s.id,
52664+ extr->ips->ips_ident_s.len,
52665+ extr->ips->ips_ident_s.data),
52666+ extensions_reply) : 1)
52667+ && (extr->ips->ips_ident_d.data
52668+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
52669+ SADB_EXT_IDENTITY_DST,
52670+ extr->ips->ips_ident_d.type,
52671+ extr->ips->ips_ident_d.id,
52672+ extr->ips->ips_ident_d.len,
52673+ extr->ips->ips_ident_d.data),
52674+ extensions_reply) : 1)
52675+#if 0
52676+ /* FIXME: This won't work yet because I have not finished
52677+ it. */
52678+ && (extr->ips->ips_sens_
52679+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
52680+ extr->ips->ips_sens_dpd,
52681+ extr->ips->ips_sens_sens_level,
52682+ extr->ips->ips_sens_sens_len,
52683+ extr->ips->ips_sens_sens_bitmap,
52684+ extr->ips->ips_sens_integ_level,
52685+ extr->ips->ips_sens_integ_len,
52686+ extr->ips->ips_sens_integ_bitmap),
52687+ extensions_reply) : 1)
52688+#endif
52689+ )) {
52690+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52691+ "failed to build the update reply message extensions\n");
52692+ SENDERR(-error);
52693+ }
52694+
52695+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52696+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52697+ "failed to build the update reply message\n");
52698+ SENDERR(-error);
52699+ }
52700+ for(pfkey_socketsp = pfkey_open_sockets;
52701+ pfkey_socketsp;
52702+ pfkey_socketsp = pfkey_socketsp->next) {
52703+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52704+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52705+ "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52706+ satype,
52707+ satype2name(satype),
52708+ pfkey_socketsp->socketp,
52709+ error);
52710+ SENDERR(-error);
52711+ }
52712+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52713+ "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52714+ satype,
52715+ satype2name(satype),
52716+ pfkey_socketsp->socketp);
52717+ }
52718+
52719+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52720+ if (nat_t_ips_saved) {
52721+ /**
52722+ * As we _really_ update existing SA, we keep tdbq and need to delete
52723+ * parsed ips (nat_t_ips_saved, was extr->ips).
52724+ *
52725+ * goto errlab with extr->ips = nat_t_ips_saved will free it.
52726+ */
52727+
52728+ extr->ips = nat_t_ips_saved;
52729+
52730+ error = 0;
52731+ KLIPS_PRINT(debug_pfkey,
52732+ "klips_debug:pfkey_update_parse (NAT-T ports): "
52733+ "successful for SA: %s\n",
52734+ sa_len ? sa : " (error)");
52735+
52736+ goto errlab;
52737+ }
52738+#endif
52739+
52740+ if((error = ipsec_sa_add(extr->ips))) {
52741+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52742+ "failed to update the mature SA=%s with error=%d.\n",
52743+ sa_len ? sa : " (error)",
52744+ error);
52745+ SENDERR(-error);
52746+ }
52747+ extr->ips = NULL;
52748+
52749+ KLIPS_PRINT(debug_pfkey,
52750+ "klips_debug:pfkey_update_parse: "
52751+ "successful for SA: %s\n",
52752+ sa_len ? sa : " (error)");
52753+
52754+ errlab:
52755+ if (pfkey_reply) {
52756+ pfkey_msg_free(&pfkey_reply);
52757+ }
52758+ pfkey_extensions_free(extensions_reply);
52759+ return error;
52760+}
52761+
52762+DEBUG_NO_STATIC int
52763+pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52764+{
52765+ int error = 0;
52766+ struct ipsec_sa* ipsq;
52767+ char sa[SATOT_BUF];
52768+ size_t sa_len;
52769+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52770+ struct sadb_msg *pfkey_reply = NULL;
52771+ struct socket_list *pfkey_socketsp;
52772+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52773+
52774+ KLIPS_PRINT(debug_pfkey,
52775+ "klips_debug:pfkey_add_parse: .\n");
52776+
52777+ pfkey_extensions_init(extensions_reply);
52778+
52779+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
52780+ KLIPS_PRINT(debug_pfkey,
52781+ "klips_debug:pfkey_add_parse: "
52782+ "error, sa_state=%d must be MATURE=%d\n",
52783+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
52784+ SADB_SASTATE_MATURE);
52785+ SENDERR(EINVAL);
52786+ }
52787+
52788+ if(!extr || !extr->ips) {
52789+ KLIPS_PRINT(debug_pfkey,
52790+ "klips_debug:pfkey_add_parse: "
52791+ "extr or extr->ips pointer NULL\n");
52792+ SENDERR(EINVAL);
52793+ }
52794+
52795+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52796+
52797+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52798+ if(ipsq != NULL) {
52799+ ipsec_sa_put(ipsq);
52800+ KLIPS_PRINT(debug_pfkey,
52801+ "klips_debug:pfkey_add_parse: "
52802+ "found an old ipsec_sa for SA%s, delete it first.\n",
52803+ sa_len ? sa : " (error)");
52804+ SENDERR(EEXIST);
52805+ }
52806+
52807+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52808+ extr->ips->ips_flags |= EMT_INBOUND;
52809+ }
52810+
52811+ KLIPS_PRINT(debug_pfkey,
52812+ "klips_debug:pfkey_add_parse: "
52813+ "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
52814+ sa_len ? sa : " (error)",
52815+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52816+
52817+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52818+ extr->ips->ips_rcvif = NULL;
52819+
52820+ if ((error = pfkey_ipsec_sa_init(extr->ips))) {
52821+ KLIPS_PRINT(debug_pfkey,
52822+ "klips_debug:pfkey_add_parse: "
52823+ "not successful for SA: %s, deleting.\n",
52824+ sa_len ? sa : " (error)");
52825+ SENDERR(-error);
52826+ }
52827+
52828+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
52829+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
52830+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
52831+ }
52832+
52833+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52834+ SADB_ADD,
52835+ satype,
52836+ 0,
52837+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52838+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52839+ extensions_reply)
52840+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52841+ SADB_EXT_SA,
52842+ extr->ips->ips_said.spi,
52843+ extr->ips->ips_replaywin,
52844+ extr->ips->ips_state,
52845+ extr->ips->ips_authalg,
52846+ extr->ips->ips_encalg,
52847+ extr->ips->ips_flags,
52848+ extr->ips->ips_ref),
52849+ extensions_reply)
52850+ /* The 3 lifetime extentions should only be sent if non-zero. */
52851+ && (extensions[SADB_EXT_LIFETIME_HARD]
52852+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
52853+ SADB_EXT_LIFETIME_HARD,
52854+ extr->ips->ips_life.ipl_allocations.ipl_hard,
52855+ extr->ips->ips_life.ipl_bytes.ipl_hard,
52856+ extr->ips->ips_life.ipl_addtime.ipl_hard,
52857+ extr->ips->ips_life.ipl_usetime.ipl_hard,
52858+ extr->ips->ips_life.ipl_packets.ipl_hard),
52859+ extensions_reply) : 1)
52860+ && (extensions[SADB_EXT_LIFETIME_SOFT]
52861+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
52862+ SADB_EXT_LIFETIME_SOFT,
52863+ extr->ips->ips_life.ipl_allocations.ipl_soft,
52864+ extr->ips->ips_life.ipl_bytes.ipl_soft,
52865+ extr->ips->ips_life.ipl_addtime.ipl_soft,
52866+ extr->ips->ips_life.ipl_usetime.ipl_soft,
52867+ extr->ips->ips_life.ipl_packets.ipl_soft),
52868+ extensions_reply) : 1)
52869+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52870+ SADB_EXT_ADDRESS_SRC,
52871+ 0, /*extr->ips->ips_said.proto,*/
52872+ 0,
52873+ extr->ips->ips_addr_s),
52874+ extensions_reply)
52875+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52876+ SADB_EXT_ADDRESS_DST,
52877+ 0, /*extr->ips->ips_said.proto,*/
52878+ 0,
52879+ extr->ips->ips_addr_d),
52880+ extensions_reply)
52881+ && (extr->ips->ips_ident_s.data
52882+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
52883+ SADB_EXT_IDENTITY_SRC,
52884+ extr->ips->ips_ident_s.type,
52885+ extr->ips->ips_ident_s.id,
52886+ extr->ips->ips_ident_s.len,
52887+ extr->ips->ips_ident_s.data),
52888+ extensions_reply) : 1)
52889+ && (extr->ips->ips_ident_d.data
52890+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
52891+ SADB_EXT_IDENTITY_DST,
52892+ extr->ips->ips_ident_d.type,
52893+ extr->ips->ips_ident_d.id,
52894+ extr->ips->ips_ident_d.len,
52895+ extr->ips->ips_ident_d.data),
52896+ extensions_reply) : 1)
52897+#if 0
52898+ /* FIXME: This won't work yet because I have not finished
52899+ it. */
52900+ && (extr->ips->ips_sens_
52901+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
52902+ extr->ips->ips_sens_dpd,
52903+ extr->ips->ips_sens_sens_level,
52904+ extr->ips->ips_sens_sens_len,
52905+ extr->ips->ips_sens_sens_bitmap,
52906+ extr->ips->ips_sens_integ_level,
52907+ extr->ips->ips_sens_integ_len,
52908+ extr->ips->ips_sens_integ_bitmap),
52909+ extensions_reply) : 1)
52910+#endif
52911+ )) {
52912+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52913+ "failed to build the add reply message extensions\n");
52914+ SENDERR(-error);
52915+ }
52916+
52917+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52918+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52919+ "failed to build the add reply message\n");
52920+ SENDERR(-error);
52921+ }
52922+ for(pfkey_socketsp = pfkey_open_sockets;
52923+ pfkey_socketsp;
52924+ pfkey_socketsp = pfkey_socketsp->next) {
52925+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52926+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52927+ "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52928+ satype,
52929+ satype2name(satype),
52930+ pfkey_socketsp->socketp,
52931+ error);
52932+ SENDERR(-error);
52933+ }
52934+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52935+ "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52936+ satype,
52937+ satype2name(satype),
52938+ pfkey_socketsp->socketp);
52939+ }
52940+
52941+ if((error = ipsec_sa_add(extr->ips))) {
52942+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52943+ "failed to add the mature SA=%s with error=%d.\n",
52944+ sa_len ? sa : " (error)",
52945+ error);
52946+ SENDERR(-error);
52947+ }
52948+ extr->ips = NULL;
52949+
52950+ KLIPS_PRINT(debug_pfkey,
52951+ "klips_debug:pfkey_add_parse: "
52952+ "successful for SA: %s\n",
52953+ sa_len ? sa : " (error)");
52954+
52955+ errlab:
52956+ if (pfkey_reply) {
52957+ pfkey_msg_free(&pfkey_reply);
52958+ }
52959+ pfkey_extensions_free(extensions_reply);
52960+ return error;
52961+}
52962+
52963+DEBUG_NO_STATIC int
52964+pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52965+{
52966+ struct ipsec_sa *ipsp;
52967+ char sa[SATOT_BUF];
52968+ size_t sa_len;
52969+ int error = 0;
52970+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52971+ struct sadb_msg *pfkey_reply = NULL;
52972+ struct socket_list *pfkey_socketsp;
52973+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52974+
52975+ KLIPS_PRINT(debug_pfkey,
52976+ "klips_debug:pfkey_delete_parse: .\n");
52977+
52978+ pfkey_extensions_init(extensions_reply);
52979+
52980+ if(!extr || !extr->ips) {
52981+ KLIPS_PRINT(debug_pfkey,
52982+ "klips_debug:pfkey_delete_parse: "
52983+ "extr or extr->ips pointer NULL, fatal\n");
52984+ SENDERR(EINVAL);
52985+ }
52986+
52987+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52988+
52989+ spin_lock_bh(&tdb_lock);
52990+
52991+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
52992+ if (ipsp == NULL) {
52993+ spin_unlock_bh(&tdb_lock);
52994+ KLIPS_PRINT(debug_pfkey,
52995+ "klips_debug:pfkey_delete_parse: "
52996+ "ipsec_sa not found for SA:%s, could not delete.\n",
52997+ sa_len ? sa : " (error)");
52998+ SENDERR(ESRCH);
52999+ }
53000+
53001+ ipsec_sa_put(ipsp);
53002+ if((error = ipsec_sa_delchain(ipsp))) {
53003+ spin_unlock_bh(&tdb_lock);
53004+ KLIPS_PRINT(debug_pfkey,
53005+ "klips_debug:pfkey_delete_parse: "
53006+ "error=%d returned trying to delete ipsec_sa for SA:%s.\n",
53007+ error,
53008+ sa_len ? sa : " (error)");
53009+ SENDERR(-error);
53010+ }
53011+ spin_unlock_bh(&tdb_lock);
53012+
53013+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53014+ SADB_DELETE,
53015+ satype,
53016+ 0,
53017+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53018+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53019+ extensions_reply)
53020+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53021+ SADB_EXT_SA,
53022+ extr->ips->ips_said.spi,
53023+ 0,
53024+ 0,
53025+ 0,
53026+ 0,
53027+ 0,
53028+ extr->ips->ips_ref),
53029+ extensions_reply)
53030+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
53031+ SADB_EXT_ADDRESS_SRC,
53032+ 0, /*extr->ips->ips_said.proto,*/
53033+ 0,
53034+ extr->ips->ips_addr_s),
53035+ extensions_reply)
53036+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53037+ SADB_EXT_ADDRESS_DST,
53038+ 0, /*extr->ips->ips_said.proto,*/
53039+ 0,
53040+ extr->ips->ips_addr_d),
53041+ extensions_reply)
53042+ )) {
53043+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53044+ "failed to build the delete reply message extensions\n");
53045+ SENDERR(-error);
53046+ }
53047+
53048+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53049+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53050+ "failed to build the delete reply message\n");
53051+ SENDERR(-error);
53052+ }
53053+ for(pfkey_socketsp = pfkey_open_sockets;
53054+ pfkey_socketsp;
53055+ pfkey_socketsp = pfkey_socketsp->next) {
53056+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53057+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53058+ "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53059+ satype,
53060+ satype2name(satype),
53061+ pfkey_socketsp->socketp,
53062+ error);
53063+ SENDERR(-error);
53064+ }
53065+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53066+ "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53067+ satype,
53068+ satype2name(satype),
53069+ pfkey_socketsp->socketp);
53070+ }
53071+
53072+ errlab:
53073+ if (pfkey_reply) {
53074+ pfkey_msg_free(&pfkey_reply);
53075+ }
53076+ pfkey_extensions_free(extensions_reply);
53077+ return error;
53078+}
53079+
53080+DEBUG_NO_STATIC int
53081+pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53082+{
53083+ int error = 0;
53084+ struct ipsec_sa *ipsp;
53085+ char sa[SATOT_BUF];
53086+ size_t sa_len;
53087+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53088+ struct sadb_msg *pfkey_reply = NULL;
53089+
53090+ KLIPS_PRINT(debug_pfkey,
53091+ "klips_debug:pfkey_get_parse: .\n");
53092+
53093+ pfkey_extensions_init(extensions_reply);
53094+
53095+ if(!extr || !extr->ips) {
53096+ KLIPS_PRINT(debug_pfkey,
53097+ "klips_debug:pfkey_get_parse: "
53098+ "extr or extr->ips pointer NULL, fatal\n");
53099+ SENDERR(EINVAL);
53100+ }
53101+
53102+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
53103+
53104+ spin_lock_bh(&tdb_lock);
53105+
53106+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
53107+ if (ipsp == NULL) {
53108+ spin_unlock_bh(&tdb_lock);
53109+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53110+ "ipsec_sa not found for SA=%s, could not get.\n",
53111+ sa_len ? sa : " (error)");
53112+ SENDERR(ESRCH);
53113+ }
53114+
53115+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53116+ SADB_GET,
53117+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
53118+ 0,
53119+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53120+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53121+ extensions_reply)
53122+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53123+ SADB_EXT_SA,
53124+ extr->ips->ips_said.spi,
53125+ extr->ips->ips_replaywin,
53126+ extr->ips->ips_state,
53127+ extr->ips->ips_authalg,
53128+ extr->ips->ips_encalg,
53129+ extr->ips->ips_flags,
53130+ extr->ips->ips_ref),
53131+ extensions_reply)
53132+ /* The 3 lifetime extentions should only be sent if non-zero. */
53133+ && (ipsp->ips_life.ipl_allocations.ipl_count
53134+ || ipsp->ips_life.ipl_bytes.ipl_count
53135+ || ipsp->ips_life.ipl_addtime.ipl_count
53136+ || ipsp->ips_life.ipl_usetime.ipl_count
53137+ || ipsp->ips_life.ipl_packets.ipl_count
53138+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
53139+ SADB_EXT_LIFETIME_CURRENT,
53140+ ipsp->ips_life.ipl_allocations.ipl_count,
53141+ ipsp->ips_life.ipl_bytes.ipl_count,
53142+ ipsp->ips_life.ipl_addtime.ipl_count,
53143+ ipsp->ips_life.ipl_usetime.ipl_count,
53144+ ipsp->ips_life.ipl_packets.ipl_count),
53145+ extensions_reply) : 1)
53146+ && (ipsp->ips_life.ipl_allocations.ipl_hard
53147+ || ipsp->ips_life.ipl_bytes.ipl_hard
53148+ || ipsp->ips_life.ipl_addtime.ipl_hard
53149+ || ipsp->ips_life.ipl_usetime.ipl_hard
53150+ || ipsp->ips_life.ipl_packets.ipl_hard
53151+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
53152+ SADB_EXT_LIFETIME_HARD,
53153+ ipsp->ips_life.ipl_allocations.ipl_hard,
53154+ ipsp->ips_life.ipl_bytes.ipl_hard,
53155+ ipsp->ips_life.ipl_addtime.ipl_hard,
53156+ ipsp->ips_life.ipl_usetime.ipl_hard,
53157+ ipsp->ips_life.ipl_packets.ipl_hard),
53158+ extensions_reply) : 1)
53159+ && (ipsp->ips_life.ipl_allocations.ipl_soft
53160+ || ipsp->ips_life.ipl_bytes.ipl_soft
53161+ || ipsp->ips_life.ipl_addtime.ipl_soft
53162+ || ipsp->ips_life.ipl_usetime.ipl_soft
53163+ || ipsp->ips_life.ipl_packets.ipl_soft
53164+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
53165+ SADB_EXT_LIFETIME_SOFT,
53166+ ipsp->ips_life.ipl_allocations.ipl_soft,
53167+ ipsp->ips_life.ipl_bytes.ipl_soft,
53168+ ipsp->ips_life.ipl_addtime.ipl_soft,
53169+ ipsp->ips_life.ipl_usetime.ipl_soft,
53170+ ipsp->ips_life.ipl_packets.ipl_soft),
53171+ extensions_reply) : 1)
53172+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
53173+ SADB_EXT_ADDRESS_SRC,
53174+ 0, /*extr->ips->ips_said.proto,*/
53175+ 0,
53176+ extr->ips->ips_addr_s),
53177+ extensions_reply)
53178+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53179+ SADB_EXT_ADDRESS_DST,
53180+ 0, /*extr->ips->ips_said.proto,*/
53181+ 0,
53182+ extr->ips->ips_addr_d),
53183+ extensions_reply)
53184+ && (extr->ips->ips_addr_p
53185+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
53186+ SADB_EXT_ADDRESS_PROXY,
53187+ 0, /*extr->ips->ips_said.proto,*/
53188+ 0,
53189+ extr->ips->ips_addr_p),
53190+ extensions_reply) : 1)
53191+#if 0
53192+ /* FIXME: This won't work yet because the keys are not
53193+ stored directly in the ipsec_sa. They are stored as
53194+ contexts. */
53195+ && (extr->ips->ips_key_a_size
53196+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
53197+ SADB_EXT_KEY_AUTH,
53198+ extr->ips->ips_key_a_size * 8,
53199+ extr->ips->ips_key_a),
53200+ extensions_reply) : 1)
53201+ /* FIXME: This won't work yet because the keys are not
53202+ stored directly in the ipsec_sa. They are stored as
53203+ key schedules. */
53204+ && (extr->ips->ips_key_e_size
53205+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
53206+ SADB_EXT_KEY_ENCRYPT,
53207+ extr->ips->ips_key_e_size * 8,
53208+ extr->ips->ips_key_e),
53209+ extensions_reply) : 1)
53210+#endif
53211+ && (extr->ips->ips_ident_s.data
53212+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
53213+ SADB_EXT_IDENTITY_SRC,
53214+ extr->ips->ips_ident_s.type,
53215+ extr->ips->ips_ident_s.id,
53216+ extr->ips->ips_ident_s.len,
53217+ extr->ips->ips_ident_s.data),
53218+ extensions_reply) : 1)
53219+ && (extr->ips->ips_ident_d.data
53220+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
53221+ SADB_EXT_IDENTITY_DST,
53222+ extr->ips->ips_ident_d.type,
53223+ extr->ips->ips_ident_d.id,
53224+ extr->ips->ips_ident_d.len,
53225+ extr->ips->ips_ident_d.data),
53226+ extensions_reply) : 1)
53227+#if 0
53228+ /* FIXME: This won't work yet because I have not finished
53229+ it. */
53230+ && (extr->ips->ips_sens_
53231+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
53232+ extr->ips->ips_sens_dpd,
53233+ extr->ips->ips_sens_sens_level,
53234+ extr->ips->ips_sens_sens_len,
53235+ extr->ips->ips_sens_sens_bitmap,
53236+ extr->ips->ips_sens_integ_level,
53237+ extr->ips->ips_sens_integ_len,
53238+ extr->ips->ips_sens_integ_bitmap),
53239+ extensions_reply) : 1)
53240+#endif
53241+ )) {
53242+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53243+ "failed to build the get reply message extensions\n");
53244+ ipsec_sa_put(ipsp);
53245+ spin_unlock_bh(&tdb_lock);
53246+ SENDERR(-error);
53247+ }
53248+
53249+ ipsec_sa_put(ipsp);
53250+ spin_unlock_bh(&tdb_lock);
53251+
53252+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53253+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53254+ "failed to build the get reply message\n");
53255+ SENDERR(-error);
53256+ }
53257+
53258+ if((error = pfkey_upmsg(sk->sk_socket, pfkey_reply))) {
53259+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53260+ "failed to send the get reply message\n");
53261+ SENDERR(-error);
53262+ }
53263+
53264+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53265+ "succeeded in sending get reply message.\n");
53266+
53267+ errlab:
53268+ if (pfkey_reply) {
53269+ pfkey_msg_free(&pfkey_reply);
53270+ }
53271+ pfkey_extensions_free(extensions_reply);
53272+ return error;
53273+}
53274+
53275+DEBUG_NO_STATIC int
53276+pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53277+{
53278+ int error = 0;
53279+ struct socket_list *pfkey_socketsp;
53280+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53281+
53282+ KLIPS_PRINT(debug_pfkey,
53283+ "klips_debug:pfkey_acquire_parse: .\n");
53284+
53285+ /* XXX I don't know if we want an upper bound, since userspace may
53286+ want to register itself for an satype > SADB_SATYPE_MAX. */
53287+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53288+ KLIPS_PRINT(debug_pfkey,
53289+ "klips_debug:pfkey_acquire_parse: "
53290+ "SATYPE=%d invalid.\n",
53291+ satype);
53292+ SENDERR(EINVAL);
53293+ }
53294+
53295+ if(!(pfkey_registered_sockets[satype])) {
53296+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53297+ "no sockets registered for SAtype=%d(%s).\n",
53298+ satype,
53299+ satype2name(satype));
53300+ SENDERR(EPROTONOSUPPORT);
53301+ }
53302+
53303+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
53304+ pfkey_socketsp;
53305+ pfkey_socketsp = pfkey_socketsp->next) {
53306+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53307+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53308+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53309+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53310+ satype,
53311+ satype2name(satype),
53312+ pfkey_socketsp->socketp,
53313+ error);
53314+ SENDERR(-error);
53315+ }
53316+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53317+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53318+ satype,
53319+ satype2name(satype),
53320+ pfkey_socketsp->socketp);
53321+ }
53322+
53323+ errlab:
53324+ return error;
53325+}
53326+
53327+DEBUG_NO_STATIC int
53328+pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53329+{
53330+ int error = 0;
53331+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53332+
53333+ KLIPS_PRINT(debug_pfkey,
53334+ "klips_debug:pfkey_register_parse: .\n");
53335+
53336+ /* XXX I don't know if we want an upper bound, since userspace may
53337+ want to register itself for an satype > SADB_SATYPE_MAX. */
53338+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53339+ KLIPS_PRINT(debug_pfkey,
53340+ "klips_debug:pfkey_register_parse: "
53341+ "SATYPE=%d invalid.\n",
53342+ satype);
53343+ SENDERR(EINVAL);
53344+ }
53345+
53346+ if(!pfkey_list_insert_socket(sk->sk_socket,
53347+ &(pfkey_registered_sockets[satype]))) {
53348+ KLIPS_PRINT(debug_pfkey,
53349+ "klips_debug:pfkey_register_parse: "
53350+ "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
53351+ satype,
53352+ satype2name(satype),
53353+ key_pid(sk));
53354+ };
53355+
53356+ /* send up register msg with supported SATYPE algos */
53357+
53358+ error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]);
53359+ errlab:
53360+ return error;
53361+}
53362+
53363+int
53364+pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
53365+{
53366+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53367+ struct sadb_msg *pfkey_reply = NULL;
53368+ struct socket_list *pfkey_socketsp;
53369+ struct supported_list *pfkey_supported_listp;
53370+ unsigned int alg_num_a = 0, alg_num_e = 0;
53371+ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
53372+ int error = 0;
53373+
53374+ pfkey_extensions_init(extensions_reply);
53375+
53376+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53377+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53378+ "SAtype=%d unspecified or unknown.\n",
53379+ satype);
53380+ SENDERR(EINVAL);
53381+ }
53382+ if(!(pfkey_registered_sockets[satype])) {
53383+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53384+ "no sockets registered for SAtype=%d(%s).\n",
53385+ satype,
53386+ satype2name(satype));
53387+ SENDERR(EPROTONOSUPPORT);
53388+ }
53389+ /* send up register msg with supported SATYPE algos */
53390+ pfkey_supported_listp = pfkey_supported_list[satype];
53391+ KLIPS_PRINT(debug_pfkey,
53392+ "klips_debug:pfkey_register_reply: "
53393+ "pfkey_supported_list[%d]=0p%p\n",
53394+ satype,
53395+ pfkey_supported_list[satype]);
53396+ while(pfkey_supported_listp) {
53397+ KLIPS_PRINT(debug_pfkey,
53398+ "klips_debug:pfkey_register_reply: "
53399+ "checking supported=0p%p\n",
53400+ pfkey_supported_listp);
53401+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
53402+ KLIPS_PRINT(debug_pfkey,
53403+ "klips_debug:pfkey_register_reply: "
53404+ "adding auth alg.\n");
53405+ alg_num_a++;
53406+ }
53407+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
53408+ KLIPS_PRINT(debug_pfkey,
53409+ "klips_debug:pfkey_register_reply: "
53410+ "adding encrypt alg.\n");
53411+ alg_num_e++;
53412+ }
53413+ pfkey_supported_listp = pfkey_supported_listp->next;
53414+ }
53415+
53416+ if(alg_num_a) {
53417+ KLIPS_PRINT(debug_pfkey,
53418+ "klips_debug:pfkey_register_reply: "
53419+ "allocating %lu bytes for auth algs.\n",
53420+ (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
53421+ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
53422+ KLIPS_PRINT(debug_pfkey,
53423+ "klips_debug:pfkey_register_reply: "
53424+ "auth alg memory allocation error\n");
53425+ SENDERR(ENOMEM);
53426+ }
53427+ alg_ap = alg_a;
53428+ }
53429+
53430+ if(alg_num_e) {
53431+ KLIPS_PRINT(debug_pfkey,
53432+ "klips_debug:pfkey_register_reply: "
53433+ "allocating %lu bytes for enc algs.\n",
53434+ (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
53435+ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
53436+ KLIPS_PRINT(debug_pfkey,
53437+ "klips_debug:pfkey_register_reply: "
53438+ "enc alg memory allocation error\n");
53439+ SENDERR(ENOMEM);
53440+ }
53441+ alg_ep = alg_e;
53442+ }
53443+
53444+ pfkey_supported_listp = pfkey_supported_list[satype];
53445+ while(pfkey_supported_listp) {
53446+ if(alg_num_a) {
53447+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
53448+ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
53449+ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
53450+ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
53451+ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
53452+ alg_ap->sadb_alg_reserved = 0;
53453+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
53454+ "klips_debug:pfkey_register_reply: "
53455+ "adding auth=0p%p\n",
53456+ alg_ap);
53457+ alg_ap++;
53458+ }
53459+ }
53460+ if(alg_num_e) {
53461+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
53462+ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
53463+ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
53464+ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
53465+ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
53466+ alg_ep->sadb_alg_reserved = 0;
53467+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
53468+ "klips_debug:pfkey_register_reply: "
53469+ "adding encrypt=0p%p\n",
53470+ alg_ep);
53471+ alg_ep++;
53472+ }
53473+ }
53474+ KLIPS_PRINT(debug_pfkey,
53475+ "klips_debug:pfkey_register_reply: "
53476+ "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
53477+ satype,
53478+ satype2name(satype),
53479+ pfkey_supported_listp->supportedp->ias_exttype,
53480+ pfkey_supported_listp->supportedp->ias_id,
53481+ pfkey_supported_listp->supportedp->ias_ivlen,
53482+ pfkey_supported_listp->supportedp->ias_keyminbits,
53483+ pfkey_supported_listp->supportedp->ias_keymaxbits);
53484+ pfkey_supported_listp = pfkey_supported_listp->next;
53485+ }
53486+
53487+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53488+ SADB_REGISTER,
53489+ satype,
53490+ 0,
53491+ sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
53492+ sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
53493+ extensions_reply) &&
53494+ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
53495+ SADB_EXT_SUPPORTED_AUTH,
53496+ alg_num_a,
53497+ alg_a),
53498+ extensions_reply) : 1) &&
53499+ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
53500+ SADB_EXT_SUPPORTED_ENCRYPT,
53501+ alg_num_e,
53502+ alg_e),
53503+ extensions_reply) : 1))) {
53504+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53505+ "failed to build the register message extensions_reply\n");
53506+ SENDERR(-error);
53507+ }
53508+
53509+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53510+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53511+ "failed to build the register message\n");
53512+ SENDERR(-error);
53513+ }
53514+ /* this should go to all registered sockets for that satype only */
53515+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
53516+ pfkey_socketsp;
53517+ pfkey_socketsp = pfkey_socketsp->next) {
53518+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53519+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53520+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53521+ satype,
53522+ satype2name(satype),
53523+ pfkey_socketsp->socketp,
53524+ error);
53525+ SENDERR(-error);
53526+ }
53527+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53528+ "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n",
53529+ satype,
53530+ satype2name(satype),
53531+ pfkey_socketsp->socketp);
53532+ }
53533+
53534+ errlab:
53535+ if(alg_a) {
53536+ kfree(alg_a);
53537+ }
53538+ if(alg_e) {
53539+ kfree(alg_e);
53540+ }
53541+
53542+ if (pfkey_reply) {
53543+ pfkey_msg_free(&pfkey_reply);
53544+ }
53545+ pfkey_extensions_free(extensions_reply);
53546+ return error;
53547+}
53548+
53549+DEBUG_NO_STATIC int
53550+pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53551+{
53552+ int error = 0;
53553+ struct socket_list *pfkey_socketsp;
53554+#ifdef CONFIG_KLIPS_DEBUG
53555+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53556+#endif /* CONFIG_KLIPS_DEBUG */
53557+
53558+ KLIPS_PRINT(debug_pfkey,
53559+ "klips_debug:pfkey_expire_parse: .\n");
53560+
53561+ if(pfkey_open_sockets) {
53562+ for(pfkey_socketsp = pfkey_open_sockets;
53563+ pfkey_socketsp;
53564+ pfkey_socketsp = pfkey_socketsp->next) {
53565+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53566+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53567+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
53568+ "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53569+ satype,
53570+ satype2name(satype),
53571+ pfkey_socketsp->socketp,
53572+ error);
53573+ SENDERR(-error);
53574+ }
53575+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
53576+ "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53577+ satype,
53578+ satype2name(satype),
53579+ pfkey_socketsp->socketp);
53580+ }
53581+ }
53582+
53583+ errlab:
53584+ return error;
53585+}
53586+
53587+DEBUG_NO_STATIC int
53588+pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53589+{
53590+ int error = 0;
53591+ struct socket_list *pfkey_socketsp;
53592+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53593+ uint8_t proto = 0;
53594+
53595+ KLIPS_PRINT(debug_pfkey,
53596+ "klips_debug:pfkey_flush_parse: "
53597+ "flushing type %d SAs\n",
53598+ satype);
53599+
53600+ if(satype && !(proto = satype2proto(satype))) {
53601+ KLIPS_PRINT(debug_pfkey,
53602+ "klips_debug:pfkey_flush_parse: "
53603+ "satype %d lookup failed.\n",
53604+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
53605+ SENDERR(EINVAL);
53606+ }
53607+
53608+ if ((error = ipsec_sadb_cleanup(proto))) {
53609+ SENDERR(-error);
53610+ }
53611+
53612+ if(pfkey_open_sockets) {
53613+ for(pfkey_socketsp = pfkey_open_sockets;
53614+ pfkey_socketsp;
53615+ pfkey_socketsp = pfkey_socketsp->next) {
53616+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53617+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53618+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
53619+ "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
53620+ satype,
53621+ satype2name(satype),
53622+ proto,
53623+ pfkey_socketsp->socketp,
53624+ error);
53625+ SENDERR(-error);
53626+ }
53627+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
53628+ "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53629+ satype,
53630+ satype2name(satype),
53631+ pfkey_socketsp->socketp);
53632+ }
53633+ }
53634+
53635+ errlab:
53636+ return error;
53637+}
53638+
53639+DEBUG_NO_STATIC int
53640+pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53641+{
53642+ int error = 0;
53643+
53644+ KLIPS_PRINT(debug_pfkey,
53645+ "klips_debug:pfkey_dump_parse: .\n");
53646+
53647+ SENDERR(ENOSYS);
53648+ errlab:
53649+ return error;
53650+}
53651+
53652+DEBUG_NO_STATIC int
53653+pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53654+{
53655+ int error = 0;
53656+
53657+ KLIPS_PRINT(debug_pfkey,
53658+ "klips_debug:pfkey_promisc_parse: .\n");
53659+
53660+ SENDERR(ENOSYS);
53661+ errlab:
53662+ return error;
53663+}
53664+
53665+DEBUG_NO_STATIC int
53666+pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53667+{
53668+ int error = 0;
53669+
53670+ KLIPS_PRINT(debug_pfkey,
53671+ "klips_debug:pfkey_x_pchange_parse: .\n");
53672+
53673+ SENDERR(ENOSYS);
53674+ errlab:
53675+ return error;
53676+}
53677+
53678+DEBUG_NO_STATIC int
53679+pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53680+{
53681+ struct ipsec_sa *ips1p, *ips2p, *ipsp;
53682+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53683+ struct sadb_msg *pfkey_reply = NULL;
53684+ struct socket_list *pfkey_socketsp;
53685+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53686+ char sa1[SATOT_BUF], sa2[SATOT_BUF];
53687+ size_t sa_len1, sa_len2 = 0;
53688+ int error = 0;
53689+
53690+ KLIPS_PRINT(debug_pfkey,
53691+ "klips_debug:pfkey_x_grpsa_parse: .\n");
53692+
53693+ pfkey_extensions_init(extensions_reply);
53694+
53695+ if(extr == NULL || extr->ips == NULL) {
53696+ KLIPS_PRINT(debug_pfkey,
53697+ "klips_debug:pfkey_x_grpsa_parse: "
53698+ "extr or extr->ips is NULL, fatal.\n");
53699+ SENDERR(EINVAL);
53700+ }
53701+
53702+ sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1));
53703+ if(extr->ips2 != NULL) {
53704+ sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2));
53705+ }
53706+
53707+ spin_lock_bh(&tdb_lock);
53708+
53709+ ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
53710+ if(ips1p == NULL) {
53711+ spin_unlock_bh(&tdb_lock);
53712+ KLIPS_PRINT(debug_pfkey,
53713+ "klips_debug:pfkey_x_grpsa_parse: "
53714+ "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n",
53715+ sa_len1 ? sa1 : " (error)");
53716+ SENDERR(ENOENT);
53717+ }
53718+ if(extr->ips2) { /* GRPSA */
53719+ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
53720+ if(ips2p == NULL) {
53721+ ipsec_sa_put(ips1p);
53722+ spin_unlock_bh(&tdb_lock);
53723+ KLIPS_PRINT(debug_pfkey,
53724+ "klips_debug:pfkey_x_grpsa_parse: "
53725+ "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n",
53726+ sa_len2 ? sa2 : " (error)");
53727+ SENDERR(ENOENT);
53728+ }
53729+
53730+ /* Is either one already linked? */
53731+ if(ips1p->ips_onext) {
53732+ ipsec_sa_put(ips1p);
53733+ ipsec_sa_put(ips2p);
53734+ spin_unlock_bh(&tdb_lock);
53735+ KLIPS_PRINT(debug_pfkey,
53736+ "klips_debug:pfkey_x_grpsa_parse: "
53737+ "ipsec_sa for SA: %s is already linked.\n",
53738+ sa_len1 ? sa1 : " (error)");
53739+ SENDERR(EEXIST);
53740+ }
53741+ if(ips2p->ips_inext) {
53742+ ipsec_sa_put(ips1p);
53743+ ipsec_sa_put(ips2p);
53744+ spin_unlock_bh(&tdb_lock);
53745+ KLIPS_PRINT(debug_pfkey,
53746+ "klips_debug:pfkey_x_grpsa_parse: "
53747+ "ipsec_sa for SA: %s is already linked.\n",
53748+ sa_len2 ? sa2 : " (error)");
53749+ SENDERR(EEXIST);
53750+ }
53751+
53752+ /* Is extr->ips already linked to extr->ips2? */
53753+ ipsp = ips2p;
53754+ while(ipsp) {
53755+ if(ipsp == ips1p) {
53756+ ipsec_sa_put(ips1p);
53757+ ipsec_sa_put(ips2p);
53758+ spin_unlock_bh(&tdb_lock);
53759+ KLIPS_PRINT(debug_pfkey,
53760+ "klips_debug:pfkey_x_grpsa_parse: "
53761+ "ipsec_sa for SA: %s is already linked to %s.\n",
53762+ sa_len1 ? sa1 : " (error)",
53763+ sa_len2 ? sa2 : " (error)");
53764+ SENDERR(EEXIST);
53765+ }
53766+ ipsp = ipsp->ips_onext;
53767+ }
53768+
53769+ /* link 'em */
53770+ KLIPS_PRINT(debug_pfkey,
53771+ "klips_debug:pfkey_x_grpsa_parse: "
53772+ "linking ipsec_sa SA: %s with %s.\n",
53773+ sa_len1 ? sa1 : " (error)",
53774+ sa_len2 ? sa2 : " (error)");
53775+ ips1p->ips_onext = ips2p;
53776+ ips2p->ips_inext = ips1p;
53777+ } else { /* UNGRPSA */
53778+ ipsec_sa_put(ips1p);
53779+ KLIPS_PRINT(debug_pfkey,
53780+ "klips_debug:pfkey_x_grpsa_parse: "
53781+ "unlinking ipsec_sa SA: %s.\n",
53782+ sa_len1 ? sa1 : " (error)");
53783+ while(ips1p->ips_onext) {
53784+ ips1p = ips1p->ips_onext;
53785+ }
53786+ while(ips1p->ips_inext) {
53787+ ipsp = ips1p;
53788+ ips1p = ips1p->ips_inext;
53789+ ipsec_sa_put(ips1p);
53790+ ipsp->ips_inext = NULL;
53791+ ipsec_sa_put(ipsp);
53792+ ips1p->ips_onext = NULL;
53793+ }
53794+ }
53795+
53796+ spin_unlock_bh(&tdb_lock);
53797+
53798+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53799+ SADB_X_GRPSA,
53800+ satype,
53801+ 0,
53802+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53803+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53804+ extensions_reply)
53805+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53806+ SADB_EXT_SA,
53807+ extr->ips->ips_said.spi,
53808+ extr->ips->ips_replaywin,
53809+ extr->ips->ips_state,
53810+ extr->ips->ips_authalg,
53811+ extr->ips->ips_encalg,
53812+ extr->ips->ips_flags,
53813+ extr->ips->ips_ref),
53814+ extensions_reply)
53815+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53816+ SADB_EXT_ADDRESS_DST,
53817+ 0, /*extr->ips->ips_said.proto,*/
53818+ 0,
53819+ extr->ips->ips_addr_d),
53820+ extensions_reply)
53821+ && (extr->ips2
53822+ ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
53823+ ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
53824+ /* proto2satype(extr->ips2->ips_said.proto) */),
53825+ extensions_reply)
53826+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2],
53827+ SADB_X_EXT_SA2,
53828+ extr->ips2->ips_said.spi,
53829+ extr->ips2->ips_replaywin,
53830+ extr->ips2->ips_state,
53831+ extr->ips2->ips_authalg,
53832+ extr->ips2->ips_encalg,
53833+ extr->ips2->ips_flags,
53834+ extr->ips2->ips_ref),
53835+ extensions_reply)
53836+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
53837+ SADB_X_EXT_ADDRESS_DST2,
53838+ 0, /*extr->ips->ips_said.proto,*/
53839+ 0,
53840+ extr->ips2->ips_addr_d),
53841+ extensions_reply) ) : 1 )
53842+ )) {
53843+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53844+ "failed to build the x_grpsa reply message extensions\n");
53845+ SENDERR(-error);
53846+ }
53847+
53848+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53849+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53850+ "failed to build the x_grpsa reply message\n");
53851+ SENDERR(-error);
53852+ }
53853+
53854+ for(pfkey_socketsp = pfkey_open_sockets;
53855+ pfkey_socketsp;
53856+ pfkey_socketsp = pfkey_socketsp->next) {
53857+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53858+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53859+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53860+ satype,
53861+ satype2name(satype),
53862+ pfkey_socketsp->socketp,
53863+ error);
53864+ SENDERR(-error);
53865+ }
53866+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53867+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53868+ satype,
53869+ satype2name(satype),
53870+ pfkey_socketsp->socketp);
53871+ }
53872+
53873+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53874+ "succeeded in sending x_grpsa reply message.\n");
53875+
53876+ errlab:
53877+ if (pfkey_reply) {
53878+ pfkey_msg_free(&pfkey_reply);
53879+ }
53880+ pfkey_extensions_free(extensions_reply);
53881+ return error;
53882+}
53883+
53884+DEBUG_NO_STATIC int
53885+pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53886+{
53887+ int error = 0;
53888+#ifdef CONFIG_KLIPS_DEBUG
53889+ char buf1[64], buf2[64];
53890+#endif /* CONFIG_KLIPS_DEBUG */
53891+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53892+ struct sadb_msg *pfkey_reply = NULL;
53893+ struct socket_list *pfkey_socketsp;
53894+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53895+ ip_address srcflow, dstflow, srcmask, dstmask;
53896+
53897+ KLIPS_PRINT(debug_pfkey,
53898+ "klips_debug:pfkey_x_addflow_parse: .\n");
53899+
53900+ pfkey_extensions_init(extensions_reply);
53901+
53902+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
53903+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
53904+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
53905+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
53906+
53907+ if(!extr || !(extr->ips) || !(extr->eroute)) {
53908+ KLIPS_PRINT(debug_pfkey,
53909+ "klips_debug:pfkey_x_addflow_parse: "
53910+ "missing extr, ipsec_sa or eroute data.\n");
53911+ SENDERR(EINVAL);
53912+ }
53913+
53914+ srcflow.u.v4.sin_family = AF_INET;
53915+ dstflow.u.v4.sin_family = AF_INET;
53916+ srcmask.u.v4.sin_family = AF_INET;
53917+ dstmask.u.v4.sin_family = AF_INET;
53918+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
53919+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
53920+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
53921+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
53922+
53923+#ifdef CONFIG_KLIPS_DEBUG
53924+ if (debug_pfkey) {
53925+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
53926+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
53927+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
53928+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
53929+ KLIPS_PRINT(debug_pfkey,
53930+ "klips_debug:pfkey_x_addflow_parse: "
53931+ "calling breakeroute and/or makeroute for %s->%s\n",
53932+ buf1, buf2);
53933+ }
53934+#endif /* CONFIG_KLIPS_DEBUG */
53935+
53936+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
53937+ struct ipsec_sa *ipsp, *ipsq;
53938+ char sa[SATOT_BUF];
53939+ size_t sa_len;
53940+
53941+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
53942+ if(ipsq == NULL) {
53943+ KLIPS_PRINT(debug_pfkey,
53944+ "klips_debug:pfkey_x_addflow_parse: "
53945+ "ipsec_sa not found, cannot set incoming policy.\n");
53946+ SENDERR(ENOENT);
53947+ }
53948+
53949+ ipsp = ipsq;
53950+ while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
53951+ ipsp = ipsp->ips_inext;
53952+ }
53953+
53954+ if(ipsp == NULL) {
53955+ ipsec_sa_put(ipsq);
53956+ KLIPS_PRINT(debug_pfkey,
53957+ "klips_debug:pfkey_x_addflow_parse: "
53958+ "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
53959+ SENDERR(ENOENT);
53960+ }
53961+
53962+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
53963+
53964+ ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
53965+ ipsp->ips_flow_s = srcflow;
53966+ ipsp->ips_flow_d = dstflow;
53967+ ipsp->ips_mask_s = srcmask;
53968+ ipsp->ips_mask_d = dstmask;
53969+
53970+ ipsec_sa_put(ipsq);
53971+
53972+ KLIPS_PRINT(debug_pfkey,
53973+ "klips_debug:pfkey_x_addflow_parse: "
53974+ "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
53975+ sa_len ? sa : " (error)");
53976+ } else {
53977+ struct sk_buff *first = NULL, *last = NULL;
53978+
53979+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
53980+ KLIPS_PRINT(debug_pfkey,
53981+ "klips_debug:pfkey_x_addflow_parse: "
53982+ "REPLACEFLOW flag set, calling breakeroute.\n");
53983+ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
53984+ &(extr->eroute->er_emask),
53985+ &first, &last))) {
53986+ KLIPS_PRINT(debug_pfkey,
53987+ "klips_debug:pfkey_x_addflow_parse: "
53988+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
53989+ error,
53990+ first,
53991+ last);
53992+ if(first != NULL) {
53993+ ipsec_kfree_skb(first);
53994+ }
53995+ if(last != NULL) {
53996+ ipsec_kfree_skb(last);
53997+ }
53998+ SENDERR(-error);
53999+ }
54000+ }
54001+
54002+ KLIPS_PRINT(debug_pfkey,
54003+ "klips_debug:pfkey_x_addflow_parse: "
54004+ "calling makeroute.\n");
54005+
54006+ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
54007+ &(extr->eroute->er_emask),
54008+ extr->ips->ips_said,
54009+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
54010+ NULL,
54011+ &(extr->ips->ips_ident_s),
54012+ &(extr->ips->ips_ident_d)))) {
54013+ KLIPS_PRINT(debug_pfkey,
54014+ "klips_debug:pfkey_x_addflow_parse: "
54015+ "makeroute returned %d.\n", error);
54016+ SENDERR(-error);
54017+ }
54018+ if(first != NULL) {
54019+ KLIPS_PRINT(debug_eroute,
54020+ "klips_debug:pfkey_x_addflow_parse: "
54021+ "first=0p%p HOLD packet re-injected.\n",
54022+ first);
54023+ DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL);
54024+ }
54025+ if(last != NULL) {
54026+ KLIPS_PRINT(debug_eroute,
54027+ "klips_debug:pfkey_x_addflow_parse: "
54028+ "last=0p%p HOLD packet re-injected.\n",
54029+ last);
54030+ DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL);
54031+ }
54032+ }
54033+
54034+ KLIPS_PRINT(debug_pfkey,
54035+ "klips_debug:pfkey_x_addflow_parse: "
54036+ "makeroute call successful.\n");
54037+
54038+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
54039+ SADB_X_ADDFLOW,
54040+ satype,
54041+ 0,
54042+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
54043+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
54044+ extensions_reply)
54045+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
54046+ SADB_EXT_SA,
54047+ extr->ips->ips_said.spi,
54048+ extr->ips->ips_replaywin,
54049+ extr->ips->ips_state,
54050+ extr->ips->ips_authalg,
54051+ extr->ips->ips_encalg,
54052+ extr->ips->ips_flags,
54053+ extr->ips->ips_ref),
54054+ extensions_reply)
54055+ && (extensions[SADB_EXT_ADDRESS_SRC]
54056+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
54057+ SADB_EXT_ADDRESS_SRC,
54058+ 0, /*extr->ips->ips_said.proto,*/
54059+ 0,
54060+ extr->ips->ips_addr_s),
54061+ extensions_reply) : 1)
54062+ && (extensions[SADB_EXT_ADDRESS_DST]
54063+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
54064+ SADB_EXT_ADDRESS_DST,
54065+ 0, /*extr->ips->ips_said.proto,*/
54066+ 0,
54067+ extr->ips->ips_addr_d),
54068+ extensions_reply) : 1)
54069+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
54070+ SADB_X_EXT_ADDRESS_SRC_FLOW,
54071+ 0, /*extr->ips->ips_said.proto,*/
54072+ 0,
54073+ (struct sockaddr*)&srcflow),
54074+ extensions_reply)
54075+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
54076+ SADB_X_EXT_ADDRESS_DST_FLOW,
54077+ 0, /*extr->ips->ips_said.proto,*/
54078+ 0,
54079+ (struct sockaddr*)&dstflow),
54080+ extensions_reply)
54081+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
54082+ SADB_X_EXT_ADDRESS_SRC_MASK,
54083+ 0, /*extr->ips->ips_said.proto,*/
54084+ 0,
54085+ (struct sockaddr*)&srcmask),
54086+ extensions_reply)
54087+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
54088+ SADB_X_EXT_ADDRESS_DST_MASK,
54089+ 0, /*extr->ips->ips_said.proto,*/
54090+ 0,
54091+ (struct sockaddr*)&dstmask),
54092+ extensions_reply)
54093+ )) {
54094+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54095+ "failed to build the x_addflow reply message extensions\n");
54096+ SENDERR(-error);
54097+ }
54098+
54099+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
54100+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54101+ "failed to build the x_addflow reply message\n");
54102+ SENDERR(-error);
54103+ }
54104+
54105+ for(pfkey_socketsp = pfkey_open_sockets;
54106+ pfkey_socketsp;
54107+ pfkey_socketsp = pfkey_socketsp->next) {
54108+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
54109+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54110+ "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54111+ satype,
54112+ satype2name(satype),
54113+ pfkey_socketsp->socketp,
54114+ error);
54115+ SENDERR(-error);
54116+ }
54117+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54118+ "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
54119+ satype,
54120+ satype2name(satype),
54121+ extr->ips->ips_said.proto,
54122+ pfkey_socketsp->socketp);
54123+ }
54124+
54125+ KLIPS_PRINT(debug_pfkey,
54126+ "klips_debug:pfkey_x_addflow_parse: "
54127+ "extr->ips cleaned up and freed.\n");
54128+
54129+ errlab:
54130+ if (pfkey_reply) {
54131+ pfkey_msg_free(&pfkey_reply);
54132+ }
54133+ pfkey_extensions_free(extensions_reply);
54134+ return error;
54135+}
54136+
54137+DEBUG_NO_STATIC int
54138+pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54139+{
54140+ int error = 0;
54141+#ifdef CONFIG_KLIPS_DEBUG
54142+ char buf1[64], buf2[64];
54143+#endif /* CONFIG_KLIPS_DEBUG */
54144+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
54145+ struct sadb_msg *pfkey_reply = NULL;
54146+ struct socket_list *pfkey_socketsp;
54147+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
54148+ ip_address srcflow, dstflow, srcmask, dstmask;
54149+
54150+ KLIPS_PRINT(debug_pfkey,
54151+ "klips_debug:pfkey_x_delflow_parse: .\n");
54152+
54153+ pfkey_extensions_init(extensions_reply);
54154+
54155+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
54156+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
54157+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
54158+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
54159+
54160+ if(!extr || !(extr->ips)) {
54161+ KLIPS_PRINT(debug_pfkey,
54162+ "klips_debug:pfkey_x_delflow_parse: "
54163+ "extr, or extr->ips is NULL, fatal\n");
54164+ SENDERR(EINVAL);
54165+ }
54166+
54167+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
54168+ KLIPS_PRINT(debug_pfkey,
54169+ "klips_debug:pfkey_x_delflow_parse: "
54170+ "CLEARFLOW flag set, calling cleareroutes.\n");
54171+ if ((error = ipsec_cleareroutes()))
54172+ KLIPS_PRINT(debug_pfkey,
54173+ "klips_debug:pfkey_x_delflow_parse: "
54174+ "cleareroutes returned %d.\n", error);
54175+ SENDERR(-error);
54176+ } else {
54177+ struct sk_buff *first = NULL, *last = NULL;
54178+
54179+ if(!(extr->eroute)) {
54180+ KLIPS_PRINT(debug_pfkey,
54181+ "klips_debug:pfkey_x_delflow_parse: "
54182+ "extr->eroute is NULL, fatal.\n");
54183+ SENDERR(EINVAL);
54184+ }
54185+
54186+ srcflow.u.v4.sin_family = AF_INET;
54187+ dstflow.u.v4.sin_family = AF_INET;
54188+ srcmask.u.v4.sin_family = AF_INET;
54189+ dstmask.u.v4.sin_family = AF_INET;
54190+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
54191+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
54192+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
54193+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
54194+
54195+#ifdef CONFIG_KLIPS_DEBUG
54196+ if (debug_pfkey) {
54197+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
54198+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
54199+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
54200+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
54201+ KLIPS_PRINT(debug_pfkey,
54202+ "klips_debug:pfkey_x_delflow_parse: "
54203+ "calling breakeroute for %s->%s\n",
54204+ buf1, buf2);
54205+ }
54206+#endif /* CONFIG_KLIPS_DEBUG */
54207+ error = ipsec_breakroute(&(extr->eroute->er_eaddr),
54208+ &(extr->eroute->er_emask),
54209+ &first, &last);
54210+ if(error) {
54211+ KLIPS_PRINT(debug_pfkey,
54212+ "klips_debug:pfkey_x_delflow_parse: "
54213+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
54214+ error,
54215+ first,
54216+ last);
54217+ }
54218+ if(first != NULL) {
54219+ ipsec_kfree_skb(first);
54220+ }
54221+ if(last != NULL) {
54222+ ipsec_kfree_skb(last);
54223+ }
54224+ if(error) {
54225+ SENDERR(-error);
54226+ }
54227+ }
54228+
54229+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
54230+ SADB_X_DELFLOW,
54231+ satype,
54232+ 0,
54233+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
54234+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
54235+ extensions_reply)
54236+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
54237+ SADB_EXT_SA,
54238+ extr->ips->ips_said.spi,
54239+ extr->ips->ips_replaywin,
54240+ extr->ips->ips_state,
54241+ extr->ips->ips_authalg,
54242+ extr->ips->ips_encalg,
54243+ extr->ips->ips_flags,
54244+ extr->ips->ips_ref),
54245+ extensions_reply)
54246+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
54247+ SADB_X_EXT_ADDRESS_SRC_FLOW,
54248+ 0, /*extr->ips->ips_said.proto,*/
54249+ 0,
54250+ (struct sockaddr*)&srcflow),
54251+ extensions_reply)
54252+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
54253+ SADB_X_EXT_ADDRESS_DST_FLOW,
54254+ 0, /*extr->ips->ips_said.proto,*/
54255+ 0,
54256+ (struct sockaddr*)&dstflow),
54257+ extensions_reply)
54258+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
54259+ SADB_X_EXT_ADDRESS_SRC_MASK,
54260+ 0, /*extr->ips->ips_said.proto,*/
54261+ 0,
54262+ (struct sockaddr*)&srcmask),
54263+ extensions_reply)
54264+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
54265+ SADB_X_EXT_ADDRESS_DST_MASK,
54266+ 0, /*extr->ips->ips_said.proto,*/
54267+ 0,
54268+ (struct sockaddr*)&dstmask),
54269+ extensions_reply)
54270+ )) {
54271+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54272+ "failed to build the x_delflow reply message extensions\n");
54273+ SENDERR(-error);
54274+ }
54275+
54276+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
54277+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54278+ "failed to build the x_delflow reply message\n");
54279+ SENDERR(-error);
54280+ }
54281+
54282+ for(pfkey_socketsp = pfkey_open_sockets;
54283+ pfkey_socketsp;
54284+ pfkey_socketsp = pfkey_socketsp->next) {
54285+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
54286+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54287+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54288+ satype,
54289+ satype2name(satype),
54290+ pfkey_socketsp->socketp,
54291+ error);
54292+ SENDERR(-error);
54293+ }
54294+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54295+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
54296+ satype,
54297+ satype2name(satype),
54298+ pfkey_socketsp->socketp);
54299+ }
54300+
54301+ KLIPS_PRINT(debug_pfkey,
54302+ "klips_debug:pfkey_x_delflow_parse: "
54303+ "extr->ips cleaned up and freed.\n");
54304+
54305+ errlab:
54306+ if (pfkey_reply) {
54307+ pfkey_msg_free(&pfkey_reply);
54308+ }
54309+ pfkey_extensions_free(extensions_reply);
54310+ return error;
54311+}
54312+
54313+DEBUG_NO_STATIC int
54314+pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54315+{
54316+ int error = 0;
54317+
54318+ KLIPS_PRINT(debug_pfkey,
54319+ "klips_debug:pfkey_x_msg_debug_parse: .\n");
54320+
54321+/* errlab:*/
54322+ return error;
54323+}
54324+
54325+/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
54326+int
54327+pfkey_expire(struct ipsec_sa *ipsp, int hard)
54328+{
54329+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54330+ struct sadb_msg *pfkey_msg = NULL;
54331+ struct socket_list *pfkey_socketsp;
54332+ int error = 0;
54333+ uint8_t satype;
54334+
54335+ pfkey_extensions_init(extensions);
54336+
54337+ if(!(satype = proto2satype(ipsp->ips_said.proto))) {
54338+ KLIPS_PRINT(debug_pfkey,
54339+ "klips_debug:pfkey_expire: "
54340+ "satype lookup for protocol %d lookup failed.\n",
54341+ ipsp->ips_said.proto);
54342+ SENDERR(EINVAL);
54343+ }
54344+
54345+ if(!pfkey_open_sockets) {
54346+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54347+ "no sockets listening.\n");
54348+ SENDERR(EPROTONOSUPPORT);
54349+ }
54350+
54351+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
54352+ SADB_EXPIRE,
54353+ satype,
54354+ 0,
54355+ ++pfkey_msg_seq,
54356+ 0),
54357+ extensions)
54358+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
54359+ SADB_EXT_SA,
54360+ ipsp->ips_said.spi,
54361+ ipsp->ips_replaywin,
54362+ ipsp->ips_state,
54363+ ipsp->ips_authalg,
54364+ ipsp->ips_encalg,
54365+ ipsp->ips_flags,
54366+ ipsp->ips_ref),
54367+ extensions)
54368+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
54369+ SADB_EXT_LIFETIME_CURRENT,
54370+ ipsp->ips_life.ipl_allocations.ipl_count,
54371+ ipsp->ips_life.ipl_bytes.ipl_count,
54372+ ipsp->ips_life.ipl_addtime.ipl_count,
54373+ ipsp->ips_life.ipl_usetime.ipl_count,
54374+ ipsp->ips_life.ipl_packets.ipl_count),
54375+ extensions)
54376+ && (hard ?
54377+ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
54378+ SADB_EXT_LIFETIME_HARD,
54379+ ipsp->ips_life.ipl_allocations.ipl_hard,
54380+ ipsp->ips_life.ipl_bytes.ipl_hard,
54381+ ipsp->ips_life.ipl_addtime.ipl_hard,
54382+ ipsp->ips_life.ipl_usetime.ipl_hard,
54383+ ipsp->ips_life.ipl_packets.ipl_hard),
54384+ extensions)
54385+ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
54386+ SADB_EXT_LIFETIME_SOFT,
54387+ ipsp->ips_life.ipl_allocations.ipl_soft,
54388+ ipsp->ips_life.ipl_bytes.ipl_soft,
54389+ ipsp->ips_life.ipl_addtime.ipl_soft,
54390+ ipsp->ips_life.ipl_usetime.ipl_soft,
54391+ ipsp->ips_life.ipl_packets.ipl_soft),
54392+ extensions))
54393+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54394+ SADB_EXT_ADDRESS_SRC,
54395+ 0, /* ipsp->ips_said.proto, */
54396+ 0,
54397+ ipsp->ips_addr_s),
54398+ extensions)
54399+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54400+ SADB_EXT_ADDRESS_DST,
54401+ 0, /* ipsp->ips_said.proto, */
54402+ 0,
54403+ ipsp->ips_addr_d),
54404+ extensions))) {
54405+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54406+ "failed to build the expire message extensions\n");
54407+ spin_unlock(&tdb_lock);
54408+ goto errlab;
54409+ }
54410+
54411+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54412+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54413+ "failed to build the expire message\n");
54414+ SENDERR(-error);
54415+ }
54416+
54417+ for(pfkey_socketsp = pfkey_open_sockets;
54418+ pfkey_socketsp;
54419+ pfkey_socketsp = pfkey_socketsp->next) {
54420+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54421+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54422+ "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54423+ satype,
54424+ satype2name(satype),
54425+ pfkey_socketsp->socketp,
54426+ error);
54427+ SENDERR(-error);
54428+ }
54429+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54430+ "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
54431+ satype,
54432+ satype2name(satype),
54433+ ipsp->ips_said.proto,
54434+ pfkey_socketsp->socketp);
54435+ }
54436+
54437+ errlab:
54438+ if (pfkey_msg) {
54439+ pfkey_msg_free(&pfkey_msg);
54440+ }
54441+ pfkey_extensions_free(extensions);
54442+ return error;
54443+}
54444+
54445+int
54446+pfkey_acquire(struct ipsec_sa *ipsp)
54447+{
54448+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54449+ struct sadb_msg *pfkey_msg = NULL;
54450+ struct socket_list *pfkey_socketsp;
54451+ int error = 0;
54452+ struct sadb_comb comb[] = {
54453+ /* auth; encrypt; flags; */
54454+ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
54455+ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
54456+ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
54457+ /* soft_packets; hard_packets; */
54458+ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
54459+ 128, 128, 168, 168,
54460+ 0, 0, 0, 0, 0,
54461+ 57600, 86400, 57600, 86400,
54462+ 0, 0 },
54463+ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
54464+ 160, 160, 168, 168,
54465+ 0, 0, 0, 0, 0,
54466+ 57600, 86400, 57600, 86400,
54467+ 0, 0 }
54468+ };
54469+
54470+ /* XXX This should not be hard-coded. It should be taken from the spdb */
54471+ uint8_t satype = SADB_SATYPE_ESP;
54472+
54473+ pfkey_extensions_init(extensions);
54474+
54475+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
54476+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
54477+ "SAtype=%d unspecified or unknown.\n",
54478+ satype);
54479+ SENDERR(EINVAL);
54480+ }
54481+
54482+ if(!(pfkey_registered_sockets[satype])) {
54483+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54484+ "no sockets registered for SAtype=%d(%s).\n",
54485+ satype,
54486+ satype2name(satype));
54487+ SENDERR(EPROTONOSUPPORT);
54488+ }
54489+
54490+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
54491+ SADB_ACQUIRE,
54492+ satype,
54493+ 0,
54494+ ++pfkey_msg_seq,
54495+ 0),
54496+ extensions)
54497+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54498+ SADB_EXT_ADDRESS_SRC,
54499+ ipsp->ips_transport_protocol,
54500+ 0,
54501+ ipsp->ips_addr_s),
54502+ extensions)
54503+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54504+ SADB_EXT_ADDRESS_DST,
54505+ ipsp->ips_transport_protocol,
54506+ 0,
54507+ ipsp->ips_addr_d),
54508+ extensions)
54509+#if 0
54510+ && (ipsp->ips_addr_p
54511+ ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
54512+ SADB_EXT_ADDRESS_PROXY,
54513+ ipsp->ips_transport_protocol,
54514+ 0,
54515+ ipsp->ips_addr_p),
54516+ extensions) : 1)
54517+#endif
54518+ && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
54519+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
54520+ SADB_EXT_IDENTITY_SRC,
54521+ ipsp->ips_ident_s.type,
54522+ ipsp->ips_ident_s.id,
54523+ ipsp->ips_ident_s.len,
54524+ ipsp->ips_ident_s.data),
54525+ extensions) : 1)
54526+
54527+ && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
54528+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
54529+ SADB_EXT_IDENTITY_DST,
54530+ ipsp->ips_ident_d.type,
54531+ ipsp->ips_ident_d.id,
54532+ ipsp->ips_ident_d.len,
54533+ ipsp->ips_ident_d.data),
54534+ extensions) : 1)
54535+#if 0
54536+ /* FIXME: This won't work yet because I have not finished
54537+ it. */
54538+ && (ipsp->ips_sens_
54539+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
54540+ ipsp->ips_sens_dpd,
54541+ ipsp->ips_sens_sens_level,
54542+ ipsp->ips_sens_sens_len,
54543+ ipsp->ips_sens_sens_bitmap,
54544+ ipsp->ips_sens_integ_level,
54545+ ipsp->ips_sens_integ_len,
54546+ ipsp->ips_sens_integ_bitmap),
54547+ extensions) : 1)
54548+#endif
54549+ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
54550+ 64, /* replay */
54551+ sizeof(comb)/sizeof(struct sadb_comb),
54552+ &(comb[0])),
54553+ extensions)
54554+ )) {
54555+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54556+ "failed to build the acquire message extensions\n");
54557+ SENDERR(-error);
54558+ }
54559+
54560+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54561+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54562+ "failed to build the acquire message\n");
54563+ SENDERR(-error);
54564+ }
54565+
54566+#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
54567+ if(sysctl_ipsec_regress_pfkey_lossage) {
54568+ return(0);
54569+ }
54570+#endif
54571+
54572+ /* this should go to all registered sockets for that satype only */
54573+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
54574+ pfkey_socketsp;
54575+ pfkey_socketsp = pfkey_socketsp->next) {
54576+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54577+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54578+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54579+ satype,
54580+ satype2name(satype),
54581+ pfkey_socketsp->socketp,
54582+ error);
54583+ SENDERR(-error);
54584+ }
54585+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
54586+ "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
54587+ satype,
54588+ satype2name(satype),
54589+ pfkey_socketsp->socketp);
54590+ }
54591+
54592+ errlab:
54593+ if (pfkey_msg) {
54594+ pfkey_msg_free(&pfkey_msg);
54595+ }
54596+ pfkey_extensions_free(extensions);
54597+ return error;
54598+}
54599+
54600+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54601+int
54602+pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr,
54603+ __u16 sport)
54604+{
54605+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54606+ struct sadb_msg *pfkey_msg = NULL;
54607+ struct socket_list *pfkey_socketsp;
54608+ int error = 0;
54609+ uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0;
54610+
54611+ /* Construct SADB_X_NAT_T_NEW_MAPPING message */
54612+
54613+ pfkey_extensions_init(extensions);
54614+
54615+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
54616+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54617+ "SAtype=%d unspecified or unknown.\n",
54618+ satype);
54619+ SENDERR(EINVAL);
54620+ }
54621+
54622+ if(!(pfkey_registered_sockets[satype])) {
54623+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54624+ "no sockets registered for SAtype=%d(%s).\n",
54625+ satype,
54626+ satype2name(satype));
54627+ SENDERR(EPROTONOSUPPORT);
54628+ }
54629+
54630+ if (!(pfkey_safe_build
54631+ (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING,
54632+ satype, 0, ++pfkey_msg_seq, 0), extensions)
54633+ /* SA */
54634+ && pfkey_safe_build
54635+ (error = pfkey_sa_build(&extensions[SADB_EXT_SA],
54636+ SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions)
54637+ /* ADDRESS_SRC = old addr */
54638+ && pfkey_safe_build
54639+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54640+ SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s),
54641+ extensions)
54642+ /* NAT_T_SPORT = old port */
54643+ && pfkey_safe_build
54644+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT],
54645+ SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions)
54646+ /* ADDRESS_DST = new addr */
54647+ && pfkey_safe_build
54648+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54649+ SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions)
54650+ /* NAT_T_DPORT = new port */
54651+ && pfkey_safe_build
54652+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT],
54653+ SADB_X_EXT_NAT_T_DPORT, sport), extensions)
54654+ )) {
54655+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54656+ "failed to build the nat_t_new_mapping message extensions\n");
54657+ SENDERR(-error);
54658+ }
54659+
54660+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54661+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54662+ "failed to build the nat_t_new_mapping message\n");
54663+ SENDERR(-error);
54664+ }
54665+
54666+ /* this should go to all registered sockets for that satype only */
54667+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
54668+ pfkey_socketsp;
54669+ pfkey_socketsp = pfkey_socketsp->next) {
54670+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54671+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54672+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
54673+ satype,
54674+ satype2name(satype),
54675+ pfkey_socketsp->socketp,
54676+ error);
54677+ SENDERR(-error);
54678+ }
54679+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54680+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
54681+ satype,
54682+ satype2name(satype),
54683+ pfkey_socketsp->socketp);
54684+ }
54685+
54686+ errlab:
54687+ if (pfkey_msg) {
54688+ pfkey_msg_free(&pfkey_msg);
54689+ }
54690+ pfkey_extensions_free(extensions);
54691+ return error;
54692+}
54693+
54694+DEBUG_NO_STATIC int
54695+pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54696+{
54697+ /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */
54698+ return -EINVAL;
54699+}
54700+#endif
54701+
54702+DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
54703+{
54704+ NULL, /* pfkey_msg_process, */
54705+ pfkey_sa_process,
54706+ pfkey_lifetime_process,
54707+ pfkey_lifetime_process,
54708+ pfkey_lifetime_process,
54709+ pfkey_address_process,
54710+ pfkey_address_process,
54711+ pfkey_address_process,
54712+ pfkey_key_process,
54713+ pfkey_key_process,
54714+ pfkey_ident_process,
54715+ pfkey_ident_process,
54716+ pfkey_sens_process,
54717+ pfkey_prop_process,
54718+ pfkey_supported_process,
54719+ pfkey_supported_process,
54720+ pfkey_spirange_process,
54721+ pfkey_x_kmprivate_process,
54722+ pfkey_x_satype_process,
54723+ pfkey_sa_process,
54724+ pfkey_address_process,
54725+ pfkey_address_process,
54726+ pfkey_address_process,
54727+ pfkey_address_process,
54728+ pfkey_address_process,
54729+ pfkey_x_debug_process,
54730+ pfkey_x_protocol_process
54731+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54732+ ,
54733+ pfkey_x_nat_t_type_process,
54734+ pfkey_x_nat_t_port_process,
54735+ pfkey_x_nat_t_port_process,
54736+ pfkey_address_process
54737+#endif
54738+};
54739+
54740+
54741+DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
54742+ =
54743+{
54744+ NULL, /* RESERVED */
54745+ pfkey_getspi_parse,
54746+ pfkey_update_parse,
54747+ pfkey_add_parse,
54748+ pfkey_delete_parse,
54749+ pfkey_get_parse,
54750+ pfkey_acquire_parse,
54751+ pfkey_register_parse,
54752+ pfkey_expire_parse,
54753+ pfkey_flush_parse,
54754+ pfkey_dump_parse,
54755+ pfkey_x_promisc_parse,
54756+ pfkey_x_pchange_parse,
54757+ pfkey_x_grpsa_parse,
54758+ pfkey_x_addflow_parse,
54759+ pfkey_x_delflow_parse,
54760+ pfkey_x_msg_debug_parse
54761+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54762+ , pfkey_x_nat_t_new_mapping_parse
54763+#endif
54764+};
54765+
54766+int
54767+pfkey_build_reply(struct sadb_msg *pfkey_msg,
54768+ struct pfkey_extracted_data *extr,
54769+ struct sadb_msg **pfkey_reply)
54770+{
54771+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54772+ int error = 0;
54773+ int msg_type = pfkey_msg->sadb_msg_type;
54774+ int seq = pfkey_msg->sadb_msg_seq;
54775+
54776+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
54777+ "building reply with type: %d\n",
54778+ msg_type);
54779+ pfkey_extensions_init(extensions);
54780+ if (!extr || !extr->ips) {
54781+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
54782+ "bad ipsec_sa passed\n");
54783+ return EINVAL;
54784+ }
54785+ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
54786+ msg_type,
54787+ proto2satype(extr->ips->ips_said.proto),
54788+ 0,
54789+ seq,
54790+ pfkey_msg->sadb_msg_pid),
54791+ extensions) &&
54792+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54793+ 1 << SADB_EXT_SA)
54794+ || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
54795+ SADB_EXT_SA,
54796+ extr->ips->ips_said.spi,
54797+ extr->ips->ips_replaywin,
54798+ extr->ips->ips_state,
54799+ extr->ips->ips_authalg,
54800+ extr->ips->ips_encalg,
54801+ extr->ips->ips_flags,
54802+ extr->ips->ips_ref),
54803+ extensions)) &&
54804+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54805+ 1 << SADB_EXT_LIFETIME_CURRENT)
54806+ || pfkey_safe_build(pfkey_lifetime_build(&extensions
54807+ [SADB_EXT_LIFETIME_CURRENT],
54808+ SADB_EXT_LIFETIME_CURRENT,
54809+ extr->ips->ips_life.ipl_allocations.ipl_count,
54810+ extr->ips->ips_life.ipl_bytes.ipl_count,
54811+ extr->ips->ips_life.ipl_addtime.ipl_count,
54812+ extr->ips->ips_life.ipl_usetime.ipl_count,
54813+ extr->ips->ips_life.ipl_packets.ipl_count),
54814+ extensions)) &&
54815+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54816+ 1 << SADB_EXT_ADDRESS_SRC)
54817+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54818+ SADB_EXT_ADDRESS_SRC,
54819+ extr->ips->ips_said.proto,
54820+ 0,
54821+ extr->ips->ips_addr_s),
54822+ extensions)) &&
54823+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54824+ 1 << SADB_EXT_ADDRESS_DST)
54825+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54826+ SADB_EXT_ADDRESS_DST,
54827+ extr->ips->ips_said.proto,
54828+ 0,
54829+ extr->ips->ips_addr_d),
54830+ extensions));
54831+
54832+ if (error == 0) {
54833+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
54834+ "building extensions failed\n");
54835+ return EINVAL;
54836+ }
54837+
54838+ KLIPS_PRINT(debug_pfkey,
54839+ "klips_debug:pfkey_build_reply: "
54840+ "built extensions, proceed to build the message\n");
54841+ KLIPS_PRINT(debug_pfkey,
54842+ "klips_debug:pfkey_build_reply: "
54843+ "extensions[1]=0p%p\n",
54844+ extensions[1]);
54845+ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
54846+ pfkey_extensions_free(extensions);
54847+
54848+ return error;
54849+}
54850+
54851+int
54852+pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
54853+ struct sadb_msg **pfkey_reply)
54854+{
54855+ int error = 0;
54856+ int i;
54857+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54858+ struct pfkey_extracted_data extr = {NULL, NULL, NULL};
54859+
54860+ pfkey_extensions_init(extensions);
54861+ KLIPS_PRINT(debug_pfkey,
54862+ "klips_debug:pfkey_msg_interp: "
54863+ "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
54864+ pfkey_msg->sadb_msg_version,
54865+ pfkey_msg->sadb_msg_type,
54866+ pfkey_msg->sadb_msg_errno,
54867+ pfkey_msg->sadb_msg_satype,
54868+ satype2name(pfkey_msg->sadb_msg_satype),
54869+ pfkey_msg->sadb_msg_len,
54870+ pfkey_msg->sadb_msg_reserved,
54871+ pfkey_msg->sadb_msg_seq,
54872+ pfkey_msg->sadb_msg_pid);
54873+
54874+ extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
54875+ if(extr.ips == NULL) {
54876+ KLIPS_PRINT(debug_pfkey,
54877+ "klips_debug:pfkey_msg_interp: "
54878+ "memory allocation error.\n");
54879+ SENDERR(-error);
54880+ }
54881+
54882+ KLIPS_PRINT(debug_pfkey,
54883+ "klips_debug:pfkey_msg_interp: "
54884+ "allocated extr->ips=0p%p.\n",
54885+ extr.ips);
54886+
54887+ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
54888+ KLIPS_PRINT(debug_pfkey,
54889+ "klips_debug:pfkey_msg_interp: "
54890+ "satype %d > max %d\n",
54891+ pfkey_msg->sadb_msg_satype,
54892+ SADB_SATYPE_MAX);
54893+ SENDERR(EINVAL);
54894+ }
54895+
54896+ switch(pfkey_msg->sadb_msg_type) {
54897+ case SADB_GETSPI:
54898+ case SADB_UPDATE:
54899+ case SADB_ADD:
54900+ case SADB_DELETE:
54901+ case SADB_X_GRPSA:
54902+ case SADB_X_ADDFLOW:
54903+ if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
54904+ KLIPS_PRINT(debug_pfkey,
54905+ "klips_debug:pfkey_msg_interp: "
54906+ "satype %d lookup failed.\n",
54907+ pfkey_msg->sadb_msg_satype);
54908+ SENDERR(EINVAL);
54909+ } else {
54910+ KLIPS_PRINT(debug_pfkey,
54911+ "klips_debug:pfkey_msg_interp: "
54912+ "satype %d lookups to proto=%d.\n",
54913+ pfkey_msg->sadb_msg_satype,
54914+ extr.ips->ips_said.proto);
54915+ }
54916+ break;
54917+ default:
54918+ break;
54919+ }
54920+
54921+ /* The NULL below causes the default extension parsers to be used */
54922+ /* Parse the extensions */
54923+ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
54924+ {
54925+ KLIPS_PRINT(debug_pfkey,
54926+ "klips_debug:pfkey_msg_interp: "
54927+ "message parsing failed with error %d.\n",
54928+ error);
54929+ SENDERR(-error);
54930+ }
54931+
54932+ /* Process the extensions */
54933+ for(i=1; i <= SADB_EXT_MAX;i++) {
54934+ if(extensions[i] != NULL) {
54935+ KLIPS_PRINT(debug_pfkey,
54936+ "klips_debug:pfkey_msg_interp: "
54937+ "processing ext %d 0p%p with processor 0p%p.\n",
54938+ i, extensions[i], ext_processors[i]);
54939+ if((error = ext_processors[i](extensions[i], &extr))) {
54940+ KLIPS_PRINT(debug_pfkey,
54941+ "klips_debug:pfkey_msg_interp: "
54942+ "extension processing for type %d failed with error %d.\n",
54943+ i,
54944+ error);
54945+ SENDERR(-error);
54946+ }
54947+
54948+ }
54949+
54950+ }
54951+
54952+ /* Parse the message types */
54953+ KLIPS_PRINT(debug_pfkey,
54954+ "klips_debug:pfkey_msg_interp: "
54955+ "parsing message type %d(%s) with msg_parser 0p%p.\n",
54956+ pfkey_msg->sadb_msg_type,
54957+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
54958+ msg_parsers[pfkey_msg->sadb_msg_type]);
54959+ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
54960+ KLIPS_PRINT(debug_pfkey,
54961+ "klips_debug:pfkey_msg_interp: "
54962+ "message parsing failed with error %d.\n",
54963+ error);
54964+ SENDERR(-error);
54965+ }
54966+
54967+#if 0
54968+ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
54969+ if (error) {
54970+ *pfkey_reply = NULL;
54971+ }
54972+#endif
54973+ errlab:
54974+ if(extr.ips != NULL) {
54975+ ipsec_sa_wipe(extr.ips);
54976+ }
54977+ if(extr.ips2 != NULL) {
54978+ ipsec_sa_wipe(extr.ips2);
54979+ }
54980+ if (extr.eroute != NULL) {
54981+ kfree(extr.eroute);
54982+ }
54983+ return(error);
54984+}
54985+
54986+/*
54987+ * $Log: pfkey_v2_parser.c,v $
54988+ * Revision 1.134.2.2 2006/10/06 21:39:26 paul
54989+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
54990+ * set. This is defined through autoconf.h which is included through the
54991+ * linux kernel build macros.
54992+ *
54993+ * Revision 1.134.2.1 2006/05/01 14:37:25 mcr
54994+ * ip_chk_addr -> inet_addr_type for more direct 2.4/2.6 support.
54995+ *
54996+ * Revision 1.134 2005/05/11 01:48:20 mcr
54997+ * removed "poor-man"s OOP in favour of proper C structures.
54998+ *
54999+ * Revision 1.133 2005/04/29 05:10:22 mcr
55000+ * removed from extraenous includes to make unit testing easier.
55001+ *
55002+ * Revision 1.132 2005/04/14 20:56:24 mcr
55003+ * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
55004+ *
55005+ * Revision 1.131 2005/01/26 00:50:35 mcr
55006+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
55007+ * and make sure that NAT_TRAVERSAL is set as well to match
55008+ * userspace compiles of code.
55009+ *
55010+ * Revision 1.130 2004/09/08 17:21:36 ken
55011+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
55012+ *
55013+ * Revision 1.129 2004/09/06 18:36:30 mcr
55014+ * if a protocol can not be found, then log it. This is not
55015+ * debugging.
55016+ *
55017+ * Revision 1.128 2004/08/21 00:45:19 mcr
55018+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
55019+ *
55020+ * Revision 1.127 2004/08/20 21:45:45 mcr
55021+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
55022+ * be 26sec compatible. But, some defines where changed.
55023+ *
55024+ * Revision 1.126 2004/08/17 03:27:23 mcr
55025+ * klips 2.6 edits.
55026+ *
55027+ * Revision 1.125 2004/08/04 15:57:07 mcr
55028+ * moved des .h files to include/des/ *
55029+ * included 2.6 protocol specific things
55030+ * started at NAT-T support, but it will require a kernel patch.
55031+ *
55032+ * Revision 1.124 2004/07/10 19:11:18 mcr
55033+ * CONFIG_IPSEC -> CONFIG_KLIPS.
55034+ *
55035+ * Revision 1.123 2004/04/06 02:49:26 mcr
55036+ * pullup of algo code from alg-branch.
55037+ *
55038+ * Revision 1.122.2.2 2004/04/05 04:30:46 mcr
55039+ * patches for alg-branch to compile/work with 2.x openswan
55040+ *
55041+ * Revision 1.122.2.1 2003/12/22 15:25:52 jjo
55042+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
55043+ *
55044+ * Revision 1.122 2003/12/10 01:14:27 mcr
55045+ * NAT-traversal patches to KLIPS.
55046+ *
55047+ * Revision 1.121 2003/10/31 02:27:55 mcr
55048+ * pulled up port-selector patches and sa_id elimination.
55049+ *
55050+ * Revision 1.120.4.2 2003/10/29 01:30:41 mcr
55051+ * elimited "struct sa_id".
55052+ *
55053+ * Revision 1.120.4.1 2003/09/21 13:59:56 mcr
55054+ * pre-liminary X.509 patch - does not yet pass tests.
55055+ *
55056+ * Revision 1.120 2003/04/03 17:38:09 rgb
55057+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
55058+ *
55059+ * Revision 1.119 2003/02/06 01:52:37 rgb
55060+ * Removed no longer relevant comment
55061+ *
55062+ * Revision 1.118 2003/01/30 02:32:44 rgb
55063+ *
55064+ * Transmit error code through to caller from callee for better diagnosis of problems.
55065+ *
55066+ * Revision 1.117 2003/01/16 18:48:13 rgb
55067+ *
55068+ * Fixed sign bug in error return from an sa allocation call in
55069+ * pfkey_msg_interp.
55070+ *
55071+ * Revision 1.116 2002/10/17 16:38:01 rgb
55072+ * Change pfkey_alloc_eroute() to never static since its consumers
55073+ * have been moved outside the file.
55074+ *
55075+ * Revision 1.115 2002/10/12 23:11:53 dhr
55076+ *
55077+ * [KenB + DHR] more 64-bit cleanup
55078+ *
55079+ * Revision 1.114 2002/10/05 05:02:58 dhr
55080+ *
55081+ * C labels go on statements
55082+ *
55083+ * Revision 1.113 2002/09/30 19:11:22 rgb
55084+ * Turn on debugging for upgoing acquire messages to test for reliability.
55085+ *
55086+ * Revision 1.112 2002/09/20 15:41:16 rgb
55087+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
55088+ * Added sadb_x_sa_ref to struct sadb_sa.
55089+ * Added ref parameter to pfkey_sa_build().
55090+ *
55091+ * Revision 1.111 2002/09/20 05:02:08 rgb
55092+ * Added memory allocation debugging.
55093+ * Convert to switch to divulge hmac keys for debugging.
55094+ * Added text labels to elucidate numeric values presented.
55095+ *
55096+ * Revision 1.110 2002/08/03 18:03:05 mcr
55097+ * loop that checks for SPI's to have been already linked
55098+ * fails to actually step to next pointer, but continuously
55099+ * resets to head of list. Wrong pointer used.
55100+ * test east-icmp-02 revealed this.
55101+ *
55102+ * Revision 1.109 2002/07/26 08:48:31 rgb
55103+ * Added SA ref table code.
55104+ *
55105+ * Revision 1.108 2002/05/27 18:55:03 rgb
55106+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
55107+ *
55108+ * Revision 1.107 2002/05/23 07:16:08 rgb
55109+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
55110+ * Pointer clean-up.
55111+ * Added refcount code.
55112+ *
55113+ * Revision 1.106 2002/05/14 02:34:13 rgb
55114+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
55115+ * with "put" usage in the kernel.
55116+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
55117+ * ipsec_sa or ipsec_sa.
55118+ * Moved all the extension parsing functions to pfkey_v2_ext_process.c.
55119+ *
55120+ * Revision 1.105 2002/04/24 07:55:32 mcr
55121+ * #include patches and Makefiles for post-reorg compilation.
55122+ *
55123+ * Revision 1.104 2002/04/24 07:36:34 mcr
55124+ * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v
55125+ *
55126+ * Revision 1.103 2002/04/20 00:12:25 rgb
55127+ * Added esp IV CBC attack fix, disabled.
55128+ *
55129+ * Revision 1.102 2002/03/08 01:15:17 mcr
55130+ * put some internal structure only debug messages behind
55131+ * && sysctl_ipsec_debug_verbose.
55132+ *
55133+ * Revision 1.101 2002/01/29 17:17:57 mcr
55134+ * moved include of ipsec_param.h to after include of linux/kernel.h
55135+ * otherwise, it seems that some option that is set in ipsec_param.h
55136+ * screws up something subtle in the include path to kernel.h, and
55137+ * it complains on the snprintf() prototype.
55138+ *
55139+ * Revision 1.100 2002/01/29 04:00:54 mcr
55140+ * more excise of kversions.h header.
55141+ *
55142+ * Revision 1.99 2002/01/29 02:13:19 mcr
55143+ * introduction of ipsec_kversion.h means that include of
55144+ * ipsec_param.h must preceed any decisions about what files to
55145+ * include to deal with differences in kernel source.
55146+ *
55147+ * Revision 1.98 2002/01/12 02:57:57 mcr
55148+ * first regression test causes acquire messages to be lost
55149+ * 100% of the time. This is to help testing of pluto.
55150+ *
55151+ * Revision 1.97 2001/11/26 09:23:52 rgb
55152+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
55153+ *
55154+ * Revision 1.93.2.4 2001/10/23 04:20:27 mcr
55155+ * parity was forced on wrong structure! prototypes help here.
55156+ *
55157+ * Revision 1.93.2.3 2001/10/22 21:14:59 mcr
55158+ * include des.h, removed phony prototypes and fixed calling
55159+ * conventions to match real prototypes.
55160+ *
55161+ * Revision 1.93.2.2 2001/10/15 05:39:03 mcr
55162+ * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
55163+ *
55164+ * Revision 1.93.2.1 2001/09/25 02:30:14 mcr
55165+ * struct tdb -> struct ipsec_sa.
55166+ * use new lifetime structure. common format routines for debug.
55167+ *
55168+ * Revision 1.96 2001/11/06 20:47:54 rgb
55169+ * Fixed user context call to ipsec_dev_start_xmit() bug. Call
55170+ * dev_queue_xmit() instead.
55171+ *
55172+ * Revision 1.95 2001/11/06 19:47:46 rgb
55173+ * Added packet parameter to lifetime and comb structures.
55174+ *
55175+ * Revision 1.94 2001/10/18 04:45:23 rgb
55176+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
55177+ * lib/freeswan.h version macros moved to lib/kversions.h.
55178+ * Other compiler directive cleanups.
55179+ *
55180+ * Revision 1.93 2001/09/20 15:32:59 rgb
55181+ * Min/max cleanup.
55182+ *
55183+ * Revision 1.92 2001/09/19 16:35:48 rgb
55184+ * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
55185+ *
55186+ * Revision 1.91 2001/09/15 16:24:06 rgb
55187+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
55188+ *
55189+ * Revision 1.90 2001/09/14 16:58:38 rgb
55190+ * Added support for storing the first and last packets through a HOLD.
55191+ *
55192+ * Revision 1.89 2001/09/08 21:14:07 rgb
55193+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
55194+ * Better state coherency (error management) between pf_key and IKE daemon.
55195+ * (NetCelo)
55196+ *
55197+ * Revision 1.88 2001/08/27 19:42:44 rgb
55198+ * Fix memory leak of encrypt and auth structs in pfkey register.
55199+ *
55200+ * Revision 1.87 2001/07/06 19:50:46 rgb
55201+ * Removed unused debugging code.
55202+ * Added inbound policy checking code for IPIP SAs.
55203+ *
55204+ * Revision 1.86 2001/06/20 06:26:04 rgb
55205+ * Changed missing SA errors from EEXIST to ENOENT and added debug output
55206+ * for already linked SAs.
55207+ *
55208+ * Revision 1.85 2001/06/15 04:57:02 rgb
55209+ * Remove single error return condition check and check for all errors in
55210+ * the case of a replace eroute delete operation. This means that
55211+ * applications must expect to be deleting something before replacing it
55212+ * and if nothing is found, complain.
55213+ *
55214+ * Revision 1.84 2001/06/14 19:35:12 rgb
55215+ * Update copyright date.
55216+ *
55217+ * Revision 1.83 2001/06/12 00:03:19 rgb
55218+ * Silence debug set/unset under normal conditions.
55219+ *
55220+ * Revision 1.82 2001/05/30 08:14:04 rgb
55221+ * Removed vestiges of esp-null transforms.
55222+ *
55223+ * Revision 1.81 2001/05/27 06:12:12 rgb
55224+ * Added structures for pid, packet count and last access time to eroute.
55225+ * Added packet count to beginning of /proc/net/ipsec_eroute.
55226+ *
55227+ * Revision 1.80 2001/05/03 19:43:59 rgb
55228+ * Check error return codes for all build function calls.
55229+ * Standardise on SENDERR() macro.
55230+ *
55231+ * Revision 1.79 2001/04/20 21:09:16 rgb
55232+ * Cleaned up fixed tdbwipes.
55233+ * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
55234+ * delflow (Per Cederqvist) plugging memleaks.
55235+ *
55236+ * Revision 1.78 2001/04/19 19:02:39 rgb
55237+ * Fixed extr.tdb freeing, stealing it for getspi, update and add.
55238+ * Refined a couple of spinlocks, fixed the one in update.
55239+ *
55240+ * Revision 1.77 2001/04/18 20:26:16 rgb
55241+ * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
55242+ * instead of inside each message type parser. This fixes two memleaks.
55243+ *
55244+ * Revision 1.76 2001/04/17 23:51:18 rgb
55245+ * Quiet down pfkey_x_debug_process().
55246+ *
55247+ * Revision 1.75 2001/03/29 01:55:05 rgb
55248+ * Fixed pfkey key init memleak.
55249+ * Fixed pfkey encryption key debug output.
55250+ *
55251+ * Revision 1.74 2001/03/27 05:29:14 rgb
55252+ * Debug output cleanup/silencing.
55253+ *
55254+ * Revision 1.73 2001/02/28 05:03:28 rgb
55255+ * Clean up and rationalise startup messages.
55256+ *
55257+ * Revision 1.72 2001/02/27 22:24:56 rgb
55258+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
55259+ * Check for satoa() return codes.
55260+ *
55261+ * Revision 1.71 2001/02/27 06:59:30 rgb
55262+ * Added satype2name() conversions most places satype is debug printed.
55263+ *
55264+ * Revision 1.70 2001/02/26 22:37:08 rgb
55265+ * Fixed 'unknown proto' INT bug in new code.
55266+ * Added satype to protocol debugging instrumentation.
55267+ *
55268+ * Revision 1.69 2001/02/26 19:57:51 rgb
55269+ * Re-formatted debug output (split lines, consistent spacing).
55270+ * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
55271+ * with an satype instead of proto.
55272+ * Checked for satype consistency and fixed minor bugs.
55273+ * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
55274+ * Check for satype sanity in pfkey_expire().
55275+ * Added satype sanity check to addflow.
55276+ *
55277+ * Revision 1.68 2001/02/12 23:14:40 rgb
55278+ * Remove double spin lock in pfkey_expire().
55279+ *
55280+ * Revision 1.67 2001/01/31 19:23:40 rgb
55281+ * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
55282+ *
55283+ * Revision 1.66 2001/01/29 22:20:04 rgb
55284+ * Fix minor add upmsg lifetime bug.
55285+ *
55286+ * Revision 1.65 2001/01/24 06:12:33 rgb
55287+ * Fixed address extension compile bugs just introduced.
55288+ *
55289+ * Revision 1.64 2001/01/24 00:31:15 rgb
55290+ * Added upmsg for addflow/delflow.
55291+ *
55292+ * Revision 1.63 2001/01/23 22:02:55 rgb
55293+ * Added upmsg to x_grpsa.
55294+ * Fixed lifetimes extentions to add/update/get upmsg.
55295+ *
55296+ * Revision 1.62 2000/11/30 21:47:51 rgb
55297+ * Fix error return bug after returning from pfkey_tdb_init().
55298+ *
55299+ * Revision 1.61 2000/11/17 18:10:29 rgb
55300+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
55301+ * network byte order since this is the way PF_KEYv2 stored spis.
55302+ *
55303+ * Revision 1.60 2000/11/06 04:34:53 rgb
55304+ * Changed non-exported functions to DEBUG_NO_STATIC.
55305+ * Add Svenning's adaptive content compression.
55306+ * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
55307+ * Fixed double unlock bug (Svenning).
55308+ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
55309+ * Fixed incorrect extension type (prop) in pfkey)acquire().
55310+ *
55311+ * Revision 1.59 2000/10/11 15:25:12 rgb
55312+ * Fixed IPCOMP disabled compile bug.
55313+ *
55314+ * Revision 1.58 2000/10/11 14:54:03 rgb
55315+ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
55316+ * protocol violations of setting pfkey_address_build() protocol parameter
55317+ * to non-zero except in the case of pfkey_acquire().
55318+ *
55319+ * Revision 1.57 2000/10/10 20:10:18 rgb
55320+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
55321+ *
55322+ * Revision 1.56 2000/10/06 20:24:36 rgb
55323+ * Fixes to pfkey_acquire to initialize extensions[] and use correct
55324+ * ipproto.
55325+ *
55326+ * Revision 1.55 2000/10/03 03:20:57 rgb
55327+ * Added brackets to get a?b:c scope right for pfkey_register reply.
55328+ *
55329+ * Revision 1.54 2000/09/29 19:49:30 rgb
55330+ * As-yet-unused-bits cleanup.
55331+ *
55332+ * Revision 1.53 2000/09/28 00:35:45 rgb
55333+ * Padded SATYPE printout in pfkey_register for vertical alignment.
55334+ *
55335+ * Revision 1.52 2000/09/20 16:21:58 rgb
55336+ * Cleaned up ident string alloc/free.
55337+ *
55338+ * Revision 1.51 2000/09/20 04:04:20 rgb
55339+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
55340+ * oopsen.
55341+ *
55342+ * Revision 1.50 2000/09/16 01:10:53 rgb
55343+ * Fixed unused var warning with debug off.
55344+ *
55345+ * Revision 1.49 2000/09/15 11:37:02 rgb
55346+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
55347+ * IPCOMP zlib deflate code.
55348+ *
55349+ * Revision 1.48 2000/09/15 04:57:57 rgb
55350+ * Cleaned up existing IPCOMP code before svenning addition.
55351+ * Initialize pfkey_reply and extensions_reply in case of early error in
55352+ * message parsing functions (thanks Kai!).
55353+ *
55354+ * Revision 1.47 2000/09/13 08:02:56 rgb
55355+ * Added KMd registration notification.
55356+ *
55357+ * Revision 1.46 2000/09/12 22:35:36 rgb
55358+ * Restructured to remove unused extensions from CLEARFLOW messages.
55359+ *
55360+ * Revision 1.45 2000/09/12 03:24:23 rgb
55361+ * Converted #if0 debugs to sysctl.
55362+ *
55363+ * Revision 1.44 2000/09/09 06:38:39 rgb
55364+ * Correct SADB message type for update, add and delete.
55365+ *
55366+ * Revision 1.43 2000/09/08 19:19:56 rgb
55367+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
55368+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
55369+ * Put in sanity checks in most msg type parsers to catch invalid satypes
55370+ * and empty socket lists.
55371+ * Moved spin-locks in pfkey_get_parse() to simplify.
55372+ * Added pfkey_acquire().
55373+ * Added upwards messages to update, add, delete, acquire_parse,
55374+ * expire_parse and flush.
55375+ * Fix pfkey_prop_build() parameter to be only single indirection.
55376+ * Changed all replies to use pfkey_reply.
55377+ * Check return code on puttdb() and deltdbchain() in getspi, update,
55378+ * add, delete.
55379+ * Fixed up all pfkey replies to open and registered sockets.
55380+ *
55381+ * Revision 1.42 2000/09/01 18:50:26 rgb
55382+ * Added a supported algorithms array lists, one per satype and registered
55383+ * existing algorithms.
55384+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
55385+ * list.
55386+ * Only send pfkey_expire() messages to sockets registered for that satype.
55387+ * Added reply to pfkey_getspi_parse().
55388+ * Added reply to pfkey_get_parse().
55389+ * Fixed debug output label bug in pfkey_lifetime_process().
55390+ * Cleaned up pfkey_sa_process a little.
55391+ * Moved pfkey_safe_build() above message type parsers to make it available
55392+ * for creating replies.
55393+ * Added comments for future work in pfkey_acquire_parse().
55394+ * Fleshed out guts of pfkey_register_parse().
55395+ *
55396+ * Revision 1.41 2000/08/24 16:58:11 rgb
55397+ * Fixed key debugging variables.
55398+ * Fixed error return code for a failed search.
55399+ * Changed order of pfkey_get operations.
55400+ *
55401+ * Revision 1.40 2000/08/21 16:32:27 rgb
55402+ * Re-formatted for cosmetic consistency and readability.
55403+ *
55404+ * Revision 1.39 2000/08/20 21:38:57 rgb
55405+ * Bugfixes to as-yet-unused pfkey_update_parse() and
55406+ * pfkey_register_parse(). (Momchil)
55407+ * Added functions pfkey_safe_build(), pfkey_expire() and
55408+ * pfkey_build_reply(). (Momchil)
55409+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
55410+ *
55411+ * Revision 1.38 2000/08/18 21:30:41 rgb
55412+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
55413+ *
55414+ * Revision 1.37 2000/08/18 18:18:02 rgb
55415+ * Cosmetic and descriptive changes made to debug test.
55416+ * getspi and update fixes from Momchil.
55417+ *
55418+ * Revision 1.36 2000/08/15 15:41:55 rgb
55419+ * Fixed the (as yet unused and untested) pfkey_getspi() routine.
55420+ *
55421+ * Revision 1.35 2000/08/01 14:51:52 rgb
55422+ * Removed _all_ remaining traces of DES.
55423+ *
55424+ * Revision 1.34 2000/07/28 14:58:32 rgb
55425+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
55426+ *
55427+ * Revision 1.33 2000/06/28 05:50:11 rgb
55428+ * Actually set iv_bits.
55429+ *
55430+ * Revision 1.32 2000/05/30 18:36:56 rgb
55431+ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY
55432+ * FreeS/WAN, but fixes interop with other implementations.
55433+ *
55434+ * Revision 1.31 2000/03/16 14:05:48 rgb
55435+ * Fixed brace scope preventing non-debug compile.
55436+ * Added null parameter check for pfkey_x_debug().
55437+ *
55438+ * Revision 1.30 2000/01/22 23:21:13 rgb
55439+ * Use new function satype2proto().
55440+ *
55441+ * Revision 1.29 2000/01/22 08:40:21 rgb
55442+ * Invert condition to known value to avoid AF_INET6 in 2.0.36.
55443+ *
55444+ * Revision 1.28 2000/01/22 07:58:57 rgb
55445+ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
55446+ *
55447+ * Revision 1.27 2000/01/22 03:48:01 rgb
55448+ * Added extr pointer component debugging.
55449+ *
55450+ * Revision 1.26 2000/01/21 09:41:25 rgb
55451+ * Changed a (void*) to (char*) cast to do proper pointer math.
55452+ * Don't call tdbwipe if tdb2 is NULL.
55453+ *
55454+ * Revision 1.25 2000/01/21 06:21:01 rgb
55455+ * Added address cases for eroute flows.
55456+ * Tidied up compiler directive indentation for readability.
55457+ * Added ictx,octx vars for simplification.
55458+ * Added macros for HMAC padding magic numbers.
55459+ * Converted from double tdb arguments to one structure (extr)
55460+ * containing pointers to all temporary information structures
55461+ * and checking for valid arguments to all ext processors and
55462+ * msg type parsers.
55463+ * Added spiungrp'ing.
55464+ * Added klipsdebug switching capability.
55465+ * Removed sa_process() check for zero protocol.
55466+ * Added address case for DST2 for grouping.
55467+ * Added/changed minor debugging instrumentation.
55468+ * Fixed spigrp for single said, ungrouping case.
55469+ * Added code to parse addflow and delflow messages.
55470+ * Removed redundant statements duplicating tdbwipe() functionality
55471+ * and causing double kfrees.
55472+ * Permit addflow to have a protocol of 0.
55473+ *
55474+ * Revision 1.24 1999/12/09 23:23:00 rgb
55475+ * Added check to pfkey_sa_process() to do eroutes.
55476+ * Converted to DIVUP() macro.
55477+ * Converted if() to switch() in pfkey_register_parse().
55478+ * Use new pfkey_extensions_init() instead of memset().
55479+ *
55480+ * Revision 1.23 1999/12/01 22:18:13 rgb
55481+ * Preset minspi and maxspi values in case and spirange extension is not
55482+ * included and check for the presence of an spirange extension before
55483+ * using it. Initialise tdb_sastate to LARVAL.
55484+ * Fixed debugging output typo.
55485+ * Fixed authentication context initialisation bugs (4 places).
55486+ *
55487+ * Revision 1.22 1999/11/27 11:53:08 rgb
55488+ * Moved pfkey_msg_parse prototype to pfkey.h
55489+ * Moved exts_permitted/required prototype to pfkey.h.
55490+ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
55491+ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
55492+ * be called.
55493+ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
55494+ * Debugging error messages added.
55495+ * Enable lifetime_current checking.
55496+ * Remove illegal requirement for SA extension to be present in an
55497+ * originating GETSPI call.
55498+ * Re-instate requirement for UPDATE or ADD message to be MATURE.
55499+ * Add argument to pfkey_msg_parse() for direction.
55500+ * Fixed IPIP dst address bug and purged redundant, leaky code.
55501+ *
55502+ * Revision 1.21 1999/11/24 05:24:20 rgb
55503+ * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
55504+ * Fixed indention.
55505+ * Ditched redundant replay check.
55506+ * Fixed debug message text from 'parse' to 'process'.
55507+ * Added more debug output.
55508+ * Forgot to zero extensions array causing bug, fixed.
55509+ *
55510+ * Revision 1.20 1999/11/23 23:08:13 rgb
55511+ * Move all common parsing code to lib/pfkey_v2_parse.c and rename
55512+ * remaining bits to *_process. (PJO)
55513+ * Add macros for dealing with alignment and rounding up more opaquely.
55514+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
55515+ * Sort out pfkey and freeswan headers, putting them in a library path.
55516+ * Corrected a couple of bugs in as-yet-inactive code.
55517+ *
55518+ * Revision 1.19 1999/11/20 22:01:10 rgb
55519+ * Add more descriptive error messages for non-zero reserved fields.
55520+ * Add more descriptive error message for spirange parsing.
55521+ * Start on supported extension parsing.
55522+ * Start on register and get message parsing.
55523+ *
55524+ * Revision 1.18 1999/11/18 04:09:20 rgb
55525+ * Replaced all kernel version macros to shorter, readable form.
55526+ *
55527+ * Revision 1.17 1999/11/17 15:53:41 rgb
55528+ * Changed all occurrences of #include "../../../lib/freeswan.h"
55529+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
55530+ * klips/net/ipsec/Makefile.
55531+ *
55532+ * Revision 1.16 1999/10/26 16:57:43 rgb
55533+ * Add shorter macros for compiler directives to visually clean-up.
55534+ * Give ipv6 code meaningful compiler directive.
55535+ * Add comments to other #if 0 debug code.
55536+ * Remove unused *_bh_atomic() calls.
55537+ * Fix mis-placed spinlock.
55538+ *
55539+ * Revision 1.15 1999/10/16 18:27:10 rgb
55540+ * Clean-up unused cruft.
55541+ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
55542+ *
55543+ * Revision 1.14 1999/10/08 18:37:34 rgb
55544+ * Fix end-of-line spacing to sate whining PHMs.
55545+ *
55546+ * Revision 1.13 1999/10/03 18:49:12 rgb
55547+ * Spinlock fixes for 2.0.xx and 2.3.xx.
55548+ *
55549+ * Revision 1.12 1999/10/01 15:44:54 rgb
55550+ * Move spinlock header include to 2.1> scope.
55551+ *
55552+ * Revision 1.11 1999/10/01 00:05:45 rgb
55553+ * Added tdb structure locking.
55554+ * Use 'jiffies' instead of do_get_timeofday().
55555+ * Fix lifetime assignments.
55556+ *
55557+ * Revision 1.10 1999/09/21 15:24:45 rgb
55558+ * Rework spirange code to save entropy and prevent endless loops.
55559+ *
55560+ * Revision 1.9 1999/09/16 12:10:21 rgb
55561+ * Minor fixes to random spi selection for correctness and entropy conservation.
55562+ *
55563+ * Revision 1.8 1999/05/25 22:54:46 rgb
55564+ * Fix comparison that should be an assignment in an if.
55565+ *
55566+ * Revision 1.7 1999/05/09 03:25:37 rgb
55567+ * Fix bug introduced by 2.2 quick-and-dirty patch.
55568+ *
55569+ * Revision 1.6 1999/05/08 21:32:30 rgb
55570+ * Fix error return reporting.
55571+ *
55572+ * Revision 1.5 1999/05/05 22:02:33 rgb
55573+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
55574+ *
55575+ * Revision 1.4 1999/04/29 15:22:40 rgb
55576+ * Standardise an error return method.
55577+ * Add debugging instrumentation.
55578+ * Add check for existence of macros min/max.
55579+ * Add extensions permitted/required in/out filters.
55580+ * Add satype-to-protocol table.
55581+ * Add a second tdb pointer to each parser to accomodate GRPSA.
55582+ * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
55583+ * Add OOO window check.
55584+ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
55585+ * Add timestamp to lifetime parse.
55586+ * Fix address structure length checking bug.
55587+ * Fix address structure allocation bug (forgot to kmalloc!).
55588+ * Add checks for extension lengths.
55589+ * Add checks for extension reserved illegal values.
55590+ * Add check for spirange legal values.
55591+ * Add an extension type for parsing a second satype, SA and
55592+ * DST_ADDRESS.
55593+ * Make changes to tdb_init() template to get pfkey_tdb_init(),
55594+ * eliminating any mention of xformsw.
55595+ * Implement getspi, update and grpsa (not tested).
55596+ * Add stubs for as yet unimplemented message types.
55597+ * Add table of message parsers to substitute for msg_parse switch.
55598+ *
55599+ * Revision 1.3 1999/04/15 17:58:07 rgb
55600+ * Add RCSID labels.
55601+ *
55602+ * Revision 1.2 1999/04/15 15:37:26 rgb
55603+ * Forward check changes from POST1_00 branch.
55604+ *
55605+ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb
55606+ * Add pfkeyv2 support to KLIPS.
55607+ *
55608+ * Local variables:
55609+ * c-file-style: "linux"
55610+ * End:
55611+ *
55612+ */
55613--- /dev/null Tue Mar 11 13:02:56 2003
55614+++ linux/net/ipsec/prng.c Mon Feb 9 13:51:03 2004
55615@@ -0,0 +1,201 @@
55616+/*
55617+ * crypto-class pseudorandom number generator
55618+ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
55619+ * Copyright (C) 2002 Henry Spencer.
55620+ *
55621+ * This library is free software; you can redistribute it and/or modify it
55622+ * under the terms of the GNU Library General Public License as published by
55623+ * the Free Software Foundation; either version 2 of the License, or (at your
55624+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
55625+ *
55626+ * This library is distributed in the hope that it will be useful, but
55627+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
55628+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
55629+ * License for more details.
55630+ *
55631+ * RCSID $Id: prng.c,v 1.7 2004/07/10 07:48:36 mcr Exp $
55632+ */
55633+#include "openswan.h"
55634+
55635+/*
55636+ - prng_init - initialize PRNG from a key
55637+ */
55638+void
55639+prng_init(prng, key, keylen)
55640+struct prng *prng;
55641+const unsigned char *key;
55642+size_t keylen;
55643+{
55644+ unsigned char k[256];
55645+ int i, j;
55646+ unsigned const char *p;
55647+ unsigned const char *keyend = key + keylen;
55648+ unsigned char t;
55649+
55650+ for (i = 0; i <= 255; i++)
55651+ prng->sbox[i] = i;
55652+ p = key;
55653+ for (i = 0; i <= 255; i++) {
55654+ k[i] = *p++;
55655+ if (p >= keyend)
55656+ p = key;
55657+ }
55658+ j = 0;
55659+ for (i = 0; i <= 255; i++) {
55660+ j = (j + prng->sbox[i] + k[i]) & 0xff;
55661+ t = prng->sbox[i];
55662+ prng->sbox[i] = prng->sbox[j];
55663+ prng->sbox[j] = t;
55664+ k[i] = 0; /* clear out key memory */
55665+ }
55666+ prng->i = 0;
55667+ prng->j = 0;
55668+ prng->count = 0;
55669+}
55670+
55671+/*
55672+ - prng_bytes - get some pseudorandom bytes from PRNG
55673+ */
55674+void
55675+prng_bytes(prng, dst, dstlen)
55676+struct prng *prng;
55677+unsigned char *dst;
55678+size_t dstlen;
55679+{
55680+ int i, j, t;
55681+ unsigned char *p = dst;
55682+ size_t remain = dstlen;
55683+# define MAX 4000000000ul
55684+
55685+ while (remain > 0) {
55686+ i = (prng->i + 1) & 0xff;
55687+ prng->i = i;
55688+ j = (prng->j + prng->sbox[i]) & 0xff;
55689+ prng->j = j;
55690+ t = prng->sbox[i];
55691+ prng->sbox[i] = prng->sbox[j];
55692+ prng->sbox[j] = t;
55693+ t = (t + prng->sbox[i]) & 0xff;
55694+ *p++ = prng->sbox[t];
55695+ remain--;
55696+ }
55697+ if (prng->count < MAX - dstlen)
55698+ prng->count += dstlen;
55699+ else
55700+ prng->count = MAX;
55701+}
55702+
55703+/*
55704+ - prnt_count - how many bytes have been extracted from PRNG so far?
55705+ */
55706+unsigned long
55707+prng_count(prng)
55708+struct prng *prng;
55709+{
55710+ return prng->count;
55711+}
55712+
55713+/*
55714+ - prng_final - clear out PRNG to ensure nothing left in memory
55715+ */
55716+void
55717+prng_final(prng)
55718+struct prng *prng;
55719+{
55720+ int i;
55721+
55722+ for (i = 0; i <= 255; i++)
55723+ prng->sbox[i] = 0;
55724+ prng->i = 0;
55725+ prng->j = 0;
55726+ prng->count = 0; /* just for good measure */
55727+}
55728+
55729+
55730+
55731+#ifdef PRNG_MAIN
55732+
55733+#include <stdio.h>
55734+
55735+void regress();
55736+
55737+int
55738+main(argc, argv)
55739+int argc;
55740+char *argv[];
55741+{
55742+ struct prng pr;
55743+ unsigned char buf[100];
55744+ unsigned char *p;
55745+ size_t n;
55746+
55747+ if (argc < 2) {
55748+ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
55749+ exit(2);
55750+ }
55751+
55752+ if (strcmp(argv[1], "-r") == 0) {
55753+ regress();
55754+ fprintf(stderr, "regress() returned?!?\n");
55755+ exit(1);
55756+ }
55757+
55758+ prng_init(&pr, argv[1], strlen(argv[1]));
55759+ prng_bytes(&pr, buf, 32);
55760+ printf("0x");
55761+ for (p = buf, n = 32; n > 0; p++, n--)
55762+ printf("%02x", *p);
55763+ printf("\n%lu bytes\n", prng_count(&pr));
55764+ prng_final(&pr);
55765+ exit(0);
55766+}
55767+
55768+void
55769+regress()
55770+{
55771+ struct prng pr;
55772+ unsigned char buf[100];
55773+ unsigned char *p;
55774+ size_t n;
55775+ /* somewhat non-random sample key */
55776+ unsigned char key[] = "here we go gathering nuts in May";
55777+ /* first thirty bytes of output from that key */
55778+ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
55779+ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
55780+ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
55781+ int nzero, none;
55782+ int show = 0;
55783+
55784+ prng_init(&pr, key, strlen(key));
55785+ prng_bytes(&pr, buf, sizeof(buf));
55786+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
55787+ if (*p == 0)
55788+ nzero++;
55789+ if (*p == 255)
55790+ none++;
55791+ }
55792+ if (nzero > 3 || none > 3) {
55793+ fprintf(stderr, "suspiciously non-random output!\n");
55794+ show = 1;
55795+ }
55796+ if (memcmp(buf, good, strlen(good)) != 0) {
55797+ fprintf(stderr, "incorrect output!\n");
55798+ show = 1;
55799+ }
55800+ if (show) {
55801+ fprintf(stderr, "0x");
55802+ for (p = buf, n = sizeof(buf); n > 0; p++, n--)
55803+ fprintf(stderr, "%02x", *p);
55804+ fprintf(stderr, "\n");
55805+ exit(1);
55806+ }
55807+ if (prng_count(&pr) != sizeof(buf)) {
55808+ fprintf(stderr, "got %u bytes, but count is %lu\n",
55809+ sizeof(buf), prng_count(&pr));
55810+ exit(1);
55811+ }
55812+ prng_final(&pr);
55813+ exit(0);
55814+}
55815+
55816+#endif /* PRNG_MAIN */
55817--- /dev/null Tue Mar 11 13:02:56 2003
55818+++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004
55819@@ -0,0 +1,1237 @@
55820+char radij_c_version[] = "RCSID $Id: radij.c,v 1.48.2.1 2006/10/06 21:39:27 paul Exp $";
55821+
55822+/*
55823+ * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
55824+ *
55825+ * Variable and procedure names have been modified so that they don't
55826+ * conflict with the original BSD code, as a small number of modifications
55827+ * have been introduced and we may want to reuse this code in BSD.
55828+ *
55829+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
55830+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
55831+ * spanish j as in Juan. It is not as far back in the throat like
55832+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
55833+ * It has nothing to do with the Dutch ij sound.
55834+ *
55835+ * Here is the appropriate copyright notice:
55836+ */
55837+
55838+/*
55839+ * Copyright (c) 1988, 1989, 1993
55840+ * The Regents of the University of California. All rights reserved.
55841+ *
55842+ * Redistribution and use in source and binary forms, with or without
55843+ * modification, are permitted provided that the following conditions
55844+ * are met:
55845+ * 1. Redistributions of source code must retain the above copyright
55846+ * notice, this list of conditions and the following disclaimer.
55847+ * 2. Redistributions in binary form must reproduce the above copyright
55848+ * notice, this list of conditions and the following disclaimer in the
55849+ * documentation and/or other materials provided with the distribution.
55850+ * 3. All advertising materials mentioning features or use of this software
55851+ * must display the following acknowledgement:
55852+ * This product includes software developed by the University of
55853+ * California, Berkeley and its contributors.
55854+ * 4. Neither the name of the University nor the names of its contributors
55855+ * may be used to endorse or promote products derived from this software
55856+ * without specific prior written permission.
55857+ *
55858+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55859+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55860+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55861+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55862+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55863+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55864+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55865+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55866+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55867+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55868+ * SUCH DAMAGE.
55869+ *
55870+ * @(#)radix.c 8.2 (Berkeley) 1/4/94
55871+ */
55872+
55873+/*
55874+ * Routines to build and maintain radix trees for routing lookups.
55875+ */
55876+
55877+#ifndef AUTOCONF_INCLUDED
55878+#include <linux/config.h>
55879+#endif
55880+#include <linux/version.h>
55881+#include <linux/kernel.h> /* printk() */
55882+
55883+#include "openswan/ipsec_param.h"
55884+
55885+#ifdef MALLOC_SLAB
55886+# include <linux/slab.h> /* kmalloc() */
55887+#else /* MALLOC_SLAB */
55888+# include <linux/malloc.h> /* kmalloc() */
55889+#endif /* MALLOC_SLAB */
55890+#include <linux/errno.h> /* error codes */
55891+#include <linux/types.h> /* size_t */
55892+#include <linux/interrupt.h> /* mark_bh */
55893+
55894+#include <linux/netdevice.h> /* struct device, and other headers */
55895+#include <linux/etherdevice.h> /* eth_type_trans */
55896+#include <linux/ip.h> /* struct iphdr */
55897+#include <linux/skbuff.h>
55898+#ifdef NET_21
55899+# include <linux/in6.h>
55900+#endif /* NET_21 */
55901+
55902+#include <net/ip.h>
55903+
55904+#include <openswan.h>
55905+
55906+#include "openswan/radij.h"
55907+#include "openswan/ipsec_encap.h"
55908+#include "openswan/ipsec_radij.h"
55909+
55910+int maj_keylen;
55911+struct radij_mask *rj_mkfreelist;
55912+struct radij_node_head *mask_rjhead;
55913+static int gotOddMasks;
55914+static char *maskedKey;
55915+static char *rj_zeroes, *rj_ones;
55916+
55917+#define rj_masktop (mask_rjhead->rnh_treetop)
55918+#ifdef Bcmp
55919+# undef Bcmp
55920+#endif /* Bcmp */
55921+#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
55922+/*
55923+ * The data structure for the keys is a radix tree with one way
55924+ * branching removed. The index rj_b at an internal node n represents a bit
55925+ * position to be tested. The tree is arranged so that all descendants
55926+ * of a node n have keys whose bits all agree up to position rj_b - 1.
55927+ * (We say the index of n is rj_b.)
55928+ *
55929+ * There is at least one descendant which has a one bit at position rj_b,
55930+ * and at least one with a zero there.
55931+ *
55932+ * A route is determined by a pair of key and mask. We require that the
55933+ * bit-wise logical and of the key and mask to be the key.
55934+ * We define the index of a route to associated with the mask to be
55935+ * the first bit number in the mask where 0 occurs (with bit number 0
55936+ * representing the highest order bit).
55937+ *
55938+ * We say a mask is normal if every bit is 0, past the index of the mask.
55939+ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
55940+ * and m is a normal mask, then the route applies to every descendant of n.
55941+ * If the index(m) < rj_b, this implies the trailing last few bits of k
55942+ * before bit b are all 0, (and hence consequently true of every descendant
55943+ * of n), so the route applies to all descendants of the node as well.
55944+ *
55945+ * The present version of the code makes no use of normal routes,
55946+ * but similar logic shows that a non-normal mask m such that
55947+ * index(m) <= index(n) could potentially apply to many children of n.
55948+ * Thus, for each non-host route, we attach its mask to a list at an internal
55949+ * node as high in the tree as we can go.
55950+ */
55951+
55952+struct radij_node *
55953+rj_search(v_arg, head)
55954+ void *v_arg;
55955+ struct radij_node *head;
55956+{
55957+ register struct radij_node *x;
55958+ register caddr_t v;
55959+
55960+ for (x = head, v = v_arg; x->rj_b >= 0;) {
55961+ if (x->rj_bmask & v[x->rj_off])
55962+ x = x->rj_r;
55963+ else
55964+ x = x->rj_l;
55965+ }
55966+ return (x);
55967+};
55968+
55969+struct radij_node *
55970+rj_search_m(v_arg, head, m_arg)
55971+ struct radij_node *head;
55972+ void *v_arg, *m_arg;
55973+{
55974+ register struct radij_node *x;
55975+ register caddr_t v = v_arg, m = m_arg;
55976+
55977+ for (x = head; x->rj_b >= 0;) {
55978+ if ((x->rj_bmask & m[x->rj_off]) &&
55979+ (x->rj_bmask & v[x->rj_off]))
55980+ x = x->rj_r;
55981+ else
55982+ x = x->rj_l;
55983+ }
55984+ return x;
55985+};
55986+
55987+int
55988+rj_refines(m_arg, n_arg)
55989+ void *m_arg, *n_arg;
55990+{
55991+ register caddr_t m = m_arg, n = n_arg;
55992+ register caddr_t lim, lim2 = lim = n + *(u_char *)n;
55993+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
55994+ int masks_are_equal = 1;
55995+
55996+ if (longer > 0)
55997+ lim -= longer;
55998+ while (n < lim) {
55999+ if (*n & ~(*m))
56000+ return 0;
56001+ if (*n++ != *m++)
56002+ masks_are_equal = 0;
56003+
56004+ }
56005+ while (n < lim2)
56006+ if (*n++)
56007+ return 0;
56008+ if (masks_are_equal && (longer < 0))
56009+ for (lim2 = m - longer; m < lim2; )
56010+ if (*m++)
56011+ return 1;
56012+ return (!masks_are_equal);
56013+}
56014+
56015+
56016+struct radij_node *
56017+rj_match(v_arg, head)
56018+ void *v_arg;
56019+ struct radij_node_head *head;
56020+{
56021+ caddr_t v = v_arg;
56022+ register struct radij_node *t = head->rnh_treetop, *x;
56023+ register caddr_t cp = v, cp2, cp3;
56024+ caddr_t cplim, mstart;
56025+ struct radij_node *saved_t, *top = t;
56026+ int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
56027+
56028+ /*
56029+ * Open code rj_search(v, top) to avoid overhead of extra
56030+ * subroutine call.
56031+ */
56032+ for (; t->rj_b >= 0; ) {
56033+ if (t->rj_bmask & cp[t->rj_off])
56034+ t = t->rj_r;
56035+ else
56036+ t = t->rj_l;
56037+ }
56038+ /*
56039+ * See if we match exactly as a host destination
56040+ */
56041+ KLIPS_PRINT(debug_radij,
56042+ "klips_debug:rj_match: "
56043+ "* See if we match exactly as a host destination\n");
56044+
56045+ cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
56046+ for (; cp < cplim; cp++, cp2++)
56047+ if (*cp != *cp2)
56048+ goto on1;
56049+ /*
56050+ * This extra grot is in case we are explicitly asked
56051+ * to look up the default. Ugh!
56052+ */
56053+ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
56054+ t = t->rj_dupedkey;
56055+ return t;
56056+on1:
56057+ matched_off = cp - v;
56058+ saved_t = t;
56059+ KLIPS_PRINT(debug_radij,
56060+ "klips_debug:rj_match: "
56061+ "** try to match a leaf, t=0p%p\n", t);
56062+ do {
56063+ if (t->rj_mask) {
56064+ /*
56065+ * Even if we don't match exactly as a hosts;
56066+ * we may match if the leaf we wound up at is
56067+ * a route to a net.
56068+ */
56069+ cp3 = matched_off + t->rj_mask;
56070+ cp2 = matched_off + t->rj_key;
56071+ for (; cp < cplim; cp++)
56072+ if ((*cp2++ ^ *cp) & *cp3++)
56073+ break;
56074+ if (cp == cplim)
56075+ return t;
56076+ cp = matched_off + v;
56077+ }
56078+ } while ((t = t->rj_dupedkey));
56079+ t = saved_t;
56080+ /* start searching up the tree */
56081+ KLIPS_PRINT(debug_radij,
56082+ "klips_debug:rj_match: "
56083+ "*** start searching up the tree, t=0p%p\n",
56084+ t);
56085+ do {
56086+ register struct radij_mask *m;
56087+
56088+ t = t->rj_p;
56089+ KLIPS_PRINT(debug_radij,
56090+ "klips_debug:rj_match: "
56091+ "**** t=0p%p\n",
56092+ t);
56093+ if ((m = t->rj_mklist)) {
56094+ /*
56095+ * After doing measurements here, it may
56096+ * turn out to be faster to open code
56097+ * rj_search_m here instead of always
56098+ * copying and masking.
56099+ */
56100+ /* off = min(t->rj_off, matched_off); */
56101+ off = t->rj_off;
56102+ if (matched_off < off)
56103+ off = matched_off;
56104+ mstart = maskedKey + off;
56105+ do {
56106+ cp2 = mstart;
56107+ cp3 = m->rm_mask + off;
56108+ KLIPS_PRINT(debug_radij,
56109+ "klips_debug:rj_match: "
56110+ "***** cp2=0p%p cp3=0p%p\n",
56111+ cp2, cp3);
56112+ for (cp = v + off; cp < cplim;)
56113+ *cp2++ = *cp++ & *cp3++;
56114+ x = rj_search(maskedKey, t);
56115+ while (x && x->rj_mask != m->rm_mask)
56116+ x = x->rj_dupedkey;
56117+ if (x &&
56118+ (Bcmp(mstart, x->rj_key + off,
56119+ vlen - off) == 0))
56120+ return x;
56121+ } while ((m = m->rm_mklist));
56122+ }
56123+ } while (t != top);
56124+ KLIPS_PRINT(debug_radij,
56125+ "klips_debug:rj_match: "
56126+ "***** not found.\n");
56127+ return 0;
56128+};
56129+
56130+#ifdef RJ_DEBUG
56131+int rj_nodenum;
56132+struct radij_node *rj_clist;
56133+int rj_saveinfo;
56134+DEBUG_NO_STATIC void traverse(struct radij_node *);
56135+#ifdef RJ_DEBUG2
56136+int rj_debug = 1;
56137+#else
56138+int rj_debug = 0;
56139+#endif /* RJ_DEBUG2 */
56140+#endif /* RJ_DEBUG */
56141+
56142+struct radij_node *
56143+rj_newpair(v, b, nodes)
56144+ void *v;
56145+ int b;
56146+ struct radij_node nodes[2];
56147+{
56148+ register struct radij_node *tt = nodes, *t = tt + 1;
56149+ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
56150+ t->rj_l = tt; t->rj_off = b >> 3;
56151+ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
56152+ tt->rj_flags = t->rj_flags = RJF_ACTIVE;
56153+#ifdef RJ_DEBUG
56154+ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
56155+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
56156+#endif /* RJ_DEBUG */
56157+ return t;
56158+}
56159+
56160+struct radij_node *
56161+rj_insert(v_arg, head, dupentry, nodes)
56162+ void *v_arg;
56163+ struct radij_node_head *head;
56164+ int *dupentry;
56165+ struct radij_node nodes[2];
56166+{
56167+ caddr_t v = v_arg;
56168+ struct radij_node *top = head->rnh_treetop;
56169+ int head_off = top->rj_off, vlen = (int)*((u_char *)v);
56170+ register struct radij_node *t = rj_search(v_arg, top);
56171+ register caddr_t cp = v + head_off;
56172+ register int b;
56173+ struct radij_node *tt;
56174+ /*
56175+ *find first bit at which v and t->rj_key differ
56176+ */
56177+ {
56178+ register caddr_t cp2 = t->rj_key + head_off;
56179+ register int cmp_res;
56180+ caddr_t cplim = v + vlen;
56181+
56182+ while (cp < cplim)
56183+ if (*cp2++ != *cp++)
56184+ goto on1;
56185+ *dupentry = 1;
56186+ return t;
56187+on1:
56188+ *dupentry = 0;
56189+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
56190+ for (b = (cp - v) << 3; cmp_res; b--)
56191+ cmp_res >>= 1;
56192+ }
56193+ {
56194+ register struct radij_node *p, *x = top;
56195+ cp = v;
56196+ do {
56197+ p = x;
56198+ if (cp[x->rj_off] & x->rj_bmask)
56199+ x = x->rj_r;
56200+ else x = x->rj_l;
56201+ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
56202+#ifdef RJ_DEBUG
56203+ if (rj_debug)
56204+ printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
56205+#endif /* RJ_DEBUG */
56206+ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
56207+ if ((cp[p->rj_off] & p->rj_bmask) == 0)
56208+ p->rj_l = t;
56209+ else
56210+ p->rj_r = t;
56211+ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
56212+ if ((cp[t->rj_off] & t->rj_bmask) == 0) {
56213+ t->rj_r = x;
56214+ } else {
56215+ t->rj_r = tt; t->rj_l = x;
56216+ }
56217+#ifdef RJ_DEBUG
56218+ if (rj_debug)
56219+ printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
56220+#endif /* RJ_DEBUG */
56221+ }
56222+ return (tt);
56223+}
56224+
56225+struct radij_node *
56226+rj_addmask(n_arg, search, skip)
56227+ int search, skip;
56228+ void *n_arg;
56229+{
56230+ caddr_t netmask = (caddr_t)n_arg;
56231+ register struct radij_node *x;
56232+ register caddr_t cp, cplim;
56233+ register int b, mlen, j;
56234+ int maskduplicated;
56235+
56236+ mlen = *(u_char *)netmask;
56237+ if (search) {
56238+ x = rj_search(netmask, rj_masktop);
56239+ mlen = *(u_char *)netmask;
56240+ if (Bcmp(netmask, x->rj_key, mlen) == 0)
56241+ return (x);
56242+ }
56243+ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
56244+ if (x == 0)
56245+ return (0);
56246+ Bzero(x, maj_keylen + 2 * sizeof (*x));
56247+ cp = (caddr_t)(x + 2);
56248+ Bcopy(netmask, cp, mlen);
56249+ netmask = cp;
56250+ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
56251+ /*
56252+ * Calculate index of mask.
56253+ */
56254+ cplim = netmask + mlen;
56255+ for (cp = netmask + skip; cp < cplim; cp++)
56256+ if (*(u_char *)cp != 0xff)
56257+ break;
56258+ b = (cp - netmask) << 3;
56259+ if (cp != cplim) {
56260+ if (*cp != 0) {
56261+ gotOddMasks = 1;
56262+ for (j = 0x80; j; b++, j >>= 1)
56263+ if ((j & *cp) == 0)
56264+ break;
56265+ }
56266+ }
56267+ x->rj_b = -1 - b;
56268+ return (x);
56269+}
56270+
56271+#if 0
56272+struct radij_node *
56273+#endif
56274+int
56275+rj_addroute(v_arg, n_arg, head, treenodes)
56276+ void *v_arg, *n_arg;
56277+ struct radij_node_head *head;
56278+ struct radij_node treenodes[2];
56279+{
56280+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
56281+ register struct radij_node *t, *x=NULL, *tt;
56282+ struct radij_node *saved_tt, *top = head->rnh_treetop;
56283+ short b = 0, b_leaf;
56284+ int mlen, keyduplicated;
56285+ caddr_t cplim;
56286+ struct radij_mask *m, **mp;
56287+
56288+ /*
56289+ * In dealing with non-contiguous masks, there may be
56290+ * many different routes which have the same mask.
56291+ * We will find it useful to have a unique pointer to
56292+ * the mask to speed avoiding duplicate references at
56293+ * nodes and possibly save time in calculating indices.
56294+ */
56295+ if (netmask) {
56296+ x = rj_search(netmask, rj_masktop);
56297+ mlen = *(u_char *)netmask;
56298+ if (Bcmp(netmask, x->rj_key, mlen) != 0) {
56299+ x = rj_addmask(netmask, 0, top->rj_off);
56300+ if (x == 0)
56301+ return -ENOMEM; /* (0) rgb */
56302+ }
56303+ netmask = x->rj_key;
56304+ b = -1 - x->rj_b;
56305+ }
56306+ /*
56307+ * Deal with duplicated keys: attach node to previous instance
56308+ */
56309+ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
56310+#ifdef RJ_DEBUG
56311+ printk("addkey: duplicated: %d\n", keyduplicated);
56312+#endif
56313+ if (keyduplicated) {
56314+ do {
56315+ if (tt->rj_mask == netmask)
56316+ return -EEXIST; /* -ENXIO; (0) rgb */
56317+ t = tt;
56318+ if (netmask == 0 ||
56319+ (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
56320+ break;
56321+ } while ((tt = tt->rj_dupedkey));
56322+ /*
56323+ * If the mask is not duplicated, we wouldn't
56324+ * find it among possible duplicate key entries
56325+ * anyway, so the above test doesn't hurt.
56326+ *
56327+ * We sort the masks for a duplicated key the same way as
56328+ * in a masklist -- most specific to least specific.
56329+ * This may require the unfortunate nuisance of relocating
56330+ * the head of the list.
56331+ */
56332+ if (tt && t == saved_tt) {
56333+ struct radij_node *xx = x;
56334+ /* link in at head of list */
56335+ (tt = treenodes)->rj_dupedkey = t;
56336+ tt->rj_flags = t->rj_flags;
56337+ tt->rj_p = x = t->rj_p;
56338+ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
56339+ saved_tt = tt; x = xx;
56340+ } else {
56341+ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
56342+ t->rj_dupedkey = tt;
56343+ }
56344+#ifdef RJ_DEBUG
56345+ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
56346+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
56347+#endif /* RJ_DEBUG */
56348+ t = saved_tt;
56349+ tt->rj_key = (caddr_t) v;
56350+ tt->rj_b = -1;
56351+ tt->rj_flags = t->rj_flags & ~RJF_ROOT;
56352+ }
56353+ /*
56354+ * Put mask in tree.
56355+ */
56356+ if (netmask) {
56357+ tt->rj_mask = netmask;
56358+ tt->rj_b = x->rj_b;
56359+ }
56360+ t = saved_tt->rj_p;
56361+ b_leaf = -1 - t->rj_b;
56362+ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
56363+ /* Promote general routes from below */
56364+ if (x->rj_b < 0) {
56365+ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
56366+ MKGet(m);
56367+ if (m) {
56368+ Bzero(m, sizeof *m);
56369+ m->rm_b = x->rj_b;
56370+ m->rm_mask = x->rj_mask;
56371+ x->rj_mklist = t->rj_mklist = m;
56372+ }
56373+ }
56374+ } else if (x->rj_mklist) {
56375+ /*
56376+ * Skip over masks whose index is > that of new node
56377+ */
56378+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
56379+ if (m->rm_b >= b_leaf)
56380+ break;
56381+ t->rj_mklist = m; *mp = 0;
56382+ }
56383+ /* Add new route to highest possible ancestor's list */
56384+ if ((netmask == 0) || (b > t->rj_b )) {
56385+#ifdef RJ_DEBUG
56386+ printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b);
56387+#endif
56388+ return 0; /* tt rgb */ /* can't lift at all */
56389+ }
56390+ b_leaf = tt->rj_b;
56391+ do {
56392+ x = t;
56393+ t = t->rj_p;
56394+ } while (b <= t->rj_b && x != top);
56395+ /*
56396+ * Search through routes associated with node to
56397+ * insert new route according to index.
56398+ * For nodes of equal index, place more specific
56399+ * masks first.
56400+ */
56401+ cplim = netmask + mlen;
56402+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
56403+ if (m->rm_b < b_leaf)
56404+ continue;
56405+ if (m->rm_b > b_leaf)
56406+ break;
56407+ if (m->rm_mask == netmask) {
56408+ m->rm_refs++;
56409+ tt->rj_mklist = m;
56410+#ifdef RJ_DEBUG
56411+ printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask);
56412+#endif
56413+ return 0; /* tt rgb */
56414+ }
56415+ if (rj_refines(netmask, m->rm_mask))
56416+ break;
56417+ }
56418+ MKGet(m);
56419+ if (m == 0) {
56420+ printk("klips_debug:rj_addroute: "
56421+ "Mask for route not entered\n");
56422+ return 0; /* (tt) rgb */
56423+ }
56424+ Bzero(m, sizeof *m);
56425+ m->rm_b = b_leaf;
56426+ m->rm_mask = netmask;
56427+ m->rm_mklist = *mp;
56428+ *mp = m;
56429+ tt->rj_mklist = m;
56430+#ifdef RJ_DEBUG
56431+ printk("klips:radij.c: addroute done\n");
56432+#endif
56433+ return 0; /* tt rgb */
56434+}
56435+
56436+int
56437+rj_delete(v_arg, netmask_arg, head, node)
56438+ void *v_arg, *netmask_arg;
56439+ struct radij_node_head *head;
56440+ struct radij_node **node;
56441+{
56442+ register struct radij_node *t, *p, *x, *tt;
56443+ struct radij_mask *m, *saved_m, **mp;
56444+ struct radij_node *dupedkey, *saved_tt, *top;
56445+ caddr_t v, netmask;
56446+ int b, head_off, vlen;
56447+
56448+ v = v_arg;
56449+ netmask = netmask_arg;
56450+ x = head->rnh_treetop;
56451+ tt = rj_search(v, x);
56452+ head_off = x->rj_off;
56453+ vlen = *(u_char *)v;
56454+ saved_tt = tt;
56455+ top = x;
56456+ if (tt == 0 ||
56457+ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
56458+ return -EFAULT; /* (0) rgb */
56459+ /*
56460+ * Delete our route from mask lists.
56461+ */
56462+ if ((dupedkey = tt->rj_dupedkey)) {
56463+ if (netmask)
56464+ netmask = rj_search(netmask, rj_masktop)->rj_key;
56465+ while (tt->rj_mask != netmask)
56466+ if ((tt = tt->rj_dupedkey) == 0)
56467+ return -ENOENT; /* -ENXIO; (0) rgb */
56468+ }
56469+ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
56470+ goto on1;
56471+ if (m->rm_mask != tt->rj_mask) {
56472+ printk("klips_debug:rj_delete: "
56473+ "inconsistent annotation\n");
56474+ goto on1;
56475+ }
56476+ if (--m->rm_refs >= 0)
56477+ goto on1;
56478+ b = -1 - tt->rj_b;
56479+ t = saved_tt->rj_p;
56480+ if (b > t->rj_b)
56481+ goto on1; /* Wasn't lifted at all */
56482+ do {
56483+ x = t;
56484+ t = t->rj_p;
56485+ } while (b <= t->rj_b && x != top);
56486+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
56487+ if (m == saved_m) {
56488+ *mp = m->rm_mklist;
56489+ MKFree(m);
56490+ break;
56491+ }
56492+ if (m == 0)
56493+ printk("klips_debug:rj_delete: "
56494+ "couldn't find our annotation\n");
56495+on1:
56496+ /*
56497+ * Eliminate us from tree
56498+ */
56499+ if (tt->rj_flags & RJF_ROOT)
56500+ return -EFAULT; /* (0) rgb */
56501+#ifdef RJ_DEBUG
56502+ /* Get us out of the creation list */
56503+ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
56504+ if (t) t->rj_ybro = tt->rj_ybro;
56505+#endif /* RJ_DEBUG */
56506+ t = tt->rj_p;
56507+ if (dupedkey) {
56508+ if (tt == saved_tt) {
56509+ x = dupedkey; x->rj_p = t;
56510+ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
56511+ } else {
56512+ for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
56513+ p = p->rj_dupedkey;
56514+ if (p) p->rj_dupedkey = tt->rj_dupedkey;
56515+ else printk("klips_debug:rj_delete: "
56516+ "couldn't find node that we started with\n");
56517+ }
56518+ t = tt + 1;
56519+ if (t->rj_flags & RJF_ACTIVE) {
56520+#ifndef RJ_DEBUG
56521+ *++x = *t; p = t->rj_p;
56522+#else
56523+ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
56524+#endif /* RJ_DEBUG */
56525+ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
56526+ x->rj_l->rj_p = x; x->rj_r->rj_p = x;
56527+ }
56528+ goto out;
56529+ }
56530+ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
56531+ p = t->rj_p;
56532+ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
56533+ x->rj_p = p;
56534+ /*
56535+ * Demote routes attached to us.
56536+ */
56537+ if (t->rj_mklist) {
56538+ if (x->rj_b >= 0) {
56539+ for (mp = &x->rj_mklist; (m = *mp);)
56540+ mp = &m->rm_mklist;
56541+ *mp = t->rj_mklist;
56542+ } else {
56543+ for (m = t->rj_mklist; m;) {
56544+ struct radij_mask *mm = m->rm_mklist;
56545+ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
56546+ x->rj_mklist = 0;
56547+ MKFree(m);
56548+ } else
56549+ printk("klips_debug:rj_delete: "
56550+ "Orphaned Mask 0p%p at 0p%p\n", m, x);
56551+ m = mm;
56552+ }
56553+ }
56554+ }
56555+ /*
56556+ * We may be holding an active internal node in the tree.
56557+ */
56558+ x = tt + 1;
56559+ if (t != x) {
56560+#ifndef RJ_DEBUG
56561+ *t = *x;
56562+#else
56563+ b = t->rj_info; *t = *x; t->rj_info = b;
56564+#endif /* RJ_DEBUG */
56565+ t->rj_l->rj_p = t; t->rj_r->rj_p = t;
56566+ p = x->rj_p;
56567+ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
56568+ }
56569+out:
56570+ tt->rj_flags &= ~RJF_ACTIVE;
56571+ tt[1].rj_flags &= ~RJF_ACTIVE;
56572+ *node = tt;
56573+ return 0; /* (tt) rgb */
56574+}
56575+
56576+int
56577+rj_walktree(h, f, w)
56578+ struct radij_node_head *h;
56579+ register int (*f)(struct radij_node *,void *);
56580+ void *w;
56581+{
56582+ int error;
56583+ struct radij_node *base, *next;
56584+ register struct radij_node *rn;
56585+
56586+ if(!h || !f /* || !w */) {
56587+ return -ENODATA;
56588+ }
56589+
56590+ rn = h->rnh_treetop;
56591+ /*
56592+ * This gets complicated because we may delete the node
56593+ * while applying the function f to it, so we need to calculate
56594+ * the successor node in advance.
56595+ */
56596+ /* First time through node, go left */
56597+ while (rn->rj_b >= 0)
56598+ rn = rn->rj_l;
56599+ for (;;) {
56600+#ifdef CONFIG_KLIPS_DEBUG
56601+ if(debug_radij) {
56602+ printk("klips_debug:rj_walktree: "
56603+ "for: rn=0p%p rj_b=%d rj_flags=%x",
56604+ rn,
56605+ rn->rj_b,
56606+ rn->rj_flags);
56607+ rn->rj_b >= 0 ?
56608+ printk(" node off=%x\n",
56609+ rn->rj_off) :
56610+ printk(" leaf key = %08x->%08x\n",
56611+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56612+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56613+ ;
56614+ }
56615+#endif /* CONFIG_KLIPS_DEBUG */
56616+ base = rn;
56617+ /* If at right child go back up, otherwise, go right */
56618+ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
56619+ rn = rn->rj_p;
56620+ /* Find the next *leaf* since next node might vanish, too */
56621+ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
56622+ rn = rn->rj_l;
56623+ next = rn;
56624+#ifdef CONFIG_KLIPS_DEBUG
56625+ if(debug_radij) {
56626+ printk("klips_debug:rj_walktree: "
56627+ "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
56628+ rn,
56629+ rn->rj_b,
56630+ rn->rj_flags);
56631+ rn->rj_b >= 0 ?
56632+ printk(" node off=%x\n",
56633+ rn->rj_off) :
56634+ printk(" leaf key = %08x->%08x\n",
56635+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56636+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56637+ ;
56638+ }
56639+#endif /* CONFIG_KLIPS_DEBUG */
56640+ /* Process leaves */
56641+ while ((rn = base)) {
56642+ base = rn->rj_dupedkey;
56643+#ifdef CONFIG_KLIPS_DEBUG
56644+ if(debug_radij) {
56645+ printk("klips_debug:rj_walktree: "
56646+ "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
56647+ base,
56648+ rn,
56649+ rn->rj_b,
56650+ rn->rj_flags);
56651+ rn->rj_b >= 0 ?
56652+ printk(" node off=%x\n",
56653+ rn->rj_off) :
56654+ printk(" leaf key = %08x->%08x\n",
56655+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56656+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56657+ ;
56658+ }
56659+#endif /* CONFIG_KLIPS_DEBUG */
56660+ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
56661+ return (-error);
56662+ }
56663+ rn = next;
56664+ if (rn->rj_flags & RJF_ROOT)
56665+ return (0);
56666+ }
56667+ /* NOTREACHED */
56668+}
56669+
56670+int
56671+rj_inithead(head, off)
56672+ void **head;
56673+ int off;
56674+{
56675+ register struct radij_node_head *rnh;
56676+ register struct radij_node *t, *tt, *ttt;
56677+ if (*head)
56678+ return (1);
56679+ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
56680+ if (rnh == NULL)
56681+ return (0);
56682+ Bzero(rnh, sizeof (*rnh));
56683+ *head = rnh;
56684+ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
56685+ ttt = rnh->rnh_nodes + 2;
56686+ t->rj_r = ttt;
56687+ t->rj_p = t;
56688+ tt = t->rj_l;
56689+ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
56690+ tt->rj_b = -1 - off;
56691+ *ttt = *tt;
56692+ ttt->rj_key = rj_ones;
56693+ rnh->rnh_addaddr = rj_addroute;
56694+ rnh->rnh_deladdr = rj_delete;
56695+ rnh->rnh_matchaddr = rj_match;
56696+ rnh->rnh_walktree = rj_walktree;
56697+ rnh->rnh_treetop = t;
56698+ return (1);
56699+}
56700+
56701+void
56702+rj_init()
56703+{
56704+ char *cp, *cplim;
56705+
56706+ if (maj_keylen == 0) {
56707+ printk("klips_debug:rj_init: "
56708+ "radij functions require maj_keylen be set\n");
56709+ return;
56710+ }
56711+ R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
56712+ if (rj_zeroes == NULL)
56713+ panic("rj_init");
56714+ Bzero(rj_zeroes, 3 * maj_keylen);
56715+ rj_ones = cp = rj_zeroes + maj_keylen;
56716+ maskedKey = cplim = rj_ones + maj_keylen;
56717+ while (cp < cplim)
56718+ *cp++ = -1;
56719+ if (rj_inithead((void **)&mask_rjhead, 0) == 0)
56720+ panic("rj_init 2");
56721+}
56722+
56723+void
56724+rj_preorder(struct radij_node *rn, int l)
56725+{
56726+ int i;
56727+
56728+ if (rn == NULL){
56729+ printk("klips_debug:rj_preorder: "
56730+ "NULL pointer\n");
56731+ return;
56732+ }
56733+
56734+ if (rn->rj_b >= 0){
56735+ rj_preorder(rn->rj_l, l+1);
56736+ rj_preorder(rn->rj_r, l+1);
56737+ printk("klips_debug:");
56738+ for (i=0; i<l; i++)
56739+ printk("*");
56740+ printk(" off = %d\n",
56741+ rn->rj_off);
56742+ } else {
56743+ printk("klips_debug:");
56744+ for (i=0; i<l; i++)
56745+ printk("@");
56746+ printk(" flags = %x",
56747+ (u_int)rn->rj_flags);
56748+ if (rn->rj_flags & RJF_ACTIVE) {
56749+ printk(" @key=0p%p",
56750+ rn->rj_key);
56751+ printk(" key = %08x->%08x",
56752+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56753+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
56754+ printk(" @mask=0p%p",
56755+ rn->rj_mask);
56756+ if (rn->rj_mask)
56757+ printk(" mask = %08x->%08x",
56758+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
56759+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
56760+ if (rn->rj_dupedkey)
56761+ printk(" dupedkey = 0p%p",
56762+ rn->rj_dupedkey);
56763+ }
56764+ printk("\n");
56765+ }
56766+}
56767+
56768+#ifdef RJ_DEBUG
56769+DEBUG_NO_STATIC void traverse(struct radij_node *p)
56770+{
56771+ rj_preorder(p, 0);
56772+}
56773+#endif /* RJ_DEBUG */
56774+
56775+void
56776+rj_dumptrees(void)
56777+{
56778+ rj_preorder(rnh->rnh_treetop, 0);
56779+}
56780+
56781+void
56782+rj_free_mkfreelist(void)
56783+{
56784+ struct radij_mask *mknp, *mknp2;
56785+
56786+ mknp = rj_mkfreelist;
56787+ while(mknp)
56788+ {
56789+ mknp2 = mknp;
56790+ mknp = mknp->rm_mklist;
56791+ kfree(mknp2);
56792+ }
56793+}
56794+
56795+int
56796+radijcleartree(void)
56797+{
56798+ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
56799+}
56800+
56801+int
56802+radijcleanup(void)
56803+{
56804+ int error = 0;
56805+
56806+ error = radijcleartree();
56807+
56808+ rj_free_mkfreelist();
56809+
56810+/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
56811+ if(mask_rjhead) {
56812+ kfree(mask_rjhead);
56813+ }
56814+
56815+ if(rj_zeroes) {
56816+ kfree(rj_zeroes);
56817+ }
56818+
56819+ if(rnh) {
56820+ kfree(rnh);
56821+ }
56822+
56823+ return error;
56824+}
56825+
56826+/*
56827+ * $Log: radij.c,v $
56828+ * Revision 1.48.2.1 2006/10/06 21:39:27 paul
56829+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
56830+ * set. This is defined through autoconf.h which is included through the
56831+ * linux kernel build macros.
56832+ *
56833+ * Revision 1.48 2005/04/29 05:10:22 mcr
56834+ * removed from extraenous includes to make unit testing easier.
56835+ *
56836+ * Revision 1.47 2004/07/10 19:11:18 mcr
56837+ * CONFIG_IPSEC -> CONFIG_KLIPS.
56838+ *
56839+ * Revision 1.46 2004/04/06 02:49:26 mcr
56840+ * pullup of algo code from alg-branch.
56841+ *
56842+ * Revision 1.45 2003/10/31 02:27:55 mcr
56843+ * pulled up port-selector patches and sa_id elimination.
56844+ *
56845+ * Revision 1.44.30.1 2003/10/29 01:30:41 mcr
56846+ * elimited "struct sa_id".
56847+ *
56848+ * Revision 1.44 2002/07/24 18:44:54 rgb
56849+ * Type fiddling to tame ia64 compiler.
56850+ *
56851+ * Revision 1.43 2002/05/23 07:14:11 rgb
56852+ * Cleaned up %p variants to 0p%p for test suite cleanup.
56853+ *
56854+ * Revision 1.42 2002/04/24 07:55:32 mcr
56855+ * #include patches and Makefiles for post-reorg compilation.
56856+ *
56857+ * Revision 1.41 2002/04/24 07:36:35 mcr
56858+ * Moved from ./klips/net/ipsec/radij.c,v
56859+ *
56860+ * Revision 1.40 2002/01/29 17:17:58 mcr
56861+ * moved include of ipsec_param.h to after include of linux/kernel.h
56862+ * otherwise, it seems that some option that is set in ipsec_param.h
56863+ * screws up something subtle in the include path to kernel.h, and
56864+ * it complains on the snprintf() prototype.
56865+ *
56866+ * Revision 1.39 2002/01/29 04:00:55 mcr
56867+ * more excise of kversions.h header.
56868+ *
56869+ * Revision 1.38 2002/01/29 02:13:19 mcr
56870+ * introduction of ipsec_kversion.h means that include of
56871+ * ipsec_param.h must preceed any decisions about what files to
56872+ * include to deal with differences in kernel source.
56873+ *
56874+ * Revision 1.37 2001/10/18 04:45:23 rgb
56875+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
56876+ * lib/freeswan.h version macros moved to lib/kversions.h.
56877+ * Other compiler directive cleanups.
56878+ *
56879+ * Revision 1.36 2001/08/22 13:43:51 henry
56880+ * eliminate the single use of min() to avoid problems with Linus changing it
56881+ *
56882+ * Revision 1.35 2001/06/15 04:57:29 rgb
56883+ * Clarified error return codes.
56884+ * Changed mask add already exists to EEXIST.
56885+ * Changed mask delete did not exist to ENOENT.
56886+ *
56887+ * Revision 1.34 2001/05/03 19:44:26 rgb
56888+ * Fix sign of error return codes for rj_addroute().
56889+ *
56890+ * Revision 1.33 2001/02/27 22:24:56 rgb
56891+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
56892+ * Check for satoa() return codes.
56893+ *
56894+ * Revision 1.32 2001/02/27 06:23:15 rgb
56895+ * Debug line splitting.
56896+ *
56897+ * Revision 1.31 2000/11/06 04:35:21 rgb
56898+ * Clear table *before* releasing other items in radijcleanup.
56899+ *
56900+ * Revision 1.30 2000/09/20 04:07:40 rgb
56901+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
56902+ * oopsen.
56903+ *
56904+ * Revision 1.29 2000/09/12 03:25:02 rgb
56905+ * Moved radij_c_version printing to ipsec_version_get_info().
56906+ *
56907+ * Revision 1.28 2000/09/08 19:12:56 rgb
56908+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
56909+ *
56910+ * Revision 1.27 2000/07/28 14:58:32 rgb
56911+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
56912+ *
56913+ * Revision 1.26 2000/05/10 23:11:37 rgb
56914+ * Comment out most of the startup version information.
56915+ *
56916+ * Revision 1.25 2000/01/21 06:21:47 rgb
56917+ * Change return codes to negative on error.
56918+ *
56919+ * Revision 1.24 1999/11/18 04:09:20 rgb
56920+ * Replaced all kernel version macros to shorter, readable form.
56921+ *
56922+ * Revision 1.23 1999/11/17 15:53:41 rgb
56923+ * Changed all occurrences of #include "../../../lib/freeswan.h"
56924+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
56925+ * klips/net/ipsec/Makefile.
56926+ *
56927+ * Revision 1.22 1999/10/15 22:17:28 rgb
56928+ * Modify radijcleanup() to call radijcleartree().
56929+ *
56930+ * Revision 1.21 1999/10/08 18:37:34 rgb
56931+ * Fix end-of-line spacing to sate whining PHMs.
56932+ *
56933+ * Revision 1.20 1999/10/01 15:44:54 rgb
56934+ * Move spinlock header include to 2.1> scope.
56935+ *
56936+ * Revision 1.19 1999/10/01 08:35:52 rgb
56937+ * Add spinlock include to shut up compiler for 2.0.38.
56938+ *
56939+ * Revision 1.18 1999/09/23 18:02:52 rgb
56940+ * De-alarm the search failure message so it doesn't sound so grave.
56941+ *
56942+ * Revision 1.17 1999/05/25 21:26:01 rgb
56943+ * Fix rj_walktree() sanity checking bug.
56944+ *
56945+ * Revision 1.16 1999/05/09 03:25:38 rgb
56946+ * Fix bug introduced by 2.2 quick-and-dirty patch.
56947+ *
56948+ * Revision 1.15 1999/05/05 22:02:33 rgb
56949+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
56950+ *
56951+ * Revision 1.14 1999/04/29 15:24:15 rgb
56952+ * Add sanity checking for null pointer arguments.
56953+ * Standardise an error return method.
56954+ *
56955+ * Revision 1.13 1999/04/11 00:29:02 henry
56956+ * GPL boilerplate
56957+ *
56958+ * Revision 1.12 1999/04/06 04:54:28 rgb
56959+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
56960+ * patch shell fixes.
56961+ *
56962+ * Revision 1.11 1999/02/17 16:52:53 rgb
56963+ * Convert DEBUG_IPSEC to KLIPS_PRINT
56964+ * Clean out unused cruft.
56965+ *
56966+ * Revision 1.10 1999/01/22 06:30:05 rgb
56967+ * Cruft clean-out.
56968+ * 64-bit clean-up.
56969+ *
56970+ * Revision 1.9 1998/12/01 13:22:04 rgb
56971+ * Added support for debug printing of version info.
56972+ *
56973+ * Revision 1.8 1998/11/30 13:22:55 rgb
56974+ * Rationalised all the klips kernel file headers. They are much shorter
56975+ * now and won't conflict under RH5.2.
56976+ *
56977+ * Revision 1.7 1998/10/25 02:43:26 rgb
56978+ * Change return type on rj_addroute and rj_delete and add and argument
56979+ * to the latter to be able to transmit more infomation about errors.
56980+ *
56981+ * Revision 1.6 1998/10/19 14:30:06 rgb
56982+ * Added inclusion of freeswan.h.
56983+ *
56984+ * Revision 1.5 1998/10/09 04:33:27 rgb
56985+ * Added 'klips_debug' prefix to all klips printk debug statements.
56986+ * Fixed output formatting slightly.
56987+ *
56988+ * Revision 1.4 1998/07/28 00:06:59 rgb
56989+ * Add debug detail to tree traversing.
56990+ *
56991+ * Revision 1.3 1998/07/14 18:07:58 rgb
56992+ * Add a routine to clear the eroute tree.
56993+ *
56994+ * Revision 1.2 1998/06/25 20:03:22 rgb
56995+ * Cleanup #endif comments. Debug output for rj_init.
56996+ *
56997+ * Revision 1.1 1998/06/18 21:30:22 henry
56998+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
56999+ * build scripts happier about symlinks
57000+ *
57001+ * Revision 1.8 1998/05/25 20:34:15 rgb
57002+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
57003+ *
57004+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
57005+ * add ipsec_rj_walker_delete.
57006+ *
57007+ * Recover memory for eroute table on unload of module.
57008+ *
57009+ * Revision 1.7 1998/05/21 12:58:58 rgb
57010+ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
57011+ *
57012+ * Revision 1.6 1998/04/23 20:57:29 rgb
57013+ * Cleaned up compiler warnings for unused debugging functions.
57014+ *
57015+ * Revision 1.5 1998/04/22 16:51:38 rgb
57016+ * Tidy up radij debug code from recent rash of modifications to debug code.
57017+ *
57018+ * Revision 1.4 1998/04/21 21:28:56 rgb
57019+ * Rearrange debug switches to change on the fly debug output from user
57020+ * space. Only kernel changes checked in at this time. radij.c was also
57021+ * changed to temporarily remove buggy debugging code in rj_delete causing
57022+ * an OOPS and hence, netlink device open errors.
57023+ *
57024+ * Revision 1.3 1998/04/14 17:30:37 rgb
57025+ * Fix up compiling errors for radij tree memory reclamation.
57026+ *
57027+ * Revision 1.2 1998/04/12 22:03:25 rgb
57028+ * Updated ESP-3DES-HMAC-MD5-96,
57029+ * ESP-DES-HMAC-MD5-96,
57030+ * AH-HMAC-MD5-96,
57031+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
57032+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
57033+ *
57034+ * Fixed eroute references in /proc/net/ipsec*.
57035+ *
57036+ * Started to patch module unloading memory leaks in ipsec_netlink and
57037+ * radij tree unloading.
57038+ *
57039+ * Revision 1.1 1998/04/09 03:06:15 henry
57040+ * sources moved up from linux/net/ipsec
57041+ *
57042+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
57043+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
57044+ *
57045+ * Revision 0.4 1997/01/15 01:28:15 ji
57046+ * No changes.
57047+ *
57048+ * Revision 0.3 1996/11/20 14:39:04 ji
57049+ * Minor cleanups.
57050+ * Rationalized debugging code.
57051+ *
57052+ * Revision 0.2 1996/11/02 00:18:33 ji
57053+ * First limited release.
57054+ *
57055+ *
57056+ */
57057--- /dev/null Tue Mar 11 13:02:56 2003
57058+++ linux/net/ipsec/rangetoa.c Mon Feb 9 13:51:03 2004
57059@@ -0,0 +1,60 @@
57060+/*
57061+ * convert binary form of address range to ASCII
57062+ * Copyright (C) 1998, 1999 Henry Spencer.
57063+ *
57064+ * This library is free software; you can redistribute it and/or modify it
57065+ * under the terms of the GNU Library General Public License as published by
57066+ * the Free Software Foundation; either version 2 of the License, or (at your
57067+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57068+ *
57069+ * This library is distributed in the hope that it will be useful, but
57070+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57071+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57072+ * License for more details.
57073+ *
57074+ * RCSID $Id: rangetoa.c,v 1.9 2004/07/10 07:48:37 mcr Exp $
57075+ */
57076+#include "openswan.h"
57077+
57078+/*
57079+ - rangetoa - convert address range to ASCII
57080+ */
57081+size_t /* space needed for full conversion */
57082+rangetoa(addrs, format, dst, dstlen)
57083+struct in_addr addrs[2];
57084+int format; /* character */
57085+char *dst; /* need not be valid if dstlen is 0 */
57086+size_t dstlen;
57087+{
57088+ size_t len;
57089+ size_t rest;
57090+ int n;
57091+ char *p;
57092+
57093+ switch (format) {
57094+ case 0:
57095+ break;
57096+ default:
57097+ return 0;
57098+ break;
57099+ }
57100+
57101+ len = addrtoa(addrs[0], 0, dst, dstlen);
57102+ if (len < dstlen)
57103+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
57104+ p++, len++, n--)
57105+ *p = '.';
57106+ else
57107+ p = NULL;
57108+ if (len < dstlen)
57109+ rest = dstlen - len;
57110+ else {
57111+ if (dstlen > 0)
57112+ *(dst + dstlen - 1) = '\0';
57113+ rest = 0;
57114+ }
57115+
57116+ len += addrtoa(addrs[1], 0, p, rest);
57117+
57118+ return len;
57119+}
57120--- /dev/null Tue Mar 11 13:02:56 2003
57121+++ linux/net/ipsec/satot.c Mon Feb 9 13:51:03 2004
57122@@ -0,0 +1,133 @@
57123+/*
57124+ * convert from binary form of SA ID to text
57125+ * Copyright (C) 2000, 2001 Henry Spencer.
57126+ *
57127+ * This library is free software; you can redistribute it and/or modify it
57128+ * under the terms of the GNU Library General Public License as published by
57129+ * the Free Software Foundation; either version 2 of the License, or (at your
57130+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57131+ *
57132+ * This library is distributed in the hope that it will be useful, but
57133+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57134+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57135+ * License for more details.
57136+ *
57137+ * RCSID $Id: satot.c,v 1.13 2004/07/10 07:48:37 mcr Exp $
57138+ */
57139+#include "openswan.h"
57140+
57141+static struct typename {
57142+ char type;
57143+ char *name;
57144+} typenames[] = {
57145+ { SA_AH, "ah" },
57146+ { SA_ESP, "esp" },
57147+ { SA_IPIP, "tun" },
57148+ { SA_COMP, "comp" },
57149+ { SA_INT, "int" },
57150+ { 0, NULL }
57151+};
57152+
57153+/*
57154+ - satot - convert SA to text "ah507@1.2.3.4"
57155+ */
57156+size_t /* space needed for full conversion */
57157+satot(sa, format, dst, dstlen)
57158+const ip_said *sa;
57159+int format; /* character */
57160+char *dst; /* need not be valid if dstlen is 0 */
57161+size_t dstlen;
57162+{
57163+ size_t len = 0; /* 0 means "not recognized yet" */
57164+ int base;
57165+ int showversion; /* use delimiter to show IP version? */
57166+ struct typename *tn;
57167+ char *p;
57168+ char *pre;
57169+ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
57170+ char unk[10];
57171+
57172+ switch (format) {
57173+ case 0:
57174+ base = 16;
57175+ showversion = 1;
57176+ break;
57177+ case 'f':
57178+ base = 17;
57179+ showversion = 1;
57180+ break;
57181+ case 'x':
57182+ base = 'x';
57183+ showversion = 0;
57184+ break;
57185+ case 'd':
57186+ base = 10;
57187+ showversion = 0;
57188+ break;
57189+ default:
57190+ return 0;
57191+ break;
57192+ }
57193+
57194+ memset(buf, 0, sizeof(buf));
57195+
57196+ pre = NULL;
57197+ for (tn = typenames; tn->name != NULL; tn++)
57198+ if (sa->proto == tn->type) {
57199+ pre = tn->name;
57200+ break; /* NOTE BREAK OUT */
57201+ }
57202+ if (pre == NULL) { /* unknown protocol */
57203+ strcpy(unk, "unk");
57204+ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
57205+ sizeof(unk)-strlen(unk));
57206+ pre = unk;
57207+ }
57208+
57209+ if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
57210+ sa->spi == PASSTHROUGHSPI &&
57211+ isunspecaddr(&sa->dst)) {
57212+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
57213+ PASSTHROUGH4NAME :
57214+ PASSTHROUGH6NAME);
57215+ len = strlen(buf);
57216+ }
57217+
57218+ if (sa->proto == SA_INT) {
57219+ switch (ntohl(sa->spi)) {
57220+ case SPI_PASS: p = "%pass"; break;
57221+ case SPI_DROP: p = "%drop"; break;
57222+ case SPI_REJECT: p = "%reject"; break;
57223+ case SPI_HOLD: p = "%hold"; break;
57224+ case SPI_TRAP: p = "%trap"; break;
57225+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
57226+ default: p = NULL; break;
57227+ }
57228+ if (p != NULL) {
57229+ strcpy(buf, p);
57230+ len = strlen(buf);
57231+ }
57232+ }
57233+
57234+ if (len == 0) { /* general case needed */
57235+ strcpy(buf, pre);
57236+ len = strlen(buf);
57237+ if (showversion) {
57238+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
57239+ ':';
57240+ len++;
57241+ *(buf+len) = '\0';
57242+ }
57243+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
57244+ *(buf+len-1) = '@';
57245+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
57246+ *(buf+len) = '\0';
57247+ }
57248+
57249+ if (dst != NULL) {
57250+ if (len > dstlen)
57251+ *(buf+dstlen-1) = '\0';
57252+ strcpy(dst, buf);
57253+ }
57254+ return len;
57255+}
57256--- /dev/null Tue Mar 11 13:02:56 2003
57257+++ linux/net/ipsec/subnetof.c Mon Feb 9 13:51:03 2004
57258@@ -0,0 +1,59 @@
57259+/*
57260+ * minor network-address manipulation utilities
57261+ * Copyright (C) 1998, 1999 Henry Spencer.
57262+ *
57263+ * This library is free software; you can redistribute it and/or modify it
57264+ * under the terms of the GNU Library General Public License as published by
57265+ * the Free Software Foundation; either version 2 of the License, or (at your
57266+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57267+ *
57268+ * This library is distributed in the hope that it will be useful, but
57269+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57270+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57271+ * License for more details.
57272+ *
57273+ * RCSID $Id: subnetof.c,v 1.8 2004/07/10 07:48:37 mcr Exp $
57274+ */
57275+#include "openswan.h"
57276+
57277+/*
57278+ - subnetof - given address and mask, return subnet part
57279+ */
57280+struct in_addr
57281+subnetof(addr, mask)
57282+struct in_addr addr;
57283+struct in_addr mask;
57284+{
57285+ struct in_addr result;
57286+
57287+ result.s_addr = addr.s_addr & mask.s_addr;
57288+ return result;
57289+}
57290+
57291+/*
57292+ - hostof - given address and mask, return host part
57293+ */
57294+struct in_addr
57295+hostof(addr, mask)
57296+struct in_addr addr;
57297+struct in_addr mask;
57298+{
57299+ struct in_addr result;
57300+
57301+ result.s_addr = addr.s_addr & ~mask.s_addr;
57302+ return result;
57303+}
57304+
57305+/*
57306+ - broadcastof - given (network) address and mask, return broadcast address
57307+ */
57308+struct in_addr
57309+broadcastof(addr, mask)
57310+struct in_addr addr;
57311+struct in_addr mask;
57312+{
57313+ struct in_addr result;
57314+
57315+ result.s_addr = addr.s_addr | ~mask.s_addr;
57316+ return result;
57317+}
57318--- /dev/null Tue Mar 11 13:02:56 2003
57319+++ linux/net/ipsec/subnettoa.c Mon Feb 9 13:51:03 2004
57320@@ -0,0 +1,61 @@
57321+/*
57322+ * convert binary form of subnet description to ASCII
57323+ * Copyright (C) 1998, 1999 Henry Spencer.
57324+ *
57325+ * This library is free software; you can redistribute it and/or modify it
57326+ * under the terms of the GNU Library General Public License as published by
57327+ * the Free Software Foundation; either version 2 of the License, or (at your
57328+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57329+ *
57330+ * This library is distributed in the hope that it will be useful, but
57331+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57332+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57333+ * License for more details.
57334+ *
57335+ * RCSID $Id: subnettoa.c,v 1.11 2004/07/10 07:48:37 mcr Exp $
57336+ */
57337+#include "openswan.h"
57338+
57339+/*
57340+ - subnettoa - convert address and mask to ASCII "addr/mask"
57341+ * Output expresses the mask as a bit count if possible, else dotted decimal.
57342+ */
57343+size_t /* space needed for full conversion */
57344+subnettoa(addr, mask, format, dst, dstlen)
57345+struct in_addr addr;
57346+struct in_addr mask;
57347+int format; /* character */
57348+char *dst; /* need not be valid if dstlen is 0 */
57349+size_t dstlen;
57350+{
57351+ size_t len;
57352+ size_t rest;
57353+ int n;
57354+ char *p;
57355+
57356+ switch (format) {
57357+ case 0:
57358+ break;
57359+ default:
57360+ return 0;
57361+ break;
57362+ }
57363+
57364+ len = addrtoa(addr, 0, dst, dstlen);
57365+ if (len < dstlen) {
57366+ dst[len - 1] = '/';
57367+ p = dst + len;
57368+ rest = dstlen - len;
57369+ } else {
57370+ p = NULL;
57371+ rest = 0;
57372+ }
57373+
57374+ n = masktobits(mask);
57375+ if (n >= 0)
57376+ len += ultoa((unsigned long)n, 10, p, rest);
57377+ else
57378+ len += addrtoa(mask, 0, p, rest);
57379+
57380+ return len;
57381+}
57382--- /dev/null Tue Mar 11 13:02:56 2003
57383+++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004
57384@@ -0,0 +1,199 @@
57385+/*
57386+ * sysctl interface to net IPSEC subsystem.
57387+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
57388+ *
57389+ * This program is free software; you can redistribute it and/or modify it
57390+ * under the terms of the GNU General Public License as published by the
57391+ * Free Software Foundation; either version 2 of the License, or (at your
57392+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
57393+ *
57394+ * This program is distributed in the hope that it will be useful, but
57395+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57396+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57397+ * for more details.
57398+ *
57399+ * RCSID $Id: sysctl_net_ipsec.c,v 1.17 2004/07/10 19:11:18 mcr Exp $
57400+ */
57401+
57402+/* -*- linux-c -*-
57403+ *
57404+ * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
57405+ */
57406+
57407+#include <linux/mm.h>
57408+#include <linux/sysctl.h>
57409+
57410+#include "openswan/ipsec_param.h"
57411+
57412+#ifdef CONFIG_SYSCTL
57413+
57414+#define NET_IPSEC 2112 /* Random number */
57415+#ifdef CONFIG_KLIPS_DEBUG
57416+extern int debug_ah;
57417+extern int debug_esp;
57418+extern int debug_tunnel;
57419+extern int debug_eroute;
57420+extern int debug_spi;
57421+extern int debug_radij;
57422+extern int debug_netlink;
57423+extern int debug_xform;
57424+extern int debug_rcv;
57425+extern int debug_pfkey;
57426+extern int sysctl_ipsec_debug_verbose;
57427+#ifdef CONFIG_KLIPS_IPCOMP
57428+extern int sysctl_ipsec_debug_ipcomp;
57429+#endif /* CONFIG_KLIPS_IPCOMP */
57430+#endif /* CONFIG_KLIPS_DEBUG */
57431+
57432+extern int sysctl_ipsec_icmp;
57433+extern int sysctl_ipsec_inbound_policy_check;
57434+extern int sysctl_ipsec_tos;
57435+int sysctl_ipsec_regress_pfkey_lossage;
57436+
57437+enum {
57438+#ifdef CONFIG_KLIPS_DEBUG
57439+ NET_IPSEC_DEBUG_AH=1,
57440+ NET_IPSEC_DEBUG_ESP=2,
57441+ NET_IPSEC_DEBUG_TUNNEL=3,
57442+ NET_IPSEC_DEBUG_EROUTE=4,
57443+ NET_IPSEC_DEBUG_SPI=5,
57444+ NET_IPSEC_DEBUG_RADIJ=6,
57445+ NET_IPSEC_DEBUG_NETLINK=7,
57446+ NET_IPSEC_DEBUG_XFORM=8,
57447+ NET_IPSEC_DEBUG_RCV=9,
57448+ NET_IPSEC_DEBUG_PFKEY=10,
57449+ NET_IPSEC_DEBUG_VERBOSE=11,
57450+ NET_IPSEC_DEBUG_IPCOMP=12,
57451+#endif /* CONFIG_KLIPS_DEBUG */
57452+ NET_IPSEC_ICMP=13,
57453+ NET_IPSEC_INBOUND_POLICY_CHECK=14,
57454+ NET_IPSEC_TOS=15,
57455+ NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
57456+};
57457+
57458+static ctl_table ipsec_table[] = {
57459+#ifdef CONFIG_KLIPS_DEBUG
57460+ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
57461+ sizeof(int), 0644, NULL, &proc_dointvec},
57462+ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
57463+ sizeof(int), 0644, NULL, &proc_dointvec},
57464+ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
57465+ sizeof(int), 0644, NULL, &proc_dointvec},
57466+ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
57467+ sizeof(int), 0644, NULL, &proc_dointvec},
57468+ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
57469+ sizeof(int), 0644, NULL, &proc_dointvec},
57470+ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
57471+ sizeof(int), 0644, NULL, &proc_dointvec},
57472+ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
57473+ sizeof(int), 0644, NULL, &proc_dointvec},
57474+ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
57475+ sizeof(int), 0644, NULL, &proc_dointvec},
57476+ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
57477+ sizeof(int), 0644, NULL, &proc_dointvec},
57478+ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
57479+ sizeof(int), 0644, NULL, &proc_dointvec},
57480+ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
57481+ sizeof(int), 0644, NULL, &proc_dointvec},
57482+#ifdef CONFIG_KLIPS_IPCOMP
57483+ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
57484+ sizeof(int), 0644, NULL, &proc_dointvec},
57485+#endif /* CONFIG_KLIPS_IPCOMP */
57486+
57487+#ifdef CONFIG_KLIPS_REGRESS
57488+ { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
57489+ &sysctl_ipsec_regress_pfkey_lossage,
57490+ sizeof(int), 0644, NULL, &proc_dointvec},
57491+#endif /* CONFIG_KLIPS_REGRESS */
57492+
57493+#endif /* CONFIG_KLIPS_DEBUG */
57494+ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
57495+ sizeof(int), 0644, NULL, &proc_dointvec},
57496+ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
57497+ sizeof(int), 0644, NULL, &proc_dointvec},
57498+ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
57499+ sizeof(int), 0644, NULL, &proc_dointvec},
57500+ {0}
57501+};
57502+
57503+static ctl_table ipsec_net_table[] = {
57504+ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
57505+ { 0 }
57506+};
57507+
57508+static ctl_table ipsec_root_table[] = {
57509+ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
57510+ { 0 }
57511+};
57512+
57513+static struct ctl_table_header *ipsec_table_header;
57514+
57515+int ipsec_sysctl_register(void)
57516+{
57517+ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
57518+ if (!ipsec_table_header) {
57519+ return -ENOMEM;
57520+ }
57521+ return 0;
57522+}
57523+
57524+void ipsec_sysctl_unregister(void)
57525+{
57526+ unregister_sysctl_table(ipsec_table_header);
57527+}
57528+
57529+#endif /* CONFIG_SYSCTL */
57530+
57531+/*
57532+ * $Log: sysctl_net_ipsec.c,v $
57533+ * Revision 1.17 2004/07/10 19:11:18 mcr
57534+ * CONFIG_IPSEC -> CONFIG_KLIPS.
57535+ *
57536+ * Revision 1.16 2004/04/06 02:49:26 mcr
57537+ * pullup of algo code from alg-branch.
57538+ *
57539+ * Revision 1.15 2002/04/24 07:55:32 mcr
57540+ * #include patches and Makefiles for post-reorg compilation.
57541+ *
57542+ * Revision 1.14 2002/04/24 07:36:35 mcr
57543+ * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
57544+ *
57545+ * Revision 1.13 2002/01/12 02:58:32 mcr
57546+ * first regression test causes acquire messages to be lost
57547+ * 100% of the time. This is to help testing of pluto.
57548+ *
57549+ * Revision 1.12 2001/06/14 19:35:13 rgb
57550+ * Update copyright date.
57551+ *
57552+ * Revision 1.11 2001/02/26 19:58:13 rgb
57553+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
57554+ *
57555+ * Revision 1.10 2000/09/16 01:50:15 rgb
57556+ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
57557+ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
57558+ *
57559+ * Revision 1.9 2000/09/15 23:17:51 rgb
57560+ * Moved stuff around to compile with debug off.
57561+ *
57562+ * Revision 1.8 2000/09/15 11:37:02 rgb
57563+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
57564+ * IPCOMP zlib deflate code.
57565+ *
57566+ * Revision 1.7 2000/09/15 07:37:15 rgb
57567+ * Munged silly log comment that was causing a warning.
57568+ *
57569+ * Revision 1.6 2000/09/15 04:58:23 rgb
57570+ * Added tos runtime switch.
57571+ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
57572+ *
57573+ * Revision 1.5 2000/09/12 03:25:28 rgb
57574+ * Filled in and implemented sysctl.
57575+ *
57576+ * Revision 1.4 1999/04/11 00:29:03 henry
57577+ * GPL boilerplate
57578+ *
57579+ * Revision 1.3 1999/04/06 04:54:29 rgb
57580+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
57581+ * patch shell fixes.
57582+ *
57583+ */
57584--- /dev/null Tue Mar 11 13:02:56 2003
57585+++ linux/net/ipsec/trees.c Mon Feb 9 13:51:03 2004
57586@@ -0,0 +1,1214 @@
57587+/* trees.c -- output deflated data using Huffman coding
57588+ * Copyright (C) 1995-2002 Jean-loup Gailly
57589+ * For conditions of distribution and use, see copyright notice in zlib.h
57590+ */
57591+
57592+/*
57593+ * ALGORITHM
57594+ *
57595+ * The "deflation" process uses several Huffman trees. The more
57596+ * common source values are represented by shorter bit sequences.
57597+ *
57598+ * Each code tree is stored in a compressed form which is itself
57599+ * a Huffman encoding of the lengths of all the code strings (in
57600+ * ascending order by source values). The actual code strings are
57601+ * reconstructed from the lengths in the inflate process, as described
57602+ * in the deflate specification.
57603+ *
57604+ * REFERENCES
57605+ *
57606+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
57607+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
57608+ *
57609+ * Storer, James A.
57610+ * Data Compression: Methods and Theory, pp. 49-50.
57611+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
57612+ *
57613+ * Sedgewick, R.
57614+ * Algorithms, p290.
57615+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
57616+ */
57617+
57618+/* @(#) $Id: trees.c,v 1.4 2004/07/10 07:48:39 mcr Exp $ */
57619+
57620+/* #define GEN_TREES_H */
57621+
57622+#include "deflate.h"
57623+
57624+#ifdef DEBUG
57625+# include <ctype.h>
57626+#endif
57627+
57628+/* ===========================================================================
57629+ * Constants
57630+ */
57631+
57632+#define MAX_BL_BITS 7
57633+/* Bit length codes must not exceed MAX_BL_BITS bits */
57634+
57635+#define END_BLOCK 256
57636+/* end of block literal code */
57637+
57638+#define REP_3_6 16
57639+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
57640+
57641+#define REPZ_3_10 17
57642+/* repeat a zero length 3-10 times (3 bits of repeat count) */
57643+
57644+#define REPZ_11_138 18
57645+/* repeat a zero length 11-138 times (7 bits of repeat count) */
57646+
57647+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
57648+ = {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};
57649+
57650+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
57651+ = {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};
57652+
57653+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
57654+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
57655+
57656+local const uch bl_order[BL_CODES]
57657+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
57658+/* The lengths of the bit length codes are sent in order of decreasing
57659+ * probability, to avoid transmitting the lengths for unused bit length codes.
57660+ */
57661+
57662+#define Buf_size (8 * 2*sizeof(char))
57663+/* Number of bits used within bi_buf. (bi_buf might be implemented on
57664+ * more than 16 bits on some systems.)
57665+ */
57666+
57667+/* ===========================================================================
57668+ * Local data. These are initialized only once.
57669+ */
57670+
57671+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
57672+
57673+#if defined(GEN_TREES_H) || !defined(STDC)
57674+/* non ANSI compilers may not accept trees.h */
57675+
57676+local ct_data static_ltree[L_CODES+2];
57677+/* The static literal tree. Since the bit lengths are imposed, there is no
57678+ * need for the L_CODES extra codes used during heap construction. However
57679+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
57680+ * below).
57681+ */
57682+
57683+local ct_data static_dtree[D_CODES];
57684+/* The static distance tree. (Actually a trivial tree since all codes use
57685+ * 5 bits.)
57686+ */
57687+
57688+uch _dist_code[DIST_CODE_LEN];
57689+/* Distance codes. The first 256 values correspond to the distances
57690+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
57691+ * the 15 bit distances.
57692+ */
57693+
57694+uch _length_code[MAX_MATCH-MIN_MATCH+1];
57695+/* length code for each normalized match length (0 == MIN_MATCH) */
57696+
57697+local int base_length[LENGTH_CODES];
57698+/* First normalized length for each code (0 = MIN_MATCH) */
57699+
57700+local int base_dist[D_CODES];
57701+/* First normalized distance for each code (0 = distance of 1) */
57702+
57703+#else
57704+# include "trees.h"
57705+#endif /* GEN_TREES_H */
57706+
57707+struct static_tree_desc_s {
57708+ const ct_data *static_tree; /* static tree or NULL */
57709+ const intf *extra_bits; /* extra bits for each code or NULL */
57710+ int extra_base; /* base index for extra_bits */
57711+ int elems; /* max number of elements in the tree */
57712+ int max_length; /* max bit length for the codes */
57713+};
57714+
57715+local static_tree_desc static_l_desc =
57716+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
57717+
57718+local static_tree_desc static_d_desc =
57719+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
57720+
57721+local static_tree_desc static_bl_desc =
57722+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
57723+
57724+/* ===========================================================================
57725+ * Local (static) routines in this file.
57726+ */
57727+
57728+local void tr_static_init OF((void));
57729+local void init_block OF((deflate_state *s));
57730+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
57731+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
57732+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
57733+local void build_tree OF((deflate_state *s, tree_desc *desc));
57734+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
57735+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
57736+local int build_bl_tree OF((deflate_state *s));
57737+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
57738+ int blcodes));
57739+local void compress_block OF((deflate_state *s, const ct_data *ltree,
57740+ const ct_data *dtree));
57741+local void set_data_type OF((deflate_state *s));
57742+local unsigned bi_reverse OF((unsigned value, int length));
57743+local void bi_windup OF((deflate_state *s));
57744+local void bi_flush OF((deflate_state *s));
57745+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
57746+ int header));
57747+
57748+#ifdef GEN_TREES_H
57749+local void gen_trees_header OF((void));
57750+#endif
57751+
57752+#ifndef DEBUG
57753+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
57754+ /* Send a code of the given tree. c and tree must not have side effects */
57755+
57756+#else /* DEBUG */
57757+# define send_code(s, c, tree) \
57758+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
57759+ send_bits(s, tree[c].Code, tree[c].Len); }
57760+#endif
57761+
57762+/* ===========================================================================
57763+ * Output a short LSB first on the stream.
57764+ * IN assertion: there is enough room in pendingBuf.
57765+ */
57766+#define put_short(s, w) { \
57767+ put_byte(s, (uch)((w) & 0xff)); \
57768+ put_byte(s, (uch)((ush)(w) >> 8)); \
57769+}
57770+
57771+/* ===========================================================================
57772+ * Send a value on a given number of bits.
57773+ * IN assertion: length <= 16 and value fits in length bits.
57774+ */
57775+#ifdef DEBUG
57776+local void send_bits OF((deflate_state *s, int value, int length));
57777+
57778+local void send_bits(s, value, length)
57779+ deflate_state *s;
57780+ int value; /* value to send */
57781+ int length; /* number of bits */
57782+{
57783+ Tracevv((stderr," l %2d v %4x ", length, value));
57784+ Assert(length > 0 && length <= 15, "invalid length");
57785+ s->bits_sent += (ulg)length;
57786+
57787+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
57788+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
57789+ * unused bits in value.
57790+ */
57791+ if (s->bi_valid > (int)Buf_size - length) {
57792+ s->bi_buf |= (value << s->bi_valid);
57793+ put_short(s, s->bi_buf);
57794+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
57795+ s->bi_valid += length - Buf_size;
57796+ } else {
57797+ s->bi_buf |= value << s->bi_valid;
57798+ s->bi_valid += length;
57799+ }
57800+}
57801+#else /* !DEBUG */
57802+
57803+#define send_bits(s, value, length) \
57804+{ int len = length;\
57805+ if (s->bi_valid > (int)Buf_size - len) {\
57806+ int val = value;\
57807+ s->bi_buf |= (val << s->bi_valid);\
57808+ put_short(s, s->bi_buf);\
57809+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
57810+ s->bi_valid += len - Buf_size;\
57811+ } else {\
57812+ s->bi_buf |= (value) << s->bi_valid;\
57813+ s->bi_valid += len;\
57814+ }\
57815+}
57816+#endif /* DEBUG */
57817+
57818+
57819+#define MAX(a,b) (a >= b ? a : b)
57820+/* the arguments must not have side effects */
57821+
57822+/* ===========================================================================
57823+ * Initialize the various 'constant' tables.
57824+ */
57825+local void tr_static_init()
57826+{
57827+#if defined(GEN_TREES_H) || !defined(STDC)
57828+ static int static_init_done = 0;
57829+ int n; /* iterates over tree elements */
57830+ int bits; /* bit counter */
57831+ int length; /* length value */
57832+ int code; /* code value */
57833+ int dist; /* distance index */
57834+ ush bl_count[MAX_BITS+1];
57835+ /* number of codes at each bit length for an optimal tree */
57836+
57837+ if (static_init_done) return;
57838+
57839+ /* For some embedded targets, global variables are not initialized: */
57840+ static_l_desc.static_tree = static_ltree;
57841+ static_l_desc.extra_bits = extra_lbits;
57842+ static_d_desc.static_tree = static_dtree;
57843+ static_d_desc.extra_bits = extra_dbits;
57844+ static_bl_desc.extra_bits = extra_blbits;
57845+
57846+ /* Initialize the mapping length (0..255) -> length code (0..28) */
57847+ length = 0;
57848+ for (code = 0; code < LENGTH_CODES-1; code++) {
57849+ base_length[code] = length;
57850+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
57851+ _length_code[length++] = (uch)code;
57852+ }
57853+ }
57854+ Assert (length == 256, "tr_static_init: length != 256");
57855+ /* Note that the length 255 (match length 258) can be represented
57856+ * in two different ways: code 284 + 5 bits or code 285, so we
57857+ * overwrite length_code[255] to use the best encoding:
57858+ */
57859+ _length_code[length-1] = (uch)code;
57860+
57861+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
57862+ dist = 0;
57863+ for (code = 0 ; code < 16; code++) {
57864+ base_dist[code] = dist;
57865+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
57866+ _dist_code[dist++] = (uch)code;
57867+ }
57868+ }
57869+ Assert (dist == 256, "tr_static_init: dist != 256");
57870+ dist >>= 7; /* from now on, all distances are divided by 128 */
57871+ for ( ; code < D_CODES; code++) {
57872+ base_dist[code] = dist << 7;
57873+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
57874+ _dist_code[256 + dist++] = (uch)code;
57875+ }
57876+ }
57877+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
57878+
57879+ /* Construct the codes of the static literal tree */
57880+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
57881+ n = 0;
57882+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
57883+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
57884+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
57885+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
57886+ /* Codes 286 and 287 do not exist, but we must include them in the
57887+ * tree construction to get a canonical Huffman tree (longest code
57888+ * all ones)
57889+ */
57890+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
57891+
57892+ /* The static distance tree is trivial: */
57893+ for (n = 0; n < D_CODES; n++) {
57894+ static_dtree[n].Len = 5;
57895+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
57896+ }
57897+ static_init_done = 1;
57898+
57899+# ifdef GEN_TREES_H
57900+ gen_trees_header();
57901+# endif
57902+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
57903+}
57904+
57905+/* ===========================================================================
57906+ * Genererate the file trees.h describing the static trees.
57907+ */
57908+#ifdef GEN_TREES_H
57909+# ifndef DEBUG
57910+# include <stdio.h>
57911+# endif
57912+
57913+# define SEPARATOR(i, last, width) \
57914+ ((i) == (last)? "\n};\n\n" : \
57915+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
57916+
57917+void gen_trees_header()
57918+{
57919+ FILE *header = fopen("trees.h", "w");
57920+ int i;
57921+
57922+ Assert (header != NULL, "Can't open trees.h");
57923+ fprintf(header,
57924+ "/* header created automatically with -DGEN_TREES_H */\n\n");
57925+
57926+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
57927+ for (i = 0; i < L_CODES+2; i++) {
57928+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
57929+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
57930+ }
57931+
57932+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
57933+ for (i = 0; i < D_CODES; i++) {
57934+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
57935+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
57936+ }
57937+
57938+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
57939+ for (i = 0; i < DIST_CODE_LEN; i++) {
57940+ fprintf(header, "%2u%s", _dist_code[i],
57941+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
57942+ }
57943+
57944+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
57945+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
57946+ fprintf(header, "%2u%s", _length_code[i],
57947+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
57948+ }
57949+
57950+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
57951+ for (i = 0; i < LENGTH_CODES; i++) {
57952+ fprintf(header, "%1u%s", base_length[i],
57953+ SEPARATOR(i, LENGTH_CODES-1, 20));
57954+ }
57955+
57956+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
57957+ for (i = 0; i < D_CODES; i++) {
57958+ fprintf(header, "%5u%s", base_dist[i],
57959+ SEPARATOR(i, D_CODES-1, 10));
57960+ }
57961+
57962+ fclose(header);
57963+}
57964+#endif /* GEN_TREES_H */
57965+
57966+/* ===========================================================================
57967+ * Initialize the tree data structures for a new zlib stream.
57968+ */
57969+void _tr_init(s)
57970+ deflate_state *s;
57971+{
57972+ tr_static_init();
57973+
57974+ s->l_desc.dyn_tree = s->dyn_ltree;
57975+ s->l_desc.stat_desc = &static_l_desc;
57976+
57977+ s->d_desc.dyn_tree = s->dyn_dtree;
57978+ s->d_desc.stat_desc = &static_d_desc;
57979+
57980+ s->bl_desc.dyn_tree = s->bl_tree;
57981+ s->bl_desc.stat_desc = &static_bl_desc;
57982+
57983+ s->bi_buf = 0;
57984+ s->bi_valid = 0;
57985+ s->last_eob_len = 8; /* enough lookahead for inflate */
57986+#ifdef DEBUG
57987+ s->compressed_len = 0L;
57988+ s->bits_sent = 0L;
57989+#endif
57990+
57991+ /* Initialize the first block of the first file: */
57992+ init_block(s);
57993+}
57994+
57995+/* ===========================================================================
57996+ * Initialize a new block.
57997+ */
57998+local void init_block(s)
57999+ deflate_state *s;
58000+{
58001+ int n; /* iterates over tree elements */
58002+
58003+ /* Initialize the trees. */
58004+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
58005+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
58006+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
58007+
58008+ s->dyn_ltree[END_BLOCK].Freq = 1;
58009+ s->opt_len = s->static_len = 0L;
58010+ s->last_lit = s->matches = 0;
58011+}
58012+
58013+#define SMALLEST 1
58014+/* Index within the heap array of least frequent node in the Huffman tree */
58015+
58016+
58017+/* ===========================================================================
58018+ * Remove the smallest element from the heap and recreate the heap with
58019+ * one less element. Updates heap and heap_len.
58020+ */
58021+#define pqremove(s, tree, top) \
58022+{\
58023+ top = s->heap[SMALLEST]; \
58024+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
58025+ pqdownheap(s, tree, SMALLEST); \
58026+}
58027+
58028+/* ===========================================================================
58029+ * Compares to subtrees, using the tree depth as tie breaker when
58030+ * the subtrees have equal frequency. This minimizes the worst case length.
58031+ */
58032+#define smaller(tree, n, m, depth) \
58033+ (tree[n].Freq < tree[m].Freq || \
58034+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
58035+
58036+/* ===========================================================================
58037+ * Restore the heap property by moving down the tree starting at node k,
58038+ * exchanging a node with the smallest of its two sons if necessary, stopping
58039+ * when the heap property is re-established (each father smaller than its
58040+ * two sons).
58041+ */
58042+local void pqdownheap(s, tree, k)
58043+ deflate_state *s;
58044+ ct_data *tree; /* the tree to restore */
58045+ int k; /* node to move down */
58046+{
58047+ int v = s->heap[k];
58048+ int j = k << 1; /* left son of k */
58049+ while (j <= s->heap_len) {
58050+ /* Set j to the smallest of the two sons: */
58051+ if (j < s->heap_len &&
58052+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
58053+ j++;
58054+ }
58055+ /* Exit if v is smaller than both sons */
58056+ if (smaller(tree, v, s->heap[j], s->depth)) break;
58057+
58058+ /* Exchange v with the smallest son */
58059+ s->heap[k] = s->heap[j]; k = j;
58060+
58061+ /* And continue down the tree, setting j to the left son of k */
58062+ j <<= 1;
58063+ }
58064+ s->heap[k] = v;
58065+}
58066+
58067+/* ===========================================================================
58068+ * Compute the optimal bit lengths for a tree and update the total bit length
58069+ * for the current block.
58070+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
58071+ * above are the tree nodes sorted by increasing frequency.
58072+ * OUT assertions: the field len is set to the optimal bit length, the
58073+ * array bl_count contains the frequencies for each bit length.
58074+ * The length opt_len is updated; static_len is also updated if stree is
58075+ * not null.
58076+ */
58077+local void gen_bitlen(s, desc)
58078+ deflate_state *s;
58079+ tree_desc *desc; /* the tree descriptor */
58080+{
58081+ ct_data *tree = desc->dyn_tree;
58082+ int max_code = desc->max_code;
58083+ const ct_data *stree = desc->stat_desc->static_tree;
58084+ const intf *extra = desc->stat_desc->extra_bits;
58085+ int base = desc->stat_desc->extra_base;
58086+ int max_length = desc->stat_desc->max_length;
58087+ int h; /* heap index */
58088+ int n, m; /* iterate over the tree elements */
58089+ int bits; /* bit length */
58090+ int xbits; /* extra bits */
58091+ ush f; /* frequency */
58092+ int overflow = 0; /* number of elements with bit length too large */
58093+
58094+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
58095+
58096+ /* In a first pass, compute the optimal bit lengths (which may
58097+ * overflow in the case of the bit length tree).
58098+ */
58099+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
58100+
58101+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
58102+ n = s->heap[h];
58103+ bits = tree[tree[n].Dad].Len + 1;
58104+ if (bits > max_length) bits = max_length, overflow++;
58105+ tree[n].Len = (ush)bits;
58106+ /* We overwrite tree[n].Dad which is no longer needed */
58107+
58108+ if (n > max_code) continue; /* not a leaf node */
58109+
58110+ s->bl_count[bits]++;
58111+ xbits = 0;
58112+ if (n >= base) xbits = extra[n-base];
58113+ f = tree[n].Freq;
58114+ s->opt_len += (ulg)f * (bits + xbits);
58115+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
58116+ }
58117+ if (overflow == 0) return;
58118+
58119+ Trace((stderr,"\nbit length overflow\n"));
58120+ /* This happens for example on obj2 and pic of the Calgary corpus */
58121+
58122+ /* Find the first bit length which could increase: */
58123+ do {
58124+ bits = max_length-1;
58125+ while (s->bl_count[bits] == 0) bits--;
58126+ s->bl_count[bits]--; /* move one leaf down the tree */
58127+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
58128+ s->bl_count[max_length]--;
58129+ /* The brother of the overflow item also moves one step up,
58130+ * but this does not affect bl_count[max_length]
58131+ */
58132+ overflow -= 2;
58133+ } while (overflow > 0);
58134+
58135+ /* Now recompute all bit lengths, scanning in increasing frequency.
58136+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
58137+ * lengths instead of fixing only the wrong ones. This idea is taken
58138+ * from 'ar' written by Haruhiko Okumura.)
58139+ */
58140+ for (bits = max_length; bits != 0; bits--) {
58141+ n = s->bl_count[bits];
58142+ while (n != 0) {
58143+ m = s->heap[--h];
58144+ if (m > max_code) continue;
58145+ if (tree[m].Len != (unsigned) bits) {
58146+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
58147+ s->opt_len += ((long)bits - (long)tree[m].Len)
58148+ *(long)tree[m].Freq;
58149+ tree[m].Len = (ush)bits;
58150+ }
58151+ n--;
58152+ }
58153+ }
58154+}
58155+
58156+/* ===========================================================================
58157+ * Generate the codes for a given tree and bit counts (which need not be
58158+ * optimal).
58159+ * IN assertion: the array bl_count contains the bit length statistics for
58160+ * the given tree and the field len is set for all tree elements.
58161+ * OUT assertion: the field code is set for all tree elements of non
58162+ * zero code length.
58163+ */
58164+local void gen_codes (tree, max_code, bl_count)
58165+ ct_data *tree; /* the tree to decorate */
58166+ int max_code; /* largest code with non zero frequency */
58167+ ushf *bl_count; /* number of codes at each bit length */
58168+{
58169+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
58170+ ush code = 0; /* running code value */
58171+ int bits; /* bit index */
58172+ int n; /* code index */
58173+
58174+ /* The distribution counts are first used to generate the code values
58175+ * without bit reversal.
58176+ */
58177+ for (bits = 1; bits <= MAX_BITS; bits++) {
58178+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
58179+ }
58180+ /* Check that the bit counts in bl_count are consistent. The last code
58181+ * must be all ones.
58182+ */
58183+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
58184+ "inconsistent bit counts");
58185+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
58186+
58187+ for (n = 0; n <= max_code; n++) {
58188+ int len = tree[n].Len;
58189+ if (len == 0) continue;
58190+ /* Now reverse the bits */
58191+ tree[n].Code = bi_reverse(next_code[len]++, len);
58192+
58193+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
58194+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
58195+ }
58196+}
58197+
58198+/* ===========================================================================
58199+ * Construct one Huffman tree and assigns the code bit strings and lengths.
58200+ * Update the total bit length for the current block.
58201+ * IN assertion: the field freq is set for all tree elements.
58202+ * OUT assertions: the fields len and code are set to the optimal bit length
58203+ * and corresponding code. The length opt_len is updated; static_len is
58204+ * also updated if stree is not null. The field max_code is set.
58205+ */
58206+local void build_tree(s, desc)
58207+ deflate_state *s;
58208+ tree_desc *desc; /* the tree descriptor */
58209+{
58210+ ct_data *tree = desc->dyn_tree;
58211+ const ct_data *stree = desc->stat_desc->static_tree;
58212+ int elems = desc->stat_desc->elems;
58213+ int n, m; /* iterate over heap elements */
58214+ int max_code = -1; /* largest code with non zero frequency */
58215+ int node; /* new node being created */
58216+
58217+ /* Construct the initial heap, with least frequent element in
58218+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
58219+ * heap[0] is not used.
58220+ */
58221+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
58222+
58223+ for (n = 0; n < elems; n++) {
58224+ if (tree[n].Freq != 0) {
58225+ s->heap[++(s->heap_len)] = max_code = n;
58226+ s->depth[n] = 0;
58227+ } else {
58228+ tree[n].Len = 0;
58229+ }
58230+ }
58231+
58232+ /* The pkzip format requires that at least one distance code exists,
58233+ * and that at least one bit should be sent even if there is only one
58234+ * possible code. So to avoid special checks later on we force at least
58235+ * two codes of non zero frequency.
58236+ */
58237+ while (s->heap_len < 2) {
58238+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
58239+ tree[node].Freq = 1;
58240+ s->depth[node] = 0;
58241+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
58242+ /* node is 0 or 1 so it does not have extra bits */
58243+ }
58244+ desc->max_code = max_code;
58245+
58246+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
58247+ * establish sub-heaps of increasing lengths:
58248+ */
58249+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
58250+
58251+ /* Construct the Huffman tree by repeatedly combining the least two
58252+ * frequent nodes.
58253+ */
58254+ node = elems; /* next internal node of the tree */
58255+ do {
58256+ pqremove(s, tree, n); /* n = node of least frequency */
58257+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
58258+
58259+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
58260+ s->heap[--(s->heap_max)] = m;
58261+
58262+ /* Create a new node father of n and m */
58263+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
58264+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
58265+ tree[n].Dad = tree[m].Dad = (ush)node;
58266+#ifdef DUMP_BL_TREE
58267+ if (tree == s->bl_tree) {
58268+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
58269+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
58270+ }
58271+#endif
58272+ /* and insert the new node in the heap */
58273+ s->heap[SMALLEST] = node++;
58274+ pqdownheap(s, tree, SMALLEST);
58275+
58276+ } while (s->heap_len >= 2);
58277+
58278+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
58279+
58280+ /* At this point, the fields freq and dad are set. We can now
58281+ * generate the bit lengths.
58282+ */
58283+ gen_bitlen(s, (tree_desc *)desc);
58284+
58285+ /* The field len is now set, we can generate the bit codes */
58286+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
58287+}
58288+
58289+/* ===========================================================================
58290+ * Scan a literal or distance tree to determine the frequencies of the codes
58291+ * in the bit length tree.
58292+ */
58293+local void scan_tree (s, tree, max_code)
58294+ deflate_state *s;
58295+ ct_data *tree; /* the tree to be scanned */
58296+ int max_code; /* and its largest code of non zero frequency */
58297+{
58298+ int n; /* iterates over all tree elements */
58299+ int prevlen = -1; /* last emitted length */
58300+ int curlen; /* length of current code */
58301+ int nextlen = tree[0].Len; /* length of next code */
58302+ int count = 0; /* repeat count of the current code */
58303+ int max_count = 7; /* max repeat count */
58304+ int min_count = 4; /* min repeat count */
58305+
58306+ if (nextlen == 0) max_count = 138, min_count = 3;
58307+ tree[max_code+1].Len = (ush)0xffff; /* guard */
58308+
58309+ for (n = 0; n <= max_code; n++) {
58310+ curlen = nextlen; nextlen = tree[n+1].Len;
58311+ if (++count < max_count && curlen == nextlen) {
58312+ continue;
58313+ } else if (count < min_count) {
58314+ s->bl_tree[curlen].Freq += count;
58315+ } else if (curlen != 0) {
58316+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
58317+ s->bl_tree[REP_3_6].Freq++;
58318+ } else if (count <= 10) {
58319+ s->bl_tree[REPZ_3_10].Freq++;
58320+ } else {
58321+ s->bl_tree[REPZ_11_138].Freq++;
58322+ }
58323+ count = 0; prevlen = curlen;
58324+ if (nextlen == 0) {
58325+ max_count = 138, min_count = 3;
58326+ } else if (curlen == nextlen) {
58327+ max_count = 6, min_count = 3;
58328+ } else {
58329+ max_count = 7, min_count = 4;
58330+ }
58331+ }
58332+}
58333+
58334+/* ===========================================================================
58335+ * Send a literal or distance tree in compressed form, using the codes in
58336+ * bl_tree.
58337+ */
58338+local void send_tree (s, tree, max_code)
58339+ deflate_state *s;
58340+ ct_data *tree; /* the tree to be scanned */
58341+ int max_code; /* and its largest code of non zero frequency */
58342+{
58343+ int n; /* iterates over all tree elements */
58344+ int prevlen = -1; /* last emitted length */
58345+ int curlen; /* length of current code */
58346+ int nextlen = tree[0].Len; /* length of next code */
58347+ int count = 0; /* repeat count of the current code */
58348+ int max_count = 7; /* max repeat count */
58349+ int min_count = 4; /* min repeat count */
58350+
58351+ /* tree[max_code+1].Len = -1; */ /* guard already set */
58352+ if (nextlen == 0) max_count = 138, min_count = 3;
58353+
58354+ for (n = 0; n <= max_code; n++) {
58355+ curlen = nextlen; nextlen = tree[n+1].Len;
58356+ if (++count < max_count && curlen == nextlen) {
58357+ continue;
58358+ } else if (count < min_count) {
58359+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
58360+
58361+ } else if (curlen != 0) {
58362+ if (curlen != prevlen) {
58363+ send_code(s, curlen, s->bl_tree); count--;
58364+ }
58365+ Assert(count >= 3 && count <= 6, " 3_6?");
58366+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
58367+
58368+ } else if (count <= 10) {
58369+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
58370+
58371+ } else {
58372+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
58373+ }
58374+ count = 0; prevlen = curlen;
58375+ if (nextlen == 0) {
58376+ max_count = 138, min_count = 3;
58377+ } else if (curlen == nextlen) {
58378+ max_count = 6, min_count = 3;
58379+ } else {
58380+ max_count = 7, min_count = 4;
58381+ }
58382+ }
58383+}
58384+
58385+/* ===========================================================================
58386+ * Construct the Huffman tree for the bit lengths and return the index in
58387+ * bl_order of the last bit length code to send.
58388+ */
58389+local int build_bl_tree(s)
58390+ deflate_state *s;
58391+{
58392+ int max_blindex; /* index of last bit length code of non zero freq */
58393+
58394+ /* Determine the bit length frequencies for literal and distance trees */
58395+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
58396+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
58397+
58398+ /* Build the bit length tree: */
58399+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
58400+ /* opt_len now includes the length of the tree representations, except
58401+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
58402+ */
58403+
58404+ /* Determine the number of bit length codes to send. The pkzip format
58405+ * requires that at least 4 bit length codes be sent. (appnote.txt says
58406+ * 3 but the actual value used is 4.)
58407+ */
58408+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
58409+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
58410+ }
58411+ /* Update opt_len to include the bit length tree and counts */
58412+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
58413+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
58414+ s->opt_len, s->static_len));
58415+
58416+ return max_blindex;
58417+}
58418+
58419+/* ===========================================================================
58420+ * Send the header for a block using dynamic Huffman trees: the counts, the
58421+ * lengths of the bit length codes, the literal tree and the distance tree.
58422+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
58423+ */
58424+local void send_all_trees(s, lcodes, dcodes, blcodes)
58425+ deflate_state *s;
58426+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
58427+{
58428+ int rank; /* index in bl_order */
58429+
58430+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
58431+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
58432+ "too many codes");
58433+ Tracev((stderr, "\nbl counts: "));
58434+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
58435+ send_bits(s, dcodes-1, 5);
58436+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
58437+ for (rank = 0; rank < blcodes; rank++) {
58438+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
58439+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
58440+ }
58441+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
58442+
58443+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
58444+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
58445+
58446+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
58447+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
58448+}
58449+
58450+/* ===========================================================================
58451+ * Send a stored block
58452+ */
58453+void _tr_stored_block(s, buf, stored_len, eof)
58454+ deflate_state *s;
58455+ charf *buf; /* input block */
58456+ ulg stored_len; /* length of input block */
58457+ int eof; /* true if this is the last block for a file */
58458+{
58459+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
58460+#ifdef DEBUG
58461+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
58462+ s->compressed_len += (stored_len + 4) << 3;
58463+#endif
58464+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
58465+}
58466+
58467+/* ===========================================================================
58468+ * Send one empty static block to give enough lookahead for inflate.
58469+ * This takes 10 bits, of which 7 may remain in the bit buffer.
58470+ * The current inflate code requires 9 bits of lookahead. If the
58471+ * last two codes for the previous block (real code plus EOB) were coded
58472+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
58473+ * the last real code. In this case we send two empty static blocks instead
58474+ * of one. (There are no problems if the previous block is stored or fixed.)
58475+ * To simplify the code, we assume the worst case of last real code encoded
58476+ * on one bit only.
58477+ */
58478+void _tr_align(s)
58479+ deflate_state *s;
58480+{
58481+ send_bits(s, STATIC_TREES<<1, 3);
58482+ send_code(s, END_BLOCK, static_ltree);
58483+#ifdef DEBUG
58484+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
58485+#endif
58486+ bi_flush(s);
58487+ /* Of the 10 bits for the empty block, we have already sent
58488+ * (10 - bi_valid) bits. The lookahead for the last real code (before
58489+ * the EOB of the previous block) was thus at least one plus the length
58490+ * of the EOB plus what we have just sent of the empty static block.
58491+ */
58492+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
58493+ send_bits(s, STATIC_TREES<<1, 3);
58494+ send_code(s, END_BLOCK, static_ltree);
58495+#ifdef DEBUG
58496+ s->compressed_len += 10L;
58497+#endif
58498+ bi_flush(s);
58499+ }
58500+ s->last_eob_len = 7;
58501+}
58502+
58503+/* ===========================================================================
58504+ * Determine the best encoding for the current block: dynamic trees, static
58505+ * trees or store, and output the encoded block to the zip file.
58506+ */
58507+void _tr_flush_block(s, buf, stored_len, eof)
58508+ deflate_state *s;
58509+ charf *buf; /* input block, or NULL if too old */
58510+ ulg stored_len; /* length of input block */
58511+ int eof; /* true if this is the last block for a file */
58512+{
58513+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
58514+ int max_blindex = 0; /* index of last bit length code of non zero freq */
58515+
58516+ /* Build the Huffman trees unless a stored block is forced */
58517+ if (s->level > 0) {
58518+
58519+ /* Check if the file is ascii or binary */
58520+ if (s->data_type == Z_UNKNOWN) set_data_type(s);
58521+
58522+ /* Construct the literal and distance trees */
58523+ build_tree(s, (tree_desc *)(&(s->l_desc)));
58524+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
58525+ s->static_len));
58526+
58527+ build_tree(s, (tree_desc *)(&(s->d_desc)));
58528+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
58529+ s->static_len));
58530+ /* At this point, opt_len and static_len are the total bit lengths of
58531+ * the compressed block data, excluding the tree representations.
58532+ */
58533+
58534+ /* Build the bit length tree for the above two trees, and get the index
58535+ * in bl_order of the last bit length code to send.
58536+ */
58537+ max_blindex = build_bl_tree(s);
58538+
58539+ /* Determine the best encoding. Compute first the block length in bytes*/
58540+ opt_lenb = (s->opt_len+3+7)>>3;
58541+ static_lenb = (s->static_len+3+7)>>3;
58542+
58543+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
58544+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
58545+ s->last_lit));
58546+
58547+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
58548+
58549+ } else {
58550+ Assert(buf != (char*)0, "lost buf");
58551+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
58552+ }
58553+
58554+#ifdef FORCE_STORED
58555+ if (buf != (char*)0) { /* force stored block */
58556+#else
58557+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
58558+ /* 4: two words for the lengths */
58559+#endif
58560+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
58561+ * Otherwise we can't have processed more than WSIZE input bytes since
58562+ * the last block flush, because compression would have been
58563+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
58564+ * transform a block into a stored block.
58565+ */
58566+ _tr_stored_block(s, buf, stored_len, eof);
58567+
58568+#ifdef FORCE_STATIC
58569+ } else if (static_lenb >= 0) { /* force static trees */
58570+#else
58571+ } else if (static_lenb == opt_lenb) {
58572+#endif
58573+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
58574+ compress_block(s, static_ltree, static_dtree);
58575+#ifdef DEBUG
58576+ s->compressed_len += 3 + s->static_len;
58577+#endif
58578+ } else {
58579+ send_bits(s, (DYN_TREES<<1)+eof, 3);
58580+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
58581+ max_blindex+1);
58582+ compress_block(s, s->dyn_ltree, s->dyn_dtree);
58583+#ifdef DEBUG
58584+ s->compressed_len += 3 + s->opt_len;
58585+#endif
58586+ }
58587+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
58588+ /* The above check is made mod 2^32, for files larger than 512 MB
58589+ * and uLong implemented on 32 bits.
58590+ */
58591+ init_block(s);
58592+
58593+ if (eof) {
58594+ bi_windup(s);
58595+#ifdef DEBUG
58596+ s->compressed_len += 7; /* align on byte boundary */
58597+#endif
58598+ }
58599+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
58600+ s->compressed_len-7*eof));
58601+}
58602+
58603+/* ===========================================================================
58604+ * Save the match info and tally the frequency counts. Return true if
58605+ * the current block must be flushed.
58606+ */
58607+int _tr_tally (s, dist, lc)
58608+ deflate_state *s;
58609+ unsigned dist; /* distance of matched string */
58610+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
58611+{
58612+ s->d_buf[s->last_lit] = (ush)dist;
58613+ s->l_buf[s->last_lit++] = (uch)lc;
58614+ if (dist == 0) {
58615+ /* lc is the unmatched char */
58616+ s->dyn_ltree[lc].Freq++;
58617+ } else {
58618+ s->matches++;
58619+ /* Here, lc is the match length - MIN_MATCH */
58620+ dist--; /* dist = match distance - 1 */
58621+ Assert((ush)dist < (ush)MAX_DIST(s) &&
58622+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
58623+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
58624+
58625+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
58626+ s->dyn_dtree[d_code(dist)].Freq++;
58627+ }
58628+
58629+#ifdef TRUNCATE_BLOCK
58630+ /* Try to guess if it is profitable to stop the current block here */
58631+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
58632+ /* Compute an upper bound for the compressed length */
58633+ ulg out_length = (ulg)s->last_lit*8L;
58634+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
58635+ int dcode;
58636+ for (dcode = 0; dcode < D_CODES; dcode++) {
58637+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
58638+ (5L+extra_dbits[dcode]);
58639+ }
58640+ out_length >>= 3;
58641+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
58642+ s->last_lit, in_length, out_length,
58643+ 100L - out_length*100L/in_length));
58644+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
58645+ }
58646+#endif
58647+ return (s->last_lit == s->lit_bufsize-1);
58648+ /* We avoid equality with lit_bufsize because of wraparound at 64K
58649+ * on 16 bit machines and because stored blocks are restricted to
58650+ * 64K-1 bytes.
58651+ */
58652+}
58653+
58654+/* ===========================================================================
58655+ * Send the block data compressed using the given Huffman trees
58656+ */
58657+local void compress_block(s, ltree, dtree)
58658+ deflate_state *s;
58659+ const ct_data *ltree; /* literal tree */
58660+ const ct_data *dtree; /* distance tree */
58661+{
58662+ unsigned dist; /* distance of matched string */
58663+ int lc; /* match length or unmatched char (if dist == 0) */
58664+ unsigned lx = 0; /* running index in l_buf */
58665+ unsigned code; /* the code to send */
58666+ int extra; /* number of extra bits to send */
58667+
58668+ if (s->last_lit != 0) do {
58669+ dist = s->d_buf[lx];
58670+ lc = s->l_buf[lx++];
58671+ if (dist == 0) {
58672+ send_code(s, lc, ltree); /* send a literal byte */
58673+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
58674+ } else {
58675+ /* Here, lc is the match length - MIN_MATCH */
58676+ code = _length_code[lc];
58677+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
58678+ extra = extra_lbits[code];
58679+ if (extra != 0) {
58680+ lc -= base_length[code];
58681+ send_bits(s, lc, extra); /* send the extra length bits */
58682+ }
58683+ dist--; /* dist is now the match distance - 1 */
58684+ code = d_code(dist);
58685+ Assert (code < D_CODES, "bad d_code");
58686+
58687+ send_code(s, code, dtree); /* send the distance code */
58688+ extra = extra_dbits[code];
58689+ if (extra != 0) {
58690+ dist -= base_dist[code];
58691+ send_bits(s, dist, extra); /* send the extra distance bits */
58692+ }
58693+ } /* literal or match pair ? */
58694+
58695+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
58696+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
58697+
58698+ } while (lx < s->last_lit);
58699+
58700+ send_code(s, END_BLOCK, ltree);
58701+ s->last_eob_len = ltree[END_BLOCK].Len;
58702+}
58703+
58704+/* ===========================================================================
58705+ * Set the data type to ASCII or BINARY, using a crude approximation:
58706+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
58707+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
58708+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
58709+ */
58710+local void set_data_type(s)
58711+ deflate_state *s;
58712+{
58713+ int n = 0;
58714+ unsigned ascii_freq = 0;
58715+ unsigned bin_freq = 0;
58716+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
58717+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
58718+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
58719+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
58720+}
58721+
58722+/* ===========================================================================
58723+ * Reverse the first len bits of a code, using straightforward code (a faster
58724+ * method would use a table)
58725+ * IN assertion: 1 <= len <= 15
58726+ */
58727+local unsigned bi_reverse(code, len)
58728+ unsigned code; /* the value to invert */
58729+ int len; /* its bit length */
58730+{
58731+ register unsigned res = 0;
58732+ do {
58733+ res |= code & 1;
58734+ code >>= 1, res <<= 1;
58735+ } while (--len > 0);
58736+ return res >> 1;
58737+}
58738+
58739+/* ===========================================================================
58740+ * Flush the bit buffer, keeping at most 7 bits in it.
58741+ */
58742+local void bi_flush(s)
58743+ deflate_state *s;
58744+{
58745+ if (s->bi_valid == 16) {
58746+ put_short(s, s->bi_buf);
58747+ s->bi_buf = 0;
58748+ s->bi_valid = 0;
58749+ } else if (s->bi_valid >= 8) {
58750+ put_byte(s, (Byte)s->bi_buf);
58751+ s->bi_buf >>= 8;
58752+ s->bi_valid -= 8;
58753+ }
58754+}
58755+
58756+/* ===========================================================================
58757+ * Flush the bit buffer and align the output on a byte boundary
58758+ */
58759+local void bi_windup(s)
58760+ deflate_state *s;
58761+{
58762+ if (s->bi_valid > 8) {
58763+ put_short(s, s->bi_buf);
58764+ } else if (s->bi_valid > 0) {
58765+ put_byte(s, (Byte)s->bi_buf);
58766+ }
58767+ s->bi_buf = 0;
58768+ s->bi_valid = 0;
58769+#ifdef DEBUG
58770+ s->bits_sent = (s->bits_sent+7) & ~7;
58771+#endif
58772+}
58773+
58774+/* ===========================================================================
58775+ * Copy a stored block, storing first the length and its
58776+ * one's complement if requested.
58777+ */
58778+local void copy_block(s, buf, len, header)
58779+ deflate_state *s;
58780+ charf *buf; /* the input data */
58781+ unsigned len; /* its length */
58782+ int header; /* true if block header must be written */
58783+{
58784+ bi_windup(s); /* align on byte boundary */
58785+ s->last_eob_len = 8; /* enough lookahead for inflate */
58786+
58787+ if (header) {
58788+ put_short(s, (ush)len);
58789+ put_short(s, (ush)~len);
58790+#ifdef DEBUG
58791+ s->bits_sent += 2*16;
58792+#endif
58793+ }
58794+#ifdef DEBUG
58795+ s->bits_sent += (ulg)len<<3;
58796+#endif
58797+ while (len--) {
58798+ put_byte(s, *buf++);
58799+ }
58800+}
58801--- /dev/null Tue Mar 11 13:02:56 2003
58802+++ linux/net/ipsec/trees.h Mon Feb 9 13:51:03 2004
58803@@ -0,0 +1,128 @@
58804+/* header created automatically with -DGEN_TREES_H */
58805+
58806+local const ct_data static_ltree[L_CODES+2] = {
58807+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
58808+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
58809+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
58810+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
58811+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
58812+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
58813+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
58814+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
58815+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
58816+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
58817+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
58818+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
58819+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
58820+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
58821+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
58822+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
58823+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
58824+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
58825+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
58826+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
58827+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
58828+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
58829+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
58830+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
58831+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
58832+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
58833+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
58834+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
58835+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
58836+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
58837+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
58838+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
58839+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
58840+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
58841+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
58842+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
58843+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
58844+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
58845+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
58846+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
58847+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
58848+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
58849+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
58850+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
58851+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
58852+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
58853+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
58854+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
58855+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
58856+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
58857+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
58858+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
58859+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
58860+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
58861+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
58862+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
58863+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
58864+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
58865+};
58866+
58867+local const ct_data static_dtree[D_CODES] = {
58868+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
58869+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
58870+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
58871+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
58872+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
58873+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
58874+};
58875+
58876+const uch _dist_code[DIST_CODE_LEN] = {
58877+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
58878+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
58879+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
58880+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
58881+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
58882+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
58883+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
58884+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
58885+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
58886+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
58887+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
58888+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
58889+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
58890+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
58891+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
58892+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
58893+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
58894+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
58895+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
58896+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
58897+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
58898+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
58899+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
58900+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
58901+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
58902+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
58903+};
58904+
58905+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
58906+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
58907+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
58908+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
58909+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
58910+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
58911+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
58912+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
58913+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
58914+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
58915+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
58916+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
58917+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
58918+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
58919+};
58920+
58921+local const int base_length[LENGTH_CODES] = {
58922+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
58923+64, 80, 96, 112, 128, 160, 192, 224, 0
58924+};
58925+
58926+local const int base_dist[D_CODES] = {
58927+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
58928+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
58929+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
58930+};
58931+
58932--- /dev/null Tue Mar 11 13:02:56 2003
58933+++ linux/net/ipsec/ultoa.c Mon Feb 9 13:51:03 2004
58934@@ -0,0 +1,66 @@
58935+/*
58936+ * convert unsigned long to ASCII
58937+ * Copyright (C) 1998, 1999 Henry Spencer.
58938+ *
58939+ * This library is free software; you can redistribute it and/or modify it
58940+ * under the terms of the GNU Library General Public License as published by
58941+ * the Free Software Foundation; either version 2 of the License, or (at your
58942+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
58943+ *
58944+ * This library is distributed in the hope that it will be useful, but
58945+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
58946+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
58947+ * License for more details.
58948+ *
58949+ * RCSID $Id: ultoa.c,v 1.10 2004/07/10 07:48:37 mcr Exp $
58950+ */
58951+#include "openswan.h"
58952+
58953+/*
58954+ - ultoa - convert unsigned long to decimal ASCII
58955+ */
58956+size_t /* length required for full conversion */
58957+ultoa(n, base, dst, dstlen)
58958+unsigned long n;
58959+int base;
58960+char *dst; /* need not be valid if dstlen is 0 */
58961+size_t dstlen;
58962+{
58963+ char buf[3*sizeof(unsigned long) + 1];
58964+ char *bufend = buf + sizeof(buf);
58965+ size_t len;
58966+ char *p;
58967+ static char hex[] = "0123456789abcdef";
58968+
58969+ p = bufend;
58970+ *--p = '\0';
58971+ if (base == 10) {
58972+ do {
58973+ *--p = n%10 + '0';
58974+ n /= 10;
58975+ } while (n != 0);
58976+ } else if (base == 16) {
58977+ do {
58978+ *--p = hex[n&0xf];
58979+ n >>= 4;
58980+ } while (n != 0);
58981+ *--p = 'x';
58982+ *--p = '0';
58983+ } else if (base == 8) {
58984+ do {
58985+ *--p = (n&07) + '0';
58986+ n >>= 3;
58987+ } while (n != 0);
58988+ *--p = '0';
58989+ } else
58990+ *--p = '?';
58991+
58992+ len = bufend - p;
58993+
58994+ if (dstlen > 0) {
58995+ if (len > dstlen)
58996+ *(p + dstlen - 1) = '\0';
58997+ strcpy(dst, p);
58998+ }
58999+ return len;
59000+}
59001--- /dev/null Tue Mar 11 13:02:56 2003
59002+++ linux/net/ipsec/ultot.c Mon Feb 9 13:51:03 2004
59003@@ -0,0 +1,82 @@
59004+/*
59005+ * convert unsigned long to text
59006+ * Copyright (C) 2000 Henry Spencer.
59007+ *
59008+ * This library is free software; you can redistribute it and/or modify it
59009+ * under the terms of the GNU Library General Public License as published by
59010+ * the Free Software Foundation; either version 2 of the License, or (at your
59011+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
59012+ *
59013+ * This library is distributed in the hope that it will be useful, but
59014+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
59015+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
59016+ * License for more details.
59017+ *
59018+ * RCSID $Id: ultot.c,v 1.5 2004/07/10 07:48:37 mcr Exp $
59019+ */
59020+#include "openswan.h"
59021+
59022+/*
59023+ - ultot - convert unsigned long to text
59024+ */
59025+size_t /* length required for full conversion */
59026+ultot(n, base, dst, dstlen)
59027+unsigned long n;
59028+int base;
59029+char *dst; /* need not be valid if dstlen is 0 */
59030+size_t dstlen;
59031+{
59032+ char buf[3*sizeof(unsigned long) + 1];
59033+ char *bufend = buf + sizeof(buf);
59034+ size_t len;
59035+ char *p;
59036+ static char hex[] = "0123456789abcdef";
59037+# define HEX32 (32/4)
59038+
59039+ p = bufend;
59040+ *--p = '\0';
59041+ switch (base) {
59042+ case 10:
59043+ case 'd':
59044+ do {
59045+ *--p = n%10 + '0';
59046+ n /= 10;
59047+ } while (n != 0);
59048+ break;
59049+ case 16:
59050+ case 17:
59051+ case 'x':
59052+ do {
59053+ *--p = hex[n&0xf];
59054+ n >>= 4;
59055+ } while (n != 0);
59056+ if (base == 17)
59057+ while (bufend - p < HEX32 + 1)
59058+ *--p = '0';
59059+ if (base == 'x') {
59060+ *--p = 'x';
59061+ *--p = '0';
59062+ }
59063+ break;
59064+ case 8:
59065+ case 'o':
59066+ do {
59067+ *--p = (n&07) + '0';
59068+ n >>= 3;
59069+ } while (n != 0);
59070+ if (base == 'o')
59071+ *--p = '0';
59072+ break;
59073+ default:
59074+ return 0;
59075+ break;
59076+ }
59077+
59078+ len = bufend - p;
59079+ if (dstlen > 0) {
59080+ if (len > dstlen)
59081+ *(p + dstlen - 1) = '\0';
59082+ strcpy(dst, p);
59083+ }
59084+ return len;
59085+}
59086--- /dev/null Tue Mar 11 13:02:56 2003
59087+++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004
59088@@ -0,0 +1,44 @@
59089+/*
59090+ * return IPsec version information
59091+ * Copyright (C) 2001 Henry Spencer.
59092+ *
59093+ * This library is free software; you can redistribute it and/or modify it
59094+ * under the terms of the GNU Library General Public License as published by
59095+ * the Free Software Foundation; either version 2 of the License, or (at your
59096+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
59097+ *
59098+ * This library is distributed in the hope that it will be useful, but
59099+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
59100+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
59101+ * License for more details.
59102+ *
59103+ * RCSID $Id: version.in.c,v 1.2 2004/04/14 05:09:46 ken Exp $
59104+ */
59105+
59106+#ifdef __KERNEL__
59107+#include <linux/netdevice.h>
59108+#endif
59109+
59110+#include "openswan.h"
59111+
4b871415 59112+#define V "2.4.9" /* substituted in by Makefile */
b4f8d26c
MT
59113+static const char openswan_number[] = V;
59114+static const char openswan_string[] = "Openswan " V;
59115+
59116+/*
59117+ - ipsec_version_code - return IPsec version number/code, as string
59118+ */
59119+const char *
59120+ipsec_version_code()
59121+{
59122+ return openswan_number;
59123+}
59124+
59125+/*
59126+ - ipsec_version_string - return full version string
59127+ */
59128+const char *
59129+ipsec_version_string()
59130+{
59131+ return openswan_string;
59132+}
59133--- /dev/null Tue Mar 11 13:02:56 2003
59134+++ linux/net/ipsec/zutil.c Mon Feb 9 13:51:03 2004
59135@@ -0,0 +1,227 @@
59136+/* zutil.c -- target dependent utility functions for the compression library
59137+ * Copyright (C) 1995-2002 Jean-loup Gailly.
59138+ * For conditions of distribution and use, see copyright notice in zlib.h
59139+ */
59140+
59141+/* @(#) $Id: zutil.c,v 1.5 2004/07/10 07:48:40 mcr Exp $ */
59142+
59143+#include <zlib/zutil.h>
59144+
59145+#define MY_ZCALLOC
59146+
59147+struct internal_state {int dummy;}; /* for buggy compilers */
59148+
59149+#ifndef STDC
59150+extern void exit OF((int));
59151+#endif
59152+
59153+const char *z_errmsg[10] = {
59154+"need dictionary", /* Z_NEED_DICT 2 */
59155+"stream end", /* Z_STREAM_END 1 */
59156+"", /* Z_OK 0 */
59157+"file error", /* Z_ERRNO (-1) */
59158+"stream error", /* Z_STREAM_ERROR (-2) */
59159+"data error", /* Z_DATA_ERROR (-3) */
59160+"insufficient memory", /* Z_MEM_ERROR (-4) */
59161+"buffer error", /* Z_BUF_ERROR (-5) */
59162+"incompatible version",/* Z_VERSION_ERROR (-6) */
59163+""};
59164+
59165+
59166+const char * ZEXPORT zlibVersion()
59167+{
59168+ return ZLIB_VERSION;
59169+}
59170+
59171+#ifdef DEBUG
59172+
59173+# ifndef verbose
59174+# define verbose 0
59175+# endif
59176+int z_verbose = verbose;
59177+
59178+void z_error (m)
59179+ char *m;
59180+{
59181+ fprintf(stderr, "%s\n", m);
59182+ exit(1);
59183+}
59184+#endif
59185+
59186+/* exported to allow conversion of error code to string for compress() and
59187+ * uncompress()
59188+ */
59189+const char * ZEXPORT zError(err)
59190+ int err;
59191+{
59192+ return ERR_MSG(err);
59193+}
59194+
59195+
59196+#ifndef HAVE_MEMCPY
59197+
59198+void zmemcpy(dest, source, len)
59199+ Bytef* dest;
59200+ const Bytef* source;
59201+ uInt len;
59202+{
59203+ if (len == 0) return;
59204+ do {
59205+ *dest++ = *source++; /* ??? to be unrolled */
59206+ } while (--len != 0);
59207+}
59208+
59209+int zmemcmp(s1, s2, len)
59210+ const Bytef* s1;
59211+ const Bytef* s2;
59212+ uInt len;
59213+{
59214+ uInt j;
59215+
59216+ for (j = 0; j < len; j++) {
59217+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
59218+ }
59219+ return 0;
59220+}
59221+
59222+void zmemzero(dest, len)
59223+ Bytef* dest;
59224+ uInt len;
59225+{
59226+ if (len == 0) return;
59227+ do {
59228+ *dest++ = 0; /* ??? to be unrolled */
59229+ } while (--len != 0);
59230+}
59231+#endif
59232+
59233+#ifdef __TURBOC__
59234+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
59235+/* Small and medium model in Turbo C are for now limited to near allocation
59236+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
59237+ */
59238+# define MY_ZCALLOC
59239+
59240+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
59241+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
59242+ * must fix the pointer. Warning: the pointer must be put back to its
59243+ * original form in order to free it, use zcfree().
59244+ */
59245+
59246+#define MAX_PTR 10
59247+/* 10*64K = 640K */
59248+
59249+local int next_ptr = 0;
59250+
59251+typedef struct ptr_table_s {
59252+ voidpf org_ptr;
59253+ voidpf new_ptr;
59254+} ptr_table;
59255+
59256+local ptr_table table[MAX_PTR];
59257+/* This table is used to remember the original form of pointers
59258+ * to large buffers (64K). Such pointers are normalized with a zero offset.
59259+ * Since MSDOS is not a preemptive multitasking OS, this table is not
59260+ * protected from concurrent access. This hack doesn't work anyway on
59261+ * a protected system like OS/2. Use Microsoft C instead.
59262+ */
59263+
59264+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
59265+{
59266+ voidpf buf = opaque; /* just to make some compilers happy */
59267+ ulg bsize = (ulg)items*size;
59268+
59269+ /* If we allocate less than 65520 bytes, we assume that farmalloc
59270+ * will return a usable pointer which doesn't have to be normalized.
59271+ */
59272+ if (bsize < 65520L) {
59273+ buf = farmalloc(bsize);
59274+ if (*(ush*)&buf != 0) return buf;
59275+ } else {
59276+ buf = farmalloc(bsize + 16L);
59277+ }
59278+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
59279+ table[next_ptr].org_ptr = buf;
59280+
59281+ /* Normalize the pointer to seg:0 */
59282+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
59283+ *(ush*)&buf = 0;
59284+ table[next_ptr++].new_ptr = buf;
59285+ return buf;
59286+}
59287+
59288+void zcfree (voidpf opaque, voidpf ptr)
59289+{
59290+ int n;
59291+ if (*(ush*)&ptr != 0) { /* object < 64K */
59292+ farfree(ptr);
59293+ return;
59294+ }
59295+ /* Find the original pointer */
59296+ for (n = 0; n < next_ptr; n++) {
59297+ if (ptr != table[n].new_ptr) continue;
59298+
59299+ farfree(table[n].org_ptr);
59300+ while (++n < next_ptr) {
59301+ table[n-1] = table[n];
59302+ }
59303+ next_ptr--;
59304+ return;
59305+ }
59306+ ptr = opaque; /* just to make some compilers happy */
59307+ Assert(0, "zcfree: ptr not found");
59308+}
59309+#endif
59310+#endif /* __TURBOC__ */
59311+
59312+
59313+#if defined(M_I86) && !defined(__32BIT__)
59314+/* Microsoft C in 16-bit mode */
59315+
59316+# define MY_ZCALLOC
59317+
59318+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
59319+# define _halloc halloc
59320+# define _hfree hfree
59321+#endif
59322+
59323+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
59324+{
59325+ if (opaque) opaque = 0; /* to make compiler happy */
59326+ return _halloc((long)items, size);
59327+}
59328+
59329+void zcfree (voidpf opaque, voidpf ptr)
59330+{
59331+ if (opaque) opaque = 0; /* to make compiler happy */
59332+ _hfree(ptr);
59333+}
59334+
59335+#endif /* MSC */
59336+
59337+
59338+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
59339+
59340+#ifndef STDC
59341+extern voidp calloc OF((uInt items, uInt size));
59342+extern void free OF((voidpf ptr));
59343+#endif
59344+
59345+voidpf zcalloc (opaque, items, size)
59346+ voidpf opaque;
59347+ unsigned items;
59348+ unsigned size;
59349+{
59350+ if (opaque) items += size - size; /* make compiler happy */
59351+ return (voidpf)calloc(items, size);
59352+}
59353+
59354+void zcfree (opaque, ptr)
59355+ voidpf opaque;
59356+ voidpf ptr;
59357+{
59358+ free(ptr);
59359+ if (opaque) return; /* make compiler happy */
59360+}
59361+
59362+#endif /* MY_ZCALLOC */
59363--- swan26/net/ipv4/af_inet.c.orig Wed Jun 16 01:18:58 2004
59364+++ swan26/net/ipv4/af_inet.c Fri Aug 13 23:09:27 2004
59365@@ -1169,6 +1169,18 @@
59366 #if defined(CONFIG_IP_MROUTE)
59367 ip_mr_init();
59368 #endif
59369+
59370+#if defined(CONFIG_KLIPS)
59371+ {
59372+ extern int ipsec_klips_init(void);
59373+ /*
59374+ * Initialise AF_INET ESP and AH protocol support including
59375+ * e-routing and SA tables
59376+ */
59377+ ipsec_klips_init();
59378+ }
59379+#endif /* CONFIG_IPSEC */
59380+
59381 /*
59382 * Initialise per-cpu ipv4 mibs
59383 */
59384--- /dev/null Fri May 10 13:59:54 2002
59385+++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002
59386@@ -0,0 +1 @@
4b871415 59387+IPSECVERSION=2.4.9