]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/openswan-2.4.12.kernel-2.6-klips.patch
Add udev rule for SCSI/SATA/LIBATA Cdrom
[people/pmueller/ipfire-2.x.git] / src / patches / openswan-2.4.12.kernel-2.6-klips.patch
CommitLineData
4ce37908
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,429 @@
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.21 2008-02-17 20:35:35 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)
3845+# if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) && defined(CONFIG_NETFILTER))
3846+# define SKB_RESET_NFCT
3847+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
3848+# if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
3849+# define SKB_RESET_NFCT
3850+# endif
3851+# endif
3852+#endif
3853+
3854+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
3855+#define IP_SELECT_IDENT_NEW
3856+#endif
3857+
3858+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
3859+#define IPH_is_SKB_PULLED
3860+#define SKB_COW_NEW
3861+#define PROTO_HANDLER_SINGLE_PARM
3862+#define IP_FRAGMENT_LINEARIZE 1
3863+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3864+# ifdef REDHAT_BOGOSITY
3865+# define IP_SELECT_IDENT_NEW
3866+# define IPH_is_SKB_PULLED
3867+# define SKB_COW_NEW
3868+# define PROTO_HANDLER_SINGLE_PARM
3869+# endif /* REDHAT_BOGOSITY */
3870+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3871+
3872+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
3873+#define MALLOC_SLAB
3874+#define LINUX_KERNEL_HAS_SNPRINTF
3875+#endif
3876+
3877+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3878+#define HAVE_NETDEV_PRINTK 1
3879+#define NET_26
3880+#endif
3881+
3882+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
3883+#define NEED_INET_PROTOCOL
3884+#endif
3885+
3886+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
3887+#define HAVE_SOCK_ZAPPED
3888+#define NET_26_12_SKALLOC
3889+#endif
3890+
3891+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
3892+#define HAVE_SOCK_SECURITY
3893+/* skb->nf_debug disappared completely in 2.6.13 */
3894+#define HAVE_SKB_NF_DEBUG
3895+#endif
3896+
3897+#define SYSCTL_IPSEC_DEFAULT_TTL sysctl_ip_default_ttl
3898+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
3899+/* skb->stamp changed to skb->tstamp in 2.6.14 */
3900+#define HAVE_TSTAMP
3901+#define HAVE_INET_SK_SPORT
3902+#undef SYSCTL_IPSEC_DEFAULT_TTL
3903+#define SYSCTL_IPSEC_DEFAULT_TTL IPSEC_DEFAULT_TTL
3904+#else
3905+#define HAVE_SKB_LIST
3906+#endif
3907+
3908+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) || SLE_VERSION_CODE >= 655616
3909+#define HAVE_NEW_SKB_LINEARIZE
3910+#endif
3911+
3912+/* this is the best we can do to detect XEN, which makes
3913+ * * patches to linux/skbuff.h, making it look like 2.6.18 version
3914+ * */
3915+#ifdef CONFIG_XEN
3916+#define HAVE_NEW_SKB_LINEARIZE
3917+#endif
3918+
3919+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
3920+#define VOID_SOCK_UNREGISTER
3921+#endif
3922+
3923+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3924+/* skb->nfmark changed to skb->mark in 2.6.20 */
3925+#define nfmark mark
3926+#endif
3927+
3928+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
3929+/* need to include ip.h early, no longer pick it up in skbuff.h */
3930+#include <linux/ip.h>
3931+# define HAVE_KERNEL_TSTAMP
3932+/* type of sock.sk_stamp changed from timeval to ktime */
3933+# define grab_socket_timeval(tv, sock) { (tv) = ktime_to_timeval((sock).sk_stamp); }
3934+#else
3935+# define grab_socket_timeval(tv, sock) { (tv) = (sock).sk_stamp; }
3936+/* internals of struct skbuff changed */
3937+# define HAVE_DEV_NEXT
3938+# define ip_hdr(skb) ((skb)->nh.iph)
3939+# define skb_tail_pointer(skb) ((skb)->tail)
3940+# define skb_end_pointer(skb) ((skb)->end)
3941+# define skb_network_header(skb) ((skb)->nh.raw)
3942+# define skb_set_network_header(skb,off) ((skb)->nh.raw = (skb)->data + (off))
3943+# define tcp_hdr(skb) ((skb)->h.th)
3944+# define udp_hdr(skb) ((skb)->h.uh)
3945+# define skb_transport_header(skb) ((skb)->h.raw)
3946+# define skb_set_transport_header(skb,off) ((skb)->h.raw = (skb)->data + (off))
3947+# define skb_mac_header(skb) ((skb)->mac.raw)
3948+# define skb_set_mac_header(skb,off) ((skb)->mac.raw = (skb)->data + (off))
3949+#endif
3950+/* turn a pointer into an offset for above macros */
3951+#define ipsec_skb_offset(skb, ptr) (((unsigned char *)(ptr)) - (skb)->data)
3952+
3953+#ifdef NET_21
3954+# include <linux/in6.h>
3955+#else
3956+ /* old kernel in.h has some IPv6 stuff, but not quite enough */
3957+# define s6_addr16 s6_addr
3958+# define AF_INET6 10
3959+# define uint8_t __u8
3960+# define uint16_t __u16
3961+# define uint32_t __u32
3962+# define uint64_t __u64
3963+#endif
3964+
3965+#ifdef NET_21
3966+# define ipsec_kfree_skb(a) kfree_skb(a)
3967+#else /* NET_21 */
3968+# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
3969+#endif /* NET_21 */
3970+
3971+#ifdef NETDEV_23
3972+#if 0
3973+#ifndef NETDEV_25
3974+#define device net_device
3975+#endif
3976+#endif
3977+# define ipsec_dev_get dev_get_by_name
3978+# define __ipsec_dev_get __dev_get_by_name
3979+# define ipsec_dev_put(x) dev_put(x)
3980+# define __ipsec_dev_put(x) __dev_put(x)
3981+# define ipsec_dev_hold(x) dev_hold(x)
3982+#else /* NETDEV_23 */
3983+# define ipsec_dev_get dev_get
3984+# define __ipsec_dev_put(x)
3985+# define ipsec_dev_put(x)
3986+# define ipsec_dev_hold(x)
3987+#endif /* NETDEV_23 */
3988+
3989+#ifndef SPINLOCK
3990+# include <linux/bios32.h>
3991+ /* simulate spin locks and read/write locks */
3992+ typedef struct {
3993+ volatile char lock;
3994+ } spinlock_t;
3995+
3996+ typedef struct {
3997+ volatile unsigned int lock;
3998+ } rwlock_t;
3999+
4000+# define spin_lock_init(x) { (x)->lock = 0;}
4001+# define rw_lock_init(x) { (x)->lock = 0; }
4002+
4003+# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
4004+# define spin_lock_irq(x) { cli(); spin_lock(x);}
4005+# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
4006+
4007+# define spin_unlock(x) { (x)->lock=0;}
4008+# define spin_unlock_irq(x) { spin_unlock(x); sti();}
4009+# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
4010+
4011+# define read_lock(x) spin_lock(x)
4012+# define read_lock_irq(x) spin_lock_irq(x)
4013+# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
4014+
4015+# define read_unlock(x) spin_unlock(x)
4016+# define read_unlock_irq(x) spin_unlock_irq(x)
4017+# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
4018+
4019+# define write_lock(x) spin_lock(x)
4020+# define write_lock_irq(x) spin_lock_irq(x)
4021+# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
4022+
4023+# define write_unlock(x) spin_unlock(x)
4024+# define write_unlock_irq(x) spin_unlock_irq(x)
4025+# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
4026+#endif /* !SPINLOCK */
4027+
4028+#ifndef SPINLOCK_23
4029+# define spin_lock_bh(x) spin_lock_irq(x)
4030+# define spin_unlock_bh(x) spin_unlock_irq(x)
4031+
4032+# define read_lock_bh(x) read_lock_irq(x)
4033+# define read_unlock_bh(x) read_unlock_irq(x)
4034+
4035+# define write_lock_bh(x) write_lock_irq(x)
4036+# define write_unlock_bh(x) write_unlock_irq(x)
4037+#endif /* !SPINLOCK_23 */
4038+
4039+#ifndef HAVE_NETDEV_PRINTK
4040+#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
4041+ printk(sevlevel "%s: " format , netdev->name , ## arg)
4042+#endif
4043+
4044+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0)
4045+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4046+#include "openswan/ipsec_kern24.h"
4047+#else
4048+#error "kernels before 2.4 are not supported at this time"
4049+#endif
4050+#endif
4051+
4052+
4053+#endif /* _OPENSWAN_KVERSIONS_H */
4054+
4055+/*
4056+ * $Log: ipsec_kversion.h,v $
4057+ * Revision 1.15.2.21 2008-02-17 20:35:35 paul
4058+ * enable HAVE_NEW_SKB_LINEARIZE for Suse Linux SLES10 SP1
4059+ *
4060+ * Revision 1.15.2.20 2007-11-16 06:16:10 paul
4061+ * Fix brackets on SKB_RESET_NFCT case
4062+ *
4063+ * Revision 1.15.2.19 2007-11-16 06:01:27 paul
4064+ * On 2.6.23+, sk->nfct is part of skbut only when CONFIG_NF_CONNTRACK or
4065+ * CONFIG_NF_CONNTRACK_MODUE is set, where previously this was handled with
4066+ * CONFIG_NETFILTER.
4067+ *
4068+ * Revision 1.15.2.18 2007-11-07 14:17:56 paul
4069+ * Xen modifies skb structures, so xen kernels < 2.6.18 need to have
4070+ * HAVE_NEW_SKB_LINEARIZE defined.
4071+ *
4072+ * Revision 1.15.2.17 2007-10-31 19:57:40 paul
4073+ * type of sock.sk_stamp changed from timeval to ktime [dhr]
4074+ *
4075+ * Revision 1.15.2.16 2007-10-30 22:17:02 paul
4076+ * Move the define for ktime_to_timeval() from "not 2.6.22" to "< 2.6.16",
4077+ * where it belongs.
4078+ *
4079+ * Revision 1.15.2.15 2007-10-30 21:44:00 paul
4080+ * added a backport definition for define skb_end_pointer [dhr]
4081+ *
4082+ * Revision 1.15.2.14 2007-10-28 00:26:03 paul
4083+ * Start of fix for 2.6.22+ kernels and skb_tail_pointer()
4084+ *
4085+ * Revision 1.15.2.13 2007/09/05 02:28:27 paul
4086+ * Patch by David McCullough for 2.6.22 compatibility (HAVE_KERNEL_TSTAMP,
4087+ * HAVE_DEV_NEXT and other header surgery)
4088+ *
4089+ * Revision 1.15.2.12 2007/08/10 01:40:49 paul
4090+ * Fix for sock_unregister for 2.6.19 by Sergeil
4091+ *
4092+ * Revision 1.15.2.11 2007/02/20 03:53:16 paul
4093+ * Added comment, made layout consistent with other checks.
4094+ *
4095+ * Revision 1.15.2.10 2007/02/16 19:08:12 paul
4096+ * Fix for compiling on 2.6.20 (nfmark is now called mark in sk_buff)
4097+ *
4098+ * Revision 1.15.2.9 2006/07/29 05:00:40 paul
4099+ * Added HAVE_NEW_SKB_LINEARIZE for 2.6.18+ kernels where skb_linearize
4100+ * only takes 1 argument.
4101+ *
4102+ * Revision 1.15.2.8 2006/05/01 14:31:52 mcr
4103+ * FREESWAN->OPENSWAN in #ifdef.
4104+ *
4105+ * Revision 1.15.2.7 2006/01/11 02:02:59 mcr
4106+ * updated patches and DEFAULT_TTL code to work
4107+ *
4108+ * Revision 1.15.2.6 2006/01/03 19:25:02 ken
4109+ * Remove duplicated #ifdef for TTL fix - bad patch
4110+ *
4111+ * Revision 1.15.2.5 2006/01/03 18:06:33 ken
4112+ * Fix for missing sysctl default ttl
4113+ *
4114+ * Revision 1.15.2.4 2005/11/27 21:40:14 paul
4115+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
4116+ * in for klips as module.
4117+ *
4118+ * Revision 1.15.2.3 2005/11/22 04:11:52 ken
4119+ * Backport fixes for 2.6.14 kernels from HEAD
4120+ *
4121+ * Revision 1.15.2.2 2005/09/01 01:57:19 paul
4122+ * michael's fixes for 2.6.13 from head
4123+ *
4124+ * Revision 1.15.2.1 2005/08/27 23:13:48 paul
4125+ * Fix for:
4126+ * 7 weeks ago: [NET]: Remove unused security member in sk_buff
4127+ * changeset 4280: 328ea53f5fee
4128+ * parent 4279: beb0afb0e3f8
4129+ * author: Thomas Graf <tgraf@suug.ch>
4130+ * date: Tue Jul 5 21:12:44 2005
4131+ * 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
4132+ *
4133+ * This should fix compilation on 2.6.13(rc) kernels
4134+ *
4135+ * Revision 1.15 2005/07/19 20:02:15 mcr
4136+ * sk_alloc() interface change.
4137+ *
4138+ * Revision 1.14 2005/07/08 16:20:05 mcr
4139+ * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
4140+ *
4141+ * Revision 1.13 2005/05/20 03:19:18 mcr
4142+ * modifications for use on 2.4.30 kernel, with backported
4143+ * printk_ratelimit(). all warnings removed.
4144+ *
4145+ * Revision 1.12 2005/04/13 22:46:21 mcr
4146+ * note that KLIPS does not work on Linux 2.0.
4147+ *
4148+ * Revision 1.11 2004/09/13 02:22:26 mcr
4149+ * #define inet_protocol if necessary.
4150+ *
4151+ * Revision 1.10 2004/08/03 18:17:15 mcr
4152+ * in 2.6, use "net_device" instead of #define device->net_device.
4153+ * this probably breaks 2.0 compiles.
4154+ *
4155+ * Revision 1.9 2004/04/05 19:55:05 mcr
4156+ * Moved from linux/include/freeswan/ipsec_kversion.h,v
4157+ *
4158+ * Revision 1.8 2003/12/13 19:10:16 mcr
4159+ * refactored rcv and xmit code - same as FS 2.05.
4160+ *
4161+ * Revision 1.7 2003/07/31 22:48:08 mcr
4162+ * derive NET25-ness from presence of NETLINK_XFRM macro.
4163+ *
4164+ * Revision 1.6 2003/06/24 20:22:32 mcr
4165+ * added new global: ipsecdevices[] so that we can keep track of
4166+ * the ipsecX devices. They will be referenced with dev_hold(),
4167+ * so 2.2 may need this as well.
4168+ *
4169+ * Revision 1.5 2003/04/03 17:38:09 rgb
4170+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4171+ *
4172+ * Revision 1.4 2002/04/24 07:36:46 mcr
4173+ * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
4174+ *
4175+ * Revision 1.3 2002/04/12 03:21:17 mcr
4176+ * three parameter version of ip_select_ident appears first
4177+ * in 2.4.2 (RH7.1) not 2.4.4.
4178+ *
4179+ * Revision 1.2 2002/03/08 21:35:22 rgb
4180+ * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
4181+ * 2.4.9. (Andreas Piesk).
4182+ *
4183+ * Revision 1.1 2002/01/29 02:11:42 mcr
4184+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
4185+ * updating of IPv6 structures to match latest in6.h version.
4186+ * removed dead code from freeswan.h that also duplicated kversions.h
4187+ * code.
4188+ *
4189+ *
4190+ */
4191--- /dev/null Tue Mar 11 13:02:56 2003
4192+++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004
4193@@ -0,0 +1,112 @@
4194+/*
4195+ * Definitions relevant to IPSEC lifetimes
4196+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4197+ * and Michael Richardson <mcr@freeswan.org>
4198+ *
4199+ * This program is free software; you can redistribute it and/or modify it
4200+ * under the terms of the GNU General Public License as published by the
4201+ * Free Software Foundation; either version 2 of the License, or (at your
4202+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4203+ *
4204+ * This program is distributed in the hope that it will be useful, but
4205+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4206+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4207+ * for more details.
4208+ *
4209+ * RCSID $Id: ipsec_life.h,v 1.4 2004-04-05 19:55:05 mcr Exp $
4210+ *
4211+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
4212+ *
4213+ */
4214+
4215+/*
4216+ * This file describes the book keeping fields for the
4217+ * IPsec Security Association Structure. ("ipsec_sa")
4218+ *
4219+ * This structure is never allocated directly by kernel code,
4220+ * (it is always a static/auto or is part of a structure)
4221+ * so it does not have a reference count.
4222+ *
4223+ */
4224+
4225+#ifndef _IPSEC_LIFE_H_
4226+
4227+/*
4228+ * _count is total count.
4229+ * _hard is hard limit (kill SA after this number)
4230+ * _soft is soft limit (try to renew SA after this number)
4231+ * _last is used in some special cases.
4232+ *
4233+ */
4234+
4235+struct ipsec_lifetime64
4236+{
4237+ __u64 ipl_count;
4238+ __u64 ipl_soft;
4239+ __u64 ipl_hard;
4240+ __u64 ipl_last;
4241+};
4242+
4243+struct ipsec_lifetimes
4244+{
4245+ /* number of bytes processed */
4246+ struct ipsec_lifetime64 ipl_bytes;
4247+
4248+ /* number of packets processed */
4249+ struct ipsec_lifetime64 ipl_packets;
4250+
4251+ /* time since SA was added */
4252+ struct ipsec_lifetime64 ipl_addtime;
4253+
4254+ /* time since SA was first used */
4255+ struct ipsec_lifetime64 ipl_usetime;
4256+
4257+ /* from rfc2367:
4258+ * For CURRENT, the number of different connections,
4259+ * endpoints, or flows that the association has been
4260+ * allocated towards. For HARD and SOFT, the number of
4261+ * these the association may be allocated towards
4262+ * before it expires. The concept of a connection,
4263+ * flow, or endpoint is system specific.
4264+ *
4265+ * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
4266+ * They are maintained for PF_KEY compatibility.
4267+ */
4268+ struct ipsec_lifetime64 ipl_allocations;
4269+};
4270+
4271+enum ipsec_life_alive {
4272+ ipsec_life_harddied = -1,
4273+ ipsec_life_softdied = 0,
4274+ ipsec_life_okay = 1
4275+};
4276+
4277+enum ipsec_life_type {
4278+ ipsec_life_timebased = 1,
4279+ ipsec_life_countbased= 0
4280+};
4281+
4282+#define _IPSEC_LIFE_H_
4283+#endif /* _IPSEC_LIFE_H_ */
4284+
4285+
4286+/*
4287+ * $Log: ipsec_life.h,v $
4288+ * Revision 1.4 2004-04-05 19:55:05 mcr
4289+ * Moved from linux/include/freeswan/ipsec_life.h,v
4290+ *
4291+ * Revision 1.3 2002/04/24 07:36:46 mcr
4292+ * Moved from ./klips/net/ipsec/ipsec_life.h,v
4293+ *
4294+ * Revision 1.2 2001/11/26 09:16:14 rgb
4295+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4296+ *
4297+ * Revision 1.1.2.1 2001/09/25 02:25:58 mcr
4298+ * lifetime structure created and common functions created.
4299+ *
4300+ *
4301+ * Local variables:
4302+ * c-file-style: "linux"
4303+ * End:
4304+ *
4305+ */
4306--- /dev/null Tue Mar 11 13:02:56 2003
4307+++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004
4308@@ -0,0 +1,143 @@
4309+/*
4310+ * RCSID $Id: ipsec_md5h.h,v 1.10 2004-09-08 17:21:35 ken Exp $
4311+ */
4312+
4313+/*
4314+ * The rest of this file is Copyright RSA DSI. See the following comments
4315+ * for the full Copyright notice.
4316+ */
4317+
4318+#ifndef _IPSEC_MD5H_H_
4319+#define _IPSEC_MD5H_H_
4320+
4321+/* GLOBAL.H - RSAREF types and constants
4322+ */
4323+
4324+/* PROTOTYPES should be set to one if and only if the compiler supports
4325+ function argument prototyping.
4326+ The following makes PROTOTYPES default to 0 if it has not already
4327+ been defined with C compiler flags.
4328+ */
4329+#ifndef PROTOTYPES
4330+#define PROTOTYPES 1
4331+#endif /* !PROTOTYPES */
4332+
4333+/* POINTER defines a generic pointer type */
4334+typedef __u8 *POINTER;
4335+
4336+/* UINT2 defines a two byte word */
4337+typedef __u16 UINT2;
4338+
4339+/* UINT4 defines a four byte word */
4340+typedef __u32 UINT4;
4341+
4342+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
4343+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
4344+ returns an empty list.
4345+ */
4346+
4347+#if PROTOTYPES
4348+#define PROTO_LIST(list) list
4349+#else /* PROTOTYPES */
4350+#define PROTO_LIST(list) ()
4351+#endif /* PROTOTYPES */
4352+
4353+
4354+/* MD5.H - header file for MD5C.C
4355+ */
4356+
4357+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
4358+rights reserved.
4359+
4360+License to copy and use this software is granted provided that it
4361+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
4362+Algorithm" in all material mentioning or referencing this software
4363+or this function.
4364+
4365+License is also granted to make and use derivative works provided
4366+that such works are identified as "derived from the RSA Data
4367+Security, Inc. MD5 Message-Digest Algorithm" in all material
4368+mentioning or referencing the derived work.
4369+
4370+RSA Data Security, Inc. makes no representations concerning either
4371+the merchantability of this software or the suitability of this
4372+software for any particular purpose. It is provided "as is"
4373+without express or implied warranty of any kind.
4374+
4375+These notices must be retained in any copies of any part of this
4376+documentation and/or software.
4377+ */
4378+
4379+/* MD5 context. */
4380+typedef struct {
4381+ UINT4 state[4]; /* state (ABCD) */
4382+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
4383+ unsigned char buffer[64]; /* input buffer */
4384+} MD5_CTX;
4385+
4386+void osMD5Init PROTO_LIST ((void *));
4387+void osMD5Update PROTO_LIST
4388+ ((void *, unsigned char *, __u32));
4389+void osMD5Final PROTO_LIST ((unsigned char [16], void *));
4390+
4391+#endif /* _IPSEC_MD5H_H_ */
4392+
4393+/*
4394+ * $Log: ipsec_md5h.h,v $
4395+ * Revision 1.10 2004-09-08 17:21:35 ken
4396+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
4397+ *
4398+ * Revision 1.9 2004/04/05 19:55:05 mcr
4399+ * Moved from linux/include/freeswan/ipsec_md5h.h,v
4400+ *
4401+ * Revision 1.8 2002/09/10 01:45:09 mcr
4402+ * changed type of MD5_CTX and SHA1_CTX to void * so that
4403+ * the function prototypes would match, and could be placed
4404+ * into a pointer to a function.
4405+ *
4406+ * Revision 1.7 2002/04/24 07:36:46 mcr
4407+ * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
4408+ *
4409+ * Revision 1.6 1999/12/13 13:59:13 rgb
4410+ * Quick fix to argument size to Update bugs.
4411+ *
4412+ * Revision 1.5 1999/12/07 18:16:23 rgb
4413+ * Fixed comments at end of #endif lines.
4414+ *
4415+ * Revision 1.4 1999/04/06 04:54:26 rgb
4416+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
4417+ * patch shell fixes.
4418+ *
4419+ * Revision 1.3 1999/01/22 06:19:58 rgb
4420+ * 64-bit clean-up.
4421+ *
4422+ * Revision 1.2 1998/11/30 13:22:54 rgb
4423+ * Rationalised all the klips kernel file headers. They are much shorter
4424+ * now and won't conflict under RH5.2.
4425+ *
4426+ * Revision 1.1 1998/06/18 21:27:48 henry
4427+ * move sources from klips/src to klips/net/ipsec, to keep stupid
4428+ * kernel-build scripts happier in the presence of symlinks
4429+ *
4430+ * Revision 1.2 1998/04/23 20:54:03 rgb
4431+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
4432+ * verified.
4433+ *
4434+ * Revision 1.1 1998/04/09 03:04:21 henry
4435+ * sources moved up from linux/net/ipsec
4436+ * these two include files modified not to include others except in kernel
4437+ *
4438+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
4439+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
4440+ *
4441+ * Revision 0.4 1997/01/15 01:28:15 ji
4442+ * No changes.
4443+ *
4444+ * Revision 0.3 1996/11/20 14:48:53 ji
4445+ * Release update only.
4446+ *
4447+ * Revision 0.2 1996/11/02 00:18:33 ji
4448+ * First limited release.
4449+ *
4450+ *
4451+ */
4452--- /dev/null Tue Mar 11 13:02:56 2003
4453+++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004
4454@@ -0,0 +1,397 @@
4455+/*
4456+ * @(#) Openswan tunable paramaters
4457+ *
4458+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4459+ * and Michael Richardson <mcr@freeswan.org>
4460+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
4461+ *
4462+ * This program is free software; you can redistribute it and/or modify it
4463+ * under the terms of the GNU General Public License as published by the
4464+ * Free Software Foundation; either version 2 of the License, or (at your
4465+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4466+ *
4467+ * This program is distributed in the hope that it will be useful, but
4468+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4469+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4470+ * for more details.
4471+ *
4472+ * RCSID $Id: ipsec_param.h,v 1.29.6.5 2008-02-18 16:27:19 paul Exp $
4473+ *
4474+ */
4475+
4476+/*
4477+ * This file provides a set of #define's which may be tuned by various
4478+ * people/configurations. It keeps all compile-time tunables in one place.
4479+ *
4480+ * This file should be included before all other IPsec kernel-only files.
4481+ *
4482+ */
4483+
4484+#ifndef _IPSEC_PARAM_H_
4485+
4486+#ifdef __KERNEL__
4487+#include "ipsec_kversion.h"
4488+
4489+/* Set number of ipsecX virtual devices here. */
4490+/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
4491+/* It must also be reasonable so as not to overload the memory and CPU */
4492+/* constraints of the host. */
4493+#define IPSEC_NUM_IF 4
4494+/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
4495+/* With "ipsec" being 5 characters, that means 10 is the max field width */
4496+/* but machine memory and CPU constraints are not likely to tollerate */
4497+/* more than 3 digits. The default is one digit. */
4498+/* Update: userland scripts get upset if they can't find "ipsec0", so */
4499+/* for now, no "0"-padding should be used (which would have been helpful */
4500+/* to make text-searches work */
4501+#define IPSEC_DEV_FORMAT "ipsec%d"
4502+/* For, say, 500 virtual ipsec devices, I would recommend: */
4503+/* #define IPSEC_NUM_IF 500 */
4504+/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
4505+/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
4506+
4507+/* use dynamic ipsecX device allocation */
4508+#ifndef CONFIG_KLIPS_DYNDEV
4509+#define CONFIG_KLIPS_DYNDEV 1
4510+#endif /* CONFIG_KLIPS_DYNDEV */
4511+
4512+
4513+#ifdef CONFIG_KLIPS_BIGGATE
4514+# define SADB_HASHMOD 8069
4515+#else /* CONFIG_KLIPS_BIGGATE */
4516+# define SADB_HASHMOD 257
4517+#endif /* CONFIG_KLIPS_BIGGATE */
4518+#endif /* __KERNEL__ */
4519+
4520+/*
4521+ * This is for the SA reference table. This number is related to the
4522+ * maximum number of SAs that KLIPS can concurrently deal with, plus enough
4523+ * space for keeping expired SAs around.
4524+ *
4525+ * TABLE_MAX_WIDTH is the number of bits that we will use.
4526+ * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
4527+ *
4528+ */
4529+#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
4530+# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
4531+#endif
4532+
4533+#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
4534+# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
4535+#endif
4536+
4537+#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
4538+# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
4539+#endif
4540+
4541+#ifndef IPSEC_SA_REF_CODE
4542+# define IPSEC_SA_REF_CODE 1
4543+#endif
4544+
4545+#ifdef __KERNEL__
4546+/* This is defined for 2.4, but not 2.2.... */
4547+#ifndef ARPHRD_VOID
4548+# define ARPHRD_VOID 0xFFFF
4549+#endif
4550+
4551+/* always turn on IPIP mode */
4552+#ifndef CONFIG_KLIPS_IPIP
4553+#define CONFIG_KLIPS_IPIP 1
4554+#endif
4555+
4556+/*
4557+ * Worry about PROC_FS stuff
4558+ */
4559+#if defined(PROC_FS_2325)
4560+/* kernel 2.4 */
4561+# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
4562+# define IPSEC_PROCFS_DEBUG_NO_STATIC
4563+# define IPSEC_PROC_SUBDIRS
4564+#else
4565+/* kernel <2.4 */
4566+# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
4567+
4568+# ifndef PROC_NO_DUMMY
4569+# define IPSEC_PROC_LAST_ARG , int dummy
4570+# else
4571+# define IPSEC_PROC_LAST_ARG
4572+# endif /* !PROC_NO_DUMMY */
4573+#endif /* PROC_FS_2325 */
4574+
4575+#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
4576+/* GNU CPP specific! */
4577+# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
4578+#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
4579+
4580+#ifdef SPINLOCK
4581+# ifdef SPINLOCK_23
4582+# include <linux/spinlock.h> /* *lock* */
4583+# else /* SPINLOCK_23 */
4584+# include <asm/spinlock.h> /* *lock* */
4585+# endif /* SPINLOCK_23 */
4586+#endif /* SPINLOCK */
4587+
4588+#ifndef KLIPS_FIXES_DES_PARITY
4589+# define KLIPS_FIXES_DES_PARITY 1
4590+#endif /* !KLIPS_FIXES_DES_PARITY */
4591+
4592+/* we don't really want to print these unless there are really big problems */
4593+#ifndef KLIPS_DIVULGE_CYPHER_KEY
4594+# define KLIPS_DIVULGE_CYPHER_KEY 0
4595+#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
4596+
4597+#ifndef KLIPS_DIVULGE_HMAC_KEY
4598+# define KLIPS_DIVULGE_HMAC_KEY 0
4599+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4600+
4601+#ifndef IPSEC_DISALLOW_IPOPTIONS
4602+# define IPSEC_DISALLOW_IPOPTIONS 1
4603+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4604+
4605+/* extra toggles for regression testing */
4606+#ifdef CONFIG_KLIPS_REGRESS
4607+
4608+/*
4609+ * should pfkey_acquire() become 100% lossy?
4610+ *
4611+ */
4612+extern int sysctl_ipsec_regress_pfkey_lossage;
4613+#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
4614+# ifdef CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE
4615+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
4616+# endif /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4617+#else
4618+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4619+#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4620+
4621+#else /* CONFIG_KLIPS_REGRESS */
4622+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4623+
4624+#endif /* CONFIG_KLIPS_REGRESS */
4625+
4626+
4627+/*
4628+ * debugging routines.
4629+ */
4630+#define KLIPS_ERROR(flag, format, args...) if(printk_ratelimit() || flag) printk(KERN_ERR "KLIPS " format, ## args)
4631+#ifdef CONFIG_KLIPS_DEBUG
4632+#include <linux/ip.h>
4633+extern void ipsec_print_ip(struct iphdr *ip);
4634+
4635+ #define KLIPS_PRINT(flag, format, args...) \
4636+ ((flag) ? printk(KERN_INFO format , ## args) : 0)
4637+ #define KLIPS_PRINTMORE(flag, format, args...) \
4638+ ((flag) ? printk(format , ## args) : 0)
4639+ #define KLIPS_IP_PRINT(flag, ip) \
4640+ ((flag) ? ipsec_print_ip(ip) : 0)
4641+ #define KLIPS_SATOT(flag, sa, format, dst, dstlen) \
4642+ ((flag) ? satot(sa, format, dst, dstlen) : 0)
4643+#else /* CONFIG_KLIPS_DEBUG */
4644+ #define KLIPS_PRINT(flag, format, args...) do ; while(0)
4645+ #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
4646+ #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
4647+ #define KLIPS_SATOT(flag, sa, format, dst, dstlen) (0)
4648+#endif /* CONFIG_KLIPS_DEBUG */
4649+
4650+
4651+/*
4652+ * Stupid kernel API differences in APIs. Not only do some
4653+ * kernels not have ip_select_ident, but some have differing APIs,
4654+ * and SuSE has one with one parameter, but no way of checking to
4655+ * see what is really what.
4656+ */
4657+
4658+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
4659+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
4660+#else
4661+
4662+/* simplest case, nothing */
4663+#if !defined(IP_SELECT_IDENT)
4664+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
4665+#endif
4666+
4667+/* kernels > 2.3.37-ish */
4668+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
4669+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
4670+#endif
4671+
4672+/* kernels > 2.4.2 */
4673+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
4674+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
4675+#endif
4676+
4677+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
4678+
4679+/*
4680+ * make klips fail test:east-espiv-01.
4681+ * exploit is at testing/attacks/espiv
4682+ *
4683+ */
4684+#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
4685+
4686+
4687+/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
4688+#ifndef IP_FRAGMENT_LINEARIZE
4689+# define IP_FRAGMENT_LINEARIZE 0
4690+#endif /* IP_FRAGMENT_LINEARIZE */
4691+#endif /* __KERNEL__ */
4692+
4693+#ifdef NEED_INET_PROTOCOL
4694+#define inet_protocol net_protocol
4695+#endif
4696+
4697+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && CONFIG_IPSEC_NAT_TRAVERSAL
4698+#define NAT_TRAVERSAL 1
4699+#else
4700+/* let people either #undef, or #define = 0 it */
4701+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
4702+#undef CONFIG_IPSEC_NAT_TRAVERSAL
4703+#endif
4704+#endif
4705+
4706+#ifndef IPSEC_DEFAULT_TTL
4707+#define IPSEC_DEFAULT_TTL 64
4708+#endif
4709+
4710+#define _IPSEC_PARAM_H_
4711+#endif /* _IPSEC_PARAM_H_ */
4712+
4713+/*
4714+ * $Log: ipsec_param.h,v $
4715+ * Revision 1.29.6.5 2008-02-18 16:27:19 paul
4716+ * include linux/ip.h for struct iphdr (bug 814) - patch by sedrez
4717+ *
4718+ * Revision 1.29.6.4 2007/09/05 02:30:06 paul
4719+ * KLIPS_SATOT macro. Patch by David McCullough
4720+ *
4721+ * Revision 1.29.6.3 2006/05/01 14:32:31 mcr
4722+ * added KLIPS_ERROR and make sure that things work without CONFIG_KLIPS_REGRESS.
4723+ *
4724+ * Revision 1.29.6.2 2005/11/27 21:40:14 paul
4725+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
4726+ * in for klips as module.
4727+ *
4728+ * Revision 1.29.6.1 2005/08/12 16:24:18 ken
4729+ * Pull in NAT-T compile logic from HEAD
4730+ *
4731+ * Revision 1.29 2005/01/26 00:50:35 mcr
4732+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
4733+ * and make sure that NAT_TRAVERSAL is set as well to match
4734+ * userspace compiles of code.
4735+ *
4736+ * Revision 1.28 2004/09/13 15:50:15 mcr
4737+ * spell NEED_INET properly, not NET_INET.
4738+ *
4739+ * Revision 1.27 2004/09/13 02:21:45 mcr
4740+ * always turn on IPIP mode.
4741+ * #define inet_protocol if necessary.
4742+ *
4743+ * Revision 1.26 2004/08/17 03:25:43 mcr
4744+ * freeswan->openswan.
4745+ *
4746+ * Revision 1.25 2004/07/10 19:08:41 mcr
4747+ * CONFIG_IPSEC -> CONFIG_KLIPS.
4748+ *
4749+ * Revision 1.24 2004/04/05 19:55:06 mcr
4750+ * Moved from linux/include/freeswan/ipsec_param.h,v
4751+ *
4752+ * Revision 1.23 2003/12/13 19:10:16 mcr
4753+ * refactored rcv and xmit code - same as FS 2.05.
4754+ *
4755+ * Revision 1.22 2003/10/31 02:27:05 mcr
4756+ * pulled up port-selector patches and sa_id elimination.
4757+ *
4758+ * Revision 1.21.4.1 2003/10/29 01:10:19 mcr
4759+ * elimited "struct sa_id"
4760+ *
4761+ * Revision 1.21 2003/04/03 17:38:18 rgb
4762+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4763+ * Change indentation for readability.
4764+ *
4765+ * Revision 1.20 2003/03/14 08:09:26 rgb
4766+ * Fixed up CONFIG_IPSEC_DYNDEV definitions.
4767+ *
4768+ * Revision 1.19 2003/01/30 02:31:43 rgb
4769+ *
4770+ * Rename SAref table macro names for clarity.
4771+ *
4772+ * Revision 1.18 2002/09/30 19:06:26 rgb
4773+ * Reduce default table to 16 bits width.
4774+ *
4775+ * Revision 1.17 2002/09/20 15:40:29 rgb
4776+ * Define switch to activate new SAref code.
4777+ * Prefix macros with "IPSEC_".
4778+ * Rework saref freelist.
4779+ * Restrict some bits to kernel context for use to klips utils.
4780+ *
4781+ * Revision 1.16 2002/09/20 05:00:31 rgb
4782+ * Define switch to divulge hmac keys for debugging.
4783+ * Added IPOPTIONS switch.
4784+ *
4785+ * Revision 1.15 2002/09/19 02:34:24 mcr
4786+ * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
4787+ * to decide if we are to create /proc/net/ipsec/.
4788+ *
4789+ * Revision 1.14 2002/08/30 01:20:54 mcr
4790+ * reorganized 2.0/2.2/2.4 procfs support macro so match
4791+ * 2.4 values/typedefs.
4792+ *
4793+ * Revision 1.13 2002/07/28 22:03:28 mcr
4794+ * added some documentation to SA_REF_*
4795+ * turned on fix for ESPIV attack, now that we have the attack code.
4796+ *
4797+ * Revision 1.12 2002/07/26 08:48:31 rgb
4798+ * Added SA ref table code.
4799+ *
4800+ * Revision 1.11 2002/07/23 02:57:45 rgb
4801+ * Define ARPHRD_VOID for < 2.4 kernels.
4802+ *
4803+ * Revision 1.10 2002/05/27 21:37:28 rgb
4804+ * Set the defaults sanely for those adventurous enough to try more than 1
4805+ * digit of ipsec devices.
4806+ *
4807+ * Revision 1.9 2002/05/27 18:56:07 rgb
4808+ * Convert to dynamic ipsec device allocation.
4809+ *
4810+ * Revision 1.8 2002/04/24 07:36:47 mcr
4811+ * Moved from ./klips/net/ipsec/ipsec_param.h,v
4812+ *
4813+ * Revision 1.7 2002/04/20 00:12:25 rgb
4814+ * Added esp IV CBC attack fix, disabled.
4815+ *
4816+ * Revision 1.6 2002/01/29 02:11:42 mcr
4817+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
4818+ * updating of IPv6 structures to match latest in6.h version.
4819+ * removed dead code from freeswan.h that also duplicated kversions.h
4820+ * code.
4821+ *
4822+ * Revision 1.5 2002/01/28 19:22:01 mcr
4823+ * by default, turn off LINEARIZE option
4824+ * (let kversions.h turn it on)
4825+ *
4826+ * Revision 1.4 2002/01/20 20:19:36 mcr
4827+ * renamed option to IP_FRAGMENT_LINEARIZE.
4828+ *
4829+ * Revision 1.3 2002/01/12 02:57:25 mcr
4830+ * first regression test causes acquire messages to be lost
4831+ * 100% of the time. This is to help testing of pluto.
4832+ *
4833+ * Revision 1.2 2001/11/26 09:16:14 rgb
4834+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4835+ *
4836+ * Revision 1.1.2.3 2001/10/23 04:40:16 mcr
4837+ * added #define for DIVULGING session keys in debug output.
4838+ *
4839+ * Revision 1.1.2.2 2001/10/22 20:53:25 mcr
4840+ * added a define to control forcing of DES parity.
4841+ *
4842+ * Revision 1.1.2.1 2001/09/25 02:20:19 mcr
4843+ * many common kernel configuration questions centralized.
4844+ * more things remain that should be moved from freeswan.h.
4845+ *
4846+ *
4847+ * Local variables:
4848+ * c-file-style: "linux"
4849+ * End:
4850+ *
4851+ */
4852--- /dev/null Tue Mar 11 13:02:56 2003
4853+++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004
4854@@ -0,0 +1,217 @@
4855+#ifndef _IPSEC_POLICY_H
4856+/*
4857+ * policy interface file between pluto and applications
4858+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
4859+ *
4860+ * This library is free software; you can redistribute it and/or modify it
4861+ * under the terms of the GNU Library General Public License as published by
4862+ * the Free Software Foundation; either version 2 of the License, or (at your
4863+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
4864+ *
4865+ * This library is distributed in the hope that it will be useful, but
4866+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4867+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
4868+ * License for more details.
4869+ *
4870+ * RCSID $Id: ipsec_policy.h,v 1.7.6.1 2005-07-26 01:53:07 ken Exp $
4871+ */
4872+#define _IPSEC_POLICY_H /* seen it, no need to see it again */
4873+
4874+
4875+/*
4876+ * this file defines an interface between an application (or rather an
4877+ * application library) and a key/policy daemon. It provides for inquiries
4878+ * as to the current state of a connected socket, as well as for general
4879+ * questions.
4880+ *
4881+ * In general, the interface is defined as a series of functional interfaces,
4882+ * and the policy messages should be internal. However, because this is in
4883+ * fact an ABI between pieces of the system that may get compiled and revised
4884+ * seperately, this ABI must be public and revision controlled.
4885+ *
4886+ * It is expected that the daemon will always support previous versions.
4887+ */
4888+
4889+#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
4890+
4891+enum ipsec_policy_command {
4892+ IPSEC_CMD_QUERY_FD = 1,
4893+ IPSEC_CMD_QUERY_HOSTPAIR = 2,
4894+ IPSEC_CMD_QUERY_DSTONLY = 3,
4895+};
4896+
4897+struct ipsec_policy_msg_head {
4898+ u_int32_t ipm_version;
4899+ u_int32_t ipm_msg_len;
4900+ u_int32_t ipm_msg_type;
4901+ u_int32_t ipm_msg_seq;
4902+};
4903+
4904+enum ipsec_privacy_quality {
4905+ IPSEC_PRIVACY_NONE = 0,
4906+ IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
4907+ IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
4908+ IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
4909+ IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
4910+ IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
4911+ IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
4912+ IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
4913+ IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
4914+};
4915+
4916+enum ipsec_bandwidth_quality {
4917+ IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
4918+ IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
4919+ Good enough for telnet/ssh. */
4920+ IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
4921+ IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
4922+ offloaded, but latency/jitter may be bad */
4923+ IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
4924+};
4925+
4926+/* moved from programs/pluto/constants.h */
4927+/* IPsec AH transform values
4928+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
4929+ * and in http://www.iana.org/assignments/isakmp-registry
4930+ */
4931+enum ipsec_authentication_algo {
4932+ AH_MD5=2,
4933+ AH_SHA=3,
4934+ AH_DES=4,
4935+ AH_SHA2_256=5,
4936+ AH_SHA2_384=6,
4937+ AH_SHA2_512=7
4938+};
4939+
4940+/* IPsec ESP transform values
4941+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
4942+ * and from http://www.iana.org/assignments/isakmp-registry
4943+ */
4944+
4945+enum ipsec_cipher_algo {
4946+ ESP_reserved=0,
4947+ ESP_DES_IV64=1,
4948+ ESP_DES=2,
4949+ ESP_3DES=3,
4950+ ESP_RC5=4,
4951+ ESP_IDEA=5,
4952+ ESP_CAST=6,
4953+ ESP_BLOWFISH=7,
4954+ ESP_3IDEA=8,
4955+ ESP_DES_IV32=9,
4956+ ESP_RC4=10,
4957+ ESP_NULL=11,
4958+ ESP_AES=12, /* 128 bit AES */
4959+};
4960+
4961+/* IPCOMP transform values
4962+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
4963+ */
4964+
4965+enum ipsec_comp_algo {
4966+ IPCOMP_OUI= 1,
4967+ IPCOMP_DEFLATE= 2,
4968+ IPCOMP_LZS= 3,
4969+ IPCOMP_V42BIS= 4
4970+};
4971+
4972+/* Identification type values
4973+ * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
4974+ */
4975+
4976+enum ipsec_id_type {
4977+ ID_IMPOSSIBLE= (-2), /* private to Pluto */
4978+ ID_MYID= (-1), /* private to Pluto */
4979+ ID_NONE= 0, /* private to Pluto */
4980+ ID_IPV4_ADDR= 1,
4981+ ID_FQDN= 2,
4982+ ID_USER_FQDN= 3,
4983+ ID_IPV4_ADDR_SUBNET= 4,
4984+ ID_IPV6_ADDR= 5,
4985+ ID_IPV6_ADDR_SUBNET= 6,
4986+ ID_IPV4_ADDR_RANGE= 7,
4987+ ID_IPV6_ADDR_RANGE= 8,
4988+ ID_DER_ASN1_DN= 9,
4989+ ID_DER_ASN1_GN= 10,
4990+ ID_KEY_ID= 11
4991+};
4992+
4993+/* Certificate type values
4994+ * RFC 2408 ISAKMP, chapter 3.9
4995+ */
4996+enum ipsec_cert_type {
4997+ CERT_NONE= 0, /* none, or guess from file contents */
4998+ CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */
4999+ CERT_PGP= 2,
5000+ CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */
5001+ CERT_X509_SIGNATURE= 4,
5002+ CERT_X509_KEY_EXCHANGE= 5,
5003+ CERT_KERBEROS_TOKENS= 6,
5004+ CERT_CRL= 7,
5005+ CERT_ARL= 8,
5006+ CERT_SPKI= 9,
5007+ CERT_X509_ATTRIBUTE= 10,
5008+ CERT_RAW_RSA= 11, /* raw RSA from config file */
5009+};
5010+
5011+/* a SIG record in ASCII */
5012+struct ipsec_dns_sig {
5013+ char fqdn[256];
5014+ char dns_sig[768]; /* empty string if not signed */
5015+};
5016+
5017+struct ipsec_raw_key {
5018+ char id_name[256];
5019+ char fs_keyid[8];
5020+};
5021+
5022+struct ipsec_identity {
5023+ enum ipsec_id_type ii_type;
5024+ enum ipsec_cert_type ii_format;
5025+ union {
5026+ struct ipsec_dns_sig ipsec_dns_signed;
5027+ /* some thing for PGP */
5028+ /* some thing for PKIX */
5029+ struct ipsec_raw_key ipsec_raw_key;
5030+ } ii_credential;
5031+};
5032+
5033+#define IPSEC_MAX_CREDENTIALS 32
5034+
5035+struct ipsec_policy_cmd_query {
5036+ struct ipsec_policy_msg_head head;
5037+
5038+ /* Query section */
5039+ ip_address query_local; /* us */
5040+ ip_address query_remote; /* them */
5041+ u_int8_t proto; /* TCP, ICMP, etc. */
5042+ u_short src_port, dst_port;
5043+
5044+ /* Answer section */
5045+ enum ipsec_privacy_quality strength;
5046+ enum ipsec_bandwidth_quality bandwidth;
5047+ enum ipsec_authentication_algo auth_detail;
5048+ enum ipsec_cipher_algo esp_detail;
5049+ enum ipsec_comp_algo comp_detail;
5050+
5051+ int credential_count;
5052+
5053+ struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
5054+};
5055+
5056+#define IPSEC_POLICY_SOCKET "/var/run/pluto/pluto.info"
5057+
5058+/* prototypes */
5059+extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
5060+extern err_t ipsec_policy_init(void);
5061+extern err_t ipsec_policy_final(void);
5062+extern err_t ipsec_policy_readmsg(int policysock,
5063+ unsigned char *buf, size_t buflen);
5064+extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
5065+extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
5066+
5067+
5068+extern const char *ipsec_policy_version_code(void);
5069+extern const char *ipsec_policy_version_string(void);
5070+
5071+#endif /* _IPSEC_POLICY_H */
5072--- /dev/null Tue Mar 11 13:02:56 2003
5073+++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004
5074@@ -0,0 +1,199 @@
5075+/*
5076+ * @(#) prototypes for FreeSWAN functions
5077+ *
5078+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
5079+ * and Michael Richardson <mcr@freeswan.org>
5080+ *
5081+ * This program is free software; you can redistribute it and/or modify it
5082+ * under the terms of the GNU General Public License as published by the
5083+ * Free Software Foundation; either version 2 of the License, or (at your
5084+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5085+ *
5086+ * This program is distributed in the hope that it will be useful, but
5087+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5088+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5089+ * for more details.
5090+ *
5091+ * RCSID $Id: ipsec_proto.h,v 1.14 2005-04-29 04:50:03 mcr Exp $
5092+ *
5093+ */
5094+
5095+#ifndef _IPSEC_PROTO_H_
5096+
5097+#include "ipsec_param.h"
5098+
5099+/*
5100+ * This file is a kernel only file that declares prototypes for
5101+ * all intra-module function calls and global data structures.
5102+ *
5103+ * Include this file last.
5104+ *
5105+ */
5106+
5107+/* forward references */
5108+enum ipsec_direction;
5109+enum ipsec_life_type;
5110+struct ipsec_lifetime64;
5111+struct ident;
5112+struct sockaddr_encap;
5113+struct ipsec_sa;
5114+
5115+/* ipsec_init.c */
5116+extern struct prng ipsec_prng;
5117+
5118+/* ipsec_sa.c */
5119+extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
5120+extern spinlock_t tdb_lock;
5121+extern int ipsec_sadb_init(void);
5122+extern int ipsec_sadb_cleanup(__u8);
5123+
5124+extern struct ipsec_sa *ipsec_sa_alloc(int*error);
5125+
5126+
5127+extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *);
5128+extern int ipsec_sa_put(struct ipsec_sa *);
5129+extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
5130+extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
5131+extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
5132+
5133+extern int ipsec_sa_init(struct ipsec_sa *ipsp);
5134+extern int ipsec_sa_wipe(struct ipsec_sa *ipsp);
5135+
5136+/* debug declarations */
5137+
5138+/* ipsec_proc.c */
5139+extern int ipsec_proc_init(void);
5140+extern void ipsec_proc_cleanup(void);
5141+
5142+/* ipsec_rcv.c */
5143+extern int ipsec_rcv(struct sk_buff *skb);
5144+extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5145+
5146+/* ipsec_xmit.c */
5147+struct ipsec_xmit_state;
5148+extern enum ipsec_xmit_value ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
5149+extern enum ipsec_xmit_value ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
5150+extern void ipsec_print_ip(struct iphdr *ip);
5151+
5152+
5153+
5154+/* ipsec_radij.c */
5155+extern int ipsec_makeroute(struct sockaddr_encap *ea,
5156+ struct sockaddr_encap *em,
5157+ ip_said said,
5158+ uint32_t pid,
5159+ struct sk_buff *skb,
5160+ struct ident *ident_s,
5161+ struct ident *ident_d);
5162+
5163+extern int ipsec_breakroute(struct sockaddr_encap *ea,
5164+ struct sockaddr_encap *em,
5165+ struct sk_buff **first,
5166+ struct sk_buff **last);
5167+
5168+int ipsec_radijinit(void);
5169+int ipsec_cleareroutes(void);
5170+int ipsec_radijcleanup(void);
5171+
5172+/* ipsec_life.c */
5173+extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
5174+ const char *lifename,
5175+ const char *saname,
5176+ enum ipsec_life_type ilt,
5177+ enum ipsec_direction idir,
5178+ struct ipsec_sa *ips);
5179+
5180+
5181+extern int ipsec_lifetime_format(char *buffer,
5182+ int buflen,
5183+ char *lifename,
5184+ enum ipsec_life_type timebaselife,
5185+ struct ipsec_lifetime64 *lifetime);
5186+
5187+extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
5188+ __u64 newvalue);
5189+
5190+extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
5191+ __u64 newvalue);
5192+
5193+/* ipsec_snprintf.c */
5194+extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
5195+extern void ipsec_dmp_block(char *s, caddr_t bb, int len);
5196+
5197+
5198+/* ipsec_alg.c */
5199+extern int ipsec_alg_init(void);
5200+
5201+
5202+#ifdef CONFIG_KLIPS_DEBUG
5203+
5204+extern int debug_xform;
5205+extern int debug_eroute;
5206+extern int debug_spi;
5207+extern int debug_netlink;
5208+
5209+#endif /* CONFIG_KLIPS_DEBUG */
5210+
5211+
5212+
5213+
5214+#define _IPSEC_PROTO_H
5215+#endif /* _IPSEC_PROTO_H_ */
5216+
5217+/*
5218+ * $Log: ipsec_proto.h,v $
5219+ * Revision 1.14 2005-04-29 04:50:03 mcr
5220+ * prototypes for xmit and alg code.
5221+ *
5222+ * Revision 1.13 2005/04/17 03:46:07 mcr
5223+ * added prototypes for ipsec_rcv() routines.
5224+ *
5225+ * Revision 1.12 2005/04/14 20:28:37 mcr
5226+ * added additional prototypes.
5227+ *
5228+ * Revision 1.11 2005/04/14 01:16:28 mcr
5229+ * add prototypes for snprintf.
5230+ *
5231+ * Revision 1.10 2005/04/13 22:47:28 mcr
5232+ * make sure that forward references are available.
5233+ *
5234+ * Revision 1.9 2004/07/10 19:08:41 mcr
5235+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5236+ *
5237+ * Revision 1.8 2004/04/05 19:55:06 mcr
5238+ * Moved from linux/include/freeswan/ipsec_proto.h,v
5239+ *
5240+ * Revision 1.7 2003/10/31 02:27:05 mcr
5241+ * pulled up port-selector patches and sa_id elimination.
5242+ *
5243+ * Revision 1.6.30.1 2003/10/29 01:10:19 mcr
5244+ * elimited "struct sa_id"
5245+ *
5246+ * Revision 1.6 2002/05/23 07:13:48 rgb
5247+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
5248+ *
5249+ * Revision 1.5 2002/05/14 02:36:40 rgb
5250+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
5251+ * with "put" usage in the kernel.
5252+ *
5253+ * Revision 1.4 2002/04/24 07:36:47 mcr
5254+ * Moved from ./klips/net/ipsec/ipsec_proto.h,v
5255+ *
5256+ * Revision 1.3 2002/04/20 00:12:25 rgb
5257+ * Added esp IV CBC attack fix, disabled.
5258+ *
5259+ * Revision 1.2 2001/11/26 09:16:15 rgb
5260+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5261+ *
5262+ * Revision 1.1.2.1 2001/09/25 02:21:01 mcr
5263+ * ipsec_proto.h created to keep prototypes rather than deal with
5264+ * cyclic dependancies of structures and prototypes in .h files.
5265+ *
5266+ *
5267+ *
5268+ * Local variables:
5269+ * c-file-style: "linux"
5270+ * End:
5271+ *
5272+ */
5273+
5274--- /dev/null Tue Mar 11 13:02:56 2003
5275+++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004
5276@@ -0,0 +1,179 @@
5277+/*
5278+ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
5279+ * Copyright (C) 1996, 1997 John Ioannidis.
5280+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5281+ *
5282+ * This program is free software; you can redistribute it and/or modify it
5283+ * under the terms of the GNU General Public License as published by the
5284+ * Free Software Foundation; either version 2 of the License, or (at your
5285+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5286+ *
5287+ * This program is distributed in the hope that it will be useful, but
5288+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5289+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5290+ * for more details.
5291+ *
5292+ * RCSID $Id: ipsec_radij.h,v 1.22 2004-07-10 19:08:41 mcr Exp $
5293+ */
5294+
5295+#ifndef _IPSEC_RADIJ_H
5296+
5297+#include <openswan.h>
5298+
5299+int ipsec_walk(char *);
5300+
5301+int ipsec_rj_walker_procprint(struct radij_node *, void *);
5302+int ipsec_rj_walker_delete(struct radij_node *, void *);
5303+
5304+/* This structure is used to pass information between
5305+ * ipsec_eroute_get_info and ipsec_rj_walker_procprint
5306+ * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
5307+ */
5308+struct wsbuf
5309+{
5310+ /* from caller of ipsec_eroute_get_info: */
5311+ char *const buffer; /* start of buffer provided */
5312+ const int length; /* length of buffer provided */
5313+ const off_t offset; /* file position of first character of interest */
5314+ /* accumulated by ipsec_rj_walker_procprint: */
5315+ int len; /* number of character filled into buffer */
5316+ off_t begin; /* file position contained in buffer[0] (<=offset) */
5317+};
5318+
5319+extern struct radij_node_head *rnh;
5320+extern spinlock_t eroute_lock;
5321+
5322+struct eroute * ipsec_findroute(struct sockaddr_encap *);
5323+
5324+#define O1(x) (int)(((x)>>24)&0xff)
5325+#define O2(x) (int)(((x)>>16)&0xff)
5326+#define O3(x) (int)(((x)>>8)&0xff)
5327+#define O4(x) (int)(((x))&0xff)
5328+
5329+#ifdef CONFIG_KLIPS_DEBUG
5330+extern int debug_radij;
5331+void rj_dumptrees(void);
5332+
5333+#define DB_RJ_DUMPTREES 0x0001
5334+#define DB_RJ_FINDROUTE 0x0002
5335+#endif /* CONFIG_KLIPS_DEBUG */
5336+
5337+#define _IPSEC_RADIJ_H
5338+#endif
5339+
5340+/*
5341+ * $Log: ipsec_radij.h,v $
5342+ * Revision 1.22 2004-07-10 19:08:41 mcr
5343+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5344+ *
5345+ * Revision 1.21 2004/04/29 11:06:42 ken
5346+ * Last bits from 2.06 procfs updates
5347+ *
5348+ * Revision 1.20 2004/04/06 02:49:08 mcr
5349+ * pullup of algo code from alg-branch.
5350+ *
5351+ * Revision 1.19 2004/04/05 19:55:06 mcr
5352+ * Moved from linux/include/freeswan/ipsec_radij.h,v
5353+ *
5354+ * Revision 1.18 2002/04/24 07:36:47 mcr
5355+ * Moved from ./klips/net/ipsec/ipsec_radij.h,v
5356+ *
5357+ * Revision 1.17 2001/11/26 09:23:49 rgb
5358+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5359+ *
5360+ * Revision 1.16.2.1 2001/09/25 02:21:17 mcr
5361+ * ipsec_proto.h created to keep prototypes rather than deal with
5362+ * cyclic dependancies of structures and prototypes in .h files.
5363+ *
5364+ * Revision 1.16 2001/09/15 16:24:04 rgb
5365+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
5366+ *
5367+ * Revision 1.15 2001/09/14 16:58:37 rgb
5368+ * Added support for storing the first and last packets through a HOLD.
5369+ *
5370+ * Revision 1.14 2001/09/08 21:13:32 rgb
5371+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
5372+ *
5373+ * Revision 1.13 2001/06/14 19:35:09 rgb
5374+ * Update copyright date.
5375+ *
5376+ * Revision 1.12 2001/05/27 06:12:11 rgb
5377+ * Added structures for pid, packet count and last access time to eroute.
5378+ * Added packet count to beginning of /proc/net/ipsec_eroute.
5379+ *
5380+ * Revision 1.11 2000/09/08 19:12:56 rgb
5381+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
5382+ *
5383+ * Revision 1.10 1999/11/17 15:53:39 rgb
5384+ * Changed all occurrences of #include "../../../lib/freeswan.h"
5385+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
5386+ * klips/net/ipsec/Makefile.
5387+ *
5388+ * Revision 1.9 1999/10/01 00:01:23 rgb
5389+ * Added eroute structure locking.
5390+ *
5391+ * Revision 1.8 1999/04/11 00:28:59 henry
5392+ * GPL boilerplate
5393+ *
5394+ * Revision 1.7 1999/04/06 04:54:26 rgb
5395+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5396+ * patch shell fixes.
5397+ *
5398+ * Revision 1.6 1999/01/22 06:23:26 rgb
5399+ * Cruft clean-out.
5400+ *
5401+ * Revision 1.5 1998/10/25 02:42:08 rgb
5402+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
5403+ * argument to be able to transmit more infomation about errors.
5404+ *
5405+ * Revision 1.4 1998/10/19 14:44:29 rgb
5406+ * Added inclusion of freeswan.h.
5407+ * sa_id structure implemented and used: now includes protocol.
5408+ *
5409+ * Revision 1.3 1998/07/28 00:03:31 rgb
5410+ * Comment out temporary inet_nto4u() kluge.
5411+ *
5412+ * Revision 1.2 1998/07/14 18:22:00 rgb
5413+ * Add function to clear the eroute table.
5414+ *
5415+ * Revision 1.1 1998/06/18 21:27:49 henry
5416+ * move sources from klips/src to klips/net/ipsec, to keep stupid
5417+ * kernel-build scripts happier in the presence of symlinks
5418+ *
5419+ * Revision 1.5 1998/05/25 20:30:38 rgb
5420+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
5421+ *
5422+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
5423+ * add ipsec_rj_walker_delete.
5424+ *
5425+ * Revision 1.4 1998/05/21 13:02:56 rgb
5426+ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
5427+ * limit fix.
5428+ *
5429+ * Revision 1.3 1998/04/21 21:29:09 rgb
5430+ * Rearrange debug switches to change on the fly debug output from user
5431+ * space. Only kernel changes checked in at this time. radij.c was also
5432+ * changed to temporarily remove buggy debugging code in rj_delete causing
5433+ * an OOPS and hence, netlink device open errors.
5434+ *
5435+ * Revision 1.2 1998/04/14 17:30:39 rgb
5436+ * Fix up compiling errors for radij tree memory reclamation.
5437+ *
5438+ * Revision 1.1 1998/04/09 03:06:10 henry
5439+ * sources moved up from linux/net/ipsec
5440+ *
5441+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
5442+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5443+ *
5444+ * Revision 0.4 1997/01/15 01:28:15 ji
5445+ * No changes.
5446+ *
5447+ * Revision 0.3 1996/11/20 14:39:04 ji
5448+ * Minor cleanups.
5449+ * Rationalized debugging code.
5450+ *
5451+ * Revision 0.2 1996/11/02 00:18:33 ji
5452+ * First limited release.
5453+ *
5454+ *
5455+ */
5456--- /dev/null Tue Mar 11 13:02:56 2003
5457+++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004
5458@@ -0,0 +1,199 @@
5459+/*
5460+ *
5461+ * Copyright (C) 1996, 1997 John Ioannidis.
5462+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5463+ *
5464+ * This program is free software; you can redistribute it and/or modify it
5465+ * under the terms of the GNU General Public License as published by the
5466+ * Free Software Foundation; either version 2 of the License, or (at your
5467+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5468+ *
5469+ * This program is distributed in the hope that it will be useful, but
5470+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5471+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5472+ * for more details.
5473+ *
5474+ * RCSID $Id: ipsec_rcv.h,v 1.28.2.2 2006-10-06 21:39:26 paul Exp $
5475+ */
5476+
5477+#ifndef IPSEC_RCV_H
5478+#define IPSEC_RCV_H
5479+
5480+#include "openswan/ipsec_auth.h"
5481+
5482+#define DB_RX_PKTRX 0x0001
5483+#define DB_RX_PKTRX2 0x0002
5484+#define DB_RX_DMP 0x0004
5485+#define DB_RX_IPSA 0x0010
5486+#define DB_RX_XF 0x0020
5487+#define DB_RX_IPAD 0x0040
5488+#define DB_RX_INAU 0x0080
5489+#define DB_RX_OINFO 0x0100
5490+#define DB_RX_OINFO2 0x0200
5491+#define DB_RX_OH 0x0400
5492+#define DB_RX_REPLAY 0x0800
5493+
5494+#ifdef __KERNEL__
5495+/* struct options; */
5496+
5497+#define __NO_VERSION__
5498+#ifndef AUTOCONF_INCLUDED
5499+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
5500+#endif
5501+#ifdef CONFIG_MODULES
5502+#include <linux/module.h>
5503+#endif
5504+#include <linux/version.h>
5505+#include <openswan.h>
5506+
5507+#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
5508+
5509+struct ipsec_birth_reply {
5510+ int packet_template_len;
5511+ unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
5512+};
5513+
5514+extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
5515+extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
5516+
5517+enum ipsec_rcv_value {
5518+ IPSEC_RCV_LASTPROTO=1,
5519+ IPSEC_RCV_OK=0,
5520+ IPSEC_RCV_BADPROTO=-1,
5521+ IPSEC_RCV_BADLEN=-2,
5522+ IPSEC_RCV_ESP_BADALG=-3,
5523+ IPSEC_RCV_3DES_BADBLOCKING=-4,
5524+ IPSEC_RCV_ESP_DECAPFAIL=-5,
5525+ IPSEC_RCV_DECAPFAIL=-6,
5526+ IPSEC_RCV_SAIDNOTFOUND=-7,
5527+ IPSEC_RCV_IPCOMPALONE=-8,
5528+ IPSEC_RCV_IPCOMPFAILED=-10,
5529+ IPSEC_RCV_SAIDNOTLIVE=-11,
5530+ IPSEC_RCV_FAILEDINBOUND=-12,
5531+ IPSEC_RCV_LIFETIMEFAILED=-13,
5532+ IPSEC_RCV_BADAUTH=-14,
5533+ IPSEC_RCV_REPLAYFAILED=-15,
5534+ IPSEC_RCV_AUTHFAILED=-16,
5535+ IPSEC_RCV_REPLAYROLLED=-17,
5536+ IPSEC_RCV_BAD_DECRYPT=-18
5537+};
5538+
5539+struct ipsec_rcv_state {
5540+ struct sk_buff *skb;
5541+ struct net_device_stats *stats;
5542+ struct iphdr *ipp; /* the IP header */
5543+ struct ipsec_sa *ipsp; /* current SA being processed */
5544+ int len; /* length of packet */
5545+ int ilen; /* length of inner payload (-authlen) */
5546+ int authlen; /* how big is the auth data at end */
5547+ int hard_header_len; /* layer 2 size */
5548+ int iphlen; /* how big is IP header */
5549+ struct auth_alg *authfuncs;
5550+ ip_said said;
5551+ char sa[SATOT_BUF];
5552+ size_t sa_len;
5553+ __u8 next_header;
5554+ __u8 hash[AH_AMAX];
5555+ char ipsaddr_txt[ADDRTOA_BUF];
5556+ char ipdaddr_txt[ADDRTOA_BUF];
5557+ __u8 *octx;
5558+ __u8 *ictx;
5559+ int ictx_len;
5560+ int octx_len;
5561+ union {
5562+ struct {
5563+ struct esphdr *espp;
5564+ } espstuff;
5565+ struct {
5566+ struct ahhdr *ahp;
5567+ } ahstuff;
5568+ struct {
5569+ struct ipcomphdr *compp;
5570+ } ipcompstuff;
5571+ } protostuff;
5572+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
5573+ __u8 natt_type;
5574+ __u16 natt_sport;
5575+ __u16 natt_dport;
5576+ int natt_len;
5577+#endif
5578+};
5579+
5580+extern int
5581+#ifdef PROTO_HANDLER_SINGLE_PARM
5582+ipsec_rcv(struct sk_buff *skb);
5583+#else /* PROTO_HANDLER_SINGLE_PARM */
5584+ipsec_rcv(struct sk_buff *skb,
5585+ unsigned short xlen);
5586+#endif /* PROTO_HANDLER_SINGLE_PARM */
5587+
5588+#ifdef CONFIG_KLIPS_DEBUG
5589+extern int debug_rcv;
5590+#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
5591+#else
5592+#define ipsec_rcv_dmp(_x,_y, _z) do {} while(0)
5593+#endif /* CONFIG_KLIPS_DEBUG */
5594+
5595+extern int sysctl_ipsec_inbound_policy_check;
5596+#endif /* __KERNEL__ */
5597+
5598+extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5599+
5600+
5601+#endif /* IPSEC_RCV_H */
5602+
5603+/*
5604+ * $Log: ipsec_rcv.h,v $
5605+ * Revision 1.28.2.2 2006-10-06 21:39:26 paul
5606+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
5607+ * set. This is defined through autoconf.h which is included through the
5608+ * linux kernel build macros.
5609+ *
5610+ * Revision 1.28.2.1 2006/07/10 15:52:20 paul
5611+ * Fix for bug #642 by Bart Trojanowski
5612+ *
5613+ * Revision 1.28 2005/05/11 00:59:45 mcr
5614+ * do not call debug routines if !defined KLIPS_DEBUG.
5615+ *
5616+ * Revision 1.27 2005/04/29 04:59:46 mcr
5617+ * use ipsec_dmp_block.
5618+ *
5619+ * Revision 1.26 2005/04/13 22:48:35 mcr
5620+ * added comments, and removed some log.
5621+ * removed Linux 2.0 support.
5622+ *
5623+ * Revision 1.25 2005/04/08 18:25:37 mcr
5624+ * prototype klips26 encap receive function
5625+ *
5626+ * Revision 1.24 2004/08/20 21:45:37 mcr
5627+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5628+ * be 26sec compatible. But, some defines where changed.
5629+ *
5630+ * Revision 1.23 2004/08/03 18:17:40 mcr
5631+ * in 2.6, use "net_device" instead of #define device->net_device.
5632+ * this probably breaks 2.0 compiles.
5633+ *
5634+ * Revision 1.22 2004/07/10 19:08:41 mcr
5635+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5636+ *
5637+ * Revision 1.21 2004/04/06 02:49:08 mcr
5638+ * pullup of algo code from alg-branch.
5639+ *
5640+ * Revision 1.20 2004/04/05 19:55:06 mcr
5641+ * Moved from linux/include/freeswan/ipsec_rcv.h,v
5642+ *
5643+ * Revision 1.19 2003/12/15 18:13:09 mcr
5644+ * when compiling with NAT traversal, don't assume that the
5645+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
5646+ * is set.
5647+ *
5648+ * history elided 2005-04-12.
5649+ *
5650+ * Local Variables:
5651+ * c-basic-offset:8
5652+ * c-style:linux
5653+ * End:
5654+ *
5655+ */
5656+
5657+
5658--- /dev/null Tue Mar 11 13:02:56 2003
5659+++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004
5660@@ -0,0 +1,361 @@
5661+/*
5662+ * @(#) Definitions of IPsec Security Association (ipsec_sa)
5663+ *
5664+ * Copyright (C) 2001, 2002, 2003
5665+ * Richard Guy Briggs <rgb@freeswan.org>
5666+ * and Michael Richardson <mcr@freeswan.org>
5667+ *
5668+ * This program is free software; you can redistribute it and/or modify it
5669+ * under the terms of the GNU General Public License as published by the
5670+ * Free Software Foundation; either version 2 of the License, or (at your
5671+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5672+ *
5673+ * This program is distributed in the hope that it will be useful, but
5674+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5675+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5676+ * for more details.
5677+ *
5678+ * RCSID $Id: ipsec_sa.h,v 1.23.2.1 2007-09-05 02:31:15 paul Exp $
5679+ *
5680+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
5681+ *
5682+ */
5683+
5684+/*
5685+ * This file describes the IPsec Security Association Structure.
5686+ *
5687+ * This structure keeps track of a single transform that may be done
5688+ * to a set of packets. It can describe applying the transform or
5689+ * apply the reverse. (e.g. compression vs expansion). However, it
5690+ * only describes one at a time. To describe both, two structures would
5691+ * be used, but since the sides of the transform are performed
5692+ * on different machines typically it is usual to have only one side
5693+ * of each association.
5694+ *
5695+ */
5696+
5697+#ifndef _IPSEC_SA_H_
5698+
5699+#ifdef __KERNEL__
5700+#include "openswan/ipsec_stats.h"
5701+#include "openswan/ipsec_life.h"
5702+#include "openswan/ipsec_eroute.h"
5703+#endif /* __KERNEL__ */
5704+#include "openswan/ipsec_param.h"
5705+
5706+#include "pfkeyv2.h"
5707+
5708+
5709+/* SAs are held in a table.
5710+ * Entries in this table are referenced by IPsecSAref_t values.
5711+ * IPsecSAref_t values are conceptually subscripts. Because
5712+ * we want to allocate the table piece-meal, the subscripting
5713+ * is implemented with two levels, a bit like paged virtual memory.
5714+ * This representation mechanism is known as an Iliffe Vector.
5715+ *
5716+ * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
5717+ * pointers to subtables.
5718+ * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
5719+ * is a pointer to an SA.
5720+ *
5721+ * An IPsecSAref_t contains either an exceptional value (signified by the
5722+ * high-order bit being on) or a reference to a table entry. A table entry
5723+ * reference has the subtable subscript in the low-order
5724+ * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
5725+ * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
5726+ *
5727+ * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
5728+ * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
5729+ *
5730+ * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
5731+ * struct ipsec_sa*. The macro definition clearly shows the two-level
5732+ * access needed to find the SA pointer.
5733+ *
5734+ * The Maintable is allocated when IPsec is initialized.
5735+ * Each subtable is allocated when needed, but the first is allocated
5736+ * when IPsec is initialized.
5737+ *
5738+ * IPsecSAref_t is designed to be smaller than an NFmark so that
5739+ * they can be stored in NFmarks and still leave a few bits for other
5740+ * purposes. The spare bits are in the low order of the NFmark
5741+ * but in the high order of the IPsecSAref_t, so conversion is required.
5742+ * We pick the upper bits of NFmark on the theory that they are less likely to
5743+ * interfere with more pedestrian uses of nfmark.
5744+ */
5745+
5746+
5747+typedef unsigned short int IPsecRefTableUnusedCount;
5748+
5749+#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
5750+
5751+#ifdef __KERNEL__
5752+#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
5753+#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")"
5754+#endif
5755+
5756+#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5757+
5758+#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5759+#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5760+
5761+#ifdef CONFIG_NETFILTER
5762+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5763+#define nfmark mark
5764+#endif
5765+#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
5766+#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
5767+#else /* CONFIG_NETFILTER */
5768+/* just make it work for now, it doesn't matter, since there is no nfmark */
5769+#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
5770+#endif /* CONFIG_NETFILTER */
5771+#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
5772+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
5773+
5774+#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
5775+#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)
5776+#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
5777+
5778+#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5779+#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
5780+#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
5781+
5782+#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
5783+#define IPsecSA2SAref(x) ((x)->ips_ref)
5784+
5785+#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
5786+
5787+/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
5788+struct ipsec_sa
5789+{
5790+ IPsecSAref_t ips_ref; /* reference table entry number */
5791+ atomic_t ips_refcount; /* reference count for this struct */
5792+ struct ipsec_sa *ips_hnext; /* next in hash chain */
5793+ struct ipsec_sa *ips_inext; /* pointer to next xform */
5794+ struct ipsec_sa *ips_onext; /* pointer to prev xform */
5795+
5796+ struct ifnet *ips_rcvif; /* related rcv encap interface */
5797+
5798+ ip_said ips_said; /* SA ID */
5799+
5800+ __u32 ips_seq; /* seq num of msg that initiated this SA */
5801+ __u32 ips_pid; /* PID of process that initiated this SA */
5802+ __u8 ips_authalg; /* auth algorithm for this SA */
5803+ __u8 ips_encalg; /* enc algorithm for this SA */
5804+
5805+ struct ipsec_stats ips_errs;
5806+
5807+ __u8 ips_replaywin; /* replay window size */
5808+ enum sadb_sastate ips_state; /* state of SA */
5809+ __u32 ips_replaywin_lastseq; /* last pkt sequence num */
5810+ __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
5811+ __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
5812+
5813+ __u32 ips_flags; /* generic xform flags */
5814+
5815+
5816+ struct ipsec_lifetimes ips_life; /* lifetime records */
5817+
5818+ /* selector information */
5819+ __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */
5820+ struct sockaddr*ips_addr_s; /* src sockaddr */
5821+ struct sockaddr*ips_addr_d; /* dst sockaddr */
5822+ struct sockaddr*ips_addr_p; /* proxy sockaddr */
5823+ __u16 ips_addr_s_size;
5824+ __u16 ips_addr_d_size;
5825+ __u16 ips_addr_p_size;
5826+ ip_address ips_flow_s;
5827+ ip_address ips_flow_d;
5828+ ip_address ips_mask_s;
5829+ ip_address ips_mask_d;
5830+
5831+ __u16 ips_key_bits_a; /* size of authkey in bits */
5832+ __u16 ips_auth_bits; /* size of authenticator in bits */
5833+ __u16 ips_key_bits_e; /* size of enckey in bits */
5834+ __u16 ips_iv_bits; /* size of IV in bits */
5835+ __u8 ips_iv_size;
5836+ __u16 ips_key_a_size;
5837+ __u16 ips_key_e_size;
5838+
5839+ caddr_t ips_key_a; /* authentication key */
5840+ caddr_t ips_key_e; /* encryption key */
5841+ caddr_t ips_iv; /* Initialisation Vector */
5842+
5843+ struct ident ips_ident_s; /* identity src */
5844+ struct ident ips_ident_d; /* identity dst */
5845+
5846+ /* these are included even if CONFIG_KLIPS_IPCOMP is off */
5847+ __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
5848+ __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
5849+ __u64 ips_comp_ratio_cbytes; /* compressed bytes */
5850+ __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
5851+
5852+ /* these are included even if CONFIG_IPSEC_NAT_TRAVERSAL is off */
5853+ __u8 ips_natt_type;
5854+ __u8 ips_natt_reserved[3];
5855+ __u16 ips_natt_sport;
5856+ __u16 ips_natt_dport;
5857+
5858+ struct sockaddr *ips_natt_oa;
5859+ __u16 ips_natt_oa_size;
5860+ __u16 ips_natt_reserved2;
5861+
5862+#if 0
5863+ __u32 ips_sens_dpd;
5864+ __u8 ips_sens_sens_level;
5865+ __u8 ips_sens_sens_len;
5866+ __u64* ips_sens_sens_bitmap;
5867+ __u8 ips_sens_integ_level;
5868+ __u8 ips_sens_integ_len;
5869+ __u64* ips_sens_integ_bitmap;
5870+#endif
5871+ struct ipsec_alg_enc *ips_alg_enc;
5872+ struct ipsec_alg_auth *ips_alg_auth;
5873+ IPsecSAref_t ips_ref_rel;
5874+};
5875+
5876+struct IPsecSArefSubTable
5877+{
5878+ struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
5879+};
5880+
5881+struct ipsec_sadb {
5882+ struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
5883+ IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
5884+ int refFreeListHead;
5885+ int refFreeListTail;
5886+ IPsecSAref_t refFreeListCont;
5887+ IPsecSAref_t said_hash[SADB_HASHMOD];
5888+ spinlock_t sadb_lock;
5889+};
5890+
5891+extern struct ipsec_sadb ipsec_sadb;
5892+
5893+extern int ipsec_SAref_recycle(void);
5894+extern int ipsec_SArefSubTable_alloc(unsigned table);
5895+extern int ipsec_saref_freelist_init(void);
5896+extern int ipsec_sadb_init(void);
5897+extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
5898+extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
5899+extern int ipsec_sa_free(struct ipsec_sa* ips);
5900+extern int ipsec_sa_put(struct ipsec_sa *ips);
5901+extern int ipsec_sa_add(struct ipsec_sa *ips);
5902+extern int ipsec_sa_del(struct ipsec_sa *ips);
5903+extern int ipsec_sa_delchain(struct ipsec_sa *ips);
5904+extern int ipsec_sadb_cleanup(__u8 proto);
5905+extern int ipsec_sadb_free(void);
5906+extern int ipsec_sa_wipe(struct ipsec_sa *ips);
5907+#endif /* __KERNEL__ */
5908+
5909+enum ipsec_direction {
5910+ ipsec_incoming = 1,
5911+ ipsec_outgoing = 2
5912+};
5913+
5914+#define _IPSEC_SA_H_
5915+#endif /* _IPSEC_SA_H_ */
5916+
5917+/*
5918+ * $Log: ipsec_sa.h,v $
5919+ * Revision 1.23.2.1 2007-09-05 02:31:15 paul
5920+ * Fix an nfmark -> mark occurance. Patch by David McCullough
5921+ *
5922+ * Revision 1.23 2005/05/11 01:18:59 mcr
5923+ * do not change structure based upon options, to avoid
5924+ * too many #ifdef.
5925+ *
5926+ * Revision 1.22 2005/04/14 01:17:09 mcr
5927+ * change sadb_state to an enum.
5928+ *
5929+ * Revision 1.21 2004/08/20 21:45:37 mcr
5930+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5931+ * be 26sec compatible. But, some defines where changed.
5932+ *
5933+ * Revision 1.20 2004/07/10 19:08:41 mcr
5934+ * CONFIG_IPSEC -> CONFIG_KLIPS.
5935+ *
5936+ * Revision 1.19 2004/04/05 19:55:06 mcr
5937+ * Moved from linux/include/freeswan/ipsec_sa.h,v
5938+ *
5939+ * Revision 1.18 2004/04/05 19:41:05 mcr
5940+ * merged alg-branch code.
5941+ *
5942+ * Revision 1.17.2.1 2003/12/22 15:25:52 jjo
5943+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
5944+ *
5945+ * Revision 1.17 2003/12/10 01:20:06 mcr
5946+ * NAT-traversal patches to KLIPS.
5947+ *
5948+ * Revision 1.16 2003/10/31 02:27:05 mcr
5949+ * pulled up port-selector patches and sa_id elimination.
5950+ *
5951+ * Revision 1.15.4.1 2003/10/29 01:10:19 mcr
5952+ * elimited "struct sa_id"
5953+ *
5954+ * Revision 1.15 2003/05/11 00:53:09 mcr
5955+ * IPsecSAref_t and macros were moved to freeswan.h.
5956+ *
5957+ * Revision 1.14 2003/02/12 19:31:55 rgb
5958+ * Fixed bug in "file seen" machinery.
5959+ * Updated copyright year.
5960+ *
5961+ * Revision 1.13 2003/01/30 02:31:52 rgb
5962+ *
5963+ * Re-wrote comments describing SAref system for accuracy.
5964+ * Rename SAref table macro names for clarity.
5965+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
5966+ * Transmit error code through to caller from callee for better diagnosis of problems.
5967+ * Enclose all macro arguments in parens to avoid any possible obscrure bugs.
5968+ *
5969+ * Revision 1.12 2002/10/07 18:31:19 rgb
5970+ * Change comment to reflect the flexible nature of the main and sub-table widths.
5971+ * Added a counter for the number of unused entries in each subtable.
5972+ * Further break up host field type macro to host field.
5973+ * Move field width sanity checks to ipsec_sa.c
5974+ * Define a mask for an entire saref.
5975+ *
5976+ * Revision 1.11 2002/09/20 15:40:33 rgb
5977+ * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys.
5978+ * Fixed SAref/nfmark macros.
5979+ * Rework saref freeslist.
5980+ * Place all ipsec sadb globals into one struct.
5981+ * Restrict some bits to kernel context for use to klips utils.
5982+ *
5983+ * Revision 1.10 2002/09/20 05:00:34 rgb
5984+ * Update copyright date.
5985+ *
5986+ * Revision 1.9 2002/09/17 17:19:29 mcr
5987+ * make it compile even if there is no netfilter - we lost
5988+ * functionality, but it works, especially on 2.2.
5989+ *
5990+ * Revision 1.8 2002/07/28 22:59:53 mcr
5991+ * clarified/expanded one comment.
5992+ *
5993+ * Revision 1.7 2002/07/26 08:48:31 rgb
5994+ * Added SA ref table code.
5995+ *
5996+ * Revision 1.6 2002/05/31 17:27:48 rgb
5997+ * Comment fix.
5998+ *
5999+ * Revision 1.5 2002/05/27 18:55:03 rgb
6000+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
6001+ *
6002+ * Revision 1.4 2002/05/23 07:13:36 rgb
6003+ * Convert "usecount" to "refcount" to remove ambiguity.
6004+ *
6005+ * Revision 1.3 2002/04/24 07:36:47 mcr
6006+ * Moved from ./klips/net/ipsec/ipsec_sa.h,v
6007+ *
6008+ * Revision 1.2 2001/11/26 09:16:15 rgb
6009+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6010+ *
6011+ * Revision 1.1.2.1 2001/09/25 02:24:58 mcr
6012+ * struct tdb -> struct ipsec_sa.
6013+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
6014+ * ipsec_xform.c removed. header file still contains useful things.
6015+ *
6016+ *
6017+ * Local variables:
6018+ * c-file-style: "linux"
6019+ * End:
6020+ *
6021+ */
6022--- /dev/null Tue Mar 11 13:02:56 2003
6023+++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004
6024@@ -0,0 +1,79 @@
6025+/*
6026+ * RCSID $Id: ipsec_sha1.h,v 1.8 2004-04-05 19:55:07 mcr Exp $
6027+ */
6028+
6029+/*
6030+ * Here is the original comment from the distribution:
6031+
6032+SHA-1 in C
6033+By Steve Reid <steve@edmweb.com>
6034+100% Public Domain
6035+
6036+ * Adapted for use by the IPSEC code by John Ioannidis
6037+ */
6038+
6039+
6040+#ifndef _IPSEC_SHA1_H_
6041+#define _IPSEC_SHA1_H_
6042+
6043+typedef struct
6044+{
6045+ __u32 state[5];
6046+ __u32 count[2];
6047+ __u8 buffer[64];
6048+} SHA1_CTX;
6049+
6050+void SHA1Transform(__u32 state[5], __u8 buffer[64]);
6051+void SHA1Init(void *context);
6052+void SHA1Update(void *context, unsigned char *data, __u32 len);
6053+void SHA1Final(unsigned char digest[20], void *context);
6054+
6055+
6056+#endif /* _IPSEC_SHA1_H_ */
6057+
6058+/*
6059+ * $Log: ipsec_sha1.h,v $
6060+ * Revision 1.8 2004-04-05 19:55:07 mcr
6061+ * Moved from linux/include/freeswan/ipsec_sha1.h,v
6062+ *
6063+ * Revision 1.7 2002/09/10 01:45:09 mcr
6064+ * changed type of MD5_CTX and SHA1_CTX to void * so that
6065+ * the function prototypes would match, and could be placed
6066+ * into a pointer to a function.
6067+ *
6068+ * Revision 1.6 2002/04/24 07:36:47 mcr
6069+ * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
6070+ *
6071+ * Revision 1.5 1999/12/13 13:59:13 rgb
6072+ * Quick fix to argument size to Update bugs.
6073+ *
6074+ * Revision 1.4 1999/12/07 18:16:23 rgb
6075+ * Fixed comments at end of #endif lines.
6076+ *
6077+ * Revision 1.3 1999/04/06 04:54:27 rgb
6078+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
6079+ * patch shell fixes.
6080+ *
6081+ * Revision 1.2 1998/11/30 13:22:54 rgb
6082+ * Rationalised all the klips kernel file headers. They are much shorter
6083+ * now and won't conflict under RH5.2.
6084+ *
6085+ * Revision 1.1 1998/06/18 21:27:50 henry
6086+ * move sources from klips/src to klips/net/ipsec, to keep stupid
6087+ * kernel-build scripts happier in the presence of symlinks
6088+ *
6089+ * Revision 1.2 1998/04/23 20:54:05 rgb
6090+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
6091+ * verified.
6092+ *
6093+ * Revision 1.1 1998/04/09 03:04:21 henry
6094+ * sources moved up from linux/net/ipsec
6095+ * these two include files modified not to include others except in kernel
6096+ *
6097+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
6098+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6099+ *
6100+ * Revision 0.4 1997/01/15 01:28:15 ji
6101+ * New transform
6102+ *
6103+ */
6104--- /dev/null Tue Mar 11 13:02:56 2003
6105+++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004
6106@@ -0,0 +1,76 @@
6107+/*
6108+ * @(#) definition of ipsec_stats structure
6109+ *
6110+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
6111+ * and Michael Richardson <mcr@freeswan.org>
6112+ *
6113+ * This program is free software; you can redistribute it and/or modify it
6114+ * under the terms of the GNU General Public License as published by the
6115+ * Free Software Foundation; either version 2 of the License, or (at your
6116+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6117+ *
6118+ * This program is distributed in the hope that it will be useful, but
6119+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6120+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6121+ * for more details.
6122+ *
6123+ * RCSID $Id: ipsec_stats.h,v 1.7 2005-04-14 01:17:45 mcr Exp $
6124+ *
6125+ */
6126+
6127+/*
6128+ * This file describes the errors/statistics that FreeSWAN collects.
6129+ */
6130+
6131+#ifndef _IPSEC_STATS_H_
6132+
6133+struct ipsec_stats {
6134+ __u32 ips_alg_errs; /* number of algorithm errors */
6135+ __u32 ips_auth_errs; /* # of authentication errors */
6136+ __u32 ips_encsize_errs; /* # of encryption size errors*/
6137+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
6138+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
6139+};
6140+
6141+#define _IPSEC_STATS_H_
6142+#endif /* _IPSEC_STATS_H_ */
6143+
6144+/*
6145+ * $Log: ipsec_stats.h,v $
6146+ * Revision 1.7 2005-04-14 01:17:45 mcr
6147+ * add prototypes for snprintf.
6148+ *
6149+ * Revision 1.6 2004/04/05 19:55:07 mcr
6150+ * Moved from linux/include/freeswan/ipsec_stats.h,v
6151+ *
6152+ * Revision 1.5 2004/04/05 19:41:05 mcr
6153+ * merged alg-branch code.
6154+ *
6155+ * Revision 1.4 2004/03/28 20:27:19 paul
6156+ * Included tested and confirmed fixes mcr made and dhr verified for
6157+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
6158+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
6159+ * dhr. (thanks dhr!)
6160+ *
6161+ * Revision 1.4 2004/03/24 01:58:31 mcr
6162+ * sprintf->snprintf for formatting into proc buffer.
6163+ *
6164+ * Revision 1.3.34.1 2004/04/05 04:30:46 mcr
6165+ * patches for alg-branch to compile/work with 2.x openswan
6166+ *
6167+ * Revision 1.3 2002/04/24 07:36:47 mcr
6168+ * Moved from ./klips/net/ipsec/ipsec_stats.h,v
6169+ *
6170+ * Revision 1.2 2001/11/26 09:16:16 rgb
6171+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6172+ *
6173+ * Revision 1.1.2.1 2001/09/25 02:27:00 mcr
6174+ * statistics moved to seperate structure.
6175+ *
6176+ *
6177+ *
6178+ * Local variables:
6179+ * c-file-style: "linux"
6180+ * End:
6181+ *
6182+ */
6183--- /dev/null Tue Mar 11 13:02:56 2003
6184+++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004
6185@@ -0,0 +1,280 @@
6186+/*
6187+ * IPSEC tunneling code
6188+ * Copyright (C) 1996, 1997 John Ioannidis.
6189+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6190+ *
6191+ * This program is free software; you can redistribute it and/or modify it
6192+ * under the terms of the GNU General Public License as published by the
6193+ * Free Software Foundation; either version 2 of the License, or (at your
6194+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6195+ *
6196+ * This program is distributed in the hope that it will be useful, but
6197+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6198+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6199+ * for more details.
6200+ *
6201+ * RCSID $Id: ipsec_tunnel.h,v 1.33 2005-06-04 16:06:05 mcr Exp $
6202+ */
6203+
6204+
6205+#ifdef NET_21
6206+# define DEV_QUEUE_XMIT(skb, device, pri) {\
6207+ skb->dev = device; \
6208+ neigh_compat_output(skb); \
6209+ /* skb->dst->output(skb); */ \
6210+ }
6211+# define ICMP_SEND(skb_in, type, code, info, dev) \
6212+ icmp_send(skb_in, type, code, htonl(info))
6213+# define IP_SEND(skb, dev) \
6214+ ip_send(skb);
6215+#else /* NET_21 */
6216+# define DEV_QUEUE_XMIT(skb, device, pri) {\
6217+ dev_queue_xmit(skb, device, pri); \
6218+ }
6219+# define ICMP_SEND(skb_in, type, code, info, dev) \
6220+ icmp_send(skb_in, type, code, info, dev)
6221+# define IP_SEND(skb, dev) \
6222+ if(ntohs(iph->tot_len) > physmtu) { \
6223+ ip_fragment(NULL, skb, dev, 0); \
6224+ ipsec_kfree_skb(skb); \
6225+ } else { \
6226+ dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
6227+ }
6228+#endif /* NET_21 */
6229+
6230+
6231+/*
6232+ * Heavily based on drivers/net/new_tunnel.c. Lots
6233+ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
6234+ */
6235+
6236+struct ipsectunnelconf
6237+{
6238+ __u32 cf_cmd;
6239+ union
6240+ {
6241+ char cfu_name[12];
6242+ } cf_u;
6243+#define cf_name cf_u.cfu_name
6244+};
6245+
6246+#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
6247+#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
6248+#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
6249+
6250+#ifdef __KERNEL__
6251+#include <linux/version.h>
6252+#ifndef KERNEL_VERSION
6253+# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
6254+#endif
6255+struct ipsecpriv
6256+{
6257+ struct sk_buff_head sendq;
6258+ struct net_device *dev;
6259+ struct wait_queue *wait_queue;
6260+ char locked;
6261+ int (*hard_start_xmit) (struct sk_buff *skb,
6262+ struct net_device *dev);
6263+ int (*hard_header) (struct sk_buff *skb,
6264+ struct net_device *dev,
6265+ unsigned short type,
6266+ void *daddr,
6267+ void *saddr,
6268+ unsigned len);
6269+#ifdef NET_21
6270+ int (*rebuild_header)(struct sk_buff *skb);
6271+#else /* NET_21 */
6272+ int (*rebuild_header)(void *buff, struct net_device *dev,
6273+ unsigned long raddr, struct sk_buff *skb);
6274+#endif /* NET_21 */
6275+ int (*set_mac_address)(struct net_device *dev, void *addr);
6276+#ifndef NET_21
6277+ void (*header_cache_bind)(struct hh_cache **hhp, struct net_device *dev,
6278+ unsigned short htype, __u32 daddr);
6279+#endif /* !NET_21 */
6280+ void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr);
6281+ struct net_device_stats *(*get_stats)(struct net_device *dev);
6282+ struct net_device_stats mystats;
6283+ int mtu; /* What is the desired MTU? */
6284+};
6285+
6286+extern char ipsec_tunnel_c_version[];
6287+
6288+extern struct net_device *ipsecdevices[IPSEC_NUM_IF];
6289+
6290+int ipsec_tunnel_init_devices(void);
6291+
6292+/* void */ int ipsec_tunnel_cleanup_devices(void);
6293+
6294+extern /* void */ int ipsec_init(void);
6295+
6296+extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev);
6297+extern struct net_device *ipsec_get_device(int inst);
6298+
6299+#ifdef CONFIG_KLIPS_DEBUG
6300+extern int debug_tunnel;
6301+extern int sysctl_ipsec_debug_verbose;
6302+#endif /* CONFIG_KLIPS_DEBUG */
6303+#endif /* __KERNEL__ */
6304+
6305+#ifdef CONFIG_KLIPS_DEBUG
6306+#define DB_TN_INIT 0x0001
6307+#define DB_TN_PROCFS 0x0002
6308+#define DB_TN_XMIT 0x0010
6309+#define DB_TN_OHDR 0x0020
6310+#define DB_TN_CROUT 0x0040
6311+#define DB_TN_OXFS 0x0080
6312+#define DB_TN_REVEC 0x0100
6313+#define DB_TN_ENCAP 0x0200
6314+#endif /* CONFIG_KLIPS_DEBUG */
6315+
6316+/*
6317+ * $Log: ipsec_tunnel.h,v $
6318+ * Revision 1.33 2005-06-04 16:06:05 mcr
6319+ * better patch for nat-t rcv-device code.
6320+ *
6321+ * Revision 1.32 2005/05/21 03:18:35 mcr
6322+ * added additional debug flag tunnelling.
6323+ *
6324+ * Revision 1.31 2004/08/03 18:18:02 mcr
6325+ * in 2.6, use "net_device" instead of #define device->net_device.
6326+ * this probably breaks 2.0 compiles.
6327+ *
6328+ * Revision 1.30 2004/07/10 19:08:41 mcr
6329+ * CONFIG_IPSEC -> CONFIG_KLIPS.
6330+ *
6331+ * Revision 1.29 2004/04/05 19:55:07 mcr
6332+ * Moved from linux/include/freeswan/ipsec_tunnel.h,v
6333+ *
6334+ * Revision 1.28 2003/06/24 20:22:32 mcr
6335+ * added new global: ipsecdevices[] so that we can keep track of
6336+ * the ipsecX devices. They will be referenced with dev_hold(),
6337+ * so 2.2 may need this as well.
6338+ *
6339+ * Revision 1.27 2003/04/03 17:38:09 rgb
6340+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
6341+ *
6342+ * Revision 1.26 2003/02/12 19:32:20 rgb
6343+ * Updated copyright year.
6344+ *
6345+ * Revision 1.25 2002/05/27 18:56:07 rgb
6346+ * Convert to dynamic ipsec device allocation.
6347+ *
6348+ * Revision 1.24 2002/04/24 07:36:48 mcr
6349+ * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
6350+ *
6351+ * Revision 1.23 2001/11/06 19:50:44 rgb
6352+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
6353+ * use also by pfkey_v2_parser.c
6354+ *
6355+ * Revision 1.22 2001/09/15 16:24:05 rgb
6356+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
6357+ *
6358+ * Revision 1.21 2001/06/14 19:35:10 rgb
6359+ * Update copyright date.
6360+ *
6361+ * Revision 1.20 2000/09/15 11:37:02 rgb
6362+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
6363+ * IPCOMP zlib deflate code.
6364+ *
6365+ * Revision 1.19 2000/09/08 19:12:56 rgb
6366+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6367+ *
6368+ * Revision 1.18 2000/07/28 13:50:54 rgb
6369+ * Changed enet_statistics to net_device_stats and added back compatibility
6370+ * for pre-2.1.19.
6371+ *
6372+ * Revision 1.17 1999/11/19 01:12:15 rgb
6373+ * Purge unneeded proc_info prototypes, now that static linking uses
6374+ * dynamic proc_info registration.
6375+ *
6376+ * Revision 1.16 1999/11/18 18:51:00 rgb
6377+ * Changed all device registrations for static linking to
6378+ * dynamic to reduce the number and size of patches.
6379+ *
6380+ * Revision 1.15 1999/11/18 04:14:21 rgb
6381+ * Replaced all kernel version macros to shorter, readable form.
6382+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
6383+ * Added Marc Boucher's 2.3.25 proc patches.
6384+ *
6385+ * Revision 1.14 1999/05/25 02:50:10 rgb
6386+ * Fix kernel version macros for 2.0.x static linking.
6387+ *
6388+ * Revision 1.13 1999/05/25 02:41:06 rgb
6389+ * Add ipsec_klipsdebug support for static linking.
6390+ *
6391+ * Revision 1.12 1999/05/05 22:02:32 rgb
6392+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
6393+ *
6394+ * Revision 1.11 1999/04/29 15:19:50 rgb
6395+ * Add return values to init and cleanup functions.
6396+ *
6397+ * Revision 1.10 1999/04/16 16:02:39 rgb
6398+ * Bump up macro to 4 ipsec I/Fs.
6399+ *
6400+ * Revision 1.9 1999/04/15 15:37:25 rgb
6401+ * Forward check changes from POST1_00 branch.
6402+ *
6403+ * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
6404+ * Backcheck from HEAD, pre1.0.
6405+ *
6406+ * Revision 1.8 1999/04/11 00:29:01 henry
6407+ * GPL boilerplate
6408+ *
6409+ * Revision 1.7 1999/04/06 04:54:28 rgb
6410+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
6411+ * patch shell fixes.
6412+ *
6413+ * Revision 1.6 1999/03/31 05:44:48 rgb
6414+ * Keep PMTU reduction private.
6415+ *
6416+ * Revision 1.5 1999/02/10 22:31:20 rgb
6417+ * Change rebuild_header member to reflect generality of link layer.
6418+ *
6419+ * Revision 1.4 1998/12/01 13:22:04 rgb
6420+ * Added support for debug printing of version info.
6421+ *
6422+ * Revision 1.3 1998/07/29 20:42:46 rgb
6423+ * Add a macro for clearing all tunnel devices.
6424+ * Rearrange structures and declarations for sharing with userspace.
6425+ *
6426+ * Revision 1.2 1998/06/25 20:01:45 rgb
6427+ * Make prototypes available for ipsec_init and ipsec proc_dir_entries
6428+ * for static linking.
6429+ *
6430+ * Revision 1.1 1998/06/18 21:27:50 henry
6431+ * move sources from klips/src to klips/net/ipsec, to keep stupid
6432+ * kernel-build scripts happier in the presence of symlinks
6433+ *
6434+ * Revision 1.3 1998/05/18 21:51:50 rgb
6435+ * Added macros for num of I/F's and a procfs debug switch.
6436+ *
6437+ * Revision 1.2 1998/04/21 21:29:09 rgb
6438+ * Rearrange debug switches to change on the fly debug output from user
6439+ * space. Only kernel changes checked in at this time. radij.c was also
6440+ * changed to temporarily remove buggy debugging code in rj_delete causing
6441+ * an OOPS and hence, netlink device open errors.
6442+ *
6443+ * Revision 1.1 1998/04/09 03:06:13 henry
6444+ * sources moved up from linux/net/ipsec
6445+ *
6446+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
6447+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6448+ *
6449+ * Revision 0.5 1997/06/03 04:24:48 ji
6450+ * Added transport mode.
6451+ * Changed the way routing is done.
6452+ * Lots of bug fixes.
6453+ *
6454+ * Revision 0.4 1997/01/15 01:28:15 ji
6455+ * No changes.
6456+ *
6457+ * Revision 0.3 1996/11/20 14:39:04 ji
6458+ * Minor cleanups.
6459+ * Rationalized debugging code.
6460+ *
6461+ * Revision 0.2 1996/11/02 00:18:33 ji
6462+ * First limited release.
6463+ *
6464+ *
6465+ */
6466--- /dev/null Tue Mar 11 13:02:56 2003
6467+++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004
6468@@ -0,0 +1,257 @@
6469+/*
6470+ * Definitions relevant to IPSEC transformations
6471+ * Copyright (C) 1996, 1997 John Ioannidis.
6472+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
6473+ * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
6474+ *
6475+ * This program is free software; you can redistribute it and/or modify it
6476+ * under the terms of the GNU General Public License as published by the
6477+ * Free Software Foundation; either version 2 of the License, or (at your
6478+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6479+ *
6480+ * This program is distributed in the hope that it will be useful, but
6481+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6482+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6483+ * for more details.
6484+ *
6485+ * RCSID $Id: ipsec_xform.h,v 1.41 2004-07-10 19:08:41 mcr Exp $
6486+ */
6487+
6488+#ifndef _IPSEC_XFORM_H_
6489+
6490+#include <openswan.h>
6491+
6492+#define XF_NONE 0 /* No transform set */
6493+#define XF_IP4 1 /* IPv4 inside IPv4 */
6494+#define XF_AHMD5 2 /* AH MD5 */
6495+#define XF_AHSHA 3 /* AH SHA */
6496+#define XF_ESP3DES 5 /* ESP DES3-CBC */
6497+#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
6498+#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
6499+#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
6500+#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
6501+#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
6502+#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
6503+#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
6504+#define XF_IP6 15 /* IPv6 inside IPv6 */
6505+#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
6506+
6507+#define XF_CLR 126 /* Clear SA table */
6508+#define XF_DEL 127 /* Delete SA */
6509+
6510+/* IPsec AH transform values
6511+ * RFC 2407
6512+ * draft-ietf-ipsec-doi-tc-mib-02.txt
6513+ */
6514+
6515+#define AH_NONE 0
6516+#define AH_MD5 2
6517+#define AH_SHA 3
6518+/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */
6519+#define AH_SHA2_256 5
6520+#define AH_SHA2_384 6
6521+#define AH_SHA2_512 7
6522+#define AH_RIPEMD 8
6523+#define AH_MAX 15
6524+
6525+/* IPsec ESP transform values */
6526+
6527+#define ESP_NONE 0
6528+#define ESP_DES 2
6529+#define ESP_3DES 3
6530+#define ESP_RC5 4
6531+#define ESP_IDEA 5
6532+#define ESP_CAST 6
6533+#define ESP_BLOWFISH 7
6534+#define ESP_3IDEA 8
6535+#define ESP_RC4 10
6536+#define ESP_NULL 11
6537+#define ESP_AES 12
6538+
6539+/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */
6540+#define ESP_MARS 249
6541+#define ESP_RC6 250
6542+#define ESP_SERPENT 252
6543+#define ESP_TWOFISH 253
6544+
6545+/* IPCOMP transform values */
6546+
6547+#define IPCOMP_NONE 0
6548+#define IPCOMP_OUI 1
6549+#define IPCOMP_DEFLAT 2
6550+#define IPCOMP_LZS 3
6551+#define IPCOMP_V42BIS 4
6552+
6553+#define XFT_AUTH 0x0001
6554+#define XFT_CONF 0x0100
6555+
6556+/* available if CONFIG_KLIPS_DEBUG is defined */
6557+#define DB_XF_INIT 0x0001
6558+
6559+#define PROTO2TXT(x) \
6560+ (x) == IPPROTO_AH ? "AH" : \
6561+ (x) == IPPROTO_ESP ? "ESP" : \
6562+ (x) == IPPROTO_IPIP ? "IPIP" : \
6563+ (x) == IPPROTO_COMP ? "COMP" : \
6564+ "UNKNOWN_proto"
6565+static inline const char *enc_name_id (unsigned id) {
6566+ static char buf[16];
6567+ snprintf(buf, sizeof(buf), "_ID%d", id);
6568+ return buf;
6569+}
6570+static inline const char *auth_name_id (unsigned id) {
6571+ static char buf[16];
6572+ snprintf(buf, sizeof(buf), "_ID%d", id);
6573+ return buf;
6574+}
6575+#define IPS_XFORM_NAME(x) \
6576+ PROTO2TXT((x)->ips_said.proto), \
6577+ (x)->ips_said.proto == IPPROTO_COMP ? \
6578+ ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
6579+ "_DEFLATE" : "_UNKNOWN_comp") : \
6580+ (x)->ips_encalg == ESP_NONE ? "" : \
6581+ (x)->ips_encalg == ESP_3DES ? "_3DES" : \
6582+ (x)->ips_encalg == ESP_AES ? "_AES" : \
6583+ (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
6584+ (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
6585+ enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
6586+ (x)->ips_authalg == AH_NONE ? "" : \
6587+ (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
6588+ (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
6589+ (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
6590+ (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
6591+ (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
6592+ auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
6593+
6594+#ifdef __KERNEL__
6595+struct ipsec_rcv_state;
6596+struct ipsec_xmit_state;
6597+
6598+struct xform_functions {
6599+ enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
6600+ struct sk_buff *skb);
6601+ enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
6602+
6603+ enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
6604+ struct sk_buff *skb,
6605+ __u32 *replay,
6606+ unsigned char **authenticator);
6607+ enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
6608+ struct sk_buff *skb);
6609+
6610+ enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
6611+ enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
6612+
6613+ enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
6614+ struct sk_buff *skb,
6615+ __u32 *replay,
6616+ unsigned char **authenticator);
6617+ enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
6618+ struct sk_buff *skb);
6619+ int xmit_headroom;
6620+ int xmit_needtailroom;
6621+};
6622+
6623+#endif /* __KERNEL__ */
6624+
6625+#ifdef CONFIG_KLIPS_DEBUG
6626+extern void ipsec_dmp(char *s, caddr_t bb, int len);
6627+#else /* CONFIG_KLIPS_DEBUG */
6628+#define ipsec_dmp(_x, _y, _z)
6629+#endif /* CONFIG_KLIPS_DEBUG */
6630+
6631+
6632+#define _IPSEC_XFORM_H_
6633+#endif /* _IPSEC_XFORM_H_ */
6634+
6635+/*
6636+ * $Log: ipsec_xform.h,v $
6637+ * Revision 1.41 2004-07-10 19:08:41 mcr
6638+ * CONFIG_IPSEC -> CONFIG_KLIPS.
6639+ *
6640+ * Revision 1.40 2004/04/06 02:49:08 mcr
6641+ * pullup of algo code from alg-branch.
6642+ *
6643+ * Revision 1.39 2004/04/05 19:55:07 mcr
6644+ * Moved from linux/include/freeswan/ipsec_xform.h,v
6645+ *
6646+ * Revision 1.38 2004/04/05 19:41:05 mcr
6647+ * merged alg-branch code.
6648+ *
6649+ * Revision 1.37 2003/12/13 19:10:16 mcr
6650+ * refactored rcv and xmit code - same as FS 2.05.
6651+ *
6652+ * Revision 1.36.34.1 2003/12/22 15:25:52 jjo
6653+ * Merged algo-0.8.1-rc11-test1 into alg-branch
6654+ *
6655+ * Revision 1.36 2002/04/24 07:36:48 mcr
6656+ * Moved from ./klips/net/ipsec/ipsec_xform.h,v
6657+ *
6658+ * Revision 1.35 2001/11/26 09:23:51 rgb
6659+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6660+ *
6661+ * Revision 1.33.2.1 2001/09/25 02:24:58 mcr
6662+ * struct tdb -> struct ipsec_sa.
6663+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
6664+ * ipsec_xform.c removed. header file still contains useful things.
6665+ *
6666+ * Revision 1.34 2001/11/06 19:47:17 rgb
6667+ * Changed lifetime_packets to uint32 from uint64.
6668+ *
6669+ * Revision 1.33 2001/09/08 21:13:34 rgb
6670+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
6671+ *
6672+ * Revision 1.32 2001/07/06 07:40:01 rgb
6673+ * Reformatted for readability.
6674+ * Added inbound policy checking fields for use with IPIP SAs.
6675+ *
6676+ * Revision 1.31 2001/06/14 19:35:11 rgb
6677+ * Update copyright date.
6678+ *
6679+ * Revision 1.30 2001/05/30 08:14:03 rgb
6680+ * Removed vestiges of esp-null transforms.
6681+ *
6682+ * Revision 1.29 2001/01/30 23:42:47 rgb
6683+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
6684+ * and subsequent ADD or UDATE.
6685+ *
6686+ * Revision 1.28 2000/11/06 04:30:40 rgb
6687+ * Add Svenning's adaptive content compression.
6688+ *
6689+ * Revision 1.27 2000/09/19 00:38:25 rgb
6690+ * Fixed algorithm name bugs introduced for ipcomp.
6691+ *
6692+ * Revision 1.26 2000/09/17 21:36:48 rgb
6693+ * Added proto2txt macro.
6694+ *
6695+ * Revision 1.25 2000/09/17 18:56:47 rgb
6696+ * Added IPCOMP support.
6697+ *
6698+ * Revision 1.24 2000/09/12 19:34:12 rgb
6699+ * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
6700+ *
6701+ * Revision 1.23 2000/09/12 03:23:14 rgb
6702+ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
6703+ *
6704+ * Revision 1.22 2000/09/08 19:12:56 rgb
6705+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6706+ *
6707+ * Revision 1.21 2000/09/01 18:32:43 rgb
6708+ * Added (disabled) sensitivity members to tdb struct.
6709+ *
6710+ * Revision 1.20 2000/08/30 05:31:01 rgb
6711+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
6712+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
6713+ *
6714+ * Revision 1.19 2000/08/01 14:51:52 rgb
6715+ * Removed _all_ remaining traces of DES.
6716+ *
6717+ * Revision 1.18 2000/01/21 06:17:45 rgb
6718+ * Tidied up spacing.
6719+ *
6720+ *
6721+ * Local variables:
6722+ * c-file-style: "linux"
6723+ * End:
6724+ *
6725+ */
6726--- /dev/null Tue Mar 11 13:02:56 2003
6727+++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004
6728@@ -0,0 +1,198 @@
6729+/*
6730+ * IPSEC tunneling code
6731+ * Copyright (C) 1996, 1997 John Ioannidis.
6732+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6733+ *
6734+ * This program is free software; you can redistribute it and/or modify it
6735+ * under the terms of the GNU General Public License as published by the
6736+ * Free Software Foundation; either version 2 of the License, or (at your
6737+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6738+ *
6739+ * This program is distributed in the hope that it will be useful, but
6740+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6741+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6742+ * for more details.
6743+ *
6744+ * RCSID $Id: ipsec_xmit.h,v 1.14 2005-05-11 01:00:26 mcr Exp $
6745+ */
6746+
6747+#include "openswan/ipsec_sa.h"
6748+
6749+enum ipsec_xmit_value
6750+{
6751+ IPSEC_XMIT_STOLEN=2,
6752+ IPSEC_XMIT_PASS=1,
6753+ IPSEC_XMIT_OK=0,
6754+ IPSEC_XMIT_ERRMEMALLOC=-1,
6755+ IPSEC_XMIT_ESP_BADALG=-2,
6756+ IPSEC_XMIT_BADPROTO=-3,
6757+ IPSEC_XMIT_ESP_PUSHPULLERR=-4,
6758+ IPSEC_XMIT_BADLEN=-5,
6759+ IPSEC_XMIT_AH_BADALG=-6,
6760+ IPSEC_XMIT_SAIDNOTFOUND=-7,
6761+ IPSEC_XMIT_SAIDNOTLIVE=-8,
6762+ IPSEC_XMIT_REPLAYROLLED=-9,
6763+ IPSEC_XMIT_LIFETIMEFAILED=-10,
6764+ IPSEC_XMIT_CANNOTFRAG=-11,
6765+ IPSEC_XMIT_MSSERR=-12,
6766+ IPSEC_XMIT_ERRSKBALLOC=-13,
6767+ IPSEC_XMIT_ENCAPFAIL=-14,
6768+ IPSEC_XMIT_NODEV=-15,
6769+ IPSEC_XMIT_NOPRIVDEV=-16,
6770+ IPSEC_XMIT_NOPHYSDEV=-17,
6771+ IPSEC_XMIT_NOSKB=-18,
6772+ IPSEC_XMIT_NOIPV6=-19,
6773+ IPSEC_XMIT_NOIPOPTIONS=-20,
6774+ IPSEC_XMIT_TTLEXPIRED=-21,
6775+ IPSEC_XMIT_BADHHLEN=-22,
6776+ IPSEC_XMIT_PUSHPULLERR=-23,
6777+ IPSEC_XMIT_ROUTEERR=-24,
6778+ IPSEC_XMIT_RECURSDETECT=-25,
6779+ IPSEC_XMIT_IPSENDFAILURE=-26,
6780+ IPSEC_XMIT_ESPUDP=-27,
6781+ IPSEC_XMIT_ESPUDP_BADTYPE=-28,
6782+};
6783+
6784+struct ipsec_xmit_state
6785+{
6786+ struct sk_buff *skb; /* working skb pointer */
6787+ struct net_device *dev; /* working dev pointer */
6788+ struct ipsecpriv *prv; /* Our device' private space */
6789+ struct sk_buff *oskb; /* Original skb pointer */
6790+ struct net_device_stats *stats; /* This device's statistics */
6791+ struct iphdr *iph; /* Our new IP header */
6792+ __u32 newdst; /* The other SG's IP address */
6793+ __u32 orgdst; /* Original IP destination address */
6794+ __u32 orgedst; /* 1st SG's IP address */
6795+ __u32 newsrc; /* The new source SG's IP address */
6796+ __u32 orgsrc; /* Original IP source address */
6797+ __u32 innersrc; /* Innermost IP source address */
6798+ int iphlen; /* IP header length */
6799+ int pyldsz; /* upper protocol payload size */
6800+ int headroom;
6801+ int tailroom;
6802+ int authlen;
6803+ int max_headroom; /* The extra header space needed */
6804+ int max_tailroom; /* The extra stuffing needed */
6805+ int ll_headroom; /* The extra link layer hard_header space needed */
6806+ int tot_headroom; /* The total header space needed */
6807+ int tot_tailroom; /* The totalstuffing needed */
6808+ __u8 *saved_header; /* saved copy of the hard header */
6809+ unsigned short sport, dport;
6810+
6811+ struct sockaddr_encap matcher; /* eroute search key */
6812+ struct eroute *eroute;
6813+ struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */
6814+ char sa_txt[SATOT_BUF];
6815+ size_t sa_len;
6816+ int hard_header_stripped; /* has the hard header been removed yet? */
6817+ int hard_header_len;
6818+ struct net_device *physdev;
6819+/* struct device *virtdev; */
6820+ short physmtu;
6821+ short cur_mtu; /* copy of prv->mtu, cause prv may == NULL */
6822+ short mtudiff;
6823+#ifdef NET_21
6824+ struct rtable *route;
6825+#endif /* NET_21 */
6826+ ip_said outgoing_said;
6827+#ifdef NET_21
6828+ int pass;
6829+#endif /* NET_21 */
6830+ int error;
6831+ uint32_t eroute_pid;
6832+ struct ipsec_sa ips;
6833+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
6834+ uint8_t natt_type;
6835+ uint8_t natt_head;
6836+ uint16_t natt_sport;
6837+ uint16_t natt_dport;
6838+#endif
6839+};
6840+
6841+enum ipsec_xmit_value
6842+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
6843+
6844+enum ipsec_xmit_value
6845+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
6846+
6847+enum ipsec_xmit_value
6848+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
6849+
6850+extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
6851+
6852+
6853+extern int ipsec_xmit_trap_count;
6854+extern int ipsec_xmit_trap_sendcount;
6855+
6856+#ifdef CONFIG_KLIPS_DEBUG
6857+extern int debug_tunnel;
6858+
6859+#define debug_xmit debug_tunnel
6860+
6861+#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
6862+#else
6863+#define ipsec_xmit_dmp(_x,_y, _z) do {} while(0)
6864+
6865+#endif /* CONFIG_KLIPS_DEBUG */
6866+
6867+extern int sysctl_ipsec_debug_verbose;
6868+extern int sysctl_ipsec_icmp;
6869+extern int sysctl_ipsec_tos;
6870+
6871+
6872+/*
6873+ * $Log: ipsec_xmit.h,v $
6874+ * Revision 1.14 2005-05-11 01:00:26 mcr
6875+ * do not call debug routines if !defined KLIPS_DEBUG.
6876+ *
6877+ * Revision 1.13 2005/04/29 05:01:38 mcr
6878+ * use ipsec_dmp_block.
6879+ * added cur_mtu to ixs instead of using ixs->dev.
6880+ *
6881+ * Revision 1.12 2004/08/20 21:45:37 mcr
6882+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
6883+ * be 26sec compatible. But, some defines where changed.
6884+ *
6885+ * Revision 1.11 2004/08/03 18:18:21 mcr
6886+ * in 2.6, use "net_device" instead of #define device->net_device.
6887+ * this probably breaks 2.0 compiles.
6888+ *
6889+ * Revision 1.10 2004/07/10 19:08:41 mcr
6890+ * CONFIG_IPSEC -> CONFIG_KLIPS.
6891+ *
6892+ * Revision 1.9 2004/04/06 02:49:08 mcr
6893+ * pullup of algo code from alg-branch.
6894+ *
6895+ * Revision 1.8 2004/04/05 19:55:07 mcr
6896+ * Moved from linux/include/freeswan/ipsec_xmit.h,v
6897+ *
6898+ * Revision 1.7 2004/02/03 03:11:40 mcr
6899+ * new xmit type if the UDP encapsulation is wrong.
6900+ *
6901+ * Revision 1.6 2003/12/13 19:10:16 mcr
6902+ * refactored rcv and xmit code - same as FS 2.05.
6903+ *
6904+ * Revision 1.5 2003/12/10 01:20:06 mcr
6905+ * NAT-traversal patches to KLIPS.
6906+ *
6907+ * Revision 1.4 2003/12/06 16:37:04 mcr
6908+ * 1.4.7a X.509 patch applied.
6909+ *
6910+ * Revision 1.3 2003/10/31 02:27:05 mcr
6911+ * pulled up port-selector patches and sa_id elimination.
6912+ *
6913+ * Revision 1.2.4.2 2003/10/29 01:10:19 mcr
6914+ * elimited "struct sa_id"
6915+ *
6916+ * Revision 1.2.4.1 2003/09/21 13:59:38 mcr
6917+ * pre-liminary X.509 patch - does not yet pass tests.
6918+ *
6919+ * Revision 1.2 2003/06/20 01:42:13 mcr
6920+ * added counters to measure how many ACQUIREs we send to pluto,
6921+ * and how many are successfully sent.
6922+ *
6923+ * Revision 1.1 2003/02/12 19:31:03 rgb
6924+ * Refactored from ipsec_tunnel.c
6925+ *
6926+ */
6927--- /dev/null Tue Mar 11 13:02:56 2003
6928+++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004
6929@@ -0,0 +1,75 @@
6930+/*
6931+ * sanitize a string into a printable format.
6932+ *
6933+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
6934+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
6935+ *
6936+ * This library is free software; you can redistribute it and/or modify it
6937+ * under the terms of the GNU Library General Public License as published by
6938+ * the Free Software Foundation; either version 2 of the License, or (at your
6939+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
6940+ *
6941+ * This library is distributed in the hope that it will be useful, but
6942+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6943+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
6944+ * License for more details.
6945+ *
6946+ * RCSID $Id: passert.h,v 1.7.8.1 2007-09-05 02:32:24 paul Exp $
6947+ */
6948+
6949+#include "openswan.h"
6950+
6951+#ifndef _OPENSWAN_PASSERT_H
6952+#define _OPENSWAN_PASSERT_H
6953+/* our versions of assert: log result */
6954+
6955+#ifdef DEBUG
6956+
6957+typedef void (*openswan_passert_fail_t)(const char *pred_str,
6958+ const char *file_str,
6959+ unsigned long line_no) NEVER_RETURNS;
6960+
6961+extern openswan_passert_fail_t openswan_passert_fail;
6962+
6963+extern void pexpect_log(const char *pred_str
6964+ , const char *file_str, unsigned long line_no);
6965+
6966+# define impossible() do { \
6967+ if(openswan_passert_fail) { \
6968+ (*openswan_passert_fail)("impossible", __FILE__, __LINE__); \
6969+ }} while(0)
6970+
6971+extern void switch_fail(int n
6972+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
6973+
6974+# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
6975+
6976+# define passert(pred) do { \
6977+ if (!(pred)) \
6978+ if(openswan_passert_fail) { \
6979+ (*openswan_passert_fail)(#pred, __FILE__, __LINE__); \
6980+ } \
6981+ } while(0)
6982+
6983+# define pexpect(pred) do { \
6984+ if (!(pred)) \
6985+ pexpect_log(#pred, __FILE__, __LINE__); \
6986+ } while(0)
6987+
6988+/* assert that an err_t is NULL; evaluate exactly once */
6989+# define happy(x) { \
6990+ err_t ugh = x; \
6991+ if (ugh != NULL) \
6992+ if(openswan_passert_fail) { (*openswan_passert_fail)(ugh, __FILE__, __LINE__); } \
6993+ }
6994+
6995+#else /*!DEBUG*/
6996+
6997+# define impossible() abort()
6998+# define bad_case(n) abort()
6999+# define passert(pred) { } /* do nothing */
7000+# define happy(x) { (void) x; } /* evaluate non-judgementally */
7001+
7002+#endif /*!DEBUG*/
7003+
7004+#endif /* _OPENSWAN_PASSERT_H */
7005--- /dev/null Tue Mar 11 13:02:56 2003
7006+++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004
7007@@ -0,0 +1,54 @@
7008+/*
7009+ * sanitize a string into a printable format.
7010+ *
7011+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
7012+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
7013+ *
7014+ * This library is free software; you can redistribute it and/or modify it
7015+ * under the terms of the GNU Library General Public License as published by
7016+ * the Free Software Foundation; either version 2 of the License, or (at your
7017+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
7018+ *
7019+ * This library is distributed in the hope that it will be useful, but
7020+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7021+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
7022+ * License for more details.
7023+ *
7024+ * RCSID $Id: pfkey_debug.h,v 1.3 2004-04-05 19:55:07 mcr Exp $
7025+ */
7026+
7027+#ifndef _FREESWAN_PFKEY_DEBUG_H
7028+#define _FREESWAN_PFKEY_DEBUG_H
7029+
7030+#ifdef __KERNEL__
7031+
7032+/* note, kernel version ignores pfkey levels */
7033+# define DEBUGGING(level,args...) \
7034+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
7035+
7036+# define ERROR(args...) printk(KERN_ERR "klips:" args)
7037+
7038+#else
7039+
7040+extern unsigned int pfkey_lib_debug;
7041+
7042+extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
7043+extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
7044+
7045+#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \
7046+ if(pfkey_debug_func != NULL) { \
7047+ (*pfkey_debug_func)("pfkey_lib_debug:" args); \
7048+ } else { \
7049+ printf("pfkey_lib_debug:" args); \
7050+ } }
7051+
7052+#define ERROR(args...) if(pfkey_error_func != NULL) { \
7053+ (*pfkey_error_func)("pfkey_lib_debug:" args); \
7054+ }
7055+
7056+# define MALLOC(size) malloc(size)
7057+# define FREE(obj) free(obj)
7058+
7059+#endif
7060+
7061+#endif
7062--- /dev/null Tue Mar 11 13:02:56 2003
7063+++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004
7064@@ -0,0 +1,280 @@
7065+/*
7066+ * RCSID $Id: radij.h,v 1.13 2004-04-05 19:55:08 mcr Exp $
7067+ */
7068+
7069+/*
7070+ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
7071+ *
7072+ * Variable and procedure names have been modified so that they don't
7073+ * conflict with the original BSD code, as a small number of modifications
7074+ * have been introduced and we may want to reuse this code in BSD.
7075+ *
7076+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
7077+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
7078+ * spanish j as in Juan. It is not as far back in the throat like
7079+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
7080+ * It has nothing to do with the Dutch ij sound.
7081+ *
7082+ * Here is the appropriate copyright notice:
7083+ */
7084+
7085+/*
7086+ * Copyright (c) 1988, 1989, 1993
7087+ * The Regents of the University of California. All rights reserved.
7088+ *
7089+ * Redistribution and use in source and binary forms, with or without
7090+ * modification, are permitted provided that the following conditions
7091+ * are met:
7092+ * 1. Redistributions of source code must retain the above copyright
7093+ * notice, this list of conditions and the following disclaimer.
7094+ * 2. Redistributions in binary form must reproduce the above copyright
7095+ * notice, this list of conditions and the following disclaimer in the
7096+ * documentation and/or other materials provided with the distribution.
7097+ * 3. All advertising materials mentioning features or use of this software
7098+ * must display the following acknowledgement:
7099+ * This product includes software developed by the University of
7100+ * California, Berkeley and its contributors.
7101+ * 4. Neither the name of the University nor the names of its contributors
7102+ * may be used to endorse or promote products derived from this software
7103+ * without specific prior written permission.
7104+ *
7105+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
7106+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7107+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7108+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
7109+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7110+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
7111+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7112+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7113+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7114+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7115+ * SUCH DAMAGE.
7116+ *
7117+ * @(#)radix.h 8.1 (Berkeley) 6/10/93
7118+ */
7119+
7120+#ifndef _RADIJ_H_
7121+#define _RADIJ_H_
7122+
7123+/*
7124+#define RJ_DEBUG
7125+*/
7126+
7127+#ifdef __KERNEL__
7128+
7129+#ifndef __P
7130+#ifdef __STDC__
7131+#define __P(x) x
7132+#else
7133+#define __P(x) ()
7134+#endif
7135+#endif
7136+
7137+/*
7138+ * Radix search tree node layout.
7139+ */
7140+
7141+struct radij_node
7142+{
7143+ struct radij_mask *rj_mklist; /* list of masks contained in subtree */
7144+ struct radij_node *rj_p; /* parent */
7145+ short rj_b; /* bit offset; -1-index(netmask) */
7146+ char rj_bmask; /* node: mask for bit test*/
7147+ u_char rj_flags; /* enumerated next */
7148+#define RJF_NORMAL 1 /* leaf contains normal route */
7149+#define RJF_ROOT 2 /* leaf is root leaf for tree */
7150+#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
7151+ union {
7152+ struct { /* leaf only data: */
7153+ caddr_t rj_Key; /* object of search */
7154+ caddr_t rj_Mask; /* netmask, if present */
7155+ struct radij_node *rj_Dupedkey;
7156+ } rj_leaf;
7157+ struct { /* node only data: */
7158+ int rj_Off; /* where to start compare */
7159+ struct radij_node *rj_L;/* progeny */
7160+ struct radij_node *rj_R;/* progeny */
7161+ }rj_node;
7162+ } rj_u;
7163+#ifdef RJ_DEBUG
7164+ int rj_info;
7165+ struct radij_node *rj_twin;
7166+ struct radij_node *rj_ybro;
7167+#endif
7168+};
7169+
7170+#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
7171+#define rj_key rj_u.rj_leaf.rj_Key
7172+#define rj_mask rj_u.rj_leaf.rj_Mask
7173+#define rj_off rj_u.rj_node.rj_Off
7174+#define rj_l rj_u.rj_node.rj_L
7175+#define rj_r rj_u.rj_node.rj_R
7176+
7177+/*
7178+ * Annotations to tree concerning potential routes applying to subtrees.
7179+ */
7180+
7181+extern struct radij_mask {
7182+ short rm_b; /* bit offset; -1-index(netmask) */
7183+ char rm_unused; /* cf. rj_bmask */
7184+ u_char rm_flags; /* cf. rj_flags */
7185+ struct radij_mask *rm_mklist; /* more masks to try */
7186+ caddr_t rm_mask; /* the mask */
7187+ int rm_refs; /* # of references to this struct */
7188+} *rj_mkfreelist;
7189+
7190+#define MKGet(m) {\
7191+ if (rj_mkfreelist) {\
7192+ m = rj_mkfreelist; \
7193+ rj_mkfreelist = (m)->rm_mklist; \
7194+ } else \
7195+ R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
7196+
7197+#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
7198+
7199+struct radij_node_head {
7200+ struct radij_node *rnh_treetop;
7201+ int rnh_addrsize; /* permit, but not require fixed keys */
7202+ int rnh_pktsize; /* permit, but not require fixed keys */
7203+#if 0
7204+ struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
7205+ __P((void *v, void *mask,
7206+ struct radij_node_head *head, struct radij_node nodes[]));
7207+#endif
7208+ int (*rnh_addaddr) /* add based on sockaddr */
7209+ __P((void *v, void *mask,
7210+ struct radij_node_head *head, struct radij_node nodes[]));
7211+ struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
7212+ __P((void *v, void *mask,
7213+ struct radij_node_head *head, struct radij_node nodes[]));
7214+#if 0
7215+ struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
7216+ __P((void *v, void *mask, struct radij_node_head *head));
7217+#endif
7218+ int (*rnh_deladdr) /* remove based on sockaddr */
7219+ __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
7220+ struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
7221+ __P((void *v, void *mask, struct radij_node_head *head));
7222+ struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
7223+ __P((void *v, struct radij_node_head *head));
7224+ struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
7225+ __P((void *v, struct radij_node_head *head));
7226+ int (*rnh_walktree) /* traverse tree */
7227+ __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7228+ struct radij_node rnh_nodes[3]; /* empty tree for common case */
7229+};
7230+
7231+
7232+#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7233+#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7234+#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
7235+#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
7236+#define Free(p) kfree((caddr_t)p);
7237+
7238+void rj_init __P((void));
7239+int rj_inithead __P((void **, int));
7240+int rj_refines __P((void *, void *));
7241+int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7242+struct radij_node
7243+ *rj_addmask __P((void *, int, int)) /* , rgb */ ;
7244+int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
7245+ struct radij_node [2])) /* , rgb */ ;
7246+int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
7247+struct radij_node /* rgb */
7248+ *rj_insert __P((void *, struct radij_node_head *, int *,
7249+ struct radij_node [2])),
7250+ *rj_match __P((void *, struct radij_node_head *)),
7251+ *rj_newpair __P((void *, int, struct radij_node[2])),
7252+ *rj_search __P((void *, struct radij_node *)),
7253+ *rj_search_m __P((void *, struct radij_node *, void *));
7254+
7255+void rj_deltree(struct radij_node_head *);
7256+void rj_delnodes(struct radij_node *);
7257+void rj_free_mkfreelist(void);
7258+int radijcleartree(void);
7259+int radijcleanup(void);
7260+
7261+extern struct radij_node_head *mask_rjhead;
7262+extern int maj_keylen;
7263+#endif /* __KERNEL__ */
7264+
7265+#endif /* _RADIJ_H_ */
7266+
7267+
7268+/*
7269+ * $Log: radij.h,v $
7270+ * Revision 1.13 2004-04-05 19:55:08 mcr
7271+ * Moved from linux/include/freeswan/radij.h,v
7272+ *
7273+ * Revision 1.12 2002/04/24 07:36:48 mcr
7274+ * Moved from ./klips/net/ipsec/radij.h,v
7275+ *
7276+ * Revision 1.11 2001/09/20 15:33:00 rgb
7277+ * Min/max cleanup.
7278+ *
7279+ * Revision 1.10 1999/11/18 04:09:20 rgb
7280+ * Replaced all kernel version macros to shorter, readable form.
7281+ *
7282+ * Revision 1.9 1999/05/05 22:02:33 rgb
7283+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
7284+ *
7285+ * Revision 1.8 1999/04/29 15:24:58 rgb
7286+ * Add check for existence of macros min/max.
7287+ *
7288+ * Revision 1.7 1999/04/11 00:29:02 henry
7289+ * GPL boilerplate
7290+ *
7291+ * Revision 1.6 1999/04/06 04:54:29 rgb
7292+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
7293+ * patch shell fixes.
7294+ *
7295+ * Revision 1.5 1999/01/22 06:30:32 rgb
7296+ * 64-bit clean-up.
7297+ *
7298+ * Revision 1.4 1998/11/30 13:22:55 rgb
7299+ * Rationalised all the klips kernel file headers. They are much shorter
7300+ * now and won't conflict under RH5.2.
7301+ *
7302+ * Revision 1.3 1998/10/25 02:43:27 rgb
7303+ * Change return type on rj_addroute and rj_delete and add and argument
7304+ * to the latter to be able to transmit more infomation about errors.
7305+ *
7306+ * Revision 1.2 1998/07/14 18:09:51 rgb
7307+ * Add a routine to clear eroute table.
7308+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
7309+ *
7310+ * Revision 1.1 1998/06/18 21:30:22 henry
7311+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
7312+ * build scripts happier about symlinks
7313+ *
7314+ * Revision 1.4 1998/05/25 20:34:16 rgb
7315+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
7316+ *
7317+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
7318+ * add ipsec_rj_walker_delete.
7319+ *
7320+ * Recover memory for eroute table on unload of module.
7321+ *
7322+ * Revision 1.3 1998/04/22 16:51:37 rgb
7323+ * Tidy up radij debug code from recent rash of modifications to debug code.
7324+ *
7325+ * Revision 1.2 1998/04/14 17:30:38 rgb
7326+ * Fix up compiling errors for radij tree memory reclamation.
7327+ *
7328+ * Revision 1.1 1998/04/09 03:06:16 henry
7329+ * sources moved up from linux/net/ipsec
7330+ *
7331+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
7332+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
7333+ *
7334+ * Revision 0.4 1997/01/15 01:28:15 ji
7335+ * No changes.
7336+ *
7337+ * Revision 0.3 1996/11/20 14:44:45 ji
7338+ * Release update only.
7339+ *
7340+ * Revision 0.2 1996/11/02 00:18:33 ji
7341+ * First limited release.
7342+ *
7343+ *
7344+ */
7345--- /dev/null Tue Mar 11 13:02:56 2003
7346+++ linux/include/pfkey.h Mon Feb 9 13:51:03 2004
7347@@ -0,0 +1,529 @@
7348+/*
7349+ * FreeS/WAN specific PF_KEY headers
7350+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
7351+ *
7352+ * This program is free software; you can redistribute it and/or modify it
7353+ * under the terms of the GNU General Public License as published by the
7354+ * Free Software Foundation; either version 2 of the License, or (at your
7355+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
7356+ *
7357+ * This program is distributed in the hope that it will be useful, but
7358+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7359+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7360+ * for more details.
7361+ *
7362+ * RCSID $Id: pfkey.h,v 1.49 2005-05-11 00:57:29 mcr Exp $
7363+ */
7364+
7365+#ifndef __NET_IPSEC_PF_KEY_H
7366+#define __NET_IPSEC_PF_KEY_H
7367+#ifdef __KERNEL__
7368+extern struct proto_ops pfkey_proto_ops;
7369+typedef struct sock pfkey_sock;
7370+extern int debug_pfkey;
7371+
7372+extern /* void */ int pfkey_init(void);
7373+extern /* void */ int pfkey_cleanup(void);
7374+
7375+struct socket_list
7376+{
7377+ struct socket *socketp;
7378+ struct socket_list *next;
7379+};
7380+extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
7381+extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
7382+extern struct socket_list *pfkey_open_sockets;
7383+extern struct socket_list *pfkey_registered_sockets[];
7384+
7385+struct ipsec_alg_supported
7386+{
7387+ uint16_t ias_exttype;
7388+ uint8_t ias_id;
7389+ uint8_t ias_ivlen;
7390+ uint16_t ias_keyminbits;
7391+ uint16_t ias_keymaxbits;
7392+ char *ias_name;
7393+};
7394+
7395+extern struct supported_list *pfkey_supported_list[];
7396+struct supported_list
7397+{
7398+ struct ipsec_alg_supported *supportedp;
7399+ struct supported_list *next;
7400+};
7401+extern int pfkey_list_insert_supported(struct ipsec_alg_supported*, struct supported_list**);
7402+extern int pfkey_list_remove_supported(struct ipsec_alg_supported*, struct supported_list**);
7403+
7404+struct sockaddr_key
7405+{
7406+ uint16_t key_family; /* PF_KEY */
7407+ uint16_t key_pad; /* not used */
7408+ uint32_t key_pid; /* process ID */
7409+};
7410+
7411+struct pfkey_extracted_data
7412+{
7413+ struct ipsec_sa* ips;
7414+ struct ipsec_sa* ips2;
7415+ struct eroute *eroute;
7416+};
7417+
7418+/* forward reference */
7419+struct sadb_ext;
7420+struct sadb_msg;
7421+struct sockaddr;
7422+struct sadb_comb;
7423+struct sadb_sadb;
7424+struct sadb_alg;
7425+
7426+extern int
7427+pfkey_alloc_eroute(struct eroute** eroute);
7428+
7429+extern int
7430+pfkey_sa_process(struct sadb_ext *pfkey_ext,
7431+ struct pfkey_extracted_data* extr);
7432+
7433+extern int
7434+pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
7435+ struct pfkey_extracted_data* extr);
7436+
7437+extern int
7438+pfkey_address_process(struct sadb_ext *pfkey_ext,
7439+ struct pfkey_extracted_data* extr);
7440+
7441+extern int
7442+pfkey_key_process(struct sadb_ext *pfkey_ext,
7443+ struct pfkey_extracted_data* extr);
7444+
7445+extern int
7446+pfkey_ident_process(struct sadb_ext *pfkey_ext,
7447+ struct pfkey_extracted_data* extr);
7448+
7449+extern int
7450+pfkey_sens_process(struct sadb_ext *pfkey_ext,
7451+ struct pfkey_extracted_data* extr);
7452+
7453+extern int
7454+pfkey_prop_process(struct sadb_ext *pfkey_ext,
7455+ struct pfkey_extracted_data* extr);
7456+
7457+extern int
7458+pfkey_supported_process(struct sadb_ext *pfkey_ext,
7459+ struct pfkey_extracted_data* extr);
7460+
7461+extern int
7462+pfkey_spirange_process(struct sadb_ext *pfkey_ext,
7463+ struct pfkey_extracted_data* extr);
7464+
7465+extern int
7466+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
7467+ struct pfkey_extracted_data* extr);
7468+
7469+extern int
7470+pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
7471+ struct pfkey_extracted_data* extr);
7472+
7473+extern int
7474+pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
7475+ struct pfkey_extracted_data* extr);
7476+
7477+extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
7478+extern int pfkey_expire(struct ipsec_sa *, int);
7479+extern int pfkey_acquire(struct ipsec_sa *);
7480+#else /* ! __KERNEL__ */
7481+
7482+extern void (*pfkey_debug_func)(const char *message, ...);
7483+extern void (*pfkey_error_func)(const char *message, ...);
7484+extern void pfkey_print(struct sadb_msg *msg, FILE *out);
7485+
7486+
7487+#endif /* __KERNEL__ */
7488+
7489+extern uint8_t satype2proto(uint8_t satype);
7490+extern uint8_t proto2satype(uint8_t proto);
7491+extern char* satype2name(uint8_t satype);
7492+extern char* proto2name(uint8_t proto);
7493+
7494+struct key_opt
7495+{
7496+ uint32_t key_pid; /* process ID */
7497+ struct sock *sk;
7498+};
7499+
7500+#define key_pid(sk) ((struct key_opt*)&((sk)->sk_protinfo))->key_pid
7501+
7502+/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
7503+ * words.
7504+ */
7505+#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
7506+#define BITS_PER_OCTET 8
7507+#define OCTETBITS 8
7508+#define PFKEYBITS 64
7509+#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
7510+#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
7511+
7512+#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN)
7513+#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN)
7514+
7515+
7516+#define PFKEYv2_MAX_MSGSIZE 4096
7517+
7518+/*
7519+ * PF_KEYv2 permitted and required extensions in and out bitmaps
7520+ */
7521+struct pf_key_ext_parsers_def {
7522+ int (*parser)(struct sadb_ext*);
7523+ char *parser_name;
7524+};
7525+
7526+
7527+#define SADB_EXTENSIONS_MAX 31
7528+extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX];
7529+#define EXT_BITS_IN 0
7530+#define EXT_BITS_OUT 1
7531+#define EXT_BITS_PERM 0
7532+#define EXT_BITS_REQ 1
7533+
7534+extern void pfkey_extensions_init(struct sadb_ext *extensions[]);
7535+extern void pfkey_extensions_free(struct sadb_ext *extensions[]);
7536+extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
7537+
7538+extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
7539+ struct pf_key_ext_parsers_def *ext_parsers[],
7540+ struct sadb_ext **extensions,
7541+ int dir);
7542+
7543+extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg);
7544+
7545+/*
7546+ * PF_KEYv2 build function prototypes
7547+ */
7548+
7549+int
7550+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
7551+ uint8_t msg_type,
7552+ uint8_t satype,
7553+ uint8_t msg_errno,
7554+ uint32_t seq,
7555+ uint32_t pid);
7556+
7557+int
7558+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
7559+ uint16_t exttype,
7560+ uint32_t spi, /* in network order */
7561+ uint8_t replay_window,
7562+ uint8_t sa_state,
7563+ uint8_t auth,
7564+ uint8_t encrypt,
7565+ uint32_t flags,
7566+ uint32_t/*IPsecSAref_t*/ ref);
7567+
7568+int
7569+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
7570+ uint16_t exttype,
7571+ uint32_t spi, /* in network order */
7572+ uint8_t replay_window,
7573+ uint8_t sa_state,
7574+ uint8_t auth,
7575+ uint8_t encrypt,
7576+ uint32_t flags);
7577+
7578+int
7579+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
7580+ uint16_t exttype,
7581+ uint32_t allocations,
7582+ uint64_t bytes,
7583+ uint64_t addtime,
7584+ uint64_t usetime,
7585+ uint32_t packets);
7586+
7587+int
7588+pfkey_address_build(struct sadb_ext** pfkey_ext,
7589+ uint16_t exttype,
7590+ uint8_t proto,
7591+ uint8_t prefixlen,
7592+ struct sockaddr* address);
7593+
7594+int
7595+pfkey_key_build(struct sadb_ext** pfkey_ext,
7596+ uint16_t exttype,
7597+ uint16_t key_bits,
7598+ char* key);
7599+
7600+int
7601+pfkey_ident_build(struct sadb_ext** pfkey_ext,
7602+ uint16_t exttype,
7603+ uint16_t ident_type,
7604+ uint64_t ident_id,
7605+ uint8_t ident_len,
7606+ char* ident_string);
7607+
7608+#ifdef __KERNEL__
7609+extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
7610+extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7611+extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7612+#endif /* __KERNEL__ */
7613+int
7614+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
7615+ uint8_t type);
7616+int
7617+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
7618+ uint16_t exttype,
7619+ uint16_t port);
7620+
7621+int
7622+pfkey_sens_build(struct sadb_ext** pfkey_ext,
7623+ uint32_t dpd,
7624+ uint8_t sens_level,
7625+ uint8_t sens_len,
7626+ uint64_t* sens_bitmap,
7627+ uint8_t integ_level,
7628+ uint8_t integ_len,
7629+ uint64_t* integ_bitmap);
7630+
7631+int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
7632+
7633+
7634+int
7635+pfkey_prop_build(struct sadb_ext** pfkey_ext,
7636+ uint8_t replay,
7637+ unsigned int comb_num,
7638+ struct sadb_comb* comb);
7639+
7640+int
7641+pfkey_supported_build(struct sadb_ext** pfkey_ext,
7642+ uint16_t exttype,
7643+ unsigned int alg_num,
7644+ struct sadb_alg* alg);
7645+
7646+int
7647+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
7648+ uint16_t exttype,
7649+ uint32_t min,
7650+ uint32_t max);
7651+
7652+int
7653+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
7654+
7655+int
7656+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
7657+ uint8_t satype);
7658+
7659+int
7660+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
7661+ uint32_t tunnel,
7662+ uint32_t netlink,
7663+ uint32_t xform,
7664+ uint32_t eroute,
7665+ uint32_t spi,
7666+ uint32_t radij,
7667+ uint32_t esp,
7668+ uint32_t ah,
7669+ uint32_t rcv,
7670+ uint32_t pfkey,
7671+ uint32_t ipcomp,
7672+ uint32_t verbose);
7673+
7674+int
7675+pfkey_msg_build(struct sadb_msg** pfkey_msg,
7676+ struct sadb_ext* extensions[],
7677+ int dir);
7678+
7679+/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
7680+const char *
7681+pfkey_v2_sadb_ext_string(int extnum);
7682+
7683+const char *
7684+pfkey_v2_sadb_type_string(int sadb_type);
7685+
7686+
7687+#endif /* __NET_IPSEC_PF_KEY_H */
7688+
7689+/*
7690+ * $Log: pfkey.h,v $
7691+ * Revision 1.49 2005-05-11 00:57:29 mcr
7692+ * rename struct supported -> struct ipsec_alg_supported.
7693+ * make pfkey.h more standalone.
7694+ *
7695+ * Revision 1.48 2005/05/01 03:12:50 mcr
7696+ * include name of algorithm in datastructure.
7697+ *
7698+ * Revision 1.47 2004/08/21 00:44:14 mcr
7699+ * simplify definition of nat_t related prototypes.
7700+ *
7701+ * Revision 1.46 2004/08/04 16:27:22 mcr
7702+ * 2.6 sk_ options.
7703+ *
7704+ * Revision 1.45 2004/04/06 02:49:00 mcr
7705+ * pullup of algo code from alg-branch.
7706+ *
7707+ * Revision 1.44 2003/12/10 01:20:01 mcr
7708+ * NAT-traversal patches to KLIPS.
7709+ *
7710+ * Revision 1.43 2003/10/31 02:26:44 mcr
7711+ * pulled up port-selector patches.
7712+ *
7713+ * Revision 1.42.2.2 2003/10/29 01:09:32 mcr
7714+ * added debugging for pfkey library.
7715+ *
7716+ * Revision 1.42.2.1 2003/09/21 13:59:34 mcr
7717+ * pre-liminary X.509 patch - does not yet pass tests.
7718+ *
7719+ * Revision 1.42 2003/08/25 22:08:19 mcr
7720+ * removed pfkey_proto_init() from pfkey.h for 2.6 support.
7721+ *
7722+ * Revision 1.41 2003/05/07 17:28:57 mcr
7723+ * new function pfkey_debug_func added for us in debugging from
7724+
7725+ * pfkey library.
7726+ *
7727+ * Revision 1.40 2003/01/30 02:31:34 rgb
7728+ *
7729+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
7730+ *
7731+ * Revision 1.39 2002/09/20 15:40:21 rgb
7732+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
7733+ * Added ref parameter to pfkey_sa_build().
7734+ * Cleaned out unused cruft.
7735+ *
7736+ * Revision 1.38 2002/05/14 02:37:24 rgb
7737+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
7738+ * ipsec_sa or ipsec_sa.
7739+ * Added function prototypes for the functions moved to
7740+ * pfkey_v2_ext_process.c.
7741+ *
7742+ * Revision 1.37 2002/04/24 07:36:49 mcr
7743+ * Moved from ./lib/pfkey.h,v
7744+ *
7745+ * Revision 1.36 2002/01/20 20:34:49 mcr
7746+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
7747+ *
7748+ * Revision 1.35 2001/11/27 05:27:47 mcr
7749+ * pfkey parses are now maintained by a structure
7750+ * that includes their name for debug purposes.
7751+ *
7752+ * Revision 1.34 2001/11/26 09:23:53 rgb
7753+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
7754+ *
7755+ * Revision 1.33 2001/11/06 19:47:47 rgb
7756+ * Added packet parameter to lifetime and comb structures.
7757+ *
7758+ * Revision 1.32 2001/09/08 21:13:34 rgb
7759+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
7760+ *
7761+ * Revision 1.31 2001/06/14 19:35:16 rgb
7762+ * Update copyright date.
7763+ *
7764+ * Revision 1.30 2001/02/27 07:04:52 rgb
7765+ * Added satype2name prototype.
7766+ *
7767+ * Revision 1.29 2001/02/26 19:59:33 rgb
7768+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
7769+ *
7770+ * Revision 1.28 2000/10/10 20:10:19 rgb
7771+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
7772+ *
7773+ * Revision 1.27 2000/09/21 04:20:45 rgb
7774+ * Fixed array size off-by-one error. (Thanks Svenning!)
7775+ *
7776+ * Revision 1.26 2000/09/12 03:26:05 rgb
7777+ * Added pfkey_acquire prototype.
7778+ *
7779+ * Revision 1.25 2000/09/08 19:21:28 rgb
7780+ * Fix pfkey_prop_build() parameter to be only single indirection.
7781+ *
7782+ * Revision 1.24 2000/09/01 18:46:42 rgb
7783+ * Added a supported algorithms array lists, one per satype and registered
7784+ * existing algorithms.
7785+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
7786+ * list.
7787+ *
7788+ * Revision 1.23 2000/08/27 01:55:26 rgb
7789+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
7790+ *
7791+ * Revision 1.22 2000/08/20 21:39:23 rgb
7792+ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
7793+ * pfkey_expire().
7794+ *
7795+ * Revision 1.21 2000/08/15 17:29:23 rgb
7796+ * Fixes from SZI to untested pfkey_prop_build().
7797+ *
7798+ * Revision 1.20 2000/05/10 20:14:19 rgb
7799+ * Fleshed out sensitivity, proposal and supported extensions.
7800+ *
7801+ * Revision 1.19 2000/03/16 14:07:23 rgb
7802+ * Renamed ALIGN macro to avoid fighting with others in kernel.
7803+ *
7804+ * Revision 1.18 2000/01/22 23:24:06 rgb
7805+ * Added prototypes for proto2satype(), satype2proto() and proto2name().
7806+ *
7807+ * Revision 1.17 2000/01/21 06:26:59 rgb
7808+ * Converted from double tdb arguments to one structure (extr)
7809+ * containing pointers to all temporary information structures.
7810+ * Added klipsdebug switching capability.
7811+ * Dropped unused argument to pfkey_x_satype_build().
7812+ *
7813+ * Revision 1.16 1999/12/29 21:17:41 rgb
7814+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
7815+ * parameter for cleaner manipulation of extensions[] and to guard
7816+ * against potential memory leaks.
7817+ * Changed the I/F to pfkey_msg_free() for the same reason.
7818+ *
7819+ * Revision 1.15 1999/12/09 23:12:54 rgb
7820+ * Added macro for BITS_PER_OCTET.
7821+ * Added argument to pfkey_sa_build() to do eroutes.
7822+ *
7823+ * Revision 1.14 1999/12/08 20:33:25 rgb
7824+ * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
7825+ *
7826+ * Revision 1.13 1999/12/07 19:53:40 rgb
7827+ * Removed unused first argument from extension parsers.
7828+ * Changed __u* types to uint* to avoid use of asm/types.h and
7829+ * sys/types.h in userspace code.
7830+ * Added function prototypes for pfkey message and extensions
7831+ * initialisation and cleanup.
7832+ *
7833+ * Revision 1.12 1999/12/01 22:19:38 rgb
7834+ * Change pfkey_sa_build to accept an SPI in network byte order.
7835+ *
7836+ * Revision 1.11 1999/11/27 11:55:26 rgb
7837+ * Added extern sadb_satype2proto to enable moving protocol lookup table
7838+ * to lib/pfkey_v2_parse.c.
7839+ * Delete unused, moved typedefs.
7840+ * Add argument to pfkey_msg_parse() for direction.
7841+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
7842+ *
7843+ * Revision 1.10 1999/11/23 22:29:21 rgb
7844+ * This file has been moved in the distribution from klips/net/ipsec to
7845+ * lib.
7846+ * Add macros for dealing with alignment and rounding up more opaquely.
7847+ * The uint<n>_t type defines have been moved to freeswan.h to avoid
7848+ * chicken-and-egg problems.
7849+ * Add macros for dealing with alignment and rounding up more opaque.
7850+ * Added prototypes for using extention header bitmaps.
7851+ * Added prototypes of all the build functions.
7852+ *
7853+ * Revision 1.9 1999/11/20 21:59:48 rgb
7854+ * Moved socketlist type declarations and prototypes for shared use.
7855+ * Slightly modified scope of sockaddr_key declaration.
7856+ *
7857+ * Revision 1.8 1999/11/17 14:34:25 rgb
7858+ * Protect sa_family_t from being used in userspace with GLIBC<2.
7859+ *
7860+ * Revision 1.7 1999/10/27 19:40:35 rgb
7861+ * Add a maximum PFKEY packet size macro.
7862+ *
7863+ * Revision 1.6 1999/10/26 16:58:58 rgb
7864+ * Created a sockaddr_key and key_opt socket extension structures.
7865+ *
7866+ * Revision 1.5 1999/06/10 05:24:41 rgb
7867+ * Renamed variables to reduce confusion.
7868+ *
7869+ * Revision 1.4 1999/04/29 15:21:11 rgb
7870+ * Add pfkey support to debugging.
7871+ * Add return values to init and cleanup functions.
7872+ *
7873+ * Revision 1.3 1999/04/15 17:58:07 rgb
7874+ * Add RCSID labels.
7875+ *
7876+ */
7877--- /dev/null Tue Mar 11 13:02:56 2003
7878+++ linux/include/pfkeyv2.h Mon Feb 9 13:51:03 2004
7879@@ -0,0 +1,472 @@
7880+/*
7881+ * RCSID $Id: pfkeyv2.h,v 1.31 2005-04-14 01:14:54 mcr Exp $
7882+ */
7883+
7884+/*
7885+RFC 2367 PF_KEY Key Management API July 1998
7886+
7887+
7888+Appendix D: Sample Header File
7889+
7890+This file defines structures and symbols for the PF_KEY Version 2
7891+key management interface. It was written at the U.S. Naval Research
7892+Laboratory. This file is in the public domain. The authors ask that
7893+you leave this credit intact on any copies of this file.
7894+*/
7895+#ifndef __PFKEY_V2_H
7896+#define __PFKEY_V2_H 1
7897+
7898+#define PF_KEY_V2 2
7899+#define PFKEYV2_REVISION 199806L
7900+
7901+#define SADB_RESERVED 0
7902+#define SADB_GETSPI 1
7903+#define SADB_UPDATE 2
7904+#define SADB_ADD 3
7905+#define SADB_DELETE 4
7906+#define SADB_GET 5
7907+#define SADB_ACQUIRE 6
7908+#define SADB_REGISTER 7
7909+#define SADB_EXPIRE 8
7910+#define SADB_FLUSH 9
7911+#define SADB_DUMP 10
7912+#define SADB_X_PROMISC 11
7913+#define SADB_X_PCHANGE 12
7914+#define SADB_X_GRPSA 13
7915+#define SADB_X_ADDFLOW 14
7916+#define SADB_X_DELFLOW 15
7917+#define SADB_X_DEBUG 16
7918+#define SADB_X_NAT_T_NEW_MAPPING 17
7919+#define SADB_MAX 17
7920+
7921+struct sadb_msg {
7922+ uint8_t sadb_msg_version;
7923+ uint8_t sadb_msg_type;
7924+ uint8_t sadb_msg_errno;
7925+ uint8_t sadb_msg_satype;
7926+ uint16_t sadb_msg_len;
7927+ uint16_t sadb_msg_reserved;
7928+ uint32_t sadb_msg_seq;
7929+ uint32_t sadb_msg_pid;
7930+};
7931+
7932+struct sadb_ext {
7933+ uint16_t sadb_ext_len;
7934+ uint16_t sadb_ext_type;
7935+};
7936+
7937+struct sadb_sa {
7938+ uint16_t sadb_sa_len;
7939+ uint16_t sadb_sa_exttype;
7940+ uint32_t sadb_sa_spi;
7941+ uint8_t sadb_sa_replay;
7942+ uint8_t sadb_sa_state;
7943+ uint8_t sadb_sa_auth;
7944+ uint8_t sadb_sa_encrypt;
7945+ uint32_t sadb_sa_flags;
7946+ uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
7947+ uint8_t sadb_x_reserved[4];
7948+};
7949+
7950+struct sadb_sa_v1 {
7951+ uint16_t sadb_sa_len;
7952+ uint16_t sadb_sa_exttype;
7953+ uint32_t sadb_sa_spi;
7954+ uint8_t sadb_sa_replay;
7955+ uint8_t sadb_sa_state;
7956+ uint8_t sadb_sa_auth;
7957+ uint8_t sadb_sa_encrypt;
7958+ uint32_t sadb_sa_flags;
7959+};
7960+
7961+struct sadb_lifetime {
7962+ uint16_t sadb_lifetime_len;
7963+ uint16_t sadb_lifetime_exttype;
7964+ uint32_t sadb_lifetime_allocations;
7965+ uint64_t sadb_lifetime_bytes;
7966+ uint64_t sadb_lifetime_addtime;
7967+ uint64_t sadb_lifetime_usetime;
7968+ uint32_t sadb_x_lifetime_packets;
7969+ uint32_t sadb_x_lifetime_reserved;
7970+};
7971+
7972+struct sadb_address {
7973+ uint16_t sadb_address_len;
7974+ uint16_t sadb_address_exttype;
7975+ uint8_t sadb_address_proto;
7976+ uint8_t sadb_address_prefixlen;
7977+ uint16_t sadb_address_reserved;
7978+};
7979+
7980+struct sadb_key {
7981+ uint16_t sadb_key_len;
7982+ uint16_t sadb_key_exttype;
7983+ uint16_t sadb_key_bits;
7984+ uint16_t sadb_key_reserved;
7985+};
7986+
7987+struct sadb_ident {
7988+ uint16_t sadb_ident_len;
7989+ uint16_t sadb_ident_exttype;
7990+ uint16_t sadb_ident_type;
7991+ uint16_t sadb_ident_reserved;
7992+ uint64_t sadb_ident_id;
7993+};
7994+
7995+struct sadb_sens {
7996+ uint16_t sadb_sens_len;
7997+ uint16_t sadb_sens_exttype;
7998+ uint32_t sadb_sens_dpd;
7999+ uint8_t sadb_sens_sens_level;
8000+ uint8_t sadb_sens_sens_len;
8001+ uint8_t sadb_sens_integ_level;
8002+ uint8_t sadb_sens_integ_len;
8003+ uint32_t sadb_sens_reserved;
8004+};
8005+
8006+struct sadb_prop {
8007+ uint16_t sadb_prop_len;
8008+ uint16_t sadb_prop_exttype;
8009+ uint8_t sadb_prop_replay;
8010+ uint8_t sadb_prop_reserved[3];
8011+};
8012+
8013+struct sadb_comb {
8014+ uint8_t sadb_comb_auth;
8015+ uint8_t sadb_comb_encrypt;
8016+ uint16_t sadb_comb_flags;
8017+ uint16_t sadb_comb_auth_minbits;
8018+ uint16_t sadb_comb_auth_maxbits;
8019+ uint16_t sadb_comb_encrypt_minbits;
8020+ uint16_t sadb_comb_encrypt_maxbits;
8021+ uint32_t sadb_comb_reserved;
8022+ uint32_t sadb_comb_soft_allocations;
8023+ uint32_t sadb_comb_hard_allocations;
8024+ uint64_t sadb_comb_soft_bytes;
8025+ uint64_t sadb_comb_hard_bytes;
8026+ uint64_t sadb_comb_soft_addtime;
8027+ uint64_t sadb_comb_hard_addtime;
8028+ uint64_t sadb_comb_soft_usetime;
8029+ uint64_t sadb_comb_hard_usetime;
8030+ uint32_t sadb_x_comb_soft_packets;
8031+ uint32_t sadb_x_comb_hard_packets;
8032+};
8033+
8034+struct sadb_supported {
8035+ uint16_t sadb_supported_len;
8036+ uint16_t sadb_supported_exttype;
8037+ uint32_t sadb_supported_reserved;
8038+};
8039+
8040+struct sadb_alg {
8041+ uint8_t sadb_alg_id;
8042+ uint8_t sadb_alg_ivlen;
8043+ uint16_t sadb_alg_minbits;
8044+ uint16_t sadb_alg_maxbits;
8045+ uint16_t sadb_alg_reserved;
8046+};
8047+
8048+struct sadb_spirange {
8049+ uint16_t sadb_spirange_len;
8050+ uint16_t sadb_spirange_exttype;
8051+ uint32_t sadb_spirange_min;
8052+ uint32_t sadb_spirange_max;
8053+ uint32_t sadb_spirange_reserved;
8054+};
8055+
8056+struct sadb_x_kmprivate {
8057+ uint16_t sadb_x_kmprivate_len;
8058+ uint16_t sadb_x_kmprivate_exttype;
8059+ uint32_t sadb_x_kmprivate_reserved;
8060+};
8061+
8062+struct sadb_x_satype {
8063+ uint16_t sadb_x_satype_len;
8064+ uint16_t sadb_x_satype_exttype;
8065+ uint8_t sadb_x_satype_satype;
8066+ uint8_t sadb_x_satype_reserved[3];
8067+};
8068+
8069+struct sadb_x_policy {
8070+ uint16_t sadb_x_policy_len;
8071+ uint16_t sadb_x_policy_exttype;
8072+ uint16_t sadb_x_policy_type;
8073+ uint8_t sadb_x_policy_dir;
8074+ uint8_t sadb_x_policy_reserved;
8075+ uint32_t sadb_x_policy_id;
8076+ uint32_t sadb_x_policy_reserved2;
8077+};
8078+
8079+struct sadb_x_debug {
8080+ uint16_t sadb_x_debug_len;
8081+ uint16_t sadb_x_debug_exttype;
8082+ uint32_t sadb_x_debug_tunnel;
8083+ uint32_t sadb_x_debug_netlink;
8084+ uint32_t sadb_x_debug_xform;
8085+ uint32_t sadb_x_debug_eroute;
8086+ uint32_t sadb_x_debug_spi;
8087+ uint32_t sadb_x_debug_radij;
8088+ uint32_t sadb_x_debug_esp;
8089+ uint32_t sadb_x_debug_ah;
8090+ uint32_t sadb_x_debug_rcv;
8091+ uint32_t sadb_x_debug_pfkey;
8092+ uint32_t sadb_x_debug_ipcomp;
8093+ uint32_t sadb_x_debug_verbose;
8094+ uint8_t sadb_x_debug_reserved[4];
8095+};
8096+
8097+struct sadb_x_nat_t_type {
8098+ uint16_t sadb_x_nat_t_type_len;
8099+ uint16_t sadb_x_nat_t_type_exttype;
8100+ uint8_t sadb_x_nat_t_type_type;
8101+ uint8_t sadb_x_nat_t_type_reserved[3];
8102+};
8103+struct sadb_x_nat_t_port {
8104+ uint16_t sadb_x_nat_t_port_len;
8105+ uint16_t sadb_x_nat_t_port_exttype;
8106+ uint16_t sadb_x_nat_t_port_port;
8107+ uint16_t sadb_x_nat_t_port_reserved;
8108+};
8109+
8110+/*
8111+ * A protocol structure for passing through the transport level
8112+ * protocol. It contains more fields than are actually used/needed
8113+ * but it is this way to be compatible with the structure used in
8114+ * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
8115+ */
8116+struct sadb_protocol {
8117+ uint16_t sadb_protocol_len;
8118+ uint16_t sadb_protocol_exttype;
8119+ uint8_t sadb_protocol_proto;
8120+ uint8_t sadb_protocol_direction;
8121+ uint8_t sadb_protocol_flags;
8122+ uint8_t sadb_protocol_reserved2;
8123+};
8124+
8125+#define SADB_EXT_RESERVED 0
8126+#define SADB_EXT_SA 1
8127+#define SADB_EXT_LIFETIME_CURRENT 2
8128+#define SADB_EXT_LIFETIME_HARD 3
8129+#define SADB_EXT_LIFETIME_SOFT 4
8130+#define SADB_EXT_ADDRESS_SRC 5
8131+#define SADB_EXT_ADDRESS_DST 6
8132+#define SADB_EXT_ADDRESS_PROXY 7
8133+#define SADB_EXT_KEY_AUTH 8
8134+#define SADB_EXT_KEY_ENCRYPT 9
8135+#define SADB_EXT_IDENTITY_SRC 10
8136+#define SADB_EXT_IDENTITY_DST 11
8137+#define SADB_EXT_SENSITIVITY 12
8138+#define SADB_EXT_PROPOSAL 13
8139+#define SADB_EXT_SUPPORTED_AUTH 14
8140+#define SADB_EXT_SUPPORTED_ENCRYPT 15
8141+#define SADB_EXT_SPIRANGE 16
8142+#define SADB_X_EXT_KMPRIVATE 17
8143+#define SADB_X_EXT_SATYPE2 18
8144+#ifdef KERNEL26_HAS_KAME_DUPLICATES
8145+#define SADB_X_EXT_POLICY 18
8146+#endif
8147+#define SADB_X_EXT_SA2 19
8148+#define SADB_X_EXT_ADDRESS_DST2 20
8149+#define SADB_X_EXT_ADDRESS_SRC_FLOW 21
8150+#define SADB_X_EXT_ADDRESS_DST_FLOW 22
8151+#define SADB_X_EXT_ADDRESS_SRC_MASK 23
8152+#define SADB_X_EXT_ADDRESS_DST_MASK 24
8153+#define SADB_X_EXT_DEBUG 25
8154+#define SADB_X_EXT_PROTOCOL 26
8155+#define SADB_X_EXT_NAT_T_TYPE 27
8156+#define SADB_X_EXT_NAT_T_SPORT 28
8157+#define SADB_X_EXT_NAT_T_DPORT 29
8158+#define SADB_X_EXT_NAT_T_OA 30
8159+#define SADB_EXT_MAX 30
8160+
8161+/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
8162+#define SADB_X_EXT_ADDRESS_DELFLOW \
8163+ ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
8164+ | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
8165+ | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
8166+ | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
8167+
8168+#define SADB_SATYPE_UNSPEC 0
8169+#define SADB_SATYPE_AH 2
8170+#define SADB_SATYPE_ESP 3
8171+#define SADB_SATYPE_RSVP 5
8172+#define SADB_SATYPE_OSPFV2 6
8173+#define SADB_SATYPE_RIPV2 7
8174+#define SADB_SATYPE_MIP 8
8175+#define SADB_X_SATYPE_IPIP 9
8176+#ifdef KERNEL26_HAS_KAME_DUPLICATES
8177+#define SADB_X_SATYPE_IPCOMP 9 /* ICK! */
8178+#endif
8179+#define SADB_X_SATYPE_COMP 10
8180+#define SADB_X_SATYPE_INT 11
8181+#define SADB_SATYPE_MAX 11
8182+
8183+enum sadb_sastate {
8184+ SADB_SASTATE_LARVAL=0,
8185+ SADB_SASTATE_MATURE=1,
8186+ SADB_SASTATE_DYING=2,
8187+ SADB_SASTATE_DEAD=3
8188+};
8189+#define SADB_SASTATE_MAX 3
8190+
8191+#define SADB_SAFLAGS_PFS 1
8192+#define SADB_X_SAFLAGS_REPLACEFLOW 2
8193+#define SADB_X_SAFLAGS_CLEARFLOW 4
8194+#define SADB_X_SAFLAGS_INFLOW 8
8195+
8196+/* not obvious, but these are the same values as used in isakmp,
8197+ * and in freeswan/ipsec_policy.h. If you need to add any, they
8198+ * should be added as according to
8199+ * http://www.iana.org/assignments/isakmp-registry
8200+ *
8201+ * and if not, then please try to use a private-use value, and
8202+ * consider asking IANA to assign a value.
8203+ */
8204+#define SADB_AALG_NONE 0
8205+#define SADB_AALG_MD5HMAC 2
8206+#define SADB_AALG_SHA1HMAC 3
8207+#define SADB_X_AALG_SHA2_256HMAC 5
8208+#define SADB_X_AALG_SHA2_384HMAC 6
8209+#define SADB_X_AALG_SHA2_512HMAC 7
8210+#define SADB_X_AALG_RIPEMD160HMAC 8
8211+#define SADB_X_AALG_NULL 251 /* kame */
8212+#define SADB_AALG_MAX 251
8213+
8214+#define SADB_EALG_NONE 0
8215+#define SADB_EALG_DESCBC 2
8216+#define SADB_EALG_3DESCBC 3
8217+#define SADB_X_EALG_CASTCBC 6
8218+#define SADB_X_EALG_BLOWFISHCBC 7
8219+#define SADB_EALG_NULL 11
8220+#define SADB_X_EALG_AESCBC 12
8221+#define SADB_EALG_MAX 255
8222+
8223+#define SADB_X_CALG_NONE 0
8224+#define SADB_X_CALG_OUI 1
8225+#define SADB_X_CALG_DEFLATE 2
8226+#define SADB_X_CALG_LZS 3
8227+#define SADB_X_CALG_V42BIS 4
8228+#ifdef KERNEL26_HAS_KAME_DUPLICATES
8229+#define SADB_X_CALG_LZJH 4
8230+#endif
8231+#define SADB_X_CALG_MAX 4
8232+
8233+#define SADB_X_TALG_NONE 0
8234+#define SADB_X_TALG_IPv4_in_IPv4 1
8235+#define SADB_X_TALG_IPv6_in_IPv4 2
8236+#define SADB_X_TALG_IPv4_in_IPv6 3
8237+#define SADB_X_TALG_IPv6_in_IPv6 4
8238+#define SADB_X_TALG_MAX 4
8239+
8240+
8241+#define SADB_IDENTTYPE_RESERVED 0
8242+#define SADB_IDENTTYPE_PREFIX 1
8243+#define SADB_IDENTTYPE_FQDN 2
8244+#define SADB_IDENTTYPE_USERFQDN 3
8245+#define SADB_X_IDENTTYPE_CONNECTION 4
8246+#define SADB_IDENTTYPE_MAX 4
8247+
8248+#define SADB_KEY_FLAGS_MAX 0
8249+#endif /* __PFKEY_V2_H */
8250+
8251+/*
8252+ * $Log: pfkeyv2.h,v $
8253+ * Revision 1.31 2005-04-14 01:14:54 mcr
8254+ * change sadb_state to an enum.
8255+ *
8256+ * Revision 1.30 2004/04/06 02:49:00 mcr
8257+ * pullup of algo code from alg-branch.
8258+ *
8259+ * Revision 1.29 2003/12/22 21:35:58 mcr
8260+ * new patches from Dr{Who}.
8261+ *
8262+ * Revision 1.28 2003/12/22 19:33:15 mcr
8263+ * added 0.6c NAT-T patch.
8264+ *
8265+ * Revision 1.27 2003/12/10 01:20:01 mcr
8266+ * NAT-traversal patches to KLIPS.
8267+ *
8268+ * Revision 1.26 2003/10/31 02:26:44 mcr
8269+ * pulled up port-selector patches.
8270+ *
8271+ * Revision 1.25.4.1 2003/09/21 13:59:34 mcr
8272+ * pre-liminary X.509 patch - does not yet pass tests.
8273+ *
8274+ * Revision 1.25 2003/07/31 23:59:17 mcr
8275+ * re-introduce kernel 2.6 duplicate values for now.
8276+ * hope to get them changed!
8277+ *
8278+ * Revision 1.24 2003/07/31 22:55:27 mcr
8279+ * added some definitions to keep pfkeyv2.h files in sync.
8280+ *
8281+ * Revision 1.23 2003/05/11 00:43:48 mcr
8282+ * added comment about origin of values used
8283+ *
8284+ * Revision 1.22 2003/01/30 02:31:34 rgb
8285+ *
8286+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
8287+ *
8288+ * Revision 1.21 2002/12/16 19:26:49 mcr
8289+ * added definition of FS 1.xx sadb structure
8290+ *
8291+ * Revision 1.20 2002/09/20 15:40:25 rgb
8292+ * Added sadb_x_sa_ref to struct sadb_sa.
8293+ *
8294+ * Revision 1.19 2002/04/24 07:36:49 mcr
8295+ * Moved from ./lib/pfkeyv2.h,v
8296+ *
8297+ * Revision 1.18 2001/11/06 19:47:47 rgb
8298+ * Added packet parameter to lifetime and comb structures.
8299+ *
8300+ * Revision 1.17 2001/09/08 21:13:35 rgb
8301+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
8302+ *
8303+ * Revision 1.16 2001/07/06 19:49:46 rgb
8304+ * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks.
8305+ *
8306+ * Revision 1.15 2001/02/26 20:00:43 rgb
8307+ * Added internal IP protocol 61 for magic SAs.
8308+ *
8309+ * Revision 1.14 2001/02/08 18:51:05 rgb
8310+ * Include RFC document title and appendix subsection title.
8311+ *
8312+ * Revision 1.13 2000/10/10 20:10:20 rgb
8313+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
8314+ *
8315+ * Revision 1.12 2000/09/15 06:41:50 rgb
8316+ * Added V42BIS constant.
8317+ *
8318+ * Revision 1.11 2000/09/12 22:35:37 rgb
8319+ * Restructured to remove unused extensions from CLEARFLOW messages.
8320+ *
8321+ * Revision 1.10 2000/09/12 18:50:09 rgb
8322+ * Added IPIP tunnel types as algo support.
8323+ *
8324+ * Revision 1.9 2000/08/21 16:47:19 rgb
8325+ * Added SADB_X_CALG_* macros for IPCOMP.
8326+ *
8327+ * Revision 1.8 2000/08/09 20:43:34 rgb
8328+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
8329+ *
8330+ * Revision 1.7 2000/01/21 06:28:37 rgb
8331+ * Added flow add/delete message type macros.
8332+ * Added flow address extension type macros.
8333+ * Tidied up spacing.
8334+ * Added klipsdebug switching capability.
8335+ *
8336+ * Revision 1.6 1999/11/27 11:56:08 rgb
8337+ * Add SADB_X_SATYPE_COMP for compression, eventually.
8338+ *
8339+ * Revision 1.5 1999/11/23 22:23:16 rgb
8340+ * This file has been moved in the distribution from klips/net/ipsec to
8341+ * lib.
8342+ *
8343+ * Revision 1.4 1999/04/29 15:23:29 rgb
8344+ * Add GRPSA support.
8345+ * Add support for a second SATYPE, SA and DST_ADDRESS.
8346+ * Add IPPROTO_IPIP support.
8347+ *
8348+ * Revision 1.3 1999/04/15 17:58:08 rgb
8349+ * Add RCSID labels.
8350+ *
8351+ */
8352--- /dev/null Tue Mar 11 13:02:56 2003
8353+++ linux/include/zlib/zconf.h Mon Feb 9 13:51:03 2004
8354@@ -0,0 +1,309 @@
8355+/* zconf.h -- configuration of the zlib compression library
8356+ * Copyright (C) 1995-2002 Jean-loup Gailly.
8357+ * For conditions of distribution and use, see copyright notice in zlib.h
8358+ */
8359+
8360+/* @(#) $Id: zconf.h,v 1.4 2004-07-10 07:48:40 mcr Exp $ */
8361+
8362+#ifndef _ZCONF_H
8363+#define _ZCONF_H
8364+
8365+/*
8366+ * If you *really* need a unique prefix for all types and library functions,
8367+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
8368+ */
8369+#ifdef IPCOMP_PREFIX
8370+# define deflateInit_ ipcomp_deflateInit_
8371+# define deflate ipcomp_deflate
8372+# define deflateEnd ipcomp_deflateEnd
8373+# define inflateInit_ ipcomp_inflateInit_
8374+# define inflate ipcomp_inflate
8375+# define inflateEnd ipcomp_inflateEnd
8376+# define deflateInit2_ ipcomp_deflateInit2_
8377+# define deflateSetDictionary ipcomp_deflateSetDictionary
8378+# define deflateCopy ipcomp_deflateCopy
8379+# define deflateReset ipcomp_deflateReset
8380+# define deflateParams ipcomp_deflateParams
8381+# define inflateInit2_ ipcomp_inflateInit2_
8382+# define inflateSetDictionary ipcomp_inflateSetDictionary
8383+# define inflateSync ipcomp_inflateSync
8384+# define inflateSyncPoint ipcomp_inflateSyncPoint
8385+# define inflateReset ipcomp_inflateReset
8386+# define compress ipcomp_compress
8387+# define compress2 ipcomp_compress2
8388+# define uncompress ipcomp_uncompress
8389+# define adler32 ipcomp_adler32
8390+# define crc32 ipcomp_crc32
8391+# define get_crc_table ipcomp_get_crc_table
8392+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
8393+# define inflate_blocks ipcomp_deflate_blocks
8394+# define inflate_blocks_free ipcomp_deflate_blocks_free
8395+# define inflate_blocks_new ipcomp_inflate_blocks_new
8396+# define inflate_blocks_reset ipcomp_inflate_blocks_reset
8397+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
8398+# define inflate_set_dictionary ipcomp_inflate_set_dictionary
8399+# define inflate_codes ipcomp_inflate_codes
8400+# define inflate_codes_free ipcomp_inflate_codes_free
8401+# define inflate_codes_new ipcomp_inflate_codes_new
8402+# define inflate_fast ipcomp_inflate_fast
8403+# define inflate_trees_bits ipcomp_inflate_trees_bits
8404+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
8405+# define inflate_trees_fixed ipcomp_inflate_trees_fixed
8406+# define inflate_flush ipcomp_inflate_flush
8407+# define inflate_mask ipcomp_inflate_mask
8408+# define _dist_code _ipcomp_dist_code
8409+# define _length_code _ipcomp_length_code
8410+# define _tr_align _ipcomp_tr_align
8411+# define _tr_flush_block _ipcomp_tr_flush_block
8412+# define _tr_init _ipcomp_tr_init
8413+# define _tr_stored_block _ipcomp_tr_stored_block
8414+# define _tr_tally _ipcomp_tr_tally
8415+# define zError ipcomp_zError
8416+# define z_errmsg ipcomp_z_errmsg
8417+# define zlibVersion ipcomp_zlibVersion
8418+# define match_init ipcomp_match_init
8419+# define longest_match ipcomp_longest_match
8420+#endif
8421+
8422+#ifdef Z_PREFIX
8423+# define Byte z_Byte
8424+# define uInt z_uInt
8425+# define uLong z_uLong
8426+# define Bytef z_Bytef
8427+# define charf z_charf
8428+# define intf z_intf
8429+# define uIntf z_uIntf
8430+# define uLongf z_uLongf
8431+# define voidpf z_voidpf
8432+# define voidp z_voidp
8433+#endif
8434+
8435+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
8436+# define WIN32
8437+#endif
8438+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
8439+# ifndef __32BIT__
8440+# define __32BIT__
8441+# endif
8442+#endif
8443+#if defined(__MSDOS__) && !defined(MSDOS)
8444+# define MSDOS
8445+#endif
8446+
8447+/*
8448+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
8449+ * than 64k bytes at a time (needed on systems with 16-bit int).
8450+ */
8451+#if defined(MSDOS) && !defined(__32BIT__)
8452+# define MAXSEG_64K
8453+#endif
8454+#ifdef MSDOS
8455+# define UNALIGNED_OK
8456+#endif
8457+
8458+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
8459+# define STDC
8460+#endif
8461+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
8462+# ifndef STDC
8463+# define STDC
8464+# endif
8465+#endif
8466+
8467+#ifndef STDC
8468+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
8469+# define const
8470+# endif
8471+#endif
8472+
8473+/* Some Mac compilers merge all .h files incorrectly: */
8474+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
8475+# define NO_DUMMY_DECL
8476+#endif
8477+
8478+/* Old Borland C incorrectly complains about missing returns: */
8479+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
8480+# define NEED_DUMMY_RETURN
8481+#endif
8482+
8483+
8484+/* Maximum value for memLevel in deflateInit2 */
8485+#ifndef MAX_MEM_LEVEL
8486+# ifdef MAXSEG_64K
8487+# define MAX_MEM_LEVEL 8
8488+# else
8489+# define MAX_MEM_LEVEL 9
8490+# endif
8491+#endif
8492+
8493+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
8494+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
8495+ * created by gzip. (Files created by minigzip can still be extracted by
8496+ * gzip.)
8497+ */
8498+#ifndef MAX_WBITS
8499+# define MAX_WBITS 15 /* 32K LZ77 window */
8500+#endif
8501+
8502+/* The memory requirements for deflate are (in bytes):
8503+ (1 << (windowBits+2)) + (1 << (memLevel+9))
8504+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
8505+ plus a few kilobytes for small objects. For example, if you want to reduce
8506+ the default memory requirements from 256K to 128K, compile with
8507+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
8508+ Of course this will generally degrade compression (there's no free lunch).
8509+
8510+ The memory requirements for inflate are (in bytes) 1 << windowBits
8511+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
8512+ for small objects.
8513+*/
8514+
8515+ /* Type declarations */
8516+
8517+#ifndef OF /* function prototypes */
8518+# ifdef STDC
8519+# define OF(args) args
8520+# else
8521+# define OF(args) ()
8522+# endif
8523+#endif
8524+
8525+/* The following definitions for FAR are needed only for MSDOS mixed
8526+ * model programming (small or medium model with some far allocations).
8527+ * This was tested only with MSC; for other MSDOS compilers you may have
8528+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
8529+ * just define FAR to be empty.
8530+ */
8531+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
8532+ /* MSC small or medium model */
8533+# define SMALL_MEDIUM
8534+# ifdef _MSC_VER
8535+# define FAR _far
8536+# else
8537+# define FAR far
8538+# endif
8539+#endif
8540+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
8541+# ifndef __32BIT__
8542+# define SMALL_MEDIUM
8543+# define FAR _far
8544+# endif
8545+#endif
8546+
8547+/* Compile with -DZLIB_DLL for Windows DLL support */
8548+#if defined(ZLIB_DLL)
8549+# if defined(_WINDOWS) || defined(WINDOWS)
8550+# ifdef FAR
8551+# undef FAR
8552+# endif
8553+# include <windows.h>
8554+# define ZEXPORT WINAPI
8555+# ifdef WIN32
8556+# define ZEXPORTVA WINAPIV
8557+# else
8558+# define ZEXPORTVA FAR _cdecl _export
8559+# endif
8560+# endif
8561+# if defined (__BORLANDC__)
8562+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
8563+# include <windows.h>
8564+# define ZEXPORT __declspec(dllexport) WINAPI
8565+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
8566+# else
8567+# if defined (_Windows) && defined (__DLL__)
8568+# define ZEXPORT _export
8569+# define ZEXPORTVA _export
8570+# endif
8571+# endif
8572+# endif
8573+#endif
8574+
8575+#if defined (__BEOS__)
8576+# if defined (ZLIB_DLL)
8577+# define ZEXTERN extern __declspec(dllexport)
8578+# else
8579+# define ZEXTERN extern __declspec(dllimport)
8580+# endif
8581+#endif
8582+
8583+#ifndef ZEXPORT
8584+# define ZEXPORT
8585+#endif
8586+#ifndef ZEXPORTVA
8587+# define ZEXPORTVA
8588+#endif
8589+#ifndef ZEXTERN
8590+# define ZEXTERN extern
8591+#endif
8592+
8593+#ifndef FAR
8594+# define FAR
8595+#endif
8596+
8597+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
8598+typedef unsigned char Byte; /* 8 bits */
8599+#endif
8600+typedef unsigned int uInt; /* 16 bits or more */
8601+typedef unsigned long uLong; /* 32 bits or more */
8602+
8603+#ifdef SMALL_MEDIUM
8604+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
8605+# define Bytef Byte FAR
8606+#else
8607+ typedef Byte FAR Bytef;
8608+#endif
8609+typedef char FAR charf;
8610+typedef int FAR intf;
8611+typedef uInt FAR uIntf;
8612+typedef uLong FAR uLongf;
8613+
8614+#ifdef STDC
8615+ typedef void FAR *voidpf;
8616+ typedef void *voidp;
8617+#else
8618+ typedef Byte FAR *voidpf;
8619+ typedef Byte *voidp;
8620+#endif
8621+
8622+#ifdef HAVE_UNISTD_H
8623+# include <sys/types.h> /* for off_t */
8624+# include <unistd.h> /* for SEEK_* and off_t */
8625+# define z_off_t off_t
8626+#endif
8627+#ifndef SEEK_SET
8628+# define SEEK_SET 0 /* Seek from beginning of file. */
8629+# define SEEK_CUR 1 /* Seek from current position. */
8630+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
8631+#endif
8632+#ifndef z_off_t
8633+# define z_off_t long
8634+#endif
8635+
8636+/* MVS linker does not support external names larger than 8 bytes */
8637+#if defined(__MVS__)
8638+# pragma map(deflateInit_,"DEIN")
8639+# pragma map(deflateInit2_,"DEIN2")
8640+# pragma map(deflateEnd,"DEEND")
8641+# pragma map(inflateInit_,"ININ")
8642+# pragma map(inflateInit2_,"ININ2")
8643+# pragma map(inflateEnd,"INEND")
8644+# pragma map(inflateSync,"INSY")
8645+# pragma map(inflateSetDictionary,"INSEDI")
8646+# pragma map(inflate_blocks,"INBL")
8647+# pragma map(inflate_blocks_new,"INBLNE")
8648+# pragma map(inflate_blocks_free,"INBLFR")
8649+# pragma map(inflate_blocks_reset,"INBLRE")
8650+# pragma map(inflate_codes_free,"INCOFR")
8651+# pragma map(inflate_codes,"INCO")
8652+# pragma map(inflate_fast,"INFA")
8653+# pragma map(inflate_flush,"INFLU")
8654+# pragma map(inflate_mask,"INMA")
8655+# pragma map(inflate_set_dictionary,"INSEDI2")
8656+# pragma map(ipcomp_inflate_copyright,"INCOPY")
8657+# pragma map(inflate_trees_bits,"INTRBI")
8658+# pragma map(inflate_trees_dynamic,"INTRDY")
8659+# pragma map(inflate_trees_fixed,"INTRFI")
8660+# pragma map(inflate_trees_free,"INTRFR")
8661+#endif
8662+
8663+#endif /* _ZCONF_H */
8664--- /dev/null Tue Mar 11 13:02:56 2003
8665+++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004
8666@@ -0,0 +1,893 @@
8667+/* zlib.h -- interface of the 'zlib' general purpose compression library
8668+ version 1.1.4, March 11th, 2002
8669+
8670+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
8671+
8672+ This software is provided 'as-is', without any express or implied
8673+ warranty. In no event will the authors be held liable for any damages
8674+ arising from the use of this software.
8675+
8676+ Permission is granted to anyone to use this software for any purpose,
8677+ including commercial applications, and to alter it and redistribute it
8678+ freely, subject to the following restrictions:
8679+
8680+ 1. The origin of this software must not be misrepresented; you must not
8681+ claim that you wrote the original software. If you use this software
8682+ in a product, an acknowledgment in the product documentation would be
8683+ appreciated but is not required.
8684+ 2. Altered source versions must be plainly marked as such, and must not be
8685+ misrepresented as being the original software.
8686+ 3. This notice may not be removed or altered from any source distribution.
8687+
8688+ Jean-loup Gailly Mark Adler
8689+ jloup@gzip.org madler@alumni.caltech.edu
8690+
8691+
8692+ The data format used by the zlib library is described by RFCs (Request for
8693+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
8694+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
8695+*/
8696+
8697+#ifndef _ZLIB_H
8698+#define _ZLIB_H
8699+
8700+#include "zconf.h"
8701+
8702+#ifdef __cplusplus
8703+extern "C" {
8704+#endif
8705+
8706+#define ZLIB_VERSION "1.1.4"
8707+
8708+/*
8709+ The 'zlib' compression library provides in-memory compression and
8710+ decompression functions, including integrity checks of the uncompressed
8711+ data. This version of the library supports only one compression method
8712+ (deflation) but other algorithms will be added later and will have the same
8713+ stream interface.
8714+
8715+ Compression can be done in a single step if the buffers are large
8716+ enough (for example if an input file is mmap'ed), or can be done by
8717+ repeated calls of the compression function. In the latter case, the
8718+ application must provide more input and/or consume the output
8719+ (providing more output space) before each call.
8720+
8721+ The library also supports reading and writing files in gzip (.gz) format
8722+ with an interface similar to that of stdio.
8723+
8724+ The library does not install any signal handler. The decoder checks
8725+ the consistency of the compressed data, so the library should never
8726+ crash even in case of corrupted input.
8727+*/
8728+
8729+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
8730+typedef void (*free_func) OF((voidpf opaque, voidpf address));
8731+
8732+struct internal_state;
8733+
8734+typedef struct z_stream_s {
8735+ Bytef *next_in; /* next input byte */
8736+ uInt avail_in; /* number of bytes available at next_in */
8737+ uLong total_in; /* total nb of input bytes read so far */
8738+
8739+ Bytef *next_out; /* next output byte should be put there */
8740+ uInt avail_out; /* remaining free space at next_out */
8741+ uLong total_out; /* total nb of bytes output so far */
8742+
8743+ const char *msg; /* last error message, NULL if no error */
8744+ struct internal_state FAR *state; /* not visible by applications */
8745+
8746+ alloc_func zalloc; /* used to allocate the internal state */
8747+ free_func zfree; /* used to free the internal state */
8748+ voidpf opaque; /* private data object passed to zalloc and zfree */
8749+
8750+ int data_type; /* best guess about the data type: ascii or binary */
8751+ uLong adler; /* adler32 value of the uncompressed data */
8752+ uLong reserved; /* reserved for future use */
8753+} z_stream;
8754+
8755+typedef z_stream FAR *z_streamp;
8756+
8757+/*
8758+ The application must update next_in and avail_in when avail_in has
8759+ dropped to zero. It must update next_out and avail_out when avail_out
8760+ has dropped to zero. The application must initialize zalloc, zfree and
8761+ opaque before calling the init function. All other fields are set by the
8762+ compression library and must not be updated by the application.
8763+
8764+ The opaque value provided by the application will be passed as the first
8765+ parameter for calls of zalloc and zfree. This can be useful for custom
8766+ memory management. The compression library attaches no meaning to the
8767+ opaque value.
8768+
8769+ zalloc must return Z_NULL if there is not enough memory for the object.
8770+ If zlib is used in a multi-threaded application, zalloc and zfree must be
8771+ thread safe.
8772+
8773+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
8774+ exactly 65536 bytes, but will not be required to allocate more than this
8775+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
8776+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
8777+ have their offset normalized to zero. The default allocation function
8778+ provided by this library ensures this (see zutil.c). To reduce memory
8779+ requirements and avoid any allocation of 64K objects, at the expense of
8780+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
8781+
8782+ The fields total_in and total_out can be used for statistics or
8783+ progress reports. After compression, total_in holds the total size of
8784+ the uncompressed data and may be saved for use in the decompressor
8785+ (particularly if the decompressor wants to decompress everything in
8786+ a single step).
8787+*/
8788+
8789+ /* constants */
8790+
8791+#define Z_NO_FLUSH 0
8792+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
8793+#define Z_SYNC_FLUSH 2
8794+#define Z_FULL_FLUSH 3
8795+#define Z_FINISH 4
8796+/* Allowed flush values; see deflate() below for details */
8797+
8798+#define Z_OK 0
8799+#define Z_STREAM_END 1
8800+#define Z_NEED_DICT 2
8801+#define Z_ERRNO (-1)
8802+#define Z_STREAM_ERROR (-2)
8803+#define Z_DATA_ERROR (-3)
8804+#define Z_MEM_ERROR (-4)
8805+#define Z_BUF_ERROR (-5)
8806+#define Z_VERSION_ERROR (-6)
8807+/* Return codes for the compression/decompression functions. Negative
8808+ * values are errors, positive values are used for special but normal events.
8809+ */
8810+
8811+#define Z_NO_COMPRESSION 0
8812+#define Z_BEST_SPEED 1
8813+#define Z_BEST_COMPRESSION 9
8814+#define Z_DEFAULT_COMPRESSION (-1)
8815+/* compression levels */
8816+
8817+#define Z_FILTERED 1
8818+#define Z_HUFFMAN_ONLY 2
8819+#define Z_DEFAULT_STRATEGY 0
8820+/* compression strategy; see deflateInit2() below for details */
8821+
8822+#define Z_BINARY 0
8823+#define Z_ASCII 1
8824+#define Z_UNKNOWN 2
8825+/* Possible values of the data_type field */
8826+
8827+#define Z_DEFLATED 8
8828+/* The deflate compression method (the only one supported in this version) */
8829+
8830+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
8831+
8832+#define zlib_version zlibVersion()
8833+/* for compatibility with versions < 1.0.2 */
8834+
8835+ /* basic functions */
8836+
8837+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
8838+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
8839+ If the first character differs, the library code actually used is
8840+ not compatible with the zlib.h header file used by the application.
8841+ This check is automatically made by deflateInit and inflateInit.
8842+ */
8843+
8844+/*
8845+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
8846+
8847+ Initializes the internal stream state for compression. The fields
8848+ zalloc, zfree and opaque must be initialized before by the caller.
8849+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
8850+ use default allocation functions.
8851+
8852+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
8853+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
8854+ all (the input data is simply copied a block at a time).
8855+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
8856+ compression (currently equivalent to level 6).
8857+
8858+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
8859+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
8860+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
8861+ with the version assumed by the caller (ZLIB_VERSION).
8862+ msg is set to null if there is no error message. deflateInit does not
8863+ perform any compression: this will be done by deflate().
8864+*/
8865+
8866+
8867+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
8868+/*
8869+ deflate compresses as much data as possible, and stops when the input
8870+ buffer becomes empty or the output buffer becomes full. It may introduce some
8871+ output latency (reading input without producing any output) except when
8872+ forced to flush.
8873+
8874+ The detailed semantics are as follows. deflate performs one or both of the
8875+ following actions:
8876+
8877+ - Compress more input starting at next_in and update next_in and avail_in
8878+ accordingly. If not all input can be processed (because there is not
8879+ enough room in the output buffer), next_in and avail_in are updated and
8880+ processing will resume at this point for the next call of deflate().
8881+
8882+ - Provide more output starting at next_out and update next_out and avail_out
8883+ accordingly. This action is forced if the parameter flush is non zero.
8884+ Forcing flush frequently degrades the compression ratio, so this parameter
8885+ should be set only when necessary (in interactive applications).
8886+ Some output may be provided even if flush is not set.
8887+
8888+ Before the call of deflate(), the application should ensure that at least
8889+ one of the actions is possible, by providing more input and/or consuming
8890+ more output, and updating avail_in or avail_out accordingly; avail_out
8891+ should never be zero before the call. The application can consume the
8892+ compressed output when it wants, for example when the output buffer is full
8893+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
8894+ and with zero avail_out, it must be called again after making room in the
8895+ output buffer because there might be more output pending.
8896+
8897+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
8898+ flushed to the output buffer and the output is aligned on a byte boundary, so
8899+ that the decompressor can get all input data available so far. (In particular
8900+ avail_in is zero after the call if enough output space has been provided
8901+ before the call.) Flushing may degrade compression for some compression
8902+ algorithms and so it should be used only when necessary.
8903+
8904+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
8905+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
8906+ restart from this point if previous compressed data has been damaged or if
8907+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
8908+ the compression.
8909+
8910+ If deflate returns with avail_out == 0, this function must be called again
8911+ with the same value of the flush parameter and more output space (updated
8912+ avail_out), until the flush is complete (deflate returns with non-zero
8913+ avail_out).
8914+
8915+ If the parameter flush is set to Z_FINISH, pending input is processed,
8916+ pending output is flushed and deflate returns with Z_STREAM_END if there
8917+ was enough output space; if deflate returns with Z_OK, this function must be
8918+ called again with Z_FINISH and more output space (updated avail_out) but no
8919+ more input data, until it returns with Z_STREAM_END or an error. After
8920+ deflate has returned Z_STREAM_END, the only possible operations on the
8921+ stream are deflateReset or deflateEnd.
8922+
8923+ Z_FINISH can be used immediately after deflateInit if all the compression
8924+ is to be done in a single step. In this case, avail_out must be at least
8925+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
8926+ Z_STREAM_END, then it must be called again as described above.
8927+
8928+ deflate() sets strm->adler to the adler32 checksum of all input read
8929+ so far (that is, total_in bytes).
8930+
8931+ deflate() may update data_type if it can make a good guess about
8932+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
8933+ binary. This field is only for information purposes and does not affect
8934+ the compression algorithm in any manner.
8935+
8936+ deflate() returns Z_OK if some progress has been made (more input
8937+ processed or more output produced), Z_STREAM_END if all input has been
8938+ consumed and all output has been produced (only when flush is set to
8939+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
8940+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
8941+ (for example avail_in or avail_out was zero).
8942+*/
8943+
8944+
8945+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
8946+/*
8947+ All dynamically allocated data structures for this stream are freed.
8948+ This function discards any unprocessed input and does not flush any
8949+ pending output.
8950+
8951+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
8952+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
8953+ prematurely (some input or output was discarded). In the error case,
8954+ msg may be set but then points to a static string (which must not be
8955+ deallocated).
8956+*/
8957+
8958+
8959+/*
8960+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
8961+
8962+ Initializes the internal stream state for decompression. The fields
8963+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
8964+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
8965+ value depends on the compression method), inflateInit determines the
8966+ compression method from the zlib header and allocates all data structures
8967+ accordingly; otherwise the allocation will be deferred to the first call of
8968+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
8969+ use default allocation functions.
8970+
8971+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
8972+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
8973+ version assumed by the caller. msg is set to null if there is no error
8974+ message. inflateInit does not perform any decompression apart from reading
8975+ the zlib header if present: this will be done by inflate(). (So next_in and
8976+ avail_in may be modified, but next_out and avail_out are unchanged.)
8977+*/
8978+
8979+
8980+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
8981+/*
8982+ inflate decompresses as much data as possible, and stops when the input
8983+ buffer becomes empty or the output buffer becomes full. It may some
8984+ introduce some output latency (reading input without producing any output)
8985+ except when forced to flush.
8986+
8987+ The detailed semantics are as follows. inflate performs one or both of the
8988+ following actions:
8989+
8990+ - Decompress more input starting at next_in and update next_in and avail_in
8991+ accordingly. If not all input can be processed (because there is not
8992+ enough room in the output buffer), next_in is updated and processing
8993+ will resume at this point for the next call of inflate().
8994+
8995+ - Provide more output starting at next_out and update next_out and avail_out
8996+ accordingly. inflate() provides as much output as possible, until there
8997+ is no more input data or no more space in the output buffer (see below
8998+ about the flush parameter).
8999+
9000+ Before the call of inflate(), the application should ensure that at least
9001+ one of the actions is possible, by providing more input and/or consuming
9002+ more output, and updating the next_* and avail_* values accordingly.
9003+ The application can consume the uncompressed output when it wants, for
9004+ example when the output buffer is full (avail_out == 0), or after each
9005+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
9006+ must be called again after making room in the output buffer because there
9007+ might be more output pending.
9008+
9009+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
9010+ output as possible to the output buffer. The flushing behavior of inflate is
9011+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
9012+ and Z_FINISH, but the current implementation actually flushes as much output
9013+ as possible anyway.
9014+
9015+ inflate() should normally be called until it returns Z_STREAM_END or an
9016+ error. However if all decompression is to be performed in a single step
9017+ (a single call of inflate), the parameter flush should be set to
9018+ Z_FINISH. In this case all pending input is processed and all pending
9019+ output is flushed; avail_out must be large enough to hold all the
9020+ uncompressed data. (The size of the uncompressed data may have been saved
9021+ by the compressor for this purpose.) The next operation on this stream must
9022+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
9023+ is never required, but can be used to inform inflate that a faster routine
9024+ may be used for the single inflate() call.
9025+
9026+ If a preset dictionary is needed at this point (see inflateSetDictionary
9027+ below), inflate sets strm-adler to the adler32 checksum of the
9028+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
9029+ it sets strm->adler to the adler32 checksum of all output produced
9030+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
9031+ an error code as described below. At the end of the stream, inflate()
9032+ checks that its computed adler32 checksum is equal to that saved by the
9033+ compressor and returns Z_STREAM_END only if the checksum is correct.
9034+
9035+ inflate() returns Z_OK if some progress has been made (more input processed
9036+ or more output produced), Z_STREAM_END if the end of the compressed data has
9037+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
9038+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
9039+ corrupted (input stream not conforming to the zlib format or incorrect
9040+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
9041+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
9042+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
9043+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
9044+ case, the application may then call inflateSync to look for a good
9045+ compression block.
9046+*/
9047+
9048+
9049+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
9050+/*
9051+ All dynamically allocated data structures for this stream are freed.
9052+ This function discards any unprocessed input and does not flush any
9053+ pending output.
9054+
9055+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
9056+ was inconsistent. In the error case, msg may be set but then points to a
9057+ static string (which must not be deallocated).
9058+*/
9059+
9060+ /* Advanced functions */
9061+
9062+/*
9063+ The following functions are needed only in some special applications.
9064+*/
9065+
9066+/*
9067+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
9068+ int level,
9069+ int method,
9070+ int windowBits,
9071+ int memLevel,
9072+ int strategy));
9073+
9074+ This is another version of deflateInit with more compression options. The
9075+ fields next_in, zalloc, zfree and opaque must be initialized before by
9076+ the caller.
9077+
9078+ The method parameter is the compression method. It must be Z_DEFLATED in
9079+ this version of the library.
9080+
9081+ The windowBits parameter is the base two logarithm of the window size
9082+ (the size of the history buffer). It should be in the range 8..15 for this
9083+ version of the library. Larger values of this parameter result in better
9084+ compression at the expense of memory usage. The default value is 15 if
9085+ deflateInit is used instead.
9086+
9087+ The memLevel parameter specifies how much memory should be allocated
9088+ for the internal compression state. memLevel=1 uses minimum memory but
9089+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
9090+ for optimal speed. The default value is 8. See zconf.h for total memory
9091+ usage as a function of windowBits and memLevel.
9092+
9093+ The strategy parameter is used to tune the compression algorithm. Use the
9094+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
9095+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
9096+ string match). Filtered data consists mostly of small values with a
9097+ somewhat random distribution. In this case, the compression algorithm is
9098+ tuned to compress them better. The effect of Z_FILTERED is to force more
9099+ Huffman coding and less string matching; it is somewhat intermediate
9100+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
9101+ the compression ratio but not the correctness of the compressed output even
9102+ if it is not set appropriately.
9103+
9104+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9105+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
9106+ method). msg is set to null if there is no error message. deflateInit2 does
9107+ not perform any compression: this will be done by deflate().
9108+*/
9109+
9110+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
9111+ const Bytef *dictionary,
9112+ uInt dictLength));
9113+/*
9114+ Initializes the compression dictionary from the given byte sequence
9115+ without producing any compressed output. This function must be called
9116+ immediately after deflateInit, deflateInit2 or deflateReset, before any
9117+ call of deflate. The compressor and decompressor must use exactly the same
9118+ dictionary (see inflateSetDictionary).
9119+
9120+ The dictionary should consist of strings (byte sequences) that are likely
9121+ to be encountered later in the data to be compressed, with the most commonly
9122+ used strings preferably put towards the end of the dictionary. Using a
9123+ dictionary is most useful when the data to be compressed is short and can be
9124+ predicted with good accuracy; the data can then be compressed better than
9125+ with the default empty dictionary.
9126+
9127+ Depending on the size of the compression data structures selected by
9128+ deflateInit or deflateInit2, a part of the dictionary may in effect be
9129+ discarded, for example if the dictionary is larger than the window size in
9130+ deflate or deflate2. Thus the strings most likely to be useful should be
9131+ put at the end of the dictionary, not at the front.
9132+
9133+ Upon return of this function, strm->adler is set to the Adler32 value
9134+ of the dictionary; the decompressor may later use this value to determine
9135+ which dictionary has been used by the compressor. (The Adler32 value
9136+ applies to the whole dictionary even if only a subset of the dictionary is
9137+ actually used by the compressor.)
9138+
9139+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
9140+ parameter is invalid (such as NULL dictionary) or the stream state is
9141+ inconsistent (for example if deflate has already been called for this stream
9142+ or if the compression method is bsort). deflateSetDictionary does not
9143+ perform any compression: this will be done by deflate().
9144+*/
9145+
9146+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
9147+ z_streamp source));
9148+/*
9149+ Sets the destination stream as a complete copy of the source stream.
9150+
9151+ This function can be useful when several compression strategies will be
9152+ tried, for example when there are several ways of pre-processing the input
9153+ data with a filter. The streams that will be discarded should then be freed
9154+ by calling deflateEnd. Note that deflateCopy duplicates the internal
9155+ compression state which can be quite large, so this strategy is slow and
9156+ can consume lots of memory.
9157+
9158+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
9159+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
9160+ (such as zalloc being NULL). msg is left unchanged in both source and
9161+ destination.
9162+*/
9163+
9164+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
9165+/*
9166+ This function is equivalent to deflateEnd followed by deflateInit,
9167+ but does not free and reallocate all the internal compression state.
9168+ The stream will keep the same compression level and any other attributes
9169+ that may have been set by deflateInit2.
9170+
9171+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9172+ stream state was inconsistent (such as zalloc or state being NULL).
9173+*/
9174+
9175+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
9176+ int level,
9177+ int strategy));
9178+/*
9179+ Dynamically update the compression level and compression strategy. The
9180+ interpretation of level and strategy is as in deflateInit2. This can be
9181+ used to switch between compression and straight copy of the input data, or
9182+ to switch to a different kind of input data requiring a different
9183+ strategy. If the compression level is changed, the input available so far
9184+ is compressed with the old level (and may be flushed); the new level will
9185+ take effect only at the next call of deflate().
9186+
9187+ Before the call of deflateParams, the stream state must be set as for
9188+ a call of deflate(), since the currently available input may have to
9189+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
9190+
9191+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
9192+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
9193+ if strm->avail_out was zero.
9194+*/
9195+
9196+/*
9197+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
9198+ int windowBits));
9199+
9200+ This is another version of inflateInit with an extra parameter. The
9201+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
9202+ before by the caller.
9203+
9204+ The windowBits parameter is the base two logarithm of the maximum window
9205+ size (the size of the history buffer). It should be in the range 8..15 for
9206+ this version of the library. The default value is 15 if inflateInit is used
9207+ instead. If a compressed stream with a larger window size is given as
9208+ input, inflate() will return with the error code Z_DATA_ERROR instead of
9209+ trying to allocate a larger window.
9210+
9211+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9212+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
9213+ memLevel). msg is set to null if there is no error message. inflateInit2
9214+ does not perform any decompression apart from reading the zlib header if
9215+ present: this will be done by inflate(). (So next_in and avail_in may be
9216+ modified, but next_out and avail_out are unchanged.)
9217+*/
9218+
9219+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
9220+ const Bytef *dictionary,
9221+ uInt dictLength));
9222+/*
9223+ Initializes the decompression dictionary from the given uncompressed byte
9224+ sequence. This function must be called immediately after a call of inflate
9225+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
9226+ can be determined from the Adler32 value returned by this call of
9227+ inflate. The compressor and decompressor must use exactly the same
9228+ dictionary (see deflateSetDictionary).
9229+
9230+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
9231+ parameter is invalid (such as NULL dictionary) or the stream state is
9232+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
9233+ expected one (incorrect Adler32 value). inflateSetDictionary does not
9234+ perform any decompression: this will be done by subsequent calls of
9235+ inflate().
9236+*/
9237+
9238+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
9239+/*
9240+ Skips invalid compressed data until a full flush point (see above the
9241+ description of deflate with Z_FULL_FLUSH) can be found, or until all
9242+ available input is skipped. No output is provided.
9243+
9244+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
9245+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
9246+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
9247+ case, the application may save the current current value of total_in which
9248+ indicates where valid compressed data was found. In the error case, the
9249+ application may repeatedly call inflateSync, providing more input each time,
9250+ until success or end of the input data.
9251+*/
9252+
9253+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
9254+/*
9255+ This function is equivalent to inflateEnd followed by inflateInit,
9256+ but does not free and reallocate all the internal decompression state.
9257+ The stream will keep attributes that may have been set by inflateInit2.
9258+
9259+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9260+ stream state was inconsistent (such as zalloc or state being NULL).
9261+*/
9262+
9263+
9264+ /* utility functions */
9265+
9266+/*
9267+ The following utility functions are implemented on top of the
9268+ basic stream-oriented functions. To simplify the interface, some
9269+ default options are assumed (compression level and memory usage,
9270+ standard memory allocation functions). The source code of these
9271+ utility functions can easily be modified if you need special options.
9272+*/
9273+
9274+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
9275+ const Bytef *source, uLong sourceLen));
9276+/*
9277+ Compresses the source buffer into the destination buffer. sourceLen is
9278+ the byte length of the source buffer. Upon entry, destLen is the total
9279+ size of the destination buffer, which must be at least 0.1% larger than
9280+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
9281+ compressed buffer.
9282+ This function can be used to compress a whole file at once if the
9283+ input file is mmap'ed.
9284+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
9285+ enough memory, Z_BUF_ERROR if there was not enough room in the output
9286+ buffer.
9287+*/
9288+
9289+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
9290+ const Bytef *source, uLong sourceLen,
9291+ int level));
9292+/*
9293+ Compresses the source buffer into the destination buffer. The level
9294+ parameter has the same meaning as in deflateInit. sourceLen is the byte
9295+ length of the source buffer. Upon entry, destLen is the total size of the
9296+ destination buffer, which must be at least 0.1% larger than sourceLen plus
9297+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
9298+
9299+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9300+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
9301+ Z_STREAM_ERROR if the level parameter is invalid.
9302+*/
9303+
9304+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
9305+ const Bytef *source, uLong sourceLen));
9306+/*
9307+ Decompresses the source buffer into the destination buffer. sourceLen is
9308+ the byte length of the source buffer. Upon entry, destLen is the total
9309+ size of the destination buffer, which must be large enough to hold the
9310+ entire uncompressed data. (The size of the uncompressed data must have
9311+ been saved previously by the compressor and transmitted to the decompressor
9312+ by some mechanism outside the scope of this compression library.)
9313+ Upon exit, destLen is the actual size of the compressed buffer.
9314+ This function can be used to decompress a whole file at once if the
9315+ input file is mmap'ed.
9316+
9317+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
9318+ enough memory, Z_BUF_ERROR if there was not enough room in the output
9319+ buffer, or Z_DATA_ERROR if the input data was corrupted.
9320+*/
9321+
9322+
9323+typedef voidp gzFile;
9324+
9325+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
9326+/*
9327+ Opens a gzip (.gz) file for reading or writing. The mode parameter
9328+ is as in fopen ("rb" or "wb") but can also include a compression level
9329+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
9330+ Huffman only compression as in "wb1h". (See the description
9331+ of deflateInit2 for more information about the strategy parameter.)
9332+
9333+ gzopen can be used to read a file which is not in gzip format; in this
9334+ case gzread will directly read from the file without decompression.
9335+
9336+ gzopen returns NULL if the file could not be opened or if there was
9337+ insufficient memory to allocate the (de)compression state; errno
9338+ can be checked to distinguish the two cases (if errno is zero, the
9339+ zlib error is Z_MEM_ERROR). */
9340+
9341+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
9342+/*
9343+ gzdopen() associates a gzFile with the file descriptor fd. File
9344+ descriptors are obtained from calls like open, dup, creat, pipe or
9345+ fileno (in the file has been previously opened with fopen).
9346+ The mode parameter is as in gzopen.
9347+ The next call of gzclose on the returned gzFile will also close the
9348+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
9349+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
9350+ gzdopen returns NULL if there was insufficient memory to allocate
9351+ the (de)compression state.
9352+*/
9353+
9354+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
9355+/*
9356+ Dynamically update the compression level or strategy. See the description
9357+ of deflateInit2 for the meaning of these parameters.
9358+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
9359+ opened for writing.
9360+*/
9361+
9362+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
9363+/*
9364+ Reads the given number of uncompressed bytes from the compressed file.
9365+ If the input file was not in gzip format, gzread copies the given number
9366+ of bytes into the buffer.
9367+ gzread returns the number of uncompressed bytes actually read (0 for
9368+ end of file, -1 for error). */
9369+
9370+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
9371+ const voidp buf, unsigned len));
9372+/*
9373+ Writes the given number of uncompressed bytes into the compressed file.
9374+ gzwrite returns the number of uncompressed bytes actually written
9375+ (0 in case of error).
9376+*/
9377+
9378+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
9379+/*
9380+ Converts, formats, and writes the args to the compressed file under
9381+ control of the format string, as in fprintf. gzprintf returns the number of
9382+ uncompressed bytes actually written (0 in case of error).
9383+*/
9384+
9385+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
9386+/*
9387+ Writes the given null-terminated string to the compressed file, excluding
9388+ the terminating null character.
9389+ gzputs returns the number of characters written, or -1 in case of error.
9390+*/
9391+
9392+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
9393+/*
9394+ Reads bytes from the compressed file until len-1 characters are read, or
9395+ a newline character is read and transferred to buf, or an end-of-file
9396+ condition is encountered. The string is then terminated with a null
9397+ character.
9398+ gzgets returns buf, or Z_NULL in case of error.
9399+*/
9400+
9401+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
9402+/*
9403+ Writes c, converted to an unsigned char, into the compressed file.
9404+ gzputc returns the value that was written, or -1 in case of error.
9405+*/
9406+
9407+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
9408+/*
9409+ Reads one byte from the compressed file. gzgetc returns this byte
9410+ or -1 in case of end of file or error.
9411+*/
9412+
9413+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
9414+/*
9415+ Flushes all pending output into the compressed file. The parameter
9416+ flush is as in the deflate() function. The return value is the zlib
9417+ error number (see function gzerror below). gzflush returns Z_OK if
9418+ the flush parameter is Z_FINISH and all output could be flushed.
9419+ gzflush should be called only when strictly necessary because it can
9420+ degrade compression.
9421+*/
9422+
9423+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
9424+ z_off_t offset, int whence));
9425+/*
9426+ Sets the starting position for the next gzread or gzwrite on the
9427+ given compressed file. The offset represents a number of bytes in the
9428+ uncompressed data stream. The whence parameter is defined as in lseek(2);
9429+ the value SEEK_END is not supported.
9430+ If the file is opened for reading, this function is emulated but can be
9431+ extremely slow. If the file is opened for writing, only forward seeks are
9432+ supported; gzseek then compresses a sequence of zeroes up to the new
9433+ starting position.
9434+
9435+ gzseek returns the resulting offset location as measured in bytes from
9436+ the beginning of the uncompressed stream, or -1 in case of error, in
9437+ particular if the file is opened for writing and the new starting position
9438+ would be before the current position.
9439+*/
9440+
9441+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
9442+/*
9443+ Rewinds the given file. This function is supported only for reading.
9444+
9445+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
9446+*/
9447+
9448+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
9449+/*
9450+ Returns the starting position for the next gzread or gzwrite on the
9451+ given compressed file. This position represents a number of bytes in the
9452+ uncompressed data stream.
9453+
9454+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
9455+*/
9456+
9457+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
9458+/*
9459+ Returns 1 when EOF has previously been detected reading the given
9460+ input stream, otherwise zero.
9461+*/
9462+
9463+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
9464+/*
9465+ Flushes all pending output if necessary, closes the compressed file
9466+ and deallocates all the (de)compression state. The return value is the zlib
9467+ error number (see function gzerror below).
9468+*/
9469+
9470+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
9471+/*
9472+ Returns the error message for the last error which occurred on the
9473+ given compressed file. errnum is set to zlib error number. If an
9474+ error occurred in the file system and not in the compression library,
9475+ errnum is set to Z_ERRNO and the application may consult errno
9476+ to get the exact error code.
9477+*/
9478+
9479+ /* checksum functions */
9480+
9481+/*
9482+ These functions are not related to compression but are exported
9483+ anyway because they might be useful in applications using the
9484+ compression library.
9485+*/
9486+
9487+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
9488+
9489+/*
9490+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
9491+ return the updated checksum. If buf is NULL, this function returns
9492+ the required initial value for the checksum.
9493+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
9494+ much faster. Usage example:
9495+
9496+ uLong adler = adler32(0L, Z_NULL, 0);
9497+
9498+ while (read_buffer(buffer, length) != EOF) {
9499+ adler = adler32(adler, buffer, length);
9500+ }
9501+ if (adler != original_adler) error();
9502+*/
9503+
9504+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
9505+/*
9506+ Update a running crc with the bytes buf[0..len-1] and return the updated
9507+ crc. If buf is NULL, this function returns the required initial value
9508+ for the crc. Pre- and post-conditioning (one's complement) is performed
9509+ within this function so it shouldn't be done by the application.
9510+ Usage example:
9511+
9512+ uLong crc = crc32(0L, Z_NULL, 0);
9513+
9514+ while (read_buffer(buffer, length) != EOF) {
9515+ crc = crc32(crc, buffer, length);
9516+ }
9517+ if (crc != original_crc) error();
9518+*/
9519+
9520+
9521+ /* various hacks, don't look :) */
9522+
9523+/* deflateInit and inflateInit are macros to allow checking the zlib version
9524+ * and the compiler's view of z_stream:
9525+ */
9526+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
9527+ const char *version, int stream_size));
9528+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
9529+ const char *version, int stream_size));
9530+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
9531+ int windowBits, int memLevel,
9532+ int strategy, const char *version,
9533+ int stream_size));
9534+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
9535+ const char *version, int stream_size));
9536+#define deflateInit(strm, level) \
9537+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
9538+#define inflateInit(strm) \
9539+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
9540+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
9541+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
9542+ (strategy), ZLIB_VERSION, sizeof(z_stream))
9543+#define inflateInit2(strm, windowBits) \
9544+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
9545+
9546+
9547+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
9548+ struct internal_state {int dummy;}; /* hack for buggy compilers */
9549+#endif
9550+
9551+ZEXTERN const char * ZEXPORT zError OF((int err));
9552+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
9553+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
9554+
9555+#ifdef __cplusplus
9556+}
9557+#endif
9558+
9559+#endif /* _ZLIB_H */
9560--- /dev/null Tue Mar 11 13:02:56 2003
9561+++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004
9562@@ -0,0 +1,225 @@
9563+/* zutil.h -- internal interface and configuration of the compression library
9564+ * Copyright (C) 1995-2002 Jean-loup Gailly.
9565+ * For conditions of distribution and use, see copyright notice in zlib.h
9566+ */
9567+
9568+/* WARNING: this file should *not* be used by applications. It is
9569+ part of the implementation of the compression library and is
9570+ subject to change. Applications should only use zlib.h.
9571+ */
9572+
9573+/* @(#) $Id: zutil.h,v 1.4 2002-04-24 07:36:48 mcr Exp $ */
9574+
9575+#ifndef _Z_UTIL_H
9576+#define _Z_UTIL_H
9577+
9578+#include "zlib.h"
9579+
9580+#include <linux/string.h>
9581+#define HAVE_MEMCPY
9582+
9583+#if 0 // #ifdef STDC
9584+# include <stddef.h>
9585+# include <string.h>
9586+# include <stdlib.h>
9587+#endif
9588+#ifndef __KERNEL__
9589+#ifdef NO_ERRNO_H
9590+ extern int errno;
9591+#else
9592+# include <errno.h>
9593+#endif
9594+#endif
9595+
9596+#ifndef local
9597+# define local static
9598+#endif
9599+/* compile with -Dlocal if your debugger can't find static symbols */
9600+
9601+typedef unsigned char uch;
9602+typedef uch FAR uchf;
9603+typedef unsigned short ush;
9604+typedef ush FAR ushf;
9605+typedef unsigned long ulg;
9606+
9607+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
9608+/* (size given to avoid silly warnings with Visual C++) */
9609+
9610+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
9611+
9612+#define ERR_RETURN(strm,err) \
9613+ return (strm->msg = ERR_MSG(err), (err))
9614+/* To be used only when the state is known to be valid */
9615+
9616+ /* common constants */
9617+
9618+#ifndef DEF_WBITS
9619+# define DEF_WBITS MAX_WBITS
9620+#endif
9621+/* default windowBits for decompression. MAX_WBITS is for compression only */
9622+
9623+#if MAX_MEM_LEVEL >= 8
9624+# define DEF_MEM_LEVEL 8
9625+#else
9626+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
9627+#endif
9628+/* default memLevel */
9629+
9630+#define STORED_BLOCK 0
9631+#define STATIC_TREES 1
9632+#define DYN_TREES 2
9633+/* The three kinds of block type */
9634+
9635+#define MIN_MATCH 3
9636+#define MAX_MATCH 258
9637+/* The minimum and maximum match lengths */
9638+
9639+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
9640+
9641+ /* target dependencies */
9642+
9643+#ifdef MSDOS
9644+# define OS_CODE 0x00
9645+# if defined(__TURBOC__) || defined(__BORLANDC__)
9646+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
9647+ /* Allow compilation with ANSI keywords only enabled */
9648+ void _Cdecl farfree( void *block );
9649+ void *_Cdecl farmalloc( unsigned long nbytes );
9650+# else
9651+# include <alloc.h>
9652+# endif
9653+# else /* MSC or DJGPP */
9654+# include <malloc.h>
9655+# endif
9656+#endif
9657+
9658+#ifdef OS2
9659+# define OS_CODE 0x06
9660+#endif
9661+
9662+#ifdef WIN32 /* Window 95 & Windows NT */
9663+# define OS_CODE 0x0b
9664+#endif
9665+
9666+#if defined(VAXC) || defined(VMS)
9667+# define OS_CODE 0x02
9668+# define F_OPEN(name, mode) \
9669+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
9670+#endif
9671+
9672+#ifdef AMIGA
9673+# define OS_CODE 0x01
9674+#endif
9675+
9676+#if defined(ATARI) || defined(atarist)
9677+# define OS_CODE 0x05
9678+#endif
9679+
9680+#if defined(MACOS) || defined(TARGET_OS_MAC)
9681+# define OS_CODE 0x07
9682+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
9683+# include <unix.h> /* for fdopen */
9684+# else
9685+# ifndef fdopen
9686+# define fdopen(fd,mode) NULL /* No fdopen() */
9687+# endif
9688+# endif
9689+#endif
9690+
9691+#ifdef __50SERIES /* Prime/PRIMOS */
9692+# define OS_CODE 0x0F
9693+#endif
9694+
9695+#ifdef TOPS20
9696+# define OS_CODE 0x0a
9697+#endif
9698+
9699+#if defined(_BEOS_) || defined(RISCOS)
9700+# define fdopen(fd,mode) NULL /* No fdopen() */
9701+#endif
9702+
9703+#if (defined(_MSC_VER) && (_MSC_VER > 600))
9704+# define fdopen(fd,type) _fdopen(fd,type)
9705+#endif
9706+
9707+
9708+ /* Common defaults */
9709+
9710+#ifndef OS_CODE
9711+# define OS_CODE 0x03 /* assume Unix */
9712+#endif
9713+
9714+#ifndef F_OPEN
9715+# define F_OPEN(name, mode) fopen((name), (mode))
9716+#endif
9717+
9718+ /* functions */
9719+
9720+#ifdef HAVE_STRERROR
9721+ extern char *strerror OF((int));
9722+# define zstrerror(errnum) strerror(errnum)
9723+#else
9724+# define zstrerror(errnum) ""
9725+#endif
9726+
9727+#if defined(pyr)
9728+# define NO_MEMCPY
9729+#endif
9730+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
9731+ /* Use our own functions for small and medium model with MSC <= 5.0.
9732+ * You may have to use the same strategy for Borland C (untested).
9733+ * The __SC__ check is for Symantec.
9734+ */
9735+# define NO_MEMCPY
9736+#endif
9737+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
9738+# define HAVE_MEMCPY
9739+#endif
9740+#ifdef HAVE_MEMCPY
9741+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
9742+# define zmemcpy _fmemcpy
9743+# define zmemcmp _fmemcmp
9744+# define zmemzero(dest, len) _fmemset(dest, 0, len)
9745+# else
9746+# define zmemcpy memcpy
9747+# define zmemcmp memcmp
9748+# define zmemzero(dest, len) memset(dest, 0, len)
9749+# endif
9750+#else
9751+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
9752+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
9753+ extern void zmemzero OF((Bytef* dest, uInt len));
9754+#endif
9755+
9756+/* Diagnostic functions */
9757+#ifdef DEBUG
9758+# include <stdio.h>
9759+ extern int z_verbose;
9760+ extern void z_error OF((char *m));
9761+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
9762+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
9763+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
9764+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
9765+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
9766+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
9767+#else
9768+# define Assert(cond,msg)
9769+# define Trace(x)
9770+# define Tracev(x)
9771+# define Tracevv(x)
9772+# define Tracec(c,x)
9773+# define Tracecv(c,x)
9774+#endif
9775+
9776+
9777+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
9778+ uInt len));
9779+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
9780+void zcfree OF((voidpf opaque, voidpf ptr));
9781+
9782+#define ZALLOC(strm, items, size) \
9783+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
9784+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
9785+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
9786+
9787+#endif /* _Z_UTIL_H */
9788--- /dev/null Tue Mar 11 13:02:56 2003
9789+++ linux/lib/libfreeswan/Makefile.objs Mon Feb 9 13:51:03 2004
9790@@ -0,0 +1,21 @@
9791+obj-y += satot.o
9792+obj-y += addrtot.o
9793+obj-y += ultot.o
9794+obj-y += addrtypeof.o
9795+obj-y += anyaddr.o
9796+obj-y += initaddr.o
9797+obj-y += ultoa.o
9798+obj-y += addrtoa.o
9799+obj-y += subnettoa.o
9800+obj-y += subnetof.o
9801+obj-y += goodmask.o
9802+obj-y += datatot.o
9803+obj-y += rangetoa.o
9804+obj-y += prng.o
9805+obj-y += pfkey_v2_parse.o
9806+obj-y += pfkey_v2_build.o
9807+obj-y += pfkey_v2_debug.o
9808+obj-y += pfkey_v2_ext_bits.o
9809+
9810+#version.c: ${LIBFREESWANDIR}/version.in.c ${OPENSWANSRCDIR}/Makefile.ver
9811+# sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@
9812--- /dev/null Tue Mar 11 13:02:56 2003
9813+++ linux/lib/zlib/Makefile Mon Feb 9 13:51:03 2004
9814@@ -0,0 +1,118 @@
9815+# (kernel) Makefile for IPCOMP zlib deflate code
9816+# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
9817+# Copyright (C) 2000 Svenning Soerensen
9818+#
9819+# This program is free software; you can redistribute it and/or modify it
9820+# under the terms of the GNU General Public License as published by the
9821+# Free Software Foundation; either version 2 of the License, or (at your
9822+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9823+#
9824+# This program is distributed in the hope that it will be useful, but
9825+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9826+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9827+# for more details.
9828+#
9829+# RCSID $Id: Makefile,v 1.9 2002-04-24 07:55:32 mcr Exp $
9830+#
9831+
9832+
9833+
9834+include ../Makefile.inc
9835+
9836+
9837+
9838+ifndef TOPDIR
9839+TOPDIR := /usr/src/linux
9840+endif
9841+
9842+
9843+L_TARGET := zlib.a
9844+
9845+obj-y :=
9846+
9847+include Makefile.objs
9848+
9849+EXTRA_CFLAGS += $(KLIPSCOMPILE)
9850+
9851+EXTRA_CFLAGS += -Wall
9852+#EXTRA_CFLAGS += -Wconversion
9853+#EXTRA_CFLAGS += -Wmissing-prototypes
9854+EXTRA_CFLAGS += -Wpointer-arith
9855+#EXTRA_CFLAGS += -Wcast-qual
9856+#EXTRA_CFLAGS += -Wmissing-declarations
9857+EXTRA_CFLAGS += -Wstrict-prototypes
9858+#EXTRA_CFLAGS += -pedantic
9859+#EXTRA_CFLAGS += -W
9860+#EXTRA_CFLAGS += -Wwrite-strings
9861+EXTRA_CFLAGS += -Wbad-function-cast
9862+EXTRA_CFLAGS += -DIPCOMP_PREFIX
9863+
9864+.S.o:
9865+ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o
9866+
9867+asm-obj-$(CONFIG_M586) += match586.o
9868+asm-obj-$(CONFIG_M586TSC) += match586.o
9869+asm-obj-$(CONFIG_M586MMX) += match586.o
9870+asm-obj-$(CONFIG_M686) += match686.o
9871+asm-obj-$(CONFIG_MPENTIUMIII) += match686.o
9872+asm-obj-$(CONFIG_MPENTIUM4) += match686.o
9873+asm-obj-$(CONFIG_MK6) += match586.o
9874+asm-obj-$(CONFIG_MK7) += match686.o
9875+asm-obj-$(CONFIG_MCRUSOE) += match586.o
9876+asm-obj-$(CONFIG_MWINCHIPC6) += match586.o
9877+asm-obj-$(CONFIG_MWINCHIP2) += match686.o
9878+asm-obj-$(CONFIG_MWINCHIP3D) += match686.o
9879+
9880+obj-y += $(asm-obj-y)
9881+ifneq ($(strip $(asm-obj-y)),)
9882+ EXTRA_CFLAGS += -DASMV
9883+endif
9884+
9885+active-objs := $(sort $(obj-y) $(obj-m))
9886+L_OBJS := $(obj-y)
9887+M_OBJS := $(obj-m)
9888+MIX_OBJS := $(filter $(export-objs), $(active-objs))
9889+
9890+include $(TOPDIR)/Rules.make
9891+
9892+$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
9893+
9894+
9895+clean:
9896+ -rm -f *.o *.a
9897+
9898+checkprograms:
9899+programs: $(L_TARGET)
9900+
9901+#
9902+# $Log: Makefile,v $
9903+# Revision 1.9 2002-04-24 07:55:32 mcr
9904+# #include patches and Makefiles for post-reorg compilation.
9905+#
9906+# Revision 1.8 2002/04/24 07:36:44 mcr
9907+# Moved from ./zlib/Makefile,v
9908+#
9909+# Revision 1.7 2002/03/27 23:34:35 mcr
9910+# added programs: target
9911+#
9912+# Revision 1.6 2001/12/05 20:19:08 henry
9913+# use new compile-control variable
9914+#
9915+# Revision 1.5 2001/11/27 16:38:08 mcr
9916+# added new "checkprograms" target to deal with programs that
9917+# are required for "make check", but that may not be ready to
9918+# build for every user due to external dependancies.
9919+#
9920+# Revision 1.4 2001/10/24 14:46:24 henry
9921+# Makefile.inc
9922+#
9923+# Revision 1.3 2001/04/21 23:05:24 rgb
9924+# Update asm directives for 2.4 style makefiles.
9925+#
9926+# Revision 1.2 2001/01/29 22:22:00 rgb
9927+# Convert to 2.4 new style with back compat.
9928+#
9929+# Revision 1.1.1.1 2000/09/29 18:51:33 rgb
9930+# zlib_beginnings
9931+#
9932+#
9933--- /dev/null Tue Mar 11 13:02:56 2003
9934+++ linux/lib/zlib/Makefile.objs Mon Feb 9 13:51:03 2004
9935@@ -0,0 +1,27 @@
9936+obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o
9937+obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o
9938+obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o
9939+obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o
9940+obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o
9941+obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o
9942+obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o
9943+obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o
9944+obj-$(CONFIG_IPSEC_IPCOMP) += trees.o
9945+obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o
9946+
9947+asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o
9948+asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o
9949+asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o
9950+asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o
9951+asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o
9952+asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o
9953+asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o
9954+asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o
9955+asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o
9956+asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o
9957+asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o
9958+asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o
9959+
9960+EXTRA_CFLAGS += -DIPCOMP_PREFIX
9961+
9962+
9963--- swan26/net/Kconfig.preipsec 2005-09-01 18:15:19.000000000 -0400
9964+++ swan26/net/Kconfig 2005-09-03 16:51:17.000000000 -0400
9965@@ -215,2 +215,6 @@
9966
9967+if INET
9968+source "net/ipsec/Kconfig"
9969+endif # if INET
9970+
9971 endif # if NET
9972--- /distros/kernel/linux-2.6.3-rc4/net/Makefile Mon Feb 16 21:22:12 2004
9973+++ ref26/net/Makefile Thu Feb 19 21:02:25 2004
9974@@ -42,3 +42,6 @@
9975 ifeq ($(CONFIG_NET),y)
9976 obj-$(CONFIG_SYSCTL) += sysctl_net.o
9977 endif
9978+
9979+obj-$(CONFIG_KLIPS) += ipsec/
9980+
9981--- /dev/null Tue Mar 11 13:02:56 2003
9982+++ linux/net/ipsec/Kconfig Mon Feb 9 13:51:03 2004
9983@@ -0,0 +1,172 @@
9984+#
9985+# IPSEC configuration
9986+# Copyright (C) 2004 Michael Richardson <mcr@freeswan.org>
9987+#
9988+# This program is free software; you can redistribute it and/or modify it
9989+# under the terms of the GNU General Public License as published by the
9990+# Free Software Foundation; either version 2 of the License, or (at your
9991+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9992+#
9993+# This program is distributed in the hope that it will be useful, but
9994+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9995+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9996+# for more details.
9997+#
9998+# RCSID $Id: Kconfig,v 1.6.2.3 2007-12-06 15:51:01 paul Exp $
9999+
10000+config KLIPS
10001+ tristate "Openswan IPsec (KLIPS26)"
10002+ default n
10003+ help
10004+ KLIPS is the Openswan (www.openswan.org) Kernel Level IP Security
10005+ system. It is extensively tested, and has interoperated with
10006+ many other systems.
10007+ It provides "ipsecX" devices on which one can do firewalling.
10008+ The userland, is compatible with both KLIPS and 26sec.
10009+
10010+menu "KLIPS options"
10011+ depends on KLIPS
10012+
10013+config KLIPS_ESP
10014+ bool 'Encapsulating Security Payload - ESP ("VPN")'
10015+ default y
10016+ help
10017+ This option provides support for the IPSEC Encapsulation Security
10018+ Payload (IP protocol 50) which provides packet layer content
10019+ hiding, and content authentication.
10020+ It is recommended to enable this. RFC2406
10021+
10022+config KLIPS_AH
10023+ bool 'Authentication Header - AH'
10024+ default n
10025+ help
10026+ This option provides support for the IPSEC Authentication Header
10027+ (IP protocol 51) which provides packet layer sender and content
10028+ authentication. It does not provide for confidentiality.
10029+ It is not recommended to enable this. RFC2402
10030+
10031+config KLIPS_AUTH_HMAC_MD5
10032+ bool 'HMAC-MD5 authentication algorithm'
10033+ default y
10034+ help
10035+ The HMAC-MD5 algorithm is used by ESP (and AH) to guarantee packet
10036+ integrity. There is little reason not to include it.
10037+
10038+config KLIPS_AUTH_HMAC_SHA1
10039+ bool 'HMAC-SHA1 authentication algorithm'
10040+ default y
10041+ help
10042+ The HMAC-SHA1 algorithm is used by ESP (and AH) to guarantee packet
10043+ integrity. SHA1 is a little slower than MD5, but is said to be
10044+ a bit more secure. There is little reason not to include it.
10045+
10046+config KLIPS_ALG
10047+ bool 'KLIPS_ALG software encryption'
10048+ default y
10049+ help
10050+ You should only disabled this if using the external OCF patch
10051+ for hardware offload.
10052+
10053+config KLIPS_ENC_CRYPTOAPI
10054+ bool 'CryptoAPI algorithm interface'
10055+ default n
10056+ help
10057+ Enable the algorithm interface to make all CryptoAPI 1.0 algorithms
10058+ available to KLIPS.
10059+
10060+config KLIPS_ENC_1DES
10061+ bool 'Include 1DES with CryptoAPI'
10062+ default n
10063+ depends on KLIPS_ENC_CRYPTOAPI
10064+ help
10065+ The CryptoAPI interface does not include support for every algorithm
10066+ yet, and one that it doesn't support by default is the VERY WEAK
10067+ 1DES. Select this if you are terminally stupid.
10068+
10069+config KLIPS_ENC_3DES
10070+ bool '3DES encryption algorithm'
10071+ default y
10072+ help
10073+ The 3DES algorithm is used by ESP to provide for packet privacy.
10074+ 3DES is 3-repeats of the DES algorithm. 3DES is widely supported,
10075+ and analyzed and is considered very secure. 1DES is not supported.
10076+
10077+config KLIPS_ENC_AES
10078+ bool 'AES encryption algorithm'
10079+ default y
10080+ help
10081+ The AES algorithm is used by ESP to provide for packet privacy.
10082+ AES the NIST replacement for DES. AES is being widely analyzed,
10083+ and is very fast.
10084+
10085+config KLIPS_ENC_NULL
10086+ bool 'NULL NON-encryption algorithm'
10087+ default n
10088+ help
10089+ NON encryption algo , maybe useful for ESP auth only scenarios
10090+ (eg: with NAT-T), see RFC 2410.
10091+
10092+config KLIPS_IPCOMP
10093+ bool 'IP compression'
10094+ default y
10095+ help
10096+ The IPcomp protocol is used prior to ESP to make the packet
10097+ smaller. Once encrypted, compression will fail, so any link
10098+ layer efforts (e.g. PPP) will not work.
10099+
10100+config KLIPS_DEBUG
10101+ bool 'IPsec debugging'
10102+ default y
10103+ help
10104+ KLIPS includes a lot of debugging code. Unless there is a real
10105+ tangible benefit to removing this code, it should be left in place.
10106+ Debugging connections without access to kernel level debugging is
10107+ essentially impossible. Leave this on.
10108+
10109+endmenu
10110+
10111+#
10112+#
10113+# $Log: Kconfig,v $
10114+# Revision 1.6.2.3 2007-12-06 15:51:01 paul
10115+# Enable KLIPS_ALG in default build, when not using Makefile.inc.
10116+# Patch by Laszlo Attila Toth
10117+#
10118+# Revision 1.6.2.2 2006/10/11 18:14:33 paul
10119+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
10120+# per default.
10121+#
10122+# Revision 1.6.2.1 2006/04/20 16:33:06 mcr
10123+# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
10124+# Fix in-kernel module compilation. Sub-makefiles do not work.
10125+#
10126+# Revision 1.6 2005/05/18 20:55:27 mcr
10127+# default cryptoapi to n.
10128+#
10129+# Revision 1.5 2005/05/11 01:23:25 mcr
10130+# added 1DES option to cryptoapi.
10131+#
10132+# Revision 1.4 2005/04/29 05:29:54 mcr
10133+# add option to include cryptoapi algorithms.
10134+#
10135+# Revision 1.3 2004/08/17 03:27:23 mcr
10136+# klips 2.6 edits.
10137+#
10138+# Revision 1.2 2004/08/14 03:27:39 mcr
10139+# 2.6 kernel build/configuration files.
10140+#
10141+# Revision 1.1 2004/08/14 02:47:55 mcr
10142+# kernel build/config patches
10143+#
10144+# Revision 1.3 2004/02/24 17:17:04 mcr
10145+# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
10146+# turn it on/off as well.
10147+#
10148+# Revision 1.2 2004/02/22 06:50:42 mcr
10149+# kernel 2.6 port - merged with 2.4 code.
10150+#
10151+# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
10152+# module configuration for KLIPS 2.6
10153+#
10154+#
10155+
10156--- /dev/null Tue Mar 11 13:02:56 2003
10157+++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004
10158@@ -0,0 +1,195 @@
10159+# Makefile for KLIPS kernel code as a module for 2.6 kernels
10160+#
10161+# Makefile for KLIPS kernel code as a module
10162+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
10163+# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
10164+#
10165+# This program is free software; you can redistribute it and/or modify it
10166+# under the terms of the GNU General Public License as published by the
10167+# Free Software Foundation; either version 2 of the License, or (at your
10168+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10169+#
10170+# This program is distributed in the hope that it will be useful, but
10171+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10172+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10173+# for more details.
10174+#
10175+# RCSID $Id: Makefile.fs2_6,v 1.8.2.2 2006-10-11 18:14:33 paul Exp $
10176+#
10177+# Note! Dependencies are done automagically by 'make dep', which also
10178+# removes any old dependencies. DON'T put your own dependencies here
10179+# unless it's something special (ie not a .c file).
10180+#
10181+
10182+OPENSWANSRCDIR?=.
10183+KLIPS_TOP?=.
10184+
10185+-include ${OPENSWANSRCDIR}/Makefile.ver
10186+
10187+base-klips-objs :=
10188+
10189+base-klips-objs+= ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
10190+base-klips-objs+= ipsec_life.o ipsec_proc.o
10191+base-klips-objs+= ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
10192+base-klips-objs+= ipsec_snprintf.o
10193+base-klips-objs+= sysctl_net_ipsec.o
10194+base-klips-objs+= pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
10195+base-klips-objs+= version.o
10196+
10197+base-klips-objs+= satot.o
10198+base-klips-objs+= addrtot.o
10199+base-klips-objs+= ultot.o
10200+base-klips-objs+= addrtypeof.o
10201+base-klips-objs+= anyaddr.o
10202+base-klips-objs+= initaddr.o
10203+base-klips-objs+= ultoa.o
10204+base-klips-objs+= addrtoa.o
10205+base-klips-objs+= subnettoa.o
10206+base-klips-objs+= subnetof.o
10207+base-klips-objs+= goodmask.o
10208+base-klips-objs+= datatot.o
10209+base-klips-objs+= rangetoa.o
10210+base-klips-objs+= prng.o
10211+base-klips-objs+= pfkey_v2_parse.o
10212+base-klips-objs+= pfkey_v2_build.o
10213+base-klips-objs+= pfkey_v2_debug.o
10214+base-klips-objs+= pfkey_v2_ext_bits.o
10215+base-klips-objs+= version.o
10216+
10217+obj-${CONFIG_KLIPS} += ipsec.o
10218+
10219+ipsec-objs += ${base-klips-objs}
10220+
10221+ipsec-$(CONFIG_KLIPS_ESP) += ipsec_esp.o
10222+ipsec-$(CONFIG_KLIPS_IPCOMP) += ipsec_ipcomp.o
10223+ipsec-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
10224+ipsec-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
10225+
10226+# AH, if you really think you need it.
10227+ipsec-$(CONFIG_KLIPS_AH) += ipsec_ah.o
10228+
10229+ipsec-y += ipsec_alg.o
10230+
10231+# include code from DES subdir
10232+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ipsec_alg_3des.o
10233+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/cbc_enc.o
10234+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ecb_enc.o
10235+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/set_key.o
10236+
10237+ifeq ($(strip ${SUBARCH}),)
10238+SUBARCH:=${ARCH}
10239+endif
10240+
10241+# the assembly version expects frame pointers, which are
10242+# optional in many kernel builds. If you want speed, you should
10243+# probably use cryptoapi code instead.
10244+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10245+ifeq (${USEASSEMBLY},i386y)
10246+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/dx86unix.o
10247+else
10248+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/des_enc.o
10249+endif
10250+
10251+# include code from AES subdir
10252+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/ipsec_alg_aes.o
10253+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_xcbc_mac.o
10254+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_cbc.o
10255+
10256+ifeq ($(strip ${SUBARCH}),)
10257+SUBARCH:=${ARCH}
10258+endif
10259+
10260+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10261+ifeq (${USEASSEMBLY},i386y)
10262+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes-i586.o
10263+else
10264+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes.o
10265+endif
10266+
10267+crypto-$(CONFIG_KLIPS_ENC_NULL) += null/ipsec_alg_null.o
10268+
10269+ipsec-y += ${crypto-y}
10270+
10271+ipsec-$(CONFIG_KLIPS_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o
10272+
10273+# IPcomp stuff
10274+base-ipcomp-objs := ipcomp.o
10275+base-ipcomp-objs += adler32.o
10276+base-ipcomp-objs += deflate.o
10277+base-ipcomp-objs += infblock.o
10278+base-ipcomp-objs += infcodes.o
10279+base-ipcomp-objs += inffast.o
10280+base-ipcomp-objs += inflate.o
10281+base-ipcomp-objs += inftrees.o
10282+base-ipcomp-objs += infutil.o
10283+base-ipcomp-objs += trees.o
10284+base-ipcomp-objs += zutil.o
10285+asm-ipcomp-obj-$(CONFIG_M586) += match586.o
10286+asm-ipcomp-obj-$(CONFIG_M586TSC) += match586.o
10287+asm-ipcomp-obj-$(CONFIG_M586MMX) += match586.o
10288+asm-ipcomp-obj-$(CONFIG_M686) += match686.o
10289+asm-ipcomp-obj-$(CONFIG_MPENTIUMIII) += match686.o
10290+asm-ipcomp-obj-$(CONFIG_MPENTIUM4) += match686.o
10291+asm-ipcomp-obj-$(CONFIG_MK6) += match586.o
10292+asm-ipcomp-obj-$(CONFIG_MK7) += match686.o
10293+asm-ipcomp-obj-$(CONFIG_MCRUSOE) += match586.o
10294+asm-ipcomp-obj-$(CONFIG_MWINCHIPC6) += match586.o
10295+asm-ipcomp-obj-$(CONFIG_MWINCHIP2) += match686.o
10296+asm-ipcomp-obj-$(CONFIG_MWINCHIP3D) += match686.o
10297+base-ipcomp-objs += ${asm-ipcomp-obj-y}
10298+
10299+ipsec-$(CONFIG_KLIPS_IPCOMP) += ${base-ipcomp-objs}
10300+
10301+EXTRA_CFLAGS += -DIPCOMP_PREFIX
10302+
10303+#
10304+# $Log: Makefile.fs2_6,v $
10305+# Revision 1.8.2.2 2006-10-11 18:14:33 paul
10306+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
10307+# per default.
10308+#
10309+# Revision 1.8.2.1 2006/04/20 16:33:06 mcr
10310+# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
10311+# Fix in-kernel module compilation. Sub-makefiles do not work.
10312+#
10313+# Revision 1.8 2005/05/11 03:15:42 mcr
10314+# adjusted makefiles to sanely build modules properly.
10315+#
10316+# Revision 1.7 2005/04/13 22:52:12 mcr
10317+# moved KLIPS specific snprintf() wrapper to seperate file.
10318+#
10319+# Revision 1.6 2004/08/22 05:02:03 mcr
10320+# organized symbols such that it is easier to build modules.
10321+#
10322+# Revision 1.5 2004/08/18 01:43:56 mcr
10323+# adjusted makefile enumation so that it can be used by module
10324+# wrapper.
10325+#
10326+# Revision 1.4 2004/08/17 03:27:23 mcr
10327+# klips 2.6 edits.
10328+#
10329+# Revision 1.3 2004/08/04 16:50:13 mcr
10330+# removed duplicate definition of dx86unix.o
10331+#
10332+# Revision 1.2 2004/08/03 18:21:09 mcr
10333+# only set KLIPS_TOP and OPENSWANSRCDIR if not already set.
10334+#
10335+# Revision 1.1 2004/07/26 15:02:22 mcr
10336+# makefile for KLIPS module for 2.6.
10337+#
10338+# Revision 1.3 2004/02/24 17:17:04 mcr
10339+# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
10340+# turn it on/off as well.
10341+#
10342+# Revision 1.2 2004/02/22 06:50:42 mcr
10343+# kernel 2.6 port - merged with 2.4 code.
10344+#
10345+# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
10346+# module configuration for KLIPS 2.6
10347+#
10348+#
10349+# Local Variables:
10350+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
10351+# End Variables:
10352+#
10353+
10354--- /dev/null Tue Mar 11 13:02:56 2003
10355+++ linux/net/ipsec/README-zlib Mon Feb 9 13:51:03 2004
10356@@ -0,0 +1,147 @@
10357+zlib 1.1.4 is a general purpose data compression library. All the code
10358+is thread safe. The data format used by the zlib library
10359+is described by RFCs (Request for Comments) 1950 to 1952 in the files
10360+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
10361+format) and rfc1952.txt (gzip format). These documents are also available in
10362+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
10363+
10364+All functions of the compression library are documented in the file zlib.h
10365+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
10366+example of the library is given in the file example.c which also tests that
10367+the library is working correctly. Another example is given in the file
10368+minigzip.c. The compression library itself is composed of all source files
10369+except example.c and minigzip.c.
10370+
10371+To compile all files and run the test program, follow the instructions
10372+given at the top of Makefile. In short "make test; make install"
10373+should work for most machines. For Unix: "./configure; make test; make install"
10374+For MSDOS, use one of the special makefiles such as Makefile.msc.
10375+For VMS, use Make_vms.com or descrip.mms.
10376+
10377+Questions about zlib should be sent to <zlib@gzip.org>, or to
10378+Gilles Vollant <info@winimage.com> for the Windows DLL version.
10379+The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
10380+Before reporting a problem, please check this site to verify that
10381+you have the latest version of zlib; otherwise get the latest version and
10382+check whether the problem still exists or not.
10383+
10384+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
10385+before asking for help.
10386+
10387+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
10388+issue of Dr. Dobb's Journal; a copy of the article is available in
10389+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
10390+
10391+The changes made in version 1.1.4 are documented in the file ChangeLog.
10392+The only changes made since 1.1.3 are bug corrections:
10393+
10394+- ZFREE was repeated on same allocation on some error conditions.
10395+ This creates a security problem described in
10396+ http://www.zlib.org/advisory-2002-03-11.txt
10397+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
10398+- Avoid accesses before window for invalid distances with inflate window
10399+ less than 32K.
10400+- force windowBits > 8 to avoid a bug in the encoder for a window size
10401+ of 256 bytes. (A complete fix will be available in 1.1.5).
10402+
10403+The beta version 1.1.5beta includes many more changes. A new official
10404+version 1.1.5 will be released as soon as extensive testing has been
10405+completed on it.
10406+
10407+
10408+Unsupported third party contributions are provided in directory "contrib".
10409+
10410+A Java implementation of zlib is available in the Java Development Kit
10411+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
10412+See the zlib home page http://www.zlib.org for details.
10413+
10414+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
10415+is in the CPAN (Comprehensive Perl Archive Network) sites
10416+http://www.cpan.org/modules/by-module/Compress/
10417+
10418+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
10419+is available in Python 1.5 and later versions, see
10420+http://www.python.org/doc/lib/module-zlib.html
10421+
10422+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
10423+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
10424+
10425+An experimental package to read and write files in .zip format,
10426+written on top of zlib by Gilles Vollant <info@winimage.com>, is
10427+available at http://www.winimage.com/zLibDll/unzip.html
10428+and also in the contrib/minizip directory of zlib.
10429+
10430+
10431+Notes for some targets:
10432+
10433+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
10434+ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
10435+ The zlib DLL support was initially done by Alessandro Iacopetti and is
10436+ now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
10437+ home page at http://www.winimage.com/zLibDll
10438+
10439+ From Visual Basic, you can call the DLL functions which do not take
10440+ a structure as argument: compress, uncompress and all gz* functions.
10441+ See contrib/visual-basic.txt for more information, or get
10442+ http://www.tcfb.com/dowseware/cmp-z-it.zip
10443+
10444+- For 64-bit Irix, deflate.c must be compiled without any optimization.
10445+ With -O, one libpng test fails. The test works in 32 bit mode (with
10446+ the -n32 compiler flag). The compiler bug has been reported to SGI.
10447+
10448+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
10449+ it works when compiled with cc.
10450+
10451+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
10452+ is necessary to get gzprintf working correctly. This is done by configure.
10453+
10454+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
10455+ with other compilers. Use "make test" to check your compiler.
10456+
10457+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
10458+
10459+- For Turbo C the small model is supported only with reduced performance to
10460+ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
10461+
10462+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
10463+ Per Harald Myrvang <perm@stud.cs.uit.no>
10464+
10465+
10466+Acknowledgments:
10467+
10468+ The deflate format used by zlib was defined by Phil Katz. The deflate
10469+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
10470+ people who reported problems and suggested various improvements in zlib;
10471+ they are too numerous to cite here.
10472+
10473+Copyright notice:
10474+
10475+ (C) 1995-2002 Jean-loup Gailly and Mark Adler
10476+
10477+ This software is provided 'as-is', without any express or implied
10478+ warranty. In no event will the authors be held liable for any damages
10479+ arising from the use of this software.
10480+
10481+ Permission is granted to anyone to use this software for any purpose,
10482+ including commercial applications, and to alter it and redistribute it
10483+ freely, subject to the following restrictions:
10484+
10485+ 1. The origin of this software must not be misrepresented; you must not
10486+ claim that you wrote the original software. If you use this software
10487+ in a product, an acknowledgment in the product documentation would be
10488+ appreciated but is not required.
10489+ 2. Altered source versions must be plainly marked as such, and must not be
10490+ misrepresented as being the original software.
10491+ 3. This notice may not be removed or altered from any source distribution.
10492+
10493+ Jean-loup Gailly Mark Adler
10494+ jloup@gzip.org madler@alumni.caltech.edu
10495+
10496+If you use the zlib library in a product, we would appreciate *not*
10497+receiving lengthy legal documents to sign. The sources are provided
10498+for free but without warranty of any kind. The library has been
10499+entirely written by Jean-loup Gailly and Mark Adler; it does not
10500+include third-party code.
10501+
10502+If you redistribute modified sources, we would appreciate that you include
10503+in the file ChangeLog history information documenting your changes.
10504--- /dev/null Tue Mar 11 13:02:56 2003
10505+++ linux/net/ipsec/README-zlib.freeswan Mon Feb 9 13:51:03 2004
10506@@ -0,0 +1,13 @@
10507+The only changes made to these files for use in FreeS/WAN are:
10508+
10509+ - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
10510+ (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
10511+ - The copyright strings are defined local (static)
10512+
10513+ The above changes are made to avoid name collisions with ppp_deflate
10514+ and ext2compr.
10515+
10516+ - Files not needed for FreeS/WAN have been removed
10517+
10518+ See the "README" file for information about where to obtain the complete
10519+ zlib package.
10520--- /dev/null Tue Mar 11 13:02:56 2003
10521+++ linux/net/ipsec/addrtoa.c Mon Feb 9 13:51:03 2004
10522@@ -0,0 +1,67 @@
10523+/*
10524+ * addresses to ASCII
10525+ * Copyright (C) 1998, 1999 Henry Spencer.
10526+ *
10527+ * This library is free software; you can redistribute it and/or modify it
10528+ * under the terms of the GNU Library General Public License as published by
10529+ * the Free Software Foundation; either version 2 of the License, or (at your
10530+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10531+ *
10532+ * This library is distributed in the hope that it will be useful, but
10533+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10534+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10535+ * License for more details.
10536+ *
10537+ * RCSID $Id: addrtoa.c,v 1.10 2004-07-10 07:43:47 mcr Exp $
10538+ */
10539+#include "openswan.h"
10540+
10541+#define NBYTES 4 /* bytes in an address */
10542+#define PERBYTE 4 /* three digits plus a dot or NUL */
10543+#define BUFLEN (NBYTES*PERBYTE)
10544+
10545+#if BUFLEN != ADDRTOA_BUF
10546+#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code"
10547+#endif
10548+
10549+/*
10550+ - addrtoa - convert binary address to ASCII dotted decimal
10551+ */
10552+size_t /* space needed for full conversion */
10553+addrtoa(addr, format, dst, dstlen)
10554+struct in_addr addr;
10555+int format; /* character */
10556+char *dst; /* need not be valid if dstlen is 0 */
10557+size_t dstlen;
10558+{
10559+ unsigned long a = ntohl(addr.s_addr);
10560+ int i;
10561+ size_t n;
10562+ unsigned long byte;
10563+ char buf[BUFLEN];
10564+ char *p;
10565+
10566+ switch (format) {
10567+ case 0:
10568+ break;
10569+ default:
10570+ return 0;
10571+ break;
10572+ }
10573+
10574+ p = buf;
10575+ for (i = NBYTES-1; i >= 0; i--) {
10576+ byte = (a >> (i*8)) & 0xff;
10577+ p += ultoa(byte, 10, p, PERBYTE);
10578+ if (i != 0)
10579+ *(p-1) = '.';
10580+ }
10581+ n = p - buf;
10582+
10583+ if (dstlen > 0) {
10584+ if (n > dstlen)
10585+ buf[dstlen - 1] = '\0';
10586+ strcpy(dst, buf);
10587+ }
10588+ return n;
10589+}
10590--- /dev/null Tue Mar 11 13:02:56 2003
10591+++ linux/net/ipsec/addrtot.c Mon Feb 9 13:51:03 2004
10592@@ -0,0 +1,431 @@
10593+/*
10594+ * addresses to text
10595+ * Copyright (C) 2000 Henry Spencer.
10596+ *
10597+ * This library is free software; you can redistribute it and/or modify it
10598+ * under the terms of the GNU Library General Public License as published by
10599+ * the Free Software Foundation; either version 2 of the License, or (at your
10600+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10601+ *
10602+ * This library is distributed in the hope that it will be useful, but
10603+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10604+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10605+ * License for more details.
10606+ *
10607+ * RCSID $Id: addrtot.c,v 1.22.2.2 2007-10-30 21:32:26 paul Exp $
10608+ */
10609+
10610+#if defined(__KERNEL__) && defined(__HAVE_ARCH_STRSTR)
10611+#include <linux/string.h>
10612+#endif
10613+
10614+#include "openswan.h"
10615+
10616+#define IP4BYTES 4 /* bytes in an IPv4 address */
10617+#define PERBYTE 4 /* three digits plus a dot or NUL */
10618+#define IP6BYTES 16 /* bytes in an IPv6 address */
10619+
10620+/* forwards */
10621+static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
10622+static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
10623+static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
10624+static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
10625+
10626+#if defined(__KERNEL__) && !defined(__HAVE_ARCH_STRSTR)
10627+#define strstr ipsec_strstr
10628+/*
10629+ * Find the first occurrence of find in s.
10630+ * (from NetBSD 1.6's /src/lib/libc/string/strstr.c)
10631+ */
10632+static char *strstr(const char *s, const char *find);
10633+
10634+static char *
10635+strstr(s, find)
10636+ const char *s, *find;
10637+{
10638+ char c, sc;
10639+ size_t len;
10640+
10641+ if ((c = *find++) != 0) {
10642+ len = strlen(find);
10643+ do {
10644+ do {
10645+ if ((sc = *s++) == 0)
10646+ return (NULL);
10647+ } while (sc != c);
10648+ } while (strncmp(s, find, len) != 0);
10649+ s--;
10650+ }
10651+ /* LINTED interface specification */
10652+ return ((char *)s);
10653+}
10654+#endif
10655+
10656+/*
10657+ - addrtot - convert binary address to text (dotted decimal or IPv6 string)
10658+ */
10659+size_t /* space needed for full conversion */
10660+addrtot(src, format, dst, dstlen)
10661+const ip_address *src;
10662+int format; /* character */
10663+char *dst; /* need not be valid if dstlen is 0 */
10664+size_t dstlen;
10665+{
10666+ const unsigned char *b;
10667+ size_t n;
10668+ char buf[1+ADDRTOT_BUF+1]; /* :address: */
10669+ char *p;
10670+ int t = addrtypeof(src);
10671+# define TF(t, f) (((t)<<8) | (f))
10672+
10673+ n = addrbytesptr(src, &b);
10674+ if (n == 0) {
10675+ bad:
10676+ dst[0]='\0';
10677+ strncat(dst, "<invalid>", dstlen);
10678+ return sizeof("<invalid>");
10679+ }
10680+
10681+ switch (TF(t, format)) {
10682+ case TF(AF_INET, 0):
10683+ n = normal4(b, n, buf, &p);
10684+ break;
10685+ case TF(AF_INET6, 0):
10686+ n = normal6(b, n, buf, &p, 1);
10687+ break;
10688+ case TF(AF_INET, 'Q'):
10689+ n = normal4(b, n, buf, &p);
10690+ break;
10691+ case TF(AF_INET6, 'Q'):
10692+ n = normal6(b, n, buf, &p, 0);
10693+ break;
10694+ case TF(AF_INET, 'r'):
10695+ n = reverse4(b, n, buf, &p);
10696+ break;
10697+ case TF(AF_INET6, 'r'):
10698+ n = reverse6(b, n, buf, &p);
10699+ break;
10700+ default: /* including (AF_INET, 'R') */
10701+ goto bad;
10702+ break;
10703+ }
10704+
10705+ if (dstlen > 0) {
10706+ if (dstlen < n)
10707+ p[dstlen - 1] = '\0';
10708+ strcpy(dst, p);
10709+ }
10710+ return n;
10711+}
10712+
10713+/*
10714+ - normal4 - normal IPv4 address-text conversion
10715+ */
10716+static size_t /* size of text, including NUL */
10717+normal4(srcp, srclen, buf, dstp)
10718+const unsigned char *srcp;
10719+size_t srclen;
10720+char *buf; /* guaranteed large enough */
10721+char **dstp; /* where to put result pointer */
10722+{
10723+ int i;
10724+ char *p;
10725+
10726+ if (srclen != IP4BYTES) /* "can't happen" */
10727+ return 0;
10728+ p = buf;
10729+ for (i = 0; i < IP4BYTES; i++) {
10730+ p += ultot(srcp[i], 10, p, PERBYTE);
10731+ if (i != IP4BYTES - 1)
10732+ *(p-1) = '.'; /* overwrites the NUL */
10733+ }
10734+ *dstp = buf;
10735+ return p - buf;
10736+}
10737+
10738+/*
10739+ - normal6 - normal IPv6 address-text conversion
10740+ */
10741+static size_t /* size of text, including NUL */
10742+normal6(srcp, srclen, buf, dstp, squish)
10743+const unsigned char *srcp;
10744+size_t srclen;
10745+char *buf; /* guaranteed large enough, plus 2 */
10746+char **dstp; /* where to put result pointer */
10747+int squish; /* whether to squish out 0:0 */
10748+{
10749+ int i;
10750+ unsigned long piece;
10751+ char *p;
10752+ char *q;
10753+
10754+ if (srclen != IP6BYTES) /* "can't happen" */
10755+ return 0;
10756+ p = buf;
10757+ *p++ = ':';
10758+ for (i = 0; i < IP6BYTES/2; i++) {
10759+ piece = (srcp[2*i] << 8) + srcp[2*i + 1];
10760+ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
10761+ *(p-1) = ':'; /* overwrites the NUL */
10762+ }
10763+ *p = '\0';
10764+ q = strstr(buf, ":0:0:");
10765+ if (squish && q != NULL) { /* zero squishing is possible */
10766+ p = q + 1;
10767+ while (*p == '0' && *(p+1) == ':')
10768+ p += 2;
10769+ q++;
10770+ *q++ = ':'; /* overwrite first 0 */
10771+ while (*p != '\0')
10772+ *q++ = *p++;
10773+ *q = '\0';
10774+ if (!(*(q-1) == ':' && *(q-2) == ':'))
10775+ *--q = '\0'; /* strip final : unless :: */
10776+ p = buf;
10777+ if (!(*p == ':' && *(p+1) == ':'))
10778+ p++; /* skip initial : unless :: */
10779+ } else {
10780+ q = p;
10781+ *--q = '\0'; /* strip final : */
10782+ p = buf + 1; /* skip initial : */
10783+ }
10784+ *dstp = p;
10785+ return q - p + 1;
10786+}
10787+
10788+/*
10789+ - reverse4 - IPv4 reverse-lookup conversion
10790+ */
10791+static size_t /* size of text, including NUL */
10792+reverse4(srcp, srclen, buf, dstp)
10793+const unsigned char *srcp;
10794+size_t srclen;
10795+char *buf; /* guaranteed large enough */
10796+char **dstp; /* where to put result pointer */
10797+{
10798+ int i;
10799+ char *p;
10800+
10801+ if (srclen != IP4BYTES) /* "can't happen" */
10802+ return 0;
10803+ p = buf;
10804+ for (i = IP4BYTES-1; i >= 0; i--) {
10805+ p += ultot(srcp[i], 10, p, PERBYTE);
10806+ *(p-1) = '.'; /* overwrites the NUL */
10807+ }
10808+ strcpy(p, "IN-ADDR.ARPA.");
10809+ *dstp = buf;
10810+ return strlen(buf) + 1;
10811+}
10812+
10813+/*
10814+ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
10815+ * A trifle inefficient, really shouldn't use ultot...
10816+ */
10817+static size_t /* size of text, including NUL */
10818+reverse6(srcp, srclen, buf, dstp)
10819+const unsigned char *srcp;
10820+size_t srclen;
10821+char *buf; /* guaranteed large enough */
10822+char **dstp; /* where to put result pointer */
10823+{
10824+ int i;
10825+ unsigned long piece;
10826+ char *p;
10827+
10828+ if (srclen != IP6BYTES) /* "can't happen" */
10829+ return 0;
10830+ p = buf;
10831+ for (i = IP6BYTES-1; i >= 0; i--) {
10832+ piece = srcp[i];
10833+ p += ultot(piece&0xf, 16, p, 2);
10834+ *(p-1) = '.';
10835+ p += ultot(piece>>4, 16, p, 2);
10836+ *(p-1) = '.';
10837+ }
10838+ strcpy(p, "IP6.ARPA.");
10839+ *dstp = buf;
10840+ return strlen(buf) + 1;
10841+}
10842+
10843+/*
10844+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
10845+ * this version removed as it was obsoleted in the end.
10846+ */
10847+
10848+#ifdef ADDRTOT_MAIN
10849+
10850+#include <stdio.h>
10851+#include <sys/socket.h>
10852+#include <netinet/in.h>
10853+#include <arpa/inet.h>
10854+
10855+void regress(void);
10856+
10857+int
10858+main(int argc, char *argv[])
10859+{
10860+ if (argc < 2) {
10861+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
10862+ argv[0]);
10863+ exit(2);
10864+ }
10865+
10866+ if (strcmp(argv[1], "-r") == 0) {
10867+ regress();
10868+ fprintf(stderr, "regress() returned?!?\n");
10869+ exit(1);
10870+ }
10871+ exit(0);
10872+}
10873+
10874+struct rtab {
10875+ char *input;
10876+ char format;
10877+ char *output; /* NULL means error expected */
10878+} rtab[] = {
10879+ {"1.2.3.0", 0, "1.2.3.0"},
10880+ {"1:2::3:4", 0, "1:2::3:4"},
10881+ {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
10882+ {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
10883+ {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
10884+ /* 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 */
10885+ {"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."},
10886+ {NULL, 0, NULL}
10887+};
10888+
10889+void
10890+regress()
10891+{
10892+ struct rtab *r;
10893+ int status = 0;
10894+ ip_address a;
10895+ char in[100];
10896+ char buf[100];
10897+ const char *oops;
10898+ size_t n;
10899+
10900+ for (r = rtab; r->input != NULL; r++) {
10901+ strcpy(in, r->input);
10902+
10903+ /* convert it *to* internal format */
10904+ oops = ttoaddr(in, strlen(in), 0, &a);
10905+
10906+ /* now convert it back */
10907+
10908+ n = addrtot(&a, r->format, buf, sizeof(buf));
10909+
10910+ if (n == 0 && r->output == NULL)
10911+ {} /* okay, error expected */
10912+
10913+ else if (n == 0) {
10914+ printf("`%s' atoasr failed\n", r->input);
10915+ status = 1;
10916+
10917+ } else if (r->output == NULL) {
10918+ printf("`%s' atoasr succeeded unexpectedly '%c'\n",
10919+ r->input, r->format);
10920+ status = 1;
10921+ } else {
10922+ if (strcasecmp(r->output, buf) != 0) {
10923+ printf("`%s' '%c' gave `%s', expected `%s'\n",
10924+ r->input, r->format, buf, r->output);
10925+ status = 1;
10926+ }
10927+ }
10928+ }
10929+ exit(status);
10930+}
10931+
10932+#endif /* ADDRTOT_MAIN */
10933+
10934+/*
10935+ * $Log: addrtot.c,v $
10936+ * Revision 1.22.2.2 2007-10-30 21:32:26 paul
10937+ * Added strstr prototype [dhr]
10938+ *
10939+ * Revision 1.22.2.1 2005/11/17 22:30:49 paul
10940+ * pull up strstr fix from head.
10941+ *
10942+ * Revision 1.22 2005/05/20 16:47:40 mcr
10943+ * make strstr static if we need it.
10944+ *
10945+ * Revision 1.21 2005/03/21 00:35:12 mcr
10946+ * test for strstr properly
10947+ *
10948+ * Revision 1.20 2004/11/09 22:52:20 mcr
10949+ * until we figure out which kernels have strsep and which
10950+ * do not (UML does not under certain circumstances), then
10951+ * let's just provide our own.
10952+ *
10953+ * Revision 1.19 2004/10/08 16:30:33 mcr
10954+ * pull-up of initial crypto-offload work.
10955+ *
10956+ * Revision 1.18 2004/09/18 19:33:08 mcr
10957+ * use an appropriate kernel happy ifdef for strstr.
10958+ *
10959+ * Revision 1.17 2004/09/15 21:49:02 mcr
10960+ * use local copy of strstr() if this is going in the kernel.
10961+ * Not clear why this worked before, or why this shows up
10962+ * for modules only.
10963+ *
10964+ * Revision 1.16 2004/07/10 07:43:47 mcr
10965+ * Moved from linux/lib/libfreeswan/addrtot.c,v
10966+ *
10967+ * Revision 1.15 2004/04/11 17:39:25 mcr
10968+ * removed internal.h requirements.
10969+ *
10970+ * Revision 1.14 2004/03/08 01:59:08 ken
10971+ * freeswan.h -> openswan.h
10972+ *
10973+ * Revision 1.13 2004/01/05 23:21:05 mcr
10974+ * if the address type is invalid, then return length of <invalid>
10975+ * string!
10976+ *
10977+ * Revision 1.12 2003/12/30 06:42:48 mcr
10978+ * added $Log: addrtot.c,v $
10979+ * added Revision 1.22.2.2 2007-10-30 21:32:26 paul
10980+ * added Added strstr prototype [dhr]
10981+ * added
10982+ * added Revision 1.22.2.1 2005/11/17 22:30:49 paul
10983+ * added pull up strstr fix from head.
10984+ * added
10985+ * added Revision 1.22 2005/05/20 16:47:40 mcr
10986+ * added make strstr static if we need it.
10987+ * added
10988+ * added Revision 1.21 2005/03/21 00:35:12 mcr
10989+ * added test for strstr properly
10990+ * added
10991+ * added Revision 1.20 2004/11/09 22:52:20 mcr
10992+ * added until we figure out which kernels have strsep and which
10993+ * added do not (UML does not under certain circumstances), then
10994+ * added let's just provide our own.
10995+ * added
10996+ * added Revision 1.19 2004/10/08 16:30:33 mcr
10997+ * added pull-up of initial crypto-offload work.
10998+ * added
10999+ * added Revision 1.18 2004/09/18 19:33:08 mcr
11000+ * added use an appropriate kernel happy ifdef for strstr.
11001+ * added
11002+ * added Revision 1.17 2004/09/15 21:49:02 mcr
11003+ * added use local copy of strstr() if this is going in the kernel.
11004+ * added Not clear why this worked before, or why this shows up
11005+ * added for modules only.
11006+ * added
11007+ * added Revision 1.16 2004/07/10 07:43:47 mcr
11008+ * added Moved from linux/lib/libfreeswan/addrtot.c,v
11009+ * added
11010+ * added Revision 1.15 2004/04/11 17:39:25 mcr
11011+ * added removed internal.h requirements.
11012+ * added
11013+ * added Revision 1.14 2004/03/08 01:59:08 ken
11014+ * added freeswan.h -> openswan.h
11015+ * added
11016+ * added Revision 1.13 2004/01/05 23:21:05 mcr
11017+ * added if the address type is invalid, then return length of <invalid>
11018+ * added string!
11019+ * added
11020+ *
11021+ *
11022+ */
11023+
11024--- /dev/null Tue Mar 11 13:02:56 2003
11025+++ linux/net/ipsec/addrtypeof.c Mon Feb 9 13:51:03 2004
11026@@ -0,0 +1,93 @@
11027+/*
11028+ * extract parts of an ip_address
11029+ * Copyright (C) 2000 Henry Spencer.
11030+ *
11031+ * This library is free software; you can redistribute it and/or modify it
11032+ * under the terms of the GNU Library General Public License as published by
11033+ * the Free Software Foundation; either version 2 of the License, or (at your
11034+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
11035+ *
11036+ * This library is distributed in the hope that it will be useful, but
11037+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11038+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
11039+ * License for more details.
11040+ *
11041+ * RCSID $Id: addrtypeof.c,v 1.10 2004-07-10 07:43:47 mcr Exp $
11042+ */
11043+#include "openswan.h"
11044+
11045+/*
11046+ - addrtypeof - get the type of an ip_address
11047+ */
11048+int
11049+addrtypeof(src)
11050+const ip_address *src;
11051+{
11052+ return src->u.v4.sin_family;
11053+}
11054+
11055+/*
11056+ - addrbytesptr - get pointer to the address bytes of an ip_address
11057+ */
11058+size_t /* 0 for error */
11059+addrbytesptr(src, dstp)
11060+const ip_address *src;
11061+const unsigned char **dstp; /* NULL means just a size query */
11062+{
11063+ const unsigned char *p;
11064+ size_t n;
11065+
11066+ switch (src->u.v4.sin_family) {
11067+ case AF_INET:
11068+ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
11069+ n = 4;
11070+ break;
11071+ case AF_INET6:
11072+ p = (const unsigned char *)&src->u.v6.sin6_addr;
11073+ n = 16;
11074+ break;
11075+ default:
11076+ return 0;
11077+ break;
11078+ }
11079+
11080+ if (dstp != NULL)
11081+ *dstp = p;
11082+ return n;
11083+}
11084+
11085+/*
11086+ - addrlenof - get length of the address bytes of an ip_address
11087+ */
11088+size_t /* 0 for error */
11089+addrlenof(src)
11090+const ip_address *src;
11091+{
11092+ return addrbytesptr(src, NULL);
11093+}
11094+
11095+/*
11096+ - addrbytesof - get the address bytes of an ip_address
11097+ */
11098+size_t /* 0 for error */
11099+addrbytesof(src, dst, dstlen)
11100+const ip_address *src;
11101+unsigned char *dst;
11102+size_t dstlen;
11103+{
11104+ const unsigned char *p;
11105+ size_t n;
11106+ size_t ncopy;
11107+
11108+ n = addrbytesptr(src, &p);
11109+ if (n == 0)
11110+ return 0;
11111+
11112+ if (dstlen > 0) {
11113+ ncopy = n;
11114+ if (ncopy > dstlen)
11115+ ncopy = dstlen;
11116+ memcpy(dst, p, ncopy);
11117+ }
11118+ return n;
11119+}
11120--- /dev/null Tue Mar 11 13:02:56 2003
11121+++ linux/net/ipsec/adler32.c Mon Feb 9 13:51:03 2004
11122@@ -0,0 +1,49 @@
11123+/* adler32.c -- compute the Adler-32 checksum of a data stream
11124+ * Copyright (C) 1995-2002 Mark Adler
11125+ * For conditions of distribution and use, see copyright notice in zlib.h
11126+ */
11127+
11128+/* @(#) $Id: adler32.c,v 1.6 2004-07-10 19:11:18 mcr Exp $ */
11129+
11130+#include <zlib/zlib.h>
11131+#include <zlib/zconf.h>
11132+
11133+#define BASE 65521L /* largest prime smaller than 65536 */
11134+#define NMAX 5552
11135+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
11136+
11137+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
11138+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
11139+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
11140+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
11141+#define DO16(buf) DO8(buf,0); DO8(buf,8);
11142+
11143+/* ========================================================================= */
11144+uLong ZEXPORT adler32(adler, buf, len)
11145+ uLong adler;
11146+ const Bytef *buf;
11147+ uInt len;
11148+{
11149+ unsigned long s1 = adler & 0xffff;
11150+ unsigned long s2 = (adler >> 16) & 0xffff;
11151+ int k;
11152+
11153+ if (buf == Z_NULL) return 1L;
11154+
11155+ while (len > 0) {
11156+ k = len < NMAX ? len : NMAX;
11157+ len -= k;
11158+ while (k >= 16) {
11159+ DO16(buf);
11160+ buf += 16;
11161+ k -= 16;
11162+ }
11163+ if (k != 0) do {
11164+ s1 += *buf++;
11165+ s2 += s1;
11166+ } while (--k);
11167+ s1 %= BASE;
11168+ s2 %= BASE;
11169+ }
11170+ return (s2 << 16) | s1;
11171+}
11172--- /dev/null Tue Mar 11 13:02:56 2003
11173+++ linux/net/ipsec/aes/Makefile Mon Feb 9 13:51:03 2004
11174@@ -0,0 +1,59 @@
11175+# Makefile for KLIPS 3DES kernel code as a module for 2.6 kernels
11176+#
11177+# Makefile for KLIPS kernel code as a module
11178+# Copyright (C) 2002-2004 Michael Richardson <mcr@xelerance.com>
11179+#
11180+# This program is free software; you can redistribute it and/or modify it
11181+# under the terms of the GNU General Public License as published by the
11182+# Free Software Foundation; either version 2 of the License, or (at your
11183+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11184+#
11185+# This program is distributed in the hope that it will be useful, but
11186+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11187+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11188+# for more details.
11189+#
11190+# RCSID $Id: Makefile.fs2_6,v 1.1.10.1 2005-08-12 16:10:05 ken Exp $
11191+#
11192+# Note! Dependencies are done automagically by 'make dep', which also
11193+# removes any old dependencies. DON'T put your own dependencies here
11194+# unless it's something special (ie not a .c file).
11195+#
11196+
11197+obj-$(CONFIG_KLIPS_ENC_AES) += ipsec_alg_aes.o
11198+obj-$(CONFIG_KLIPS_ENC_AES) += aes_xcbc_mac.o
11199+obj-$(CONFIG_KLIPS_ENC_AES) += aes_cbc.o
11200+
11201+ifeq ($(strip ${SUBARCH}),)
11202+SUBARCH:=${ARCH}
11203+endif
11204+
11205+# the assembly version expects frame pointers, which are
11206+# optional in many kernel builds. If you want speed, you should
11207+# probably use cryptoapi code instead.
11208+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
11209+ifeq (${USEASSEMBLY},i386y)
11210+obj-$(CONFIG_KLIPS_ENC_AES) += aes-i586.o
11211+else
11212+obj-$(CONFIG_KLIPS_ENC_AES) += aes.o
11213+endif
11214+
11215+
11216+#
11217+# $Log: Makefile.fs2_6,v $
11218+# Revision 1.1.10.1 2005-08-12 16:10:05 ken
11219+# do not use assembly code with there are no frame pointers
11220+#
11221+# Revision 1.2 2005/08/12 14:13:58 mcr
11222+# do not use assembly code with there are no frame pointers,
11223+# as it does not have the right linkages.
11224+#
11225+# Revision 1.1 2004/08/17 03:31:34 mcr
11226+# klips 2.6 edits.
11227+#
11228+#
11229+# Local Variables:
11230+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
11231+# End Variables:
11232+#
11233+
11234--- /dev/null Tue Mar 11 13:02:56 2003
11235+++ linux/net/ipsec/aes/aes-i586.S Mon Feb 9 13:51:03 2004
11236@@ -0,0 +1,892 @@
11237+//
11238+// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
11239+// All rights reserved.
11240+//
11241+// TERMS
11242+//
11243+// Redistribution and use in source and binary forms, with or without
11244+// modification, are permitted subject to the following conditions:
11245+//
11246+// 1. Redistributions of source code must retain the above copyright
11247+// notice, this list of conditions and the following disclaimer.
11248+//
11249+// 2. Redistributions in binary form must reproduce the above copyright
11250+// notice, this list of conditions and the following disclaimer in the
11251+// documentation and/or other materials provided with the distribution.
11252+//
11253+// 3. The copyright holder's name must not be used to endorse or promote
11254+// any products derived from this software without his specific prior
11255+// written permission.
11256+//
11257+// This software is provided 'as is' with no express or implied warranties
11258+// of correctness or fitness for purpose.
11259+
11260+// Modified by Jari Ruusu, December 24 2001
11261+// - Converted syntax to GNU CPP/assembler syntax
11262+// - C programming interface converted back to "old" API
11263+// - Minor portability cleanups and speed optimizations
11264+
11265+// An AES (Rijndael) implementation for the Pentium. This version only
11266+// implements the standard AES block length (128 bits, 16 bytes). This code
11267+// does not preserve the eax, ecx or edx registers or the artihmetic status
11268+// flags. However, the ebx, esi, edi, and ebp registers are preserved across
11269+// calls.
11270+
11271+// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
11272+// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
11273+// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
11274+
11275+#if defined(USE_UNDERLINE)
11276+# define aes_set_key _aes_set_key
11277+# define aes_encrypt _aes_encrypt
11278+# define aes_decrypt _aes_decrypt
11279+#endif
11280+#if !defined(ALIGN32BYTES)
11281+# define ALIGN32BYTES 32
11282+#endif
11283+
11284+ .file "aes-i586.S"
11285+ .globl aes_set_key
11286+ .globl aes_encrypt
11287+ .globl aes_decrypt
11288+
11289+#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
11290+
11291+// offsets to parameters with one register pushed onto stack
11292+
11293+#define ctx 8 // AES context structure
11294+#define in_blk 12 // input byte array address parameter
11295+#define out_blk 16 // output byte array address parameter
11296+
11297+// offsets in context structure
11298+
11299+#define nkey 0 // key length, size 4
11300+#define nrnd 4 // number of rounds, size 4
11301+#define ekey 8 // encryption key schedule base address, size 256
11302+#define dkey 264 // decryption key schedule base address, size 256
11303+
11304+// This macro performs a forward encryption cycle. It is entered with
11305+// the first previous round column values in %eax, %ebx, %esi and %edi and
11306+// exits with the final values in the same registers.
11307+
11308+#define fwd_rnd(p1,p2) \
11309+ mov %ebx,(%esp) ;\
11310+ movzbl %al,%edx ;\
11311+ mov %eax,%ecx ;\
11312+ mov p2(%ebp),%eax ;\
11313+ mov %edi,4(%esp) ;\
11314+ mov p2+12(%ebp),%edi ;\
11315+ xor p1(,%edx,4),%eax ;\
11316+ movzbl %ch,%edx ;\
11317+ shr $16,%ecx ;\
11318+ mov p2+4(%ebp),%ebx ;\
11319+ xor p1+tlen(,%edx,4),%edi ;\
11320+ movzbl %cl,%edx ;\
11321+ movzbl %ch,%ecx ;\
11322+ xor p1+3*tlen(,%ecx,4),%ebx ;\
11323+ mov %esi,%ecx ;\
11324+ mov p1+2*tlen(,%edx,4),%esi ;\
11325+ movzbl %cl,%edx ;\
11326+ xor p1(,%edx,4),%esi ;\
11327+ movzbl %ch,%edx ;\
11328+ shr $16,%ecx ;\
11329+ xor p1+tlen(,%edx,4),%ebx ;\
11330+ movzbl %cl,%edx ;\
11331+ movzbl %ch,%ecx ;\
11332+ xor p1+2*tlen(,%edx,4),%eax ;\
11333+ mov (%esp),%edx ;\
11334+ xor p1+3*tlen(,%ecx,4),%edi ;\
11335+ movzbl %dl,%ecx ;\
11336+ xor p2+8(%ebp),%esi ;\
11337+ xor p1(,%ecx,4),%ebx ;\
11338+ movzbl %dh,%ecx ;\
11339+ shr $16,%edx ;\
11340+ xor p1+tlen(,%ecx,4),%eax ;\
11341+ movzbl %dl,%ecx ;\
11342+ movzbl %dh,%edx ;\
11343+ xor p1+2*tlen(,%ecx,4),%edi ;\
11344+ mov 4(%esp),%ecx ;\
11345+ xor p1+3*tlen(,%edx,4),%esi ;\
11346+ movzbl %cl,%edx ;\
11347+ xor p1(,%edx,4),%edi ;\
11348+ movzbl %ch,%edx ;\
11349+ shr $16,%ecx ;\
11350+ xor p1+tlen(,%edx,4),%esi ;\
11351+ movzbl %cl,%edx ;\
11352+ movzbl %ch,%ecx ;\
11353+ xor p1+2*tlen(,%edx,4),%ebx ;\
11354+ xor p1+3*tlen(,%ecx,4),%eax
11355+
11356+// This macro performs an inverse encryption cycle. It is entered with
11357+// the first previous round column values in %eax, %ebx, %esi and %edi and
11358+// exits with the final values in the same registers.
11359+
11360+#define inv_rnd(p1,p2) \
11361+ movzbl %al,%edx ;\
11362+ mov %ebx,(%esp) ;\
11363+ mov %eax,%ecx ;\
11364+ mov p2(%ebp),%eax ;\
11365+ mov %edi,4(%esp) ;\
11366+ mov p2+4(%ebp),%ebx ;\
11367+ xor p1(,%edx,4),%eax ;\
11368+ movzbl %ch,%edx ;\
11369+ shr $16,%ecx ;\
11370+ mov p2+12(%ebp),%edi ;\
11371+ xor p1+tlen(,%edx,4),%ebx ;\
11372+ movzbl %cl,%edx ;\
11373+ movzbl %ch,%ecx ;\
11374+ xor p1+3*tlen(,%ecx,4),%edi ;\
11375+ mov %esi,%ecx ;\
11376+ mov p1+2*tlen(,%edx,4),%esi ;\
11377+ movzbl %cl,%edx ;\
11378+ xor p1(,%edx,4),%esi ;\
11379+ movzbl %ch,%edx ;\
11380+ shr $16,%ecx ;\
11381+ xor p1+tlen(,%edx,4),%edi ;\
11382+ movzbl %cl,%edx ;\
11383+ movzbl %ch,%ecx ;\
11384+ xor p1+2*tlen(,%edx,4),%eax ;\
11385+ mov (%esp),%edx ;\
11386+ xor p1+3*tlen(,%ecx,4),%ebx ;\
11387+ movzbl %dl,%ecx ;\
11388+ xor p2+8(%ebp),%esi ;\
11389+ xor p1(,%ecx,4),%ebx ;\
11390+ movzbl %dh,%ecx ;\
11391+ shr $16,%edx ;\
11392+ xor p1+tlen(,%ecx,4),%esi ;\
11393+ movzbl %dl,%ecx ;\
11394+ movzbl %dh,%edx ;\
11395+ xor p1+2*tlen(,%ecx,4),%edi ;\
11396+ mov 4(%esp),%ecx ;\
11397+ xor p1+3*tlen(,%edx,4),%eax ;\
11398+ movzbl %cl,%edx ;\
11399+ xor p1(,%edx,4),%edi ;\
11400+ movzbl %ch,%edx ;\
11401+ shr $16,%ecx ;\
11402+ xor p1+tlen(,%edx,4),%eax ;\
11403+ movzbl %cl,%edx ;\
11404+ movzbl %ch,%ecx ;\
11405+ xor p1+2*tlen(,%edx,4),%ebx ;\
11406+ xor p1+3*tlen(,%ecx,4),%esi
11407+
11408+// AES (Rijndael) Encryption Subroutine
11409+
11410+ .text
11411+ .align ALIGN32BYTES
11412+aes_encrypt:
11413+ push %ebp
11414+ mov ctx(%esp),%ebp // pointer to context
11415+ mov in_blk(%esp),%ecx
11416+ push %ebx
11417+ push %esi
11418+ push %edi
11419+ mov nrnd(%ebp),%edx // number of rounds
11420+ lea ekey+16(%ebp),%ebp // key pointer
11421+
11422+// input four columns and xor in first round key
11423+
11424+ mov (%ecx),%eax
11425+ mov 4(%ecx),%ebx
11426+ mov 8(%ecx),%esi
11427+ mov 12(%ecx),%edi
11428+ xor -16(%ebp),%eax
11429+ xor -12(%ebp),%ebx
11430+ xor -8(%ebp),%esi
11431+ xor -4(%ebp),%edi
11432+
11433+ sub $8,%esp // space for register saves on stack
11434+
11435+ sub $10,%edx
11436+ je aes_15
11437+ add $32,%ebp
11438+ sub $2,%edx
11439+ je aes_13
11440+ add $32,%ebp
11441+
11442+ fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
11443+ fwd_rnd(aes_ft_tab,-48)
11444+aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
11445+ fwd_rnd(aes_ft_tab,-16)
11446+aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
11447+ fwd_rnd(aes_ft_tab,16)
11448+ fwd_rnd(aes_ft_tab,32)
11449+ fwd_rnd(aes_ft_tab,48)
11450+ fwd_rnd(aes_ft_tab,64)
11451+ fwd_rnd(aes_ft_tab,80)
11452+ fwd_rnd(aes_ft_tab,96)
11453+ fwd_rnd(aes_ft_tab,112)
11454+ fwd_rnd(aes_ft_tab,128)
11455+ fwd_rnd(aes_fl_tab,144) // last round uses a different table
11456+
11457+// move final values to the output array.
11458+
11459+ mov out_blk+20(%esp),%ebp
11460+ add $8,%esp
11461+ mov %eax,(%ebp)
11462+ mov %ebx,4(%ebp)
11463+ mov %esi,8(%ebp)
11464+ mov %edi,12(%ebp)
11465+ pop %edi
11466+ pop %esi
11467+ pop %ebx
11468+ pop %ebp
11469+ ret
11470+
11471+
11472+// AES (Rijndael) Decryption Subroutine
11473+
11474+ .align ALIGN32BYTES
11475+aes_decrypt:
11476+ push %ebp
11477+ mov ctx(%esp),%ebp // pointer to context
11478+ mov in_blk(%esp),%ecx
11479+ push %ebx
11480+ push %esi
11481+ push %edi
11482+ mov nrnd(%ebp),%edx // number of rounds
11483+ lea dkey+16(%ebp),%ebp // key pointer
11484+
11485+// input four columns and xor in first round key
11486+
11487+ mov (%ecx),%eax
11488+ mov 4(%ecx),%ebx
11489+ mov 8(%ecx),%esi
11490+ mov 12(%ecx),%edi
11491+ xor -16(%ebp),%eax
11492+ xor -12(%ebp),%ebx
11493+ xor -8(%ebp),%esi
11494+ xor -4(%ebp),%edi
11495+
11496+ sub $8,%esp // space for register saves on stack
11497+
11498+ sub $10,%edx
11499+ je aes_25
11500+ add $32,%ebp
11501+ sub $2,%edx
11502+ je aes_23
11503+ add $32,%ebp
11504+
11505+ inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
11506+ inv_rnd(aes_it_tab,-48)
11507+aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
11508+ inv_rnd(aes_it_tab,-16)
11509+aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
11510+ inv_rnd(aes_it_tab,16)
11511+ inv_rnd(aes_it_tab,32)
11512+ inv_rnd(aes_it_tab,48)
11513+ inv_rnd(aes_it_tab,64)
11514+ inv_rnd(aes_it_tab,80)
11515+ inv_rnd(aes_it_tab,96)
11516+ inv_rnd(aes_it_tab,112)
11517+ inv_rnd(aes_it_tab,128)
11518+ inv_rnd(aes_il_tab,144) // last round uses a different table
11519+
11520+// move final values to the output array.
11521+
11522+ mov out_blk+20(%esp),%ebp
11523+ add $8,%esp
11524+ mov %eax,(%ebp)
11525+ mov %ebx,4(%ebp)
11526+ mov %esi,8(%ebp)
11527+ mov %edi,12(%ebp)
11528+ pop %edi
11529+ pop %esi
11530+ pop %ebx
11531+ pop %ebp
11532+ ret
11533+
11534+// AES (Rijndael) Key Schedule Subroutine
11535+
11536+// input/output parameters
11537+
11538+#define aes_cx 12 // AES context
11539+#define in_key 16 // key input array address
11540+#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
11541+#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
11542+
11543+// offsets for locals
11544+
11545+#define cnt -4
11546+#define kpf -8
11547+#define slen 8
11548+
11549+// This macro performs a column mixing operation on an input 32-bit
11550+// word to give a 32-bit result. It uses each of the 4 bytes in the
11551+// the input column to index 4 different tables of 256 32-bit words
11552+// that are xored together to form the output value.
11553+
11554+#define mix_col(p1) \
11555+ movzbl %bl,%ecx ;\
11556+ mov p1(,%ecx,4),%eax ;\
11557+ movzbl %bh,%ecx ;\
11558+ ror $16,%ebx ;\
11559+ xor p1+tlen(,%ecx,4),%eax ;\
11560+ movzbl %bl,%ecx ;\
11561+ xor p1+2*tlen(,%ecx,4),%eax ;\
11562+ movzbl %bh,%ecx ;\
11563+ xor p1+3*tlen(,%ecx,4),%eax
11564+
11565+// Key Schedule Macros
11566+
11567+#define ksc4(p1) \
11568+ rol $24,%ebx ;\
11569+ mix_col(aes_fl_tab) ;\
11570+ ror $8,%ebx ;\
11571+ xor 4*p1+aes_rcon_tab,%eax ;\
11572+ xor %eax,%esi ;\
11573+ xor %esi,%ebp ;\
11574+ mov %esi,16*p1(%edi) ;\
11575+ mov %ebp,16*p1+4(%edi) ;\
11576+ xor %ebp,%edx ;\
11577+ xor %edx,%ebx ;\
11578+ mov %edx,16*p1+8(%edi) ;\
11579+ mov %ebx,16*p1+12(%edi)
11580+
11581+#define ksc6(p1) \
11582+ rol $24,%ebx ;\
11583+ mix_col(aes_fl_tab) ;\
11584+ ror $8,%ebx ;\
11585+ xor 4*p1+aes_rcon_tab,%eax ;\
11586+ xor 24*p1-24(%edi),%eax ;\
11587+ mov %eax,24*p1(%edi) ;\
11588+ xor 24*p1-20(%edi),%eax ;\
11589+ mov %eax,24*p1+4(%edi) ;\
11590+ xor %eax,%esi ;\
11591+ xor %esi,%ebp ;\
11592+ mov %esi,24*p1+8(%edi) ;\
11593+ mov %ebp,24*p1+12(%edi) ;\
11594+ xor %ebp,%edx ;\
11595+ xor %edx,%ebx ;\
11596+ mov %edx,24*p1+16(%edi) ;\
11597+ mov %ebx,24*p1+20(%edi)
11598+
11599+#define ksc8(p1) \
11600+ rol $24,%ebx ;\
11601+ mix_col(aes_fl_tab) ;\
11602+ ror $8,%ebx ;\
11603+ xor 4*p1+aes_rcon_tab,%eax ;\
11604+ xor 32*p1-32(%edi),%eax ;\
11605+ mov %eax,32*p1(%edi) ;\
11606+ xor 32*p1-28(%edi),%eax ;\
11607+ mov %eax,32*p1+4(%edi) ;\
11608+ xor 32*p1-24(%edi),%eax ;\
11609+ mov %eax,32*p1+8(%edi) ;\
11610+ xor 32*p1-20(%edi),%eax ;\
11611+ mov %eax,32*p1+12(%edi) ;\
11612+ push %ebx ;\
11613+ mov %eax,%ebx ;\
11614+ mix_col(aes_fl_tab) ;\
11615+ pop %ebx ;\
11616+ xor %eax,%esi ;\
11617+ xor %esi,%ebp ;\
11618+ mov %esi,32*p1+16(%edi) ;\
11619+ mov %ebp,32*p1+20(%edi) ;\
11620+ xor %ebp,%edx ;\
11621+ xor %edx,%ebx ;\
11622+ mov %edx,32*p1+24(%edi) ;\
11623+ mov %ebx,32*p1+28(%edi)
11624+
11625+ .align ALIGN32BYTES
11626+aes_set_key:
11627+ pushfl
11628+ push %ebp
11629+ mov %esp,%ebp
11630+ sub $slen,%esp
11631+ push %ebx
11632+ push %esi
11633+ push %edi
11634+
11635+ mov aes_cx(%ebp),%edx // edx -> AES context
11636+
11637+ mov key_ln(%ebp),%ecx // key length
11638+ cmpl $128,%ecx
11639+ jb aes_30
11640+ shr $3,%ecx
11641+aes_30: cmpl $32,%ecx
11642+ je aes_32
11643+ cmpl $24,%ecx
11644+ je aes_32
11645+ mov $16,%ecx
11646+aes_32: shr $2,%ecx
11647+ mov %ecx,nkey(%edx)
11648+
11649+ lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
11650+ mov %eax,nrnd(%edx)
11651+
11652+ mov in_key(%ebp),%esi // key input array
11653+ lea ekey(%edx),%edi // key position in AES context
11654+ cld
11655+ push %ebp
11656+ mov %ecx,%eax // save key length in eax
11657+ rep ; movsl // words in the key schedule
11658+ mov -4(%esi),%ebx // put some values in registers
11659+ mov -8(%esi),%edx // to allow faster code
11660+ mov -12(%esi),%ebp
11661+ mov -16(%esi),%esi
11662+
11663+ cmpl $4,%eax // jump on key size
11664+ je aes_36
11665+ cmpl $6,%eax
11666+ je aes_35
11667+
11668+ ksc8(0)
11669+ ksc8(1)
11670+ ksc8(2)
11671+ ksc8(3)
11672+ ksc8(4)
11673+ ksc8(5)
11674+ ksc8(6)
11675+ jmp aes_37
11676+aes_35: ksc6(0)
11677+ ksc6(1)
11678+ ksc6(2)
11679+ ksc6(3)
11680+ ksc6(4)
11681+ ksc6(5)
11682+ ksc6(6)
11683+ ksc6(7)
11684+ jmp aes_37
11685+aes_36: ksc4(0)
11686+ ksc4(1)
11687+ ksc4(2)
11688+ ksc4(3)
11689+ ksc4(4)
11690+ ksc4(5)
11691+ ksc4(6)
11692+ ksc4(7)
11693+ ksc4(8)
11694+ ksc4(9)
11695+aes_37: pop %ebp
11696+ mov aes_cx(%ebp),%edx // edx -> AES context
11697+ cmpl $0,ed_flg(%ebp)
11698+ jne aes_39
11699+
11700+// compile decryption key schedule from encryption schedule - reverse
11701+// order and do mix_column operation on round keys except first and last
11702+
11703+ mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
11704+ shl $2,%eax
11705+ lea dkey(%edx,%eax,4),%edi
11706+ lea ekey(%edx),%esi // kf = cx->e_key
11707+
11708+ movsl // copy first round key (unmodified)
11709+ movsl
11710+ movsl
11711+ movsl
11712+ sub $32,%edi
11713+ movl $1,cnt(%ebp)
11714+aes_38: // do mix column on each column of
11715+ lodsl // each round key
11716+ mov %eax,%ebx
11717+ mix_col(aes_im_tab)
11718+ stosl
11719+ lodsl
11720+ mov %eax,%ebx
11721+ mix_col(aes_im_tab)
11722+ stosl
11723+ lodsl
11724+ mov %eax,%ebx
11725+ mix_col(aes_im_tab)
11726+ stosl
11727+ lodsl
11728+ mov %eax,%ebx
11729+ mix_col(aes_im_tab)
11730+ stosl
11731+ sub $32,%edi
11732+
11733+ incl cnt(%ebp)
11734+ mov cnt(%ebp),%eax
11735+ cmp nrnd(%edx),%eax
11736+ jb aes_38
11737+
11738+ movsl // copy last round key (unmodified)
11739+ movsl
11740+ movsl
11741+ movsl
11742+aes_39: pop %edi
11743+ pop %esi
11744+ pop %ebx
11745+ mov %ebp,%esp
11746+ pop %ebp
11747+ popfl
11748+ ret
11749+
11750+
11751+// finite field multiplies by {02}, {04} and {08}
11752+
11753+#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
11754+#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
11755+#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
11756+
11757+// finite field multiplies required in table generation
11758+
11759+#define f3(x) (f2(x) ^ x)
11760+#define f9(x) (f8(x) ^ x)
11761+#define fb(x) (f8(x) ^ f2(x) ^ x)
11762+#define fd(x) (f8(x) ^ f4(x) ^ x)
11763+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
11764+
11765+// These defines generate the forward table entries
11766+
11767+#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
11768+#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
11769+#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
11770+#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
11771+
11772+// These defines generate the inverse table entries
11773+
11774+#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
11775+#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
11776+#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
11777+#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
11778+
11779+// These defines generate entries for the last round tables
11780+
11781+#define w0(x) (x)
11782+#define w1(x) (x << 8)
11783+#define w2(x) (x << 16)
11784+#define w3(x) (x << 24)
11785+
11786+// macro to generate inverse mix column tables (needed for the key schedule)
11787+
11788+#define im_data0(p1) \
11789+ .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
11790+ .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
11791+ .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
11792+ .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
11793+#define im_data1(p1) \
11794+ .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
11795+ .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
11796+ .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
11797+ .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
11798+#define im_data2(p1) \
11799+ .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
11800+ .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
11801+ .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
11802+ .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
11803+#define im_data3(p1) \
11804+ .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
11805+ .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
11806+ .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
11807+ .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
11808+#define im_data4(p1) \
11809+ .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
11810+ .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
11811+ .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
11812+ .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
11813+#define im_data5(p1) \
11814+ .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
11815+ .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
11816+ .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
11817+ .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
11818+#define im_data6(p1) \
11819+ .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
11820+ .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
11821+ .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
11822+ .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
11823+#define im_data7(p1) \
11824+ .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
11825+ .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
11826+ .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
11827+ .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
11828+
11829+// S-box data - 256 entries
11830+
11831+#define sb_data0(p1) \
11832+ .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
11833+ .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
11834+ .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
11835+ .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
11836+#define sb_data1(p1) \
11837+ .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
11838+ .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
11839+ .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
11840+ .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
11841+#define sb_data2(p1) \
11842+ .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
11843+ .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
11844+ .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
11845+ .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
11846+#define sb_data3(p1) \
11847+ .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
11848+ .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
11849+ .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
11850+ .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
11851+#define sb_data4(p1) \
11852+ .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
11853+ .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
11854+ .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
11855+ .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
11856+#define sb_data5(p1) \
11857+ .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
11858+ .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
11859+ .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
11860+ .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
11861+#define sb_data6(p1) \
11862+ .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
11863+ .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
11864+ .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
11865+ .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
11866+#define sb_data7(p1) \
11867+ .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
11868+ .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
11869+ .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
11870+ .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
11871+
11872+// Inverse S-box data - 256 entries
11873+
11874+#define ib_data0(p1) \
11875+ .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
11876+ .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
11877+ .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
11878+ .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
11879+#define ib_data1(p1) \
11880+ .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
11881+ .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
11882+ .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
11883+ .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
11884+#define ib_data2(p1) \
11885+ .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
11886+ .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
11887+ .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
11888+ .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
11889+#define ib_data3(p1) \
11890+ .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
11891+ .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
11892+ .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
11893+ .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
11894+#define ib_data4(p1) \
11895+ .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
11896+ .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
11897+ .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
11898+ .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
11899+#define ib_data5(p1) \
11900+ .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
11901+ .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
11902+ .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
11903+ .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
11904+#define ib_data6(p1) \
11905+ .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
11906+ .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
11907+ .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
11908+ .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
11909+#define ib_data7(p1) \
11910+ .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
11911+ .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
11912+ .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
11913+ .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
11914+
11915+// The rcon_table (needed for the key schedule)
11916+//
11917+// Here is original Dr Brian Gladman's source code:
11918+// _rcon_tab:
11919+// %assign x 1
11920+// %rep 29
11921+// dd x
11922+// %assign x f2(x)
11923+// %endrep
11924+//
11925+// Here is precomputed output (it's more portable this way):
11926+
11927+ .align ALIGN32BYTES
11928+aes_rcon_tab:
11929+ .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
11930+ .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
11931+ .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
11932+ .long 0xb3,0x7d,0xfa,0xef,0xc5
11933+
11934+// The forward xor tables
11935+
11936+ .align ALIGN32BYTES
11937+aes_ft_tab:
11938+ sb_data0(u0)
11939+ sb_data1(u0)
11940+ sb_data2(u0)
11941+ sb_data3(u0)
11942+ sb_data4(u0)
11943+ sb_data5(u0)
11944+ sb_data6(u0)
11945+ sb_data7(u0)
11946+
11947+ sb_data0(u1)
11948+ sb_data1(u1)
11949+ sb_data2(u1)
11950+ sb_data3(u1)
11951+ sb_data4(u1)
11952+ sb_data5(u1)
11953+ sb_data6(u1)
11954+ sb_data7(u1)
11955+
11956+ sb_data0(u2)
11957+ sb_data1(u2)
11958+ sb_data2(u2)
11959+ sb_data3(u2)
11960+ sb_data4(u2)
11961+ sb_data5(u2)
11962+ sb_data6(u2)
11963+ sb_data7(u2)
11964+
11965+ sb_data0(u3)
11966+ sb_data1(u3)
11967+ sb_data2(u3)
11968+ sb_data3(u3)
11969+ sb_data4(u3)
11970+ sb_data5(u3)
11971+ sb_data6(u3)
11972+ sb_data7(u3)
11973+
11974+ .align ALIGN32BYTES
11975+aes_fl_tab:
11976+ sb_data0(w0)
11977+ sb_data1(w0)
11978+ sb_data2(w0)
11979+ sb_data3(w0)
11980+ sb_data4(w0)
11981+ sb_data5(w0)
11982+ sb_data6(w0)
11983+ sb_data7(w0)
11984+
11985+ sb_data0(w1)
11986+ sb_data1(w1)
11987+ sb_data2(w1)
11988+ sb_data3(w1)
11989+ sb_data4(w1)
11990+ sb_data5(w1)
11991+ sb_data6(w1)
11992+ sb_data7(w1)
11993+
11994+ sb_data0(w2)
11995+ sb_data1(w2)
11996+ sb_data2(w2)
11997+ sb_data3(w2)
11998+ sb_data4(w2)
11999+ sb_data5(w2)
12000+ sb_data6(w2)
12001+ sb_data7(w2)
12002+
12003+ sb_data0(w3)
12004+ sb_data1(w3)
12005+ sb_data2(w3)
12006+ sb_data3(w3)
12007+ sb_data4(w3)
12008+ sb_data5(w3)
12009+ sb_data6(w3)
12010+ sb_data7(w3)
12011+
12012+// The inverse xor tables
12013+
12014+ .align ALIGN32BYTES
12015+aes_it_tab:
12016+ ib_data0(v0)
12017+ ib_data1(v0)
12018+ ib_data2(v0)
12019+ ib_data3(v0)
12020+ ib_data4(v0)
12021+ ib_data5(v0)
12022+ ib_data6(v0)
12023+ ib_data7(v0)
12024+
12025+ ib_data0(v1)
12026+ ib_data1(v1)
12027+ ib_data2(v1)
12028+ ib_data3(v1)
12029+ ib_data4(v1)
12030+ ib_data5(v1)
12031+ ib_data6(v1)
12032+ ib_data7(v1)
12033+
12034+ ib_data0(v2)
12035+ ib_data1(v2)
12036+ ib_data2(v2)
12037+ ib_data3(v2)
12038+ ib_data4(v2)
12039+ ib_data5(v2)
12040+ ib_data6(v2)
12041+ ib_data7(v2)
12042+
12043+ ib_data0(v3)
12044+ ib_data1(v3)
12045+ ib_data2(v3)
12046+ ib_data3(v3)
12047+ ib_data4(v3)
12048+ ib_data5(v3)
12049+ ib_data6(v3)
12050+ ib_data7(v3)
12051+
12052+ .align ALIGN32BYTES
12053+aes_il_tab:
12054+ ib_data0(w0)
12055+ ib_data1(w0)
12056+ ib_data2(w0)
12057+ ib_data3(w0)
12058+ ib_data4(w0)
12059+ ib_data5(w0)
12060+ ib_data6(w0)
12061+ ib_data7(w0)
12062+
12063+ ib_data0(w1)
12064+ ib_data1(w1)
12065+ ib_data2(w1)
12066+ ib_data3(w1)
12067+ ib_data4(w1)
12068+ ib_data5(w1)
12069+ ib_data6(w1)
12070+ ib_data7(w1)
12071+
12072+ ib_data0(w2)
12073+ ib_data1(w2)
12074+ ib_data2(w2)
12075+ ib_data3(w2)
12076+ ib_data4(w2)
12077+ ib_data5(w2)
12078+ ib_data6(w2)
12079+ ib_data7(w2)
12080+
12081+ ib_data0(w3)
12082+ ib_data1(w3)
12083+ ib_data2(w3)
12084+ ib_data3(w3)
12085+ ib_data4(w3)
12086+ ib_data5(w3)
12087+ ib_data6(w3)
12088+ ib_data7(w3)
12089+
12090+// The inverse mix column tables
12091+
12092+ .align ALIGN32BYTES
12093+aes_im_tab:
12094+ im_data0(v0)
12095+ im_data1(v0)
12096+ im_data2(v0)
12097+ im_data3(v0)
12098+ im_data4(v0)
12099+ im_data5(v0)
12100+ im_data6(v0)
12101+ im_data7(v0)
12102+
12103+ im_data0(v1)
12104+ im_data1(v1)
12105+ im_data2(v1)
12106+ im_data3(v1)
12107+ im_data4(v1)
12108+ im_data5(v1)
12109+ im_data6(v1)
12110+ im_data7(v1)
12111+
12112+ im_data0(v2)
12113+ im_data1(v2)
12114+ im_data2(v2)
12115+ im_data3(v2)
12116+ im_data4(v2)
12117+ im_data5(v2)
12118+ im_data6(v2)
12119+ im_data7(v2)
12120+
12121+ im_data0(v3)
12122+ im_data1(v3)
12123+ im_data2(v3)
12124+ im_data3(v3)
12125+ im_data4(v3)
12126+ im_data5(v3)
12127+ im_data6(v3)
12128+ im_data7(v3)
12129--- /dev/null Tue Mar 11 13:02:56 2003
12130+++ linux/net/ipsec/aes/aes.c Mon Feb 9 13:51:03 2004
12131@@ -0,0 +1,1415 @@
12132+// I retain copyright in this code but I encourage its free use provided
12133+// that I don't carry any responsibility for the results. I am especially
12134+// happy to see it used in free and open source software. If you do use
12135+// it I would appreciate an acknowledgement of its origin in the code or
12136+// the product that results and I would also appreciate knowing a little
12137+// about the use to which it is being put. I am grateful to Frank Yellin
12138+// for some ideas that are used in this implementation.
12139+//
12140+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
12141+//
12142+// This is an implementation of the AES encryption algorithm (Rijndael)
12143+// designed by Joan Daemen and Vincent Rijmen. This version is designed
12144+// to provide both fixed and dynamic block and key lengths and can also
12145+// run with either big or little endian internal byte order (see aes.h).
12146+// It inputs block and key lengths in bytes with the legal values being
12147+// 16, 24 and 32.
12148+
12149+/*
12150+ * Modified by Jari Ruusu, May 1 2001
12151+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
12152+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
12153+ * - Major name space cleanup: Names visible to outside now begin
12154+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
12155+ * - Removed C++ and DLL support as part of name space cleanup.
12156+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
12157+ * - Merged precomputed constant tables to aes.c file.
12158+ * - Removed data alignment restrictions for portability reasons.
12159+ * - Made block and key lengths accept bit count (128/192/256)
12160+ * as well byte count (16/24/32).
12161+ * - Removed all error checks. This change also eliminated the need
12162+ * to preinitialize the context struct to zero.
12163+ * - Removed some totally unused constants.
12164+ */
12165+
12166+#include "crypto/aes.h"
12167+
12168+// CONFIGURATION OPTIONS (see also aes.h)
12169+//
12170+// 1. Define UNROLL for full loop unrolling in encryption and decryption.
12171+// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
12172+// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
12173+// 4. Define FF_TABLES to use tables for field multiplies and inverses.
12174+// Do not enable this without understanding stack space requirements.
12175+// 5. Define ARRAYS to use arrays to hold the local state block. If this
12176+// is not defined, individually declared 32-bit words are used.
12177+// 6. Define FAST_VARIABLE if a high speed variable block implementation
12178+// is needed (essentially three separate fixed block size code sequences)
12179+// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
12180+// version using 1 table (2 kbytes of table space) or 4 tables (8
12181+// kbytes of table space) for higher speed.
12182+// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
12183+// increase by using tables for the last rounds but with more table
12184+// space (2 or 8 kbytes extra).
12185+// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
12186+// slower version is provided.
12187+// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
12188+// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
12189+
12190+#define UNROLL
12191+//#define PARTIAL_UNROLL
12192+
12193+#define FIXED_TABLES
12194+//#define FF_TABLES
12195+//#define ARRAYS
12196+#define FAST_VARIABLE
12197+
12198+//#define ONE_TABLE
12199+#define FOUR_TABLES
12200+
12201+//#define ONE_LR_TABLE
12202+#define FOUR_LR_TABLES
12203+
12204+//#define ONE_IM_TABLE
12205+#define FOUR_IM_TABLES
12206+
12207+#if defined(UNROLL) && defined (PARTIAL_UNROLL)
12208+#error both UNROLL and PARTIAL_UNROLL are defined
12209+#endif
12210+
12211+#if defined(ONE_TABLE) && defined (FOUR_TABLES)
12212+#error both ONE_TABLE and FOUR_TABLES are defined
12213+#endif
12214+
12215+#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
12216+#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
12217+#endif
12218+
12219+#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
12220+#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
12221+#endif
12222+
12223+#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
12224+#error an illegal block size has been specified
12225+#endif
12226+
12227+// upr(x,n): rotates bytes within words by n positions, moving bytes
12228+// to higher index positions with wrap around into low positions
12229+// ups(x,n): moves bytes by n positions to higher index positions in
12230+// words but without wrap around
12231+// bval(x,n): extracts a byte from a word
12232+
12233+#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
12234+#define ups(x,n) ((x) << 8 * (n))
12235+#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
12236+#define bytes2word(b0, b1, b2, b3) \
12237+ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
12238+
12239+
12240+/* little endian processor without data alignment restrictions: AES_LE_OK */
12241+/* original code: i386 */
12242+#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
12243+#define AES_LE_OK 1
12244+/* added (tested): alpha --jjo */
12245+#elif defined(__alpha__)|| defined (__alpha)
12246+#define AES_LE_OK 1
12247+/* added (tested): ia64 --jjo */
12248+#elif defined(__ia64__)|| defined (__ia64)
12249+#define AES_LE_OK 1
12250+#endif
12251+
12252+#ifdef AES_LE_OK
12253+/* little endian processor without data alignment restrictions */
12254+#define word_in(x) *(u_int32_t*)(x)
12255+#define const_word_in(x) *(const u_int32_t*)(x)
12256+#define word_out(x,v) *(u_int32_t*)(x) = (v)
12257+#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
12258+#else
12259+/* slower but generic big endian or with data alignment restrictions */
12260+/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
12261+#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))
12262+#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))
12263+#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)
12264+#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)
12265+#endif
12266+
12267+// Disable at least some poor combinations of options
12268+
12269+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
12270+#define FIXED_TABLES
12271+#undef UNROLL
12272+#undef ONE_LR_TABLE
12273+#undef FOUR_LR_TABLES
12274+#undef ONE_IM_TABLE
12275+#undef FOUR_IM_TABLES
12276+#elif !defined(FOUR_TABLES)
12277+#ifdef FOUR_LR_TABLES
12278+#undef FOUR_LR_TABLES
12279+#define ONE_LR_TABLE
12280+#endif
12281+#ifdef FOUR_IM_TABLES
12282+#undef FOUR_IM_TABLES
12283+#define ONE_IM_TABLE
12284+#endif
12285+#elif !defined(AES_BLOCK_SIZE)
12286+#if defined(UNROLL)
12287+#define PARTIAL_UNROLL
12288+#undef UNROLL
12289+#endif
12290+#endif
12291+
12292+// the finite field modular polynomial and elements
12293+
12294+#define ff_poly 0x011b
12295+#define ff_hi 0x80
12296+
12297+// multiply four bytes in GF(2^8) by 'x' {02} in parallel
12298+
12299+#define m1 0x80808080
12300+#define m2 0x7f7f7f7f
12301+#define m3 0x0000001b
12302+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
12303+
12304+// The following defines provide alternative definitions of FFmulX that might
12305+// give improved performance if a fast 32-bit multiply is not available. Note
12306+// that a temporary variable u needs to be defined where FFmulX is used.
12307+
12308+// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
12309+// #define m4 0x1b1b1b1b
12310+// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
12311+
12312+// perform column mix operation on four bytes in parallel
12313+
12314+#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
12315+
12316+#if defined(FIXED_TABLES)
12317+
12318+// the S-Box table
12319+
12320+static const unsigned char s_box[256] =
12321+{
12322+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
12323+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
12324+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
12325+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
12326+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
12327+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
12328+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
12329+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
12330+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
12331+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
12332+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
12333+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
12334+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
12335+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
12336+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
12337+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
12338+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
12339+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
12340+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
12341+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
12342+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
12343+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
12344+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
12345+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
12346+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
12347+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
12348+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
12349+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
12350+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
12351+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
12352+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
12353+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
12354+};
12355+
12356+// the inverse S-Box table
12357+
12358+static const unsigned char inv_s_box[256] =
12359+{
12360+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
12361+ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
12362+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
12363+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
12364+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
12365+ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
12366+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
12367+ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
12368+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
12369+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
12370+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
12371+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
12372+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
12373+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
12374+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
12375+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
12376+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
12377+ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
12378+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
12379+ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
12380+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
12381+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
12382+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
12383+ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
12384+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
12385+ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
12386+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
12387+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
12388+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
12389+ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
12390+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
12391+ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
12392+};
12393+
12394+#define w0(p) 0x000000##p
12395+
12396+// Number of elements required in this table for different
12397+// block and key lengths is:
12398+//
12399+// Nk = 4 6 8
12400+// ----------
12401+// Nb = 4 | 10 8 7
12402+// 6 | 19 12 11
12403+// 8 | 29 19 14
12404+//
12405+// this table can be a table of bytes if the key schedule
12406+// code is adjusted accordingly
12407+
12408+static const u_int32_t rcon_tab[29] =
12409+{
12410+ w0(01), w0(02), w0(04), w0(08),
12411+ w0(10), w0(20), w0(40), w0(80),
12412+ w0(1b), w0(36), w0(6c), w0(d8),
12413+ w0(ab), w0(4d), w0(9a), w0(2f),
12414+ w0(5e), w0(bc), w0(63), w0(c6),
12415+ w0(97), w0(35), w0(6a), w0(d4),
12416+ w0(b3), w0(7d), w0(fa), w0(ef),
12417+ w0(c5)
12418+};
12419+
12420+#undef w0
12421+
12422+#define r0(p,q,r,s) 0x##p##q##r##s
12423+#define r1(p,q,r,s) 0x##q##r##s##p
12424+#define r2(p,q,r,s) 0x##r##s##p##q
12425+#define r3(p,q,r,s) 0x##s##p##q##r
12426+#define w0(p) 0x000000##p
12427+#define w1(p) 0x0000##p##00
12428+#define w2(p) 0x00##p##0000
12429+#define w3(p) 0x##p##000000
12430+
12431+#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
12432+
12433+// data for forward tables (other than last round)
12434+
12435+#define f_table \
12436+ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
12437+ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
12438+ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
12439+ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
12440+ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
12441+ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
12442+ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
12443+ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
12444+ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
12445+ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
12446+ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
12447+ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
12448+ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
12449+ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
12450+ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
12451+ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
12452+ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
12453+ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
12454+ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
12455+ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
12456+ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
12457+ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
12458+ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
12459+ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
12460+ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
12461+ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
12462+ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
12463+ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
12464+ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
12465+ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
12466+ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
12467+ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
12468+ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
12469+ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
12470+ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
12471+ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
12472+ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
12473+ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
12474+ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
12475+ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
12476+ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
12477+ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
12478+ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
12479+ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
12480+ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
12481+ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
12482+ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
12483+ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
12484+ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
12485+ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
12486+ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
12487+ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
12488+ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
12489+ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
12490+ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
12491+ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
12492+ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
12493+ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
12494+ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
12495+ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
12496+ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
12497+ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
12498+ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
12499+ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
12500+
12501+// data for inverse tables (other than last round)
12502+
12503+#define i_table \
12504+ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
12505+ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
12506+ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
12507+ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
12508+ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
12509+ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
12510+ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
12511+ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
12512+ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
12513+ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
12514+ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
12515+ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
12516+ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
12517+ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
12518+ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
12519+ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
12520+ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
12521+ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
12522+ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
12523+ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
12524+ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
12525+ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
12526+ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
12527+ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
12528+ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
12529+ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
12530+ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
12531+ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
12532+ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
12533+ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
12534+ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
12535+ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
12536+ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
12537+ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
12538+ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
12539+ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
12540+ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
12541+ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
12542+ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
12543+ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
12544+ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
12545+ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
12546+ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
12547+ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
12548+ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
12549+ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
12550+ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
12551+ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
12552+ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
12553+ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
12554+ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
12555+ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
12556+ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
12557+ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
12558+ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
12559+ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
12560+ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
12561+ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
12562+ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
12563+ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
12564+ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
12565+ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
12566+ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
12567+ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
12568+
12569+// generate the required tables in the desired endian format
12570+
12571+#undef r
12572+#define r r0
12573+
12574+#if defined(ONE_TABLE)
12575+static const u_int32_t ft_tab[256] =
12576+ { f_table };
12577+#elif defined(FOUR_TABLES)
12578+static const u_int32_t ft_tab[4][256] =
12579+{ { f_table },
12580+#undef r
12581+#define r r1
12582+ { f_table },
12583+#undef r
12584+#define r r2
12585+ { f_table },
12586+#undef r
12587+#define r r3
12588+ { f_table }
12589+};
12590+#endif
12591+
12592+#undef r
12593+#define r r0
12594+#if defined(ONE_TABLE)
12595+static const u_int32_t it_tab[256] =
12596+ { i_table };
12597+#elif defined(FOUR_TABLES)
12598+static const u_int32_t it_tab[4][256] =
12599+{ { i_table },
12600+#undef r
12601+#define r r1
12602+ { i_table },
12603+#undef r
12604+#define r r2
12605+ { i_table },
12606+#undef r
12607+#define r r3
12608+ { i_table }
12609+};
12610+#endif
12611+
12612+#endif
12613+
12614+#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
12615+
12616+// data for inverse tables (last round)
12617+
12618+#define li_table \
12619+ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
12620+ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
12621+ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
12622+ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
12623+ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
12624+ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
12625+ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
12626+ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
12627+ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
12628+ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
12629+ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
12630+ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
12631+ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
12632+ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
12633+ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
12634+ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
12635+ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
12636+ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
12637+ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
12638+ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
12639+ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
12640+ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
12641+ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
12642+ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
12643+ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
12644+ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
12645+ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
12646+ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
12647+ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
12648+ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
12649+ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
12650+ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
12651+
12652+// generate the required tables in the desired endian format
12653+
12654+#undef r
12655+#define r(p,q,r,s) w0(q)
12656+#if defined(ONE_LR_TABLE)
12657+static const u_int32_t fl_tab[256] =
12658+ { f_table };
12659+#elif defined(FOUR_LR_TABLES)
12660+static const u_int32_t fl_tab[4][256] =
12661+{ { f_table },
12662+#undef r
12663+#define r(p,q,r,s) w1(q)
12664+ { f_table },
12665+#undef r
12666+#define r(p,q,r,s) w2(q)
12667+ { f_table },
12668+#undef r
12669+#define r(p,q,r,s) w3(q)
12670+ { f_table }
12671+};
12672+#endif
12673+
12674+#undef w
12675+#define w w0
12676+#if defined(ONE_LR_TABLE)
12677+static const u_int32_t il_tab[256] =
12678+ { li_table };
12679+#elif defined(FOUR_LR_TABLES)
12680+static const u_int32_t il_tab[4][256] =
12681+{ { li_table },
12682+#undef w
12683+#define w w1
12684+ { li_table },
12685+#undef w
12686+#define w w2
12687+ { li_table },
12688+#undef w
12689+#define w w3
12690+ { li_table }
12691+};
12692+#endif
12693+
12694+#endif
12695+
12696+#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
12697+
12698+#define m_table \
12699+ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
12700+ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
12701+ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
12702+ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
12703+ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
12704+ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
12705+ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
12706+ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
12707+ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
12708+ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
12709+ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
12710+ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
12711+ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
12712+ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
12713+ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
12714+ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
12715+ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
12716+ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
12717+ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
12718+ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
12719+ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
12720+ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
12721+ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
12722+ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
12723+ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
12724+ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
12725+ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
12726+ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
12727+ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
12728+ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
12729+ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
12730+ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
12731+ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
12732+ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
12733+ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
12734+ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
12735+ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
12736+ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
12737+ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
12738+ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
12739+ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
12740+ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
12741+ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
12742+ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
12743+ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
12744+ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
12745+ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
12746+ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
12747+ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
12748+ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
12749+ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
12750+ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
12751+ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
12752+ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
12753+ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
12754+ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
12755+ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
12756+ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
12757+ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
12758+ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
12759+ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
12760+ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
12761+ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
12762+ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
12763+
12764+#undef r
12765+#define r r0
12766+
12767+#if defined(ONE_IM_TABLE)
12768+static const u_int32_t im_tab[256] =
12769+ { m_table };
12770+#elif defined(FOUR_IM_TABLES)
12771+static const u_int32_t im_tab[4][256] =
12772+{ { m_table },
12773+#undef r
12774+#define r r1
12775+ { m_table },
12776+#undef r
12777+#define r r2
12778+ { m_table },
12779+#undef r
12780+#define r r3
12781+ { m_table }
12782+};
12783+#endif
12784+
12785+#endif
12786+
12787+#else
12788+
12789+static int tab_gen = 0;
12790+
12791+static unsigned char s_box[256]; // the S box
12792+static unsigned char inv_s_box[256]; // the inverse S box
12793+static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
12794+
12795+#if defined(ONE_TABLE)
12796+static u_int32_t ft_tab[256];
12797+static u_int32_t it_tab[256];
12798+#elif defined(FOUR_TABLES)
12799+static u_int32_t ft_tab[4][256];
12800+static u_int32_t it_tab[4][256];
12801+#endif
12802+
12803+#if defined(ONE_LR_TABLE)
12804+static u_int32_t fl_tab[256];
12805+static u_int32_t il_tab[256];
12806+#elif defined(FOUR_LR_TABLES)
12807+static u_int32_t fl_tab[4][256];
12808+static u_int32_t il_tab[4][256];
12809+#endif
12810+
12811+#if defined(ONE_IM_TABLE)
12812+static u_int32_t im_tab[256];
12813+#elif defined(FOUR_IM_TABLES)
12814+static u_int32_t im_tab[4][256];
12815+#endif
12816+
12817+// Generate the tables for the dynamic table option
12818+
12819+#if !defined(FF_TABLES)
12820+
12821+// It will generally be sensible to use tables to compute finite
12822+// field multiplies and inverses but where memory is scarse this
12823+// code might sometimes be better.
12824+
12825+// return 2 ^ (n - 1) where n is the bit number of the highest bit
12826+// set in x with x in the range 1 < x < 0x00000200. This form is
12827+// used so that locals within FFinv can be bytes rather than words
12828+
12829+static unsigned char hibit(const u_int32_t x)
12830+{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
12831+
12832+ r |= (r >> 2);
12833+ r |= (r >> 4);
12834+ return (r + 1) >> 1;
12835+}
12836+
12837+// return the inverse of the finite field element x
12838+
12839+static unsigned char FFinv(const unsigned char x)
12840+{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
12841+
12842+ if(x < 2) return x;
12843+
12844+ for(;;)
12845+ {
12846+ if(!n1) return v1;
12847+
12848+ while(n2 >= n1)
12849+ {
12850+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
12851+ }
12852+
12853+ if(!n2) return v2;
12854+
12855+ while(n1 >= n2)
12856+ {
12857+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
12858+ }
12859+ }
12860+}
12861+
12862+// define the finite field multiplies required for Rijndael
12863+
12864+#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
12865+#define FFmul03(x) ((x) ^ FFmul02(x))
12866+#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
12867+#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
12868+#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
12869+#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
12870+
12871+#else
12872+
12873+#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
12874+
12875+#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
12876+#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
12877+#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
12878+#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
12879+#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
12880+#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
12881+
12882+#endif
12883+
12884+// The forward and inverse affine transformations used in the S-box
12885+
12886+#define fwd_affine(x) \
12887+ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
12888+
12889+#define inv_affine(x) \
12890+ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
12891+
12892+static void gen_tabs(void)
12893+{ u_int32_t i, w;
12894+
12895+#if defined(FF_TABLES)
12896+
12897+ unsigned char pow[512], log[256];
12898+
12899+ // log and power tables for GF(2^8) finite field with
12900+ // 0x011b as modular polynomial - the simplest primitive
12901+ // root is 0x03, used here to generate the tables
12902+
12903+ i = 0; w = 1;
12904+ do
12905+ {
12906+ pow[i] = (unsigned char)w;
12907+ pow[i + 255] = (unsigned char)w;
12908+ log[w] = (unsigned char)i++;
12909+ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12910+ }
12911+ while (w != 1);
12912+
12913+#endif
12914+
12915+ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
12916+ {
12917+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
12918+ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12919+ }
12920+
12921+ for(i = 0; i < 256; ++i)
12922+ { unsigned char b;
12923+
12924+ s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
12925+
12926+ w = bytes2word(b, 0, 0, 0);
12927+#if defined(ONE_LR_TABLE)
12928+ fl_tab[i] = w;
12929+#elif defined(FOUR_LR_TABLES)
12930+ fl_tab[0][i] = w;
12931+ fl_tab[1][i] = upr(w,1);
12932+ fl_tab[2][i] = upr(w,2);
12933+ fl_tab[3][i] = upr(w,3);
12934+#endif
12935+ w = bytes2word(FFmul02(b), b, b, FFmul03(b));
12936+#if defined(ONE_TABLE)
12937+ ft_tab[i] = w;
12938+#elif defined(FOUR_TABLES)
12939+ ft_tab[0][i] = w;
12940+ ft_tab[1][i] = upr(w,1);
12941+ ft_tab[2][i] = upr(w,2);
12942+ ft_tab[3][i] = upr(w,3);
12943+#endif
12944+ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
12945+
12946+ w = bytes2word(b, 0, 0, 0);
12947+#if defined(ONE_LR_TABLE)
12948+ il_tab[i] = w;
12949+#elif defined(FOUR_LR_TABLES)
12950+ il_tab[0][i] = w;
12951+ il_tab[1][i] = upr(w,1);
12952+ il_tab[2][i] = upr(w,2);
12953+ il_tab[3][i] = upr(w,3);
12954+#endif
12955+ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
12956+#if defined(ONE_TABLE)
12957+ it_tab[i] = w;
12958+#elif defined(FOUR_TABLES)
12959+ it_tab[0][i] = w;
12960+ it_tab[1][i] = upr(w,1);
12961+ it_tab[2][i] = upr(w,2);
12962+ it_tab[3][i] = upr(w,3);
12963+#endif
12964+#if defined(ONE_IM_TABLE)
12965+ im_tab[b] = w;
12966+#elif defined(FOUR_IM_TABLES)
12967+ im_tab[0][b] = w;
12968+ im_tab[1][b] = upr(w,1);
12969+ im_tab[2][b] = upr(w,2);
12970+ im_tab[3][b] = upr(w,3);
12971+#endif
12972+
12973+ }
12974+}
12975+
12976+#endif
12977+
12978+#define no_table(x,box,vf,rf,c) bytes2word( \
12979+ box[bval(vf(x,0,c),rf(0,c))], \
12980+ box[bval(vf(x,1,c),rf(1,c))], \
12981+ box[bval(vf(x,2,c),rf(2,c))], \
12982+ box[bval(vf(x,3,c),rf(3,c))])
12983+
12984+#define one_table(x,op,tab,vf,rf,c) \
12985+ ( tab[bval(vf(x,0,c),rf(0,c))] \
12986+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
12987+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
12988+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
12989+
12990+#define four_tables(x,tab,vf,rf,c) \
12991+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
12992+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
12993+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
12994+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
12995+
12996+#define vf1(x,r,c) (x)
12997+#define rf1(r,c) (r)
12998+#define rf2(r,c) ((r-c)&3)
12999+
13000+#if defined(FOUR_LR_TABLES)
13001+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
13002+#elif defined(ONE_LR_TABLE)
13003+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
13004+#else
13005+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
13006+#endif
13007+
13008+#if defined(FOUR_IM_TABLES)
13009+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
13010+#elif defined(ONE_IM_TABLE)
13011+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
13012+#else
13013+#define inv_mcol(x) \
13014+ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
13015+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
13016+#endif
13017+
13018+// Subroutine to set the block size (if variable) in bytes, legal
13019+// values being 16, 24 and 32.
13020+
13021+#if defined(AES_BLOCK_SIZE)
13022+#define nc (AES_BLOCK_SIZE / 4)
13023+#else
13024+#define nc (cx->aes_Ncol)
13025+
13026+void aes_set_blk(aes_context *cx, int n_bytes)
13027+{
13028+#if !defined(FIXED_TABLES)
13029+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
13030+#endif
13031+
13032+ switch(n_bytes) {
13033+ case 32: /* bytes */
13034+ case 256: /* bits */
13035+ nc = 8;
13036+ break;
13037+ case 24: /* bytes */
13038+ case 192: /* bits */
13039+ nc = 6;
13040+ break;
13041+ case 16: /* bytes */
13042+ case 128: /* bits */
13043+ default:
13044+ nc = 4;
13045+ break;
13046+ }
13047+}
13048+
13049+#endif
13050+
13051+// Initialise the key schedule from the user supplied key. The key
13052+// length is now specified in bytes - 16, 24 or 32 as appropriate.
13053+// This corresponds to bit lengths of 128, 192 and 256 bits, and
13054+// to Nk values of 4, 6 and 8 respectively.
13055+
13056+#define mx(t,f) (*t++ = inv_mcol(*f),f++)
13057+#define cp(t,f) *t++ = *f++
13058+
13059+#if AES_BLOCK_SIZE == 16
13060+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
13061+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
13062+#elif AES_BLOCK_SIZE == 24
13063+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
13064+ cp(d,s); cp(d,s)
13065+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
13066+ mx(d,s); mx(d,s)
13067+#elif AES_BLOCK_SIZE == 32
13068+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
13069+ cp(d,s); cp(d,s); cp(d,s); cp(d,s)
13070+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
13071+ mx(d,s); mx(d,s); mx(d,s); mx(d,s)
13072+#else
13073+
13074+#define cpy(d,s) \
13075+switch(nc) \
13076+{ case 8: cp(d,s); cp(d,s); \
13077+ case 6: cp(d,s); cp(d,s); \
13078+ case 4: cp(d,s); cp(d,s); \
13079+ cp(d,s); cp(d,s); \
13080+}
13081+
13082+#define mix(d,s) \
13083+switch(nc) \
13084+{ case 8: mx(d,s); mx(d,s); \
13085+ case 6: mx(d,s); mx(d,s); \
13086+ case 4: mx(d,s); mx(d,s); \
13087+ mx(d,s); mx(d,s); \
13088+}
13089+
13090+#endif
13091+
13092+void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
13093+{ u_int32_t *kf, *kt, rci;
13094+
13095+#if !defined(FIXED_TABLES)
13096+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
13097+#endif
13098+
13099+ switch(n_bytes) {
13100+ case 32: /* bytes */
13101+ case 256: /* bits */
13102+ cx->aes_Nkey = 8;
13103+ break;
13104+ case 24: /* bytes */
13105+ case 192: /* bits */
13106+ cx->aes_Nkey = 6;
13107+ break;
13108+ case 16: /* bytes */
13109+ case 128: /* bits */
13110+ default:
13111+ cx->aes_Nkey = 4;
13112+ break;
13113+ }
13114+
13115+ cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
13116+
13117+ cx->aes_e_key[0] = const_word_in(in_key );
13118+ cx->aes_e_key[1] = const_word_in(in_key + 4);
13119+ cx->aes_e_key[2] = const_word_in(in_key + 8);
13120+ cx->aes_e_key[3] = const_word_in(in_key + 12);
13121+
13122+ kf = cx->aes_e_key;
13123+ kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
13124+ rci = 0;
13125+
13126+ switch(cx->aes_Nkey)
13127+ {
13128+ case 4: do
13129+ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
13130+ kf[5] = kf[1] ^ kf[4];
13131+ kf[6] = kf[2] ^ kf[5];
13132+ kf[7] = kf[3] ^ kf[6];
13133+ kf += 4;
13134+ }
13135+ while(kf < kt);
13136+ break;
13137+
13138+ case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
13139+ cx->aes_e_key[5] = const_word_in(in_key + 20);
13140+ do
13141+ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
13142+ kf[ 7] = kf[1] ^ kf[ 6];
13143+ kf[ 8] = kf[2] ^ kf[ 7];
13144+ kf[ 9] = kf[3] ^ kf[ 8];
13145+ kf[10] = kf[4] ^ kf[ 9];
13146+ kf[11] = kf[5] ^ kf[10];
13147+ kf += 6;
13148+ }
13149+ while(kf < kt);
13150+ break;
13151+
13152+ case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
13153+ cx->aes_e_key[5] = const_word_in(in_key + 20);
13154+ cx->aes_e_key[6] = const_word_in(in_key + 24);
13155+ cx->aes_e_key[7] = const_word_in(in_key + 28);
13156+ do
13157+ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
13158+ kf[ 9] = kf[1] ^ kf[ 8];
13159+ kf[10] = kf[2] ^ kf[ 9];
13160+ kf[11] = kf[3] ^ kf[10];
13161+ kf[12] = kf[4] ^ ls_box(kf[11],0);
13162+ kf[13] = kf[5] ^ kf[12];
13163+ kf[14] = kf[6] ^ kf[13];
13164+ kf[15] = kf[7] ^ kf[14];
13165+ kf += 8;
13166+ }
13167+ while (kf < kt);
13168+ break;
13169+ }
13170+
13171+ if(!f)
13172+ { u_int32_t i;
13173+
13174+ kt = cx->aes_d_key + nc * cx->aes_Nrnd;
13175+ kf = cx->aes_e_key;
13176+
13177+ cpy(kt, kf); kt -= 2 * nc;
13178+
13179+ for(i = 1; i < cx->aes_Nrnd; ++i)
13180+ {
13181+#if defined(ONE_TABLE) || defined(FOUR_TABLES)
13182+#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
13183+ u_int32_t f2, f4, f8, f9;
13184+#endif
13185+ mix(kt, kf);
13186+#else
13187+ cpy(kt, kf);
13188+#endif
13189+ kt -= 2 * nc;
13190+ }
13191+
13192+ cpy(kt, kf);
13193+ }
13194+}
13195+
13196+// y = output word, x = input word, r = row, c = column
13197+// for r = 0, 1, 2 and 3 = column accessed for row r
13198+
13199+#if defined(ARRAYS)
13200+#define s(x,c) x[c]
13201+#else
13202+#define s(x,c) x##c
13203+#endif
13204+
13205+// I am grateful to Frank Yellin for the following constructions
13206+// which, given the column (c) of the output state variable that
13207+// is being computed, return the input state variables which are
13208+// needed for each row (r) of the state
13209+
13210+// For the fixed block size options, compilers reduce these two
13211+// expressions to fixed variable references. For variable block
13212+// size code conditional clauses will sometimes be returned
13213+
13214+#define unused 77 // Sunset Strip
13215+
13216+#define fwd_var(x,r,c) \
13217+ ( r==0 ? \
13218+ ( c==0 ? s(x,0) \
13219+ : c==1 ? s(x,1) \
13220+ : c==2 ? s(x,2) \
13221+ : c==3 ? s(x,3) \
13222+ : c==4 ? s(x,4) \
13223+ : c==5 ? s(x,5) \
13224+ : c==6 ? s(x,6) \
13225+ : s(x,7)) \
13226+ : r==1 ? \
13227+ ( c==0 ? s(x,1) \
13228+ : c==1 ? s(x,2) \
13229+ : c==2 ? s(x,3) \
13230+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
13231+ : c==4 ? s(x,5) \
13232+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \
13233+ : c==6 ? s(x,7) \
13234+ : s(x,0)) \
13235+ : r==2 ? \
13236+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
13237+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
13238+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
13239+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
13240+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \
13241+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \
13242+ : c==6 ? s(x,1) \
13243+ : s(x,2)) \
13244+ : \
13245+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
13246+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
13247+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
13248+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
13249+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
13250+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
13251+ : c==6 ? s(x,2) \
13252+ : s(x,3)))
13253+
13254+#define inv_var(x,r,c) \
13255+ ( r==0 ? \
13256+ ( c==0 ? s(x,0) \
13257+ : c==1 ? s(x,1) \
13258+ : c==2 ? s(x,2) \
13259+ : c==3 ? s(x,3) \
13260+ : c==4 ? s(x,4) \
13261+ : c==5 ? s(x,5) \
13262+ : c==6 ? s(x,6) \
13263+ : s(x,7)) \
13264+ : r==1 ? \
13265+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
13266+ : c==1 ? s(x,0) \
13267+ : c==2 ? s(x,1) \
13268+ : c==3 ? s(x,2) \
13269+ : c==4 ? s(x,3) \
13270+ : c==5 ? s(x,4) \
13271+ : c==6 ? s(x,5) \
13272+ : s(x,6)) \
13273+ : r==2 ? \
13274+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
13275+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
13276+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
13277+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
13278+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
13279+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
13280+ : c==6 ? s(x,3) \
13281+ : s(x,4)) \
13282+ : \
13283+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
13284+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
13285+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
13286+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \
13287+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
13288+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
13289+ : c==6 ? s(x,2) \
13290+ : s(x,3)))
13291+
13292+#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
13293+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
13294+
13295+#if defined(FOUR_TABLES)
13296+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
13297+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
13298+#elif defined(ONE_TABLE)
13299+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
13300+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
13301+#else
13302+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
13303+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
13304+#endif
13305+
13306+#if defined(FOUR_LR_TABLES)
13307+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
13308+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
13309+#elif defined(ONE_LR_TABLE)
13310+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
13311+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
13312+#else
13313+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
13314+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
13315+#endif
13316+
13317+#if AES_BLOCK_SIZE == 16
13318+
13319+#if defined(ARRAYS)
13320+#define locals(y,x) x[4],y[4]
13321+#else
13322+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
13323+// the following defines prevent the compiler requiring the declaration
13324+// of generated but unused variables in the fwd_var and inv_var macros
13325+#define b04 unused
13326+#define b05 unused
13327+#define b06 unused
13328+#define b07 unused
13329+#define b14 unused
13330+#define b15 unused
13331+#define b16 unused
13332+#define b17 unused
13333+#endif
13334+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13335+ s(y,2) = s(x,2); s(y,3) = s(x,3);
13336+#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)
13337+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
13338+#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)
13339+
13340+#elif AES_BLOCK_SIZE == 24
13341+
13342+#if defined(ARRAYS)
13343+#define locals(y,x) x[6],y[6]
13344+#else
13345+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
13346+ y##0,y##1,y##2,y##3,y##4,y##5
13347+#define b06 unused
13348+#define b07 unused
13349+#define b16 unused
13350+#define b17 unused
13351+#endif
13352+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13353+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
13354+ s(y,4) = s(x,4); s(y,5) = s(x,5);
13355+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
13356+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
13357+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
13358+ so(y,x,3); so(y,x,4); so(y,x,5)
13359+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
13360+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
13361+#else
13362+
13363+#if defined(ARRAYS)
13364+#define locals(y,x) x[8],y[8]
13365+#else
13366+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
13367+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
13368+#endif
13369+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13370+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
13371+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
13372+ s(y,6) = s(x,6); s(y,7) = s(x,7);
13373+
13374+#if AES_BLOCK_SIZE == 32
13375+
13376+#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); \
13377+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
13378+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
13379+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
13380+#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); \
13381+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
13382+#else
13383+
13384+#define state_in(y,x,k) \
13385+switch(nc) \
13386+{ case 8: si(y,x,k,7); si(y,x,k,6); \
13387+ case 6: si(y,x,k,5); si(y,x,k,4); \
13388+ case 4: si(y,x,k,3); si(y,x,k,2); \
13389+ si(y,x,k,1); si(y,x,k,0); \
13390+}
13391+
13392+#define state_out(y,x) \
13393+switch(nc) \
13394+{ case 8: so(y,x,7); so(y,x,6); \
13395+ case 6: so(y,x,5); so(y,x,4); \
13396+ case 4: so(y,x,3); so(y,x,2); \
13397+ so(y,x,1); so(y,x,0); \
13398+}
13399+
13400+#if defined(FAST_VARIABLE)
13401+
13402+#define round(rm,y,x,k) \
13403+switch(nc) \
13404+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13405+ rm(y,x,k,5); rm(y,x,k,4); \
13406+ rm(y,x,k,3); rm(y,x,k,2); \
13407+ rm(y,x,k,1); rm(y,x,k,0); \
13408+ break; \
13409+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
13410+ rm(y,x,k,3); rm(y,x,k,2); \
13411+ rm(y,x,k,1); rm(y,x,k,0); \
13412+ break; \
13413+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
13414+ rm(y,x,k,1); rm(y,x,k,0); \
13415+ break; \
13416+}
13417+#else
13418+
13419+#define round(rm,y,x,k) \
13420+switch(nc) \
13421+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13422+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
13423+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
13424+ rm(y,x,k,1); rm(y,x,k,0); \
13425+}
13426+
13427+#endif
13428+
13429+#endif
13430+#endif
13431+
13432+void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13433+{ u_int32_t locals(b0, b1);
13434+ const u_int32_t *kp = cx->aes_e_key;
13435+
13436+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13437+ u_int32_t f2;
13438+#endif
13439+
13440+ state_in(b0, in_blk, kp); kp += nc;
13441+
13442+#if defined(UNROLL)
13443+
13444+ switch(cx->aes_Nrnd)
13445+ {
13446+ case 14: round(fwd_rnd, b1, b0, kp );
13447+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13448+ case 12: round(fwd_rnd, b1, b0, kp );
13449+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13450+ case 10: round(fwd_rnd, b1, b0, kp );
13451+ round(fwd_rnd, b0, b1, kp + nc);
13452+ round(fwd_rnd, b1, b0, kp + 2 * nc);
13453+ round(fwd_rnd, b0, b1, kp + 3 * nc);
13454+ round(fwd_rnd, b1, b0, kp + 4 * nc);
13455+ round(fwd_rnd, b0, b1, kp + 5 * nc);
13456+ round(fwd_rnd, b1, b0, kp + 6 * nc);
13457+ round(fwd_rnd, b0, b1, kp + 7 * nc);
13458+ round(fwd_rnd, b1, b0, kp + 8 * nc);
13459+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
13460+ }
13461+
13462+#elif defined(PARTIAL_UNROLL)
13463+ { u_int32_t rnd;
13464+
13465+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13466+ {
13467+ round(fwd_rnd, b1, b0, kp);
13468+ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
13469+ }
13470+
13471+ round(fwd_rnd, b1, b0, kp);
13472+ round(fwd_lrnd, b0, b1, kp + nc);
13473+ }
13474+#else
13475+ { u_int32_t rnd;
13476+
13477+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13478+ {
13479+ round(fwd_rnd, b1, b0, kp);
13480+ l_copy(b0, b1); kp += nc;
13481+ }
13482+
13483+ round(fwd_lrnd, b0, b1, kp);
13484+ }
13485+#endif
13486+
13487+ state_out(out_blk, b0);
13488+}
13489+
13490+void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13491+{ u_int32_t locals(b0, b1);
13492+ const u_int32_t *kp = cx->aes_d_key;
13493+
13494+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13495+ u_int32_t f2, f4, f8, f9;
13496+#endif
13497+
13498+ state_in(b0, in_blk, kp); kp += nc;
13499+
13500+#if defined(UNROLL)
13501+
13502+ switch(cx->aes_Nrnd)
13503+ {
13504+ case 14: round(inv_rnd, b1, b0, kp );
13505+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13506+ case 12: round(inv_rnd, b1, b0, kp );
13507+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13508+ case 10: round(inv_rnd, b1, b0, kp );
13509+ round(inv_rnd, b0, b1, kp + nc);
13510+ round(inv_rnd, b1, b0, kp + 2 * nc);
13511+ round(inv_rnd, b0, b1, kp + 3 * nc);
13512+ round(inv_rnd, b1, b0, kp + 4 * nc);
13513+ round(inv_rnd, b0, b1, kp + 5 * nc);
13514+ round(inv_rnd, b1, b0, kp + 6 * nc);
13515+ round(inv_rnd, b0, b1, kp + 7 * nc);
13516+ round(inv_rnd, b1, b0, kp + 8 * nc);
13517+ round(inv_lrnd, b0, b1, kp + 9 * nc);
13518+ }
13519+
13520+#elif defined(PARTIAL_UNROLL)
13521+ { u_int32_t rnd;
13522+
13523+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13524+ {
13525+ round(inv_rnd, b1, b0, kp);
13526+ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
13527+ }
13528+
13529+ round(inv_rnd, b1, b0, kp);
13530+ round(inv_lrnd, b0, b1, kp + nc);
13531+ }
13532+#else
13533+ { u_int32_t rnd;
13534+
13535+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13536+ {
13537+ round(inv_rnd, b1, b0, kp);
13538+ l_copy(b0, b1); kp += nc;
13539+ }
13540+
13541+ round(inv_lrnd, b0, b1, kp);
13542+ }
13543+#endif
13544+
13545+ state_out(out_blk, b0);
13546+}
13547--- /dev/null Tue Mar 11 13:02:56 2003
13548+++ linux/net/ipsec/aes/aes_cbc.c Mon Feb 9 13:51:03 2004
13549@@ -0,0 +1,46 @@
13550+/*
13551+// I retain copyright in this code but I encourage its free use provided
13552+// that I don't carry any responsibility for the results. I am especially
13553+// happy to see it used in free and open source software. If you do use
13554+// it I would appreciate an acknowledgement of its origin in the code or
13555+// the product that results and I would also appreciate knowing a little
13556+// about the use to which it is being put. I am grateful to Frank Yellin
13557+// for some ideas that are used in this implementation.
13558+//
13559+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
13560+//
13561+// This is an implementation of the AES encryption algorithm (Rijndael)
13562+// designed by Joan Daemen and Vincent Rijmen. This version is designed
13563+// to provide both fixed and dynamic block and key lengths and can also
13564+// run with either big or little endian internal byte order (see aes.h).
13565+// It inputs block and key lengths in bytes with the legal values being
13566+// 16, 24 and 32.
13567+*
13568+*/
13569+
13570+#ifdef __KERNEL__
13571+#include <linux/types.h>
13572+#else
13573+#include <sys/types.h>
13574+#endif
13575+#include "crypto/aes_cbc.h"
13576+#include "crypto/cbc_generic.h"
13577+
13578+/* returns bool success */
13579+int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
13580+ aes_set_key(aes_ctx, key, keysize, 0);
13581+ return 1;
13582+}
13583+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
13584+
13585+
13586+/*
13587+ * $Log: aes_cbc.c,v $
13588+ * Revision 1.2 2004-07-10 07:48:40 mcr
13589+ * Moved from linux/crypto/ciphers/aes/aes_cbc.c,v
13590+ *
13591+ * Revision 1.1 2004/04/06 02:48:12 mcr
13592+ * pullup of AES cipher from alg-branch.
13593+ *
13594+ *
13595+ */
13596--- /dev/null Tue Mar 11 13:02:56 2003
13597+++ linux/net/ipsec/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004
13598@@ -0,0 +1,67 @@
13599+#ifdef __KERNEL__
13600+#include <linux/types.h>
13601+#include <linux/kernel.h>
13602+#define DEBUG(x)
13603+#else
13604+#include <stdio.h>
13605+#include <sys/types.h>
13606+#define DEBUG(x) x
13607+#endif
13608+
13609+#include "crypto/aes.h"
13610+#include "crypto/aes_xcbc_mac.h"
13611+
13612+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
13613+{
13614+ int ret=1;
13615+ aes_block kn[3] = {
13616+ { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
13617+ { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
13618+ { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
13619+ };
13620+ aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
13621+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
13622+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
13623+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
13624+ aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
13625+ return ret;
13626+}
13627+static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
13628+ int pos=0;
13629+ for (pos=1; pos <= 16; pos++, in++, out++) {
13630+ if (pos <= len)
13631+ *out ^= *in;
13632+ if (pos > len) {
13633+ DEBUG(printf("put 0x80 at pos=%d\n", pos));
13634+ *out ^= 0x80;
13635+ break;
13636+ }
13637+ }
13638+}
13639+static void xor_block(aes_block res, const aes_block op) {
13640+ res[0] ^= op[0];
13641+ res[1] ^= op[1];
13642+ res[2] ^= op[2];
13643+ res[3] ^= op[3];
13644+}
13645+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
13646+ int ret=ilen;
13647+ u_int32_t out[4] = { 0, 0, 0, 0 };
13648+ for (; ilen > 16 ; ilen-=16) {
13649+ xor_block(out, (const u_int32_t*) &in[0]);
13650+ aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
13651+ in+=16;
13652+ }
13653+ do_pad_xor((u_int8_t *)&out, in, ilen);
13654+ if (ilen==16) {
13655+ DEBUG(printf("using k3\n"));
13656+ xor_block(out, ctxm->k3);
13657+ }
13658+ else
13659+ {
13660+ DEBUG(printf("using k2\n"));
13661+ xor_block(out, ctxm->k2);
13662+ }
13663+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
13664+ return ret;
13665+}
13666--- /dev/null Tue Mar 11 13:02:56 2003
13667+++ linux/net/ipsec/aes/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
13668@@ -0,0 +1,296 @@
13669+/*
13670+ * ipsec_alg AES cipher stubs
13671+ *
13672+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
13673+ *
13674+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13675+ *
13676+ * This program is free software; you can redistribute it and/or modify it
13677+ * under the terms of the GNU General Public License as published by the
13678+ * Free Software Foundation; either version 2 of the License, or (at your
13679+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13680+ *
13681+ * This program is distributed in the hope that it will be useful, but
13682+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13683+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13684+ * for more details.
13685+ *
13686+ * Fixes by:
13687+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
13688+ * Fixes list:
13689+ * PK: make XCBC comply with latest draft (keylength)
13690+ *
13691+ */
13692+#ifndef AUTOCONF_INCLUDED
13693+#include <linux/config.h>
13694+#endif
13695+#include <linux/version.h>
13696+
13697+/*
13698+ * special case: ipsec core modular with this static algo inside:
13699+ * must avoid MODULE magic for this file
13700+ */
13701+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_AES)
13702+#undef MODULE
13703+#endif
13704+
13705+#include <linux/module.h>
13706+#include <linux/init.h>
13707+
13708+#include <linux/kernel.h> /* printk() */
13709+#include <linux/errno.h> /* error codes */
13710+#include <linux/types.h> /* size_t */
13711+#include <linux/string.h>
13712+
13713+/* Check if __exit is defined, if not null it */
13714+#ifndef __exit
13715+#define __exit
13716+#endif
13717+
13718+/* Low freeswan header coupling */
13719+#include "openswan/ipsec_alg.h"
13720+#include "crypto/aes_cbc.h"
13721+
13722+#define CONFIG_KLIPS_ENC_AES_MAC 1
13723+
13724+#define AES_CONTEXT_T aes_context
13725+static int debug_aes=0;
13726+static int test_aes=0;
13727+static int excl_aes=0;
13728+static int keyminbits=0;
13729+static int keymaxbits=0;
13730+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13731+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
13732+#ifdef module_param
13733+module_param(debug_aes,int,0600)
13734+module_param(test_aes,int,0600)
13735+module_param(excl_aes,int,0600)
13736+module_param(keyminbits,int,0600)
13737+module_param(keymaxbits,int,0600)
13738+#else
13739+MODULE_PARM(debug_aes, "i");
13740+MODULE_PARM(test_aes, "i");
13741+MODULE_PARM(excl_aes, "i");
13742+MODULE_PARM(keyminbits, "i");
13743+MODULE_PARM(keymaxbits, "i");
13744+#endif
13745+#endif
13746+
13747+#if CONFIG_KLIPS_ENC_AES_MAC
13748+#include "crypto/aes_xcbc_mac.h"
13749+
13750+/*
13751+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
13752+ * We use 9 for non-modular algorithm and none for modular, thus
13753+ * forcing user to specify one on module load. -kravietz
13754+ */
13755+#ifdef MODULE
13756+static int auth_id=0;
13757+#else
13758+static int auth_id=9;
13759+#endif
13760+#ifdef module_param
13761+module_param(auth_id, int, 0600);
13762+#else
13763+MODULE_PARM(auth_id, "i");
13764+#endif
13765+#endif
13766+
13767+#define ESP_AES 12 /* truely _constant_ :) */
13768+
13769+/* 128, 192 or 256 */
13770+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
13771+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
13772+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
13773+
13774+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
13775+ * -kravietz
13776+ */
13777+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
13778+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
13779+
13780+static int _aes_set_key(struct ipsec_alg_enc *alg,
13781+ __u8 * key_e, const __u8 * key,
13782+ size_t keysize)
13783+{
13784+ int ret;
13785+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13786+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
13787+ if (debug_aes > 0)
13788+ printk(KERN_DEBUG "klips_debug:_aes_set_key:"
13789+ "ret=%d key_e=%p key=%p keysize=%ld\n",
13790+ ret, key_e, key, (unsigned long int) keysize);
13791+ return ret;
13792+}
13793+
13794+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e,
13795+ __u8 * in, int ilen, const __u8 * iv,
13796+ int encrypt)
13797+{
13798+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13799+ if (debug_aes > 0)
13800+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
13801+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
13802+ key_e, in, ilen, iv, encrypt);
13803+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
13804+}
13805+#if CONFIG_KLIPS_ENC_AES_MAC
13806+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
13807+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
13808+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
13809+}
13810+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
13811+ int ret;
13812+ char hash_buf[16];
13813+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
13814+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
13815+ memcpy(hash, hash_buf, hashlen);
13816+ return ret;
13817+}
13818+static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
13819+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13820+ ixt_refcnt: ATOMIC_INIT(0),
13821+ ixt_name: "aes_mac",
13822+ ixt_blocksize: ESP_AES_MAC_BLK_LEN,
13823+ ixt_support: {
13824+ ias_exttype: IPSEC_ALG_TYPE_AUTH,
13825+ ias_id: 0,
13826+ ias_keyminbits: ESP_AES_MAC_KEY_SZ*8,
13827+ ias_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
13828+ },
13829+ },
13830+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13831+ ixt_module: THIS_MODULE,
13832+#endif
13833+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
13834+ ixt_a_ctx_size: sizeof(aes_context_mac),
13835+ ixt_a_hmac_set_key: _aes_mac_set_key,
13836+ ixt_a_hmac_hash:_aes_mac_hash,
13837+};
13838+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13839+static struct ipsec_alg_enc ipsec_alg_AES = {
13840+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13841+ ixt_refcnt: ATOMIC_INIT(0),
13842+ ixt_name: "aes",
13843+ ixt_blocksize: ESP_AES_CBC_BLK_LEN,
13844+ ixt_support: {
13845+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
13846+ ias_id: ESP_AES,
13847+ ias_keyminbits: ESP_AES_KEY_SZ_MIN*8,
13848+ ias_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
13849+ },
13850+ },
13851+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13852+ ixt_module: THIS_MODULE,
13853+#endif
13854+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
13855+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
13856+ ixt_e_set_key: _aes_set_key,
13857+ ixt_e_cbc_encrypt:_aes_cbc_encrypt,
13858+};
13859+
13860+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13861+IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
13862+#else
13863+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
13864+#endif
13865+{
13866+ int ret, test_ret;
13867+
13868+ if (keyminbits)
13869+ ipsec_alg_AES.ixt_common.ixt_support.ias_keyminbits=keyminbits;
13870+ if (keymaxbits) {
13871+ ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits=keymaxbits;
13872+ if (keymaxbits*8>ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits)
13873+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
13874+ }
13875+ if (excl_aes) ipsec_alg_AES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
13876+ ret=register_ipsec_alg_enc(&ipsec_alg_AES);
13877+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13878+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype,
13879+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13880+ ipsec_alg_AES.ixt_common.ixt_name,
13881+ ret);
13882+ if (ret==0 && test_aes) {
13883+ test_ret=ipsec_alg_test(
13884+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13885+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13886+ test_aes);
13887+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13888+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13889+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13890+ test_ret);
13891+ }
13892+#if CONFIG_KLIPS_ENC_AES_MAC
13893+ if (auth_id!=0){
13894+ int ret;
13895+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id=auth_id;
13896+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13897+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13898+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13899+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13900+ ipsec_alg_AES_MAC.ixt_common.ixt_name,
13901+ ret);
13902+ if (ret==0 && test_aes) {
13903+ test_ret=ipsec_alg_test(
13904+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13905+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13906+ test_aes);
13907+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13908+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13909+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13910+ test_ret);
13911+ }
13912+ } else {
13913+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
13914+ }
13915+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13916+ return ret;
13917+}
13918+
13919+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13920+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
13921+#else
13922+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
13923+#endif
13924+{
13925+#if CONFIG_KLIPS_ENC_AES_MAC
13926+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13927+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13928+ unregister_ipsec_alg_enc(&ipsec_alg_AES);
13929+ return;
13930+}
13931+#ifdef MODULE_LICENSE
13932+MODULE_LICENSE("GPL");
13933+#endif
13934+
13935+#if 0 /* +NOT_YET */
13936+#ifndef MODULE
13937+/*
13938+ * This is intended for static module setups, currently
13939+ * doesn't work for modular ipsec.o with static algos inside
13940+ */
13941+static int setup_keybits(const char *str)
13942+{
13943+ unsigned aux;
13944+ char *end;
13945+
13946+ aux = simple_strtoul(str,&end,0);
13947+ if (aux != 128 && aux != 192 && aux != 256)
13948+ return 0;
13949+ keyminbits = aux;
13950+
13951+ if (*end == 0 || *end != ',')
13952+ return 1;
13953+ str=end+1;
13954+ aux = simple_strtoul(str, NULL, 0);
13955+ if (aux != 128 && aux != 192 && aux != 256)
13956+ return 0;
13957+ if (aux >= keyminbits)
13958+ keymaxbits = aux;
13959+ return 1;
13960+}
13961+__setup("ipsec_aes_keybits=", setup_keybits);
13962+#endif
13963+#endif
13964+
13965--- /dev/null Tue Mar 11 13:02:56 2003
13966+++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004
13967@@ -0,0 +1,3 @@
13968+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13969+ tristate ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES
13970+fi
13971--- /dev/null Tue Mar 11 13:02:56 2003
13972+++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004
13973@@ -0,0 +1,6 @@
13974+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13975+ dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
13976+ if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
13977+ bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
13978+ fi
13979+fi
13980--- /dev/null Tue Mar 11 13:02:56 2003
13981+++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004
13982@@ -0,0 +1,3 @@
13983+#Placeholder
13984+source net/ipsec/alg/Config.alg_aes.in
13985+source net/ipsec/alg/Config.alg_cryptoapi.in
13986--- /dev/null Tue Mar 11 13:02:56 2003
13987+++ linux/net/ipsec/alg/Makefile Mon Feb 9 13:51:03 2004
13988@@ -0,0 +1,112 @@
13989+# Makefile,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13990+ifeq ($(strip $(KLIPSMODULE)),)
13991+FREESWANSRCDIR=.
13992+else
13993+FREESWANSRCDIR=../../../..
13994+endif
13995+ifeq ($(strip $(KLIPS_TOP)),)
13996+KLIPS_TOP=../../..
13997+override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include
13998+endif
13999+
14000+ifeq ($(CONFIG_IPSEC_DEBUG),y)
14001+override EXTRA_CFLAGS += -g
14002+endif
14003+
14004+# LIBCRYPTO normally comes as an argument from "parent" Makefile
14005+# (this applies both to FS' "make module" and eg. Linux' "make modules"
14006+# But make dep doest follow same evaluations, so we need this default:
14007+LIBCRYPTO=$(TOPDIR)/lib/libcrypto
14008+
14009+override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include
14010+override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes
14011+
14012+MOD_LIST_NAME := NET_MISC_MODULES
14013+
14014+#O_TARGET := static_init.o
14015+
14016+subdir- :=
14017+subdir-n :=
14018+subdir-y :=
14019+subdir-m :=
14020+
14021+obj-y := static_init.o
14022+
14023+ARCH_ASM-y :=
14024+ARCH_ASM-$(CONFIG_M586) := i586
14025+ARCH_ASM-$(CONFIG_M586TSC) := i586
14026+ARCH_ASM-$(CONFIG_M586MMX) := i586
14027+ARCH_ASM-$(CONFIG_MK6) := i586
14028+ARCH_ASM-$(CONFIG_M686) := i686
14029+ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686
14030+ARCH_ASM-$(CONFIG_MPENTIUM4) := i686
14031+ARCH_ASM-$(CONFIG_MK7) := i686
14032+ARCH_ASM-$(CONFIG_MCRUSOE) := i586
14033+ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586
14034+ARCH_ASM-$(CONFIG_MWINCHIP2) := i586
14035+ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586
14036+ARCH_ASM-$(CONFIG_USERMODE) := i586
14037+
14038+ARCH_ASM :=$(ARCH_ASM-y)
14039+ifdef NO_ASM
14040+ARCH_ASM :=
14041+endif
14042+
14043+# The algorithm makefiles may put dependences, short-circuit them
14044+null:
14045+
14046+makefiles=$(filter-out %.preipsec, $(wildcard Makefile.alg_*))
14047+ifneq ($(makefiles),)
14048+#include Makefile.alg_aes
14049+#include Makefile.alg_aes-opt
14050+include $(makefiles)
14051+endif
14052+
14053+# These rules translate from new to old makefile rules
14054+# Translate to Rules.make lists.
14055+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m))
14056+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs))
14057+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m))
14058+O_OBJS := $(obj-y)
14059+M_OBJS := $(obj-m)
14060+MIX_OBJS := $(filter $(export-objs), $(active-objs))
14061+#OX_OBJS := $(export-objs)
14062+SUB_DIRS := $(subdir-y)
14063+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
14064+MOD_SUB_DIRS := $(subdir-m)
14065+
14066+
14067+static_init_mod.o: $(obj-y)
14068+ rm -f $@
14069+ $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@
14070+
14071+perlasm: ../../../crypto/ciphers/des/asm/perlasm
14072+ ln -sf $? $@
14073+
14074+$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
14075+$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
14076+
14077+
14078+all_alg_modules: perlasm $(ALG_MODULES)
14079+ @echo "ALG_MODULES=$(ALG_MODULES)"
14080+
14081+
14082+#
14083+# Construct alg. init. function: call ipsec_ALGO_init() for every static algo
14084+# Needed when there are static algos (with static or modular ipsec.o)
14085+#
14086+static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh
14087+ @echo "Re-creating $@"
14088+ $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@
14089+
14090+clean:
14091+ @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0
14092+ @find . -type l -exec rm -f {} \;
14093+ -rm -f perlasm
14094+ -rm -rf $(ALG_SUBDIRS)
14095+ -rm -f *.o static_init.c
14096+
14097+ifdef TOPDIR
14098+include $(TOPDIR)/Rules.make
14099+endif
14100+
14101--- /dev/null Tue Mar 11 13:02:56 2003
14102+++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004
14103@@ -0,0 +1,18 @@
14104+MOD_AES := ipsec_aes.o
14105+
14106+ALG_MODULES += $(MOD_AES)
14107+ALG_SUBDIRS += libaes
14108+
14109+obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
14110+static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
14111+alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
14112+
14113+AES_OBJS := ipsec_alg_aes.o $(LIBCRYPTO)/libaes/libaes.a
14114+
14115+
14116+$(MOD_AES): $(AES_OBJS)
14117+ $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
14118+
14119+$(LIBCRYPTO)/libaes/libaes.a:
14120+ $(MAKE) -C $(LIBCRYPTO)/libaes CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a
14121+
14122--- /dev/null Tue Mar 11 13:02:56 2003
14123+++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004
14124@@ -0,0 +1,14 @@
14125+MOD_CRYPTOAPI := ipsec_cryptoapi.o
14126+
14127+ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
14128+ALG_MODULES += $(MOD_CRYPTOAPI)
14129+obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
14130+static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
14131+alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
14132+else
14133+$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
14134+endif
14135+
14136+CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
14137+$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
14138+ $(LD) -r $(CRYPTOAPI_OBJS) -o $@
14139--- /dev/null Tue Mar 11 13:02:56 2003
14140+++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
14141@@ -0,0 +1,442 @@
14142+/*
14143+ * ipsec_alg to linux cryptoapi GLUE
14144+ *
14145+ * Authors: CODE.ar TEAM
14146+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
14147+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
14148+ * Luciano Ruete <docemeses@softhome.net>
14149+ *
14150+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
14151+ *
14152+ * This program is free software; you can redistribute it and/or modify it
14153+ * under the terms of the GNU General Public License as published by the
14154+ * Free Software Foundation; either version 2 of the License, or (at your
14155+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
14156+ *
14157+ * This program is distributed in the hope that it will be useful, but
14158+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14159+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14160+ * for more details.
14161+ *
14162+ * Example usage:
14163+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
14164+ * modprobe ipsec_cryptoapi
14165+ * modprobe ipsec_cryptoapi test=1
14166+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
14167+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
14168+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
14169+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
14170+ */
14171+#ifndef AUTOCONF_INCLUDED
14172+#include <linux/config.h>
14173+#endif
14174+#include <linux/version.h>
14175+
14176+/*
14177+ * special case: ipsec core modular with this static algo inside:
14178+ * must avoid MODULE magic for this file
14179+ */
14180+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
14181+#undef MODULE
14182+#endif
14183+
14184+#include <linux/module.h>
14185+#include <linux/init.h>
14186+
14187+#include <linux/kernel.h> /* printk() */
14188+#include <linux/errno.h> /* error codes */
14189+#include <linux/types.h> /* size_t */
14190+#include <linux/string.h>
14191+
14192+/* Check if __exit is defined, if not null it */
14193+#ifndef __exit
14194+#define __exit
14195+#endif
14196+
14197+/* warn the innocent */
14198+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
14199+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
14200+#define NO_CRYPTOAPI_SUPPORT
14201+#endif
14202+/* Low freeswan header coupling */
14203+#include "openswan/ipsec_alg.h"
14204+
14205+#include <linux/crypto.h>
14206+#ifdef CRYPTO_API_VERSION_CODE
14207+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
14208+#define NO_CRYPTOAPI_SUPPORT
14209+#endif
14210+
14211+#ifdef NO_CRYPTOAPI_SUPPORT
14212+#warning "Building an unusable module :P"
14213+/* Catch old CryptoAPI by not allowing module to load */
14214+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
14215+{
14216+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
14217+ return -EINVAL;
14218+}
14219+#else
14220+#include <asm/scatterlist.h>
14221+#include <asm/pgtable.h>
14222+#include <linux/mm.h>
14223+
14224+#define CIPHERNAME_AES "aes"
14225+#define CIPHERNAME_3DES "des3_ede"
14226+#define CIPHERNAME_BLOWFISH "blowfish"
14227+#define CIPHERNAME_CAST "cast5"
14228+#define CIPHERNAME_SERPENT "serpent"
14229+#define CIPHERNAME_TWOFISH "twofish"
14230+
14231+#define ESP_3DES 3
14232+#define ESP_AES 12
14233+#define ESP_BLOWFISH 7 /* truely _constant_ :) */
14234+#define ESP_CAST 6 /* quite constant :) */
14235+#define ESP_SERPENT 252 /* from ipsec drafts */
14236+#define ESP_TWOFISH 253 /* from ipsec drafts */
14237+
14238+#define AH_MD5 2
14239+#define AH_SHA 3
14240+#define DIGESTNAME_MD5 "md5"
14241+#define DIGESTNAME_SHA1 "sha1"
14242+
14243+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
14244+static int debug=0;
14245+static int test=0;
14246+static int excl=0;
14247+static int noauto = 0;
14248+
14249+static int des_ede3[] = {-1, -1};
14250+static int aes[] = {-1, -1};
14251+static int blowfish[] = {-1, -1};
14252+static int cast[] = {-1, -1};
14253+static int serpent[] = {-1, -1};
14254+static int twofish[] = {-1, -1};
14255+
14256+#ifdef module_param
14257+module_param(debug,int,0600);
14258+module_param(test,int,0600);
14259+module_param(ebug,int,0600);
14260+
14261+module_param(noauto,int,0600);
14262+module_param(ebug,int,0600);
14263+
14264+module_param_array(des_ede3,int,NULL,0);
14265+module_param(aes,int,NULL,0);
14266+module_param(blowfish,int,NULL,0);
14267+module_param(cast,int,NULL,0);
14268+module_param(serpent,int,NULL,0);
14269+module_param(twofish,int,NULL,0);
14270+#else
14271+MODULE_PARM(debug, "i");
14272+MODULE_PARM(test, "i");
14273+MODULE_PARM(excl, "i");
14274+
14275+MODULE_PARM(noauto,"i");
14276+
14277+MODULE_PARM(des_ede3,"1-2i");
14278+MODULE_PARM(aes,"1-2i");
14279+MODULE_PARM(blowfish,"1-2i");
14280+MODULE_PARM(cast,"1-2i");
14281+MODULE_PARM(serpent,"1-2i");
14282+MODULE_PARM(twofish,"1-2i");
14283+#endif
14284+
14285+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
14286+
14287+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
14288+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
14289+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
14290+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
14291+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
14292+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
14293+
14294+struct ipsec_alg_capi_cipher {
14295+ const char *ciphername; /* cryptoapi's ciphername */
14296+ unsigned blocksize;
14297+ unsigned short minbits;
14298+ unsigned short maxbits;
14299+ int *parm; /* lkm param for this cipher */
14300+ struct ipsec_alg_enc alg; /* note it's not a pointer */
14301+};
14302+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
14303+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
14304+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
14305+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
14306+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
14307+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
14308+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
14309+ { NULL, 0, 0, 0, NULL, {} }
14310+};
14311+#ifdef NOT_YET
14312+struct ipsec_alg_capi_digest {
14313+ const char *digestname; /* cryptoapi's digestname */
14314+ struct digest_implementation *di;
14315+ struct ipsec_alg_auth alg; /* note it's not a pointer */
14316+};
14317+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
14318+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
14319+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
14320+ { NULL, NULL, {} }
14321+};
14322+#endif
14323+/*
14324+ * "generic" linux cryptoapi setup_cipher() function
14325+ */
14326+int setup_cipher(const char *ciphername)
14327+{
14328+ return crypto_alg_available(ciphername, 0);
14329+}
14330+
14331+/*
14332+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
14333+ * register_ipsec_alg for cointaned ipsec_alg object
14334+ */
14335+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
14336+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
14337+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
14338+
14339+static int
14340+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
14341+{
14342+ int ret;
14343+ cptr->alg.ixt_version = IPSEC_ALG_VERSION;
14344+ cptr->alg.ixt_module = THIS_MODULE;
14345+ atomic_set (& cptr->alg.ixt_refcnt, 0);
14346+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
14347+
14348+ cptr->alg.ixt_blocksize=cptr->blocksize;
14349+ cptr->alg.ixt_keyminbits=cptr->minbits;
14350+ cptr->alg.ixt_keymaxbits=cptr->maxbits;
14351+ cptr->alg.ixt_state = 0;
14352+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
14353+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
14354+ cptr->alg.ixt_e_ctx_size = 0;
14355+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
14356+ cptr->alg.ixt_e_new_key = _capi_new_key;
14357+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
14358+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
14359+ cptr->alg.ixt_data = cptr;
14360+
14361+ ret=register_ipsec_alg_enc(&cptr->alg);
14362+ printk("setup_ipsec_alg_capi_cipher(): "
14363+ "alg_type=%d alg_id=%d name=%s "
14364+ "keyminbits=%d keymaxbits=%d, ret=%d\n",
14365+ cptr->alg.ixt_alg_type,
14366+ cptr->alg.ixt_alg_id,
14367+ cptr->alg.ixt_name,
14368+ cptr->alg.ixt_keyminbits,
14369+ cptr->alg.ixt_keymaxbits,
14370+ ret);
14371+ return ret;
14372+}
14373+/*
14374+ * called in ipsec_sa_wipe() time, will destroy key contexts
14375+ * and do 1 unbind()
14376+ */
14377+static void
14378+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
14379+{
14380+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
14381+
14382+ if (debug > 0)
14383+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
14384+ "name=%s key_e=%p \n",
14385+ alg->ixt_name, key_e);
14386+ if (!key_e) {
14387+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
14388+ "name=%s NULL key_e!\n",
14389+ alg->ixt_name);
14390+ return;
14391+ }
14392+ crypto_free_tfm(tfm);
14393+}
14394+
14395+/*
14396+ * create new key context, need alg->ixt_data to know which
14397+ * (of many) cipher inside this module is the target
14398+ */
14399+static __u8 *
14400+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
14401+{
14402+ struct ipsec_alg_capi_cipher *cptr;
14403+ struct crypto_tfm *tfm=NULL;
14404+
14405+ cptr = alg->ixt_data;
14406+ if (!cptr) {
14407+ printk(KERN_ERR "_capi_new_key(): "
14408+ "NULL ixt_data (?!) for \"%s\" algo\n"
14409+ , alg->ixt_name);
14410+ goto err;
14411+ }
14412+ if (debug > 0)
14413+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
14414+ "name=%s cptr=%p key=%p keysize=%d\n",
14415+ alg->ixt_name, cptr, key, keylen);
14416+
14417+ /*
14418+ * alloc tfm
14419+ */
14420+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
14421+ if (!tfm) {
14422+ printk(KERN_ERR "_capi_new_key(): "
14423+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
14424+ , alg->ixt_name, cptr->ciphername);
14425+ goto err;
14426+ }
14427+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
14428+ printk(KERN_ERR "_capi_new_key(): "
14429+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
14430+ , alg->ixt_name, keylen);
14431+ crypto_free_tfm(tfm);
14432+ tfm=NULL;
14433+ }
14434+err:
14435+ if (debug > 0)
14436+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
14437+ "name=%s key=%p keylen=%d tfm=%p\n",
14438+ alg->ixt_name, key, keylen, tfm);
14439+ return (__u8 *) tfm;
14440+}
14441+/*
14442+ * core encryption function: will use cx->ci to call actual cipher's
14443+ * cbc function
14444+ */
14445+static int
14446+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
14447+ int error =0;
14448+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
14449+ struct scatterlist sg = {
14450+ .page = virt_to_page(in),
14451+ .offset = (unsigned long)(in) % PAGE_SIZE,
14452+ .length=ilen,
14453+ };
14454+ if (debug > 1)
14455+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
14456+ "key_e=%p "
14457+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
14458+ , key_e
14459+ , in, in, ilen, iv, encrypt);
14460+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
14461+ if (encrypt)
14462+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
14463+ else
14464+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
14465+ if (debug > 1)
14466+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
14467+ "error=%d\n"
14468+ , error);
14469+ return (error<0)? error : ilen;
14470+}
14471+/*
14472+ * main initialization loop: for each cipher in list, do
14473+ * 1) setup cryptoapi cipher else continue
14474+ * 2) register ipsec_alg object
14475+ */
14476+static int
14477+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
14478+{
14479+ struct ipsec_alg_capi_cipher *cptr;
14480+ /* foreach cipher in list ... */
14481+ for (cptr=clist;cptr->ciphername;cptr++) {
14482+ /*
14483+ * see if cipher has been disabled (0) or
14484+ * if noauto set and not enabled (1)
14485+ */
14486+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
14487+ if (debug>0)
14488+ printk(KERN_INFO "setup_cipher_list(): "
14489+ "ciphername=%s skipped at user request: "
14490+ "noauto=%d parm[0]=%d parm[1]=%d\n"
14491+ , cptr->ciphername
14492+ , noauto
14493+ , cptr->parm[0]
14494+ , cptr->parm[1]);
14495+ continue;
14496+ }
14497+ /*
14498+ * use a local ci to avoid touching cptr->ci,
14499+ * if register ipsec_alg success then bind cipher
14500+ */
14501+ if( setup_cipher(cptr->ciphername) ) {
14502+ if (debug > 0)
14503+ printk(KERN_DEBUG "klips_debug:"
14504+ "setup_cipher_list():"
14505+ "ciphername=%s found\n"
14506+ , cptr->ciphername);
14507+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
14508+
14509+
14510+ } else {
14511+ printk(KERN_ERR "klips_debug:"
14512+ "setup_cipher_list():"
14513+ "ciphername=%s failed ipsec_alg_register\n"
14514+ , cptr->ciphername);
14515+ }
14516+ } else {
14517+ if (debug>0)
14518+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
14519+ cptr->ciphername);
14520+ }
14521+ }
14522+ return 0;
14523+}
14524+/*
14525+ * deregister ipsec_alg objects and unbind ciphers
14526+ */
14527+static int
14528+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
14529+{
14530+ struct ipsec_alg_capi_cipher *cptr;
14531+ /* foreach cipher in list ... */
14532+ for (cptr=clist;cptr->ciphername;cptr++) {
14533+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14534+ unregister_ipsec_alg_enc(&cptr->alg);
14535+ }
14536+ }
14537+ return 0;
14538+}
14539+/*
14540+ * test loop for registered algos
14541+ */
14542+static int
14543+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
14544+{
14545+ int test_ret;
14546+ struct ipsec_alg_capi_cipher *cptr;
14547+ /* foreach cipher in list ... */
14548+ for (cptr=clist;cptr->ciphername;cptr++) {
14549+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14550+ test_ret=ipsec_alg_test(
14551+ cptr->alg.ixt_alg_type,
14552+ cptr->alg.ixt_alg_id,
14553+ test);
14554+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
14555+ cptr->alg.ixt_alg_type,
14556+ cptr->alg.ixt_alg_id,
14557+ test_ret);
14558+ }
14559+ }
14560+ return 0;
14561+}
14562+
14563+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
14564+{
14565+ int ret, test_ret;
14566+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
14567+ return -EPROTONOSUPPORT;
14568+ if (ret==0 && test) {
14569+ test_ret=test_cipher_list(alg_capi_carray);
14570+ }
14571+ return ret;
14572+}
14573+IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
14574+{
14575+ unsetup_cipher_list(alg_capi_carray);
14576+ return;
14577+}
14578+#ifdef MODULE_LICENSE
14579+MODULE_LICENSE("GPL");
14580+#endif
14581+
14582+EXPORT_NO_SYMBOLS;
14583+#endif /* NO_CRYPTOAPI_SUPPORT */
14584--- /dev/null Tue Mar 11 13:02:56 2003
14585+++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004
14586@@ -0,0 +1,18 @@
14587+#!/bin/sh
14588+cat << EOF
14589+#include <linux/kernel.h>
14590+#include <linux/list.h>
14591+#include "freeswan/ipsec_alg.h"
14592+$(for i in $*; do
14593+ test -z "$i" && continue
14594+ echo "extern int $i(void);"
14595+done)
14596+void ipsec_alg_static_init(void){
14597+ int __attribute__ ((unused)) err=0;
14598+$(for i in $*; do
14599+ test -z "$i" && continue
14600+ echo " if ((err=$i()) < 0)"
14601+ echo " printk(KERN_WARNING \"$i() returned %d\", err);"
14602+done)
14603+}
14604+EOF
14605--- /dev/null Tue Mar 11 13:02:56 2003
14606+++ linux/net/ipsec/anyaddr.c Mon Feb 9 13:51:03 2004
14607@@ -0,0 +1,148 @@
14608+/*
14609+ * special addresses
14610+ * Copyright (C) 2000 Henry Spencer.
14611+ *
14612+ * This library is free software; you can redistribute it and/or modify it
14613+ * under the terms of the GNU Library General Public License as published by
14614+ * the Free Software Foundation; either version 2 of the License, or (at your
14615+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14616+ *
14617+ * This library is distributed in the hope that it will be useful, but
14618+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14619+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14620+ * License for more details.
14621+ *
14622+ * RCSID $Id: anyaddr.c,v 1.10.10.1 2006-11-24 05:55:46 paul Exp $
14623+ */
14624+#include "openswan.h"
14625+
14626+/* these are mostly fallbacks for the no-IPv6-support-in-library case */
14627+#ifndef IN6ADDR_ANY_INIT
14628+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
14629+#endif
14630+#ifndef IN6ADDR_LOOPBACK_INIT
14631+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
14632+#endif
14633+
14634+static struct in6_addr v6any = IN6ADDR_ANY_INIT;
14635+static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
14636+
14637+/*
14638+ - anyaddr - initialize to the any-address value
14639+ */
14640+err_t /* NULL for success, else string literal */
14641+anyaddr(af, dst)
14642+int af; /* address family */
14643+ip_address *dst;
14644+{
14645+ uint32_t v4any = htonl(INADDR_ANY);
14646+
14647+ switch (af) {
14648+ case AF_INET:
14649+ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
14650+ break;
14651+ case AF_INET6:
14652+ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
14653+ break;
14654+ default:
14655+ return "unknown address family in anyaddr/unspecaddr";
14656+ break;
14657+ }
14658+}
14659+
14660+/*
14661+ - unspecaddr - initialize to the unspecified-address value
14662+ */
14663+err_t /* NULL for success, else string literal */
14664+unspecaddr(af, dst)
14665+int af; /* address family */
14666+ip_address *dst;
14667+{
14668+ return anyaddr(af, dst);
14669+}
14670+
14671+/*
14672+ - loopbackaddr - initialize to the loopback-address value
14673+ */
14674+err_t /* NULL for success, else string literal */
14675+loopbackaddr(af, dst)
14676+int af; /* address family */
14677+ip_address *dst;
14678+{
14679+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
14680+
14681+ switch (af) {
14682+ case AF_INET:
14683+ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
14684+ break;
14685+ case AF_INET6:
14686+ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
14687+ break;
14688+ default:
14689+ return "unknown address family in loopbackaddr";
14690+ break;
14691+ }
14692+}
14693+
14694+/*
14695+ - isanyaddr - test for the any-address value
14696+ */
14697+int
14698+isanyaddr(src)
14699+const ip_address *src;
14700+{
14701+ uint32_t v4any = htonl(INADDR_ANY);
14702+ int cmp;
14703+
14704+ switch (src->u.v4.sin_family) {
14705+ case AF_INET:
14706+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
14707+ break;
14708+ case AF_INET6:
14709+ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
14710+ break;
14711+ case 0:
14712+ /* a zeroed structure is considered any address */
14713+ return 1;
14714+ default:
14715+ return 0;
14716+ break;
14717+ }
14718+
14719+ return (cmp == 0) ? 1 : 0;
14720+}
14721+
14722+/*
14723+ - isunspecaddr - test for the unspecified-address value
14724+ */
14725+int
14726+isunspecaddr(src)
14727+const ip_address *src;
14728+{
14729+ return isanyaddr(src);
14730+}
14731+
14732+/*
14733+ - isloopbackaddr - test for the loopback-address value
14734+ */
14735+int
14736+isloopbackaddr(src)
14737+const ip_address *src;
14738+{
14739+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
14740+ int cmp;
14741+
14742+ switch (src->u.v4.sin_family) {
14743+ case AF_INET:
14744+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
14745+ break;
14746+ case AF_INET6:
14747+ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
14748+ break;
14749+ default:
14750+ return 0;
14751+ break;
14752+ }
14753+
14754+ return (cmp == 0) ? 1 : 0;
14755+}
14756--- /dev/null Tue Mar 11 13:02:56 2003
14757+++ linux/net/ipsec/datatot.c Mon Feb 9 13:51:03 2004
14758@@ -0,0 +1,234 @@
14759+/*
14760+ * convert from binary data (e.g. key) to text form
14761+ * Copyright (C) 2000 Henry Spencer.
14762+ *
14763+ * This library is free software; you can redistribute it and/or modify it
14764+ * under the terms of the GNU Library General Public License as published by
14765+ * the Free Software Foundation; either version 2 of the License, or (at your
14766+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14767+ *
14768+ * This library is distributed in the hope that it will be useful, but
14769+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14770+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14771+ * License for more details.
14772+ *
14773+ * RCSID $Id: datatot.c,v 1.7 2005-04-14 20:48:43 mcr Exp $
14774+ */
14775+#include "openswan.h"
14776+
14777+static void convert(const char *src, size_t nreal, int format, char *out);
14778+
14779+/*
14780+ - datatot - convert data bytes to text
14781+ */
14782+size_t /* true length (with NUL) for success */
14783+datatot(src, srclen, format, dst, dstlen)
14784+const char *src;
14785+size_t srclen;
14786+int format; /* character indicating what format */
14787+char *dst; /* need not be valid if dstlen is 0 */
14788+size_t dstlen;
14789+{
14790+ size_t inblocksize; /* process this many bytes at a time */
14791+ size_t outblocksize; /* producing this many */
14792+ size_t breakevery; /* add a _ every this many (0 means don't) */
14793+ size_t sincebreak; /* output bytes since last _ */
14794+ char breakchar; /* character used to break between groups */
14795+ char inblock[10]; /* enough for any format */
14796+ char outblock[10]; /* enough for any format */
14797+ char fake[1]; /* fake output area for dstlen == 0 */
14798+ size_t needed; /* return value */
14799+ char *stop; /* where the terminating NUL will go */
14800+ size_t ntodo; /* remaining input */
14801+ size_t nreal;
14802+ char *out;
14803+ char *prefix;
14804+
14805+ breakevery = 0;
14806+ breakchar = '_';
14807+
14808+ switch (format) {
14809+ case 0:
14810+ case 'h':
14811+ format = 'x';
14812+ breakevery = 8;
14813+ /* FALLTHROUGH */
14814+ case 'x':
14815+ inblocksize = 1;
14816+ outblocksize = 2;
14817+ prefix = "0x";
14818+ break;
14819+ case ':':
14820+ format = 'x';
14821+ breakevery = 2;
14822+ breakchar = ':';
14823+ /* FALLTHROUGH */
14824+ case 16:
14825+ inblocksize = 1;
14826+ outblocksize = 2;
14827+ prefix = "";
14828+ format = 'x';
14829+ break;
14830+ case 's':
14831+ inblocksize = 3;
14832+ outblocksize = 4;
14833+ prefix = "0s";
14834+ break;
14835+ case 64: /* beware, equals ' ' */
14836+ inblocksize = 3;
14837+ outblocksize = 4;
14838+ prefix = "";
14839+ format = 's';
14840+ break;
14841+ default:
14842+ return 0;
14843+ break;
14844+ }
14845+
14846+ user_assert(inblocksize < sizeof(inblock));
14847+ user_assert(outblocksize < sizeof(outblock));
14848+ user_assert(breakevery % outblocksize == 0);
14849+
14850+ if (srclen == 0)
14851+ return 0;
14852+ ntodo = srclen;
14853+
14854+ if (dstlen == 0) { /* dispose of awkward special case */
14855+ dst = fake;
14856+ dstlen = 1;
14857+ }
14858+ stop = dst + dstlen - 1;
14859+
14860+ nreal = strlen(prefix);
14861+ needed = nreal; /* for starters */
14862+ if (dstlen <= nreal) { /* prefix won't fit */
14863+ strncpy(dst, prefix, dstlen - 1);
14864+ dst += dstlen - 1;
14865+ } else {
14866+ strcpy(dst, prefix);
14867+ dst += nreal;
14868+ }
14869+
14870+ user_assert(dst <= stop);
14871+ sincebreak = 0;
14872+
14873+ while (ntodo > 0) {
14874+ if (ntodo < inblocksize) { /* incomplete input */
14875+ memset(inblock, 0, sizeof(inblock));
14876+ memcpy(inblock, src, ntodo);
14877+ src = inblock;
14878+ nreal = ntodo;
14879+ ntodo = inblocksize;
14880+ } else
14881+ nreal = inblocksize;
14882+ out = (outblocksize > stop - dst) ? outblock : dst;
14883+
14884+ convert(src, nreal, format, out);
14885+ needed += outblocksize;
14886+ sincebreak += outblocksize;
14887+ if (dst < stop) {
14888+ if (out != dst) {
14889+ user_assert(outblocksize > stop - dst);
14890+ memcpy(dst, out, stop - dst);
14891+ dst = stop;
14892+ } else
14893+ dst += outblocksize;
14894+ }
14895+
14896+ src += inblocksize;
14897+ ntodo -= inblocksize;
14898+ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
14899+ if (dst < stop)
14900+ *dst++ = breakchar;
14901+ needed++;
14902+ sincebreak = 0;
14903+ }
14904+ }
14905+
14906+ user_assert(dst <= stop);
14907+ *dst++ = '\0';
14908+ needed++;
14909+
14910+ return needed;
14911+}
14912+
14913+/*
14914+ - convert - convert one input block to one output block
14915+ */
14916+static void
14917+convert(src, nreal, format, out)
14918+const char *src;
14919+size_t nreal; /* how much of the input block is real */
14920+int format;
14921+char *out;
14922+{
14923+ static char hex[] = "0123456789abcdef";
14924+ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
14925+ "abcdefghijklmnopqrstuvwxyz"
14926+ "0123456789+/";
14927+ unsigned char c;
14928+ unsigned char c1, c2, c3;
14929+
14930+ user_assert(nreal > 0);
14931+ switch (format) {
14932+ case 'x':
14933+ user_assert(nreal == 1);
14934+ c = (unsigned char)*src;
14935+ *out++ = hex[c >> 4];
14936+ *out++ = hex[c & 0xf];
14937+ break;
14938+ case 's':
14939+ c1 = (unsigned char)*src++;
14940+ c2 = (unsigned char)*src++;
14941+ c3 = (unsigned char)*src++;
14942+ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
14943+ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
14944+ c |= c2 >> 4; /* ...top 4 of c2 */
14945+ *out++ = base64[c];
14946+ if (nreal == 1)
14947+ *out++ = '=';
14948+ else {
14949+ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
14950+ c |= c3 >> 6; /* ...top 2 of c3 */
14951+ *out++ = base64[c];
14952+ }
14953+ if (nreal <= 2)
14954+ *out++ = '=';
14955+ else
14956+ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
14957+ break;
14958+ default:
14959+ user_assert(nreal == 0); /* unknown format */
14960+ break;
14961+ }
14962+}
14963+
14964+/*
14965+ - datatoa - convert data to ASCII
14966+ * backward-compatibility synonym for datatot
14967+ */
14968+size_t /* true length (with NUL) for success */
14969+datatoa(src, srclen, format, dst, dstlen)
14970+const char *src;
14971+size_t srclen;
14972+int format; /* character indicating what format */
14973+char *dst; /* need not be valid if dstlen is 0 */
14974+size_t dstlen;
14975+{
14976+ return datatot(src, srclen, format, dst, dstlen);
14977+}
14978+
14979+/*
14980+ - bytestoa - convert data bytes to ASCII
14981+ * backward-compatibility synonym for datatot
14982+ */
14983+size_t /* true length (with NUL) for success */
14984+bytestoa(src, srclen, format, dst, dstlen)
14985+const char *src;
14986+size_t srclen;
14987+int format; /* character indicating what format */
14988+char *dst; /* need not be valid if dstlen is 0 */
14989+size_t dstlen;
14990+{
14991+ return datatot(src, srclen, format, dst, dstlen);
14992+}
14993--- /dev/null Tue Mar 11 13:02:56 2003
14994+++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004
14995@@ -0,0 +1,148 @@
14996+
14997+#
14998+# RCSID $Id: defconfig,v 1.28.2.1 2006-10-11 18:14:33 paul Exp $
14999+#
15000+
15001+#
15002+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
15003+#
15004+
15005+#
15006+# First, lets override stuff already set or not in the kernel config.
15007+#
15008+# We can't even think about leaving this off...
15009+CONFIG_INET=y
15010+
15011+#
15012+# This must be on for subnet protection.
15013+CONFIG_IP_FORWARD=y
15014+
15015+# Shut off IPSEC masquerading if it has been enabled, since it will
15016+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
15017+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
15018+CONFIG_IP_MASQUERADE_IPSEC=n
15019+
15020+#
15021+# Next, lets set the recommended FreeS/WAN configuration.
15022+#
15023+
15024+# To config as static (preferred), 'y'. To config as module, 'm'.
15025+CONFIG_KLIPS=m
15026+
15027+# To do tunnel mode IPSec, this must be enabled.
15028+CONFIG_KLIPS_IPIP=y
15029+
15030+# To enable authentication, say 'y'. (Highly recommended)
15031+CONFIG_KLIPS_AH=y
15032+
15033+# Authentication algorithm(s):
15034+CONFIG_KLIPS_AUTH_HMAC_MD5=y
15035+CONFIG_KLIPS_AUTH_HMAC_SHA1=y
15036+
15037+# To enable encryption, say 'y'. (Highly recommended)
15038+CONFIG_KLIPS_ESP=y
15039+
15040+# modular algo extensions (and new ALGOs)
15041+CONFIG_KLIPS_ALG=y
15042+
15043+# Encryption algorithm(s):
15044+CONFIG_KLIPS_ENC_3DES=y
15045+CONFIG_KLIPS_ENC_AES=y
15046+# CONFIG_KLIPS_ENC_NULL=y
15047+
15048+# Use CryptoAPI for ALG? - by default, no.
15049+CONFIG_KLIPS_ENC_CRYPTOAPI=n
15050+
15051+# IP Compression: new, probably still has minor bugs.
15052+CONFIG_KLIPS_IPCOMP=y
15053+
15054+# To enable userspace-switchable KLIPS debugging, say 'y'.
15055+CONFIG_KLIPS_DEBUG=y
15056+
15057+# NAT Traversal
15058+CONFIG_IPSEC_NAT_TRAVERSAL=y
15059+
15060+#
15061+#
15062+# $Log: defconfig,v $
15063+# Revision 1.28.2.1 2006-10-11 18:14:33 paul
15064+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
15065+# per default.
15066+#
15067+# Revision 1.28 2005/05/11 03:15:42 mcr
15068+# adjusted makefiles to sanely build modules properly.
15069+#
15070+# Revision 1.27 2005/03/20 03:00:05 mcr
15071+# default configuration should enable NAT_TRAVERSAL.
15072+#
15073+# Revision 1.26 2004/07/10 19:11:18 mcr
15074+# CONFIG_IPSEC -> CONFIG_KLIPS.
15075+#
15076+# Revision 1.25 2004/07/05 01:03:53 mcr
15077+# fix for adding cryptoapi code.
15078+# keep it off for now, since UMLs do not have it yet.
15079+#
15080+# Revision 1.24 2004/04/06 02:49:25 mcr
15081+# pullup of algo code from alg-branch.
15082+#
15083+# Revision 1.23.2.2 2004/04/05 04:30:46 mcr
15084+# patches for alg-branch to compile/work with 2.x openswan
15085+#
15086+# Revision 1.23.2.1 2003/12/22 15:25:52 jjo
15087+# . Merged algo-0.8.1-rc11-test1 into alg-branch
15088+#
15089+# Revision 1.23 2003/12/10 01:14:27 mcr
15090+# NAT-traversal patches to KLIPS.
15091+#
15092+# Revision 1.22 2003/02/24 19:37:27 mcr
15093+# changed default compilation mode to static.
15094+#
15095+# Revision 1.21 2002/04/24 07:36:27 mcr
15096+# Moved from ./klips/net/ipsec/defconfig,v
15097+#
15098+# Revision 1.20 2002/04/02 04:07:40 mcr
15099+# default build is now 'm'odule for KLIPS
15100+#
15101+# Revision 1.19 2002/03/08 18:57:17 rgb
15102+# Added a blank line at the beginning of the file to make it easier for
15103+# other projects to patch ./arch/i386/defconfig, for example
15104+# LIDS+grSecurity requested by Jason Pattie.
15105+#
15106+# Revision 1.18 2000/11/30 17:26:56 rgb
15107+# Cleaned out unused options and enabled ipcomp by default.
15108+#
15109+# Revision 1.17 2000/09/15 11:37:01 rgb
15110+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
15111+# IPCOMP zlib deflate code.
15112+#
15113+# Revision 1.16 2000/09/08 19:12:55 rgb
15114+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
15115+#
15116+# Revision 1.15 2000/05/24 19:37:13 rgb
15117+# *** empty log message ***
15118+#
15119+# Revision 1.14 2000/05/11 21:14:57 henry
15120+# just commenting the FOOBAR=y lines out is not enough
15121+#
15122+# Revision 1.13 2000/05/10 20:17:58 rgb
15123+# Comment out netlink defaults, which are no longer needed.
15124+#
15125+# Revision 1.12 2000/05/10 19:13:38 rgb
15126+# Added configure option to shut off no eroute passthrough.
15127+#
15128+# Revision 1.11 2000/03/16 07:09:46 rgb
15129+# Hardcode PF_KEYv2 support.
15130+# Disable IPSEC_ICMP by default.
15131+# Remove DES config option from defaults file.
15132+#
15133+# Revision 1.10 2000/01/11 03:09:42 rgb
15134+# Added a default of 'y' to PF_KEYv2 keying I/F.
15135+#
15136+# Revision 1.9 1999/05/08 21:23:12 rgb
15137+# Added support for 2.2.x kernels.
15138+#
15139+# Revision 1.8 1999/04/06 04:54:25 rgb
15140+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
15141+# patch shell fixes.
15142+#
15143+#
15144--- /dev/null Tue Mar 11 13:02:56 2003
15145+++ linux/net/ipsec/deflate.c Mon Feb 9 13:51:03 2004
15146@@ -0,0 +1,1351 @@
15147+/* deflate.c -- compress data using the deflation algorithm
15148+ * Copyright (C) 1995-2002 Jean-loup Gailly.
15149+ * For conditions of distribution and use, see copyright notice in zlib.h
15150+ */
15151+
15152+/*
15153+ * ALGORITHM
15154+ *
15155+ * The "deflation" process depends on being able to identify portions
15156+ * of the input text which are identical to earlier input (within a
15157+ * sliding window trailing behind the input currently being processed).
15158+ *
15159+ * The most straightforward technique turns out to be the fastest for
15160+ * most input files: try all possible matches and select the longest.
15161+ * The key feature of this algorithm is that insertions into the string
15162+ * dictionary are very simple and thus fast, and deletions are avoided
15163+ * completely. Insertions are performed at each input character, whereas
15164+ * string matches are performed only when the previous match ends. So it
15165+ * is preferable to spend more time in matches to allow very fast string
15166+ * insertions and avoid deletions. The matching algorithm for small
15167+ * strings is inspired from that of Rabin & Karp. A brute force approach
15168+ * is used to find longer strings when a small match has been found.
15169+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
15170+ * (by Leonid Broukhis).
15171+ * A previous version of this file used a more sophisticated algorithm
15172+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
15173+ * time, but has a larger average cost, uses more memory and is patented.
15174+ * However the F&G algorithm may be faster for some highly redundant
15175+ * files if the parameter max_chain_length (described below) is too large.
15176+ *
15177+ * ACKNOWLEDGEMENTS
15178+ *
15179+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
15180+ * I found it in 'freeze' written by Leonid Broukhis.
15181+ * Thanks to many people for bug reports and testing.
15182+ *
15183+ * REFERENCES
15184+ *
15185+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
15186+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt
15187+ *
15188+ * A description of the Rabin and Karp algorithm is given in the book
15189+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
15190+ *
15191+ * Fiala,E.R., and Greene,D.H.
15192+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
15193+ *
15194+ */
15195+
15196+/* @(#) $Id: deflate.c,v 1.4 2004-07-10 07:48:37 mcr Exp $ */
15197+
15198+#include "deflate.h"
15199+
15200+local const char deflate_copyright[] =
15201+ " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
15202+/*
15203+ If you use the zlib library in a product, an acknowledgment is welcome
15204+ in the documentation of your product. If for some reason you cannot
15205+ include such an acknowledgment, I would appreciate that you keep this
15206+ copyright string in the executable of your product.
15207+ */
15208+
15209+/* ===========================================================================
15210+ * Function prototypes.
15211+ */
15212+typedef enum {
15213+ need_more, /* block not completed, need more input or more output */
15214+ block_done, /* block flush performed */
15215+ finish_started, /* finish started, need only more output at next deflate */
15216+ finish_done /* finish done, accept no more input or output */
15217+} block_state;
15218+
15219+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
15220+/* Compression function. Returns the block state after the call. */
15221+
15222+local void fill_window OF((deflate_state *s));
15223+local block_state deflate_stored OF((deflate_state *s, int flush));
15224+local block_state deflate_fast OF((deflate_state *s, int flush));
15225+local block_state deflate_slow OF((deflate_state *s, int flush));
15226+local void lm_init OF((deflate_state *s));
15227+local void putShortMSB OF((deflate_state *s, uInt b));
15228+local void flush_pending OF((z_streamp strm));
15229+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
15230+#ifdef ASMV
15231+ void match_init OF((void)); /* asm code initialization */
15232+ uInt longest_match OF((deflate_state *s, IPos cur_match));
15233+#else
15234+local uInt longest_match OF((deflate_state *s, IPos cur_match));
15235+#endif
15236+
15237+#ifdef DEBUG
15238+local void check_match OF((deflate_state *s, IPos start, IPos match,
15239+ int length));
15240+#endif
15241+
15242+/* ===========================================================================
15243+ * Local data
15244+ */
15245+
15246+#define NIL 0
15247+/* Tail of hash chains */
15248+
15249+#ifndef TOO_FAR
15250+# define TOO_FAR 4096
15251+#endif
15252+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
15253+
15254+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
15255+/* Minimum amount of lookahead, except at the end of the input file.
15256+ * See deflate.c for comments about the MIN_MATCH+1.
15257+ */
15258+
15259+/* Values for max_lazy_match, good_match and max_chain_length, depending on
15260+ * the desired pack level (0..9). The values given below have been tuned to
15261+ * exclude worst case performance for pathological files. Better values may be
15262+ * found for specific files.
15263+ */
15264+typedef struct config_s {
15265+ ush good_length; /* reduce lazy search above this match length */
15266+ ush max_lazy; /* do not perform lazy search above this match length */
15267+ ush nice_length; /* quit search above this match length */
15268+ ush max_chain;
15269+ compress_func func;
15270+} config;
15271+
15272+local const config configuration_table[10] = {
15273+/* good lazy nice chain */
15274+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
15275+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
15276+/* 2 */ {4, 5, 16, 8, deflate_fast},
15277+/* 3 */ {4, 6, 32, 32, deflate_fast},
15278+
15279+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
15280+/* 5 */ {8, 16, 32, 32, deflate_slow},
15281+/* 6 */ {8, 16, 128, 128, deflate_slow},
15282+/* 7 */ {8, 32, 128, 256, deflate_slow},
15283+/* 8 */ {32, 128, 258, 1024, deflate_slow},
15284+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
15285+
15286+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
15287+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
15288+ * meaning.
15289+ */
15290+
15291+#define EQUAL 0
15292+/* result of memcmp for equal strings */
15293+
15294+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
15295+
15296+/* ===========================================================================
15297+ * Update a hash value with the given input byte
15298+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
15299+ * input characters, so that a running hash key can be computed from the
15300+ * previous key instead of complete recalculation each time.
15301+ */
15302+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
15303+
15304+
15305+/* ===========================================================================
15306+ * Insert string str in the dictionary and set match_head to the previous head
15307+ * of the hash chain (the most recent string with same hash key). Return
15308+ * the previous length of the hash chain.
15309+ * If this file is compiled with -DFASTEST, the compression level is forced
15310+ * to 1, and no hash chains are maintained.
15311+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
15312+ * input characters and the first MIN_MATCH bytes of str are valid
15313+ * (except for the last MIN_MATCH-1 bytes of the input file).
15314+ */
15315+#ifdef FASTEST
15316+#define INSERT_STRING(s, str, match_head) \
15317+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
15318+ match_head = s->head[s->ins_h], \
15319+ s->head[s->ins_h] = (Pos)(str))
15320+#else
15321+#define INSERT_STRING(s, str, match_head) \
15322+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
15323+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
15324+ s->head[s->ins_h] = (Pos)(str))
15325+#endif
15326+
15327+/* ===========================================================================
15328+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
15329+ * prev[] will be initialized on the fly.
15330+ */
15331+#define CLEAR_HASH(s) \
15332+ s->head[s->hash_size-1] = NIL; \
15333+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
15334+
15335+/* ========================================================================= */
15336+int ZEXPORT deflateInit_(strm, level, version, stream_size)
15337+ z_streamp strm;
15338+ int level;
15339+ const char *version;
15340+ int stream_size;
15341+{
15342+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
15343+ Z_DEFAULT_STRATEGY, version, stream_size);
15344+ /* To do: ignore strm->next_in if we use it as window */
15345+}
15346+
15347+/* ========================================================================= */
15348+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
15349+ version, stream_size)
15350+ z_streamp strm;
15351+ int level;
15352+ int method;
15353+ int windowBits;
15354+ int memLevel;
15355+ int strategy;
15356+ const char *version;
15357+ int stream_size;
15358+{
15359+ deflate_state *s;
15360+ int noheader = 0;
15361+ static const char* my_version = ZLIB_VERSION;
15362+
15363+ ushf *overlay;
15364+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
15365+ * output size for (length,distance) codes is <= 24 bits.
15366+ */
15367+
15368+ if (version == Z_NULL || version[0] != my_version[0] ||
15369+ stream_size != sizeof(z_stream)) {
15370+ return Z_VERSION_ERROR;
15371+ }
15372+ if (strm == Z_NULL) return Z_STREAM_ERROR;
15373+
15374+ strm->msg = Z_NULL;
15375+ if (strm->zalloc == Z_NULL) {
15376+ return Z_STREAM_ERROR;
15377+/* strm->zalloc = zcalloc;
15378+ strm->opaque = (voidpf)0;*/
15379+ }
15380+ if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
15381+
15382+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
15383+#ifdef FASTEST
15384+ level = 1;
15385+#endif
15386+
15387+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
15388+ noheader = 1;
15389+ windowBits = -windowBits;
15390+ }
15391+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
15392+ windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
15393+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
15394+ return Z_STREAM_ERROR;
15395+ }
15396+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
15397+ if (s == Z_NULL) return Z_MEM_ERROR;
15398+ strm->state = (struct internal_state FAR *)s;
15399+ s->strm = strm;
15400+
15401+ s->noheader = noheader;
15402+ s->w_bits = windowBits;
15403+ s->w_size = 1 << s->w_bits;
15404+ s->w_mask = s->w_size - 1;
15405+
15406+ s->hash_bits = memLevel + 7;
15407+ s->hash_size = 1 << s->hash_bits;
15408+ s->hash_mask = s->hash_size - 1;
15409+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
15410+
15411+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
15412+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
15413+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
15414+
15415+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
15416+
15417+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
15418+ s->pending_buf = (uchf *) overlay;
15419+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
15420+
15421+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
15422+ s->pending_buf == Z_NULL) {
15423+ strm->msg = ERR_MSG(Z_MEM_ERROR);
15424+ deflateEnd (strm);
15425+ return Z_MEM_ERROR;
15426+ }
15427+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
15428+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
15429+
15430+ s->level = level;
15431+ s->strategy = strategy;
15432+ s->method = (Byte)method;
15433+
15434+ return deflateReset(strm);
15435+}
15436+
15437+/* ========================================================================= */
15438+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
15439+ z_streamp strm;
15440+ const Bytef *dictionary;
15441+ uInt dictLength;
15442+{
15443+ deflate_state *s;
15444+ uInt length = dictLength;
15445+ uInt n;
15446+ IPos hash_head = 0;
15447+
15448+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
15449+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
15450+
15451+ s = strm->state;
15452+ strm->adler = adler32(strm->adler, dictionary, dictLength);
15453+
15454+ if (length < MIN_MATCH) return Z_OK;
15455+ if (length > MAX_DIST(s)) {
15456+ length = MAX_DIST(s);
15457+#ifndef USE_DICT_HEAD
15458+ dictionary += dictLength - length; /* use the tail of the dictionary */
15459+#endif
15460+ }
15461+ zmemcpy(s->window, dictionary, length);
15462+ s->strstart = length;
15463+ s->block_start = (long)length;
15464+
15465+ /* Insert all strings in the hash table (except for the last two bytes).
15466+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
15467+ * call of fill_window.
15468+ */
15469+ s->ins_h = s->window[0];
15470+ UPDATE_HASH(s, s->ins_h, s->window[1]);
15471+ for (n = 0; n <= length - MIN_MATCH; n++) {
15472+ INSERT_STRING(s, n, hash_head);
15473+ }
15474+ if (hash_head) hash_head = 0; /* to make compiler happy */
15475+ return Z_OK;
15476+}
15477+
15478+/* ========================================================================= */
15479+int ZEXPORT deflateReset (strm)
15480+ z_streamp strm;
15481+{
15482+ deflate_state *s;
15483+
15484+ if (strm == Z_NULL || strm->state == Z_NULL ||
15485+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
15486+
15487+ strm->total_in = strm->total_out = 0;
15488+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
15489+ strm->data_type = Z_UNKNOWN;
15490+
15491+ s = (deflate_state *)strm->state;
15492+ s->pending = 0;
15493+ s->pending_out = s->pending_buf;
15494+
15495+ if (s->noheader < 0) {
15496+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
15497+ }
15498+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
15499+ strm->adler = 1;
15500+ s->last_flush = Z_NO_FLUSH;
15501+
15502+ _tr_init(s);
15503+ lm_init(s);
15504+
15505+ return Z_OK;
15506+}
15507+
15508+/* ========================================================================= */
15509+int ZEXPORT deflateParams(strm, level, strategy)
15510+ z_streamp strm;
15511+ int level;
15512+ int strategy;
15513+{
15514+ deflate_state *s;
15515+ compress_func func;
15516+ int err = Z_OK;
15517+
15518+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15519+ s = strm->state;
15520+
15521+ if (level == Z_DEFAULT_COMPRESSION) {
15522+ level = 6;
15523+ }
15524+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
15525+ return Z_STREAM_ERROR;
15526+ }
15527+ func = configuration_table[s->level].func;
15528+
15529+ if (func != configuration_table[level].func && strm->total_in != 0) {
15530+ /* Flush the last buffer: */
15531+ err = deflate(strm, Z_PARTIAL_FLUSH);
15532+ }
15533+ if (s->level != level) {
15534+ s->level = level;
15535+ s->max_lazy_match = configuration_table[level].max_lazy;
15536+ s->good_match = configuration_table[level].good_length;
15537+ s->nice_match = configuration_table[level].nice_length;
15538+ s->max_chain_length = configuration_table[level].max_chain;
15539+ }
15540+ s->strategy = strategy;
15541+ return err;
15542+}
15543+
15544+/* =========================================================================
15545+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
15546+ * IN assertion: the stream state is correct and there is enough room in
15547+ * pending_buf.
15548+ */
15549+local void putShortMSB (s, b)
15550+ deflate_state *s;
15551+ uInt b;
15552+{
15553+ put_byte(s, (Byte)(b >> 8));
15554+ put_byte(s, (Byte)(b & 0xff));
15555+}
15556+
15557+/* =========================================================================
15558+ * Flush as much pending output as possible. All deflate() output goes
15559+ * through this function so some applications may wish to modify it
15560+ * to avoid allocating a large strm->next_out buffer and copying into it.
15561+ * (See also read_buf()).
15562+ */
15563+local void flush_pending(strm)
15564+ z_streamp strm;
15565+{
15566+ unsigned len = strm->state->pending;
15567+
15568+ if (len > strm->avail_out) len = strm->avail_out;
15569+ if (len == 0) return;
15570+
15571+ zmemcpy(strm->next_out, strm->state->pending_out, len);
15572+ strm->next_out += len;
15573+ strm->state->pending_out += len;
15574+ strm->total_out += len;
15575+ strm->avail_out -= len;
15576+ strm->state->pending -= len;
15577+ if (strm->state->pending == 0) {
15578+ strm->state->pending_out = strm->state->pending_buf;
15579+ }
15580+}
15581+
15582+/* ========================================================================= */
15583+int ZEXPORT deflate (strm, flush)
15584+ z_streamp strm;
15585+ int flush;
15586+{
15587+ int old_flush; /* value of flush param for previous deflate call */
15588+ deflate_state *s;
15589+
15590+ if (strm == Z_NULL || strm->state == Z_NULL ||
15591+ flush > Z_FINISH || flush < 0) {
15592+ return Z_STREAM_ERROR;
15593+ }
15594+ s = strm->state;
15595+
15596+ if (strm->next_out == Z_NULL ||
15597+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
15598+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
15599+ ERR_RETURN(strm, Z_STREAM_ERROR);
15600+ }
15601+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
15602+
15603+ s->strm = strm; /* just in case */
15604+ old_flush = s->last_flush;
15605+ s->last_flush = flush;
15606+
15607+ /* Write the zlib header */
15608+ if (s->status == INIT_STATE) {
15609+
15610+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
15611+ uInt level_flags = (s->level-1) >> 1;
15612+
15613+ if (level_flags > 3) level_flags = 3;
15614+ header |= (level_flags << 6);
15615+ if (s->strstart != 0) header |= PRESET_DICT;
15616+ header += 31 - (header % 31);
15617+
15618+ s->status = BUSY_STATE;
15619+ putShortMSB(s, header);
15620+
15621+ /* Save the adler32 of the preset dictionary: */
15622+ if (s->strstart != 0) {
15623+ putShortMSB(s, (uInt)(strm->adler >> 16));
15624+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
15625+ }
15626+ strm->adler = 1L;
15627+ }
15628+
15629+ /* Flush as much pending output as possible */
15630+ if (s->pending != 0) {
15631+ flush_pending(strm);
15632+ if (strm->avail_out == 0) {
15633+ /* Since avail_out is 0, deflate will be called again with
15634+ * more output space, but possibly with both pending and
15635+ * avail_in equal to zero. There won't be anything to do,
15636+ * but this is not an error situation so make sure we
15637+ * return OK instead of BUF_ERROR at next call of deflate:
15638+ */
15639+ s->last_flush = -1;
15640+ return Z_OK;
15641+ }
15642+
15643+ /* Make sure there is something to do and avoid duplicate consecutive
15644+ * flushes. For repeated and useless calls with Z_FINISH, we keep
15645+ * returning Z_STREAM_END instead of Z_BUFF_ERROR.
15646+ */
15647+ } else if (strm->avail_in == 0 && flush <= old_flush &&
15648+ flush != Z_FINISH) {
15649+ ERR_RETURN(strm, Z_BUF_ERROR);
15650+ }
15651+
15652+ /* User must not provide more input after the first FINISH: */
15653+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
15654+ ERR_RETURN(strm, Z_BUF_ERROR);
15655+ }
15656+
15657+ /* Start a new block or continue the current one.
15658+ */
15659+ if (strm->avail_in != 0 || s->lookahead != 0 ||
15660+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
15661+ block_state bstate;
15662+
15663+ bstate = (*(configuration_table[s->level].func))(s, flush);
15664+
15665+ if (bstate == finish_started || bstate == finish_done) {
15666+ s->status = FINISH_STATE;
15667+ }
15668+ if (bstate == need_more || bstate == finish_started) {
15669+ if (strm->avail_out == 0) {
15670+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
15671+ }
15672+ return Z_OK;
15673+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
15674+ * of deflate should use the same flush parameter to make sure
15675+ * that the flush is complete. So we don't have to output an
15676+ * empty block here, this will be done at next call. This also
15677+ * ensures that for a very small output buffer, we emit at most
15678+ * one empty block.
15679+ */
15680+ }
15681+ if (bstate == block_done) {
15682+ if (flush == Z_PARTIAL_FLUSH) {
15683+ _tr_align(s);
15684+ } else { /* FULL_FLUSH or SYNC_FLUSH */
15685+ _tr_stored_block(s, (char*)0, 0L, 0);
15686+ /* For a full flush, this empty block will be recognized
15687+ * as a special marker by inflate_sync().
15688+ */
15689+ if (flush == Z_FULL_FLUSH) {
15690+ CLEAR_HASH(s); /* forget history */
15691+ }
15692+ }
15693+ flush_pending(strm);
15694+ if (strm->avail_out == 0) {
15695+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
15696+ return Z_OK;
15697+ }
15698+ }
15699+ }
15700+ Assert(strm->avail_out > 0, "bug2");
15701+
15702+ if (flush != Z_FINISH) return Z_OK;
15703+ if (s->noheader) return Z_STREAM_END;
15704+
15705+ /* Write the zlib trailer (adler32) */
15706+ putShortMSB(s, (uInt)(strm->adler >> 16));
15707+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
15708+ flush_pending(strm);
15709+ /* If avail_out is zero, the application will call deflate again
15710+ * to flush the rest.
15711+ */
15712+ s->noheader = -1; /* write the trailer only once! */
15713+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
15714+}
15715+
15716+/* ========================================================================= */
15717+int ZEXPORT deflateEnd (strm)
15718+ z_streamp strm;
15719+{
15720+ int status;
15721+
15722+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15723+
15724+ status = strm->state->status;
15725+ if (status != INIT_STATE && status != BUSY_STATE &&
15726+ status != FINISH_STATE) {
15727+ return Z_STREAM_ERROR;
15728+ }
15729+
15730+ /* Deallocate in reverse order of allocations: */
15731+ TRY_FREE(strm, strm->state->pending_buf);
15732+ TRY_FREE(strm, strm->state->head);
15733+ TRY_FREE(strm, strm->state->prev);
15734+ TRY_FREE(strm, strm->state->window);
15735+
15736+ ZFREE(strm, strm->state);
15737+ strm->state = Z_NULL;
15738+
15739+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
15740+}
15741+
15742+/* =========================================================================
15743+ * Copy the source state to the destination state.
15744+ * To simplify the source, this is not supported for 16-bit MSDOS (which
15745+ * doesn't have enough memory anyway to duplicate compression states).
15746+ */
15747+int ZEXPORT deflateCopy (dest, source)
15748+ z_streamp dest;
15749+ z_streamp source;
15750+{
15751+#ifdef MAXSEG_64K
15752+ return Z_STREAM_ERROR;
15753+#else
15754+ deflate_state *ds;
15755+ deflate_state *ss;
15756+ ushf *overlay;
15757+
15758+
15759+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
15760+ return Z_STREAM_ERROR;
15761+ }
15762+
15763+ ss = source->state;
15764+
15765+ *dest = *source;
15766+
15767+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
15768+ if (ds == Z_NULL) return Z_MEM_ERROR;
15769+ dest->state = (struct internal_state FAR *) ds;
15770+ *ds = *ss;
15771+ ds->strm = dest;
15772+
15773+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
15774+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
15775+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
15776+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
15777+ ds->pending_buf = (uchf *) overlay;
15778+
15779+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
15780+ ds->pending_buf == Z_NULL) {
15781+ deflateEnd (dest);
15782+ return Z_MEM_ERROR;
15783+ }
15784+ /* following zmemcpy do not work for 16-bit MSDOS */
15785+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
15786+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
15787+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
15788+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
15789+
15790+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
15791+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
15792+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
15793+
15794+ ds->l_desc.dyn_tree = ds->dyn_ltree;
15795+ ds->d_desc.dyn_tree = ds->dyn_dtree;
15796+ ds->bl_desc.dyn_tree = ds->bl_tree;
15797+
15798+ return Z_OK;
15799+#endif
15800+}
15801+
15802+/* ===========================================================================
15803+ * Read a new buffer from the current input stream, update the adler32
15804+ * and total number of bytes read. All deflate() input goes through
15805+ * this function so some applications may wish to modify it to avoid
15806+ * allocating a large strm->next_in buffer and copying from it.
15807+ * (See also flush_pending()).
15808+ */
15809+local int read_buf(strm, buf, size)
15810+ z_streamp strm;
15811+ Bytef *buf;
15812+ unsigned size;
15813+{
15814+ unsigned len = strm->avail_in;
15815+
15816+ if (len > size) len = size;
15817+ if (len == 0) return 0;
15818+
15819+ strm->avail_in -= len;
15820+
15821+ if (!strm->state->noheader) {
15822+ strm->adler = adler32(strm->adler, strm->next_in, len);
15823+ }
15824+ zmemcpy(buf, strm->next_in, len);
15825+ strm->next_in += len;
15826+ strm->total_in += len;
15827+
15828+ return (int)len;
15829+}
15830+
15831+/* ===========================================================================
15832+ * Initialize the "longest match" routines for a new zlib stream
15833+ */
15834+local void lm_init (s)
15835+ deflate_state *s;
15836+{
15837+ s->window_size = (ulg)2L*s->w_size;
15838+
15839+ CLEAR_HASH(s);
15840+
15841+ /* Set the default configuration parameters:
15842+ */
15843+ s->max_lazy_match = configuration_table[s->level].max_lazy;
15844+ s->good_match = configuration_table[s->level].good_length;
15845+ s->nice_match = configuration_table[s->level].nice_length;
15846+ s->max_chain_length = configuration_table[s->level].max_chain;
15847+
15848+ s->strstart = 0;
15849+ s->block_start = 0L;
15850+ s->lookahead = 0;
15851+ s->match_length = s->prev_length = MIN_MATCH-1;
15852+ s->match_available = 0;
15853+ s->ins_h = 0;
15854+#ifdef ASMV
15855+ match_init(); /* initialize the asm code */
15856+#endif
15857+}
15858+
15859+/* ===========================================================================
15860+ * Set match_start to the longest match starting at the given string and
15861+ * return its length. Matches shorter or equal to prev_length are discarded,
15862+ * in which case the result is equal to prev_length and match_start is
15863+ * garbage.
15864+ * IN assertions: cur_match is the head of the hash chain for the current
15865+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
15866+ * OUT assertion: the match length is not greater than s->lookahead.
15867+ */
15868+#ifndef ASMV
15869+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
15870+ * match.S. The code will be functionally equivalent.
15871+ */
15872+#ifndef FASTEST
15873+local uInt longest_match(s, cur_match)
15874+ deflate_state *s;
15875+ IPos cur_match; /* current match */
15876+{
15877+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
15878+ register Bytef *scan = s->window + s->strstart; /* current string */
15879+ register Bytef *match; /* matched string */
15880+ register int len; /* length of current match */
15881+ int best_len = s->prev_length; /* best match length so far */
15882+ int nice_match = s->nice_match; /* stop if match long enough */
15883+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
15884+ s->strstart - (IPos)MAX_DIST(s) : NIL;
15885+ /* Stop when cur_match becomes <= limit. To simplify the code,
15886+ * we prevent matches with the string of window index 0.
15887+ */
15888+ Posf *prev = s->prev;
15889+ uInt wmask = s->w_mask;
15890+
15891+#ifdef UNALIGNED_OK
15892+ /* Compare two bytes at a time. Note: this is not always beneficial.
15893+ * Try with and without -DUNALIGNED_OK to check.
15894+ */
15895+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
15896+ register ush scan_start = *(ushf*)scan;
15897+ register ush scan_end = *(ushf*)(scan+best_len-1);
15898+#else
15899+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15900+ register Byte scan_end1 = scan[best_len-1];
15901+ register Byte scan_end = scan[best_len];
15902+#endif
15903+
15904+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15905+ * It is easy to get rid of this optimization if necessary.
15906+ */
15907+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15908+
15909+ /* Do not waste too much time if we already have a good match: */
15910+ if (s->prev_length >= s->good_match) {
15911+ chain_length >>= 2;
15912+ }
15913+ /* Do not look for matches beyond the end of the input. This is necessary
15914+ * to make deflate deterministic.
15915+ */
15916+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
15917+
15918+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15919+
15920+ do {
15921+ Assert(cur_match < s->strstart, "no future");
15922+ match = s->window + cur_match;
15923+
15924+ /* Skip to next match if the match length cannot increase
15925+ * or if the match length is less than 2:
15926+ */
15927+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
15928+ /* This code assumes sizeof(unsigned short) == 2. Do not use
15929+ * UNALIGNED_OK if your compiler uses a different size.
15930+ */
15931+ if (*(ushf*)(match+best_len-1) != scan_end ||
15932+ *(ushf*)match != scan_start) continue;
15933+
15934+ /* It is not necessary to compare scan[2] and match[2] since they are
15935+ * always equal when the other bytes match, given that the hash keys
15936+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
15937+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
15938+ * lookahead only every 4th comparison; the 128th check will be made
15939+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
15940+ * necessary to put more guard bytes at the end of the window, or
15941+ * to check more often for insufficient lookahead.
15942+ */
15943+ Assert(scan[2] == match[2], "scan[2]?");
15944+ scan++, match++;
15945+ do {
15946+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15947+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15948+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15949+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15950+ scan < strend);
15951+ /* The funny "do {}" generates better code on most compilers */
15952+
15953+ /* Here, scan <= window+strstart+257 */
15954+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15955+ if (*scan == *match) scan++;
15956+
15957+ len = (MAX_MATCH - 1) - (int)(strend-scan);
15958+ scan = strend - (MAX_MATCH-1);
15959+
15960+#else /* UNALIGNED_OK */
15961+
15962+ if (match[best_len] != scan_end ||
15963+ match[best_len-1] != scan_end1 ||
15964+ *match != *scan ||
15965+ *++match != scan[1]) continue;
15966+
15967+ /* The check at best_len-1 can be removed because it will be made
15968+ * again later. (This heuristic is not always a win.)
15969+ * It is not necessary to compare scan[2] and match[2] since they
15970+ * are always equal when the other bytes match, given that
15971+ * the hash keys are equal and that HASH_BITS >= 8.
15972+ */
15973+ scan += 2, match++;
15974+ Assert(*scan == *match, "match[2]?");
15975+
15976+ /* We check for insufficient lookahead only every 8th comparison;
15977+ * the 256th check will be made at strstart+258.
15978+ */
15979+ do {
15980+ } while (*++scan == *++match && *++scan == *++match &&
15981+ *++scan == *++match && *++scan == *++match &&
15982+ *++scan == *++match && *++scan == *++match &&
15983+ *++scan == *++match && *++scan == *++match &&
15984+ scan < strend);
15985+
15986+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15987+
15988+ len = MAX_MATCH - (int)(strend - scan);
15989+ scan = strend - MAX_MATCH;
15990+
15991+#endif /* UNALIGNED_OK */
15992+
15993+ if (len > best_len) {
15994+ s->match_start = cur_match;
15995+ best_len = len;
15996+ if (len >= nice_match) break;
15997+#ifdef UNALIGNED_OK
15998+ scan_end = *(ushf*)(scan+best_len-1);
15999+#else
16000+ scan_end1 = scan[best_len-1];
16001+ scan_end = scan[best_len];
16002+#endif
16003+ }
16004+ } while ((cur_match = prev[cur_match & wmask]) > limit
16005+ && --chain_length != 0);
16006+
16007+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
16008+ return s->lookahead;
16009+}
16010+
16011+#else /* FASTEST */
16012+/* ---------------------------------------------------------------------------
16013+ * Optimized version for level == 1 only
16014+ */
16015+local uInt longest_match(s, cur_match)
16016+ deflate_state *s;
16017+ IPos cur_match; /* current match */
16018+{
16019+ register Bytef *scan = s->window + s->strstart; /* current string */
16020+ register Bytef *match; /* matched string */
16021+ register int len; /* length of current match */
16022+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
16023+
16024+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
16025+ * It is easy to get rid of this optimization if necessary.
16026+ */
16027+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
16028+
16029+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
16030+
16031+ Assert(cur_match < s->strstart, "no future");
16032+
16033+ match = s->window + cur_match;
16034+
16035+ /* Return failure if the match length is less than 2:
16036+ */
16037+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
16038+
16039+ /* The check at best_len-1 can be removed because it will be made
16040+ * again later. (This heuristic is not always a win.)
16041+ * It is not necessary to compare scan[2] and match[2] since they
16042+ * are always equal when the other bytes match, given that
16043+ * the hash keys are equal and that HASH_BITS >= 8.
16044+ */
16045+ scan += 2, match += 2;
16046+ Assert(*scan == *match, "match[2]?");
16047+
16048+ /* We check for insufficient lookahead only every 8th comparison;
16049+ * the 256th check will be made at strstart+258.
16050+ */
16051+ do {
16052+ } while (*++scan == *++match && *++scan == *++match &&
16053+ *++scan == *++match && *++scan == *++match &&
16054+ *++scan == *++match && *++scan == *++match &&
16055+ *++scan == *++match && *++scan == *++match &&
16056+ scan < strend);
16057+
16058+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
16059+
16060+ len = MAX_MATCH - (int)(strend - scan);
16061+
16062+ if (len < MIN_MATCH) return MIN_MATCH - 1;
16063+
16064+ s->match_start = cur_match;
16065+ return len <= s->lookahead ? len : s->lookahead;
16066+}
16067+#endif /* FASTEST */
16068+#endif /* ASMV */
16069+
16070+#ifdef DEBUG
16071+/* ===========================================================================
16072+ * Check that the match at match_start is indeed a match.
16073+ */
16074+local void check_match(s, start, match, length)
16075+ deflate_state *s;
16076+ IPos start, match;
16077+ int length;
16078+{
16079+ /* check that the match is indeed a match */
16080+ if (zmemcmp(s->window + match,
16081+ s->window + start, length) != EQUAL) {
16082+ fprintf(stderr, " start %u, match %u, length %d\n",
16083+ start, match, length);
16084+ do {
16085+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
16086+ } while (--length != 0);
16087+ z_error("invalid match");
16088+ }
16089+ if (z_verbose > 1) {
16090+ fprintf(stderr,"\\[%d,%d]", start-match, length);
16091+ do { putc(s->window[start++], stderr); } while (--length != 0);
16092+ }
16093+}
16094+#else
16095+# define check_match(s, start, match, length)
16096+#endif
16097+
16098+/* ===========================================================================
16099+ * Fill the window when the lookahead becomes insufficient.
16100+ * Updates strstart and lookahead.
16101+ *
16102+ * IN assertion: lookahead < MIN_LOOKAHEAD
16103+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
16104+ * At least one byte has been read, or avail_in == 0; reads are
16105+ * performed for at least two bytes (required for the zip translate_eol
16106+ * option -- not supported here).
16107+ */
16108+local void fill_window(s)
16109+ deflate_state *s;
16110+{
16111+ register unsigned n, m;
16112+ register Posf *p;
16113+ unsigned more; /* Amount of free space at the end of the window. */
16114+ uInt wsize = s->w_size;
16115+
16116+ do {
16117+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
16118+
16119+ /* Deal with !@#$% 64K limit: */
16120+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
16121+ more = wsize;
16122+
16123+ } else if (more == (unsigned)(-1)) {
16124+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
16125+ * and lookahead == 1 (input done one byte at time)
16126+ */
16127+ more--;
16128+
16129+ /* If the window is almost full and there is insufficient lookahead,
16130+ * move the upper half to the lower one to make room in the upper half.
16131+ */
16132+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
16133+
16134+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
16135+ s->match_start -= wsize;
16136+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
16137+ s->block_start -= (long) wsize;
16138+
16139+ /* Slide the hash table (could be avoided with 32 bit values
16140+ at the expense of memory usage). We slide even when level == 0
16141+ to keep the hash table consistent if we switch back to level > 0
16142+ later. (Using level 0 permanently is not an optimal usage of
16143+ zlib, so we don't care about this pathological case.)
16144+ */
16145+ n = s->hash_size;
16146+ p = &s->head[n];
16147+ do {
16148+ m = *--p;
16149+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
16150+ } while (--n);
16151+
16152+ n = wsize;
16153+#ifndef FASTEST
16154+ p = &s->prev[n];
16155+ do {
16156+ m = *--p;
16157+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
16158+ /* If n is not on any hash chain, prev[n] is garbage but
16159+ * its value will never be used.
16160+ */
16161+ } while (--n);
16162+#endif
16163+ more += wsize;
16164+ }
16165+ if (s->strm->avail_in == 0) return;
16166+
16167+ /* If there was no sliding:
16168+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
16169+ * more == window_size - lookahead - strstart
16170+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
16171+ * => more >= window_size - 2*WSIZE + 2
16172+ * In the BIG_MEM or MMAP case (not yet supported),
16173+ * window_size == input_size + MIN_LOOKAHEAD &&
16174+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
16175+ * Otherwise, window_size == 2*WSIZE so more >= 2.
16176+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
16177+ */
16178+ Assert(more >= 2, "more < 2");
16179+
16180+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
16181+ s->lookahead += n;
16182+
16183+ /* Initialize the hash value now that we have some input: */
16184+ if (s->lookahead >= MIN_MATCH) {
16185+ s->ins_h = s->window[s->strstart];
16186+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
16187+#if MIN_MATCH != 3
16188+ Call UPDATE_HASH() MIN_MATCH-3 more times
16189+#endif
16190+ }
16191+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
16192+ * but this is not important since only literal bytes will be emitted.
16193+ */
16194+
16195+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
16196+}
16197+
16198+/* ===========================================================================
16199+ * Flush the current block, with given end-of-file flag.
16200+ * IN assertion: strstart is set to the end of the current match.
16201+ */
16202+#define FLUSH_BLOCK_ONLY(s, eof) { \
16203+ _tr_flush_block(s, (s->block_start >= 0L ? \
16204+ (charf *)&s->window[(unsigned)s->block_start] : \
16205+ (charf *)Z_NULL), \
16206+ (ulg)((long)s->strstart - s->block_start), \
16207+ (eof)); \
16208+ s->block_start = s->strstart; \
16209+ flush_pending(s->strm); \
16210+ Tracev((stderr,"[FLUSH]")); \
16211+}
16212+
16213+/* Same but force premature exit if necessary. */
16214+#define FLUSH_BLOCK(s, eof) { \
16215+ FLUSH_BLOCK_ONLY(s, eof); \
16216+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
16217+}
16218+
16219+/* ===========================================================================
16220+ * Copy without compression as much as possible from the input stream, return
16221+ * the current block state.
16222+ * This function does not insert new strings in the dictionary since
16223+ * uncompressible data is probably not useful. This function is used
16224+ * only for the level=0 compression option.
16225+ * NOTE: this function should be optimized to avoid extra copying from
16226+ * window to pending_buf.
16227+ */
16228+local block_state deflate_stored(s, flush)
16229+ deflate_state *s;
16230+ int flush;
16231+{
16232+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
16233+ * to pending_buf_size, and each stored block has a 5 byte header:
16234+ */
16235+ ulg max_block_size = 0xffff;
16236+ ulg max_start;
16237+
16238+ if (max_block_size > s->pending_buf_size - 5) {
16239+ max_block_size = s->pending_buf_size - 5;
16240+ }
16241+
16242+ /* Copy as much as possible from input to output: */
16243+ for (;;) {
16244+ /* Fill the window as much as possible: */
16245+ if (s->lookahead <= 1) {
16246+
16247+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
16248+ s->block_start >= (long)s->w_size, "slide too late");
16249+
16250+ fill_window(s);
16251+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
16252+
16253+ if (s->lookahead == 0) break; /* flush the current block */
16254+ }
16255+ Assert(s->block_start >= 0L, "block gone");
16256+
16257+ s->strstart += s->lookahead;
16258+ s->lookahead = 0;
16259+
16260+ /* Emit a stored block if pending_buf will be full: */
16261+ max_start = s->block_start + max_block_size;
16262+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
16263+ /* strstart == 0 is possible when wraparound on 16-bit machine */
16264+ s->lookahead = (uInt)(s->strstart - max_start);
16265+ s->strstart = (uInt)max_start;
16266+ FLUSH_BLOCK(s, 0);
16267+ }
16268+ /* Flush if we may have to slide, otherwise block_start may become
16269+ * negative and the data will be gone:
16270+ */
16271+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
16272+ FLUSH_BLOCK(s, 0);
16273+ }
16274+ }
16275+ FLUSH_BLOCK(s, flush == Z_FINISH);
16276+ return flush == Z_FINISH ? finish_done : block_done;
16277+}
16278+
16279+/* ===========================================================================
16280+ * Compress as much as possible from the input stream, return the current
16281+ * block state.
16282+ * This function does not perform lazy evaluation of matches and inserts
16283+ * new strings in the dictionary only for unmatched strings or for short
16284+ * matches. It is used only for the fast compression options.
16285+ */
16286+local block_state deflate_fast(s, flush)
16287+ deflate_state *s;
16288+ int flush;
16289+{
16290+ IPos hash_head = NIL; /* head of the hash chain */
16291+ int bflush; /* set if current block must be flushed */
16292+
16293+ for (;;) {
16294+ /* Make sure that we always have enough lookahead, except
16295+ * at the end of the input file. We need MAX_MATCH bytes
16296+ * for the next match, plus MIN_MATCH bytes to insert the
16297+ * string following the next match.
16298+ */
16299+ if (s->lookahead < MIN_LOOKAHEAD) {
16300+ fill_window(s);
16301+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
16302+ return need_more;
16303+ }
16304+ if (s->lookahead == 0) break; /* flush the current block */
16305+ }
16306+
16307+ /* Insert the string window[strstart .. strstart+2] in the
16308+ * dictionary, and set hash_head to the head of the hash chain:
16309+ */
16310+ if (s->lookahead >= MIN_MATCH) {
16311+ INSERT_STRING(s, s->strstart, hash_head);
16312+ }
16313+
16314+ /* Find the longest match, discarding those <= prev_length.
16315+ * At this point we have always match_length < MIN_MATCH
16316+ */
16317+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
16318+ /* To simplify the code, we prevent matches with the string
16319+ * of window index 0 (in particular we have to avoid a match
16320+ * of the string with itself at the start of the input file).
16321+ */
16322+ if (s->strategy != Z_HUFFMAN_ONLY) {
16323+ s->match_length = longest_match (s, hash_head);
16324+ }
16325+ /* longest_match() sets match_start */
16326+ }
16327+ if (s->match_length >= MIN_MATCH) {
16328+ check_match(s, s->strstart, s->match_start, s->match_length);
16329+
16330+ _tr_tally_dist(s, s->strstart - s->match_start,
16331+ s->match_length - MIN_MATCH, bflush);
16332+
16333+ s->lookahead -= s->match_length;
16334+
16335+ /* Insert new strings in the hash table only if the match length
16336+ * is not too large. This saves time but degrades compression.
16337+ */
16338+#ifndef FASTEST
16339+ if (s->match_length <= s->max_insert_length &&
16340+ s->lookahead >= MIN_MATCH) {
16341+ s->match_length--; /* string at strstart already in hash table */
16342+ do {
16343+ s->strstart++;
16344+ INSERT_STRING(s, s->strstart, hash_head);
16345+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
16346+ * always MIN_MATCH bytes ahead.
16347+ */
16348+ } while (--s->match_length != 0);
16349+ s->strstart++;
16350+ } else
16351+#endif
16352+ {
16353+ s->strstart += s->match_length;
16354+ s->match_length = 0;
16355+ s->ins_h = s->window[s->strstart];
16356+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
16357+#if MIN_MATCH != 3
16358+ Call UPDATE_HASH() MIN_MATCH-3 more times
16359+#endif
16360+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
16361+ * matter since it will be recomputed at next deflate call.
16362+ */
16363+ }
16364+ } else {
16365+ /* No match, output a literal byte */
16366+ Tracevv((stderr,"%c", s->window[s->strstart]));
16367+ _tr_tally_lit (s, s->window[s->strstart], bflush);
16368+ s->lookahead--;
16369+ s->strstart++;
16370+ }
16371+ if (bflush) FLUSH_BLOCK(s, 0);
16372+ }
16373+ FLUSH_BLOCK(s, flush == Z_FINISH);
16374+ return flush == Z_FINISH ? finish_done : block_done;
16375+}
16376+
16377+/* ===========================================================================
16378+ * Same as above, but achieves better compression. We use a lazy
16379+ * evaluation for matches: a match is finally adopted only if there is
16380+ * no better match at the next window position.
16381+ */
16382+local block_state deflate_slow(s, flush)
16383+ deflate_state *s;
16384+ int flush;
16385+{
16386+ IPos hash_head = NIL; /* head of hash chain */
16387+ int bflush; /* set if current block must be flushed */
16388+
16389+ /* Process the input block. */
16390+ for (;;) {
16391+ /* Make sure that we always have enough lookahead, except
16392+ * at the end of the input file. We need MAX_MATCH bytes
16393+ * for the next match, plus MIN_MATCH bytes to insert the
16394+ * string following the next match.
16395+ */
16396+ if (s->lookahead < MIN_LOOKAHEAD) {
16397+ fill_window(s);
16398+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
16399+ return need_more;
16400+ }
16401+ if (s->lookahead == 0) break; /* flush the current block */
16402+ }
16403+
16404+ /* Insert the string window[strstart .. strstart+2] in the
16405+ * dictionary, and set hash_head to the head of the hash chain:
16406+ */
16407+ if (s->lookahead >= MIN_MATCH) {
16408+ INSERT_STRING(s, s->strstart, hash_head);
16409+ }
16410+
16411+ /* Find the longest match, discarding those <= prev_length.
16412+ */
16413+ s->prev_length = s->match_length, s->prev_match = s->match_start;
16414+ s->match_length = MIN_MATCH-1;
16415+
16416+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
16417+ s->strstart - hash_head <= MAX_DIST(s)) {
16418+ /* To simplify the code, we prevent matches with the string
16419+ * of window index 0 (in particular we have to avoid a match
16420+ * of the string with itself at the start of the input file).
16421+ */
16422+ if (s->strategy != Z_HUFFMAN_ONLY) {
16423+ s->match_length = longest_match (s, hash_head);
16424+ }
16425+ /* longest_match() sets match_start */
16426+
16427+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
16428+ (s->match_length == MIN_MATCH &&
16429+ s->strstart - s->match_start > TOO_FAR))) {
16430+
16431+ /* If prev_match is also MIN_MATCH, match_start is garbage
16432+ * but we will ignore the current match anyway.
16433+ */
16434+ s->match_length = MIN_MATCH-1;
16435+ }
16436+ }
16437+ /* If there was a match at the previous step and the current
16438+ * match is not better, output the previous match:
16439+ */
16440+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
16441+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
16442+ /* Do not insert strings in hash table beyond this. */
16443+
16444+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
16445+
16446+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
16447+ s->prev_length - MIN_MATCH, bflush);
16448+
16449+ /* Insert in hash table all strings up to the end of the match.
16450+ * strstart-1 and strstart are already inserted. If there is not
16451+ * enough lookahead, the last two strings are not inserted in
16452+ * the hash table.
16453+ */
16454+ s->lookahead -= s->prev_length-1;
16455+ s->prev_length -= 2;
16456+ do {
16457+ if (++s->strstart <= max_insert) {
16458+ INSERT_STRING(s, s->strstart, hash_head);
16459+ }
16460+ } while (--s->prev_length != 0);
16461+ s->match_available = 0;
16462+ s->match_length = MIN_MATCH-1;
16463+ s->strstart++;
16464+
16465+ if (bflush) FLUSH_BLOCK(s, 0);
16466+
16467+ } else if (s->match_available) {
16468+ /* If there was no match at the previous position, output a
16469+ * single literal. If there was a match but the current match
16470+ * is longer, truncate the previous match to a single literal.
16471+ */
16472+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
16473+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
16474+ if (bflush) {
16475+ FLUSH_BLOCK_ONLY(s, 0);
16476+ }
16477+ s->strstart++;
16478+ s->lookahead--;
16479+ if (s->strm->avail_out == 0) return need_more;
16480+ } else {
16481+ /* There is no previous match to compare with, wait for
16482+ * the next step to decide.
16483+ */
16484+ s->match_available = 1;
16485+ s->strstart++;
16486+ s->lookahead--;
16487+ }
16488+ }
16489+ Assert (flush != Z_NO_FLUSH, "no flush?");
16490+ if (s->match_available) {
16491+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
16492+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
16493+ s->match_available = 0;
16494+ }
16495+ FLUSH_BLOCK(s, flush == Z_FINISH);
16496+ return flush == Z_FINISH ? finish_done : block_done;
16497+}
16498--- /dev/null Tue Mar 11 13:02:56 2003
16499+++ linux/net/ipsec/deflate.h Mon Feb 9 13:51:03 2004
16500@@ -0,0 +1,318 @@
16501+/* deflate.h -- internal compression state
16502+ * Copyright (C) 1995-2002 Jean-loup Gailly
16503+ * For conditions of distribution and use, see copyright notice in zlib.h
16504+ */
16505+
16506+/* WARNING: this file should *not* be used by applications. It is
16507+ part of the implementation of the compression library and is
16508+ subject to change. Applications should only use zlib.h.
16509+ */
16510+
16511+/* @(#) $Id: deflate.h,v 1.5 2004-07-10 07:48:38 mcr Exp $ */
16512+
16513+#ifndef _DEFLATE_H
16514+#define _DEFLATE_H
16515+
16516+#include "zlib/zutil.h"
16517+
16518+/* ===========================================================================
16519+ * Internal compression state.
16520+ */
16521+
16522+#define LENGTH_CODES 29
16523+/* number of length codes, not counting the special END_BLOCK code */
16524+
16525+#define LITERALS 256
16526+/* number of literal bytes 0..255 */
16527+
16528+#define L_CODES (LITERALS+1+LENGTH_CODES)
16529+/* number of Literal or Length codes, including the END_BLOCK code */
16530+
16531+#define D_CODES 30
16532+/* number of distance codes */
16533+
16534+#define BL_CODES 19
16535+/* number of codes used to transfer the bit lengths */
16536+
16537+#define HEAP_SIZE (2*L_CODES+1)
16538+/* maximum heap size */
16539+
16540+#define MAX_BITS 15
16541+/* All codes must not exceed MAX_BITS bits */
16542+
16543+#define INIT_STATE 42
16544+#define BUSY_STATE 113
16545+#define FINISH_STATE 666
16546+/* Stream status */
16547+
16548+
16549+/* Data structure describing a single value and its code string. */
16550+typedef struct ct_data_s {
16551+ union {
16552+ ush freq; /* frequency count */
16553+ ush code; /* bit string */
16554+ } fc;
16555+ union {
16556+ ush dad; /* father node in Huffman tree */
16557+ ush len; /* length of bit string */
16558+ } dl;
16559+} FAR ct_data;
16560+
16561+#define Freq fc.freq
16562+#define Code fc.code
16563+#define Dad dl.dad
16564+#define Len dl.len
16565+
16566+typedef struct static_tree_desc_s static_tree_desc;
16567+
16568+typedef struct tree_desc_s {
16569+ ct_data *dyn_tree; /* the dynamic tree */
16570+ int max_code; /* largest code with non zero frequency */
16571+ static_tree_desc *stat_desc; /* the corresponding static tree */
16572+} FAR tree_desc;
16573+
16574+typedef ush Pos;
16575+typedef Pos FAR Posf;
16576+typedef unsigned IPos;
16577+
16578+/* A Pos is an index in the character window. We use short instead of int to
16579+ * save space in the various tables. IPos is used only for parameter passing.
16580+ */
16581+
16582+typedef struct internal_state {
16583+ z_streamp strm; /* pointer back to this zlib stream */
16584+ int status; /* as the name implies */
16585+ Bytef *pending_buf; /* output still pending */
16586+ ulg pending_buf_size; /* size of pending_buf */
16587+ Bytef *pending_out; /* next pending byte to output to the stream */
16588+ int pending; /* nb of bytes in the pending buffer */
16589+ int noheader; /* suppress zlib header and adler32 */
16590+ Byte data_type; /* UNKNOWN, BINARY or ASCII */
16591+ Byte method; /* STORED (for zip only) or DEFLATED */
16592+ int last_flush; /* value of flush param for previous deflate call */
16593+
16594+ /* used by deflate.c: */
16595+
16596+ uInt w_size; /* LZ77 window size (32K by default) */
16597+ uInt w_bits; /* log2(w_size) (8..16) */
16598+ uInt w_mask; /* w_size - 1 */
16599+
16600+ Bytef *window;
16601+ /* Sliding window. Input bytes are read into the second half of the window,
16602+ * and move to the first half later to keep a dictionary of at least wSize
16603+ * bytes. With this organization, matches are limited to a distance of
16604+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
16605+ * performed with a length multiple of the block size. Also, it limits
16606+ * the window size to 64K, which is quite useful on MSDOS.
16607+ * To do: use the user input buffer as sliding window.
16608+ */
16609+
16610+ ulg window_size;
16611+ /* Actual size of window: 2*wSize, except when the user input buffer
16612+ * is directly used as sliding window.
16613+ */
16614+
16615+ Posf *prev;
16616+ /* Link to older string with same hash index. To limit the size of this
16617+ * array to 64K, this link is maintained only for the last 32K strings.
16618+ * An index in this array is thus a window index modulo 32K.
16619+ */
16620+
16621+ Posf *head; /* Heads of the hash chains or NIL. */
16622+
16623+ uInt ins_h; /* hash index of string to be inserted */
16624+ uInt hash_size; /* number of elements in hash table */
16625+ uInt hash_bits; /* log2(hash_size) */
16626+ uInt hash_mask; /* hash_size-1 */
16627+
16628+ uInt hash_shift;
16629+ /* Number of bits by which ins_h must be shifted at each input
16630+ * step. It must be such that after MIN_MATCH steps, the oldest
16631+ * byte no longer takes part in the hash key, that is:
16632+ * hash_shift * MIN_MATCH >= hash_bits
16633+ */
16634+
16635+ long block_start;
16636+ /* Window position at the beginning of the current output block. Gets
16637+ * negative when the window is moved backwards.
16638+ */
16639+
16640+ uInt match_length; /* length of best match */
16641+ IPos prev_match; /* previous match */
16642+ int match_available; /* set if previous match exists */
16643+ uInt strstart; /* start of string to insert */
16644+ uInt match_start; /* start of matching string */
16645+ uInt lookahead; /* number of valid bytes ahead in window */
16646+
16647+ uInt prev_length;
16648+ /* Length of the best match at previous step. Matches not greater than this
16649+ * are discarded. This is used in the lazy match evaluation.
16650+ */
16651+
16652+ uInt max_chain_length;
16653+ /* To speed up deflation, hash chains are never searched beyond this
16654+ * length. A higher limit improves compression ratio but degrades the
16655+ * speed.
16656+ */
16657+
16658+ uInt max_lazy_match;
16659+ /* Attempt to find a better match only when the current match is strictly
16660+ * smaller than this value. This mechanism is used only for compression
16661+ * levels >= 4.
16662+ */
16663+# define max_insert_length max_lazy_match
16664+ /* Insert new strings in the hash table only if the match length is not
16665+ * greater than this length. This saves time but degrades compression.
16666+ * max_insert_length is used only for compression levels <= 3.
16667+ */
16668+
16669+ int level; /* compression level (1..9) */
16670+ int strategy; /* favor or force Huffman coding*/
16671+
16672+ uInt good_match;
16673+ /* Use a faster search when the previous match is longer than this */
16674+
16675+ int nice_match; /* Stop searching when current match exceeds this */
16676+
16677+ /* used by trees.c: */
16678+ /* Didn't use ct_data typedef below to supress compiler warning */
16679+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
16680+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
16681+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
16682+
16683+ struct tree_desc_s l_desc; /* desc. for literal tree */
16684+ struct tree_desc_s d_desc; /* desc. for distance tree */
16685+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
16686+
16687+ ush bl_count[MAX_BITS+1];
16688+ /* number of codes at each bit length for an optimal tree */
16689+
16690+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
16691+ int heap_len; /* number of elements in the heap */
16692+ int heap_max; /* element of largest frequency */
16693+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
16694+ * The same heap array is used to build all trees.
16695+ */
16696+
16697+ uch depth[2*L_CODES+1];
16698+ /* Depth of each subtree used as tie breaker for trees of equal frequency
16699+ */
16700+
16701+ uchf *l_buf; /* buffer for literals or lengths */
16702+
16703+ uInt lit_bufsize;
16704+ /* Size of match buffer for literals/lengths. There are 4 reasons for
16705+ * limiting lit_bufsize to 64K:
16706+ * - frequencies can be kept in 16 bit counters
16707+ * - if compression is not successful for the first block, all input
16708+ * data is still in the window so we can still emit a stored block even
16709+ * when input comes from standard input. (This can also be done for
16710+ * all blocks if lit_bufsize is not greater than 32K.)
16711+ * - if compression is not successful for a file smaller than 64K, we can
16712+ * even emit a stored file instead of a stored block (saving 5 bytes).
16713+ * This is applicable only for zip (not gzip or zlib).
16714+ * - creating new Huffman trees less frequently may not provide fast
16715+ * adaptation to changes in the input data statistics. (Take for
16716+ * example a binary file with poorly compressible code followed by
16717+ * a highly compressible string table.) Smaller buffer sizes give
16718+ * fast adaptation but have of course the overhead of transmitting
16719+ * trees more frequently.
16720+ * - I can't count above 4
16721+ */
16722+
16723+ uInt last_lit; /* running index in l_buf */
16724+
16725+ ushf *d_buf;
16726+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
16727+ * the same number of elements. To use different lengths, an extra flag
16728+ * array would be necessary.
16729+ */
16730+
16731+ ulg opt_len; /* bit length of current block with optimal trees */
16732+ ulg static_len; /* bit length of current block with static trees */
16733+ uInt matches; /* number of string matches in current block */
16734+ int last_eob_len; /* bit length of EOB code for last block */
16735+
16736+#ifdef DEBUG
16737+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
16738+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
16739+#endif
16740+
16741+ ush bi_buf;
16742+ /* Output buffer. bits are inserted starting at the bottom (least
16743+ * significant bits).
16744+ */
16745+ int bi_valid;
16746+ /* Number of valid bits in bi_buf. All bits above the last valid bit
16747+ * are always zero.
16748+ */
16749+
16750+} FAR deflate_state;
16751+
16752+/* Output a byte on the stream.
16753+ * IN assertion: there is enough room in pending_buf.
16754+ */
16755+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
16756+
16757+
16758+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
16759+/* Minimum amount of lookahead, except at the end of the input file.
16760+ * See deflate.c for comments about the MIN_MATCH+1.
16761+ */
16762+
16763+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
16764+/* In order to simplify the code, particularly on 16 bit machines, match
16765+ * distances are limited to MAX_DIST instead of WSIZE.
16766+ */
16767+
16768+ /* in trees.c */
16769+void _tr_init OF((deflate_state *s));
16770+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
16771+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
16772+ int eof));
16773+void _tr_align OF((deflate_state *s));
16774+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
16775+ int eof));
16776+
16777+#define d_code(dist) \
16778+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
16779+/* Mapping from a distance to a distance code. dist is the distance - 1 and
16780+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
16781+ * used.
16782+ */
16783+
16784+#ifndef DEBUG
16785+/* Inline versions of _tr_tally for speed: */
16786+
16787+#if defined(GEN_TREES_H) || !defined(STDC)
16788+ extern uch _length_code[];
16789+ extern uch _dist_code[];
16790+#else
16791+ extern const uch _length_code[];
16792+ extern const uch _dist_code[];
16793+#endif
16794+
16795+# define _tr_tally_lit(s, c, flush) \
16796+ { uch cc = (c); \
16797+ s->d_buf[s->last_lit] = 0; \
16798+ s->l_buf[s->last_lit++] = cc; \
16799+ s->dyn_ltree[cc].Freq++; \
16800+ flush = (s->last_lit == s->lit_bufsize-1); \
16801+ }
16802+# define _tr_tally_dist(s, distance, length, flush) \
16803+ { uch len = (length); \
16804+ ush dist = (distance); \
16805+ s->d_buf[s->last_lit] = dist; \
16806+ s->l_buf[s->last_lit++] = len; \
16807+ dist--; \
16808+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
16809+ s->dyn_dtree[d_code(dist)].Freq++; \
16810+ flush = (s->last_lit == s->lit_bufsize-1); \
16811+ }
16812+#else
16813+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
16814+# define _tr_tally_dist(s, distance, length, flush) \
16815+ flush = _tr_tally(s, distance, length)
16816+#endif
16817+
16818+#endif /* _DEFLATE_H */
16819--- /dev/null Tue Mar 11 13:02:56 2003
16820+++ linux/net/ipsec/des/COPYRIGHT Mon Feb 9 13:51:03 2004
16821@@ -0,0 +1,50 @@
16822+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
16823+All rights reserved.
16824+
16825+This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
16826+The implementation was written so as to conform with MIT's libdes.
16827+
16828+This library is free for commercial and non-commercial use as long as
16829+the following conditions are aheared to. The following conditions
16830+apply to all code found in this distribution.
16831+
16832+Copyright remains Eric Young's, and as such any Copyright notices in
16833+the code are not to be removed.
16834+If this package is used in a product, Eric Young should be given attribution
16835+as the author of that the SSL library. This can be in the form of a textual
16836+message at program startup or in documentation (online or textual) provided
16837+with the package.
16838+
16839+Redistribution and use in source and binary forms, with or without
16840+modification, are permitted provided that the following conditions
16841+are met:
16842+1. Redistributions of source code must retain the copyright
16843+ notice, this list of conditions and the following disclaimer.
16844+2. Redistributions in binary form must reproduce the above copyright
16845+ notice, this list of conditions and the following disclaimer in the
16846+ documentation and/or other materials provided with the distribution.
16847+3. All advertising materials mentioning features or use of this software
16848+ must display the following acknowledgement:
16849+ This product includes software developed by Eric Young (eay@cryptsoft.com)
16850+
16851+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
16852+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16853+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16854+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16855+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16856+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16857+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16858+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16859+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16860+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16861+SUCH DAMAGE.
16862+
16863+The license and distribution terms for any publically available version or
16864+derivative of this code cannot be changed. i.e. this code cannot simply be
16865+copied and put under another distrubution license
16866+[including the GNU Public License.]
16867+
16868+The reason behind this being stated in this direct manner is past
16869+experience in code simply being copied and the attribution removed
16870+from it and then being distributed as part of other packages. This
16871+implementation was a non-trivial and unpaid effort.
16872--- /dev/null Tue Mar 11 13:02:56 2003
16873+++ linux/net/ipsec/des/INSTALL Mon Feb 9 13:51:03 2004
16874@@ -0,0 +1,69 @@
16875+Check the CC and CFLAGS lines in the makefile
16876+
16877+If your C library does not support the times(3) function, change the
16878+#define TIMES to
16879+#undef TIMES in speed.c
16880+If it does, check the HZ value for the times(3) function.
16881+If your system does not define CLK_TCK it will be assumed to
16882+be 100.0.
16883+
16884+If possible use gcc v 2.7.?
16885+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
16886+In recent times, some system compilers give better performace.
16887+
16888+type 'make'
16889+
16890+run './destest' to check things are ok.
16891+run './rpw' to check the tty code for reading passwords works.
16892+run './speed' to see how fast those optimisations make the library run :-)
16893+run './des_opts' to determin the best compile time options.
16894+
16895+The output from des_opts should be put in the makefile options and des_enc.c
16896+should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
16897+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
16898+and then you can use the 'DES_PTR' option.
16899+
16900+The file options.txt has the options listed for best speed on quite a
16901+few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
16902+turn on the relevent option in the Makefile
16903+
16904+There are some special Makefile targets that make life easier.
16905+make cc - standard cc build
16906+make gcc - standard gcc build
16907+make x86-elf - x86 assembler (elf), linux-elf.
16908+make x86-out - x86 assembler (a.out), FreeBSD
16909+make x86-solaris- x86 assembler
16910+make x86-bsdi - x86 assembler (a.out with primative assembler).
16911+
16912+If at all possible use the assembler (for Windows NT/95, use
16913+asm/win32.obj to link with). The x86 assembler is very very fast.
16914+
16915+A make install will by default install
16916+libdes.a in /usr/local/lib/libdes.a
16917+des in /usr/local/bin/des
16918+des_crypt.man in /usr/local/man/man3/des_crypt.3
16919+des.man in /usr/local/man/man1/des.1
16920+des.h in /usr/include/des.h
16921+
16922+des(1) should be compatible with sunOS's but I have been unable to
16923+test it.
16924+
16925+These routines should compile on MSDOS, most 32bit and 64bit version
16926+of Unix (BSD and SYSV) and VMS, without modification.
16927+The only problems should be #include files that are in the wrong places.
16928+
16929+These routines can be compiled under MSDOS.
16930+I have successfully encrypted files using des(1) under MSDOS and then
16931+decrypted the files on a SparcStation.
16932+I have been able to compile and test the routines with
16933+Microsoft C v 5.1 and Turbo C v 2.0.
16934+The code in this library is in no way optimised for the 16bit
16935+operation of MSDOS.
16936+
16937+When building for glibc, ignore all of the above and just unpack into
16938+glibc-1.??/des and then gmake as per normal.
16939+
16940+As a final note on performace. Certain CPUs like sparcs and Alpha often give
16941+a %10 speed difference depending on the link order. It is rather anoying
16942+when one program reports 'x' DES encrypts a second and another reports
16943+'x*0.9' the speed.
16944--- /dev/null Tue Mar 11 13:02:56 2003
16945+++ linux/net/ipsec/des/Makefile Mon Feb 9 13:51:03 2004
16946@@ -0,0 +1,63 @@
16947+# Makefile for KLIPS kernel code as a module for 2.6 kernels
16948+#
16949+# Makefile for KLIPS kernel code as a module
16950+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
16951+# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
16952+#
16953+# This program is free software; you can redistribute it and/or modify it
16954+# under the terms of the GNU General Public License as published by the
16955+# Free Software Foundation; either version 2 of the License, or (at your
16956+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16957+#
16958+# This program is distributed in the hope that it will be useful, but
16959+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16960+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16961+# for more details.
16962+#
16963+# RCSID $Id: Makefile.fs2_6,v 1.2.2.1 2005-08-12 16:10:57 ken Exp $
16964+#
16965+# Note! Dependencies are done automagically by 'make dep', which also
16966+# removes any old dependencies. DON'T put your own dependencies here
16967+# unless it's something special (ie not a .c file).
16968+#
16969+
16970+obj-$(CONFIG_KLIPS_ENC_3DES) += ipsec_alg_3des.o
16971+obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
16972+obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
16973+obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
16974+
16975+ifeq ($(strip ${SUBARCH}),)
16976+SUBARCH:=${ARCH}
16977+endif
16978+
16979+# the assembly version expects frame pointers, which are
16980+# optional in many kernel builds. If you want speed, you should
16981+# probably use cryptoapi code instead.
16982+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
16983+ifeq (${USEASSEMBLY},i386y)
16984+obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
16985+else
16986+obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
16987+endif
16988+
16989+#
16990+# $Log: Makefile.fs2_6,v $
16991+# Revision 1.2.2.1 2005-08-12 16:10:57 ken
16992+# do not use assembly code with there are no frame pointers
16993+#
16994+# Revision 1.3 2005/08/12 14:13:59 mcr
16995+# do not use assembly code with there are no frame pointers,
16996+# as it does not have the right linkages.
16997+#
16998+# Revision 1.2 2005/04/29 05:13:07 mcr
16999+# 3DES algorithm code.
17000+#
17001+# Revision 1.1 2004/08/17 03:27:30 mcr
17002+# klips 2.6 edits.
17003+#
17004+#
17005+# Local Variables:
17006+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
17007+# End Variables:
17008+#
17009+
17010--- /dev/null Tue Mar 11 13:02:56 2003
17011+++ linux/net/ipsec/des/README Mon Feb 9 13:51:03 2004
17012@@ -0,0 +1,54 @@
17013+
17014+ libdes, Version 4.01 10-Jan-97
17015+
17016+ Copyright (c) 1997, Eric Young
17017+ All rights reserved.
17018+
17019+ This program is free software; you can redistribute it and/or modify
17020+ it under the terms specified in COPYRIGHT.
17021+
17022+--
17023+The primary ftp site for this library is
17024+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
17025+libdes is now also shipped with SSLeay. Primary ftp site of
17026+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
17027+
17028+The best way to build this library is to build it as part of SSLeay.
17029+
17030+This kit builds a DES encryption library and a DES encryption program.
17031+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
17032+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
17033+implementation of crypt(3).
17034+It contains support routines to read keys from a terminal,
17035+generate a random key, generate a key from an arbitrary length string,
17036+read/write encrypted data from/to a file descriptor.
17037+
17038+The implementation was written so as to conform with the manual entry
17039+for the des_crypt(3) library routines from MIT's project Athena.
17040+
17041+destest should be run after compilation to test the des routines.
17042+rpw should be run after compilation to test the read password routines.
17043+The des program is a replacement for the sun des command. I believe it
17044+conforms to the sun version.
17045+
17046+The Imakefile is setup for use in the kerberos distribution.
17047+
17048+These routines are best compiled with gcc or any other good
17049+optimising compiler.
17050+Just turn you optimiser up to the highest settings and run destest
17051+after the build to make sure everything works.
17052+
17053+I believe these routines are close to the fastest and most portable DES
17054+routines that use small lookup tables (4.5k) that are publicly available.
17055+The fcrypt routine is faster than ufc's fcrypt (when compiling with
17056+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
17057+(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
17058+[ 10-Jan-97 and a function of an incorrect speed testing program in
17059+ ufc which gave much better test figures that reality ].
17060+
17061+It is worth noting that on sparc and Alpha CPUs, performance of the DES
17062+library can vary by upto %10 due to the positioning of files after application
17063+linkage.
17064+
17065+Eric Young (eay@cryptsoft.com)
17066+
17067--- /dev/null Tue Mar 11 13:02:56 2003
17068+++ linux/net/ipsec/des/README.freeswan Mon Feb 9 13:51:03 2004
17069@@ -0,0 +1,33 @@
17070+The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
17071+
17072+We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
17073+on the Alpha, instead of just noting the issue in a comment.
17074+
17075+We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
17076+use it, and its call to sprintf() can cause subtle difficulties when KLIPS
17077+is built as a module (depending on details of Linux configuration options).
17078+
17079+We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
17080+it cope better with Linux kernel Makefile stupidities, and took out an
17081+explicit CC=gcc (unwise on systems with strange compilers).
17082+
17083+We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
17084+of one function found only in the full libdes (not in libdes-lite), to
17085+avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
17086+Schultz for spotting this and pointing out the fixes.)
17087+
17088+We deleted a couple of .obj files in the asm subdirectory, which appear to
17089+have been included in the original library by accident.
17090+
17091+We have added an include of our Makefile.inc file, to permit overriding
17092+things like choice of compiler (although the libdes Makefile would
17093+probably need some work to make this effective).
17094+
17095+
17096+
17097+Note that Eric Young is no longer at the email address listed in these
17098+files, and is (alas) no longer working on free crypto software.
17099+
17100+
17101+
17102+This file is RCSID $Id: README.freeswan,v 1.12 2004-07-10 08:06:51 mcr Exp $
17103--- /dev/null Tue Mar 11 13:02:56 2003
17104+++ linux/net/ipsec/des/VERSION Mon Feb 9 13:51:03 2004
17105@@ -0,0 +1,406 @@
17106+Version 4.04
17107+ Fixed a few tests in destest. Also added x86 assember for
17108+ des_ncbc_encrypt() which is the standard cbc mode function.
17109+ This makes a very very large performace difference.
17110+ Ariel Glenn ariel@columbia.edu reports that the terminal
17111+ 'turn echo off' can return (errno == EINVAL) under solaris
17112+ when redirection is used. So I now catch that as well as ENOTTY.
17113+
17114+
17115+Version 4.03
17116+ Left a static out of enc_write.c, which caused to buffer to be
17117+ continiously malloc()ed. Does anyone use these functions? I keep
17118+ on feeling like removing them since I only had these in there
17119+ for a version of kerberised login. Anyway, this was pointed out
17120+ by Theo de Raadt <deraadt@cvs.openbsd.org>
17121+ The 'n' bit ofb code was wrong, it was not shifting the shift
17122+ register. It worked correctly for n == 64. Thanks to
17123+ Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
17124+
17125+Version 4.02
17126+ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
17127+ when checking for weak keys which is wrong :-(, pointed out by
17128+ Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
17129+
17130+Version 4.01
17131+ Even faster inner loop in the DES assembler for x86 and a modification
17132+ for IP/FP which is faster on x86. Both of these changes are
17133+ from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
17134+ changes make the assembler run %40 faster on a pentium. This is just
17135+ a case of getting the instruction sequence 'just right'.
17136+ All credit to 'Svend' :-)
17137+ Quite a few special x86 'make' targets.
17138+ A libdes-l (lite) distribution.
17139+
17140+Version 4.00
17141+ After a bit of a pause, I'll up the major version number since this
17142+ is mostly a performace release. I've added x86 assembler and
17143+ added more options for performance. A %28 speedup for gcc
17144+ on a pentium and the assembler is a %50 speedup.
17145+ MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
17146+ Run des_opts to work out which options should be used.
17147+ DES_RISC1/DES_RISC2 use alternative inner loops which use
17148+ more registers but should give speedups on any CPU that does
17149+ dual issue (pentium). DES_UNROLL unrolls the inner loop,
17150+ which costs in code size.
17151+
17152+Version 3.26
17153+ I've finally removed one of the shifts in D_ENCRYPT. This
17154+ meant I've changed the des_SPtrans table (spr.h), the set_key()
17155+ function and some things in des_enc.c. This has definitly
17156+ made things faster :-). I've known about this one for some
17157+ time but I've been too lazy to follow it up :-).
17158+ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
17159+ instead of L^=((..)|(..)|(..).. This should save a register at
17160+ least.
17161+ Assember for x86. The file to replace is des_enc.c, which is replaced
17162+ by one of the assembler files found in asm. Look at des/asm/readme
17163+ for more info.
17164+
17165+ /* Modification to fcrypt so it can be compiled to support
17166+ HPUX 10.x's long password format, define -DLONGCRYPT to use this.
17167+ Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
17168+
17169+ SIGWINCH case put in des_read_passwd() so the function does not
17170+ 'exit' if this function is recieved.
17171+
17172+Version 3.25 17/07/96
17173+ Modified read_pwd.c so that stdin can be read if not a tty.
17174+ Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
17175+ des_init_random_number_generator() shortened due to VMS linker
17176+ limits.
17177+ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
17178+ 8 byte quantites xored before and after encryption.
17179+ des_xcbc_encryption() - the name is funny to preserve the des_
17180+ prefix on all functions.
17181+
17182+Version 3.24 20/04/96
17183+ The DES_PTR macro option checked and used by SSLeay configuration
17184+
17185+Version 3.23 11/04/96
17186+ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
17187+ it gives a %20 speedup :-)
17188+ Fixed the problem with des.pl under perl5. The patches were
17189+ sent by Ed Kubaitis (ejk@uiuc.edu).
17190+ if fcrypt.c, changed values to handle illegal salt values the way
17191+ normal crypt() implementations do. Some programs apparently use
17192+ them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
17193+
17194+Version 3.22 29/11/95
17195+ Bug in des(1), an error with the uuencoding stuff when the
17196+ 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
17197+ for the patch.
17198+
17199+Version 3.21 22/11/95
17200+ After some emailing back and forth with
17201+ Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
17202+ and in a future version I will probably put in some of the
17203+ optimisation he suggested for use with the DES_USE_PTR option.
17204+ Extra routines from Mark Murray <mark@grondar.za> for use in
17205+ freeBSD. They mostly involve random number generation for use
17206+ with kerberos. They involve evil machine specific system calls
17207+ etc so I would normally suggest pushing this stuff into the
17208+ application and/or using RAND_seed()/RAND_bytes() if you are
17209+ using this DES library as part of SSLeay.
17210+ Redone the read_pw() function so that it is cleaner and
17211+ supports termios, thanks to Sameer Parekh <sameer@c2.org>
17212+ for the initial patches for this.
17213+ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
17214+ done just to make things more consistent.
17215+ I have also now added triple DES versions of cfb and ofb.
17216+
17217+Version 3.20
17218+ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
17219+ my des_random_seed() function was only copying 4 bytes of the
17220+ passed seed into the init structure. It is now fixed to copy 8.
17221+ My own suggestion is to used something like MD5 :-)
17222+
17223+Version 3.19
17224+ While looking at my code one day, I though, why do I keep on
17225+ calling des_encrypt(in,out,ks,enc) when every function that
17226+ calls it has in and out the same. So I dropped the 'out'
17227+ parameter, people should not be using this function.
17228+
17229+Version 3.18 30/08/95
17230+ Fixed a few bit with the distribution and the filenames.
17231+ 3.17 had been munged via a move to DOS and back again.
17232+ NO CODE CHANGES
17233+
17234+Version 3.17 14/07/95
17235+ Fixed ede3 cbc which I had broken in 3.16. I have also
17236+ removed some unneeded variables in 7-8 of the routines.
17237+
17238+Version 3.16 26/06/95
17239+ Added des_encrypt2() which does not use IP/FP, used by triple
17240+ des routines. Tweaked things a bit elsewhere. %13 speedup on
17241+ sparc and %6 on a R4400 for ede3 cbc mode.
17242+
17243+Version 3.15 06/06/95
17244+ Added des_ncbc_encrypt(), it is des_cbc mode except that it is
17245+ 'normal' and copies the new iv value back over the top of the
17246+ passed parameter.
17247+ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
17248+ the iv. THIS WILL BREAK EXISTING CODE, but since this function
17249+ only new, I feel I can change it, not so with des_cbc_encrypt :-(.
17250+ I need to update the documentation.
17251+
17252+Version 3.14 31/05/95
17253+ New release upon the world, as part of my SSL implementation.
17254+ New copyright and usage stuff. Basically free for all to use
17255+ as long as you say it came from me :-)
17256+
17257+Version 3.13 31/05/95
17258+ A fix in speed.c, if HZ is not defined, I set it to 100.0
17259+ which is reasonable for most unixes except SunOS 4.x.
17260+ I now have a #ifdef sun but timing for SunOS 4.x looked very
17261+ good :-(. At my last job where I used SunOS 4.x, it was
17262+ defined to be 60.0 (look at the old INSTALL documentation), at
17263+ the last release had it changed to 100.0 since I now work with
17264+ Solaris2 and SVR4 boxes.
17265+ Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
17266+ one out.
17267+
17268+Version 3.12 08/05/95
17269+ As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
17270+ my D_ENCRYPT macro in crypt() had an un-necessary variable.
17271+ It has been removed.
17272+
17273+Version 3.11 03/05/95
17274+ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
17275+ and one iv. It is a standard and I needed it for my SSL code.
17276+ It makes more sense to use this for triple DES than
17277+ 3cbc_encrypt(). I have also added (or should I say tested :-)
17278+ cfb64_encrypt() which is cfb64 but it will encrypt a partial
17279+ number of bytes - 3 bytes in 3 bytes out. Again this is for
17280+ my SSL library, as a form of encryption to use with SSL
17281+ telnet.
17282+
17283+Version 3.10 22/03/95
17284+ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
17285+ to cbc3_encrypt, the 2 iv values that were being returned to
17286+ be used in the next call were reversed :-(.
17287+ Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
17288+ this error.
17289+
17290+Version 3.09 01/02/95
17291+ Fixed des_random_key to far more random, it was rather feeble
17292+ with regards to picking the initial seed. The problem was
17293+ pointed out by Olaf Kirch <okir@monad.swb.de>.
17294+
17295+Version 3.08 14/12/94
17296+ Added Makefile.PL so libdes can be built into perl5.
17297+ Changed des_locl.h so RAND is always defined.
17298+
17299+Version 3.07 05/12/94
17300+ Added GNUmake and stuff so the library can be build with
17301+ glibc.
17302+
17303+Version 3.06 30/08/94
17304+ Added rpc_enc.c which contains _des_crypt. This is for use in
17305+ secure_rpc v 4.0
17306+ Finally fixed the cfb_enc problems.
17307+ Fixed a few parameter parsing bugs in des (-3 and -b), thanks
17308+ to Rob McMillan <R.McMillan@its.gu.edu.au>
17309+
17310+Version 3.05 21/04/94
17311+ for unsigned long l; gcc does not produce ((l>>34) == 0)
17312+ This causes bugs in cfb_enc.
17313+ Thanks to Hadmut Danisch <danisch@ira.uka.de>
17314+
17315+Version 3.04 20/04/94
17316+ Added a version number to des.c and libdes.a
17317+
17318+Version 3.03 12/01/94
17319+ Fixed a bug in non zero iv in 3cbc_enc.
17320+
17321+Version 3.02 29/10/93
17322+ I now work in a place where there are 6+ architectures and 14+
17323+ OS versions :-).
17324+ Fixed TERMIO definition so the most sys V boxes will work :-)
17325+
17326+Release upon comp.sources.misc
17327+Version 3.01 08/10/93
17328+ Added des_3cbc_encrypt()
17329+
17330+Version 3.00 07/10/93
17331+ Fixed up documentation.
17332+ quad_cksum definitely compatible with MIT's now.
17333+
17334+Version 2.30 24/08/93
17335+ Triple DES now defaults to triple cbc but can do triple ecb
17336+ with the -b flag.
17337+ Fixed some MSDOS uuen/uudecoding problems, thanks to
17338+ Added prototypes.
17339+
17340+Version 2.22 29/06/93
17341+ Fixed a bug in des_is_weak_key() which stopped it working :-(
17342+ thanks to engineering@MorningStar.Com.
17343+
17344+Version 2.21 03/06/93
17345+ des(1) with no arguments gives quite a bit of help.
17346+ Added -c (generate ckecksum) flag to des(1).
17347+ Added -3 (triple DES) flag to des(1).
17348+ Added cfb and ofb routines to the library.
17349+
17350+Version 2.20 11/03/93
17351+ Added -u (uuencode) flag to des(1).
17352+ I have been playing with byte order in quad_cksum to make it
17353+ compatible with MIT's version. All I can say is avid this
17354+ function if possible since MIT's output is endian dependent.
17355+
17356+Version 2.12 14/10/92
17357+ Added MSDOS specific macro in ecb_encrypt which gives a %70
17358+ speed up when the code is compiled with turbo C.
17359+
17360+Version 2.11 12/10/92
17361+ Speedup in set_key (recoding of PC-1)
17362+ I now do it in 47 simple operations, down from 60.
17363+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
17364+ for motivating me to look for a faster system :-)
17365+ The speedup is probably less that 1% but it is still 13
17366+ instructions less :-).
17367+
17368+Version 2.10 06/10/92
17369+ The code now works on the 64bit ETA10 and CRAY without modifications or
17370+ #defines. I believe the code should work on any machine that
17371+ defines long, int or short to be 8 bytes long.
17372+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
17373+ for helping me fix the code to run on 64bit machines (he had
17374+ access to an ETA10).
17375+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
17376+ for testing the routines on a CRAY.
17377+ read_password.c has been renamed to read_passwd.c
17378+ string_to_key.c has been renamed to string2key.c
17379+
17380+Version 2.00 14/09/92
17381+ Made mods so that the library should work on 64bit CPU's.
17382+ Removed all my uchar and ulong defs. To many different
17383+ versions of unix define them in their header files in too many
17384+ different combinations :-)
17385+ IRIX - Sillicon Graphics mods (mostly in read_password.c).
17386+ Thanks to Andrew Daviel (advax@erich.triumf.ca)
17387+
17388+Version 1.99 26/08/92
17389+ Fixed a bug or 2 in enc_read.c
17390+ Fixed a bug in enc_write.c
17391+ Fixed a pseudo bug in fcrypt.c (very obscure).
17392+
17393+Version 1.98 31/07/92
17394+ Support for the ETA10. This is a strange machine that defines
17395+ longs and ints as 8 bytes and shorts as 4 bytes.
17396+ Since I do evil things with long * that assume that they are 4
17397+ bytes. Look in the Makefile for the option to compile for
17398+ this machine. quad_cksum appears to have problems but I
17399+ will don't have the time to fix it right now, and this is not
17400+ a function that uses DES and so will not effect the main uses
17401+ of the library.
17402+
17403+Version 1.97 20/05/92 eay
17404+ Fixed the Imakefile and made some changes to des.h to fix some
17405+ problems when building this package with Kerberos v 4.
17406+
17407+Version 1.96 18/05/92 eay
17408+ Fixed a small bug in string_to_key() where problems could
17409+ occur if des_check_key was set to true and the string
17410+ generated a weak key.
17411+
17412+Patch2 posted to comp.sources.misc
17413+Version 1.95 13/05/92 eay
17414+ Added an alternative version of the D_ENCRYPT macro in
17415+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the
17416+ other will be faster. This was inspired by
17417+ Dana How <how@isl.stanford.edu>, and her pointers about doing the
17418+ *(ulong *)((uchar *)ptr+(value&0xfc))
17419+ vs
17420+ ptr[value&0x3f]
17421+ to stop the C compiler doing a <<2 to convert the long array index.
17422+
17423+Version 1.94 05/05/92 eay
17424+ Fixed an incompatibility between my string_to_key and the MIT
17425+ version. When the key is longer than 8 chars, I was wrapping
17426+ with a different method. To use the old version, define
17427+ OLD_STR_TO_KEY in the makefile. Thanks to
17428+ viktor@newsu.shearson.com (Viktor Dukhovni).
17429+
17430+Version 1.93 28/04/92 eay
17431+ Fixed the VMS mods so that echo is now turned off in
17432+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
17433+ MSDOS support added. The routines can be compiled with
17434+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
17435+
17436+Patch1 posted to comp.sources.misc
17437+Version 1.92 13/04/92 eay
17438+ Changed D_ENCRYPT so that the rotation of R occurs outside of
17439+ the loop. This required rotating all the longs in sp.h (now
17440+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
17441+ speed.c has been changed so it will work without SIGALRM. If
17442+ times(3) is not present it will try to use ftime() instead.
17443+
17444+Version 1.91 08/04/92 eay
17445+ Added -E/-D options to des(1) so it can use string_to_key.
17446+ Added SVR4 mods suggested by witr@rwwa.COM
17447+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
17448+ anyone knows how to turn of tty echo in VMS please tell me or
17449+ implement it yourself :-).
17450+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
17451+ does not like IN/OUT being used.
17452+
17453+Libdes posted to comp.sources.misc
17454+Version 1.9 24/03/92 eay
17455+ Now contains a fast small crypt replacement.
17456+ Added des(1) command.
17457+ Added des_rw_mode so people can use cbc encryption with
17458+ enc_read and enc_write.
17459+
17460+Version 1.8 15/10/91 eay
17461+ Bug in cbc_cksum.
17462+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
17463+ one out.
17464+
17465+Version 1.7 24/09/91 eay
17466+ Fixed set_key :-)
17467+ set_key is 4 times faster and takes less space.
17468+ There are a few minor changes that could be made.
17469+
17470+Version 1.6 19/09/1991 eay
17471+ Finally go IP and FP finished.
17472+ Now I need to fix set_key.
17473+ This version is quite a bit faster that 1.51
17474+
17475+Version 1.52 15/06/1991 eay
17476+ 20% speedup in ecb_encrypt by changing the E bit selection
17477+ to use 2 32bit words. This also required modification of the
17478+ sp table. There is still a way to speedup the IP and IP-1
17479+ (hints from outer@sq.com) still working on this one :-(.
17480+
17481+Version 1.51 07/06/1991 eay
17482+ Faster des_encrypt by loop unrolling
17483+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
17484+
17485+Version 1.50 28/05/1991 eay
17486+ Optimised the code a bit more for the sparc. I have improved the
17487+ speed of the inner des_encrypt by speeding up the initial and
17488+ final permutations.
17489+
17490+Version 1.40 23/10/1990 eay
17491+ Fixed des_random_key, it did not produce a random key :-(
17492+
17493+Version 1.30 2/10/1990 eay
17494+ Have made des_quad_cksum the same as MIT's, the full package
17495+ should be compatible with MIT's
17496+ Have tested on a DECstation 3100
17497+ Still need to fix des_set_key (make it faster).
17498+ Does des_cbc_encrypts at 70.5k/sec on a 3100.
17499+
17500+Version 1.20 18/09/1990 eay
17501+ Fixed byte order dependencies.
17502+ Fixed (I hope) all the word alignment problems.
17503+ Speedup in des_ecb_encrypt.
17504+
17505+Version 1.10 11/09/1990 eay
17506+ Added des_enc_read and des_enc_write.
17507+ Still need to fix des_quad_cksum.
17508+ Still need to document des_enc_read and des_enc_write.
17509+
17510+Version 1.00 27/08/1990 eay
17511+
17512--- /dev/null Tue Mar 11 13:02:56 2003
17513+++ linux/net/ipsec/des/asm/des-586.pl Mon Feb 9 13:51:03 2004
17514@@ -0,0 +1,251 @@
17515+#!/usr/local/bin/perl
17516+#
17517+# The inner loop instruction sequence and the IP/FP modifications are from
17518+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
17519+#
17520+
17521+push(@INC,"perlasm","../../perlasm");
17522+require "x86asm.pl";
17523+require "cbc.pl";
17524+require "desboth.pl";
17525+
17526+# base code is in microsft
17527+# op dest, source
17528+# format.
17529+#
17530+
17531+&asm_init($ARGV[0],"des-586.pl");
17532+
17533+$L="edi";
17534+$R="esi";
17535+
17536+&external_label("des_SPtrans");
17537+&des_encrypt("des_encrypt",1);
17538+&des_encrypt("des_encrypt2",0);
17539+&des_encrypt3("des_encrypt3",1);
17540+&des_encrypt3("des_decrypt3",0);
17541+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
17542+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
17543+
17544+&asm_finish();
17545+
17546+sub des_encrypt
17547+ {
17548+ local($name,$do_ip)=@_;
17549+
17550+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
17551+
17552+ &push("esi");
17553+ &push("edi");
17554+
17555+ &comment("");
17556+ &comment("Load the 2 words");
17557+ $ks="ebp";
17558+
17559+ if ($do_ip)
17560+ {
17561+ &mov($R,&wparam(0));
17562+ &xor( "ecx", "ecx" );
17563+
17564+ &push("ebx");
17565+ &push("ebp");
17566+
17567+ &mov("eax",&DWP(0,$R,"",0));
17568+ &mov("ebx",&wparam(2)); # get encrypt flag
17569+ &mov($L,&DWP(4,$R,"",0));
17570+ &comment("");
17571+ &comment("IP");
17572+ &IP_new("eax",$L,$R,3);
17573+ }
17574+ else
17575+ {
17576+ &mov("eax",&wparam(0));
17577+ &xor( "ecx", "ecx" );
17578+
17579+ &push("ebx");
17580+ &push("ebp");
17581+
17582+ &mov($R,&DWP(0,"eax","",0));
17583+ &mov("ebx",&wparam(2)); # get encrypt flag
17584+ &rotl($R,3);
17585+ &mov($L,&DWP(4,"eax","",0));
17586+ &rotl($L,3);
17587+ }
17588+
17589+ &mov( $ks, &wparam(1) );
17590+ &cmp("ebx","0");
17591+ &je(&label("start_decrypt"));
17592+
17593+ for ($i=0; $i<16; $i+=2)
17594+ {
17595+ &comment("");
17596+ &comment("Round $i");
17597+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17598+
17599+ &comment("");
17600+ &comment("Round ".sprintf("%d",$i+1));
17601+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17602+ }
17603+ &jmp(&label("end"));
17604+
17605+ &set_label("start_decrypt");
17606+
17607+ for ($i=15; $i>0; $i-=2)
17608+ {
17609+ &comment("");
17610+ &comment("Round $i");
17611+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17612+ &comment("");
17613+ &comment("Round ".sprintf("%d",$i-1));
17614+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17615+ }
17616+
17617+ &set_label("end");
17618+
17619+ if ($do_ip)
17620+ {
17621+ &comment("");
17622+ &comment("FP");
17623+ &mov("edx",&wparam(0));
17624+ &FP_new($L,$R,"eax",3);
17625+
17626+ &mov(&DWP(0,"edx","",0),"eax");
17627+ &mov(&DWP(4,"edx","",0),$R);
17628+ }
17629+ else
17630+ {
17631+ &comment("");
17632+ &comment("Fixup");
17633+ &rotr($L,3); # r
17634+ &mov("eax",&wparam(0));
17635+ &rotr($R,3); # l
17636+ &mov(&DWP(0,"eax","",0),$L);
17637+ &mov(&DWP(4,"eax","",0),$R);
17638+ }
17639+
17640+ &pop("ebp");
17641+ &pop("ebx");
17642+ &pop("edi");
17643+ &pop("esi");
17644+ &ret();
17645+
17646+ &function_end_B($name);
17647+ }
17648+
17649+sub D_ENCRYPT
17650+ {
17651+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
17652+
17653+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17654+ &xor( $tmp1, $tmp1);
17655+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17656+ &xor( $u, $R);
17657+ &xor( $t, $R);
17658+ &and( $u, "0xfcfcfcfc" );
17659+ &and( $t, "0xcfcfcfcf" );
17660+ &movb( &LB($tmp1), &LB($u) );
17661+ &movb( &LB($tmp2), &HB($u) );
17662+ &rotr( $t, 4 );
17663+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
17664+ &movb( &LB($tmp1), &LB($t) );
17665+ &xor( $L, $ks);
17666+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
17667+ &xor( $L, $ks); ######
17668+ &movb( &LB($tmp2), &HB($t) );
17669+ &shr( $u, 16);
17670+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
17671+ &xor( $L, $ks); ######
17672+ &movb( &LB($tmp1), &HB($u) );
17673+ &shr( $t, 16);
17674+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
17675+ &xor( $L, $ks);
17676+ &mov( $ks, &wparam(1) );
17677+ &movb( &LB($tmp2), &HB($t) );
17678+ &and( $u, "0xff" );
17679+ &and( $t, "0xff" );
17680+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
17681+ &xor( $L, $tmp1);
17682+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
17683+ &xor( $L, $tmp1);
17684+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
17685+ &xor( $L, $tmp1);
17686+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
17687+ &xor( $L, $tmp1);
17688+ }
17689+
17690+sub n2a
17691+ {
17692+ sprintf("%d",$_[0]);
17693+ }
17694+
17695+# now has a side affect of rotating $a by $shift
17696+sub R_PERM_OP
17697+ {
17698+ local($a,$b,$tt,$shift,$mask,$last)=@_;
17699+
17700+ &rotl( $a, $shift ) if ($shift != 0);
17701+ &mov( $tt, $a );
17702+ &xor( $a, $b );
17703+ &and( $a, $mask );
17704+ if (!$last eq $b)
17705+ {
17706+ &xor( $b, $a );
17707+ &xor( $tt, $a );
17708+ }
17709+ else
17710+ {
17711+ &xor( $tt, $a );
17712+ &xor( $b, $a );
17713+ }
17714+ &comment("");
17715+ }
17716+
17717+sub IP_new
17718+ {
17719+ local($l,$r,$tt,$lr)=@_;
17720+
17721+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
17722+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
17723+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
17724+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
17725+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
17726+
17727+ if ($lr != 3)
17728+ {
17729+ if (($lr-3) < 0)
17730+ { &rotr($tt, 3-$lr); }
17731+ else { &rotl($tt, $lr-3); }
17732+ }
17733+ if ($lr != 2)
17734+ {
17735+ if (($lr-2) < 0)
17736+ { &rotr($r, 2-$lr); }
17737+ else { &rotl($r, $lr-2); }
17738+ }
17739+ }
17740+
17741+sub FP_new
17742+ {
17743+ local($l,$r,$tt,$lr)=@_;
17744+
17745+ if ($lr != 2)
17746+ {
17747+ if (($lr-2) < 0)
17748+ { &rotl($r, 2-$lr); }
17749+ else { &rotr($r, $lr-2); }
17750+ }
17751+ if ($lr != 3)
17752+ {
17753+ if (($lr-3) < 0)
17754+ { &rotl($l, 3-$lr); }
17755+ else { &rotr($l, $lr-3); }
17756+ }
17757+
17758+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
17759+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
17760+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
17761+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
17762+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
17763+ &rotr($tt , 4);
17764+ }
17765+
17766--- /dev/null Tue Mar 11 13:02:56 2003
17767+++ linux/net/ipsec/des/asm/des686.pl Mon Feb 9 13:51:03 2004
17768@@ -0,0 +1,230 @@
17769+#!/usr/local/bin/perl
17770+
17771+$prog="des686.pl";
17772+
17773+# base code is in microsft
17774+# op dest, source
17775+# format.
17776+#
17777+
17778+# WILL NOT WORK ANYMORE WITH desboth.pl
17779+require "desboth.pl";
17780+
17781+if ( ($ARGV[0] eq "elf"))
17782+ { require "x86unix.pl"; }
17783+elsif ( ($ARGV[0] eq "a.out"))
17784+ { $aout=1; require "x86unix.pl"; }
17785+elsif ( ($ARGV[0] eq "sol"))
17786+ { $sol=1; require "x86unix.pl"; }
17787+elsif ( ($ARGV[0] eq "cpp"))
17788+ { $cpp=1; require "x86unix.pl"; }
17789+elsif ( ($ARGV[0] eq "win32"))
17790+ { require "x86ms.pl"; }
17791+else
17792+ {
17793+ print STDERR <<"EOF";
17794+Pick one target type from
17795+ elf - linux, FreeBSD etc
17796+ a.out - old linux
17797+ sol - x86 solaris
17798+ cpp - format so x86unix.cpp can be used
17799+ win32 - Windows 95/Windows NT
17800+EOF
17801+ exit(1);
17802+ }
17803+
17804+&comment("Don't even think of reading this code");
17805+&comment("It was automatically generated by $prog");
17806+&comment("Which is a perl program used to generate the x86 assember for");
17807+&comment("any of elf, a.out, Win32, or Solaris");
17808+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
17809+&comment("eric <eay\@cryptsoft.com>");
17810+&comment("");
17811+
17812+&file("dx86xxxx");
17813+
17814+$L="edi";
17815+$R="esi";
17816+
17817+&des_encrypt("des_encrypt",1);
17818+&des_encrypt("des_encrypt2",0);
17819+
17820+&des_encrypt3("des_encrypt3",1);
17821+&des_encrypt3("des_decrypt3",0);
17822+
17823+&file_end();
17824+
17825+sub des_encrypt
17826+ {
17827+ local($name,$do_ip)=@_;
17828+
17829+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
17830+
17831+ &comment("");
17832+ &comment("Load the 2 words");
17833+ &mov("eax",&wparam(0));
17834+ &mov($L,&DWP(0,"eax","",0));
17835+ &mov($R,&DWP(4,"eax","",0));
17836+
17837+ $ksp=&wparam(1);
17838+
17839+ if ($do_ip)
17840+ {
17841+ &comment("");
17842+ &comment("IP");
17843+ &IP_new($L,$R,"eax");
17844+ }
17845+
17846+ &comment("");
17847+ &comment("fixup rotate");
17848+ &rotl($R,3);
17849+ &rotl($L,3);
17850+ &exch($L,$R);
17851+
17852+ &comment("");
17853+ &comment("load counter, key_schedule and enc flag");
17854+ &mov("eax",&wparam(2)); # get encrypt flag
17855+ &mov("ebp",&wparam(1)); # get ks
17856+ &cmp("eax","0");
17857+ &je(&label("start_decrypt"));
17858+
17859+ # encrypting part
17860+
17861+ for ($i=0; $i<16; $i+=2)
17862+ {
17863+ &comment("");
17864+ &comment("Round $i");
17865+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17866+
17867+ &comment("");
17868+ &comment("Round ".sprintf("%d",$i+1));
17869+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17870+ }
17871+ &jmp(&label("end"));
17872+
17873+ &set_label("start_decrypt");
17874+
17875+ for ($i=15; $i>0; $i-=2)
17876+ {
17877+ &comment("");
17878+ &comment("Round $i");
17879+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17880+ &comment("");
17881+ &comment("Round ".sprintf("%d",$i-1));
17882+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17883+ }
17884+
17885+ &set_label("end");
17886+
17887+ &comment("");
17888+ &comment("Fixup");
17889+ &rotr($L,3); # r
17890+ &rotr($R,3); # l
17891+
17892+ if ($do_ip)
17893+ {
17894+ &comment("");
17895+ &comment("FP");
17896+ &FP_new($R,$L,"eax");
17897+ }
17898+
17899+ &mov("eax",&wparam(0));
17900+ &mov(&DWP(0,"eax","",0),$L);
17901+ &mov(&DWP(4,"eax","",0),$R);
17902+
17903+ &function_end($name);
17904+ }
17905+
17906+
17907+# The logic is to load R into 2 registers and operate on both at the same time.
17908+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
17909+# while also masking the other copy and doing a lookup. We then also accumulate the
17910+# L value in 2 registers then combine them at the end.
17911+sub D_ENCRYPT
17912+ {
17913+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
17914+
17915+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17916+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17917+ &xor( $u, $R );
17918+ &xor( $t, $R );
17919+ &rotr( $t, 4 );
17920+
17921+ # the numbers at the end of the line are origional instruction order
17922+ &mov( $tmp2, $u ); # 1 2
17923+ &mov( $tmp1, $t ); # 1 1
17924+ &and( $tmp2, "0xfc" ); # 1 4
17925+ &and( $tmp1, "0xfc" ); # 1 3
17926+ &shr( $t, 8 ); # 1 5
17927+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
17928+ &shr( $u, 8 ); # 1 6
17929+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
17930+
17931+ &mov( $tmp2, $u ); # 2 2
17932+ &xor( $L, $tmp1 ); # 1 9
17933+ &and( $tmp2, "0xfc" ); # 2 4
17934+ &mov( $tmp1, $t ); # 2 1
17935+ &and( $tmp1, "0xfc" ); # 2 3
17936+ &shr( $t, 8 ); # 2 5
17937+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
17938+ &shr( $u, 8 ); # 2 6
17939+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
17940+ &mov( $tmp2, $u ); # 3 2
17941+
17942+ &xor( $L, $tmp1 ); # 2 9
17943+ &and( $tmp2, "0xfc" ); # 3 4
17944+
17945+ &mov( $tmp1, $t ); # 3 1
17946+ &shr( $u, 8 ); # 3 6
17947+ &and( $tmp1, "0xfc" ); # 3 3
17948+ &shr( $t, 8 ); # 3 5
17949+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
17950+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
17951+
17952+ &and( $t, "0xfc" ); # 4 1
17953+ &xor( $L, $tmp1 ); # 3 9
17954+
17955+ &and( $u, "0xfc" ); # 4 2
17956+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
17957+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
17958+ }
17959+
17960+sub PERM_OP
17961+ {
17962+ local($a,$b,$tt,$shift,$mask)=@_;
17963+
17964+ &mov( $tt, $a );
17965+ &shr( $tt, $shift );
17966+ &xor( $tt, $b );
17967+ &and( $tt, $mask );
17968+ &xor( $b, $tt );
17969+ &shl( $tt, $shift );
17970+ &xor( $a, $tt );
17971+ }
17972+
17973+sub IP_new
17974+ {
17975+ local($l,$r,$tt)=@_;
17976+
17977+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
17978+ &PERM_OP($l,$r,$tt,16,"0x0000ffff");
17979+ &PERM_OP($r,$l,$tt, 2,"0x33333333");
17980+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
17981+ &PERM_OP($r,$l,$tt, 1,"0x55555555");
17982+ }
17983+
17984+sub FP_new
17985+ {
17986+ local($l,$r,$tt)=@_;
17987+
17988+ &PERM_OP($l,$r,$tt, 1,"0x55555555");
17989+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
17990+ &PERM_OP($l,$r,$tt, 2,"0x33333333");
17991+ &PERM_OP($r,$l,$tt,16,"0x0000ffff");
17992+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
17993+ }
17994+
17995+sub n2a
17996+ {
17997+ sprintf("%d",$_[0]);
17998+ }
17999--- /dev/null Tue Mar 11 13:02:56 2003
18000+++ linux/net/ipsec/des/asm/desboth.pl Mon Feb 9 13:51:03 2004
18001@@ -0,0 +1,79 @@
18002+#!/usr/local/bin/perl
18003+
18004+$L="edi";
18005+$R="esi";
18006+
18007+sub des_encrypt3
18008+ {
18009+ local($name,$enc)=@_;
18010+
18011+ &function_begin_B($name,"");
18012+ &push("ebx");
18013+ &mov("ebx",&wparam(0));
18014+
18015+ &push("ebp");
18016+ &push("esi");
18017+
18018+ &push("edi");
18019+
18020+ &comment("");
18021+ &comment("Load the data words");
18022+ &mov($L,&DWP(0,"ebx","",0));
18023+ &mov($R,&DWP(4,"ebx","",0));
18024+ &stack_push(3);
18025+
18026+ &comment("");
18027+ &comment("IP");
18028+ &IP_new($L,$R,"edx",0);
18029+
18030+ # put them back
18031+
18032+ if ($enc)
18033+ {
18034+ &mov(&DWP(4,"ebx","",0),$R);
18035+ &mov("eax",&wparam(1));
18036+ &mov(&DWP(0,"ebx","",0),"edx");
18037+ &mov("edi",&wparam(2));
18038+ &mov("esi",&wparam(3));
18039+ }
18040+ else
18041+ {
18042+ &mov(&DWP(4,"ebx","",0),$R);
18043+ &mov("esi",&wparam(1));
18044+ &mov(&DWP(0,"ebx","",0),"edx");
18045+ &mov("edi",&wparam(2));
18046+ &mov("eax",&wparam(3));
18047+ }
18048+ &mov(&swtmp(2), (($enc)?"1":"0"));
18049+ &mov(&swtmp(1), "eax");
18050+ &mov(&swtmp(0), "ebx");
18051+ &call("des_encrypt2");
18052+ &mov(&swtmp(2), (($enc)?"0":"1"));
18053+ &mov(&swtmp(1), "edi");
18054+ &mov(&swtmp(0), "ebx");
18055+ &call("des_encrypt2");
18056+ &mov(&swtmp(2), (($enc)?"1":"0"));
18057+ &mov(&swtmp(1), "esi");
18058+ &mov(&swtmp(0), "ebx");
18059+ &call("des_encrypt2");
18060+
18061+ &stack_pop(3);
18062+ &mov($L,&DWP(0,"ebx","",0));
18063+ &mov($R,&DWP(4,"ebx","",0));
18064+
18065+ &comment("");
18066+ &comment("FP");
18067+ &FP_new($L,$R,"eax",0);
18068+
18069+ &mov(&DWP(0,"ebx","",0),"eax");
18070+ &mov(&DWP(4,"ebx","",0),$R);
18071+
18072+ &pop("edi");
18073+ &pop("esi");
18074+ &pop("ebp");
18075+ &pop("ebx");
18076+ &ret();
18077+ &function_end_B($name);
18078+ }
18079+
18080+
18081--- /dev/null Tue Mar 11 13:02:56 2003
18082+++ linux/net/ipsec/des/asm/readme Mon Feb 9 13:51:03 2004
18083@@ -0,0 +1,131 @@
18084+First up, let me say I don't like writing in assembler. It is not portable,
18085+dependant on the particular CPU architecture release and is generally a pig
18086+to debug and get right. Having said that, the x86 architecture is probably
18087+the most important for speed due to number of boxes and since
18088+it appears to be the worst architecture to to get
18089+good C compilers for. So due to this, I have lowered myself to do
18090+assembler for the inner DES routines in libdes :-).
18091+
18092+The file to implement in assembler is des_enc.c. Replace the following
18093+4 functions
18094+des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
18095+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
18096+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
18097+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
18098+
18099+They encrypt/decrypt the 64 bits held in 'data' using
18100+the 'ks' key schedules. The only difference between the 4 functions is that
18101+des_encrypt2() does not perform IP() or FP() on the data (this is an
18102+optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
18103+perform triple des. The triple DES routines are in here because it does
18104+make a big difference to have them located near the des_encrypt2 function
18105+at link time..
18106+
18107+Now as we all know, there are lots of different operating systems running on
18108+x86 boxes, and unfortunately they normally try to make sure their assembler
18109+formating is not the same as the other peoples.
18110+The 4 main formats I know of are
18111+Microsoft Windows 95/Windows NT
18112+Elf Includes Linux and FreeBSD(?).
18113+a.out The older Linux.
18114+Solaris Same as Elf but different comments :-(.
18115+
18116+Now I was not overly keen to write 4 different copies of the same code,
18117+so I wrote a few perl routines to output the correct assembler, given
18118+a target assembler type. This code is ugly and is just a hack.
18119+The libraries are x86unix.pl and x86ms.pl.
18120+des586.pl, des686.pl and des-som[23].pl are the programs to actually
18121+generate the assembler.
18122+
18123+So to generate elf assembler
18124+perl des-som3.pl elf >dx86-elf.s
18125+For Windows 95/NT
18126+perl des-som2.pl win32 >win32.asm
18127+
18128+[ update 4 Jan 1996 ]
18129+I have added another way to do things.
18130+perl des-som3.pl cpp >dx86-cpp.s
18131+generates a file that will be included by dx86unix.cpp when it is compiled.
18132+To build for elf, a.out, solaris, bsdi etc,
18133+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
18134+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
18135+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
18136+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
18137+This was done to cut down the number of files in the distribution.
18138+
18139+Now the ugly part. I acquired my copy of Intels
18140+"Optimization's For Intel's 32-Bit Processors" and found a few interesting
18141+things. First, the aim of the exersize is to 'extract' one byte at a time
18142+from a word and do an array lookup. This involves getting the byte from
18143+the 4 locations in the word and moving it to a new word and doing the lookup.
18144+The most obvious way to do this is
18145+xor eax, eax # clear word
18146+movb al, cl # get low byte
18147+xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
18148+movb al, ch # get next byte
18149+xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
18150+shr ecx 16
18151+which seems ok. For the pentium, this system appears to be the best.
18152+One has to do instruction interleaving to keep both functional units
18153+operating, but it is basically very efficient.
18154+
18155+Now the crunch. When a full register is used after a partial write, eg.
18156+mov al, cl
18157+xor edi, DWORD PTR 0x100+des_SP[eax]
18158+386 - 1 cycle stall
18159+486 - 1 cycle stall
18160+586 - 0 cycle stall
18161+686 - at least 7 cycle stall (page 22 of the above mentioned document).
18162+
18163+So the technique that produces the best results on a pentium, according to
18164+the documentation, will produce hideous results on a pentium pro.
18165+
18166+To get around this, des686.pl will generate code that is not as fast on
18167+a pentium, should be very good on a pentium pro.
18168+mov eax, ecx # copy word
18169+shr ecx, 8 # line up next byte
18170+and eax, 0fch # mask byte
18171+xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
18172+mov eax, ecx # get word
18173+shr ecx 8 # line up next byte
18174+and eax, 0fch # mask byte
18175+xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
18176+
18177+Due to the execution units in the pentium, this actually works quite well.
18178+For a pentium pro it should be very good. This is the type of output
18179+Visual C++ generates.
18180+
18181+There is a third option. instead of using
18182+mov al, ch
18183+which is bad on the pentium pro, one may be able to use
18184+movzx eax, ch
18185+which may not incur the partial write penalty. On the pentium,
18186+this instruction takes 4 cycles so is not worth using but on the
18187+pentium pro it appears it may be worth while. I need access to one to
18188+experiment :-).
18189+
18190+eric (20 Oct 1996)
18191+
18192+22 Nov 1996 - I have asked people to run the 2 different version on pentium
18193+pros and it appears that the intel documentation is wrong. The
18194+mov al,bh is still faster on a pentium pro, so just use the des586.pl
18195+install des686.pl
18196+
18197+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
18198+functions into des_enc.c because it does make a massive performance
18199+difference on some boxes to have the functions code located close to
18200+the des_encrypt2() function.
18201+
18202+9 Jan 1997 - des-som2.pl is now the correct perl script to use for
18203+pentiums. It contains an inner loop from
18204+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
18205+273,000 per second. He had a previous version at 250,000 and the best
18206+I was able to get was 203,000. The content has not changed, this is all
18207+due to instruction sequencing (and actual instructions choice) which is able
18208+to keep both functional units of the pentium going.
18209+We may have lost the ugly register usage restrictions when x86 went 32 bit
18210+but for the pentium it has been replaced by evil instruction ordering tricks.
18211+
18212+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
18213+raw DES at 281,000 per second on a pentium 100.
18214+
18215--- /dev/null Tue Mar 11 13:02:56 2003
18216+++ linux/net/ipsec/des/cbc_enc.c Mon Feb 9 13:51:03 2004
18217@@ -0,0 +1,135 @@
18218+/* crypto/des/cbc_enc.c */
18219+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18220+ * All rights reserved.
18221+ *
18222+ * This package is an SSL implementation written
18223+ * by Eric Young (eay@cryptsoft.com).
18224+ * The implementation was written so as to conform with Netscapes SSL.
18225+ *
18226+ * This library is free for commercial and non-commercial use as long as
18227+ * the following conditions are aheared to. The following conditions
18228+ * apply to all code found in this distribution, be it the RC4, RSA,
18229+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18230+ * included with this distribution is covered by the same copyright terms
18231+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18232+ *
18233+ * Copyright remains Eric Young's, and as such any Copyright notices in
18234+ * the code are not to be removed.
18235+ * If this package is used in a product, Eric Young should be given attribution
18236+ * as the author of the parts of the library used.
18237+ * This can be in the form of a textual message at program startup or
18238+ * in documentation (online or textual) provided with the package.
18239+ *
18240+ * Redistribution and use in source and binary forms, with or without
18241+ * modification, are permitted provided that the following conditions
18242+ * are met:
18243+ * 1. Redistributions of source code must retain the copyright
18244+ * notice, this list of conditions and the following disclaimer.
18245+ * 2. Redistributions in binary form must reproduce the above copyright
18246+ * notice, this list of conditions and the following disclaimer in the
18247+ * documentation and/or other materials provided with the distribution.
18248+ * 3. All advertising materials mentioning features or use of this software
18249+ * must display the following acknowledgement:
18250+ * "This product includes cryptographic software written by
18251+ * Eric Young (eay@cryptsoft.com)"
18252+ * The word 'cryptographic' can be left out if the rouines from the library
18253+ * being used are not cryptographic related :-).
18254+ * 4. If you include any Windows specific code (or a derivative thereof) from
18255+ * the apps directory (application code) you must include an acknowledgement:
18256+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18257+ *
18258+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18259+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18260+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18261+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18262+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18263+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18264+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18265+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18266+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18267+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18268+ * SUCH DAMAGE.
18269+ *
18270+ * The licence and distribution terms for any publically available version or
18271+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18272+ * copied and put under another distribution licence
18273+ * [including the GNU Public Licence.]
18274+ */
18275+
18276+#include "des/des_locl.h"
18277+
18278+void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
18279+des_cblock (*input);
18280+des_cblock (*output);
18281+long length;
18282+des_key_schedule schedule;
18283+des_cblock (*ivec);
18284+int enc;
18285+ {
18286+ register DES_LONG tin0,tin1;
18287+ register DES_LONG tout0,tout1,xor0,xor1;
18288+ register unsigned char *in,*out;
18289+ register long l=length;
18290+ DES_LONG tin[2];
18291+ unsigned char *iv;
18292+
18293+ in=(unsigned char *)input;
18294+ out=(unsigned char *)output;
18295+ iv=(unsigned char *)ivec;
18296+
18297+ if (enc)
18298+ {
18299+ c2l(iv,tout0);
18300+ c2l(iv,tout1);
18301+ for (l-=8; l>=0; l-=8)
18302+ {
18303+ c2l(in,tin0);
18304+ c2l(in,tin1);
18305+ tin0^=tout0; tin[0]=tin0;
18306+ tin1^=tout1; tin[1]=tin1;
18307+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18308+ tout0=tin[0]; l2c(tout0,out);
18309+ tout1=tin[1]; l2c(tout1,out);
18310+ }
18311+ if (l != -8)
18312+ {
18313+ c2ln(in,tin0,tin1,l+8);
18314+ tin0^=tout0; tin[0]=tin0;
18315+ tin1^=tout1; tin[1]=tin1;
18316+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18317+ tout0=tin[0]; l2c(tout0,out);
18318+ tout1=tin[1]; l2c(tout1,out);
18319+ }
18320+ }
18321+ else
18322+ {
18323+ c2l(iv,xor0);
18324+ c2l(iv,xor1);
18325+ for (l-=8; l>=0; l-=8)
18326+ {
18327+ c2l(in,tin0); tin[0]=tin0;
18328+ c2l(in,tin1); tin[1]=tin1;
18329+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18330+ tout0=tin[0]^xor0;
18331+ tout1=tin[1]^xor1;
18332+ l2c(tout0,out);
18333+ l2c(tout1,out);
18334+ xor0=tin0;
18335+ xor1=tin1;
18336+ }
18337+ if (l != -8)
18338+ {
18339+ c2l(in,tin0); tin[0]=tin0;
18340+ c2l(in,tin1); tin[1]=tin1;
18341+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18342+ tout0=tin[0]^xor0;
18343+ tout1=tin[1]^xor1;
18344+ l2cn(tout0,tout1,out,l+8);
18345+ /* xor0=tin0;
18346+ xor1=tin1; */
18347+ }
18348+ }
18349+ tin0=tin1=tout0=tout1=xor0=xor1=0;
18350+ tin[0]=tin[1]=0;
18351+ }
18352+
18353--- /dev/null Tue Mar 11 13:02:56 2003
18354+++ linux/net/ipsec/des/des.doc Mon Feb 9 13:51:03 2004
18355@@ -0,0 +1,505 @@
18356+The DES library.
18357+
18358+Please note that this library was originally written to operate with
18359+eBones, a version of Kerberos that had had encryption removed when it left
18360+the USA and then put back in. As such there are some routines that I will
18361+advise not using but they are still in the library for historical reasons.
18362+For all calls that have an 'input' and 'output' variables, they can be the
18363+same.
18364+
18365+This library requires the inclusion of 'des.h'.
18366+
18367+All of the encryption functions take what is called a des_key_schedule as an
18368+argument. A des_key_schedule is an expanded form of the des key.
18369+A des_key is 8 bytes of odd parity, the type used to hold the key is a
18370+des_cblock. A des_cblock is an array of 8 bytes, often in this library
18371+description I will refer to input bytes when the function specifies
18372+des_cblock's as input or output, this just means that the variable should
18373+be a multiple of 8 bytes.
18374+
18375+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
18376+specify decryption. The functions and global variable are as follows:
18377+
18378+int des_check_key;
18379+ DES keys are supposed to be odd parity. If this variable is set to
18380+ a non-zero value, des_set_key() will check that the key has odd
18381+ parity and is not one of the known weak DES keys. By default this
18382+ variable is turned off;
18383+
18384+void des_set_odd_parity(
18385+des_cblock *key );
18386+ This function takes a DES key (8 bytes) and sets the parity to odd.
18387+
18388+int des_is_weak_key(
18389+des_cblock *key );
18390+ This function returns a non-zero value if the DES key passed is a
18391+ weak, DES key. If it is a weak key, don't use it, try a different
18392+ one. If you are using 'random' keys, the chances of hitting a weak
18393+ key are 1/2^52 so it is probably not worth checking for them.
18394+
18395+int des_set_key(
18396+des_cblock *key,
18397+des_key_schedule schedule);
18398+ Des_set_key converts an 8 byte DES key into a des_key_schedule.
18399+ A des_key_schedule is an expanded form of the key which is used to
18400+ perform actual encryption. It can be regenerated from the DES key
18401+ so it only needs to be kept when encryption or decryption is about
18402+ to occur. Don't save or pass around des_key_schedule's since they
18403+ are CPU architecture dependent, DES keys are not. If des_check_key
18404+ is non zero, zero is returned if the key has the wrong parity or
18405+ the key is a weak key, else 1 is returned.
18406+
18407+int des_key_sched(
18408+des_cblock *key,
18409+des_key_schedule schedule);
18410+ An alternative name for des_set_key().
18411+
18412+int des_rw_mode; /* defaults to DES_PCBC_MODE */
18413+ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
18414+ This specifies the function to use in the enc_read() and enc_write()
18415+ functions.
18416+
18417+void des_encrypt(
18418+unsigned long *data,
18419+des_key_schedule ks,
18420+int enc);
18421+ This is the DES encryption function that gets called by just about
18422+ every other DES routine in the library. You should not use this
18423+ function except to implement 'modes' of DES. I say this because the
18424+ functions that call this routine do the conversion from 'char *' to
18425+ long, and this needs to be done to make sure 'non-aligned' memory
18426+ access do not occur. The characters are loaded 'little endian',
18427+ have a look at my source code for more details on how I use this
18428+ function.
18429+ Data is a pointer to 2 unsigned long's and ks is the
18430+ des_key_schedule to use. enc, is non zero specifies encryption,
18431+ zero if decryption.
18432+
18433+void des_encrypt2(
18434+unsigned long *data,
18435+des_key_schedule ks,
18436+int enc);
18437+ This functions is the same as des_encrypt() except that the DES
18438+ initial permutation (IP) and final permutation (FP) have been left
18439+ out. As for des_encrypt(), you should not use this function.
18440+ It is used by the routines in my library that implement triple DES.
18441+ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
18442+ as des_encrypt() des_encrypt() des_encrypt() except faster :-).
18443+
18444+void des_ecb_encrypt(
18445+des_cblock *input,
18446+des_cblock *output,
18447+des_key_schedule ks,
18448+int enc);
18449+ This is the basic Electronic Code Book form of DES, the most basic
18450+ form. Input is encrypted into output using the key represented by
18451+ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
18452+ decryption occurs. Input is 8 bytes long and output is 8 bytes.
18453+ (the des_cblock structure is 8 chars).
18454+
18455+void des_ecb3_encrypt(
18456+des_cblock *input,
18457+des_cblock *output,
18458+des_key_schedule ks1,
18459+des_key_schedule ks2,
18460+des_key_schedule ks3,
18461+int enc);
18462+ This is the 3 key EDE mode of ECB DES. What this means is that
18463+ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
18464+ then encrypted again with ks3, before being put into output;
18465+ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
18466+ that only takes 2 des_key_schedules that implements,
18467+ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
18468+
18469+void des_cbc_encrypt(
18470+des_cblock *input,
18471+des_cblock *output,
18472+long length,
18473+des_key_schedule ks,
18474+des_cblock *ivec,
18475+int enc);
18476+ This routine implements DES in Cipher Block Chaining mode.
18477+ Input, which should be a multiple of 8 bytes is encrypted
18478+ (or decrypted) to output which will also be a multiple of 8 bytes.
18479+ The number of bytes is in length (and from what I've said above,
18480+ should be a multiple of 8). If length is not a multiple of 8, I'm
18481+ not being held responsible :-). ivec is the initialisation vector.
18482+ This function does not modify this variable. To correctly implement
18483+ cbc mode, you need to do one of 2 things; copy the last 8 bytes of
18484+ cipher text for use as the next ivec in your application,
18485+ or use des_ncbc_encrypt().
18486+ Only this routine has this problem with updating the ivec, all
18487+ other routines that are implementing cbc mode update ivec.
18488+
18489+void des_ncbc_encrypt(
18490+des_cblock *input,
18491+des_cblock *output,
18492+long length,
18493+des_key_schedule sk,
18494+des_cblock *ivec,
18495+int enc);
18496+ For historical reasons, des_cbc_encrypt() did not update the
18497+ ivec with the value requires so that subsequent calls to
18498+ des_cbc_encrypt() would 'chain'. This was needed so that the same
18499+ 'length' values would not need to be used when decrypting.
18500+ des_ncbc_encrypt() does the right thing. It is the same as
18501+ des_cbc_encrypt accept that ivec is updates with the correct value
18502+ to pass in subsequent calls to des_ncbc_encrypt(). I advise using
18503+ des_ncbc_encrypt() instead of des_cbc_encrypt();
18504+
18505+void des_xcbc_encrypt(
18506+des_cblock *input,
18507+des_cblock *output,
18508+long length,
18509+des_key_schedule sk,
18510+des_cblock *ivec,
18511+des_cblock *inw,
18512+des_cblock *outw,
18513+int enc);
18514+ This is RSA's DESX mode of DES. It uses inw and outw to
18515+ 'whiten' the encryption. inw and outw are secret (unlike the iv)
18516+ and are as such, part of the key. So the key is sort of 24 bytes.
18517+ This is much better than cbc des.
18518+
18519+void des_3cbc_encrypt(
18520+des_cblock *input,
18521+des_cblock *output,
18522+long length,
18523+des_key_schedule sk1,
18524+des_key_schedule sk2,
18525+des_cblock *ivec1,
18526+des_cblock *ivec2,
18527+int enc);
18528+ This function is flawed, do not use it. I have left it in the
18529+ library because it is used in my des(1) program and will function
18530+ correctly when used by des(1). If I removed the function, people
18531+ could end up unable to decrypt files.
18532+ This routine implements outer triple cbc encryption using 2 ks and
18533+ 2 ivec's. Use des_ede2_cbc_encrypt() instead.
18534+
18535+void des_ede3_cbc_encrypt(
18536+des_cblock *input,
18537+des_cblock *output,
18538+long length,
18539+des_key_schedule ks1,
18540+des_key_schedule ks2,
18541+des_key_schedule ks3,
18542+des_cblock *ivec,
18543+int enc);
18544+ This function implements inner triple CBC DES encryption with 3
18545+ keys. What this means is that each 'DES' operation
18546+ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
18547+ Again, this is cbc mode so an ivec is requires.
18548+ This mode is used by SSL.
18549+ There is also a des_ede2_cbc_encrypt() that only uses 2
18550+ des_key_schedule's, the first being reused for the final
18551+ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
18552+ is used by the RSAref library.
18553+
18554+void des_pcbc_encrypt(
18555+des_cblock *input,
18556+des_cblock *output,
18557+long length,
18558+des_key_schedule ks,
18559+des_cblock *ivec,
18560+int enc);
18561+ This is Propagating Cipher Block Chaining mode of DES. It is used
18562+ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
18563+
18564+void des_cfb_encrypt(
18565+unsigned char *in,
18566+unsigned char *out,
18567+int numbits,
18568+long length,
18569+des_key_schedule ks,
18570+des_cblock *ivec,
18571+int enc);
18572+ Cipher Feedback Back mode of DES. This implementation 'feeds back'
18573+ in numbit blocks. The input (and output) is in multiples of numbits
18574+ bits. numbits should to be a multiple of 8 bits. Length is the
18575+ number of bytes input. If numbits is not a multiple of 8 bits,
18576+ the extra bits in the bytes will be considered padding. So if
18577+ numbits is 12, for each 2 input bytes, the 4 high bits of the
18578+ second byte will be ignored. So to encode 72 bits when using
18579+ a numbits of 12 take 12 bytes. To encode 72 bits when using
18580+ numbits of 9 will take 16 bytes. To encode 80 bits when using
18581+ numbits of 16 will take 10 bytes. etc, etc. This padding will
18582+ apply to both input and output.
18583+
18584+
18585+void des_cfb64_encrypt(
18586+unsigned char *in,
18587+unsigned char *out,
18588+long length,
18589+des_key_schedule ks,
18590+des_cblock *ivec,
18591+int *num,
18592+int enc);
18593+ This is one of the more useful functions in this DES library, it
18594+ implements CFB mode of DES with 64bit feedback. Why is this
18595+ useful you ask? Because this routine will allow you to encrypt an
18596+ arbitrary number of bytes, no 8 byte padding. Each call to this
18597+ routine will encrypt the input bytes to output and then update ivec
18598+ and num. num contains 'how far' we are though ivec. If this does
18599+ not make much sense, read more about cfb mode of DES :-).
18600+
18601+void des_ede3_cfb64_encrypt(
18602+unsigned char *in,
18603+unsigned char *out,
18604+long length,
18605+des_key_schedule ks1,
18606+des_key_schedule ks2,
18607+des_key_schedule ks3,
18608+des_cblock *ivec,
18609+int *num,
18610+int enc);
18611+ Same as des_cfb64_encrypt() accept that the DES operation is
18612+ triple DES. As usual, there is a macro for
18613+ des_ede2_cfb64_encrypt() which reuses ks1.
18614+
18615+void des_ofb_encrypt(
18616+unsigned char *in,
18617+unsigned char *out,
18618+int numbits,
18619+long length,
18620+des_key_schedule ks,
18621+des_cblock *ivec);
18622+ This is a implementation of Output Feed Back mode of DES. It is
18623+ the same as des_cfb_encrypt() in that numbits is the size of the
18624+ units dealt with during input and output (in bits).
18625+
18626+void des_ofb64_encrypt(
18627+unsigned char *in,
18628+unsigned char *out,
18629+long length,
18630+des_key_schedule ks,
18631+des_cblock *ivec,
18632+int *num);
18633+ The same as des_cfb64_encrypt() except that it is Output Feed Back
18634+ mode.
18635+
18636+void des_ede3_ofb64_encrypt(
18637+unsigned char *in,
18638+unsigned char *out,
18639+long length,
18640+des_key_schedule ks1,
18641+des_key_schedule ks2,
18642+des_key_schedule ks3,
18643+des_cblock *ivec,
18644+int *num);
18645+ Same as des_ofb64_encrypt() accept that the DES operation is
18646+ triple DES. As usual, there is a macro for
18647+ des_ede2_ofb64_encrypt() which reuses ks1.
18648+
18649+int des_read_pw_string(
18650+char *buf,
18651+int length,
18652+char *prompt,
18653+int verify);
18654+ This routine is used to get a password from the terminal with echo
18655+ turned off. Buf is where the string will end up and length is the
18656+ size of buf. Prompt is a string presented to the 'user' and if
18657+ verify is set, the key is asked for twice and unless the 2 copies
18658+ match, an error is returned. A return code of -1 indicates a
18659+ system error, 1 failure due to use interaction, and 0 is success.
18660+
18661+unsigned long des_cbc_cksum(
18662+des_cblock *input,
18663+des_cblock *output,
18664+long length,
18665+des_key_schedule ks,
18666+des_cblock *ivec);
18667+ This function produces an 8 byte checksum from input that it puts in
18668+ output and returns the last 4 bytes as a long. The checksum is
18669+ generated via cbc mode of DES in which only the last 8 byes are
18670+ kept. I would recommend not using this function but instead using
18671+ the EVP_Digest routines, or at least using MD5 or SHA. This
18672+ function is used by Kerberos v4 so that is why it stays in the
18673+ library.
18674+
18675+char *des_fcrypt(
18676+const char *buf,
18677+const char *salt
18678+char *ret);
18679+ This is my fast version of the unix crypt(3) function. This version
18680+ takes only a small amount of space relative to other fast
18681+ crypt() implementations. This is different to the normal crypt
18682+ in that the third parameter is the buffer that the return value
18683+ is written into. It needs to be at least 14 bytes long. This
18684+ function is thread safe, unlike the normal crypt.
18685+
18686+char *crypt(
18687+const char *buf,
18688+const char *salt);
18689+ This function calls des_fcrypt() with a static array passed as the
18690+ third parameter. This emulates the normal non-thread safe semantics
18691+ of crypt(3).
18692+
18693+void des_string_to_key(
18694+char *str,
18695+des_cblock *key);
18696+ This function takes str and converts it into a DES key. I would
18697+ recommend using MD5 instead and use the first 8 bytes of output.
18698+ When I wrote the first version of these routines back in 1990, MD5
18699+ did not exist but I feel these routines are still sound. This
18700+ routines is compatible with the one in MIT's libdes.
18701+
18702+void des_string_to_2keys(
18703+char *str,
18704+des_cblock *key1,
18705+des_cblock *key2);
18706+ This function takes str and converts it into 2 DES keys.
18707+ I would recommend using MD5 and using the 16 bytes as the 2 keys.
18708+ I have nothing against these 2 'string_to_key' routines, it's just
18709+ that if you say that your encryption key is generated by using the
18710+ 16 bytes of an MD5 hash, every-one knows how you generated your
18711+ keys.
18712+
18713+int des_read_password(
18714+des_cblock *key,
18715+char *prompt,
18716+int verify);
18717+ This routine combines des_read_pw_string() with des_string_to_key().
18718+
18719+int des_read_2passwords(
18720+des_cblock *key1,
18721+des_cblock *key2,
18722+char *prompt,
18723+int verify);
18724+ This routine combines des_read_pw_string() with des_string_to_2key().
18725+
18726+void des_random_seed(
18727+des_cblock key);
18728+ This routine sets a starting point for des_random_key().
18729+
18730+void des_random_key(
18731+des_cblock ret);
18732+ This function return a random key. Make sure to 'seed' the random
18733+ number generator (with des_random_seed()) before using this function.
18734+ I personally now use a MD5 based random number system.
18735+
18736+int des_enc_read(
18737+int fd,
18738+char *buf,
18739+int len,
18740+des_key_schedule ks,
18741+des_cblock *iv);
18742+ This function will write to a file descriptor the encrypted data
18743+ from buf. This data will be preceded by a 4 byte 'byte count' and
18744+ will be padded out to 8 bytes. The encryption is either CBC of
18745+ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
18746+ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
18747+ DES_PCBC_MODE.
18748+
18749+int des_enc_write(
18750+int fd,
18751+char *buf,
18752+int len,
18753+des_key_schedule ks,
18754+des_cblock *iv);
18755+ This routines read stuff written by des_enc_read() and decrypts it.
18756+ I have used these routines quite a lot but I don't believe they are
18757+ suitable for non-blocking io. If you are after a full
18758+ authentication/encryption over networks, have a look at SSL instead.
18759+
18760+unsigned long des_quad_cksum(
18761+des_cblock *input,
18762+des_cblock *output,
18763+long length,
18764+int out_count,
18765+des_cblock *seed);
18766+ This is a function from Kerberos v4 that is not anything to do with
18767+ DES but was needed. It is a cksum that is quicker to generate than
18768+ des_cbc_cksum(); I personally would use MD5 routines now.
18769+=====
18770+Modes of DES
18771+Quite a bit of the following information has been taken from
18772+ AS 2805.5.2
18773+ Australian Standard
18774+ Electronic funds transfer - Requirements for interfaces,
18775+ Part 5.2: Modes of operation for an n-bit block cipher algorithm
18776+ Appendix A
18777+
18778+There are several different modes in which DES can be used, they are
18779+as follows.
18780+
18781+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
18782+- 64 bits are enciphered at a time.
18783+- The order of the blocks can be rearranged without detection.
18784+- The same plaintext block always produces the same ciphertext block
18785+ (for the same key) making it vulnerable to a 'dictionary attack'.
18786+- An error will only affect one ciphertext block.
18787+
18788+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
18789+- a multiple of 64 bits are enciphered at a time.
18790+- The CBC mode produces the same ciphertext whenever the same
18791+ plaintext is encrypted using the same key and starting variable.
18792+- The chaining operation makes the ciphertext blocks dependent on the
18793+ current and all preceding plaintext blocks and therefore blocks can not
18794+ be rearranged.
18795+- The use of different starting variables prevents the same plaintext
18796+ enciphering to the same ciphertext.
18797+- An error will affect the current and the following ciphertext blocks.
18798+
18799+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
18800+- a number of bits (j) <= 64 are enciphered at a time.
18801+- The CFB mode produces the same ciphertext whenever the same
18802+ plaintext is encrypted using the same key and starting variable.
18803+- The chaining operation makes the ciphertext variables dependent on the
18804+ current and all preceding variables and therefore j-bit variables are
18805+ chained together and can not be rearranged.
18806+- The use of different starting variables prevents the same plaintext
18807+ enciphering to the same ciphertext.
18808+- The strength of the CFB mode depends on the size of k (maximal if
18809+ j == k). In my implementation this is always the case.
18810+- Selection of a small value for j will require more cycles through
18811+ the encipherment algorithm per unit of plaintext and thus cause
18812+ greater processing overheads.
18813+- Only multiples of j bits can be enciphered.
18814+- An error will affect the current and the following ciphertext variables.
18815+
18816+Output Feedback Mode (OFB) (des_ofb_encrypt())
18817+- a number of bits (j) <= 64 are enciphered at a time.
18818+- The OFB mode produces the same ciphertext whenever the same
18819+ plaintext enciphered using the same key and starting variable. More
18820+ over, in the OFB mode the same key stream is produced when the same
18821+ key and start variable are used. Consequently, for security reasons
18822+ a specific start variable should be used only once for a given key.
18823+- The absence of chaining makes the OFB more vulnerable to specific attacks.
18824+- The use of different start variables values prevents the same
18825+ plaintext enciphering to the same ciphertext, by producing different
18826+ key streams.
18827+- Selection of a small value for j will require more cycles through
18828+ the encipherment algorithm per unit of plaintext and thus cause
18829+ greater processing overheads.
18830+- Only multiples of j bits can be enciphered.
18831+- OFB mode of operation does not extend ciphertext errors in the
18832+ resultant plaintext output. Every bit error in the ciphertext causes
18833+ only one bit to be in error in the deciphered plaintext.
18834+- OFB mode is not self-synchronising. If the two operation of
18835+ encipherment and decipherment get out of synchronism, the system needs
18836+ to be re-initialised.
18837+- Each re-initialisation should use a value of the start variable
18838+ different from the start variable values used before with the same
18839+ key. The reason for this is that an identical bit stream would be
18840+ produced each time from the same parameters. This would be
18841+ susceptible to a ' known plaintext' attack.
18842+
18843+Triple ECB Mode (des_ecb3_encrypt())
18844+- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
18845+- As for ECB encryption but increases the key length to 168 bits.
18846+ There are theoretic attacks that can be used that make the effective
18847+ key length 112 bits, but this attack also requires 2^56 blocks of
18848+ memory, not very likely, even for the NSA.
18849+- If both keys are the same it is equivalent to encrypting once with
18850+ just one key.
18851+- If the first and last key are the same, the key length is 112 bits.
18852+ There are attacks that could reduce the key space to 55 bit's but it
18853+ requires 2^56 blocks of memory.
18854+- If all 3 keys are the same, this is effectively the same as normal
18855+ ecb mode.
18856+
18857+Triple CBC Mode (des_ede3_cbc_encrypt())
18858+- Encrypt with key1, decrypt with key2 and then encrypt with key3.
18859+- As for CBC encryption but increases the key length to 168 bits with
18860+ the same restrictions as for triple ecb mode.
18861--- /dev/null Tue Mar 11 13:02:56 2003
18862+++ linux/net/ipsec/des/des_enc.c Mon Feb 9 13:51:03 2004
18863@@ -0,0 +1,502 @@
18864+/* crypto/des/des_enc.c */
18865+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18866+ * All rights reserved.
18867+ *
18868+ * This package is an SSL implementation written
18869+ * by Eric Young (eay@cryptsoft.com).
18870+ * The implementation was written so as to conform with Netscapes SSL.
18871+ *
18872+ * This library is free for commercial and non-commercial use as long as
18873+ * the following conditions are aheared to. The following conditions
18874+ * apply to all code found in this distribution, be it the RC4, RSA,
18875+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18876+ * included with this distribution is covered by the same copyright terms
18877+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18878+ *
18879+ * Copyright remains Eric Young's, and as such any Copyright notices in
18880+ * the code are not to be removed.
18881+ * If this package is used in a product, Eric Young should be given attribution
18882+ * as the author of the parts of the library used.
18883+ * This can be in the form of a textual message at program startup or
18884+ * in documentation (online or textual) provided with the package.
18885+ *
18886+ * Redistribution and use in source and binary forms, with or without
18887+ * modification, are permitted provided that the following conditions
18888+ * are met:
18889+ * 1. Redistributions of source code must retain the copyright
18890+ * notice, this list of conditions and the following disclaimer.
18891+ * 2. Redistributions in binary form must reproduce the above copyright
18892+ * notice, this list of conditions and the following disclaimer in the
18893+ * documentation and/or other materials provided with the distribution.
18894+ * 3. All advertising materials mentioning features or use of this software
18895+ * must display the following acknowledgement:
18896+ * "This product includes cryptographic software written by
18897+ * Eric Young (eay@cryptsoft.com)"
18898+ * The word 'cryptographic' can be left out if the rouines from the library
18899+ * being used are not cryptographic related :-).
18900+ * 4. If you include any Windows specific code (or a derivative thereof) from
18901+ * the apps directory (application code) you must include an acknowledgement:
18902+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18903+ *
18904+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18905+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18906+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18907+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18908+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18909+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18910+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18911+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18912+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18913+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18914+ * SUCH DAMAGE.
18915+ *
18916+ * The licence and distribution terms for any publically available version or
18917+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18918+ * copied and put under another distribution licence
18919+ * [including the GNU Public Licence.]
18920+ */
18921+
18922+#include "des/des_locl.h"
18923+
18924+void des_encrypt(data, ks, enc)
18925+DES_LONG *data;
18926+des_key_schedule ks;
18927+int enc;
18928+ {
18929+ register DES_LONG l,r,t,u;
18930+#ifdef DES_PTR
18931+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18932+#endif
18933+#ifndef DES_UNROLL
18934+ register int i;
18935+#endif
18936+ register DES_LONG *s;
18937+
18938+ r=data[0];
18939+ l=data[1];
18940+
18941+ IP(r,l);
18942+ /* Things have been modified so that the initial rotate is
18943+ * done outside the loop. This required the
18944+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18945+ * One perl script later and things have a 5% speed up on a sparc2.
18946+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18947+ * for pointing this out. */
18948+ /* clear the top bits on machines with 8byte longs */
18949+ /* shift left by 2 */
18950+ r=ROTATE(r,29)&0xffffffffL;
18951+ l=ROTATE(l,29)&0xffffffffL;
18952+
18953+ s=(DES_LONG *)ks;
18954+ /* I don't know if it is worth the effort of loop unrolling the
18955+ * inner loop */
18956+ if (enc)
18957+ {
18958+#ifdef DES_UNROLL
18959+ D_ENCRYPT(l,r, 0); /* 1 */
18960+ D_ENCRYPT(r,l, 2); /* 2 */
18961+ D_ENCRYPT(l,r, 4); /* 3 */
18962+ D_ENCRYPT(r,l, 6); /* 4 */
18963+ D_ENCRYPT(l,r, 8); /* 5 */
18964+ D_ENCRYPT(r,l,10); /* 6 */
18965+ D_ENCRYPT(l,r,12); /* 7 */
18966+ D_ENCRYPT(r,l,14); /* 8 */
18967+ D_ENCRYPT(l,r,16); /* 9 */
18968+ D_ENCRYPT(r,l,18); /* 10 */
18969+ D_ENCRYPT(l,r,20); /* 11 */
18970+ D_ENCRYPT(r,l,22); /* 12 */
18971+ D_ENCRYPT(l,r,24); /* 13 */
18972+ D_ENCRYPT(r,l,26); /* 14 */
18973+ D_ENCRYPT(l,r,28); /* 15 */
18974+ D_ENCRYPT(r,l,30); /* 16 */
18975+#else
18976+ for (i=0; i<32; i+=8)
18977+ {
18978+ D_ENCRYPT(l,r,i+0); /* 1 */
18979+ D_ENCRYPT(r,l,i+2); /* 2 */
18980+ D_ENCRYPT(l,r,i+4); /* 3 */
18981+ D_ENCRYPT(r,l,i+6); /* 4 */
18982+ }
18983+#endif
18984+ }
18985+ else
18986+ {
18987+#ifdef DES_UNROLL
18988+ D_ENCRYPT(l,r,30); /* 16 */
18989+ D_ENCRYPT(r,l,28); /* 15 */
18990+ D_ENCRYPT(l,r,26); /* 14 */
18991+ D_ENCRYPT(r,l,24); /* 13 */
18992+ D_ENCRYPT(l,r,22); /* 12 */
18993+ D_ENCRYPT(r,l,20); /* 11 */
18994+ D_ENCRYPT(l,r,18); /* 10 */
18995+ D_ENCRYPT(r,l,16); /* 9 */
18996+ D_ENCRYPT(l,r,14); /* 8 */
18997+ D_ENCRYPT(r,l,12); /* 7 */
18998+ D_ENCRYPT(l,r,10); /* 6 */
18999+ D_ENCRYPT(r,l, 8); /* 5 */
19000+ D_ENCRYPT(l,r, 6); /* 4 */
19001+ D_ENCRYPT(r,l, 4); /* 3 */
19002+ D_ENCRYPT(l,r, 2); /* 2 */
19003+ D_ENCRYPT(r,l, 0); /* 1 */
19004+#else
19005+ for (i=30; i>0; i-=8)
19006+ {
19007+ D_ENCRYPT(l,r,i-0); /* 16 */
19008+ D_ENCRYPT(r,l,i-2); /* 15 */
19009+ D_ENCRYPT(l,r,i-4); /* 14 */
19010+ D_ENCRYPT(r,l,i-6); /* 13 */
19011+ }
19012+#endif
19013+ }
19014+
19015+ /* rotate and clear the top bits on machines with 8byte longs */
19016+ l=ROTATE(l,3)&0xffffffffL;
19017+ r=ROTATE(r,3)&0xffffffffL;
19018+
19019+ FP(r,l);
19020+ data[0]=l;
19021+ data[1]=r;
19022+ l=r=t=u=0;
19023+ }
19024+
19025+void des_encrypt2(data, ks, enc)
19026+DES_LONG *data;
19027+des_key_schedule ks;
19028+int enc;
19029+ {
19030+ register DES_LONG l,r,t,u;
19031+#ifdef DES_PTR
19032+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
19033+#endif
19034+#ifndef DES_UNROLL
19035+ register int i;
19036+#endif
19037+ register DES_LONG *s;
19038+
19039+ r=data[0];
19040+ l=data[1];
19041+
19042+ /* Things have been modified so that the initial rotate is
19043+ * done outside the loop. This required the
19044+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
19045+ * One perl script later and things have a 5% speed up on a sparc2.
19046+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
19047+ * for pointing this out. */
19048+ /* clear the top bits on machines with 8byte longs */
19049+ r=ROTATE(r,29)&0xffffffffL;
19050+ l=ROTATE(l,29)&0xffffffffL;
19051+
19052+ s=(DES_LONG *)ks;
19053+ /* I don't know if it is worth the effort of loop unrolling the
19054+ * inner loop */
19055+ if (enc)
19056+ {
19057+#ifdef DES_UNROLL
19058+ D_ENCRYPT(l,r, 0); /* 1 */
19059+ D_ENCRYPT(r,l, 2); /* 2 */
19060+ D_ENCRYPT(l,r, 4); /* 3 */
19061+ D_ENCRYPT(r,l, 6); /* 4 */
19062+ D_ENCRYPT(l,r, 8); /* 5 */
19063+ D_ENCRYPT(r,l,10); /* 6 */
19064+ D_ENCRYPT(l,r,12); /* 7 */
19065+ D_ENCRYPT(r,l,14); /* 8 */
19066+ D_ENCRYPT(l,r,16); /* 9 */
19067+ D_ENCRYPT(r,l,18); /* 10 */
19068+ D_ENCRYPT(l,r,20); /* 11 */
19069+ D_ENCRYPT(r,l,22); /* 12 */
19070+ D_ENCRYPT(l,r,24); /* 13 */
19071+ D_ENCRYPT(r,l,26); /* 14 */
19072+ D_ENCRYPT(l,r,28); /* 15 */
19073+ D_ENCRYPT(r,l,30); /* 16 */
19074+#else
19075+ for (i=0; i<32; i+=8)
19076+ {
19077+ D_ENCRYPT(l,r,i+0); /* 1 */
19078+ D_ENCRYPT(r,l,i+2); /* 2 */
19079+ D_ENCRYPT(l,r,i+4); /* 3 */
19080+ D_ENCRYPT(r,l,i+6); /* 4 */
19081+ }
19082+#endif
19083+ }
19084+ else
19085+ {
19086+#ifdef DES_UNROLL
19087+ D_ENCRYPT(l,r,30); /* 16 */
19088+ D_ENCRYPT(r,l,28); /* 15 */
19089+ D_ENCRYPT(l,r,26); /* 14 */
19090+ D_ENCRYPT(r,l,24); /* 13 */
19091+ D_ENCRYPT(l,r,22); /* 12 */
19092+ D_ENCRYPT(r,l,20); /* 11 */
19093+ D_ENCRYPT(l,r,18); /* 10 */
19094+ D_ENCRYPT(r,l,16); /* 9 */
19095+ D_ENCRYPT(l,r,14); /* 8 */
19096+ D_ENCRYPT(r,l,12); /* 7 */
19097+ D_ENCRYPT(l,r,10); /* 6 */
19098+ D_ENCRYPT(r,l, 8); /* 5 */
19099+ D_ENCRYPT(l,r, 6); /* 4 */
19100+ D_ENCRYPT(r,l, 4); /* 3 */
19101+ D_ENCRYPT(l,r, 2); /* 2 */
19102+ D_ENCRYPT(r,l, 0); /* 1 */
19103+#else
19104+ for (i=30; i>0; i-=8)
19105+ {
19106+ D_ENCRYPT(l,r,i-0); /* 16 */
19107+ D_ENCRYPT(r,l,i-2); /* 15 */
19108+ D_ENCRYPT(l,r,i-4); /* 14 */
19109+ D_ENCRYPT(r,l,i-6); /* 13 */
19110+ }
19111+#endif
19112+ }
19113+ /* rotate and clear the top bits on machines with 8byte longs */
19114+ data[0]=ROTATE(l,3)&0xffffffffL;
19115+ data[1]=ROTATE(r,3)&0xffffffffL;
19116+ l=r=t=u=0;
19117+ }
19118+
19119+void des_encrypt3(data,ks1,ks2,ks3)
19120+DES_LONG *data;
19121+des_key_schedule ks1;
19122+des_key_schedule ks2;
19123+des_key_schedule ks3;
19124+ {
19125+ register DES_LONG l,r;
19126+
19127+ l=data[0];
19128+ r=data[1];
19129+ IP(l,r);
19130+ data[0]=l;
19131+ data[1]=r;
19132+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
19133+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
19134+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
19135+ l=data[0];
19136+ r=data[1];
19137+ FP(r,l);
19138+ data[0]=l;
19139+ data[1]=r;
19140+ }
19141+
19142+void des_decrypt3(data,ks1,ks2,ks3)
19143+DES_LONG *data;
19144+des_key_schedule ks1;
19145+des_key_schedule ks2;
19146+des_key_schedule ks3;
19147+ {
19148+ register DES_LONG l,r;
19149+
19150+ l=data[0];
19151+ r=data[1];
19152+ IP(l,r);
19153+ data[0]=l;
19154+ data[1]=r;
19155+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
19156+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
19157+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
19158+ l=data[0];
19159+ r=data[1];
19160+ FP(r,l);
19161+ data[0]=l;
19162+ data[1]=r;
19163+ }
19164+
19165+#ifndef DES_DEFAULT_OPTIONS
19166+
19167+void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
19168+des_cblock (*input);
19169+des_cblock (*output);
19170+long length;
19171+des_key_schedule schedule;
19172+des_cblock (*ivec);
19173+int enc;
19174+ {
19175+ register DES_LONG tin0,tin1;
19176+ register DES_LONG tout0,tout1,xor0,xor1;
19177+ register unsigned char *in,*out;
19178+ register long l=length;
19179+ DES_LONG tin[2];
19180+ unsigned char *iv;
19181+
19182+ in=(unsigned char *)input;
19183+ out=(unsigned char *)output;
19184+ iv=(unsigned char *)ivec;
19185+
19186+ if (enc)
19187+ {
19188+ c2l(iv,tout0);
19189+ c2l(iv,tout1);
19190+ for (l-=8; l>=0; l-=8)
19191+ {
19192+ c2l(in,tin0);
19193+ c2l(in,tin1);
19194+ tin0^=tout0; tin[0]=tin0;
19195+ tin1^=tout1; tin[1]=tin1;
19196+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
19197+ tout0=tin[0]; l2c(tout0,out);
19198+ tout1=tin[1]; l2c(tout1,out);
19199+ }
19200+ if (l != -8)
19201+ {
19202+ c2ln(in,tin0,tin1,l+8);
19203+ tin0^=tout0; tin[0]=tin0;
19204+ tin1^=tout1; tin[1]=tin1;
19205+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
19206+ tout0=tin[0]; l2c(tout0,out);
19207+ tout1=tin[1]; l2c(tout1,out);
19208+ }
19209+ iv=(unsigned char *)ivec;
19210+ l2c(tout0,iv);
19211+ l2c(tout1,iv);
19212+ }
19213+ else
19214+ {
19215+ c2l(iv,xor0);
19216+ c2l(iv,xor1);
19217+ for (l-=8; l>=0; l-=8)
19218+ {
19219+ c2l(in,tin0); tin[0]=tin0;
19220+ c2l(in,tin1); tin[1]=tin1;
19221+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
19222+ tout0=tin[0]^xor0;
19223+ tout1=tin[1]^xor1;
19224+ l2c(tout0,out);
19225+ l2c(tout1,out);
19226+ xor0=tin0;
19227+ xor1=tin1;
19228+ }
19229+ if (l != -8)
19230+ {
19231+ c2l(in,tin0); tin[0]=tin0;
19232+ c2l(in,tin1); tin[1]=tin1;
19233+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
19234+ tout0=tin[0]^xor0;
19235+ tout1=tin[1]^xor1;
19236+ l2cn(tout0,tout1,out,l+8);
19237+ xor0=tin0;
19238+ xor1=tin1;
19239+ }
19240+
19241+ iv=(unsigned char *)ivec;
19242+ l2c(xor0,iv);
19243+ l2c(xor1,iv);
19244+ }
19245+ tin0=tin1=tout0=tout1=xor0=xor1=0;
19246+ tin[0]=tin[1]=0;
19247+ }
19248+
19249+void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
19250+des_cblock (*input);
19251+des_cblock (*output);
19252+long length;
19253+des_key_schedule ks1;
19254+des_key_schedule ks2;
19255+des_key_schedule ks3;
19256+des_cblock (*ivec);
19257+int enc;
19258+ {
19259+ register DES_LONG tin0,tin1;
19260+ register DES_LONG tout0,tout1,xor0,xor1;
19261+ register unsigned char *in,*out;
19262+ register long l=length;
19263+ DES_LONG tin[2];
19264+ unsigned char *iv;
19265+
19266+ in=(unsigned char *)input;
19267+ out=(unsigned char *)output;
19268+ iv=(unsigned char *)ivec;
19269+
19270+ if (enc)
19271+ {
19272+ c2l(iv,tout0);
19273+ c2l(iv,tout1);
19274+ for (l-=8; l>=0; l-=8)
19275+ {
19276+ c2l(in,tin0);
19277+ c2l(in,tin1);
19278+ tin0^=tout0;
19279+ tin1^=tout1;
19280+
19281+ tin[0]=tin0;
19282+ tin[1]=tin1;
19283+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19284+ tout0=tin[0];
19285+ tout1=tin[1];
19286+
19287+ l2c(tout0,out);
19288+ l2c(tout1,out);
19289+ }
19290+ if (l != -8)
19291+ {
19292+ c2ln(in,tin0,tin1,l+8);
19293+ tin0^=tout0;
19294+ tin1^=tout1;
19295+
19296+ tin[0]=tin0;
19297+ tin[1]=tin1;
19298+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19299+ tout0=tin[0];
19300+ tout1=tin[1];
19301+
19302+ l2c(tout0,out);
19303+ l2c(tout1,out);
19304+ }
19305+ iv=(unsigned char *)ivec;
19306+ l2c(tout0,iv);
19307+ l2c(tout1,iv);
19308+ }
19309+ else
19310+ {
19311+ register DES_LONG t0,t1;
19312+
19313+ c2l(iv,xor0);
19314+ c2l(iv,xor1);
19315+ for (l-=8; l>=0; l-=8)
19316+ {
19317+ c2l(in,tin0);
19318+ c2l(in,tin1);
19319+
19320+ t0=tin0;
19321+ t1=tin1;
19322+
19323+ tin[0]=tin0;
19324+ tin[1]=tin1;
19325+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19326+ tout0=tin[0];
19327+ tout1=tin[1];
19328+
19329+ tout0^=xor0;
19330+ tout1^=xor1;
19331+ l2c(tout0,out);
19332+ l2c(tout1,out);
19333+ xor0=t0;
19334+ xor1=t1;
19335+ }
19336+ if (l != -8)
19337+ {
19338+ c2l(in,tin0);
19339+ c2l(in,tin1);
19340+
19341+ t0=tin0;
19342+ t1=tin1;
19343+
19344+ tin[0]=tin0;
19345+ tin[1]=tin1;
19346+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19347+ tout0=tin[0];
19348+ tout1=tin[1];
19349+
19350+ tout0^=xor0;
19351+ tout1^=xor1;
19352+ l2cn(tout0,tout1,out,l+8);
19353+ xor0=t0;
19354+ xor1=t1;
19355+ }
19356+
19357+ iv=(unsigned char *)ivec;
19358+ l2c(xor0,iv);
19359+ l2c(xor1,iv);
19360+ }
19361+ tin0=tin1=tout0=tout1=xor0=xor1=0;
19362+ tin[0]=tin[1]=0;
19363+ }
19364+
19365+#endif /* DES_DEFAULT_OPTIONS */
19366--- /dev/null Tue Mar 11 13:02:56 2003
19367+++ linux/net/ipsec/des/des_opts.c Mon Feb 9 13:51:03 2004
19368@@ -0,0 +1,620 @@
19369+/* crypto/des/des_opts.c */
19370+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
19371+ * All rights reserved.
19372+ *
19373+ * This package is an SSL implementation written
19374+ * by Eric Young (eay@cryptsoft.com).
19375+ * The implementation was written so as to conform with Netscapes SSL.
19376+ *
19377+ * This library is free for commercial and non-commercial use as long as
19378+ * the following conditions are aheared to. The following conditions
19379+ * apply to all code found in this distribution, be it the RC4, RSA,
19380+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
19381+ * included with this distribution is covered by the same copyright terms
19382+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
19383+ *
19384+ * Copyright remains Eric Young's, and as such any Copyright notices in
19385+ * the code are not to be removed.
19386+ * If this package is used in a product, Eric Young should be given attribution
19387+ * as the author of the parts of the library used.
19388+ * This can be in the form of a textual message at program startup or
19389+ * in documentation (online or textual) provided with the package.
19390+ *
19391+ * Redistribution and use in source and binary forms, with or without
19392+ * modification, are permitted provided that the following conditions
19393+ * are met:
19394+ * 1. Redistributions of source code must retain the copyright
19395+ * notice, this list of conditions and the following disclaimer.
19396+ * 2. Redistributions in binary form must reproduce the above copyright
19397+ * notice, this list of conditions and the following disclaimer in the
19398+ * documentation and/or other materials provided with the distribution.
19399+ * 3. All advertising materials mentioning features or use of this software
19400+ * must display the following acknowledgement:
19401+ * "This product includes cryptographic software written by
19402+ * Eric Young (eay@cryptsoft.com)"
19403+ * The word 'cryptographic' can be left out if the rouines from the library
19404+ * being used are not cryptographic related :-).
19405+ * 4. If you include any Windows specific code (or a derivative thereof) from
19406+ * the apps directory (application code) you must include an acknowledgement:
19407+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
19408+ *
19409+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
19410+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19411+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19412+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19413+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19414+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19415+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19416+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19417+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19418+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
19419+ * SUCH DAMAGE.
19420+ *
19421+ * The licence and distribution terms for any publically available version or
19422+ * derivative of this code cannot be changed. i.e. this code cannot simply be
19423+ * copied and put under another distribution licence
19424+ * [including the GNU Public Licence.]
19425+ */
19426+
19427+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
19428+ * This is for machines with 64k code segment size restrictions. */
19429+
19430+#ifndef MSDOS
19431+#define TIMES
19432+#endif
19433+
19434+#include <stdio.h>
19435+#ifndef MSDOS
19436+#include <unistd.h>
19437+#else
19438+#include <io.h>
19439+extern void exit();
19440+#endif
19441+#include <signal.h>
19442+#ifndef VMS
19443+#ifndef _IRIX
19444+#include <time.h>
19445+#endif
19446+#ifdef TIMES
19447+#include <sys/types.h>
19448+#include <sys/times.h>
19449+#endif
19450+#else /* VMS */
19451+#include <types.h>
19452+struct tms {
19453+ time_t tms_utime;
19454+ time_t tms_stime;
19455+ time_t tms_uchild; /* I dunno... */
19456+ time_t tms_uchildsys; /* so these names are a guess :-) */
19457+ }
19458+#endif
19459+#ifndef TIMES
19460+#include <sys/timeb.h>
19461+#endif
19462+
19463+#ifdef sun
19464+#include <limits.h>
19465+#include <sys/param.h>
19466+#endif
19467+
19468+#include "des/des_locl.h"
19469+#include "des/spr.h"
19470+
19471+#define DES_DEFAULT_OPTIONS
19472+
19473+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
19474+#define PART1
19475+#define PART2
19476+#define PART3
19477+#define PART4
19478+#endif
19479+
19480+#ifdef PART1
19481+
19482+#undef DES_UNROLL
19483+#undef DES_RISC1
19484+#undef DES_RISC2
19485+#undef DES_PTR
19486+#undef D_ENCRYPT
19487+#define des_encrypt des_encrypt_u4_cisc_idx
19488+#define des_encrypt2 des_encrypt2_u4_cisc_idx
19489+#define des_encrypt3 des_encrypt3_u4_cisc_idx
19490+#define des_decrypt3 des_decrypt3_u4_cisc_idx
19491+#undef HEADER_DES_LOCL_H
19492+#include "des_enc.c"
19493+
19494+#define DES_UNROLL
19495+#undef DES_RISC1
19496+#undef DES_RISC2
19497+#undef DES_PTR
19498+#undef D_ENCRYPT
19499+#undef des_encrypt
19500+#undef des_encrypt2
19501+#undef des_encrypt3
19502+#undef des_decrypt3
19503+#define des_encrypt des_encrypt_u16_cisc_idx
19504+#define des_encrypt2 des_encrypt2_u16_cisc_idx
19505+#define des_encrypt3 des_encrypt3_u16_cisc_idx
19506+#define des_decrypt3 des_decrypt3_u16_cisc_idx
19507+#undef HEADER_DES_LOCL_H
19508+#include "des_enc.c"
19509+
19510+#undef DES_UNROLL
19511+#define DES_RISC1
19512+#undef DES_RISC2
19513+#undef DES_PTR
19514+#undef D_ENCRYPT
19515+#undef des_encrypt
19516+#undef des_encrypt2
19517+#undef des_encrypt3
19518+#undef des_decrypt3
19519+#define des_encrypt des_encrypt_u4_risc1_idx
19520+#define des_encrypt2 des_encrypt2_u4_risc1_idx
19521+#define des_encrypt3 des_encrypt3_u4_risc1_idx
19522+#define des_decrypt3 des_decrypt3_u4_risc1_idx
19523+#undef HEADER_DES_LOCL_H
19524+#include "des_enc.c"
19525+
19526+#endif
19527+
19528+#ifdef PART2
19529+
19530+#undef DES_UNROLL
19531+#undef DES_RISC1
19532+#define DES_RISC2
19533+#undef DES_PTR
19534+#undef D_ENCRYPT
19535+#undef des_encrypt
19536+#undef des_encrypt2
19537+#undef des_encrypt3
19538+#undef des_decrypt3
19539+#define des_encrypt des_encrypt_u4_risc2_idx
19540+#define des_encrypt2 des_encrypt2_u4_risc2_idx
19541+#define des_encrypt3 des_encrypt3_u4_risc2_idx
19542+#define des_decrypt3 des_decrypt3_u4_risc2_idx
19543+#undef HEADER_DES_LOCL_H
19544+#include "des_enc.c"
19545+
19546+#define DES_UNROLL
19547+#define DES_RISC1
19548+#undef DES_RISC2
19549+#undef DES_PTR
19550+#undef D_ENCRYPT
19551+#undef des_encrypt
19552+#undef des_encrypt2
19553+#undef des_encrypt3
19554+#undef des_decrypt3
19555+#define des_encrypt des_encrypt_u16_risc1_idx
19556+#define des_encrypt2 des_encrypt2_u16_risc1_idx
19557+#define des_encrypt3 des_encrypt3_u16_risc1_idx
19558+#define des_decrypt3 des_decrypt3_u16_risc1_idx
19559+#undef HEADER_DES_LOCL_H
19560+#include "des_enc.c"
19561+
19562+#define DES_UNROLL
19563+#undef DES_RISC1
19564+#define DES_RISC2
19565+#undef DES_PTR
19566+#undef D_ENCRYPT
19567+#undef des_encrypt
19568+#undef des_encrypt2
19569+#undef des_encrypt3
19570+#undef des_decrypt3
19571+#define des_encrypt des_encrypt_u16_risc2_idx
19572+#define des_encrypt2 des_encrypt2_u16_risc2_idx
19573+#define des_encrypt3 des_encrypt3_u16_risc2_idx
19574+#define des_decrypt3 des_decrypt3_u16_risc2_idx
19575+#undef HEADER_DES_LOCL_H
19576+#include "des_enc.c"
19577+
19578+#endif
19579+
19580+#ifdef PART3
19581+
19582+#undef DES_UNROLL
19583+#undef DES_RISC1
19584+#undef DES_RISC2
19585+#define DES_PTR
19586+#undef D_ENCRYPT
19587+#undef des_encrypt
19588+#undef des_encrypt2
19589+#undef des_encrypt3
19590+#undef des_decrypt3
19591+#define des_encrypt des_encrypt_u4_cisc_ptr
19592+#define des_encrypt2 des_encrypt2_u4_cisc_ptr
19593+#define des_encrypt3 des_encrypt3_u4_cisc_ptr
19594+#define des_decrypt3 des_decrypt3_u4_cisc_ptr
19595+#undef HEADER_DES_LOCL_H
19596+#include "des_enc.c"
19597+
19598+#define DES_UNROLL
19599+#undef DES_RISC1
19600+#undef DES_RISC2
19601+#define DES_PTR
19602+#undef D_ENCRYPT
19603+#undef des_encrypt
19604+#undef des_encrypt2
19605+#undef des_encrypt3
19606+#undef des_decrypt3
19607+#define des_encrypt des_encrypt_u16_cisc_ptr
19608+#define des_encrypt2 des_encrypt2_u16_cisc_ptr
19609+#define des_encrypt3 des_encrypt3_u16_cisc_ptr
19610+#define des_decrypt3 des_decrypt3_u16_cisc_ptr
19611+#undef HEADER_DES_LOCL_H
19612+#include "des_enc.c"
19613+
19614+#undef DES_UNROLL
19615+#define DES_RISC1
19616+#undef DES_RISC2
19617+#define DES_PTR
19618+#undef D_ENCRYPT
19619+#undef des_encrypt
19620+#undef des_encrypt2
19621+#undef des_encrypt3
19622+#undef des_decrypt3
19623+#define des_encrypt des_encrypt_u4_risc1_ptr
19624+#define des_encrypt2 des_encrypt2_u4_risc1_ptr
19625+#define des_encrypt3 des_encrypt3_u4_risc1_ptr
19626+#define des_decrypt3 des_decrypt3_u4_risc1_ptr
19627+#undef HEADER_DES_LOCL_H
19628+#include "des_enc.c"
19629+
19630+#endif
19631+
19632+#ifdef PART4
19633+
19634+#undef DES_UNROLL
19635+#undef DES_RISC1
19636+#define DES_RISC2
19637+#define DES_PTR
19638+#undef D_ENCRYPT
19639+#undef des_encrypt
19640+#undef des_encrypt2
19641+#undef des_encrypt3
19642+#undef des_decrypt3
19643+#define des_encrypt des_encrypt_u4_risc2_ptr
19644+#define des_encrypt2 des_encrypt2_u4_risc2_ptr
19645+#define des_encrypt3 des_encrypt3_u4_risc2_ptr
19646+#define des_decrypt3 des_decrypt3_u4_risc2_ptr
19647+#undef HEADER_DES_LOCL_H
19648+#include "des_enc.c"
19649+
19650+#define DES_UNROLL
19651+#define DES_RISC1
19652+#undef DES_RISC2
19653+#define DES_PTR
19654+#undef D_ENCRYPT
19655+#undef des_encrypt
19656+#undef des_encrypt2
19657+#undef des_encrypt3
19658+#undef des_decrypt3
19659+#define des_encrypt des_encrypt_u16_risc1_ptr
19660+#define des_encrypt2 des_encrypt2_u16_risc1_ptr
19661+#define des_encrypt3 des_encrypt3_u16_risc1_ptr
19662+#define des_decrypt3 des_decrypt3_u16_risc1_ptr
19663+#undef HEADER_DES_LOCL_H
19664+#include "des_enc.c"
19665+
19666+#define DES_UNROLL
19667+#undef DES_RISC1
19668+#define DES_RISC2
19669+#define DES_PTR
19670+#undef D_ENCRYPT
19671+#undef des_encrypt
19672+#undef des_encrypt2
19673+#undef des_encrypt3
19674+#undef des_decrypt3
19675+#define des_encrypt des_encrypt_u16_risc2_ptr
19676+#define des_encrypt2 des_encrypt2_u16_risc2_ptr
19677+#define des_encrypt3 des_encrypt3_u16_risc2_ptr
19678+#define des_decrypt3 des_decrypt3_u16_risc2_ptr
19679+#undef HEADER_DES_LOCL_H
19680+#include "des_enc.c"
19681+
19682+#endif
19683+
19684+/* The following if from times(3) man page. It may need to be changed */
19685+#ifndef HZ
19686+# ifndef CLK_TCK
19687+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
19688+# ifndef VMS
19689+# define HZ 100.0
19690+# else /* VMS */
19691+# define HZ 100.0
19692+# endif
19693+# else /* _BSD_CLK_TCK_ */
19694+# define HZ ((double)_BSD_CLK_TCK_)
19695+# endif
19696+# else /* CLK_TCK */
19697+# define HZ ((double)CLK_TCK)
19698+# endif
19699+#endif
19700+
19701+#define BUFSIZE ((long)1024)
19702+long run=0;
19703+
19704+#ifndef NOPROTO
19705+double Time_F(int s);
19706+#else
19707+double Time_F();
19708+#endif
19709+
19710+#ifdef SIGALRM
19711+#if defined(__STDC__) || defined(sgi)
19712+#define SIGRETTYPE void
19713+#else
19714+#define SIGRETTYPE int
19715+#endif
19716+
19717+#ifndef NOPROTO
19718+SIGRETTYPE sig_done(int sig);
19719+#else
19720+SIGRETTYPE sig_done();
19721+#endif
19722+
19723+SIGRETTYPE sig_done(sig)
19724+int sig;
19725+ {
19726+ signal(SIGALRM,sig_done);
19727+ run=0;
19728+#ifdef LINT
19729+ sig=sig;
19730+#endif
19731+ }
19732+#endif
19733+
19734+#define START 0
19735+#define STOP 1
19736+
19737+double Time_F(s)
19738+int s;
19739+ {
19740+ double ret;
19741+#ifdef TIMES
19742+ static struct tms tstart,tend;
19743+
19744+ if (s == START)
19745+ {
19746+ times(&tstart);
19747+ return(0);
19748+ }
19749+ else
19750+ {
19751+ times(&tend);
19752+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
19753+ return((ret == 0.0)?1e-6:ret);
19754+ }
19755+#else /* !times() */
19756+ static struct timeb tstart,tend;
19757+ long i;
19758+
19759+ if (s == START)
19760+ {
19761+ ftime(&tstart);
19762+ return(0);
19763+ }
19764+ else
19765+ {
19766+ ftime(&tend);
19767+ i=(long)tend.millitm-(long)tstart.millitm;
19768+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
19769+ return((ret == 0.0)?1e-6:ret);
19770+ }
19771+#endif
19772+ }
19773+
19774+#ifdef SIGALRM
19775+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
19776+#else
19777+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
19778+#endif
19779+
19780+#define time_it(func,name,index) \
19781+ print_name(name); \
19782+ Time_F(START); \
19783+ for (count=0,run=1; COND(cb); count++) \
19784+ { \
19785+ unsigned long d[2]; \
19786+ func(d,&(sch[0]),DES_ENCRYPT); \
19787+ } \
19788+ tm[index]=Time_F(STOP); \
19789+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
19790+ tm[index]=((double)COUNT(cb))/tm[index];
19791+
19792+#define print_it(name,index) \
19793+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
19794+ tm[index]*8,1.0e6/tm[index]);
19795+
19796+int main(argc,argv)
19797+int argc;
19798+char **argv;
19799+ {
19800+ long count;
19801+ static unsigned char buf[BUFSIZE];
19802+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
19803+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
19804+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
19805+ des_key_schedule sch,sch2,sch3;
19806+ double d,tm[16],max=0;
19807+ int rank[16];
19808+ char *str[16];
19809+ int max_idx=0,i,num=0,j;
19810+#ifndef SIGALARM
19811+ long ca,cb,cc,cd,ce;
19812+#endif
19813+
19814+ for (i=0; i<12; i++)
19815+ {
19816+ tm[i]=0.0;
19817+ rank[i]=0;
19818+ }
19819+
19820+#ifndef TIMES
19821+ fprintf(stderr,"To get the most acurate results, try to run this\n");
19822+ fprintf(stderr,"program when this computer is idle.\n");
19823+#endif
19824+
19825+ des_set_key((C_Block *)key,sch);
19826+ des_set_key((C_Block *)key2,sch2);
19827+ des_set_key((C_Block *)key3,sch3);
19828+
19829+#ifndef SIGALRM
19830+ fprintf(stderr,"First we calculate the approximate speed ...\n");
19831+ des_set_key((C_Block *)key,sch);
19832+ count=10;
19833+ do {
19834+ long i;
19835+ unsigned long data[2];
19836+
19837+ count*=2;
19838+ Time_F(START);
19839+ for (i=count; i; i--)
19840+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
19841+ d=Time_F(STOP);
19842+ } while (d < 3.0);
19843+ ca=count;
19844+ cb=count*3;
19845+ cc=count*3*8/BUFSIZE+1;
19846+ cd=count*8/BUFSIZE+1;
19847+
19848+ ce=count/20+1;
19849+#define COND(d) (count != (d))
19850+#define COUNT(d) (d)
19851+#else
19852+#define COND(c) (run)
19853+#define COUNT(d) (count)
19854+ signal(SIGALRM,sig_done);
19855+ alarm(10);
19856+#endif
19857+
19858+#ifdef PART1
19859+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
19860+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
19861+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
19862+ num+=3;
19863+#endif
19864+#ifdef PART2
19865+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
19866+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
19867+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
19868+ num+=3;
19869+#endif
19870+#ifdef PART3
19871+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
19872+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
19873+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
19874+ num+=3;
19875+#endif
19876+#ifdef PART4
19877+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
19878+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
19879+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
19880+ num+=3;
19881+#endif
19882+
19883+#ifdef PART1
19884+ str[0]=" 4 c i";
19885+ print_it("des_encrypt_u4_cisc_idx ",0);
19886+ max=tm[0];
19887+ max_idx=0;
19888+ str[1]="16 c i";
19889+ print_it("des_encrypt_u16_cisc_idx ",1);
19890+ if (max < tm[1]) { max=tm[1]; max_idx=1; }
19891+ str[2]=" 4 r1 i";
19892+ print_it("des_encrypt_u4_risc1_idx ",2);
19893+ if (max < tm[2]) { max=tm[2]; max_idx=2; }
19894+#endif
19895+#ifdef PART2
19896+ str[3]="16 r1 i";
19897+ print_it("des_encrypt_u16_risc1_idx",3);
19898+ if (max < tm[3]) { max=tm[3]; max_idx=3; }
19899+ str[4]=" 4 r2 i";
19900+ print_it("des_encrypt_u4_risc2_idx ",4);
19901+ if (max < tm[4]) { max=tm[4]; max_idx=4; }
19902+ str[5]="16 r2 i";
19903+ print_it("des_encrypt_u16_risc2_idx",5);
19904+ if (max < tm[5]) { max=tm[5]; max_idx=5; }
19905+#endif
19906+#ifdef PART3
19907+ str[6]=" 4 c p";
19908+ print_it("des_encrypt_u4_cisc_ptr ",6);
19909+ if (max < tm[6]) { max=tm[6]; max_idx=6; }
19910+ str[7]="16 c p";
19911+ print_it("des_encrypt_u16_cisc_ptr ",7);
19912+ if (max < tm[7]) { max=tm[7]; max_idx=7; }
19913+ str[8]=" 4 r1 p";
19914+ print_it("des_encrypt_u4_risc1_ptr ",8);
19915+ if (max < tm[8]) { max=tm[8]; max_idx=8; }
19916+#endif
19917+#ifdef PART4
19918+ str[9]="16 r1 p";
19919+ print_it("des_encrypt_u16_risc1_ptr",9);
19920+ if (max < tm[9]) { max=tm[9]; max_idx=9; }
19921+ str[10]=" 4 r2 p";
19922+ print_it("des_encrypt_u4_risc2_ptr ",10);
19923+ if (max < tm[10]) { max=tm[10]; max_idx=10; }
19924+ str[11]="16 r2 p";
19925+ print_it("des_encrypt_u16_risc2_ptr",11);
19926+ if (max < tm[11]) { max=tm[11]; max_idx=11; }
19927+#endif
19928+ printf("options des ecb/s\n");
19929+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
19930+ d=tm[max_idx];
19931+ tm[max_idx]= -2.0;
19932+ max= -1.0;
19933+ for (;;)
19934+ {
19935+ for (i=0; i<12; i++)
19936+ {
19937+ if (max < tm[i]) { max=tm[i]; j=i; }
19938+ }
19939+ if (max < 0.0) break;
19940+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
19941+ tm[j]= -2.0;
19942+ max= -1.0;
19943+ }
19944+
19945+ switch (max_idx)
19946+ {
19947+ case 0:
19948+ printf("-DDES_DEFAULT_OPTIONS\n");
19949+ break;
19950+ case 1:
19951+ printf("-DDES_UNROLL\n");
19952+ break;
19953+ case 2:
19954+ printf("-DDES_RISC1\n");
19955+ break;
19956+ case 3:
19957+ printf("-DDES_UNROLL -DDES_RISC1\n");
19958+ break;
19959+ case 4:
19960+ printf("-DDES_RISC2\n");
19961+ break;
19962+ case 5:
19963+ printf("-DDES_UNROLL -DDES_RISC2\n");
19964+ break;
19965+ case 6:
19966+ printf("-DDES_PTR\n");
19967+ break;
19968+ case 7:
19969+ printf("-DDES_UNROLL -DDES_PTR\n");
19970+ break;
19971+ case 8:
19972+ printf("-DDES_RISC1 -DDES_PTR\n");
19973+ break;
19974+ case 9:
19975+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
19976+ break;
19977+ case 10:
19978+ printf("-DDES_RISC2 -DDES_PTR\n");
19979+ break;
19980+ case 11:
19981+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
19982+ break;
19983+ }
19984+ exit(0);
19985+#if defined(LINT) || defined(MSDOS)
19986+ return(0);
19987+#endif
19988+ }
19989--- /dev/null Tue Mar 11 13:02:56 2003
19990+++ linux/net/ipsec/des/dx86unix.S Mon Feb 9 13:51:03 2004
19991@@ -0,0 +1,3160 @@
19992+/*
19993+ * This file was originally generated by Michael Richardson <mcr@freeswan.org>
19994+ * via the perl scripts found in the ASM subdir. It remains copyright of
19995+ * Eric Young, see the file COPYRIGHT.
19996+ *
19997+ * This was last done on October 9, 2002.
19998+ *
19999+ * While this file does not need to go through cpp, we pass it through
20000+ * CPP by naming it dx86unix.S instead of dx86unix.s because there is
20001+ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
20002+ * which may contain stuff that AS doesn't understand instead of
20003+ * referencing EXTRA_AFLAGS.
20004+ */
20005+
20006+ .file "dx86unix.S"
20007+ .version "01.01"
20008+.text
20009+ .align 16
20010+.globl des_encrypt
20011+ .type des_encrypt , @function
20012+des_encrypt:
20013+ pushl %esi
20014+ pushl %edi
20015+
20016+
20017+ movl 12(%esp), %esi
20018+ xorl %ecx, %ecx
20019+ pushl %ebx
20020+ pushl %ebp
20021+ movl (%esi), %eax
20022+ movl 28(%esp), %ebx
20023+ movl 4(%esi), %edi
20024+
20025+
20026+ roll $4, %eax
20027+ movl %eax, %esi
20028+ xorl %edi, %eax
20029+ andl $0xf0f0f0f0, %eax
20030+ xorl %eax, %esi
20031+ xorl %eax, %edi
20032+
20033+ roll $20, %edi
20034+ movl %edi, %eax
20035+ xorl %esi, %edi
20036+ andl $0xfff0000f, %edi
20037+ xorl %edi, %eax
20038+ xorl %edi, %esi
20039+
20040+ roll $14, %eax
20041+ movl %eax, %edi
20042+ xorl %esi, %eax
20043+ andl $0x33333333, %eax
20044+ xorl %eax, %edi
20045+ xorl %eax, %esi
20046+
20047+ roll $22, %esi
20048+ movl %esi, %eax
20049+ xorl %edi, %esi
20050+ andl $0x03fc03fc, %esi
20051+ xorl %esi, %eax
20052+ xorl %esi, %edi
20053+
20054+ roll $9, %eax
20055+ movl %eax, %esi
20056+ xorl %edi, %eax
20057+ andl $0xaaaaaaaa, %eax
20058+ xorl %eax, %esi
20059+ xorl %eax, %edi
20060+
20061+.byte 209
20062+.byte 199
20063+ movl 24(%esp), %ebp
20064+ cmpl $0, %ebx
20065+ je .L000start_decrypt
20066+
20067+
20068+ movl (%ebp), %eax
20069+ xorl %ebx, %ebx
20070+ movl 4(%ebp), %edx
20071+ xorl %esi, %eax
20072+ xorl %esi, %edx
20073+ andl $0xfcfcfcfc, %eax
20074+ andl $0xcfcfcfcf, %edx
20075+ movb %al, %bl
20076+ movb %ah, %cl
20077+ rorl $4, %edx
20078+ movl des_SPtrans(%ebx),%ebp
20079+ movb %dl, %bl
20080+ xorl %ebp, %edi
20081+ movl 0x200+des_SPtrans(%ecx),%ebp
20082+ xorl %ebp, %edi
20083+ movb %dh, %cl
20084+ shrl $16, %eax
20085+ movl 0x100+des_SPtrans(%ebx),%ebp
20086+ xorl %ebp, %edi
20087+ movb %ah, %bl
20088+ shrl $16, %edx
20089+ movl 0x300+des_SPtrans(%ecx),%ebp
20090+ xorl %ebp, %edi
20091+ movl 24(%esp), %ebp
20092+ movb %dh, %cl
20093+ andl $0xff, %eax
20094+ andl $0xff, %edx
20095+ movl 0x600+des_SPtrans(%ebx),%ebx
20096+ xorl %ebx, %edi
20097+ movl 0x700+des_SPtrans(%ecx),%ebx
20098+ xorl %ebx, %edi
20099+ movl 0x400+des_SPtrans(%eax),%ebx
20100+ xorl %ebx, %edi
20101+ movl 0x500+des_SPtrans(%edx),%ebx
20102+ xorl %ebx, %edi
20103+
20104+
20105+ movl 8(%ebp), %eax
20106+ xorl %ebx, %ebx
20107+ movl 12(%ebp), %edx
20108+ xorl %edi, %eax
20109+ xorl %edi, %edx
20110+ andl $0xfcfcfcfc, %eax
20111+ andl $0xcfcfcfcf, %edx
20112+ movb %al, %bl
20113+ movb %ah, %cl
20114+ rorl $4, %edx
20115+ movl des_SPtrans(%ebx),%ebp
20116+ movb %dl, %bl
20117+ xorl %ebp, %esi
20118+ movl 0x200+des_SPtrans(%ecx),%ebp
20119+ xorl %ebp, %esi
20120+ movb %dh, %cl
20121+ shrl $16, %eax
20122+ movl 0x100+des_SPtrans(%ebx),%ebp
20123+ xorl %ebp, %esi
20124+ movb %ah, %bl
20125+ shrl $16, %edx
20126+ movl 0x300+des_SPtrans(%ecx),%ebp
20127+ xorl %ebp, %esi
20128+ movl 24(%esp), %ebp
20129+ movb %dh, %cl
20130+ andl $0xff, %eax
20131+ andl $0xff, %edx
20132+ movl 0x600+des_SPtrans(%ebx),%ebx
20133+ xorl %ebx, %esi
20134+ movl 0x700+des_SPtrans(%ecx),%ebx
20135+ xorl %ebx, %esi
20136+ movl 0x400+des_SPtrans(%eax),%ebx
20137+ xorl %ebx, %esi
20138+ movl 0x500+des_SPtrans(%edx),%ebx
20139+ xorl %ebx, %esi
20140+
20141+
20142+ movl 16(%ebp), %eax
20143+ xorl %ebx, %ebx
20144+ movl 20(%ebp), %edx
20145+ xorl %esi, %eax
20146+ xorl %esi, %edx
20147+ andl $0xfcfcfcfc, %eax
20148+ andl $0xcfcfcfcf, %edx
20149+ movb %al, %bl
20150+ movb %ah, %cl
20151+ rorl $4, %edx
20152+ movl des_SPtrans(%ebx),%ebp
20153+ movb %dl, %bl
20154+ xorl %ebp, %edi
20155+ movl 0x200+des_SPtrans(%ecx),%ebp
20156+ xorl %ebp, %edi
20157+ movb %dh, %cl
20158+ shrl $16, %eax
20159+ movl 0x100+des_SPtrans(%ebx),%ebp
20160+ xorl %ebp, %edi
20161+ movb %ah, %bl
20162+ shrl $16, %edx
20163+ movl 0x300+des_SPtrans(%ecx),%ebp
20164+ xorl %ebp, %edi
20165+ movl 24(%esp), %ebp
20166+ movb %dh, %cl
20167+ andl $0xff, %eax
20168+ andl $0xff, %edx
20169+ movl 0x600+des_SPtrans(%ebx),%ebx
20170+ xorl %ebx, %edi
20171+ movl 0x700+des_SPtrans(%ecx),%ebx
20172+ xorl %ebx, %edi
20173+ movl 0x400+des_SPtrans(%eax),%ebx
20174+ xorl %ebx, %edi
20175+ movl 0x500+des_SPtrans(%edx),%ebx
20176+ xorl %ebx, %edi
20177+
20178+
20179+ movl 24(%ebp), %eax
20180+ xorl %ebx, %ebx
20181+ movl 28(%ebp), %edx
20182+ xorl %edi, %eax
20183+ xorl %edi, %edx
20184+ andl $0xfcfcfcfc, %eax
20185+ andl $0xcfcfcfcf, %edx
20186+ movb %al, %bl
20187+ movb %ah, %cl
20188+ rorl $4, %edx
20189+ movl des_SPtrans(%ebx),%ebp
20190+ movb %dl, %bl
20191+ xorl %ebp, %esi
20192+ movl 0x200+des_SPtrans(%ecx),%ebp
20193+ xorl %ebp, %esi
20194+ movb %dh, %cl
20195+ shrl $16, %eax
20196+ movl 0x100+des_SPtrans(%ebx),%ebp
20197+ xorl %ebp, %esi
20198+ movb %ah, %bl
20199+ shrl $16, %edx
20200+ movl 0x300+des_SPtrans(%ecx),%ebp
20201+ xorl %ebp, %esi
20202+ movl 24(%esp), %ebp
20203+ movb %dh, %cl
20204+ andl $0xff, %eax
20205+ andl $0xff, %edx
20206+ movl 0x600+des_SPtrans(%ebx),%ebx
20207+ xorl %ebx, %esi
20208+ movl 0x700+des_SPtrans(%ecx),%ebx
20209+ xorl %ebx, %esi
20210+ movl 0x400+des_SPtrans(%eax),%ebx
20211+ xorl %ebx, %esi
20212+ movl 0x500+des_SPtrans(%edx),%ebx
20213+ xorl %ebx, %esi
20214+
20215+
20216+ movl 32(%ebp), %eax
20217+ xorl %ebx, %ebx
20218+ movl 36(%ebp), %edx
20219+ xorl %esi, %eax
20220+ xorl %esi, %edx
20221+ andl $0xfcfcfcfc, %eax
20222+ andl $0xcfcfcfcf, %edx
20223+ movb %al, %bl
20224+ movb %ah, %cl
20225+ rorl $4, %edx
20226+ movl des_SPtrans(%ebx),%ebp
20227+ movb %dl, %bl
20228+ xorl %ebp, %edi
20229+ movl 0x200+des_SPtrans(%ecx),%ebp
20230+ xorl %ebp, %edi
20231+ movb %dh, %cl
20232+ shrl $16, %eax
20233+ movl 0x100+des_SPtrans(%ebx),%ebp
20234+ xorl %ebp, %edi
20235+ movb %ah, %bl
20236+ shrl $16, %edx
20237+ movl 0x300+des_SPtrans(%ecx),%ebp
20238+ xorl %ebp, %edi
20239+ movl 24(%esp), %ebp
20240+ movb %dh, %cl
20241+ andl $0xff, %eax
20242+ andl $0xff, %edx
20243+ movl 0x600+des_SPtrans(%ebx),%ebx
20244+ xorl %ebx, %edi
20245+ movl 0x700+des_SPtrans(%ecx),%ebx
20246+ xorl %ebx, %edi
20247+ movl 0x400+des_SPtrans(%eax),%ebx
20248+ xorl %ebx, %edi
20249+ movl 0x500+des_SPtrans(%edx),%ebx
20250+ xorl %ebx, %edi
20251+
20252+
20253+ movl 40(%ebp), %eax
20254+ xorl %ebx, %ebx
20255+ movl 44(%ebp), %edx
20256+ xorl %edi, %eax
20257+ xorl %edi, %edx
20258+ andl $0xfcfcfcfc, %eax
20259+ andl $0xcfcfcfcf, %edx
20260+ movb %al, %bl
20261+ movb %ah, %cl
20262+ rorl $4, %edx
20263+ movl des_SPtrans(%ebx),%ebp
20264+ movb %dl, %bl
20265+ xorl %ebp, %esi
20266+ movl 0x200+des_SPtrans(%ecx),%ebp
20267+ xorl %ebp, %esi
20268+ movb %dh, %cl
20269+ shrl $16, %eax
20270+ movl 0x100+des_SPtrans(%ebx),%ebp
20271+ xorl %ebp, %esi
20272+ movb %ah, %bl
20273+ shrl $16, %edx
20274+ movl 0x300+des_SPtrans(%ecx),%ebp
20275+ xorl %ebp, %esi
20276+ movl 24(%esp), %ebp
20277+ movb %dh, %cl
20278+ andl $0xff, %eax
20279+ andl $0xff, %edx
20280+ movl 0x600+des_SPtrans(%ebx),%ebx
20281+ xorl %ebx, %esi
20282+ movl 0x700+des_SPtrans(%ecx),%ebx
20283+ xorl %ebx, %esi
20284+ movl 0x400+des_SPtrans(%eax),%ebx
20285+ xorl %ebx, %esi
20286+ movl 0x500+des_SPtrans(%edx),%ebx
20287+ xorl %ebx, %esi
20288+
20289+
20290+ movl 48(%ebp), %eax
20291+ xorl %ebx, %ebx
20292+ movl 52(%ebp), %edx
20293+ xorl %esi, %eax
20294+ xorl %esi, %edx
20295+ andl $0xfcfcfcfc, %eax
20296+ andl $0xcfcfcfcf, %edx
20297+ movb %al, %bl
20298+ movb %ah, %cl
20299+ rorl $4, %edx
20300+ movl des_SPtrans(%ebx),%ebp
20301+ movb %dl, %bl
20302+ xorl %ebp, %edi
20303+ movl 0x200+des_SPtrans(%ecx),%ebp
20304+ xorl %ebp, %edi
20305+ movb %dh, %cl
20306+ shrl $16, %eax
20307+ movl 0x100+des_SPtrans(%ebx),%ebp
20308+ xorl %ebp, %edi
20309+ movb %ah, %bl
20310+ shrl $16, %edx
20311+ movl 0x300+des_SPtrans(%ecx),%ebp
20312+ xorl %ebp, %edi
20313+ movl 24(%esp), %ebp
20314+ movb %dh, %cl
20315+ andl $0xff, %eax
20316+ andl $0xff, %edx
20317+ movl 0x600+des_SPtrans(%ebx),%ebx
20318+ xorl %ebx, %edi
20319+ movl 0x700+des_SPtrans(%ecx),%ebx
20320+ xorl %ebx, %edi
20321+ movl 0x400+des_SPtrans(%eax),%ebx
20322+ xorl %ebx, %edi
20323+ movl 0x500+des_SPtrans(%edx),%ebx
20324+ xorl %ebx, %edi
20325+
20326+
20327+ movl 56(%ebp), %eax
20328+ xorl %ebx, %ebx
20329+ movl 60(%ebp), %edx
20330+ xorl %edi, %eax
20331+ xorl %edi, %edx
20332+ andl $0xfcfcfcfc, %eax
20333+ andl $0xcfcfcfcf, %edx
20334+ movb %al, %bl
20335+ movb %ah, %cl
20336+ rorl $4, %edx
20337+ movl des_SPtrans(%ebx),%ebp
20338+ movb %dl, %bl
20339+ xorl %ebp, %esi
20340+ movl 0x200+des_SPtrans(%ecx),%ebp
20341+ xorl %ebp, %esi
20342+ movb %dh, %cl
20343+ shrl $16, %eax
20344+ movl 0x100+des_SPtrans(%ebx),%ebp
20345+ xorl %ebp, %esi
20346+ movb %ah, %bl
20347+ shrl $16, %edx
20348+ movl 0x300+des_SPtrans(%ecx),%ebp
20349+ xorl %ebp, %esi
20350+ movl 24(%esp), %ebp
20351+ movb %dh, %cl
20352+ andl $0xff, %eax
20353+ andl $0xff, %edx
20354+ movl 0x600+des_SPtrans(%ebx),%ebx
20355+ xorl %ebx, %esi
20356+ movl 0x700+des_SPtrans(%ecx),%ebx
20357+ xorl %ebx, %esi
20358+ movl 0x400+des_SPtrans(%eax),%ebx
20359+ xorl %ebx, %esi
20360+ movl 0x500+des_SPtrans(%edx),%ebx
20361+ xorl %ebx, %esi
20362+
20363+
20364+ movl 64(%ebp), %eax
20365+ xorl %ebx, %ebx
20366+ movl 68(%ebp), %edx
20367+ xorl %esi, %eax
20368+ xorl %esi, %edx
20369+ andl $0xfcfcfcfc, %eax
20370+ andl $0xcfcfcfcf, %edx
20371+ movb %al, %bl
20372+ movb %ah, %cl
20373+ rorl $4, %edx
20374+ movl des_SPtrans(%ebx),%ebp
20375+ movb %dl, %bl
20376+ xorl %ebp, %edi
20377+ movl 0x200+des_SPtrans(%ecx),%ebp
20378+ xorl %ebp, %edi
20379+ movb %dh, %cl
20380+ shrl $16, %eax
20381+ movl 0x100+des_SPtrans(%ebx),%ebp
20382+ xorl %ebp, %edi
20383+ movb %ah, %bl
20384+ shrl $16, %edx
20385+ movl 0x300+des_SPtrans(%ecx),%ebp
20386+ xorl %ebp, %edi
20387+ movl 24(%esp), %ebp
20388+ movb %dh, %cl
20389+ andl $0xff, %eax
20390+ andl $0xff, %edx
20391+ movl 0x600+des_SPtrans(%ebx),%ebx
20392+ xorl %ebx, %edi
20393+ movl 0x700+des_SPtrans(%ecx),%ebx
20394+ xorl %ebx, %edi
20395+ movl 0x400+des_SPtrans(%eax),%ebx
20396+ xorl %ebx, %edi
20397+ movl 0x500+des_SPtrans(%edx),%ebx
20398+ xorl %ebx, %edi
20399+
20400+
20401+ movl 72(%ebp), %eax
20402+ xorl %ebx, %ebx
20403+ movl 76(%ebp), %edx
20404+ xorl %edi, %eax
20405+ xorl %edi, %edx
20406+ andl $0xfcfcfcfc, %eax
20407+ andl $0xcfcfcfcf, %edx
20408+ movb %al, %bl
20409+ movb %ah, %cl
20410+ rorl $4, %edx
20411+ movl des_SPtrans(%ebx),%ebp
20412+ movb %dl, %bl
20413+ xorl %ebp, %esi
20414+ movl 0x200+des_SPtrans(%ecx),%ebp
20415+ xorl %ebp, %esi
20416+ movb %dh, %cl
20417+ shrl $16, %eax
20418+ movl 0x100+des_SPtrans(%ebx),%ebp
20419+ xorl %ebp, %esi
20420+ movb %ah, %bl
20421+ shrl $16, %edx
20422+ movl 0x300+des_SPtrans(%ecx),%ebp
20423+ xorl %ebp, %esi
20424+ movl 24(%esp), %ebp
20425+ movb %dh, %cl
20426+ andl $0xff, %eax
20427+ andl $0xff, %edx
20428+ movl 0x600+des_SPtrans(%ebx),%ebx
20429+ xorl %ebx, %esi
20430+ movl 0x700+des_SPtrans(%ecx),%ebx
20431+ xorl %ebx, %esi
20432+ movl 0x400+des_SPtrans(%eax),%ebx
20433+ xorl %ebx, %esi
20434+ movl 0x500+des_SPtrans(%edx),%ebx
20435+ xorl %ebx, %esi
20436+
20437+
20438+ movl 80(%ebp), %eax
20439+ xorl %ebx, %ebx
20440+ movl 84(%ebp), %edx
20441+ xorl %esi, %eax
20442+ xorl %esi, %edx
20443+ andl $0xfcfcfcfc, %eax
20444+ andl $0xcfcfcfcf, %edx
20445+ movb %al, %bl
20446+ movb %ah, %cl
20447+ rorl $4, %edx
20448+ movl des_SPtrans(%ebx),%ebp
20449+ movb %dl, %bl
20450+ xorl %ebp, %edi
20451+ movl 0x200+des_SPtrans(%ecx),%ebp
20452+ xorl %ebp, %edi
20453+ movb %dh, %cl
20454+ shrl $16, %eax
20455+ movl 0x100+des_SPtrans(%ebx),%ebp
20456+ xorl %ebp, %edi
20457+ movb %ah, %bl
20458+ shrl $16, %edx
20459+ movl 0x300+des_SPtrans(%ecx),%ebp
20460+ xorl %ebp, %edi
20461+ movl 24(%esp), %ebp
20462+ movb %dh, %cl
20463+ andl $0xff, %eax
20464+ andl $0xff, %edx
20465+ movl 0x600+des_SPtrans(%ebx),%ebx
20466+ xorl %ebx, %edi
20467+ movl 0x700+des_SPtrans(%ecx),%ebx
20468+ xorl %ebx, %edi
20469+ movl 0x400+des_SPtrans(%eax),%ebx
20470+ xorl %ebx, %edi
20471+ movl 0x500+des_SPtrans(%edx),%ebx
20472+ xorl %ebx, %edi
20473+
20474+
20475+ movl 88(%ebp), %eax
20476+ xorl %ebx, %ebx
20477+ movl 92(%ebp), %edx
20478+ xorl %edi, %eax
20479+ xorl %edi, %edx
20480+ andl $0xfcfcfcfc, %eax
20481+ andl $0xcfcfcfcf, %edx
20482+ movb %al, %bl
20483+ movb %ah, %cl
20484+ rorl $4, %edx
20485+ movl des_SPtrans(%ebx),%ebp
20486+ movb %dl, %bl
20487+ xorl %ebp, %esi
20488+ movl 0x200+des_SPtrans(%ecx),%ebp
20489+ xorl %ebp, %esi
20490+ movb %dh, %cl
20491+ shrl $16, %eax
20492+ movl 0x100+des_SPtrans(%ebx),%ebp
20493+ xorl %ebp, %esi
20494+ movb %ah, %bl
20495+ shrl $16, %edx
20496+ movl 0x300+des_SPtrans(%ecx),%ebp
20497+ xorl %ebp, %esi
20498+ movl 24(%esp), %ebp
20499+ movb %dh, %cl
20500+ andl $0xff, %eax
20501+ andl $0xff, %edx
20502+ movl 0x600+des_SPtrans(%ebx),%ebx
20503+ xorl %ebx, %esi
20504+ movl 0x700+des_SPtrans(%ecx),%ebx
20505+ xorl %ebx, %esi
20506+ movl 0x400+des_SPtrans(%eax),%ebx
20507+ xorl %ebx, %esi
20508+ movl 0x500+des_SPtrans(%edx),%ebx
20509+ xorl %ebx, %esi
20510+
20511+
20512+ movl 96(%ebp), %eax
20513+ xorl %ebx, %ebx
20514+ movl 100(%ebp), %edx
20515+ xorl %esi, %eax
20516+ xorl %esi, %edx
20517+ andl $0xfcfcfcfc, %eax
20518+ andl $0xcfcfcfcf, %edx
20519+ movb %al, %bl
20520+ movb %ah, %cl
20521+ rorl $4, %edx
20522+ movl des_SPtrans(%ebx),%ebp
20523+ movb %dl, %bl
20524+ xorl %ebp, %edi
20525+ movl 0x200+des_SPtrans(%ecx),%ebp
20526+ xorl %ebp, %edi
20527+ movb %dh, %cl
20528+ shrl $16, %eax
20529+ movl 0x100+des_SPtrans(%ebx),%ebp
20530+ xorl %ebp, %edi
20531+ movb %ah, %bl
20532+ shrl $16, %edx
20533+ movl 0x300+des_SPtrans(%ecx),%ebp
20534+ xorl %ebp, %edi
20535+ movl 24(%esp), %ebp
20536+ movb %dh, %cl
20537+ andl $0xff, %eax
20538+ andl $0xff, %edx
20539+ movl 0x600+des_SPtrans(%ebx),%ebx
20540+ xorl %ebx, %edi
20541+ movl 0x700+des_SPtrans(%ecx),%ebx
20542+ xorl %ebx, %edi
20543+ movl 0x400+des_SPtrans(%eax),%ebx
20544+ xorl %ebx, %edi
20545+ movl 0x500+des_SPtrans(%edx),%ebx
20546+ xorl %ebx, %edi
20547+
20548+
20549+ movl 104(%ebp), %eax
20550+ xorl %ebx, %ebx
20551+ movl 108(%ebp), %edx
20552+ xorl %edi, %eax
20553+ xorl %edi, %edx
20554+ andl $0xfcfcfcfc, %eax
20555+ andl $0xcfcfcfcf, %edx
20556+ movb %al, %bl
20557+ movb %ah, %cl
20558+ rorl $4, %edx
20559+ movl des_SPtrans(%ebx),%ebp
20560+ movb %dl, %bl
20561+ xorl %ebp, %esi
20562+ movl 0x200+des_SPtrans(%ecx),%ebp
20563+ xorl %ebp, %esi
20564+ movb %dh, %cl
20565+ shrl $16, %eax
20566+ movl 0x100+des_SPtrans(%ebx),%ebp
20567+ xorl %ebp, %esi
20568+ movb %ah, %bl
20569+ shrl $16, %edx
20570+ movl 0x300+des_SPtrans(%ecx),%ebp
20571+ xorl %ebp, %esi
20572+ movl 24(%esp), %ebp
20573+ movb %dh, %cl
20574+ andl $0xff, %eax
20575+ andl $0xff, %edx
20576+ movl 0x600+des_SPtrans(%ebx),%ebx
20577+ xorl %ebx, %esi
20578+ movl 0x700+des_SPtrans(%ecx),%ebx
20579+ xorl %ebx, %esi
20580+ movl 0x400+des_SPtrans(%eax),%ebx
20581+ xorl %ebx, %esi
20582+ movl 0x500+des_SPtrans(%edx),%ebx
20583+ xorl %ebx, %esi
20584+
20585+
20586+ movl 112(%ebp), %eax
20587+ xorl %ebx, %ebx
20588+ movl 116(%ebp), %edx
20589+ xorl %esi, %eax
20590+ xorl %esi, %edx
20591+ andl $0xfcfcfcfc, %eax
20592+ andl $0xcfcfcfcf, %edx
20593+ movb %al, %bl
20594+ movb %ah, %cl
20595+ rorl $4, %edx
20596+ movl des_SPtrans(%ebx),%ebp
20597+ movb %dl, %bl
20598+ xorl %ebp, %edi
20599+ movl 0x200+des_SPtrans(%ecx),%ebp
20600+ xorl %ebp, %edi
20601+ movb %dh, %cl
20602+ shrl $16, %eax
20603+ movl 0x100+des_SPtrans(%ebx),%ebp
20604+ xorl %ebp, %edi
20605+ movb %ah, %bl
20606+ shrl $16, %edx
20607+ movl 0x300+des_SPtrans(%ecx),%ebp
20608+ xorl %ebp, %edi
20609+ movl 24(%esp), %ebp
20610+ movb %dh, %cl
20611+ andl $0xff, %eax
20612+ andl $0xff, %edx
20613+ movl 0x600+des_SPtrans(%ebx),%ebx
20614+ xorl %ebx, %edi
20615+ movl 0x700+des_SPtrans(%ecx),%ebx
20616+ xorl %ebx, %edi
20617+ movl 0x400+des_SPtrans(%eax),%ebx
20618+ xorl %ebx, %edi
20619+ movl 0x500+des_SPtrans(%edx),%ebx
20620+ xorl %ebx, %edi
20621+
20622+
20623+ movl 120(%ebp), %eax
20624+ xorl %ebx, %ebx
20625+ movl 124(%ebp), %edx
20626+ xorl %edi, %eax
20627+ xorl %edi, %edx
20628+ andl $0xfcfcfcfc, %eax
20629+ andl $0xcfcfcfcf, %edx
20630+ movb %al, %bl
20631+ movb %ah, %cl
20632+ rorl $4, %edx
20633+ movl des_SPtrans(%ebx),%ebp
20634+ movb %dl, %bl
20635+ xorl %ebp, %esi
20636+ movl 0x200+des_SPtrans(%ecx),%ebp
20637+ xorl %ebp, %esi
20638+ movb %dh, %cl
20639+ shrl $16, %eax
20640+ movl 0x100+des_SPtrans(%ebx),%ebp
20641+ xorl %ebp, %esi
20642+ movb %ah, %bl
20643+ shrl $16, %edx
20644+ movl 0x300+des_SPtrans(%ecx),%ebp
20645+ xorl %ebp, %esi
20646+ movl 24(%esp), %ebp
20647+ movb %dh, %cl
20648+ andl $0xff, %eax
20649+ andl $0xff, %edx
20650+ movl 0x600+des_SPtrans(%ebx),%ebx
20651+ xorl %ebx, %esi
20652+ movl 0x700+des_SPtrans(%ecx),%ebx
20653+ xorl %ebx, %esi
20654+ movl 0x400+des_SPtrans(%eax),%ebx
20655+ xorl %ebx, %esi
20656+ movl 0x500+des_SPtrans(%edx),%ebx
20657+ xorl %ebx, %esi
20658+ jmp .L001end
20659+.L000start_decrypt:
20660+
20661+
20662+ movl 120(%ebp), %eax
20663+ xorl %ebx, %ebx
20664+ movl 124(%ebp), %edx
20665+ xorl %esi, %eax
20666+ xorl %esi, %edx
20667+ andl $0xfcfcfcfc, %eax
20668+ andl $0xcfcfcfcf, %edx
20669+ movb %al, %bl
20670+ movb %ah, %cl
20671+ rorl $4, %edx
20672+ movl des_SPtrans(%ebx),%ebp
20673+ movb %dl, %bl
20674+ xorl %ebp, %edi
20675+ movl 0x200+des_SPtrans(%ecx),%ebp
20676+ xorl %ebp, %edi
20677+ movb %dh, %cl
20678+ shrl $16, %eax
20679+ movl 0x100+des_SPtrans(%ebx),%ebp
20680+ xorl %ebp, %edi
20681+ movb %ah, %bl
20682+ shrl $16, %edx
20683+ movl 0x300+des_SPtrans(%ecx),%ebp
20684+ xorl %ebp, %edi
20685+ movl 24(%esp), %ebp
20686+ movb %dh, %cl
20687+ andl $0xff, %eax
20688+ andl $0xff, %edx
20689+ movl 0x600+des_SPtrans(%ebx),%ebx
20690+ xorl %ebx, %edi
20691+ movl 0x700+des_SPtrans(%ecx),%ebx
20692+ xorl %ebx, %edi
20693+ movl 0x400+des_SPtrans(%eax),%ebx
20694+ xorl %ebx, %edi
20695+ movl 0x500+des_SPtrans(%edx),%ebx
20696+ xorl %ebx, %edi
20697+
20698+
20699+ movl 112(%ebp), %eax
20700+ xorl %ebx, %ebx
20701+ movl 116(%ebp), %edx
20702+ xorl %edi, %eax
20703+ xorl %edi, %edx
20704+ andl $0xfcfcfcfc, %eax
20705+ andl $0xcfcfcfcf, %edx
20706+ movb %al, %bl
20707+ movb %ah, %cl
20708+ rorl $4, %edx
20709+ movl des_SPtrans(%ebx),%ebp
20710+ movb %dl, %bl
20711+ xorl %ebp, %esi
20712+ movl 0x200+des_SPtrans(%ecx),%ebp
20713+ xorl %ebp, %esi
20714+ movb %dh, %cl
20715+ shrl $16, %eax
20716+ movl 0x100+des_SPtrans(%ebx),%ebp
20717+ xorl %ebp, %esi
20718+ movb %ah, %bl
20719+ shrl $16, %edx
20720+ movl 0x300+des_SPtrans(%ecx),%ebp
20721+ xorl %ebp, %esi
20722+ movl 24(%esp), %ebp
20723+ movb %dh, %cl
20724+ andl $0xff, %eax
20725+ andl $0xff, %edx
20726+ movl 0x600+des_SPtrans(%ebx),%ebx
20727+ xorl %ebx, %esi
20728+ movl 0x700+des_SPtrans(%ecx),%ebx
20729+ xorl %ebx, %esi
20730+ movl 0x400+des_SPtrans(%eax),%ebx
20731+ xorl %ebx, %esi
20732+ movl 0x500+des_SPtrans(%edx),%ebx
20733+ xorl %ebx, %esi
20734+
20735+
20736+ movl 104(%ebp), %eax
20737+ xorl %ebx, %ebx
20738+ movl 108(%ebp), %edx
20739+ xorl %esi, %eax
20740+ xorl %esi, %edx
20741+ andl $0xfcfcfcfc, %eax
20742+ andl $0xcfcfcfcf, %edx
20743+ movb %al, %bl
20744+ movb %ah, %cl
20745+ rorl $4, %edx
20746+ movl des_SPtrans(%ebx),%ebp
20747+ movb %dl, %bl
20748+ xorl %ebp, %edi
20749+ movl 0x200+des_SPtrans(%ecx),%ebp
20750+ xorl %ebp, %edi
20751+ movb %dh, %cl
20752+ shrl $16, %eax
20753+ movl 0x100+des_SPtrans(%ebx),%ebp
20754+ xorl %ebp, %edi
20755+ movb %ah, %bl
20756+ shrl $16, %edx
20757+ movl 0x300+des_SPtrans(%ecx),%ebp
20758+ xorl %ebp, %edi
20759+ movl 24(%esp), %ebp
20760+ movb %dh, %cl
20761+ andl $0xff, %eax
20762+ andl $0xff, %edx
20763+ movl 0x600+des_SPtrans(%ebx),%ebx
20764+ xorl %ebx, %edi
20765+ movl 0x700+des_SPtrans(%ecx),%ebx
20766+ xorl %ebx, %edi
20767+ movl 0x400+des_SPtrans(%eax),%ebx
20768+ xorl %ebx, %edi
20769+ movl 0x500+des_SPtrans(%edx),%ebx
20770+ xorl %ebx, %edi
20771+
20772+
20773+ movl 96(%ebp), %eax
20774+ xorl %ebx, %ebx
20775+ movl 100(%ebp), %edx
20776+ xorl %edi, %eax
20777+ xorl %edi, %edx
20778+ andl $0xfcfcfcfc, %eax
20779+ andl $0xcfcfcfcf, %edx
20780+ movb %al, %bl
20781+ movb %ah, %cl
20782+ rorl $4, %edx
20783+ movl des_SPtrans(%ebx),%ebp
20784+ movb %dl, %bl
20785+ xorl %ebp, %esi
20786+ movl 0x200+des_SPtrans(%ecx),%ebp
20787+ xorl %ebp, %esi
20788+ movb %dh, %cl
20789+ shrl $16, %eax
20790+ movl 0x100+des_SPtrans(%ebx),%ebp
20791+ xorl %ebp, %esi
20792+ movb %ah, %bl
20793+ shrl $16, %edx
20794+ movl 0x300+des_SPtrans(%ecx),%ebp
20795+ xorl %ebp, %esi
20796+ movl 24(%esp), %ebp
20797+ movb %dh, %cl
20798+ andl $0xff, %eax
20799+ andl $0xff, %edx
20800+ movl 0x600+des_SPtrans(%ebx),%ebx
20801+ xorl %ebx, %esi
20802+ movl 0x700+des_SPtrans(%ecx),%ebx
20803+ xorl %ebx, %esi
20804+ movl 0x400+des_SPtrans(%eax),%ebx
20805+ xorl %ebx, %esi
20806+ movl 0x500+des_SPtrans(%edx),%ebx
20807+ xorl %ebx, %esi
20808+
20809+
20810+ movl 88(%ebp), %eax
20811+ xorl %ebx, %ebx
20812+ movl 92(%ebp), %edx
20813+ xorl %esi, %eax
20814+ xorl %esi, %edx
20815+ andl $0xfcfcfcfc, %eax
20816+ andl $0xcfcfcfcf, %edx
20817+ movb %al, %bl
20818+ movb %ah, %cl
20819+ rorl $4, %edx
20820+ movl des_SPtrans(%ebx),%ebp
20821+ movb %dl, %bl
20822+ xorl %ebp, %edi
20823+ movl 0x200+des_SPtrans(%ecx),%ebp
20824+ xorl %ebp, %edi
20825+ movb %dh, %cl
20826+ shrl $16, %eax
20827+ movl 0x100+des_SPtrans(%ebx),%ebp
20828+ xorl %ebp, %edi
20829+ movb %ah, %bl
20830+ shrl $16, %edx
20831+ movl 0x300+des_SPtrans(%ecx),%ebp
20832+ xorl %ebp, %edi
20833+ movl 24(%esp), %ebp
20834+ movb %dh, %cl
20835+ andl $0xff, %eax
20836+ andl $0xff, %edx
20837+ movl 0x600+des_SPtrans(%ebx),%ebx
20838+ xorl %ebx, %edi
20839+ movl 0x700+des_SPtrans(%ecx),%ebx
20840+ xorl %ebx, %edi
20841+ movl 0x400+des_SPtrans(%eax),%ebx
20842+ xorl %ebx, %edi
20843+ movl 0x500+des_SPtrans(%edx),%ebx
20844+ xorl %ebx, %edi
20845+
20846+
20847+ movl 80(%ebp), %eax
20848+ xorl %ebx, %ebx
20849+ movl 84(%ebp), %edx
20850+ xorl %edi, %eax
20851+ xorl %edi, %edx
20852+ andl $0xfcfcfcfc, %eax
20853+ andl $0xcfcfcfcf, %edx
20854+ movb %al, %bl
20855+ movb %ah, %cl
20856+ rorl $4, %edx
20857+ movl des_SPtrans(%ebx),%ebp
20858+ movb %dl, %bl
20859+ xorl %ebp, %esi
20860+ movl 0x200+des_SPtrans(%ecx),%ebp
20861+ xorl %ebp, %esi
20862+ movb %dh, %cl
20863+ shrl $16, %eax
20864+ movl 0x100+des_SPtrans(%ebx),%ebp
20865+ xorl %ebp, %esi
20866+ movb %ah, %bl
20867+ shrl $16, %edx
20868+ movl 0x300+des_SPtrans(%ecx),%ebp
20869+ xorl %ebp, %esi
20870+ movl 24(%esp), %ebp
20871+ movb %dh, %cl
20872+ andl $0xff, %eax
20873+ andl $0xff, %edx
20874+ movl 0x600+des_SPtrans(%ebx),%ebx
20875+ xorl %ebx, %esi
20876+ movl 0x700+des_SPtrans(%ecx),%ebx
20877+ xorl %ebx, %esi
20878+ movl 0x400+des_SPtrans(%eax),%ebx
20879+ xorl %ebx, %esi
20880+ movl 0x500+des_SPtrans(%edx),%ebx
20881+ xorl %ebx, %esi
20882+
20883+
20884+ movl 72(%ebp), %eax
20885+ xorl %ebx, %ebx
20886+ movl 76(%ebp), %edx
20887+ xorl %esi, %eax
20888+ xorl %esi, %edx
20889+ andl $0xfcfcfcfc, %eax
20890+ andl $0xcfcfcfcf, %edx
20891+ movb %al, %bl
20892+ movb %ah, %cl
20893+ rorl $4, %edx
20894+ movl des_SPtrans(%ebx),%ebp
20895+ movb %dl, %bl
20896+ xorl %ebp, %edi
20897+ movl 0x200+des_SPtrans(%ecx),%ebp
20898+ xorl %ebp, %edi
20899+ movb %dh, %cl
20900+ shrl $16, %eax
20901+ movl 0x100+des_SPtrans(%ebx),%ebp
20902+ xorl %ebp, %edi
20903+ movb %ah, %bl
20904+ shrl $16, %edx
20905+ movl 0x300+des_SPtrans(%ecx),%ebp
20906+ xorl %ebp, %edi
20907+ movl 24(%esp), %ebp
20908+ movb %dh, %cl
20909+ andl $0xff, %eax
20910+ andl $0xff, %edx
20911+ movl 0x600+des_SPtrans(%ebx),%ebx
20912+ xorl %ebx, %edi
20913+ movl 0x700+des_SPtrans(%ecx),%ebx
20914+ xorl %ebx, %edi
20915+ movl 0x400+des_SPtrans(%eax),%ebx
20916+ xorl %ebx, %edi
20917+ movl 0x500+des_SPtrans(%edx),%ebx
20918+ xorl %ebx, %edi
20919+
20920+
20921+ movl 64(%ebp), %eax
20922+ xorl %ebx, %ebx
20923+ movl 68(%ebp), %edx
20924+ xorl %edi, %eax
20925+ xorl %edi, %edx
20926+ andl $0xfcfcfcfc, %eax
20927+ andl $0xcfcfcfcf, %edx
20928+ movb %al, %bl
20929+ movb %ah, %cl
20930+ rorl $4, %edx
20931+ movl des_SPtrans(%ebx),%ebp
20932+ movb %dl, %bl
20933+ xorl %ebp, %esi
20934+ movl 0x200+des_SPtrans(%ecx),%ebp
20935+ xorl %ebp, %esi
20936+ movb %dh, %cl
20937+ shrl $16, %eax
20938+ movl 0x100+des_SPtrans(%ebx),%ebp
20939+ xorl %ebp, %esi
20940+ movb %ah, %bl
20941+ shrl $16, %edx
20942+ movl 0x300+des_SPtrans(%ecx),%ebp
20943+ xorl %ebp, %esi
20944+ movl 24(%esp), %ebp
20945+ movb %dh, %cl
20946+ andl $0xff, %eax
20947+ andl $0xff, %edx
20948+ movl 0x600+des_SPtrans(%ebx),%ebx
20949+ xorl %ebx, %esi
20950+ movl 0x700+des_SPtrans(%ecx),%ebx
20951+ xorl %ebx, %esi
20952+ movl 0x400+des_SPtrans(%eax),%ebx
20953+ xorl %ebx, %esi
20954+ movl 0x500+des_SPtrans(%edx),%ebx
20955+ xorl %ebx, %esi
20956+
20957+
20958+ movl 56(%ebp), %eax
20959+ xorl %ebx, %ebx
20960+ movl 60(%ebp), %edx
20961+ xorl %esi, %eax
20962+ xorl %esi, %edx
20963+ andl $0xfcfcfcfc, %eax
20964+ andl $0xcfcfcfcf, %edx
20965+ movb %al, %bl
20966+ movb %ah, %cl
20967+ rorl $4, %edx
20968+ movl des_SPtrans(%ebx),%ebp
20969+ movb %dl, %bl
20970+ xorl %ebp, %edi
20971+ movl 0x200+des_SPtrans(%ecx),%ebp
20972+ xorl %ebp, %edi
20973+ movb %dh, %cl
20974+ shrl $16, %eax
20975+ movl 0x100+des_SPtrans(%ebx),%ebp
20976+ xorl %ebp, %edi
20977+ movb %ah, %bl
20978+ shrl $16, %edx
20979+ movl 0x300+des_SPtrans(%ecx),%ebp
20980+ xorl %ebp, %edi
20981+ movl 24(%esp), %ebp
20982+ movb %dh, %cl
20983+ andl $0xff, %eax
20984+ andl $0xff, %edx
20985+ movl 0x600+des_SPtrans(%ebx),%ebx
20986+ xorl %ebx, %edi
20987+ movl 0x700+des_SPtrans(%ecx),%ebx
20988+ xorl %ebx, %edi
20989+ movl 0x400+des_SPtrans(%eax),%ebx
20990+ xorl %ebx, %edi
20991+ movl 0x500+des_SPtrans(%edx),%ebx
20992+ xorl %ebx, %edi
20993+
20994+
20995+ movl 48(%ebp), %eax
20996+ xorl %ebx, %ebx
20997+ movl 52(%ebp), %edx
20998+ xorl %edi, %eax
20999+ xorl %edi, %edx
21000+ andl $0xfcfcfcfc, %eax
21001+ andl $0xcfcfcfcf, %edx
21002+ movb %al, %bl
21003+ movb %ah, %cl
21004+ rorl $4, %edx
21005+ movl des_SPtrans(%ebx),%ebp
21006+ movb %dl, %bl
21007+ xorl %ebp, %esi
21008+ movl 0x200+des_SPtrans(%ecx),%ebp
21009+ xorl %ebp, %esi
21010+ movb %dh, %cl
21011+ shrl $16, %eax
21012+ movl 0x100+des_SPtrans(%ebx),%ebp
21013+ xorl %ebp, %esi
21014+ movb %ah, %bl
21015+ shrl $16, %edx
21016+ movl 0x300+des_SPtrans(%ecx),%ebp
21017+ xorl %ebp, %esi
21018+ movl 24(%esp), %ebp
21019+ movb %dh, %cl
21020+ andl $0xff, %eax
21021+ andl $0xff, %edx
21022+ movl 0x600+des_SPtrans(%ebx),%ebx
21023+ xorl %ebx, %esi
21024+ movl 0x700+des_SPtrans(%ecx),%ebx
21025+ xorl %ebx, %esi
21026+ movl 0x400+des_SPtrans(%eax),%ebx
21027+ xorl %ebx, %esi
21028+ movl 0x500+des_SPtrans(%edx),%ebx
21029+ xorl %ebx, %esi
21030+
21031+
21032+ movl 40(%ebp), %eax
21033+ xorl %ebx, %ebx
21034+ movl 44(%ebp), %edx
21035+ xorl %esi, %eax
21036+ xorl %esi, %edx
21037+ andl $0xfcfcfcfc, %eax
21038+ andl $0xcfcfcfcf, %edx
21039+ movb %al, %bl
21040+ movb %ah, %cl
21041+ rorl $4, %edx
21042+ movl des_SPtrans(%ebx),%ebp
21043+ movb %dl, %bl
21044+ xorl %ebp, %edi
21045+ movl 0x200+des_SPtrans(%ecx),%ebp
21046+ xorl %ebp, %edi
21047+ movb %dh, %cl
21048+ shrl $16, %eax
21049+ movl 0x100+des_SPtrans(%ebx),%ebp
21050+ xorl %ebp, %edi
21051+ movb %ah, %bl
21052+ shrl $16, %edx
21053+ movl 0x300+des_SPtrans(%ecx),%ebp
21054+ xorl %ebp, %edi
21055+ movl 24(%esp), %ebp
21056+ movb %dh, %cl
21057+ andl $0xff, %eax
21058+ andl $0xff, %edx
21059+ movl 0x600+des_SPtrans(%ebx),%ebx
21060+ xorl %ebx, %edi
21061+ movl 0x700+des_SPtrans(%ecx),%ebx
21062+ xorl %ebx, %edi
21063+ movl 0x400+des_SPtrans(%eax),%ebx
21064+ xorl %ebx, %edi
21065+ movl 0x500+des_SPtrans(%edx),%ebx
21066+ xorl %ebx, %edi
21067+
21068+
21069+ movl 32(%ebp), %eax
21070+ xorl %ebx, %ebx
21071+ movl 36(%ebp), %edx
21072+ xorl %edi, %eax
21073+ xorl %edi, %edx
21074+ andl $0xfcfcfcfc, %eax
21075+ andl $0xcfcfcfcf, %edx
21076+ movb %al, %bl
21077+ movb %ah, %cl
21078+ rorl $4, %edx
21079+ movl des_SPtrans(%ebx),%ebp
21080+ movb %dl, %bl
21081+ xorl %ebp, %esi
21082+ movl 0x200+des_SPtrans(%ecx),%ebp
21083+ xorl %ebp, %esi
21084+ movb %dh, %cl
21085+ shrl $16, %eax
21086+ movl 0x100+des_SPtrans(%ebx),%ebp
21087+ xorl %ebp, %esi
21088+ movb %ah, %bl
21089+ shrl $16, %edx
21090+ movl 0x300+des_SPtrans(%ecx),%ebp
21091+ xorl %ebp, %esi
21092+ movl 24(%esp), %ebp
21093+ movb %dh, %cl
21094+ andl $0xff, %eax
21095+ andl $0xff, %edx
21096+ movl 0x600+des_SPtrans(%ebx),%ebx
21097+ xorl %ebx, %esi
21098+ movl 0x700+des_SPtrans(%ecx),%ebx
21099+ xorl %ebx, %esi
21100+ movl 0x400+des_SPtrans(%eax),%ebx
21101+ xorl %ebx, %esi
21102+ movl 0x500+des_SPtrans(%edx),%ebx
21103+ xorl %ebx, %esi
21104+
21105+
21106+ movl 24(%ebp), %eax
21107+ xorl %ebx, %ebx
21108+ movl 28(%ebp), %edx
21109+ xorl %esi, %eax
21110+ xorl %esi, %edx
21111+ andl $0xfcfcfcfc, %eax
21112+ andl $0xcfcfcfcf, %edx
21113+ movb %al, %bl
21114+ movb %ah, %cl
21115+ rorl $4, %edx
21116+ movl des_SPtrans(%ebx),%ebp
21117+ movb %dl, %bl
21118+ xorl %ebp, %edi
21119+ movl 0x200+des_SPtrans(%ecx),%ebp
21120+ xorl %ebp, %edi
21121+ movb %dh, %cl
21122+ shrl $16, %eax
21123+ movl 0x100+des_SPtrans(%ebx),%ebp
21124+ xorl %ebp, %edi
21125+ movb %ah, %bl
21126+ shrl $16, %edx
21127+ movl 0x300+des_SPtrans(%ecx),%ebp
21128+ xorl %ebp, %edi
21129+ movl 24(%esp), %ebp
21130+ movb %dh, %cl
21131+ andl $0xff, %eax
21132+ andl $0xff, %edx
21133+ movl 0x600+des_SPtrans(%ebx),%ebx
21134+ xorl %ebx, %edi
21135+ movl 0x700+des_SPtrans(%ecx),%ebx
21136+ xorl %ebx, %edi
21137+ movl 0x400+des_SPtrans(%eax),%ebx
21138+ xorl %ebx, %edi
21139+ movl 0x500+des_SPtrans(%edx),%ebx
21140+ xorl %ebx, %edi
21141+
21142+
21143+ movl 16(%ebp), %eax
21144+ xorl %ebx, %ebx
21145+ movl 20(%ebp), %edx
21146+ xorl %edi, %eax
21147+ xorl %edi, %edx
21148+ andl $0xfcfcfcfc, %eax
21149+ andl $0xcfcfcfcf, %edx
21150+ movb %al, %bl
21151+ movb %ah, %cl
21152+ rorl $4, %edx
21153+ movl des_SPtrans(%ebx),%ebp
21154+ movb %dl, %bl
21155+ xorl %ebp, %esi
21156+ movl 0x200+des_SPtrans(%ecx),%ebp
21157+ xorl %ebp, %esi
21158+ movb %dh, %cl
21159+ shrl $16, %eax
21160+ movl 0x100+des_SPtrans(%ebx),%ebp
21161+ xorl %ebp, %esi
21162+ movb %ah, %bl
21163+ shrl $16, %edx
21164+ movl 0x300+des_SPtrans(%ecx),%ebp
21165+ xorl %ebp, %esi
21166+ movl 24(%esp), %ebp
21167+ movb %dh, %cl
21168+ andl $0xff, %eax
21169+ andl $0xff, %edx
21170+ movl 0x600+des_SPtrans(%ebx),%ebx
21171+ xorl %ebx, %esi
21172+ movl 0x700+des_SPtrans(%ecx),%ebx
21173+ xorl %ebx, %esi
21174+ movl 0x400+des_SPtrans(%eax),%ebx
21175+ xorl %ebx, %esi
21176+ movl 0x500+des_SPtrans(%edx),%ebx
21177+ xorl %ebx, %esi
21178+
21179+
21180+ movl 8(%ebp), %eax
21181+ xorl %ebx, %ebx
21182+ movl 12(%ebp), %edx
21183+ xorl %esi, %eax
21184+ xorl %esi, %edx
21185+ andl $0xfcfcfcfc, %eax
21186+ andl $0xcfcfcfcf, %edx
21187+ movb %al, %bl
21188+ movb %ah, %cl
21189+ rorl $4, %edx
21190+ movl des_SPtrans(%ebx),%ebp
21191+ movb %dl, %bl
21192+ xorl %ebp, %edi
21193+ movl 0x200+des_SPtrans(%ecx),%ebp
21194+ xorl %ebp, %edi
21195+ movb %dh, %cl
21196+ shrl $16, %eax
21197+ movl 0x100+des_SPtrans(%ebx),%ebp
21198+ xorl %ebp, %edi
21199+ movb %ah, %bl
21200+ shrl $16, %edx
21201+ movl 0x300+des_SPtrans(%ecx),%ebp
21202+ xorl %ebp, %edi
21203+ movl 24(%esp), %ebp
21204+ movb %dh, %cl
21205+ andl $0xff, %eax
21206+ andl $0xff, %edx
21207+ movl 0x600+des_SPtrans(%ebx),%ebx
21208+ xorl %ebx, %edi
21209+ movl 0x700+des_SPtrans(%ecx),%ebx
21210+ xorl %ebx, %edi
21211+ movl 0x400+des_SPtrans(%eax),%ebx
21212+ xorl %ebx, %edi
21213+ movl 0x500+des_SPtrans(%edx),%ebx
21214+ xorl %ebx, %edi
21215+
21216+
21217+ movl (%ebp), %eax
21218+ xorl %ebx, %ebx
21219+ movl 4(%ebp), %edx
21220+ xorl %edi, %eax
21221+ xorl %edi, %edx
21222+ andl $0xfcfcfcfc, %eax
21223+ andl $0xcfcfcfcf, %edx
21224+ movb %al, %bl
21225+ movb %ah, %cl
21226+ rorl $4, %edx
21227+ movl des_SPtrans(%ebx),%ebp
21228+ movb %dl, %bl
21229+ xorl %ebp, %esi
21230+ movl 0x200+des_SPtrans(%ecx),%ebp
21231+ xorl %ebp, %esi
21232+ movb %dh, %cl
21233+ shrl $16, %eax
21234+ movl 0x100+des_SPtrans(%ebx),%ebp
21235+ xorl %ebp, %esi
21236+ movb %ah, %bl
21237+ shrl $16, %edx
21238+ movl 0x300+des_SPtrans(%ecx),%ebp
21239+ xorl %ebp, %esi
21240+ movl 24(%esp), %ebp
21241+ movb %dh, %cl
21242+ andl $0xff, %eax
21243+ andl $0xff, %edx
21244+ movl 0x600+des_SPtrans(%ebx),%ebx
21245+ xorl %ebx, %esi
21246+ movl 0x700+des_SPtrans(%ecx),%ebx
21247+ xorl %ebx, %esi
21248+ movl 0x400+des_SPtrans(%eax),%ebx
21249+ xorl %ebx, %esi
21250+ movl 0x500+des_SPtrans(%edx),%ebx
21251+ xorl %ebx, %esi
21252+.L001end:
21253+
21254+
21255+ movl 20(%esp), %edx
21256+.byte 209
21257+.byte 206
21258+ movl %edi, %eax
21259+ xorl %esi, %edi
21260+ andl $0xaaaaaaaa, %edi
21261+ xorl %edi, %eax
21262+ xorl %edi, %esi
21263+
21264+ roll $23, %eax
21265+ movl %eax, %edi
21266+ xorl %esi, %eax
21267+ andl $0x03fc03fc, %eax
21268+ xorl %eax, %edi
21269+ xorl %eax, %esi
21270+
21271+ roll $10, %edi
21272+ movl %edi, %eax
21273+ xorl %esi, %edi
21274+ andl $0x33333333, %edi
21275+ xorl %edi, %eax
21276+ xorl %edi, %esi
21277+
21278+ roll $18, %esi
21279+ movl %esi, %edi
21280+ xorl %eax, %esi
21281+ andl $0xfff0000f, %esi
21282+ xorl %esi, %edi
21283+ xorl %esi, %eax
21284+
21285+ roll $12, %edi
21286+ movl %edi, %esi
21287+ xorl %eax, %edi
21288+ andl $0xf0f0f0f0, %edi
21289+ xorl %edi, %esi
21290+ xorl %edi, %eax
21291+
21292+ rorl $4, %eax
21293+ movl %eax, (%edx)
21294+ movl %esi, 4(%edx)
21295+ popl %ebp
21296+ popl %ebx
21297+ popl %edi
21298+ popl %esi
21299+ ret
21300+.des_encrypt_end:
21301+ .size des_encrypt , .des_encrypt_end-des_encrypt
21302+.ident "desasm.pl"
21303+.text
21304+ .align 16
21305+.globl des_encrypt2
21306+ .type des_encrypt2 , @function
21307+des_encrypt2:
21308+ pushl %esi
21309+ pushl %edi
21310+
21311+
21312+ movl 12(%esp), %eax
21313+ xorl %ecx, %ecx
21314+ pushl %ebx
21315+ pushl %ebp
21316+ movl (%eax), %esi
21317+ movl 28(%esp), %ebx
21318+ roll $3, %esi
21319+ movl 4(%eax), %edi
21320+ roll $3, %edi
21321+ movl 24(%esp), %ebp
21322+ cmpl $0, %ebx
21323+ je .L002start_decrypt
21324+
21325+
21326+ movl (%ebp), %eax
21327+ xorl %ebx, %ebx
21328+ movl 4(%ebp), %edx
21329+ xorl %esi, %eax
21330+ xorl %esi, %edx
21331+ andl $0xfcfcfcfc, %eax
21332+ andl $0xcfcfcfcf, %edx
21333+ movb %al, %bl
21334+ movb %ah, %cl
21335+ rorl $4, %edx
21336+ movl des_SPtrans(%ebx),%ebp
21337+ movb %dl, %bl
21338+ xorl %ebp, %edi
21339+ movl 0x200+des_SPtrans(%ecx),%ebp
21340+ xorl %ebp, %edi
21341+ movb %dh, %cl
21342+ shrl $16, %eax
21343+ movl 0x100+des_SPtrans(%ebx),%ebp
21344+ xorl %ebp, %edi
21345+ movb %ah, %bl
21346+ shrl $16, %edx
21347+ movl 0x300+des_SPtrans(%ecx),%ebp
21348+ xorl %ebp, %edi
21349+ movl 24(%esp), %ebp
21350+ movb %dh, %cl
21351+ andl $0xff, %eax
21352+ andl $0xff, %edx
21353+ movl 0x600+des_SPtrans(%ebx),%ebx
21354+ xorl %ebx, %edi
21355+ movl 0x700+des_SPtrans(%ecx),%ebx
21356+ xorl %ebx, %edi
21357+ movl 0x400+des_SPtrans(%eax),%ebx
21358+ xorl %ebx, %edi
21359+ movl 0x500+des_SPtrans(%edx),%ebx
21360+ xorl %ebx, %edi
21361+
21362+
21363+ movl 8(%ebp), %eax
21364+ xorl %ebx, %ebx
21365+ movl 12(%ebp), %edx
21366+ xorl %edi, %eax
21367+ xorl %edi, %edx
21368+ andl $0xfcfcfcfc, %eax
21369+ andl $0xcfcfcfcf, %edx
21370+ movb %al, %bl
21371+ movb %ah, %cl
21372+ rorl $4, %edx
21373+ movl des_SPtrans(%ebx),%ebp
21374+ movb %dl, %bl
21375+ xorl %ebp, %esi
21376+ movl 0x200+des_SPtrans(%ecx),%ebp
21377+ xorl %ebp, %esi
21378+ movb %dh, %cl
21379+ shrl $16, %eax
21380+ movl 0x100+des_SPtrans(%ebx),%ebp
21381+ xorl %ebp, %esi
21382+ movb %ah, %bl
21383+ shrl $16, %edx
21384+ movl 0x300+des_SPtrans(%ecx),%ebp
21385+ xorl %ebp, %esi
21386+ movl 24(%esp), %ebp
21387+ movb %dh, %cl
21388+ andl $0xff, %eax
21389+ andl $0xff, %edx
21390+ movl 0x600+des_SPtrans(%ebx),%ebx
21391+ xorl %ebx, %esi
21392+ movl 0x700+des_SPtrans(%ecx),%ebx
21393+ xorl %ebx, %esi
21394+ movl 0x400+des_SPtrans(%eax),%ebx
21395+ xorl %ebx, %esi
21396+ movl 0x500+des_SPtrans(%edx),%ebx
21397+ xorl %ebx, %esi
21398+
21399+
21400+ movl 16(%ebp), %eax
21401+ xorl %ebx, %ebx
21402+ movl 20(%ebp), %edx
21403+ xorl %esi, %eax
21404+ xorl %esi, %edx
21405+ andl $0xfcfcfcfc, %eax
21406+ andl $0xcfcfcfcf, %edx
21407+ movb %al, %bl
21408+ movb %ah, %cl
21409+ rorl $4, %edx
21410+ movl des_SPtrans(%ebx),%ebp
21411+ movb %dl, %bl
21412+ xorl %ebp, %edi
21413+ movl 0x200+des_SPtrans(%ecx),%ebp
21414+ xorl %ebp, %edi
21415+ movb %dh, %cl
21416+ shrl $16, %eax
21417+ movl 0x100+des_SPtrans(%ebx),%ebp
21418+ xorl %ebp, %edi
21419+ movb %ah, %bl
21420+ shrl $16, %edx
21421+ movl 0x300+des_SPtrans(%ecx),%ebp
21422+ xorl %ebp, %edi
21423+ movl 24(%esp), %ebp
21424+ movb %dh, %cl
21425+ andl $0xff, %eax
21426+ andl $0xff, %edx
21427+ movl 0x600+des_SPtrans(%ebx),%ebx
21428+ xorl %ebx, %edi
21429+ movl 0x700+des_SPtrans(%ecx),%ebx
21430+ xorl %ebx, %edi
21431+ movl 0x400+des_SPtrans(%eax),%ebx
21432+ xorl %ebx, %edi
21433+ movl 0x500+des_SPtrans(%edx),%ebx
21434+ xorl %ebx, %edi
21435+
21436+
21437+ movl 24(%ebp), %eax
21438+ xorl %ebx, %ebx
21439+ movl 28(%ebp), %edx
21440+ xorl %edi, %eax
21441+ xorl %edi, %edx
21442+ andl $0xfcfcfcfc, %eax
21443+ andl $0xcfcfcfcf, %edx
21444+ movb %al, %bl
21445+ movb %ah, %cl
21446+ rorl $4, %edx
21447+ movl des_SPtrans(%ebx),%ebp
21448+ movb %dl, %bl
21449+ xorl %ebp, %esi
21450+ movl 0x200+des_SPtrans(%ecx),%ebp
21451+ xorl %ebp, %esi
21452+ movb %dh, %cl
21453+ shrl $16, %eax
21454+ movl 0x100+des_SPtrans(%ebx),%ebp
21455+ xorl %ebp, %esi
21456+ movb %ah, %bl
21457+ shrl $16, %edx
21458+ movl 0x300+des_SPtrans(%ecx),%ebp
21459+ xorl %ebp, %esi
21460+ movl 24(%esp), %ebp
21461+ movb %dh, %cl
21462+ andl $0xff, %eax
21463+ andl $0xff, %edx
21464+ movl 0x600+des_SPtrans(%ebx),%ebx
21465+ xorl %ebx, %esi
21466+ movl 0x700+des_SPtrans(%ecx),%ebx
21467+ xorl %ebx, %esi
21468+ movl 0x400+des_SPtrans(%eax),%ebx
21469+ xorl %ebx, %esi
21470+ movl 0x500+des_SPtrans(%edx),%ebx
21471+ xorl %ebx, %esi
21472+
21473+
21474+ movl 32(%ebp), %eax
21475+ xorl %ebx, %ebx
21476+ movl 36(%ebp), %edx
21477+ xorl %esi, %eax
21478+ xorl %esi, %edx
21479+ andl $0xfcfcfcfc, %eax
21480+ andl $0xcfcfcfcf, %edx
21481+ movb %al, %bl
21482+ movb %ah, %cl
21483+ rorl $4, %edx
21484+ movl des_SPtrans(%ebx),%ebp
21485+ movb %dl, %bl
21486+ xorl %ebp, %edi
21487+ movl 0x200+des_SPtrans(%ecx),%ebp
21488+ xorl %ebp, %edi
21489+ movb %dh, %cl
21490+ shrl $16, %eax
21491+ movl 0x100+des_SPtrans(%ebx),%ebp
21492+ xorl %ebp, %edi
21493+ movb %ah, %bl
21494+ shrl $16, %edx
21495+ movl 0x300+des_SPtrans(%ecx),%ebp
21496+ xorl %ebp, %edi
21497+ movl 24(%esp), %ebp
21498+ movb %dh, %cl
21499+ andl $0xff, %eax
21500+ andl $0xff, %edx
21501+ movl 0x600+des_SPtrans(%ebx),%ebx
21502+ xorl %ebx, %edi
21503+ movl 0x700+des_SPtrans(%ecx),%ebx
21504+ xorl %ebx, %edi
21505+ movl 0x400+des_SPtrans(%eax),%ebx
21506+ xorl %ebx, %edi
21507+ movl 0x500+des_SPtrans(%edx),%ebx
21508+ xorl %ebx, %edi
21509+
21510+
21511+ movl 40(%ebp), %eax
21512+ xorl %ebx, %ebx
21513+ movl 44(%ebp), %edx
21514+ xorl %edi, %eax
21515+ xorl %edi, %edx
21516+ andl $0xfcfcfcfc, %eax
21517+ andl $0xcfcfcfcf, %edx
21518+ movb %al, %bl
21519+ movb %ah, %cl
21520+ rorl $4, %edx
21521+ movl des_SPtrans(%ebx),%ebp
21522+ movb %dl, %bl
21523+ xorl %ebp, %esi
21524+ movl 0x200+des_SPtrans(%ecx),%ebp
21525+ xorl %ebp, %esi
21526+ movb %dh, %cl
21527+ shrl $16, %eax
21528+ movl 0x100+des_SPtrans(%ebx),%ebp
21529+ xorl %ebp, %esi
21530+ movb %ah, %bl
21531+ shrl $16, %edx
21532+ movl 0x300+des_SPtrans(%ecx),%ebp
21533+ xorl %ebp, %esi
21534+ movl 24(%esp), %ebp
21535+ movb %dh, %cl
21536+ andl $0xff, %eax
21537+ andl $0xff, %edx
21538+ movl 0x600+des_SPtrans(%ebx),%ebx
21539+ xorl %ebx, %esi
21540+ movl 0x700+des_SPtrans(%ecx),%ebx
21541+ xorl %ebx, %esi
21542+ movl 0x400+des_SPtrans(%eax),%ebx
21543+ xorl %ebx, %esi
21544+ movl 0x500+des_SPtrans(%edx),%ebx
21545+ xorl %ebx, %esi
21546+
21547+
21548+ movl 48(%ebp), %eax
21549+ xorl %ebx, %ebx
21550+ movl 52(%ebp), %edx
21551+ xorl %esi, %eax
21552+ xorl %esi, %edx
21553+ andl $0xfcfcfcfc, %eax
21554+ andl $0xcfcfcfcf, %edx
21555+ movb %al, %bl
21556+ movb %ah, %cl
21557+ rorl $4, %edx
21558+ movl des_SPtrans(%ebx),%ebp
21559+ movb %dl, %bl
21560+ xorl %ebp, %edi
21561+ movl 0x200+des_SPtrans(%ecx),%ebp
21562+ xorl %ebp, %edi
21563+ movb %dh, %cl
21564+ shrl $16, %eax
21565+ movl 0x100+des_SPtrans(%ebx),%ebp
21566+ xorl %ebp, %edi
21567+ movb %ah, %bl
21568+ shrl $16, %edx
21569+ movl 0x300+des_SPtrans(%ecx),%ebp
21570+ xorl %ebp, %edi
21571+ movl 24(%esp), %ebp
21572+ movb %dh, %cl
21573+ andl $0xff, %eax
21574+ andl $0xff, %edx
21575+ movl 0x600+des_SPtrans(%ebx),%ebx
21576+ xorl %ebx, %edi
21577+ movl 0x700+des_SPtrans(%ecx),%ebx
21578+ xorl %ebx, %edi
21579+ movl 0x400+des_SPtrans(%eax),%ebx
21580+ xorl %ebx, %edi
21581+ movl 0x500+des_SPtrans(%edx),%ebx
21582+ xorl %ebx, %edi
21583+
21584+
21585+ movl 56(%ebp), %eax
21586+ xorl %ebx, %ebx
21587+ movl 60(%ebp), %edx
21588+ xorl %edi, %eax
21589+ xorl %edi, %edx
21590+ andl $0xfcfcfcfc, %eax
21591+ andl $0xcfcfcfcf, %edx
21592+ movb %al, %bl
21593+ movb %ah, %cl
21594+ rorl $4, %edx
21595+ movl des_SPtrans(%ebx),%ebp
21596+ movb %dl, %bl
21597+ xorl %ebp, %esi
21598+ movl 0x200+des_SPtrans(%ecx),%ebp
21599+ xorl %ebp, %esi
21600+ movb %dh, %cl
21601+ shrl $16, %eax
21602+ movl 0x100+des_SPtrans(%ebx),%ebp
21603+ xorl %ebp, %esi
21604+ movb %ah, %bl
21605+ shrl $16, %edx
21606+ movl 0x300+des_SPtrans(%ecx),%ebp
21607+ xorl %ebp, %esi
21608+ movl 24(%esp), %ebp
21609+ movb %dh, %cl
21610+ andl $0xff, %eax
21611+ andl $0xff, %edx
21612+ movl 0x600+des_SPtrans(%ebx),%ebx
21613+ xorl %ebx, %esi
21614+ movl 0x700+des_SPtrans(%ecx),%ebx
21615+ xorl %ebx, %esi
21616+ movl 0x400+des_SPtrans(%eax),%ebx
21617+ xorl %ebx, %esi
21618+ movl 0x500+des_SPtrans(%edx),%ebx
21619+ xorl %ebx, %esi
21620+
21621+
21622+ movl 64(%ebp), %eax
21623+ xorl %ebx, %ebx
21624+ movl 68(%ebp), %edx
21625+ xorl %esi, %eax
21626+ xorl %esi, %edx
21627+ andl $0xfcfcfcfc, %eax
21628+ andl $0xcfcfcfcf, %edx
21629+ movb %al, %bl
21630+ movb %ah, %cl
21631+ rorl $4, %edx
21632+ movl des_SPtrans(%ebx),%ebp
21633+ movb %dl, %bl
21634+ xorl %ebp, %edi
21635+ movl 0x200+des_SPtrans(%ecx),%ebp
21636+ xorl %ebp, %edi
21637+ movb %dh, %cl
21638+ shrl $16, %eax
21639+ movl 0x100+des_SPtrans(%ebx),%ebp
21640+ xorl %ebp, %edi
21641+ movb %ah, %bl
21642+ shrl $16, %edx
21643+ movl 0x300+des_SPtrans(%ecx),%ebp
21644+ xorl %ebp, %edi
21645+ movl 24(%esp), %ebp
21646+ movb %dh, %cl
21647+ andl $0xff, %eax
21648+ andl $0xff, %edx
21649+ movl 0x600+des_SPtrans(%ebx),%ebx
21650+ xorl %ebx, %edi
21651+ movl 0x700+des_SPtrans(%ecx),%ebx
21652+ xorl %ebx, %edi
21653+ movl 0x400+des_SPtrans(%eax),%ebx
21654+ xorl %ebx, %edi
21655+ movl 0x500+des_SPtrans(%edx),%ebx
21656+ xorl %ebx, %edi
21657+
21658+
21659+ movl 72(%ebp), %eax
21660+ xorl %ebx, %ebx
21661+ movl 76(%ebp), %edx
21662+ xorl %edi, %eax
21663+ xorl %edi, %edx
21664+ andl $0xfcfcfcfc, %eax
21665+ andl $0xcfcfcfcf, %edx
21666+ movb %al, %bl
21667+ movb %ah, %cl
21668+ rorl $4, %edx
21669+ movl des_SPtrans(%ebx),%ebp
21670+ movb %dl, %bl
21671+ xorl %ebp, %esi
21672+ movl 0x200+des_SPtrans(%ecx),%ebp
21673+ xorl %ebp, %esi
21674+ movb %dh, %cl
21675+ shrl $16, %eax
21676+ movl 0x100+des_SPtrans(%ebx),%ebp
21677+ xorl %ebp, %esi
21678+ movb %ah, %bl
21679+ shrl $16, %edx
21680+ movl 0x300+des_SPtrans(%ecx),%ebp
21681+ xorl %ebp, %esi
21682+ movl 24(%esp), %ebp
21683+ movb %dh, %cl
21684+ andl $0xff, %eax
21685+ andl $0xff, %edx
21686+ movl 0x600+des_SPtrans(%ebx),%ebx
21687+ xorl %ebx, %esi
21688+ movl 0x700+des_SPtrans(%ecx),%ebx
21689+ xorl %ebx, %esi
21690+ movl 0x400+des_SPtrans(%eax),%ebx
21691+ xorl %ebx, %esi
21692+ movl 0x500+des_SPtrans(%edx),%ebx
21693+ xorl %ebx, %esi
21694+
21695+
21696+ movl 80(%ebp), %eax
21697+ xorl %ebx, %ebx
21698+ movl 84(%ebp), %edx
21699+ xorl %esi, %eax
21700+ xorl %esi, %edx
21701+ andl $0xfcfcfcfc, %eax
21702+ andl $0xcfcfcfcf, %edx
21703+ movb %al, %bl
21704+ movb %ah, %cl
21705+ rorl $4, %edx
21706+ movl des_SPtrans(%ebx),%ebp
21707+ movb %dl, %bl
21708+ xorl %ebp, %edi
21709+ movl 0x200+des_SPtrans(%ecx),%ebp
21710+ xorl %ebp, %edi
21711+ movb %dh, %cl
21712+ shrl $16, %eax
21713+ movl 0x100+des_SPtrans(%ebx),%ebp
21714+ xorl %ebp, %edi
21715+ movb %ah, %bl
21716+ shrl $16, %edx
21717+ movl 0x300+des_SPtrans(%ecx),%ebp
21718+ xorl %ebp, %edi
21719+ movl 24(%esp), %ebp
21720+ movb %dh, %cl
21721+ andl $0xff, %eax
21722+ andl $0xff, %edx
21723+ movl 0x600+des_SPtrans(%ebx),%ebx
21724+ xorl %ebx, %edi
21725+ movl 0x700+des_SPtrans(%ecx),%ebx
21726+ xorl %ebx, %edi
21727+ movl 0x400+des_SPtrans(%eax),%ebx
21728+ xorl %ebx, %edi
21729+ movl 0x500+des_SPtrans(%edx),%ebx
21730+ xorl %ebx, %edi
21731+
21732+
21733+ movl 88(%ebp), %eax
21734+ xorl %ebx, %ebx
21735+ movl 92(%ebp), %edx
21736+ xorl %edi, %eax
21737+ xorl %edi, %edx
21738+ andl $0xfcfcfcfc, %eax
21739+ andl $0xcfcfcfcf, %edx
21740+ movb %al, %bl
21741+ movb %ah, %cl
21742+ rorl $4, %edx
21743+ movl des_SPtrans(%ebx),%ebp
21744+ movb %dl, %bl
21745+ xorl %ebp, %esi
21746+ movl 0x200+des_SPtrans(%ecx),%ebp
21747+ xorl %ebp, %esi
21748+ movb %dh, %cl
21749+ shrl $16, %eax
21750+ movl 0x100+des_SPtrans(%ebx),%ebp
21751+ xorl %ebp, %esi
21752+ movb %ah, %bl
21753+ shrl $16, %edx
21754+ movl 0x300+des_SPtrans(%ecx),%ebp
21755+ xorl %ebp, %esi
21756+ movl 24(%esp), %ebp
21757+ movb %dh, %cl
21758+ andl $0xff, %eax
21759+ andl $0xff, %edx
21760+ movl 0x600+des_SPtrans(%ebx),%ebx
21761+ xorl %ebx, %esi
21762+ movl 0x700+des_SPtrans(%ecx),%ebx
21763+ xorl %ebx, %esi
21764+ movl 0x400+des_SPtrans(%eax),%ebx
21765+ xorl %ebx, %esi
21766+ movl 0x500+des_SPtrans(%edx),%ebx
21767+ xorl %ebx, %esi
21768+
21769+
21770+ movl 96(%ebp), %eax
21771+ xorl %ebx, %ebx
21772+ movl 100(%ebp), %edx
21773+ xorl %esi, %eax
21774+ xorl %esi, %edx
21775+ andl $0xfcfcfcfc, %eax
21776+ andl $0xcfcfcfcf, %edx
21777+ movb %al, %bl
21778+ movb %ah, %cl
21779+ rorl $4, %edx
21780+ movl des_SPtrans(%ebx),%ebp
21781+ movb %dl, %bl
21782+ xorl %ebp, %edi
21783+ movl 0x200+des_SPtrans(%ecx),%ebp
21784+ xorl %ebp, %edi
21785+ movb %dh, %cl
21786+ shrl $16, %eax
21787+ movl 0x100+des_SPtrans(%ebx),%ebp
21788+ xorl %ebp, %edi
21789+ movb %ah, %bl
21790+ shrl $16, %edx
21791+ movl 0x300+des_SPtrans(%ecx),%ebp
21792+ xorl %ebp, %edi
21793+ movl 24(%esp), %ebp
21794+ movb %dh, %cl
21795+ andl $0xff, %eax
21796+ andl $0xff, %edx
21797+ movl 0x600+des_SPtrans(%ebx),%ebx
21798+ xorl %ebx, %edi
21799+ movl 0x700+des_SPtrans(%ecx),%ebx
21800+ xorl %ebx, %edi
21801+ movl 0x400+des_SPtrans(%eax),%ebx
21802+ xorl %ebx, %edi
21803+ movl 0x500+des_SPtrans(%edx),%ebx
21804+ xorl %ebx, %edi
21805+
21806+
21807+ movl 104(%ebp), %eax
21808+ xorl %ebx, %ebx
21809+ movl 108(%ebp), %edx
21810+ xorl %edi, %eax
21811+ xorl %edi, %edx
21812+ andl $0xfcfcfcfc, %eax
21813+ andl $0xcfcfcfcf, %edx
21814+ movb %al, %bl
21815+ movb %ah, %cl
21816+ rorl $4, %edx
21817+ movl des_SPtrans(%ebx),%ebp
21818+ movb %dl, %bl
21819+ xorl %ebp, %esi
21820+ movl 0x200+des_SPtrans(%ecx),%ebp
21821+ xorl %ebp, %esi
21822+ movb %dh, %cl
21823+ shrl $16, %eax
21824+ movl 0x100+des_SPtrans(%ebx),%ebp
21825+ xorl %ebp, %esi
21826+ movb %ah, %bl
21827+ shrl $16, %edx
21828+ movl 0x300+des_SPtrans(%ecx),%ebp
21829+ xorl %ebp, %esi
21830+ movl 24(%esp), %ebp
21831+ movb %dh, %cl
21832+ andl $0xff, %eax
21833+ andl $0xff, %edx
21834+ movl 0x600+des_SPtrans(%ebx),%ebx
21835+ xorl %ebx, %esi
21836+ movl 0x700+des_SPtrans(%ecx),%ebx
21837+ xorl %ebx, %esi
21838+ movl 0x400+des_SPtrans(%eax),%ebx
21839+ xorl %ebx, %esi
21840+ movl 0x500+des_SPtrans(%edx),%ebx
21841+ xorl %ebx, %esi
21842+
21843+
21844+ movl 112(%ebp), %eax
21845+ xorl %ebx, %ebx
21846+ movl 116(%ebp), %edx
21847+ xorl %esi, %eax
21848+ xorl %esi, %edx
21849+ andl $0xfcfcfcfc, %eax
21850+ andl $0xcfcfcfcf, %edx
21851+ movb %al, %bl
21852+ movb %ah, %cl
21853+ rorl $4, %edx
21854+ movl des_SPtrans(%ebx),%ebp
21855+ movb %dl, %bl
21856+ xorl %ebp, %edi
21857+ movl 0x200+des_SPtrans(%ecx),%ebp
21858+ xorl %ebp, %edi
21859+ movb %dh, %cl
21860+ shrl $16, %eax
21861+ movl 0x100+des_SPtrans(%ebx),%ebp
21862+ xorl %ebp, %edi
21863+ movb %ah, %bl
21864+ shrl $16, %edx
21865+ movl 0x300+des_SPtrans(%ecx),%ebp
21866+ xorl %ebp, %edi
21867+ movl 24(%esp), %ebp
21868+ movb %dh, %cl
21869+ andl $0xff, %eax
21870+ andl $0xff, %edx
21871+ movl 0x600+des_SPtrans(%ebx),%ebx
21872+ xorl %ebx, %edi
21873+ movl 0x700+des_SPtrans(%ecx),%ebx
21874+ xorl %ebx, %edi
21875+ movl 0x400+des_SPtrans(%eax),%ebx
21876+ xorl %ebx, %edi
21877+ movl 0x500+des_SPtrans(%edx),%ebx
21878+ xorl %ebx, %edi
21879+
21880+
21881+ movl 120(%ebp), %eax
21882+ xorl %ebx, %ebx
21883+ movl 124(%ebp), %edx
21884+ xorl %edi, %eax
21885+ xorl %edi, %edx
21886+ andl $0xfcfcfcfc, %eax
21887+ andl $0xcfcfcfcf, %edx
21888+ movb %al, %bl
21889+ movb %ah, %cl
21890+ rorl $4, %edx
21891+ movl des_SPtrans(%ebx),%ebp
21892+ movb %dl, %bl
21893+ xorl %ebp, %esi
21894+ movl 0x200+des_SPtrans(%ecx),%ebp
21895+ xorl %ebp, %esi
21896+ movb %dh, %cl
21897+ shrl $16, %eax
21898+ movl 0x100+des_SPtrans(%ebx),%ebp
21899+ xorl %ebp, %esi
21900+ movb %ah, %bl
21901+ shrl $16, %edx
21902+ movl 0x300+des_SPtrans(%ecx),%ebp
21903+ xorl %ebp, %esi
21904+ movl 24(%esp), %ebp
21905+ movb %dh, %cl
21906+ andl $0xff, %eax
21907+ andl $0xff, %edx
21908+ movl 0x600+des_SPtrans(%ebx),%ebx
21909+ xorl %ebx, %esi
21910+ movl 0x700+des_SPtrans(%ecx),%ebx
21911+ xorl %ebx, %esi
21912+ movl 0x400+des_SPtrans(%eax),%ebx
21913+ xorl %ebx, %esi
21914+ movl 0x500+des_SPtrans(%edx),%ebx
21915+ xorl %ebx, %esi
21916+ jmp .L003end
21917+.L002start_decrypt:
21918+
21919+
21920+ movl 120(%ebp), %eax
21921+ xorl %ebx, %ebx
21922+ movl 124(%ebp), %edx
21923+ xorl %esi, %eax
21924+ xorl %esi, %edx
21925+ andl $0xfcfcfcfc, %eax
21926+ andl $0xcfcfcfcf, %edx
21927+ movb %al, %bl
21928+ movb %ah, %cl
21929+ rorl $4, %edx
21930+ movl des_SPtrans(%ebx),%ebp
21931+ movb %dl, %bl
21932+ xorl %ebp, %edi
21933+ movl 0x200+des_SPtrans(%ecx),%ebp
21934+ xorl %ebp, %edi
21935+ movb %dh, %cl
21936+ shrl $16, %eax
21937+ movl 0x100+des_SPtrans(%ebx),%ebp
21938+ xorl %ebp, %edi
21939+ movb %ah, %bl
21940+ shrl $16, %edx
21941+ movl 0x300+des_SPtrans(%ecx),%ebp
21942+ xorl %ebp, %edi
21943+ movl 24(%esp), %ebp
21944+ movb %dh, %cl
21945+ andl $0xff, %eax
21946+ andl $0xff, %edx
21947+ movl 0x600+des_SPtrans(%ebx),%ebx
21948+ xorl %ebx, %edi
21949+ movl 0x700+des_SPtrans(%ecx),%ebx
21950+ xorl %ebx, %edi
21951+ movl 0x400+des_SPtrans(%eax),%ebx
21952+ xorl %ebx, %edi
21953+ movl 0x500+des_SPtrans(%edx),%ebx
21954+ xorl %ebx, %edi
21955+
21956+
21957+ movl 112(%ebp), %eax
21958+ xorl %ebx, %ebx
21959+ movl 116(%ebp), %edx
21960+ xorl %edi, %eax
21961+ xorl %edi, %edx
21962+ andl $0xfcfcfcfc, %eax
21963+ andl $0xcfcfcfcf, %edx
21964+ movb %al, %bl
21965+ movb %ah, %cl
21966+ rorl $4, %edx
21967+ movl des_SPtrans(%ebx),%ebp
21968+ movb %dl, %bl
21969+ xorl %ebp, %esi
21970+ movl 0x200+des_SPtrans(%ecx),%ebp
21971+ xorl %ebp, %esi
21972+ movb %dh, %cl
21973+ shrl $16, %eax
21974+ movl 0x100+des_SPtrans(%ebx),%ebp
21975+ xorl %ebp, %esi
21976+ movb %ah, %bl
21977+ shrl $16, %edx
21978+ movl 0x300+des_SPtrans(%ecx),%ebp
21979+ xorl %ebp, %esi
21980+ movl 24(%esp), %ebp
21981+ movb %dh, %cl
21982+ andl $0xff, %eax
21983+ andl $0xff, %edx
21984+ movl 0x600+des_SPtrans(%ebx),%ebx
21985+ xorl %ebx, %esi
21986+ movl 0x700+des_SPtrans(%ecx),%ebx
21987+ xorl %ebx, %esi
21988+ movl 0x400+des_SPtrans(%eax),%ebx
21989+ xorl %ebx, %esi
21990+ movl 0x500+des_SPtrans(%edx),%ebx
21991+ xorl %ebx, %esi
21992+
21993+
21994+ movl 104(%ebp), %eax
21995+ xorl %ebx, %ebx
21996+ movl 108(%ebp), %edx
21997+ xorl %esi, %eax
21998+ xorl %esi, %edx
21999+ andl $0xfcfcfcfc, %eax
22000+ andl $0xcfcfcfcf, %edx
22001+ movb %al, %bl
22002+ movb %ah, %cl
22003+ rorl $4, %edx
22004+ movl des_SPtrans(%ebx),%ebp
22005+ movb %dl, %bl
22006+ xorl %ebp, %edi
22007+ movl 0x200+des_SPtrans(%ecx),%ebp
22008+ xorl %ebp, %edi
22009+ movb %dh, %cl
22010+ shrl $16, %eax
22011+ movl 0x100+des_SPtrans(%ebx),%ebp
22012+ xorl %ebp, %edi
22013+ movb %ah, %bl
22014+ shrl $16, %edx
22015+ movl 0x300+des_SPtrans(%ecx),%ebp
22016+ xorl %ebp, %edi
22017+ movl 24(%esp), %ebp
22018+ movb %dh, %cl
22019+ andl $0xff, %eax
22020+ andl $0xff, %edx
22021+ movl 0x600+des_SPtrans(%ebx),%ebx
22022+ xorl %ebx, %edi
22023+ movl 0x700+des_SPtrans(%ecx),%ebx
22024+ xorl %ebx, %edi
22025+ movl 0x400+des_SPtrans(%eax),%ebx
22026+ xorl %ebx, %edi
22027+ movl 0x500+des_SPtrans(%edx),%ebx
22028+ xorl %ebx, %edi
22029+
22030+
22031+ movl 96(%ebp), %eax
22032+ xorl %ebx, %ebx
22033+ movl 100(%ebp), %edx
22034+ xorl %edi, %eax
22035+ xorl %edi, %edx
22036+ andl $0xfcfcfcfc, %eax
22037+ andl $0xcfcfcfcf, %edx
22038+ movb %al, %bl
22039+ movb %ah, %cl
22040+ rorl $4, %edx
22041+ movl des_SPtrans(%ebx),%ebp
22042+ movb %dl, %bl
22043+ xorl %ebp, %esi
22044+ movl 0x200+des_SPtrans(%ecx),%ebp
22045+ xorl %ebp, %esi
22046+ movb %dh, %cl
22047+ shrl $16, %eax
22048+ movl 0x100+des_SPtrans(%ebx),%ebp
22049+ xorl %ebp, %esi
22050+ movb %ah, %bl
22051+ shrl $16, %edx
22052+ movl 0x300+des_SPtrans(%ecx),%ebp
22053+ xorl %ebp, %esi
22054+ movl 24(%esp), %ebp
22055+ movb %dh, %cl
22056+ andl $0xff, %eax
22057+ andl $0xff, %edx
22058+ movl 0x600+des_SPtrans(%ebx),%ebx
22059+ xorl %ebx, %esi
22060+ movl 0x700+des_SPtrans(%ecx),%ebx
22061+ xorl %ebx, %esi
22062+ movl 0x400+des_SPtrans(%eax),%ebx
22063+ xorl %ebx, %esi
22064+ movl 0x500+des_SPtrans(%edx),%ebx
22065+ xorl %ebx, %esi
22066+
22067+
22068+ movl 88(%ebp), %eax
22069+ xorl %ebx, %ebx
22070+ movl 92(%ebp), %edx
22071+ xorl %esi, %eax
22072+ xorl %esi, %edx
22073+ andl $0xfcfcfcfc, %eax
22074+ andl $0xcfcfcfcf, %edx
22075+ movb %al, %bl
22076+ movb %ah, %cl
22077+ rorl $4, %edx
22078+ movl des_SPtrans(%ebx),%ebp
22079+ movb %dl, %bl
22080+ xorl %ebp, %edi
22081+ movl 0x200+des_SPtrans(%ecx),%ebp
22082+ xorl %ebp, %edi
22083+ movb %dh, %cl
22084+ shrl $16, %eax
22085+ movl 0x100+des_SPtrans(%ebx),%ebp
22086+ xorl %ebp, %edi
22087+ movb %ah, %bl
22088+ shrl $16, %edx
22089+ movl 0x300+des_SPtrans(%ecx),%ebp
22090+ xorl %ebp, %edi
22091+ movl 24(%esp), %ebp
22092+ movb %dh, %cl
22093+ andl $0xff, %eax
22094+ andl $0xff, %edx
22095+ movl 0x600+des_SPtrans(%ebx),%ebx
22096+ xorl %ebx, %edi
22097+ movl 0x700+des_SPtrans(%ecx),%ebx
22098+ xorl %ebx, %edi
22099+ movl 0x400+des_SPtrans(%eax),%ebx
22100+ xorl %ebx, %edi
22101+ movl 0x500+des_SPtrans(%edx),%ebx
22102+ xorl %ebx, %edi
22103+
22104+
22105+ movl 80(%ebp), %eax
22106+ xorl %ebx, %ebx
22107+ movl 84(%ebp), %edx
22108+ xorl %edi, %eax
22109+ xorl %edi, %edx
22110+ andl $0xfcfcfcfc, %eax
22111+ andl $0xcfcfcfcf, %edx
22112+ movb %al, %bl
22113+ movb %ah, %cl
22114+ rorl $4, %edx
22115+ movl des_SPtrans(%ebx),%ebp
22116+ movb %dl, %bl
22117+ xorl %ebp, %esi
22118+ movl 0x200+des_SPtrans(%ecx),%ebp
22119+ xorl %ebp, %esi
22120+ movb %dh, %cl
22121+ shrl $16, %eax
22122+ movl 0x100+des_SPtrans(%ebx),%ebp
22123+ xorl %ebp, %esi
22124+ movb %ah, %bl
22125+ shrl $16, %edx
22126+ movl 0x300+des_SPtrans(%ecx),%ebp
22127+ xorl %ebp, %esi
22128+ movl 24(%esp), %ebp
22129+ movb %dh, %cl
22130+ andl $0xff, %eax
22131+ andl $0xff, %edx
22132+ movl 0x600+des_SPtrans(%ebx),%ebx
22133+ xorl %ebx, %esi
22134+ movl 0x700+des_SPtrans(%ecx),%ebx
22135+ xorl %ebx, %esi
22136+ movl 0x400+des_SPtrans(%eax),%ebx
22137+ xorl %ebx, %esi
22138+ movl 0x500+des_SPtrans(%edx),%ebx
22139+ xorl %ebx, %esi
22140+
22141+
22142+ movl 72(%ebp), %eax
22143+ xorl %ebx, %ebx
22144+ movl 76(%ebp), %edx
22145+ xorl %esi, %eax
22146+ xorl %esi, %edx
22147+ andl $0xfcfcfcfc, %eax
22148+ andl $0xcfcfcfcf, %edx
22149+ movb %al, %bl
22150+ movb %ah, %cl
22151+ rorl $4, %edx
22152+ movl des_SPtrans(%ebx),%ebp
22153+ movb %dl, %bl
22154+ xorl %ebp, %edi
22155+ movl 0x200+des_SPtrans(%ecx),%ebp
22156+ xorl %ebp, %edi
22157+ movb %dh, %cl
22158+ shrl $16, %eax
22159+ movl 0x100+des_SPtrans(%ebx),%ebp
22160+ xorl %ebp, %edi
22161+ movb %ah, %bl
22162+ shrl $16, %edx
22163+ movl 0x300+des_SPtrans(%ecx),%ebp
22164+ xorl %ebp, %edi
22165+ movl 24(%esp), %ebp
22166+ movb %dh, %cl
22167+ andl $0xff, %eax
22168+ andl $0xff, %edx
22169+ movl 0x600+des_SPtrans(%ebx),%ebx
22170+ xorl %ebx, %edi
22171+ movl 0x700+des_SPtrans(%ecx),%ebx
22172+ xorl %ebx, %edi
22173+ movl 0x400+des_SPtrans(%eax),%ebx
22174+ xorl %ebx, %edi
22175+ movl 0x500+des_SPtrans(%edx),%ebx
22176+ xorl %ebx, %edi
22177+
22178+
22179+ movl 64(%ebp), %eax
22180+ xorl %ebx, %ebx
22181+ movl 68(%ebp), %edx
22182+ xorl %edi, %eax
22183+ xorl %edi, %edx
22184+ andl $0xfcfcfcfc, %eax
22185+ andl $0xcfcfcfcf, %edx
22186+ movb %al, %bl
22187+ movb %ah, %cl
22188+ rorl $4, %edx
22189+ movl des_SPtrans(%ebx),%ebp
22190+ movb %dl, %bl
22191+ xorl %ebp, %esi
22192+ movl 0x200+des_SPtrans(%ecx),%ebp
22193+ xorl %ebp, %esi
22194+ movb %dh, %cl
22195+ shrl $16, %eax
22196+ movl 0x100+des_SPtrans(%ebx),%ebp
22197+ xorl %ebp, %esi
22198+ movb %ah, %bl
22199+ shrl $16, %edx
22200+ movl 0x300+des_SPtrans(%ecx),%ebp
22201+ xorl %ebp, %esi
22202+ movl 24(%esp), %ebp
22203+ movb %dh, %cl
22204+ andl $0xff, %eax
22205+ andl $0xff, %edx
22206+ movl 0x600+des_SPtrans(%ebx),%ebx
22207+ xorl %ebx, %esi
22208+ movl 0x700+des_SPtrans(%ecx),%ebx
22209+ xorl %ebx, %esi
22210+ movl 0x400+des_SPtrans(%eax),%ebx
22211+ xorl %ebx, %esi
22212+ movl 0x500+des_SPtrans(%edx),%ebx
22213+ xorl %ebx, %esi
22214+
22215+
22216+ movl 56(%ebp), %eax
22217+ xorl %ebx, %ebx
22218+ movl 60(%ebp), %edx
22219+ xorl %esi, %eax
22220+ xorl %esi, %edx
22221+ andl $0xfcfcfcfc, %eax
22222+ andl $0xcfcfcfcf, %edx
22223+ movb %al, %bl
22224+ movb %ah, %cl
22225+ rorl $4, %edx
22226+ movl des_SPtrans(%ebx),%ebp
22227+ movb %dl, %bl
22228+ xorl %ebp, %edi
22229+ movl 0x200+des_SPtrans(%ecx),%ebp
22230+ xorl %ebp, %edi
22231+ movb %dh, %cl
22232+ shrl $16, %eax
22233+ movl 0x100+des_SPtrans(%ebx),%ebp
22234+ xorl %ebp, %edi
22235+ movb %ah, %bl
22236+ shrl $16, %edx
22237+ movl 0x300+des_SPtrans(%ecx),%ebp
22238+ xorl %ebp, %edi
22239+ movl 24(%esp), %ebp
22240+ movb %dh, %cl
22241+ andl $0xff, %eax
22242+ andl $0xff, %edx
22243+ movl 0x600+des_SPtrans(%ebx),%ebx
22244+ xorl %ebx, %edi
22245+ movl 0x700+des_SPtrans(%ecx),%ebx
22246+ xorl %ebx, %edi
22247+ movl 0x400+des_SPtrans(%eax),%ebx
22248+ xorl %ebx, %edi
22249+ movl 0x500+des_SPtrans(%edx),%ebx
22250+ xorl %ebx, %edi
22251+
22252+
22253+ movl 48(%ebp), %eax
22254+ xorl %ebx, %ebx
22255+ movl 52(%ebp), %edx
22256+ xorl %edi, %eax
22257+ xorl %edi, %edx
22258+ andl $0xfcfcfcfc, %eax
22259+ andl $0xcfcfcfcf, %edx
22260+ movb %al, %bl
22261+ movb %ah, %cl
22262+ rorl $4, %edx
22263+ movl des_SPtrans(%ebx),%ebp
22264+ movb %dl, %bl
22265+ xorl %ebp, %esi
22266+ movl 0x200+des_SPtrans(%ecx),%ebp
22267+ xorl %ebp, %esi
22268+ movb %dh, %cl
22269+ shrl $16, %eax
22270+ movl 0x100+des_SPtrans(%ebx),%ebp
22271+ xorl %ebp, %esi
22272+ movb %ah, %bl
22273+ shrl $16, %edx
22274+ movl 0x300+des_SPtrans(%ecx),%ebp
22275+ xorl %ebp, %esi
22276+ movl 24(%esp), %ebp
22277+ movb %dh, %cl
22278+ andl $0xff, %eax
22279+ andl $0xff, %edx
22280+ movl 0x600+des_SPtrans(%ebx),%ebx
22281+ xorl %ebx, %esi
22282+ movl 0x700+des_SPtrans(%ecx),%ebx
22283+ xorl %ebx, %esi
22284+ movl 0x400+des_SPtrans(%eax),%ebx
22285+ xorl %ebx, %esi
22286+ movl 0x500+des_SPtrans(%edx),%ebx
22287+ xorl %ebx, %esi
22288+
22289+
22290+ movl 40(%ebp), %eax
22291+ xorl %ebx, %ebx
22292+ movl 44(%ebp), %edx
22293+ xorl %esi, %eax
22294+ xorl %esi, %edx
22295+ andl $0xfcfcfcfc, %eax
22296+ andl $0xcfcfcfcf, %edx
22297+ movb %al, %bl
22298+ movb %ah, %cl
22299+ rorl $4, %edx
22300+ movl des_SPtrans(%ebx),%ebp
22301+ movb %dl, %bl
22302+ xorl %ebp, %edi
22303+ movl 0x200+des_SPtrans(%ecx),%ebp
22304+ xorl %ebp, %edi
22305+ movb %dh, %cl
22306+ shrl $16, %eax
22307+ movl 0x100+des_SPtrans(%ebx),%ebp
22308+ xorl %ebp, %edi
22309+ movb %ah, %bl
22310+ shrl $16, %edx
22311+ movl 0x300+des_SPtrans(%ecx),%ebp
22312+ xorl %ebp, %edi
22313+ movl 24(%esp), %ebp
22314+ movb %dh, %cl
22315+ andl $0xff, %eax
22316+ andl $0xff, %edx
22317+ movl 0x600+des_SPtrans(%ebx),%ebx
22318+ xorl %ebx, %edi
22319+ movl 0x700+des_SPtrans(%ecx),%ebx
22320+ xorl %ebx, %edi
22321+ movl 0x400+des_SPtrans(%eax),%ebx
22322+ xorl %ebx, %edi
22323+ movl 0x500+des_SPtrans(%edx),%ebx
22324+ xorl %ebx, %edi
22325+
22326+
22327+ movl 32(%ebp), %eax
22328+ xorl %ebx, %ebx
22329+ movl 36(%ebp), %edx
22330+ xorl %edi, %eax
22331+ xorl %edi, %edx
22332+ andl $0xfcfcfcfc, %eax
22333+ andl $0xcfcfcfcf, %edx
22334+ movb %al, %bl
22335+ movb %ah, %cl
22336+ rorl $4, %edx
22337+ movl des_SPtrans(%ebx),%ebp
22338+ movb %dl, %bl
22339+ xorl %ebp, %esi
22340+ movl 0x200+des_SPtrans(%ecx),%ebp
22341+ xorl %ebp, %esi
22342+ movb %dh, %cl
22343+ shrl $16, %eax
22344+ movl 0x100+des_SPtrans(%ebx),%ebp
22345+ xorl %ebp, %esi
22346+ movb %ah, %bl
22347+ shrl $16, %edx
22348+ movl 0x300+des_SPtrans(%ecx),%ebp
22349+ xorl %ebp, %esi
22350+ movl 24(%esp), %ebp
22351+ movb %dh, %cl
22352+ andl $0xff, %eax
22353+ andl $0xff, %edx
22354+ movl 0x600+des_SPtrans(%ebx),%ebx
22355+ xorl %ebx, %esi
22356+ movl 0x700+des_SPtrans(%ecx),%ebx
22357+ xorl %ebx, %esi
22358+ movl 0x400+des_SPtrans(%eax),%ebx
22359+ xorl %ebx, %esi
22360+ movl 0x500+des_SPtrans(%edx),%ebx
22361+ xorl %ebx, %esi
22362+
22363+
22364+ movl 24(%ebp), %eax
22365+ xorl %ebx, %ebx
22366+ movl 28(%ebp), %edx
22367+ xorl %esi, %eax
22368+ xorl %esi, %edx
22369+ andl $0xfcfcfcfc, %eax
22370+ andl $0xcfcfcfcf, %edx
22371+ movb %al, %bl
22372+ movb %ah, %cl
22373+ rorl $4, %edx
22374+ movl des_SPtrans(%ebx),%ebp
22375+ movb %dl, %bl
22376+ xorl %ebp, %edi
22377+ movl 0x200+des_SPtrans(%ecx),%ebp
22378+ xorl %ebp, %edi
22379+ movb %dh, %cl
22380+ shrl $16, %eax
22381+ movl 0x100+des_SPtrans(%ebx),%ebp
22382+ xorl %ebp, %edi
22383+ movb %ah, %bl
22384+ shrl $16, %edx
22385+ movl 0x300+des_SPtrans(%ecx),%ebp
22386+ xorl %ebp, %edi
22387+ movl 24(%esp), %ebp
22388+ movb %dh, %cl
22389+ andl $0xff, %eax
22390+ andl $0xff, %edx
22391+ movl 0x600+des_SPtrans(%ebx),%ebx
22392+ xorl %ebx, %edi
22393+ movl 0x700+des_SPtrans(%ecx),%ebx
22394+ xorl %ebx, %edi
22395+ movl 0x400+des_SPtrans(%eax),%ebx
22396+ xorl %ebx, %edi
22397+ movl 0x500+des_SPtrans(%edx),%ebx
22398+ xorl %ebx, %edi
22399+
22400+
22401+ movl 16(%ebp), %eax
22402+ xorl %ebx, %ebx
22403+ movl 20(%ebp), %edx
22404+ xorl %edi, %eax
22405+ xorl %edi, %edx
22406+ andl $0xfcfcfcfc, %eax
22407+ andl $0xcfcfcfcf, %edx
22408+ movb %al, %bl
22409+ movb %ah, %cl
22410+ rorl $4, %edx
22411+ movl des_SPtrans(%ebx),%ebp
22412+ movb %dl, %bl
22413+ xorl %ebp, %esi
22414+ movl 0x200+des_SPtrans(%ecx),%ebp
22415+ xorl %ebp, %esi
22416+ movb %dh, %cl
22417+ shrl $16, %eax
22418+ movl 0x100+des_SPtrans(%ebx),%ebp
22419+ xorl %ebp, %esi
22420+ movb %ah, %bl
22421+ shrl $16, %edx
22422+ movl 0x300+des_SPtrans(%ecx),%ebp
22423+ xorl %ebp, %esi
22424+ movl 24(%esp), %ebp
22425+ movb %dh, %cl
22426+ andl $0xff, %eax
22427+ andl $0xff, %edx
22428+ movl 0x600+des_SPtrans(%ebx),%ebx
22429+ xorl %ebx, %esi
22430+ movl 0x700+des_SPtrans(%ecx),%ebx
22431+ xorl %ebx, %esi
22432+ movl 0x400+des_SPtrans(%eax),%ebx
22433+ xorl %ebx, %esi
22434+ movl 0x500+des_SPtrans(%edx),%ebx
22435+ xorl %ebx, %esi
22436+
22437+
22438+ movl 8(%ebp), %eax
22439+ xorl %ebx, %ebx
22440+ movl 12(%ebp), %edx
22441+ xorl %esi, %eax
22442+ xorl %esi, %edx
22443+ andl $0xfcfcfcfc, %eax
22444+ andl $0xcfcfcfcf, %edx
22445+ movb %al, %bl
22446+ movb %ah, %cl
22447+ rorl $4, %edx
22448+ movl des_SPtrans(%ebx),%ebp
22449+ movb %dl, %bl
22450+ xorl %ebp, %edi
22451+ movl 0x200+des_SPtrans(%ecx),%ebp
22452+ xorl %ebp, %edi
22453+ movb %dh, %cl
22454+ shrl $16, %eax
22455+ movl 0x100+des_SPtrans(%ebx),%ebp
22456+ xorl %ebp, %edi
22457+ movb %ah, %bl
22458+ shrl $16, %edx
22459+ movl 0x300+des_SPtrans(%ecx),%ebp
22460+ xorl %ebp, %edi
22461+ movl 24(%esp), %ebp
22462+ movb %dh, %cl
22463+ andl $0xff, %eax
22464+ andl $0xff, %edx
22465+ movl 0x600+des_SPtrans(%ebx),%ebx
22466+ xorl %ebx, %edi
22467+ movl 0x700+des_SPtrans(%ecx),%ebx
22468+ xorl %ebx, %edi
22469+ movl 0x400+des_SPtrans(%eax),%ebx
22470+ xorl %ebx, %edi
22471+ movl 0x500+des_SPtrans(%edx),%ebx
22472+ xorl %ebx, %edi
22473+
22474+
22475+ movl (%ebp), %eax
22476+ xorl %ebx, %ebx
22477+ movl 4(%ebp), %edx
22478+ xorl %edi, %eax
22479+ xorl %edi, %edx
22480+ andl $0xfcfcfcfc, %eax
22481+ andl $0xcfcfcfcf, %edx
22482+ movb %al, %bl
22483+ movb %ah, %cl
22484+ rorl $4, %edx
22485+ movl des_SPtrans(%ebx),%ebp
22486+ movb %dl, %bl
22487+ xorl %ebp, %esi
22488+ movl 0x200+des_SPtrans(%ecx),%ebp
22489+ xorl %ebp, %esi
22490+ movb %dh, %cl
22491+ shrl $16, %eax
22492+ movl 0x100+des_SPtrans(%ebx),%ebp
22493+ xorl %ebp, %esi
22494+ movb %ah, %bl
22495+ shrl $16, %edx
22496+ movl 0x300+des_SPtrans(%ecx),%ebp
22497+ xorl %ebp, %esi
22498+ movl 24(%esp), %ebp
22499+ movb %dh, %cl
22500+ andl $0xff, %eax
22501+ andl $0xff, %edx
22502+ movl 0x600+des_SPtrans(%ebx),%ebx
22503+ xorl %ebx, %esi
22504+ movl 0x700+des_SPtrans(%ecx),%ebx
22505+ xorl %ebx, %esi
22506+ movl 0x400+des_SPtrans(%eax),%ebx
22507+ xorl %ebx, %esi
22508+ movl 0x500+des_SPtrans(%edx),%ebx
22509+ xorl %ebx, %esi
22510+.L003end:
22511+
22512+
22513+ rorl $3, %edi
22514+ movl 20(%esp), %eax
22515+ rorl $3, %esi
22516+ movl %edi, (%eax)
22517+ movl %esi, 4(%eax)
22518+ popl %ebp
22519+ popl %ebx
22520+ popl %edi
22521+ popl %esi
22522+ ret
22523+.des_encrypt2_end:
22524+ .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
22525+.ident "desasm.pl"
22526+.text
22527+ .align 16
22528+.globl des_encrypt3
22529+ .type des_encrypt3 , @function
22530+des_encrypt3:
22531+ pushl %ebx
22532+ movl 8(%esp), %ebx
22533+ pushl %ebp
22534+ pushl %esi
22535+ pushl %edi
22536+
22537+
22538+ movl (%ebx), %edi
22539+ movl 4(%ebx), %esi
22540+ subl $12, %esp
22541+
22542+
22543+ roll $4, %edi
22544+ movl %edi, %edx
22545+ xorl %esi, %edi
22546+ andl $0xf0f0f0f0, %edi
22547+ xorl %edi, %edx
22548+ xorl %edi, %esi
22549+
22550+ roll $20, %esi
22551+ movl %esi, %edi
22552+ xorl %edx, %esi
22553+ andl $0xfff0000f, %esi
22554+ xorl %esi, %edi
22555+ xorl %esi, %edx
22556+
22557+ roll $14, %edi
22558+ movl %edi, %esi
22559+ xorl %edx, %edi
22560+ andl $0x33333333, %edi
22561+ xorl %edi, %esi
22562+ xorl %edi, %edx
22563+
22564+ roll $22, %edx
22565+ movl %edx, %edi
22566+ xorl %esi, %edx
22567+ andl $0x03fc03fc, %edx
22568+ xorl %edx, %edi
22569+ xorl %edx, %esi
22570+
22571+ roll $9, %edi
22572+ movl %edi, %edx
22573+ xorl %esi, %edi
22574+ andl $0xaaaaaaaa, %edi
22575+ xorl %edi, %edx
22576+ xorl %edi, %esi
22577+
22578+ rorl $3, %edx
22579+ rorl $2, %esi
22580+ movl %esi, 4(%ebx)
22581+ movl 36(%esp), %eax
22582+ movl %edx, (%ebx)
22583+ movl 40(%esp), %edi
22584+ movl 44(%esp), %esi
22585+ movl $1, 8(%esp)
22586+ movl %eax, 4(%esp)
22587+ movl %ebx, (%esp)
22588+ call des_encrypt2
22589+ movl $0, 8(%esp)
22590+ movl %edi, 4(%esp)
22591+ movl %ebx, (%esp)
22592+ call des_encrypt2
22593+ movl $1, 8(%esp)
22594+ movl %esi, 4(%esp)
22595+ movl %ebx, (%esp)
22596+ call des_encrypt2
22597+ addl $12, %esp
22598+ movl (%ebx), %edi
22599+ movl 4(%ebx), %esi
22600+
22601+
22602+ roll $2, %esi
22603+ roll $3, %edi
22604+ movl %edi, %eax
22605+ xorl %esi, %edi
22606+ andl $0xaaaaaaaa, %edi
22607+ xorl %edi, %eax
22608+ xorl %edi, %esi
22609+
22610+ roll $23, %eax
22611+ movl %eax, %edi
22612+ xorl %esi, %eax
22613+ andl $0x03fc03fc, %eax
22614+ xorl %eax, %edi
22615+ xorl %eax, %esi
22616+
22617+ roll $10, %edi
22618+ movl %edi, %eax
22619+ xorl %esi, %edi
22620+ andl $0x33333333, %edi
22621+ xorl %edi, %eax
22622+ xorl %edi, %esi
22623+
22624+ roll $18, %esi
22625+ movl %esi, %edi
22626+ xorl %eax, %esi
22627+ andl $0xfff0000f, %esi
22628+ xorl %esi, %edi
22629+ xorl %esi, %eax
22630+
22631+ roll $12, %edi
22632+ movl %edi, %esi
22633+ xorl %eax, %edi
22634+ andl $0xf0f0f0f0, %edi
22635+ xorl %edi, %esi
22636+ xorl %edi, %eax
22637+
22638+ rorl $4, %eax
22639+ movl %eax, (%ebx)
22640+ movl %esi, 4(%ebx)
22641+ popl %edi
22642+ popl %esi
22643+ popl %ebp
22644+ popl %ebx
22645+ ret
22646+.des_encrypt3_end:
22647+ .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
22648+.ident "desasm.pl"
22649+.text
22650+ .align 16
22651+.globl des_decrypt3
22652+ .type des_decrypt3 , @function
22653+des_decrypt3:
22654+ pushl %ebx
22655+ movl 8(%esp), %ebx
22656+ pushl %ebp
22657+ pushl %esi
22658+ pushl %edi
22659+
22660+
22661+ movl (%ebx), %edi
22662+ movl 4(%ebx), %esi
22663+ subl $12, %esp
22664+
22665+
22666+ roll $4, %edi
22667+ movl %edi, %edx
22668+ xorl %esi, %edi
22669+ andl $0xf0f0f0f0, %edi
22670+ xorl %edi, %edx
22671+ xorl %edi, %esi
22672+
22673+ roll $20, %esi
22674+ movl %esi, %edi
22675+ xorl %edx, %esi
22676+ andl $0xfff0000f, %esi
22677+ xorl %esi, %edi
22678+ xorl %esi, %edx
22679+
22680+ roll $14, %edi
22681+ movl %edi, %esi
22682+ xorl %edx, %edi
22683+ andl $0x33333333, %edi
22684+ xorl %edi, %esi
22685+ xorl %edi, %edx
22686+
22687+ roll $22, %edx
22688+ movl %edx, %edi
22689+ xorl %esi, %edx
22690+ andl $0x03fc03fc, %edx
22691+ xorl %edx, %edi
22692+ xorl %edx, %esi
22693+
22694+ roll $9, %edi
22695+ movl %edi, %edx
22696+ xorl %esi, %edi
22697+ andl $0xaaaaaaaa, %edi
22698+ xorl %edi, %edx
22699+ xorl %edi, %esi
22700+
22701+ rorl $3, %edx
22702+ rorl $2, %esi
22703+ movl %esi, 4(%ebx)
22704+ movl 36(%esp), %esi
22705+ movl %edx, (%ebx)
22706+ movl 40(%esp), %edi
22707+ movl 44(%esp), %eax
22708+ movl $0, 8(%esp)
22709+ movl %eax, 4(%esp)
22710+ movl %ebx, (%esp)
22711+ call des_encrypt2
22712+ movl $1, 8(%esp)
22713+ movl %edi, 4(%esp)
22714+ movl %ebx, (%esp)
22715+ call des_encrypt2
22716+ movl $0, 8(%esp)
22717+ movl %esi, 4(%esp)
22718+ movl %ebx, (%esp)
22719+ call des_encrypt2
22720+ addl $12, %esp
22721+ movl (%ebx), %edi
22722+ movl 4(%ebx), %esi
22723+
22724+
22725+ roll $2, %esi
22726+ roll $3, %edi
22727+ movl %edi, %eax
22728+ xorl %esi, %edi
22729+ andl $0xaaaaaaaa, %edi
22730+ xorl %edi, %eax
22731+ xorl %edi, %esi
22732+
22733+ roll $23, %eax
22734+ movl %eax, %edi
22735+ xorl %esi, %eax
22736+ andl $0x03fc03fc, %eax
22737+ xorl %eax, %edi
22738+ xorl %eax, %esi
22739+
22740+ roll $10, %edi
22741+ movl %edi, %eax
22742+ xorl %esi, %edi
22743+ andl $0x33333333, %edi
22744+ xorl %edi, %eax
22745+ xorl %edi, %esi
22746+
22747+ roll $18, %esi
22748+ movl %esi, %edi
22749+ xorl %eax, %esi
22750+ andl $0xfff0000f, %esi
22751+ xorl %esi, %edi
22752+ xorl %esi, %eax
22753+
22754+ roll $12, %edi
22755+ movl %edi, %esi
22756+ xorl %eax, %edi
22757+ andl $0xf0f0f0f0, %edi
22758+ xorl %edi, %esi
22759+ xorl %edi, %eax
22760+
22761+ rorl $4, %eax
22762+ movl %eax, (%ebx)
22763+ movl %esi, 4(%ebx)
22764+ popl %edi
22765+ popl %esi
22766+ popl %ebp
22767+ popl %ebx
22768+ ret
22769+.des_decrypt3_end:
22770+ .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
22771+.ident "desasm.pl"
22772+.text
22773+ .align 16
22774+.globl des_ncbc_encrypt
22775+ .type des_ncbc_encrypt , @function
22776+des_ncbc_encrypt:
22777+
22778+ pushl %ebp
22779+ pushl %ebx
22780+ pushl %esi
22781+ pushl %edi
22782+ movl 28(%esp), %ebp
22783+
22784+ movl 36(%esp), %ebx
22785+ movl (%ebx), %esi
22786+ movl 4(%ebx), %edi
22787+ pushl %edi
22788+ pushl %esi
22789+ pushl %edi
22790+ pushl %esi
22791+ movl %esp, %ebx
22792+ movl 36(%esp), %esi
22793+ movl 40(%esp), %edi
22794+
22795+ movl 56(%esp), %ecx
22796+
22797+ pushl %ecx
22798+
22799+ movl 52(%esp), %eax
22800+ pushl %eax
22801+ pushl %ebx
22802+ cmpl $0, %ecx
22803+ jz .L004decrypt
22804+ andl $4294967288, %ebp
22805+ movl 12(%esp), %eax
22806+ movl 16(%esp), %ebx
22807+ jz .L005encrypt_finish
22808+.L006encrypt_loop:
22809+ movl (%esi), %ecx
22810+ movl 4(%esi), %edx
22811+ xorl %ecx, %eax
22812+ xorl %edx, %ebx
22813+ movl %eax, 12(%esp)
22814+ movl %ebx, 16(%esp)
22815+ call des_encrypt
22816+ movl 12(%esp), %eax
22817+ movl 16(%esp), %ebx
22818+ movl %eax, (%edi)
22819+ movl %ebx, 4(%edi)
22820+ addl $8, %esi
22821+ addl $8, %edi
22822+ subl $8, %ebp
22823+ jnz .L006encrypt_loop
22824+.L005encrypt_finish:
22825+ movl 56(%esp), %ebp
22826+ andl $7, %ebp
22827+ jz .L007finish
22828+ xorl %ecx, %ecx
22829+ xorl %edx, %edx
22830+ movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
22831+ jmp *%ebp
22832+.L009ej7:
22833+ movb 6(%esi), %dh
22834+ sall $8, %edx
22835+.L010ej6:
22836+ movb 5(%esi), %dh
22837+.L011ej5:
22838+ movb 4(%esi), %dl
22839+.L012ej4:
22840+ movl (%esi), %ecx
22841+ jmp .L013ejend
22842+.L014ej3:
22843+ movb 2(%esi), %ch
22844+ sall $8, %ecx
22845+.L015ej2:
22846+ movb 1(%esi), %ch
22847+.L016ej1:
22848+ movb (%esi), %cl
22849+.L013ejend:
22850+ xorl %ecx, %eax
22851+ xorl %edx, %ebx
22852+ movl %eax, 12(%esp)
22853+ movl %ebx, 16(%esp)
22854+ call des_encrypt
22855+ movl 12(%esp), %eax
22856+ movl 16(%esp), %ebx
22857+ movl %eax, (%edi)
22858+ movl %ebx, 4(%edi)
22859+ jmp .L007finish
22860+.align 16
22861+.L004decrypt:
22862+ andl $4294967288, %ebp
22863+ movl 20(%esp), %eax
22864+ movl 24(%esp), %ebx
22865+ jz .L017decrypt_finish
22866+.L018decrypt_loop:
22867+ movl (%esi), %eax
22868+ movl 4(%esi), %ebx
22869+ movl %eax, 12(%esp)
22870+ movl %ebx, 16(%esp)
22871+ call des_encrypt
22872+ movl 12(%esp), %eax
22873+ movl 16(%esp), %ebx
22874+ movl 20(%esp), %ecx
22875+ movl 24(%esp), %edx
22876+ xorl %eax, %ecx
22877+ xorl %ebx, %edx
22878+ movl (%esi), %eax
22879+ movl 4(%esi), %ebx
22880+ movl %ecx, (%edi)
22881+ movl %edx, 4(%edi)
22882+ movl %eax, 20(%esp)
22883+ movl %ebx, 24(%esp)
22884+ addl $8, %esi
22885+ addl $8, %edi
22886+ subl $8, %ebp
22887+ jnz .L018decrypt_loop
22888+.L017decrypt_finish:
22889+ movl 56(%esp), %ebp
22890+ andl $7, %ebp
22891+ jz .L007finish
22892+ movl (%esi), %eax
22893+ movl 4(%esi), %ebx
22894+ movl %eax, 12(%esp)
22895+ movl %ebx, 16(%esp)
22896+ call des_encrypt
22897+ movl 12(%esp), %eax
22898+ movl 16(%esp), %ebx
22899+ movl 20(%esp), %ecx
22900+ movl 24(%esp), %edx
22901+ xorl %eax, %ecx
22902+ xorl %ebx, %edx
22903+ movl (%esi), %eax
22904+ movl 4(%esi), %ebx
22905+.L019dj7:
22906+ rorl $16, %edx
22907+ movb %dl, 6(%edi)
22908+ shrl $16, %edx
22909+.L020dj6:
22910+ movb %dh, 5(%edi)
22911+.L021dj5:
22912+ movb %dl, 4(%edi)
22913+.L022dj4:
22914+ movl %ecx, (%edi)
22915+ jmp .L023djend
22916+.L024dj3:
22917+ rorl $16, %ecx
22918+ movb %cl, 2(%edi)
22919+ sall $16, %ecx
22920+.L025dj2:
22921+ movb %ch, 1(%esi)
22922+.L026dj1:
22923+ movb %cl, (%esi)
22924+.L023djend:
22925+ jmp .L007finish
22926+.align 16
22927+.L007finish:
22928+ movl 64(%esp), %ecx
22929+ addl $28, %esp
22930+ movl %eax, (%ecx)
22931+ movl %ebx, 4(%ecx)
22932+ popl %edi
22933+ popl %esi
22934+ popl %ebx
22935+ popl %ebp
22936+ ret
22937+.align 16
22938+.L008cbc_enc_jmp_table:
22939+ .long 0
22940+ .long .L016ej1
22941+ .long .L015ej2
22942+ .long .L014ej3
22943+ .long .L012ej4
22944+ .long .L011ej5
22945+ .long .L010ej6
22946+ .long .L009ej7
22947+.align 16
22948+.L027cbc_dec_jmp_table:
22949+ .long 0
22950+ .long .L026dj1
22951+ .long .L025dj2
22952+ .long .L024dj3
22953+ .long .L022dj4
22954+ .long .L021dj5
22955+ .long .L020dj6
22956+ .long .L019dj7
22957+.des_ncbc_encrypt_end:
22958+ .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
22959+.ident "desasm.pl"
22960+.text
22961+ .align 16
22962+.globl des_ede3_cbc_encrypt
22963+ .type des_ede3_cbc_encrypt , @function
22964+des_ede3_cbc_encrypt:
22965+
22966+ pushl %ebp
22967+ pushl %ebx
22968+ pushl %esi
22969+ pushl %edi
22970+ movl 28(%esp), %ebp
22971+
22972+ movl 44(%esp), %ebx
22973+ movl (%ebx), %esi
22974+ movl 4(%ebx), %edi
22975+ pushl %edi
22976+ pushl %esi
22977+ pushl %edi
22978+ pushl %esi
22979+ movl %esp, %ebx
22980+ movl 36(%esp), %esi
22981+ movl 40(%esp), %edi
22982+
22983+ movl 64(%esp), %ecx
22984+
22985+ movl 56(%esp), %eax
22986+ pushl %eax
22987+
22988+ movl 56(%esp), %eax
22989+ pushl %eax
22990+
22991+ movl 56(%esp), %eax
22992+ pushl %eax
22993+ pushl %ebx
22994+ cmpl $0, %ecx
22995+ jz .L028decrypt
22996+ andl $4294967288, %ebp
22997+ movl 16(%esp), %eax
22998+ movl 20(%esp), %ebx
22999+ jz .L029encrypt_finish
23000+.L030encrypt_loop:
23001+ movl (%esi), %ecx
23002+ movl 4(%esi), %edx
23003+ xorl %ecx, %eax
23004+ xorl %edx, %ebx
23005+ movl %eax, 16(%esp)
23006+ movl %ebx, 20(%esp)
23007+ call des_encrypt3
23008+ movl 16(%esp), %eax
23009+ movl 20(%esp), %ebx
23010+ movl %eax, (%edi)
23011+ movl %ebx, 4(%edi)
23012+ addl $8, %esi
23013+ addl $8, %edi
23014+ subl $8, %ebp
23015+ jnz .L030encrypt_loop
23016+.L029encrypt_finish:
23017+ movl 60(%esp), %ebp
23018+ andl $7, %ebp
23019+ jz .L031finish
23020+ xorl %ecx, %ecx
23021+ xorl %edx, %edx
23022+ movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
23023+ jmp *%ebp
23024+.L033ej7:
23025+ movb 6(%esi), %dh
23026+ sall $8, %edx
23027+.L034ej6:
23028+ movb 5(%esi), %dh
23029+.L035ej5:
23030+ movb 4(%esi), %dl
23031+.L036ej4:
23032+ movl (%esi), %ecx
23033+ jmp .L037ejend
23034+.L038ej3:
23035+ movb 2(%esi), %ch
23036+ sall $8, %ecx
23037+.L039ej2:
23038+ movb 1(%esi), %ch
23039+.L040ej1:
23040+ movb (%esi), %cl
23041+.L037ejend:
23042+ xorl %ecx, %eax
23043+ xorl %edx, %ebx
23044+ movl %eax, 16(%esp)
23045+ movl %ebx, 20(%esp)
23046+ call des_encrypt3
23047+ movl 16(%esp), %eax
23048+ movl 20(%esp), %ebx
23049+ movl %eax, (%edi)
23050+ movl %ebx, 4(%edi)
23051+ jmp .L031finish
23052+.align 16
23053+.L028decrypt:
23054+ andl $4294967288, %ebp
23055+ movl 24(%esp), %eax
23056+ movl 28(%esp), %ebx
23057+ jz .L041decrypt_finish
23058+.L042decrypt_loop:
23059+ movl (%esi), %eax
23060+ movl 4(%esi), %ebx
23061+ movl %eax, 16(%esp)
23062+ movl %ebx, 20(%esp)
23063+ call des_decrypt3
23064+ movl 16(%esp), %eax
23065+ movl 20(%esp), %ebx
23066+ movl 24(%esp), %ecx
23067+ movl 28(%esp), %edx
23068+ xorl %eax, %ecx
23069+ xorl %ebx, %edx
23070+ movl (%esi), %eax
23071+ movl 4(%esi), %ebx
23072+ movl %ecx, (%edi)
23073+ movl %edx, 4(%edi)
23074+ movl %eax, 24(%esp)
23075+ movl %ebx, 28(%esp)
23076+ addl $8, %esi
23077+ addl $8, %edi
23078+ subl $8, %ebp
23079+ jnz .L042decrypt_loop
23080+.L041decrypt_finish:
23081+ movl 60(%esp), %ebp
23082+ andl $7, %ebp
23083+ jz .L031finish
23084+ movl (%esi), %eax
23085+ movl 4(%esi), %ebx
23086+ movl %eax, 16(%esp)
23087+ movl %ebx, 20(%esp)
23088+ call des_decrypt3
23089+ movl 16(%esp), %eax
23090+ movl 20(%esp), %ebx
23091+ movl 24(%esp), %ecx
23092+ movl 28(%esp), %edx
23093+ xorl %eax, %ecx
23094+ xorl %ebx, %edx
23095+ movl (%esi), %eax
23096+ movl 4(%esi), %ebx
23097+.L043dj7:
23098+ rorl $16, %edx
23099+ movb %dl, 6(%edi)
23100+ shrl $16, %edx
23101+.L044dj6:
23102+ movb %dh, 5(%edi)
23103+.L045dj5:
23104+ movb %dl, 4(%edi)
23105+.L046dj4:
23106+ movl %ecx, (%edi)
23107+ jmp .L047djend
23108+.L048dj3:
23109+ rorl $16, %ecx
23110+ movb %cl, 2(%edi)
23111+ sall $16, %ecx
23112+.L049dj2:
23113+ movb %ch, 1(%esi)
23114+.L050dj1:
23115+ movb %cl, (%esi)
23116+.L047djend:
23117+ jmp .L031finish
23118+.align 16
23119+.L031finish:
23120+ movl 76(%esp), %ecx
23121+ addl $32, %esp
23122+ movl %eax, (%ecx)
23123+ movl %ebx, 4(%ecx)
23124+ popl %edi
23125+ popl %esi
23126+ popl %ebx
23127+ popl %ebp
23128+ ret
23129+.align 16
23130+.L032cbc_enc_jmp_table:
23131+ .long 0
23132+ .long .L040ej1
23133+ .long .L039ej2
23134+ .long .L038ej3
23135+ .long .L036ej4
23136+ .long .L035ej5
23137+ .long .L034ej6
23138+ .long .L033ej7
23139+.align 16
23140+.L051cbc_dec_jmp_table:
23141+ .long 0
23142+ .long .L050dj1
23143+ .long .L049dj2
23144+ .long .L048dj3
23145+ .long .L046dj4
23146+ .long .L045dj5
23147+ .long .L044dj6
23148+ .long .L043dj7
23149+.des_ede3_cbc_encrypt_end:
23150+ .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
23151+.ident "desasm.pl"
23152--- /dev/null Tue Mar 11 13:02:56 2003
23153+++ linux/net/ipsec/des/ecb_enc.c Mon Feb 9 13:51:03 2004
23154@@ -0,0 +1,128 @@
23155+/* crypto/des/ecb_enc.c */
23156+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
23157+ * All rights reserved.
23158+ *
23159+ * This package is an SSL implementation written
23160+ * by Eric Young (eay@cryptsoft.com).
23161+ * The implementation was written so as to conform with Netscapes SSL.
23162+ *
23163+ * This library is free for commercial and non-commercial use as long as
23164+ * the following conditions are aheared to. The following conditions
23165+ * apply to all code found in this distribution, be it the RC4, RSA,
23166+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
23167+ * included with this distribution is covered by the same copyright terms
23168+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
23169+ *
23170+ * Copyright remains Eric Young's, and as such any Copyright notices in
23171+ * the code are not to be removed.
23172+ * If this package is used in a product, Eric Young should be given attribution
23173+ * as the author of the parts of the library used.
23174+ * This can be in the form of a textual message at program startup or
23175+ * in documentation (online or textual) provided with the package.
23176+ *
23177+ * Redistribution and use in source and binary forms, with or without
23178+ * modification, are permitted provided that the following conditions
23179+ * are met:
23180+ * 1. Redistributions of source code must retain the copyright
23181+ * notice, this list of conditions and the following disclaimer.
23182+ * 2. Redistributions in binary form must reproduce the above copyright
23183+ * notice, this list of conditions and the following disclaimer in the
23184+ * documentation and/or other materials provided with the distribution.
23185+ * 3. All advertising materials mentioning features or use of this software
23186+ * must display the following acknowledgement:
23187+ * "This product includes cryptographic software written by
23188+ * Eric Young (eay@cryptsoft.com)"
23189+ * The word 'cryptographic' can be left out if the rouines from the library
23190+ * being used are not cryptographic related :-).
23191+ * 4. If you include any Windows specific code (or a derivative thereof) from
23192+ * the apps directory (application code) you must include an acknowledgement:
23193+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
23194+ *
23195+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
23196+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23197+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23198+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23199+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23200+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23201+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23202+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23203+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23204+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23205+ * SUCH DAMAGE.
23206+ *
23207+ * The licence and distribution terms for any publically available version or
23208+ * derivative of this code cannot be changed. i.e. this code cannot simply be
23209+ * copied and put under another distribution licence
23210+ * [including the GNU Public Licence.]
23211+ */
23212+
23213+#include "des/des_locl.h"
23214+#include "des/spr.h"
23215+
23216+char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
23217+char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
23218+
23219+/* RCSID $Id: ecb_enc.c,v 1.8 2004-08-04 15:57:22 mcr Exp $ */
23220+/* This function ifdef'ed out for FreeS/WAN project. */
23221+#ifdef notdef
23222+char *des_options()
23223+ {
23224+ static int init=1;
23225+ static char buf[32];
23226+
23227+ if (init)
23228+ {
23229+ char *ptr,*unroll,*risc,*size;
23230+
23231+ init=0;
23232+#ifdef DES_PTR
23233+ ptr="ptr";
23234+#else
23235+ ptr="idx";
23236+#endif
23237+#if defined(DES_RISC1) || defined(DES_RISC2)
23238+#ifdef DES_RISC1
23239+ risc="risc1";
23240+#endif
23241+#ifdef DES_RISC2
23242+ risc="risc2";
23243+#endif
23244+#else
23245+ risc="cisc";
23246+#endif
23247+#ifdef DES_UNROLL
23248+ unroll="16";
23249+#else
23250+ unroll="4";
23251+#endif
23252+ if (sizeof(DES_LONG) != sizeof(long))
23253+ size="int";
23254+ else
23255+ size="long";
23256+ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
23257+ }
23258+ return(buf);
23259+ }
23260+#endif
23261+
23262+
23263+void des_ecb_encrypt(input, output, ks, enc)
23264+des_cblock (*input);
23265+des_cblock (*output);
23266+des_key_schedule ks;
23267+int enc;
23268+ {
23269+ register DES_LONG l;
23270+ register unsigned char *in,*out;
23271+ DES_LONG ll[2];
23272+
23273+ in=(unsigned char *)input;
23274+ out=(unsigned char *)output;
23275+ c2l(in,l); ll[0]=l;
23276+ c2l(in,l); ll[1]=l;
23277+ des_encrypt(ll,ks,enc);
23278+ l=ll[0]; l2c(l,out);
23279+ l=ll[1]; l2c(l,out);
23280+ l=ll[0]=ll[1]=0;
23281+ }
23282+
23283--- /dev/null Tue Mar 11 13:02:56 2003
23284+++ linux/net/ipsec/des/ipsec_alg_3des.c Mon Feb 9 13:51:03 2004
23285@@ -0,0 +1,181 @@
23286+/*
23287+ * ipsec_alg 3DES cipher stubs
23288+ *
23289+ * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
23290+ *
23291+ * Adapted from ipsec_alg_aes.c by JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
23292+ *
23293+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
23294+ *
23295+ * This program is free software; you can redistribute it and/or modify it
23296+ * under the terms of the GNU General Public License as published by the
23297+ * Free Software Foundation; either version 2 of the License, or (at your
23298+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
23299+ *
23300+ * This program is distributed in the hope that it will be useful, but
23301+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23302+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23303+ * for more details.
23304+ *
23305+ */
23306+#ifndef AUTOCONF_INCLUDED
23307+#include <linux/config.h>
23308+#endif
23309+#include <linux/version.h>
23310+
23311+/*
23312+ * special case: ipsec core modular with this static algo inside:
23313+ * must avoid MODULE magic for this file
23314+ */
23315+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_3DES)
23316+#undef MODULE
23317+#endif
23318+
23319+#include <linux/module.h>
23320+#include <linux/init.h>
23321+
23322+#include <linux/kernel.h> /* printk() */
23323+#include <linux/errno.h> /* error codes */
23324+#include <linux/types.h> /* size_t */
23325+#include <linux/string.h>
23326+
23327+/* Low freeswan header coupling */
23328+#include "openswan/ipsec_xform.h"
23329+#include "openswan/ipsec_alg.h"
23330+#include "crypto/des.h"
23331+#include "openswan/ipsec_alg_3des.h"
23332+
23333+#define AES_CONTEXT_T aes_context
23334+static int debug_3des=0;
23335+static int test_3des=0;
23336+static int excl_3des=0;
23337+
23338+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23339+MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
23340+#ifdef module_param
23341+module_param(debug_3des,int,0600)
23342+module_param(test_des,int,0600)
23343+module_param(excl_des,int,0600)
23344+#else
23345+MODULE_PARM(debug_3des, "i");
23346+MODULE_PARM(test_des, "i");
23347+MODULE_PARM(excl_des, "i");
23348+#endif
23349+#endif
23350+
23351+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
23352+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
23353+
23354+static int _3des_set_key(struct ipsec_alg_enc *alg,
23355+ __u8 * key_e, const __u8 * key,
23356+ size_t keysize)
23357+{
23358+ int ret = 0;
23359+ TripleDES_context *ctx = (TripleDES_context*)key_e;
23360+
23361+ if(keysize != 192/8) {
23362+ return EINVAL;
23363+ }
23364+
23365+ des_set_key((des_cblock *)(key + DES_KEY_SZ*0), ctx->s1);
23366+ des_set_key((des_cblock *)(key + DES_KEY_SZ*1), ctx->s2);
23367+ des_set_key((des_cblock *)(key + DES_KEY_SZ*2), ctx->s3);
23368+
23369+ if (debug_3des > 0)
23370+ printk(KERN_DEBUG "klips_debug:_3des_set_key:"
23371+ "ret=%d key_e=%p key=%p keysize=%ld\n",
23372+ ret, key_e, key, (unsigned long int) keysize);
23373+ return ret;
23374+}
23375+
23376+static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg,
23377+ __u8 * key_e,
23378+ __u8 * in,
23379+ int ilen, const __u8 * iv,
23380+ int encrypt)
23381+{
23382+ TripleDES_context *ctx=(TripleDES_context*)key_e;
23383+ des_cblock miv;
23384+
23385+ memcpy(&miv, iv, sizeof(miv));
23386+
23387+ if (debug_3des > 0)
23388+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
23389+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
23390+ key_e, in, ilen, iv, encrypt);
23391+
23392+ des_ede3_cbc_encrypt((des_cblock *)in,
23393+ (des_cblock *)in,
23394+ ilen,
23395+ ctx->s1,
23396+ ctx->s2,
23397+ ctx->s3,
23398+ &miv, encrypt);
23399+ return 1;
23400+}
23401+
23402+static struct ipsec_alg_enc ipsec_alg_3DES = {
23403+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
23404+ ixt_refcnt: ATOMIC_INIT(0),
23405+ ixt_name: "3des",
23406+ ixt_blocksize: ESP_3DES_CBC_BLK_LEN,
23407+ ixt_support: {
23408+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
23409+ ias_id: ESP_3DES,
23410+ ias_keyminbits: ESP_3DES_KEY_SZ*8,
23411+ ias_keymaxbits: ESP_3DES_KEY_SZ*8,
23412+ },
23413+ },
23414+#if defined(MODULE_KLIPS_ENC_3DES_MODULE)
23415+ ixt_module: THIS_MODULE,
23416+#endif
23417+ ixt_e_keylen: ESP_3DES_KEY_SZ*8,
23418+ ixt_e_ctx_size: sizeof(TripleDES_context),
23419+ ixt_e_set_key: _3des_set_key,
23420+ ixt_e_cbc_encrypt:_3des_cbc_encrypt,
23421+};
23422+
23423+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23424+IPSEC_ALG_MODULE_INIT_MOD( ipsec_3des_init )
23425+#else
23426+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_3des_init )
23427+#endif
23428+{
23429+ int ret, test_ret;
23430+
23431+ if (excl_3des) ipsec_alg_3DES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
23432+ ret=register_ipsec_alg_enc(&ipsec_alg_3DES);
23433+ printk("ipsec_3des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
23434+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23435+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23436+ ipsec_alg_3DES.ixt_common.ixt_name,
23437+ ret);
23438+ if (ret==0 && test_3des) {
23439+ test_ret=ipsec_alg_test(
23440+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23441+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23442+ test_3des);
23443+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
23444+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23445+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23446+ test_ret);
23447+ }
23448+ return ret;
23449+}
23450+
23451+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23452+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_3des_fini )
23453+#else
23454+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_3des_fini )
23455+#endif
23456+{
23457+ unregister_ipsec_alg_enc(&ipsec_alg_3DES);
23458+ return;
23459+}
23460+
23461+/* Dual, because 3des code is 4-clause BSD licensed */
23462+#ifdef MODULE_LICENSE
23463+MODULE_LICENSE("Dual BSD/GPL");
23464+#endif
23465+
23466+
23467--- /dev/null Tue Mar 11 13:02:56 2003
23468+++ linux/net/ipsec/des/set_key.c Mon Feb 9 13:51:03 2004
23469@@ -0,0 +1,246 @@
23470+/* crypto/des/set_key.c */
23471+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
23472+ * All rights reserved.
23473+ *
23474+ * This package is an SSL implementation written
23475+ * by Eric Young (eay@cryptsoft.com).
23476+ * The implementation was written so as to conform with Netscapes SSL.
23477+ *
23478+ * This library is free for commercial and non-commercial use as long as
23479+ * the following conditions are aheared to. The following conditions
23480+ * apply to all code found in this distribution, be it the RC4, RSA,
23481+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
23482+ * included with this distribution is covered by the same copyright terms
23483+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
23484+ *
23485+ * Copyright remains Eric Young's, and as such any Copyright notices in
23486+ * the code are not to be removed.
23487+ * If this package is used in a product, Eric Young should be given attribution
23488+ * as the author of the parts of the library used.
23489+ * This can be in the form of a textual message at program startup or
23490+ * in documentation (online or textual) provided with the package.
23491+ *
23492+ * Redistribution and use in source and binary forms, with or without
23493+ * modification, are permitted provided that the following conditions
23494+ * are met:
23495+ * 1. Redistributions of source code must retain the copyright
23496+ * notice, this list of conditions and the following disclaimer.
23497+ * 2. Redistributions in binary form must reproduce the above copyright
23498+ * notice, this list of conditions and the following disclaimer in the
23499+ * documentation and/or other materials provided with the distribution.
23500+ * 3. All advertising materials mentioning features or use of this software
23501+ * must display the following acknowledgement:
23502+ * "This product includes cryptographic software written by
23503+ * Eric Young (eay@cryptsoft.com)"
23504+ * The word 'cryptographic' can be left out if the rouines from the library
23505+ * being used are not cryptographic related :-).
23506+ * 4. If you include any Windows specific code (or a derivative thereof) from
23507+ * the apps directory (application code) you must include an acknowledgement:
23508+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
23509+ *
23510+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
23511+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23512+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23513+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23514+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23515+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23516+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23517+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23518+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23519+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23520+ * SUCH DAMAGE.
23521+ *
23522+ * The licence and distribution terms for any publically available version or
23523+ * derivative of this code cannot be changed. i.e. this code cannot simply be
23524+ * copied and put under another distribution licence
23525+ * [including the GNU Public Licence.]
23526+ */
23527+
23528+/* set_key.c v 1.4 eay 24/9/91
23529+ * 1.4 Speed up by 400% :-)
23530+ * 1.3 added register declarations.
23531+ * 1.2 unrolled make_key_sched a bit more
23532+ * 1.1 added norm_expand_bits
23533+ * 1.0 First working version
23534+ */
23535+#include "des/des_locl.h"
23536+#include "des/podd.h"
23537+#include "des/sk.h"
23538+
23539+#ifndef NOPROTO
23540+static int check_parity(des_cblock (*key));
23541+#else
23542+static int check_parity();
23543+#endif
23544+
23545+int des_check_key=0;
23546+
23547+void des_set_odd_parity(key)
23548+des_cblock (*key);
23549+ {
23550+ int i;
23551+
23552+ for (i=0; i<DES_KEY_SZ; i++)
23553+ (*key)[i]=odd_parity[(*key)[i]];
23554+ }
23555+
23556+static int check_parity(key)
23557+des_cblock (*key);
23558+ {
23559+ int i;
23560+
23561+ for (i=0; i<DES_KEY_SZ; i++)
23562+ {
23563+ if ((*key)[i] != odd_parity[(*key)[i]])
23564+ return(0);
23565+ }
23566+ return(1);
23567+ }
23568+
23569+/* Weak and semi week keys as take from
23570+ * %A D.W. Davies
23571+ * %A W.L. Price
23572+ * %T Security for Computer Networks
23573+ * %I John Wiley & Sons
23574+ * %D 1984
23575+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
23576+ * (and actual cblock values).
23577+ */
23578+#define NUM_WEAK_KEY 16
23579+static des_cblock weak_keys[NUM_WEAK_KEY]={
23580+ /* weak keys */
23581+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
23582+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
23583+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
23584+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
23585+ /* semi-weak keys */
23586+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
23587+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
23588+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
23589+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
23590+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
23591+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
23592+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
23593+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
23594+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
23595+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
23596+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
23597+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
23598+
23599+int des_is_weak_key(key)
23600+des_cblock (*key);
23601+ {
23602+ int i;
23603+
23604+ for (i=0; i<NUM_WEAK_KEY; i++)
23605+ /* Added == 0 to comparision, I obviously don't run
23606+ * this section very often :-(, thanks to
23607+ * engineering@MorningStar.Com for the fix
23608+ * eay 93/06/29
23609+ * Another problem, I was comparing only the first 4
23610+ * bytes, 97/03/18 */
23611+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
23612+ return(0);
23613+ }
23614+
23615+/* NOW DEFINED IN des_local.h
23616+ * See ecb_encrypt.c for a pseudo description of these macros.
23617+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
23618+ * (b)^=(t),\
23619+ * (a)=((a)^((t)<<(n))))
23620+ */
23621+
23622+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
23623+ (a)=(a)^(t)^(t>>(16-(n))))
23624+
23625+/* return 0 if key parity is odd (correct),
23626+ * return -1 if key parity error,
23627+ * return -2 if illegal weak key.
23628+ */
23629+int des_set_key(key, schedule)
23630+des_cblock (*key);
23631+des_key_schedule schedule;
23632+ {
23633+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
23634+ register DES_LONG c,d,t,s,t2;
23635+ register unsigned char *in;
23636+ register DES_LONG *k;
23637+ register int i;
23638+
23639+ if (des_check_key)
23640+ {
23641+ if (!check_parity(key))
23642+ return(-1);
23643+
23644+ if (des_is_weak_key(key))
23645+ return(-2);
23646+ }
23647+
23648+ k=(DES_LONG *)schedule;
23649+ in=(unsigned char *)key;
23650+
23651+ c2l(in,c);
23652+ c2l(in,d);
23653+
23654+ /* do PC1 in 60 simple operations */
23655+/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
23656+ HPERM_OP(c,t,-2, 0xcccc0000L);
23657+ HPERM_OP(c,t,-1, 0xaaaa0000L);
23658+ HPERM_OP(c,t, 8, 0x00ff0000L);
23659+ HPERM_OP(c,t,-1, 0xaaaa0000L);
23660+ HPERM_OP(d,t,-8, 0xff000000L);
23661+ HPERM_OP(d,t, 8, 0x00ff0000L);
23662+ HPERM_OP(d,t, 2, 0x33330000L);
23663+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
23664+ d=(d>>8)|((c&0xf0000000L)>>4);
23665+ c&=0x0fffffffL; */
23666+
23667+ /* I now do it in 47 simple operations :-)
23668+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
23669+ * for the inspiration. :-) */
23670+ PERM_OP (d,c,t,4,0x0f0f0f0fL);
23671+ HPERM_OP(c,t,-2,0xcccc0000L);
23672+ HPERM_OP(d,t,-2,0xcccc0000L);
23673+ PERM_OP (d,c,t,1,0x55555555L);
23674+ PERM_OP (c,d,t,8,0x00ff00ffL);
23675+ PERM_OP (d,c,t,1,0x55555555L);
23676+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
23677+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
23678+ c&=0x0fffffffL;
23679+
23680+ for (i=0; i<ITERATIONS; i++)
23681+ {
23682+ if (shifts2[i])
23683+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
23684+ else
23685+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
23686+ c&=0x0fffffffL;
23687+ d&=0x0fffffffL;
23688+ /* could be a few less shifts but I am to lazy at this
23689+ * point in time to investigate */
23690+ s= des_skb[0][ (c )&0x3f ]|
23691+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
23692+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
23693+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
23694+ ((c>>22L)&0x38)];
23695+ t= des_skb[4][ (d )&0x3f ]|
23696+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
23697+ des_skb[6][ (d>>15L)&0x3f ]|
23698+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
23699+
23700+ /* table contained 0213 4657 */
23701+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
23702+ *(k++)=ROTATE(t2,30)&0xffffffffL;
23703+
23704+ t2=((s>>16L)|(t&0xffff0000L));
23705+ *(k++)=ROTATE(t2,26)&0xffffffffL;
23706+ }
23707+ return(0);
23708+ }
23709+
23710+int des_key_sched(key, schedule)
23711+des_cblock (*key);
23712+des_key_schedule schedule;
23713+ {
23714+ return(des_set_key(key,schedule));
23715+ }
23716--- /dev/null Tue Mar 11 13:02:56 2003
23717+++ linux/net/ipsec/goodmask.c Mon Feb 9 13:51:03 2004
23718@@ -0,0 +1,100 @@
23719+/*
23720+ * minor utilities for subnet-mask manipulation
23721+ * Copyright (C) 1998, 1999 Henry Spencer.
23722+ *
23723+ * This library is free software; you can redistribute it and/or modify it
23724+ * under the terms of the GNU Library General Public License as published by
23725+ * the Free Software Foundation; either version 2 of the License, or (at your
23726+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
23727+ *
23728+ * This library is distributed in the hope that it will be useful, but
23729+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23730+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
23731+ * License for more details.
23732+ *
23733+ * RCSID $Id: goodmask.c,v 1.12 2004-07-10 07:43:47 mcr Exp $
23734+ */
23735+#include "openswan.h"
23736+
23737+#ifndef ABITS
23738+#define ABITS 32 /* bits in an IPv4 address */
23739+#endif
23740+
23741+/*
23742+ - goodmask - is this a good (^1*0*$) subnet mask?
23743+ * You are not expected to understand this. See Henry S. Warren Jr,
23744+ * "Functions realizable with word-parallel logical and two's-complement
23745+ * addition instructions", CACM 20.6 (June 1977), p.439.
23746+ */
23747+int /* predicate */
23748+goodmask(mask)
23749+struct in_addr mask;
23750+{
23751+ unsigned long x = ntohl(mask.s_addr);
23752+ /* clear rightmost contiguous string of 1-bits */
23753+# define CRCS1B(x) (((x|(x-1))+1)&x)
23754+# define TOPBIT (1UL << 31)
23755+
23756+ /* either zero, or has one string of 1-bits which is left-justified */
23757+ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
23758+ return 1;
23759+ return 0;
23760+}
23761+
23762+/*
23763+ - masktobits - how many bits in this mask?
23764+ * The algorithm is essentially a binary search, but highly optimized
23765+ * for this particular task.
23766+ */
23767+int /* -1 means !goodmask() */
23768+masktobits(mask)
23769+struct in_addr mask;
23770+{
23771+ unsigned long m = ntohl(mask.s_addr);
23772+ int masklen;
23773+
23774+ if (!goodmask(mask))
23775+ return -1;
23776+
23777+ if (m&0x00000001UL)
23778+ return 32;
23779+ masklen = 0;
23780+ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
23781+ masklen |= 0x10;
23782+ m <<= 16;
23783+ }
23784+ if (m&(0x00ff0000UL<<1)) {
23785+ masklen |= 0x08;
23786+ m <<= 8;
23787+ }
23788+ if (m&(0x0f000000UL<<1)) {
23789+ masklen |= 0x04;
23790+ m <<= 4;
23791+ }
23792+ if (m&(0x30000000UL<<1)) {
23793+ masklen |= 0x02;
23794+ m <<= 2;
23795+ }
23796+ if (m&(0x40000000UL<<1))
23797+ masklen |= 0x01;
23798+
23799+ return masklen;
23800+}
23801+
23802+/*
23803+ - bitstomask - return a mask with this many high bits on
23804+ */
23805+struct in_addr
23806+bitstomask(n)
23807+int n;
23808+{
23809+ struct in_addr result;
23810+
23811+ if (n > 0 && n <= ABITS)
23812+ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
23813+ else if (n == 0)
23814+ result.s_addr = 0;
23815+ else
23816+ result.s_addr = 0; /* best error report we can do */
23817+ return result;
23818+}
23819--- /dev/null Tue Mar 11 13:02:56 2003
23820+++ linux/net/ipsec/infblock.c Mon Feb 9 13:51:03 2004
23821@@ -0,0 +1,403 @@
23822+/* infblock.c -- interpret and process block types to last block
23823+ * Copyright (C) 1995-2002 Mark Adler
23824+ * For conditions of distribution and use, see copyright notice in zlib.h
23825+ */
23826+
23827+#include <zlib/zutil.h>
23828+#include "infblock.h"
23829+#include "inftrees.h"
23830+#include "infcodes.h"
23831+#include "infutil.h"
23832+
23833+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
23834+
23835+/* simplify the use of the inflate_huft type with some defines */
23836+#define exop word.what.Exop
23837+#define bits word.what.Bits
23838+
23839+/* Table for deflate from PKZIP's appnote.txt. */
23840+local const uInt border[] = { /* Order of the bit length code lengths */
23841+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
23842+
23843+/*
23844+ Notes beyond the 1.93a appnote.txt:
23845+
23846+ 1. Distance pointers never point before the beginning of the output
23847+ stream.
23848+ 2. Distance pointers can point back across blocks, up to 32k away.
23849+ 3. There is an implied maximum of 7 bits for the bit length table and
23850+ 15 bits for the actual data.
23851+ 4. If only one code exists, then it is encoded using one bit. (Zero
23852+ would be more efficient, but perhaps a little confusing.) If two
23853+ codes exist, they are coded using one bit each (0 and 1).
23854+ 5. There is no way of sending zero distance codes--a dummy must be
23855+ sent if there are none. (History: a pre 2.0 version of PKZIP would
23856+ store blocks with no distance codes, but this was discovered to be
23857+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
23858+ zero distance codes, which is sent as one code of zero bits in
23859+ length.
23860+ 6. There are up to 286 literal/length codes. Code 256 represents the
23861+ end-of-block. Note however that the static length tree defines
23862+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
23863+ cannot be used though, since there is no length base or extra bits
23864+ defined for them. Similarily, there are up to 30 distance codes.
23865+ However, static trees define 32 codes (all 5 bits) to fill out the
23866+ Huffman codes, but the last two had better not show up in the data.
23867+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
23868+ The exception is that a single code would not be complete (see #4).
23869+ 8. The five bits following the block type is really the number of
23870+ literal codes sent minus 257.
23871+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
23872+ (1+6+6). Therefore, to output three times the length, you output
23873+ three codes (1+1+1), whereas to output four times the same length,
23874+ you only need two codes (1+3). Hmm.
23875+ 10. In the tree reconstruction algorithm, Code = Code + Increment
23876+ only if BitLength(i) is not zero. (Pretty obvious.)
23877+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
23878+ 12. Note: length code 284 can represent 227-258, but length code 285
23879+ really is 258. The last length deserves its own, short code
23880+ since it gets used a lot in very redundant files. The length
23881+ 258 is special since 258 - 3 (the min match length) is 255.
23882+ 13. The literal/length and distance code bit lengths are read as a
23883+ single stream of lengths. It is possible (and advantageous) for
23884+ a repeat code (16, 17, or 18) to go across the boundary between
23885+ the two sets of lengths.
23886+ */
23887+
23888+
23889+void inflate_blocks_reset(s, z, c)
23890+inflate_blocks_statef *s;
23891+z_streamp z;
23892+uLongf *c;
23893+{
23894+ if (c != Z_NULL)
23895+ *c = s->check;
23896+ if (s->mode == BTREE || s->mode == DTREE)
23897+ ZFREE(z, s->sub.trees.blens);
23898+ if (s->mode == CODES)
23899+ inflate_codes_free(s->sub.decode.codes, z);
23900+ s->mode = TYPE;
23901+ s->bitk = 0;
23902+ s->bitb = 0;
23903+ s->read = s->write = s->window;
23904+ if (s->checkfn != Z_NULL)
23905+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
23906+ Tracev((stderr, "inflate: blocks reset\n"));
23907+}
23908+
23909+
23910+inflate_blocks_statef *inflate_blocks_new(z, c, w)
23911+z_streamp z;
23912+check_func c;
23913+uInt w;
23914+{
23915+ inflate_blocks_statef *s;
23916+
23917+ if ((s = (inflate_blocks_statef *)ZALLOC
23918+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
23919+ return s;
23920+ if ((s->hufts =
23921+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
23922+ {
23923+ ZFREE(z, s);
23924+ return Z_NULL;
23925+ }
23926+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
23927+ {
23928+ ZFREE(z, s->hufts);
23929+ ZFREE(z, s);
23930+ return Z_NULL;
23931+ }
23932+ s->end = s->window + w;
23933+ s->checkfn = c;
23934+ s->mode = TYPE;
23935+ Tracev((stderr, "inflate: blocks allocated\n"));
23936+ inflate_blocks_reset(s, z, Z_NULL);
23937+ return s;
23938+}
23939+
23940+
23941+int inflate_blocks(s, z, r)
23942+inflate_blocks_statef *s;
23943+z_streamp z;
23944+int r;
23945+{
23946+ uInt t; /* temporary storage */
23947+ uLong b; /* bit buffer */
23948+ uInt k; /* bits in bit buffer */
23949+ Bytef *p; /* input data pointer */
23950+ uInt n; /* bytes available there */
23951+ Bytef *q; /* output window write pointer */
23952+ uInt m; /* bytes to end of window or read pointer */
23953+
23954+ /* copy input/output information to locals (UPDATE macro restores) */
23955+ LOAD
23956+
23957+ /* process input based on current state */
23958+ while (1) switch (s->mode)
23959+ {
23960+ case TYPE:
23961+ NEEDBITS(3)
23962+ t = (uInt)b & 7;
23963+ s->last = t & 1;
23964+ switch (t >> 1)
23965+ {
23966+ case 0: /* stored */
23967+ Tracev((stderr, "inflate: stored block%s\n",
23968+ s->last ? " (last)" : ""));
23969+ DUMPBITS(3)
23970+ t = k & 7; /* go to byte boundary */
23971+ DUMPBITS(t)
23972+ s->mode = LENS; /* get length of stored block */
23973+ break;
23974+ case 1: /* fixed */
23975+ Tracev((stderr, "inflate: fixed codes block%s\n",
23976+ s->last ? " (last)" : ""));
23977+ {
23978+ uInt bl, bd;
23979+ inflate_huft *tl, *td;
23980+
23981+ inflate_trees_fixed(&bl, &bd, &tl, &td, z);
23982+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
23983+ if (s->sub.decode.codes == Z_NULL)
23984+ {
23985+ r = Z_MEM_ERROR;
23986+ LEAVE
23987+ }
23988+ }
23989+ DUMPBITS(3)
23990+ s->mode = CODES;
23991+ break;
23992+ case 2: /* dynamic */
23993+ Tracev((stderr, "inflate: dynamic codes block%s\n",
23994+ s->last ? " (last)" : ""));
23995+ DUMPBITS(3)
23996+ s->mode = TABLE;
23997+ break;
23998+ case 3: /* illegal */
23999+ DUMPBITS(3)
24000+ s->mode = BAD;
24001+ z->msg = (char*)"invalid block type";
24002+ r = Z_DATA_ERROR;
24003+ LEAVE
24004+ }
24005+ break;
24006+ case LENS:
24007+ NEEDBITS(32)
24008+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
24009+ {
24010+ s->mode = BAD;
24011+ z->msg = (char*)"invalid stored block lengths";
24012+ r = Z_DATA_ERROR;
24013+ LEAVE
24014+ }
24015+ s->sub.left = (uInt)b & 0xffff;
24016+ b = k = 0; /* dump bits */
24017+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
24018+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
24019+ break;
24020+ case STORED:
24021+ if (n == 0)
24022+ LEAVE
24023+ NEEDOUT
24024+ t = s->sub.left;
24025+ if (t > n) t = n;
24026+ if (t > m) t = m;
24027+ zmemcpy(q, p, t);
24028+ p += t; n -= t;
24029+ q += t; m -= t;
24030+ if ((s->sub.left -= t) != 0)
24031+ break;
24032+ Tracev((stderr, "inflate: stored end, %lu total out\n",
24033+ z->total_out + (q >= s->read ? q - s->read :
24034+ (s->end - s->read) + (q - s->window))));
24035+ s->mode = s->last ? DRY : TYPE;
24036+ break;
24037+ case TABLE:
24038+ NEEDBITS(14)
24039+ s->sub.trees.table = t = (uInt)b & 0x3fff;
24040+#ifndef PKZIP_BUG_WORKAROUND
24041+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
24042+ {
24043+ s->mode = BAD;
24044+ z->msg = (char*)"too many length or distance symbols";
24045+ r = Z_DATA_ERROR;
24046+ LEAVE
24047+ }
24048+#endif
24049+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
24050+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
24051+ {
24052+ r = Z_MEM_ERROR;
24053+ LEAVE
24054+ }
24055+ DUMPBITS(14)
24056+ s->sub.trees.index = 0;
24057+ Tracev((stderr, "inflate: table sizes ok\n"));
24058+ s->mode = BTREE;
24059+ case BTREE:
24060+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
24061+ {
24062+ NEEDBITS(3)
24063+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
24064+ DUMPBITS(3)
24065+ }
24066+ while (s->sub.trees.index < 19)
24067+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
24068+ s->sub.trees.bb = 7;
24069+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
24070+ &s->sub.trees.tb, s->hufts, z);
24071+ if (t != Z_OK)
24072+ {
24073+ r = t;
24074+ if (r == Z_DATA_ERROR)
24075+ {
24076+ ZFREE(z, s->sub.trees.blens);
24077+ s->mode = BAD;
24078+ }
24079+ LEAVE
24080+ }
24081+ s->sub.trees.index = 0;
24082+ Tracev((stderr, "inflate: bits tree ok\n"));
24083+ s->mode = DTREE;
24084+ case DTREE:
24085+ while (t = s->sub.trees.table,
24086+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
24087+ {
24088+ inflate_huft *h;
24089+ uInt i, j, c;
24090+
24091+ t = s->sub.trees.bb;
24092+ NEEDBITS(t)
24093+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
24094+ t = h->bits;
24095+ c = h->base;
24096+ if (c < 16)
24097+ {
24098+ DUMPBITS(t)
24099+ s->sub.trees.blens[s->sub.trees.index++] = c;
24100+ }
24101+ else /* c == 16..18 */
24102+ {
24103+ i = c == 18 ? 7 : c - 14;
24104+ j = c == 18 ? 11 : 3;
24105+ NEEDBITS(t + i)
24106+ DUMPBITS(t)
24107+ j += (uInt)b & inflate_mask[i];
24108+ DUMPBITS(i)
24109+ i = s->sub.trees.index;
24110+ t = s->sub.trees.table;
24111+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
24112+ (c == 16 && i < 1))
24113+ {
24114+ ZFREE(z, s->sub.trees.blens);
24115+ s->mode = BAD;
24116+ z->msg = (char*)"invalid bit length repeat";
24117+ r = Z_DATA_ERROR;
24118+ LEAVE
24119+ }
24120+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
24121+ do {
24122+ s->sub.trees.blens[i++] = c;
24123+ } while (--j);
24124+ s->sub.trees.index = i;
24125+ }
24126+ }
24127+ s->sub.trees.tb = Z_NULL;
24128+ {
24129+ uInt bl, bd;
24130+ inflate_huft *tl, *td;
24131+ inflate_codes_statef *c;
24132+
24133+ bl = 9; /* must be <= 9 for lookahead assumptions */
24134+ bd = 6; /* must be <= 9 for lookahead assumptions */
24135+ t = s->sub.trees.table;
24136+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
24137+ s->sub.trees.blens, &bl, &bd, &tl, &td,
24138+ s->hufts, z);
24139+ if (t != Z_OK)
24140+ {
24141+ if (t == (uInt)Z_DATA_ERROR)
24142+ {
24143+ ZFREE(z, s->sub.trees.blens);
24144+ s->mode = BAD;
24145+ }
24146+ r = t;
24147+ LEAVE
24148+ }
24149+ Tracev((stderr, "inflate: trees ok\n"));
24150+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
24151+ {
24152+ r = Z_MEM_ERROR;
24153+ LEAVE
24154+ }
24155+ s->sub.decode.codes = c;
24156+ }
24157+ ZFREE(z, s->sub.trees.blens);
24158+ s->mode = CODES;
24159+ case CODES:
24160+ UPDATE
24161+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
24162+ return inflate_flush(s, z, r);
24163+ r = Z_OK;
24164+ inflate_codes_free(s->sub.decode.codes, z);
24165+ LOAD
24166+ Tracev((stderr, "inflate: codes end, %lu total out\n",
24167+ z->total_out + (q >= s->read ? q - s->read :
24168+ (s->end - s->read) + (q - s->window))));
24169+ if (!s->last)
24170+ {
24171+ s->mode = TYPE;
24172+ break;
24173+ }
24174+ s->mode = DRY;
24175+ case DRY:
24176+ FLUSH
24177+ if (s->read != s->write)
24178+ LEAVE
24179+ s->mode = DONE;
24180+ case DONE:
24181+ r = Z_STREAM_END;
24182+ LEAVE
24183+ case BAD:
24184+ r = Z_DATA_ERROR;
24185+ LEAVE
24186+ default:
24187+ r = Z_STREAM_ERROR;
24188+ LEAVE
24189+ }
24190+}
24191+
24192+
24193+int inflate_blocks_free(s, z)
24194+inflate_blocks_statef *s;
24195+z_streamp z;
24196+{
24197+ inflate_blocks_reset(s, z, Z_NULL);
24198+ ZFREE(z, s->window);
24199+ ZFREE(z, s->hufts);
24200+ ZFREE(z, s);
24201+ Tracev((stderr, "inflate: blocks freed\n"));
24202+ return Z_OK;
24203+}
24204+
24205+
24206+void inflate_set_dictionary(s, d, n)
24207+inflate_blocks_statef *s;
24208+const Bytef *d;
24209+uInt n;
24210+{
24211+ zmemcpy(s->window, d, n);
24212+ s->read = s->write = s->window + n;
24213+}
24214+
24215+
24216+/* Returns true if inflate is currently at the end of a block generated
24217+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
24218+ * IN assertion: s != Z_NULL
24219+ */
24220+int inflate_blocks_sync_point(s)
24221+inflate_blocks_statef *s;
24222+{
24223+ return s->mode == LENS;
24224+}
24225--- /dev/null Tue Mar 11 13:02:56 2003
24226+++ linux/net/ipsec/infblock.h Mon Feb 9 13:51:03 2004
24227@@ -0,0 +1,39 @@
24228+/* infblock.h -- header to use infblock.c
24229+ * Copyright (C) 1995-2002 Mark Adler
24230+ * For conditions of distribution and use, see copyright notice in zlib.h
24231+ */
24232+
24233+/* WARNING: this file should *not* be used by applications. It is
24234+ part of the implementation of the compression library and is
24235+ subject to change. Applications should only use zlib.h.
24236+ */
24237+
24238+struct inflate_blocks_state;
24239+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
24240+
24241+extern inflate_blocks_statef * inflate_blocks_new OF((
24242+ z_streamp z,
24243+ check_func c, /* check function */
24244+ uInt w)); /* window size */
24245+
24246+extern int inflate_blocks OF((
24247+ inflate_blocks_statef *,
24248+ z_streamp ,
24249+ int)); /* initial return code */
24250+
24251+extern void inflate_blocks_reset OF((
24252+ inflate_blocks_statef *,
24253+ z_streamp ,
24254+ uLongf *)); /* check value on output */
24255+
24256+extern int inflate_blocks_free OF((
24257+ inflate_blocks_statef *,
24258+ z_streamp));
24259+
24260+extern void inflate_set_dictionary OF((
24261+ inflate_blocks_statef *s,
24262+ const Bytef *d, /* dictionary */
24263+ uInt n)); /* dictionary length */
24264+
24265+extern int inflate_blocks_sync_point OF((
24266+ inflate_blocks_statef *s));
24267--- /dev/null Tue Mar 11 13:02:56 2003
24268+++ linux/net/ipsec/infcodes.c Mon Feb 9 13:51:03 2004
24269@@ -0,0 +1,251 @@
24270+/* infcodes.c -- process literals and length/distance pairs
24271+ * Copyright (C) 1995-2002 Mark Adler
24272+ * For conditions of distribution and use, see copyright notice in zlib.h
24273+ */
24274+
24275+#include <zlib/zutil.h>
24276+#include "inftrees.h"
24277+#include "infblock.h"
24278+#include "infcodes.h"
24279+#include "infutil.h"
24280+#include "inffast.h"
24281+
24282+/* simplify the use of the inflate_huft type with some defines */
24283+#define exop word.what.Exop
24284+#define bits word.what.Bits
24285+
24286+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
24287+ START, /* x: set up for LEN */
24288+ LEN, /* i: get length/literal/eob next */
24289+ LENEXT, /* i: getting length extra (have base) */
24290+ DIST, /* i: get distance next */
24291+ DISTEXT, /* i: getting distance extra */
24292+ COPY, /* o: copying bytes in window, waiting for space */
24293+ LIT, /* o: got literal, waiting for output space */
24294+ WASH, /* o: got eob, possibly still output waiting */
24295+ END, /* x: got eob and all data flushed */
24296+ BADCODE} /* x: got error */
24297+inflate_codes_mode;
24298+
24299+/* inflate codes private state */
24300+struct inflate_codes_state {
24301+
24302+ /* mode */
24303+ inflate_codes_mode mode; /* current inflate_codes mode */
24304+
24305+ /* mode dependent information */
24306+ uInt len;
24307+ union {
24308+ struct {
24309+ inflate_huft *tree; /* pointer into tree */
24310+ uInt need; /* bits needed */
24311+ } code; /* if LEN or DIST, where in tree */
24312+ uInt lit; /* if LIT, literal */
24313+ struct {
24314+ uInt get; /* bits to get for extra */
24315+ uInt dist; /* distance back to copy from */
24316+ } copy; /* if EXT or COPY, where and how much */
24317+ } sub; /* submode */
24318+
24319+ /* mode independent information */
24320+ Byte lbits; /* ltree bits decoded per branch */
24321+ Byte dbits; /* dtree bits decoder per branch */
24322+ inflate_huft *ltree; /* literal/length/eob tree */
24323+ inflate_huft *dtree; /* distance tree */
24324+
24325+};
24326+
24327+
24328+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
24329+uInt bl, bd;
24330+inflate_huft *tl;
24331+inflate_huft *td; /* need separate declaration for Borland C++ */
24332+z_streamp z;
24333+{
24334+ inflate_codes_statef *c;
24335+
24336+ if ((c = (inflate_codes_statef *)
24337+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
24338+ {
24339+ c->mode = START;
24340+ c->lbits = (Byte)bl;
24341+ c->dbits = (Byte)bd;
24342+ c->ltree = tl;
24343+ c->dtree = td;
24344+ Tracev((stderr, "inflate: codes new\n"));
24345+ }
24346+ return c;
24347+}
24348+
24349+
24350+int inflate_codes(s, z, r)
24351+inflate_blocks_statef *s;
24352+z_streamp z;
24353+int r;
24354+{
24355+ uInt j; /* temporary storage */
24356+ inflate_huft *t; /* temporary pointer */
24357+ uInt e; /* extra bits or operation */
24358+ uLong b; /* bit buffer */
24359+ uInt k; /* bits in bit buffer */
24360+ Bytef *p; /* input data pointer */
24361+ uInt n; /* bytes available there */
24362+ Bytef *q; /* output window write pointer */
24363+ uInt m; /* bytes to end of window or read pointer */
24364+ Bytef *f; /* pointer to copy strings from */
24365+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
24366+
24367+ /* copy input/output information to locals (UPDATE macro restores) */
24368+ LOAD
24369+
24370+ /* process input and output based on current state */
24371+ while (1) switch (c->mode)
24372+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
24373+ case START: /* x: set up for LEN */
24374+#ifndef SLOW
24375+ if (m >= 258 && n >= 10)
24376+ {
24377+ UPDATE
24378+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
24379+ LOAD
24380+ if (r != Z_OK)
24381+ {
24382+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
24383+ break;
24384+ }
24385+ }
24386+#endif /* !SLOW */
24387+ c->sub.code.need = c->lbits;
24388+ c->sub.code.tree = c->ltree;
24389+ c->mode = LEN;
24390+ case LEN: /* i: get length/literal/eob next */
24391+ j = c->sub.code.need;
24392+ NEEDBITS(j)
24393+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
24394+ DUMPBITS(t->bits)
24395+ e = (uInt)(t->exop);
24396+ if (e == 0) /* literal */
24397+ {
24398+ c->sub.lit = t->base;
24399+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24400+ "inflate: literal '%c'\n" :
24401+ "inflate: literal 0x%02x\n", t->base));
24402+ c->mode = LIT;
24403+ break;
24404+ }
24405+ if (e & 16) /* length */
24406+ {
24407+ c->sub.copy.get = e & 15;
24408+ c->len = t->base;
24409+ c->mode = LENEXT;
24410+ break;
24411+ }
24412+ if ((e & 64) == 0) /* next table */
24413+ {
24414+ c->sub.code.need = e;
24415+ c->sub.code.tree = t + t->base;
24416+ break;
24417+ }
24418+ if (e & 32) /* end of block */
24419+ {
24420+ Tracevv((stderr, "inflate: end of block\n"));
24421+ c->mode = WASH;
24422+ break;
24423+ }
24424+ c->mode = BADCODE; /* invalid code */
24425+ z->msg = (char*)"invalid literal/length code";
24426+ r = Z_DATA_ERROR;
24427+ LEAVE
24428+ case LENEXT: /* i: getting length extra (have base) */
24429+ j = c->sub.copy.get;
24430+ NEEDBITS(j)
24431+ c->len += (uInt)b & inflate_mask[j];
24432+ DUMPBITS(j)
24433+ c->sub.code.need = c->dbits;
24434+ c->sub.code.tree = c->dtree;
24435+ Tracevv((stderr, "inflate: length %u\n", c->len));
24436+ c->mode = DIST;
24437+ case DIST: /* i: get distance next */
24438+ j = c->sub.code.need;
24439+ NEEDBITS(j)
24440+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
24441+ DUMPBITS(t->bits)
24442+ e = (uInt)(t->exop);
24443+ if (e & 16) /* distance */
24444+ {
24445+ c->sub.copy.get = e & 15;
24446+ c->sub.copy.dist = t->base;
24447+ c->mode = DISTEXT;
24448+ break;
24449+ }
24450+ if ((e & 64) == 0) /* next table */
24451+ {
24452+ c->sub.code.need = e;
24453+ c->sub.code.tree = t + t->base;
24454+ break;
24455+ }
24456+ c->mode = BADCODE; /* invalid code */
24457+ z->msg = (char*)"invalid distance code";
24458+ r = Z_DATA_ERROR;
24459+ LEAVE
24460+ case DISTEXT: /* i: getting distance extra */
24461+ j = c->sub.copy.get;
24462+ NEEDBITS(j)
24463+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
24464+ DUMPBITS(j)
24465+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
24466+ c->mode = COPY;
24467+ case COPY: /* o: copying bytes in window, waiting for space */
24468+ f = q - c->sub.copy.dist;
24469+ while (f < s->window) /* modulo window size-"while" instead */
24470+ f += s->end - s->window; /* of "if" handles invalid distances */
24471+ while (c->len)
24472+ {
24473+ NEEDOUT
24474+ OUTBYTE(*f++)
24475+ if (f == s->end)
24476+ f = s->window;
24477+ c->len--;
24478+ }
24479+ c->mode = START;
24480+ break;
24481+ case LIT: /* o: got literal, waiting for output space */
24482+ NEEDOUT
24483+ OUTBYTE(c->sub.lit)
24484+ c->mode = START;
24485+ break;
24486+ case WASH: /* o: got eob, possibly more output */
24487+ if (k > 7) /* return unused byte, if any */
24488+ {
24489+ Assert(k < 16, "inflate_codes grabbed too many bytes")
24490+ k -= 8;
24491+ n++;
24492+ p--; /* can always return one */
24493+ }
24494+ FLUSH
24495+ if (s->read != s->write)
24496+ LEAVE
24497+ c->mode = END;
24498+ case END:
24499+ r = Z_STREAM_END;
24500+ LEAVE
24501+ case BADCODE: /* x: got error */
24502+ r = Z_DATA_ERROR;
24503+ LEAVE
24504+ default:
24505+ r = Z_STREAM_ERROR;
24506+ LEAVE
24507+ }
24508+#ifdef NEED_DUMMY_RETURN
24509+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
24510+#endif
24511+}
24512+
24513+
24514+void inflate_codes_free(c, z)
24515+inflate_codes_statef *c;
24516+z_streamp z;
24517+{
24518+ ZFREE(z, c);
24519+ Tracev((stderr, "inflate: codes free\n"));
24520+}
24521--- /dev/null Tue Mar 11 13:02:56 2003
24522+++ linux/net/ipsec/infcodes.h Mon Feb 9 13:51:03 2004
24523@@ -0,0 +1,31 @@
24524+/* infcodes.h -- header to use infcodes.c
24525+ * Copyright (C) 1995-2002 Mark Adler
24526+ * For conditions of distribution and use, see copyright notice in zlib.h
24527+ */
24528+
24529+/* WARNING: this file should *not* be used by applications. It is
24530+ part of the implementation of the compression library and is
24531+ subject to change. Applications should only use zlib.h.
24532+ */
24533+
24534+#ifndef _INFCODES_H
24535+#define _INFCODES_H
24536+
24537+struct inflate_codes_state;
24538+typedef struct inflate_codes_state FAR inflate_codes_statef;
24539+
24540+extern inflate_codes_statef *inflate_codes_new OF((
24541+ uInt, uInt,
24542+ inflate_huft *, inflate_huft *,
24543+ z_streamp ));
24544+
24545+extern int inflate_codes OF((
24546+ inflate_blocks_statef *,
24547+ z_streamp ,
24548+ int));
24549+
24550+extern void inflate_codes_free OF((
24551+ inflate_codes_statef *,
24552+ z_streamp ));
24553+
24554+#endif /* _INFCODES_H */
24555--- /dev/null Tue Mar 11 13:02:56 2003
24556+++ linux/net/ipsec/inffast.c Mon Feb 9 13:51:03 2004
24557@@ -0,0 +1,183 @@
24558+/* inffast.c -- process literals and length/distance pairs fast
24559+ * Copyright (C) 1995-2002 Mark Adler
24560+ * For conditions of distribution and use, see copyright notice in zlib.h
24561+ */
24562+
24563+#include <zlib/zutil.h>
24564+#include "inftrees.h"
24565+#include "infblock.h"
24566+#include "infcodes.h"
24567+#include "infutil.h"
24568+#include "inffast.h"
24569+
24570+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
24571+
24572+/* simplify the use of the inflate_huft type with some defines */
24573+#define exop word.what.Exop
24574+#define bits word.what.Bits
24575+
24576+/* macros for bit input with no checking and for returning unused bytes */
24577+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
24578+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
24579+
24580+/* Called with number of bytes left to write in window at least 258
24581+ (the maximum string length) and number of input bytes available
24582+ at least ten. The ten bytes are six bytes for the longest length/
24583+ distance pair plus four bytes for overloading the bit buffer. */
24584+
24585+int inflate_fast(bl, bd, tl, td, s, z)
24586+uInt bl, bd;
24587+inflate_huft *tl;
24588+inflate_huft *td; /* need separate declaration for Borland C++ */
24589+inflate_blocks_statef *s;
24590+z_streamp z;
24591+{
24592+ inflate_huft *t; /* temporary pointer */
24593+ uInt e; /* extra bits or operation */
24594+ uLong b; /* bit buffer */
24595+ uInt k; /* bits in bit buffer */
24596+ Bytef *p; /* input data pointer */
24597+ uInt n; /* bytes available there */
24598+ Bytef *q; /* output window write pointer */
24599+ uInt m; /* bytes to end of window or read pointer */
24600+ uInt ml; /* mask for literal/length tree */
24601+ uInt md; /* mask for distance tree */
24602+ uInt c; /* bytes to copy */
24603+ uInt d; /* distance back to copy from */
24604+ Bytef *r; /* copy source pointer */
24605+
24606+ /* load input, output, bit values */
24607+ LOAD
24608+
24609+ /* initialize masks */
24610+ ml = inflate_mask[bl];
24611+ md = inflate_mask[bd];
24612+
24613+ /* do until not enough input or output space for fast loop */
24614+ do { /* assume called with m >= 258 && n >= 10 */
24615+ /* get literal/length code */
24616+ GRABBITS(20) /* max bits for literal/length code */
24617+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
24618+ {
24619+ DUMPBITS(t->bits)
24620+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24621+ "inflate: * literal '%c'\n" :
24622+ "inflate: * literal 0x%02x\n", t->base));
24623+ *q++ = (Byte)t->base;
24624+ m--;
24625+ continue;
24626+ }
24627+ do {
24628+ DUMPBITS(t->bits)
24629+ if (e & 16)
24630+ {
24631+ /* get extra bits for length */
24632+ e &= 15;
24633+ c = t->base + ((uInt)b & inflate_mask[e]);
24634+ DUMPBITS(e)
24635+ Tracevv((stderr, "inflate: * length %u\n", c));
24636+
24637+ /* decode distance base of block to copy */
24638+ GRABBITS(15); /* max bits for distance code */
24639+ e = (t = td + ((uInt)b & md))->exop;
24640+ do {
24641+ DUMPBITS(t->bits)
24642+ if (e & 16)
24643+ {
24644+ /* get extra bits to add to distance base */
24645+ e &= 15;
24646+ GRABBITS(e) /* get extra bits (up to 13) */
24647+ d = t->base + ((uInt)b & inflate_mask[e]);
24648+ DUMPBITS(e)
24649+ Tracevv((stderr, "inflate: * distance %u\n", d));
24650+
24651+ /* do the copy */
24652+ m -= c;
24653+ r = q - d;
24654+ if (r < s->window) /* wrap if needed */
24655+ {
24656+ do {
24657+ r += s->end - s->window; /* force pointer in window */
24658+ } while (r < s->window); /* covers invalid distances */
24659+ e = s->end - r;
24660+ if (c > e)
24661+ {
24662+ c -= e; /* wrapped copy */
24663+ do {
24664+ *q++ = *r++;
24665+ } while (--e);
24666+ r = s->window;
24667+ do {
24668+ *q++ = *r++;
24669+ } while (--c);
24670+ }
24671+ else /* normal copy */
24672+ {
24673+ *q++ = *r++; c--;
24674+ *q++ = *r++; c--;
24675+ do {
24676+ *q++ = *r++;
24677+ } while (--c);
24678+ }
24679+ }
24680+ else /* normal copy */
24681+ {
24682+ *q++ = *r++; c--;
24683+ *q++ = *r++; c--;
24684+ do {
24685+ *q++ = *r++;
24686+ } while (--c);
24687+ }
24688+ break;
24689+ }
24690+ else if ((e & 64) == 0)
24691+ {
24692+ t += t->base;
24693+ e = (t += ((uInt)b & inflate_mask[e]))->exop;
24694+ }
24695+ else
24696+ {
24697+ z->msg = (char*)"invalid distance code";
24698+ UNGRAB
24699+ UPDATE
24700+ return Z_DATA_ERROR;
24701+ }
24702+ } while (1);
24703+ break;
24704+ }
24705+ if ((e & 64) == 0)
24706+ {
24707+ t += t->base;
24708+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
24709+ {
24710+ DUMPBITS(t->bits)
24711+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24712+ "inflate: * literal '%c'\n" :
24713+ "inflate: * literal 0x%02x\n", t->base));
24714+ *q++ = (Byte)t->base;
24715+ m--;
24716+ break;
24717+ }
24718+ }
24719+ else if (e & 32)
24720+ {
24721+ Tracevv((stderr, "inflate: * end of block\n"));
24722+ UNGRAB
24723+ UPDATE
24724+ return Z_STREAM_END;
24725+ }
24726+ else
24727+ {
24728+ z->msg = (char*)"invalid literal/length code";
24729+ UNGRAB
24730+ UPDATE
24731+ return Z_DATA_ERROR;
24732+ }
24733+ } while (1);
24734+ } while (m >= 258 && n >= 10);
24735+
24736+ /* not enough input or output--restore pointers and return */
24737+ UNGRAB
24738+ UPDATE
24739+ return Z_OK;
24740+}
24741--- /dev/null Tue Mar 11 13:02:56 2003
24742+++ linux/net/ipsec/inffast.h Mon Feb 9 13:51:03 2004
24743@@ -0,0 +1,22 @@
24744+/* inffast.h -- header to use inffast.c
24745+ * Copyright (C) 1995-2002 Mark Adler
24746+ * For conditions of distribution and use, see copyright notice in zlib.h
24747+ */
24748+
24749+/* WARNING: this file should *not* be used by applications. It is
24750+ part of the implementation of the compression library and is
24751+ subject to change. Applications should only use zlib.h.
24752+ */
24753+
24754+#ifndef _INFFAST_H
24755+#define _INFFAST_H
24756+
24757+extern int inflate_fast OF((
24758+ uInt,
24759+ uInt,
24760+ inflate_huft *,
24761+ inflate_huft *,
24762+ inflate_blocks_statef *,
24763+ z_streamp ));
24764+
24765+#endif /* _INFFAST_H */
24766--- /dev/null Tue Mar 11 13:02:56 2003
24767+++ linux/net/ipsec/inffixed.h Mon Feb 9 13:51:03 2004
24768@@ -0,0 +1,151 @@
24769+/* inffixed.h -- table for decoding fixed codes
24770+ * Generated automatically by the maketree.c program
24771+ */
24772+
24773+/* WARNING: this file should *not* be used by applications. It is
24774+ part of the implementation of the compression library and is
24775+ subject to change. Applications should only use zlib.h.
24776+ */
24777+
24778+local uInt fixed_bl = 9;
24779+local uInt fixed_bd = 5;
24780+local inflate_huft fixed_tl[] = {
24781+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24782+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
24783+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
24784+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
24785+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
24786+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
24787+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
24788+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
24789+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24790+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
24791+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
24792+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
24793+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
24794+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
24795+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
24796+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
24797+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24798+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
24799+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
24800+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
24801+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
24802+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
24803+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
24804+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
24805+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24806+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
24807+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
24808+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
24809+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
24810+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
24811+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
24812+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
24813+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24814+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
24815+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
24816+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
24817+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
24818+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
24819+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
24820+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
24821+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24822+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
24823+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
24824+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
24825+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
24826+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
24827+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
24828+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
24829+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24830+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
24831+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
24832+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
24833+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
24834+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
24835+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
24836+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
24837+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24838+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
24839+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
24840+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
24841+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
24842+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
24843+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
24844+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
24845+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24846+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
24847+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
24848+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
24849+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
24850+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
24851+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
24852+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
24853+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24854+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
24855+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
24856+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
24857+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
24858+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
24859+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
24860+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
24861+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24862+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
24863+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
24864+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
24865+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
24866+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
24867+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
24868+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
24869+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24870+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
24871+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
24872+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
24873+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
24874+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
24875+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
24876+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
24877+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24878+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
24879+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
24880+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
24881+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
24882+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
24883+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
24884+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
24885+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24886+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
24887+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
24888+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
24889+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
24890+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
24891+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
24892+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
24893+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24894+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
24895+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
24896+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
24897+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
24898+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
24899+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
24900+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
24901+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24902+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
24903+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
24904+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
24905+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
24906+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
24907+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
24908+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
24909+ };
24910+local inflate_huft fixed_td[] = {
24911+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
24912+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
24913+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
24914+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
24915+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
24916+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
24917+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
24918+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
24919+ };
24920--- /dev/null Tue Mar 11 13:02:56 2003
24921+++ linux/net/ipsec/inflate.c Mon Feb 9 13:51:03 2004
24922@@ -0,0 +1,368 @@
24923+/* inflate.c -- zlib interface to inflate modules
24924+ * Copyright (C) 1995-2002 Mark Adler
24925+ * For conditions of distribution and use, see copyright notice in zlib.h
24926+ */
24927+
24928+#include <zlib/zutil.h>
24929+#include "infblock.h"
24930+
24931+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
24932+
24933+typedef enum {
24934+ METHOD, /* waiting for method byte */
24935+ FLAG, /* waiting for flag byte */
24936+ DICT4, /* four dictionary check bytes to go */
24937+ DICT3, /* three dictionary check bytes to go */
24938+ DICT2, /* two dictionary check bytes to go */
24939+ DICT1, /* one dictionary check byte to go */
24940+ DICT0, /* waiting for inflateSetDictionary */
24941+ BLOCKS, /* decompressing blocks */
24942+ CHECK4, /* four check bytes to go */
24943+ CHECK3, /* three check bytes to go */
24944+ CHECK2, /* two check bytes to go */
24945+ CHECK1, /* one check byte to go */
24946+ DONE, /* finished check, done */
24947+ BAD} /* got an error--stay here */
24948+inflate_mode;
24949+
24950+/* inflate private state */
24951+struct internal_state {
24952+
24953+ /* mode */
24954+ inflate_mode mode; /* current inflate mode */
24955+
24956+ /* mode dependent information */
24957+ union {
24958+ uInt method; /* if FLAGS, method byte */
24959+ struct {
24960+ uLong was; /* computed check value */
24961+ uLong need; /* stream check value */
24962+ } check; /* if CHECK, check values to compare */
24963+ uInt marker; /* if BAD, inflateSync's marker bytes count */
24964+ } sub; /* submode */
24965+
24966+ /* mode independent information */
24967+ int nowrap; /* flag for no wrapper */
24968+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
24969+ inflate_blocks_statef
24970+ *blocks; /* current inflate_blocks state */
24971+
24972+};
24973+
24974+
24975+int ZEXPORT inflateReset(z)
24976+z_streamp z;
24977+{
24978+ if (z == Z_NULL || z->state == Z_NULL)
24979+ return Z_STREAM_ERROR;
24980+ z->total_in = z->total_out = 0;
24981+ z->msg = Z_NULL;
24982+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
24983+ inflate_blocks_reset(z->state->blocks, z, Z_NULL);
24984+ Tracev((stderr, "inflate: reset\n"));
24985+ return Z_OK;
24986+}
24987+
24988+
24989+int ZEXPORT inflateEnd(z)
24990+z_streamp z;
24991+{
24992+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
24993+ return Z_STREAM_ERROR;
24994+ if (z->state->blocks != Z_NULL)
24995+ inflate_blocks_free(z->state->blocks, z);
24996+ ZFREE(z, z->state);
24997+ z->state = Z_NULL;
24998+ Tracev((stderr, "inflate: end\n"));
24999+ return Z_OK;
25000+}
25001+
25002+
25003+int ZEXPORT inflateInit2_(z, w, version, stream_size)
25004+z_streamp z;
25005+int w;
25006+const char *version;
25007+int stream_size;
25008+{
25009+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
25010+ stream_size != sizeof(z_stream))
25011+ return Z_VERSION_ERROR;
25012+
25013+ /* initialize state */
25014+ if (z == Z_NULL)
25015+ return Z_STREAM_ERROR;
25016+ z->msg = Z_NULL;
25017+ if (z->zalloc == Z_NULL)
25018+ {
25019+ return Z_STREAM_ERROR;
25020+/* z->zalloc = zcalloc;
25021+ z->opaque = (voidpf)0;
25022+*/
25023+ }
25024+ if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
25025+ if ((z->state = (struct internal_state FAR *)
25026+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
25027+ return Z_MEM_ERROR;
25028+ z->state->blocks = Z_NULL;
25029+
25030+ /* handle undocumented nowrap option (no zlib header or check) */
25031+ z->state->nowrap = 0;
25032+ if (w < 0)
25033+ {
25034+ w = - w;
25035+ z->state->nowrap = 1;
25036+ }
25037+
25038+ /* set window size */
25039+ if (w < 8 || w > 15)
25040+ {
25041+ inflateEnd(z);
25042+ return Z_STREAM_ERROR;
25043+ }
25044+ z->state->wbits = (uInt)w;
25045+
25046+ /* create inflate_blocks state */
25047+ if ((z->state->blocks =
25048+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
25049+ == Z_NULL)
25050+ {
25051+ inflateEnd(z);
25052+ return Z_MEM_ERROR;
25053+ }
25054+ Tracev((stderr, "inflate: allocated\n"));
25055+
25056+ /* reset state */
25057+ inflateReset(z);
25058+ return Z_OK;
25059+}
25060+
25061+
25062+int ZEXPORT inflateInit_(z, version, stream_size)
25063+z_streamp z;
25064+const char *version;
25065+int stream_size;
25066+{
25067+ return inflateInit2_(z, DEF_WBITS, version, stream_size);
25068+}
25069+
25070+
25071+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
25072+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
25073+
25074+int ZEXPORT inflate(z, f)
25075+z_streamp z;
25076+int f;
25077+{
25078+ int r;
25079+ uInt b;
25080+
25081+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
25082+ return Z_STREAM_ERROR;
25083+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
25084+ r = Z_BUF_ERROR;
25085+ while (1) switch (z->state->mode)
25086+ {
25087+ case METHOD:
25088+ NEEDBYTE
25089+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
25090+ {
25091+ z->state->mode = BAD;
25092+ z->msg = (char*)"unknown compression method";
25093+ z->state->sub.marker = 5; /* can't try inflateSync */
25094+ break;
25095+ }
25096+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
25097+ {
25098+ z->state->mode = BAD;
25099+ z->msg = (char*)"invalid window size";
25100+ z->state->sub.marker = 5; /* can't try inflateSync */
25101+ break;
25102+ }
25103+ z->state->mode = FLAG;
25104+ case FLAG:
25105+ NEEDBYTE
25106+ b = NEXTBYTE;
25107+ if (((z->state->sub.method << 8) + b) % 31)
25108+ {
25109+ z->state->mode = BAD;
25110+ z->msg = (char*)"incorrect header check";
25111+ z->state->sub.marker = 5; /* can't try inflateSync */
25112+ break;
25113+ }
25114+ Tracev((stderr, "inflate: zlib header ok\n"));
25115+ if (!(b & PRESET_DICT))
25116+ {
25117+ z->state->mode = BLOCKS;
25118+ break;
25119+ }
25120+ z->state->mode = DICT4;
25121+ case DICT4:
25122+ NEEDBYTE
25123+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
25124+ z->state->mode = DICT3;
25125+ case DICT3:
25126+ NEEDBYTE
25127+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
25128+ z->state->mode = DICT2;
25129+ case DICT2:
25130+ NEEDBYTE
25131+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
25132+ z->state->mode = DICT1;
25133+ case DICT1:
25134+ NEEDBYTE
25135+ z->state->sub.check.need += (uLong)NEXTBYTE;
25136+ z->adler = z->state->sub.check.need;
25137+ z->state->mode = DICT0;
25138+ return Z_NEED_DICT;
25139+ case DICT0:
25140+ z->state->mode = BAD;
25141+ z->msg = (char*)"need dictionary";
25142+ z->state->sub.marker = 0; /* can try inflateSync */
25143+ return Z_STREAM_ERROR;
25144+ case BLOCKS:
25145+ r = inflate_blocks(z->state->blocks, z, r);
25146+ if (r == Z_DATA_ERROR)
25147+ {
25148+ z->state->mode = BAD;
25149+ z->state->sub.marker = 0; /* can try inflateSync */
25150+ break;
25151+ }
25152+ if (r == Z_OK)
25153+ r = f;
25154+ if (r != Z_STREAM_END)
25155+ return r;
25156+ r = f;
25157+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
25158+ if (z->state->nowrap)
25159+ {
25160+ z->state->mode = DONE;
25161+ break;
25162+ }
25163+ z->state->mode = CHECK4;
25164+ case CHECK4:
25165+ NEEDBYTE
25166+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
25167+ z->state->mode = CHECK3;
25168+ case CHECK3:
25169+ NEEDBYTE
25170+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
25171+ z->state->mode = CHECK2;
25172+ case CHECK2:
25173+ NEEDBYTE
25174+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
25175+ z->state->mode = CHECK1;
25176+ case CHECK1:
25177+ NEEDBYTE
25178+ z->state->sub.check.need += (uLong)NEXTBYTE;
25179+
25180+ if (z->state->sub.check.was != z->state->sub.check.need)
25181+ {
25182+ z->state->mode = BAD;
25183+ z->msg = (char*)"incorrect data check";
25184+ z->state->sub.marker = 5; /* can't try inflateSync */
25185+ break;
25186+ }
25187+ Tracev((stderr, "inflate: zlib check ok\n"));
25188+ z->state->mode = DONE;
25189+ case DONE:
25190+ return Z_STREAM_END;
25191+ case BAD:
25192+ return Z_DATA_ERROR;
25193+ default:
25194+ return Z_STREAM_ERROR;
25195+ }
25196+#ifdef NEED_DUMMY_RETURN
25197+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
25198+#endif
25199+}
25200+
25201+
25202+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
25203+z_streamp z;
25204+const Bytef *dictionary;
25205+uInt dictLength;
25206+{
25207+ uInt length = dictLength;
25208+
25209+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
25210+ return Z_STREAM_ERROR;
25211+
25212+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
25213+ z->adler = 1L;
25214+
25215+ if (length >= ((uInt)1<<z->state->wbits))
25216+ {
25217+ length = (1<<z->state->wbits)-1;
25218+ dictionary += dictLength - length;
25219+ }
25220+ inflate_set_dictionary(z->state->blocks, dictionary, length);
25221+ z->state->mode = BLOCKS;
25222+ return Z_OK;
25223+}
25224+
25225+
25226+int ZEXPORT inflateSync(z)
25227+z_streamp z;
25228+{
25229+ uInt n; /* number of bytes to look at */
25230+ Bytef *p; /* pointer to bytes */
25231+ uInt m; /* number of marker bytes found in a row */
25232+ uLong r, w; /* temporaries to save total_in and total_out */
25233+
25234+ /* set up */
25235+ if (z == Z_NULL || z->state == Z_NULL)
25236+ return Z_STREAM_ERROR;
25237+ if (z->state->mode != BAD)
25238+ {
25239+ z->state->mode = BAD;
25240+ z->state->sub.marker = 0;
25241+ }
25242+ if ((n = z->avail_in) == 0)
25243+ return Z_BUF_ERROR;
25244+ p = z->next_in;
25245+ m = z->state->sub.marker;
25246+
25247+ /* search */
25248+ while (n && m < 4)
25249+ {
25250+ static const Byte mark[4] = {0, 0, 0xff, 0xff};
25251+ if (*p == mark[m])
25252+ m++;
25253+ else if (*p)
25254+ m = 0;
25255+ else
25256+ m = 4 - m;
25257+ p++, n--;
25258+ }
25259+
25260+ /* restore */
25261+ z->total_in += p - z->next_in;
25262+ z->next_in = p;
25263+ z->avail_in = n;
25264+ z->state->sub.marker = m;
25265+
25266+ /* return no joy or set up to restart on a new block */
25267+ if (m != 4)
25268+ return Z_DATA_ERROR;
25269+ r = z->total_in; w = z->total_out;
25270+ inflateReset(z);
25271+ z->total_in = r; z->total_out = w;
25272+ z->state->mode = BLOCKS;
25273+ return Z_OK;
25274+}
25275+
25276+
25277+/* Returns true if inflate is currently at the end of a block generated
25278+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
25279+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
25280+ * but removes the length bytes of the resulting empty stored block. When
25281+ * decompressing, PPP checks that at the end of input packet, inflate is
25282+ * waiting for these length bytes.
25283+ */
25284+int ZEXPORT inflateSyncPoint(z)
25285+z_streamp z;
25286+{
25287+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
25288+ return Z_STREAM_ERROR;
25289+ return inflate_blocks_sync_point(z->state->blocks);
25290+}
25291--- /dev/null Tue Mar 11 13:02:56 2003
25292+++ linux/net/ipsec/inftrees.c Mon Feb 9 13:51:03 2004
25293@@ -0,0 +1,454 @@
25294+/* inftrees.c -- generate Huffman trees for efficient decoding
25295+ * Copyright (C) 1995-2002 Mark Adler
25296+ * For conditions of distribution and use, see copyright notice in zlib.h
25297+ */
25298+
25299+#include <zlib/zutil.h>
25300+#include "inftrees.h"
25301+
25302+#if !defined(BUILDFIXED) && !defined(STDC)
25303+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
25304+#endif
25305+
25306+local const char inflate_copyright[] =
25307+ " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
25308+/*
25309+ If you use the zlib library in a product, an acknowledgment is welcome
25310+ in the documentation of your product. If for some reason you cannot
25311+ include such an acknowledgment, I would appreciate that you keep this
25312+ copyright string in the executable of your product.
25313+ */
25314+struct internal_state {int dummy;}; /* for buggy compilers */
25315+
25316+/* simplify the use of the inflate_huft type with some defines */
25317+#define exop word.what.Exop
25318+#define bits word.what.Bits
25319+
25320+
25321+local int huft_build OF((
25322+ uIntf *, /* code lengths in bits */
25323+ uInt, /* number of codes */
25324+ uInt, /* number of "simple" codes */
25325+ const uIntf *, /* list of base values for non-simple codes */
25326+ const uIntf *, /* list of extra bits for non-simple codes */
25327+ inflate_huft * FAR*,/* result: starting table */
25328+ uIntf *, /* maximum lookup bits (returns actual) */
25329+ inflate_huft *, /* space for trees */
25330+ uInt *, /* hufts used in space */
25331+ uIntf * )); /* space for values */
25332+
25333+/* Tables for deflate from PKZIP's appnote.txt. */
25334+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
25335+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
25336+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
25337+ /* see note #13 above about 258 */
25338+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
25339+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
25340+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
25341+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
25342+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
25343+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
25344+ 8193, 12289, 16385, 24577};
25345+local const uInt cpdext[30] = { /* Extra bits for distance codes */
25346+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
25347+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
25348+ 12, 12, 13, 13};
25349+
25350+/*
25351+ Huffman code decoding is performed using a multi-level table lookup.
25352+ The fastest way to decode is to simply build a lookup table whose
25353+ size is determined by the longest code. However, the time it takes
25354+ to build this table can also be a factor if the data being decoded
25355+ is not very long. The most common codes are necessarily the
25356+ shortest codes, so those codes dominate the decoding time, and hence
25357+ the speed. The idea is you can have a shorter table that decodes the
25358+ shorter, more probable codes, and then point to subsidiary tables for
25359+ the longer codes. The time it costs to decode the longer codes is
25360+ then traded against the time it takes to make longer tables.
25361+
25362+ This results of this trade are in the variables lbits and dbits
25363+ below. lbits is the number of bits the first level table for literal/
25364+ length codes can decode in one step, and dbits is the same thing for
25365+ the distance codes. Subsequent tables are also less than or equal to
25366+ those sizes. These values may be adjusted either when all of the
25367+ codes are shorter than that, in which case the longest code length in
25368+ bits is used, or when the shortest code is *longer* than the requested
25369+ table size, in which case the length of the shortest code in bits is
25370+ used.
25371+
25372+ There are two different values for the two tables, since they code a
25373+ different number of possibilities each. The literal/length table
25374+ codes 286 possible values, or in a flat code, a little over eight
25375+ bits. The distance table codes 30 possible values, or a little less
25376+ than five bits, flat. The optimum values for speed end up being
25377+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
25378+ The optimum values may differ though from machine to machine, and
25379+ possibly even between compilers. Your mileage may vary.
25380+ */
25381+
25382+
25383+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
25384+#define BMAX 15 /* maximum bit length of any code */
25385+
25386+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
25387+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
25388+uInt n; /* number of codes (assumed <= 288) */
25389+uInt s; /* number of simple-valued codes (0..s-1) */
25390+const uIntf *d; /* list of base values for non-simple codes */
25391+const uIntf *e; /* list of extra bits for non-simple codes */
25392+inflate_huft * FAR *t; /* result: starting table */
25393+uIntf *m; /* maximum lookup bits, returns actual */
25394+inflate_huft *hp; /* space for trees */
25395+uInt *hn; /* hufts used in space */
25396+uIntf *v; /* working area: values in order of bit length */
25397+/* Given a list of code lengths and a maximum table size, make a set of
25398+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
25399+ if the given code set is incomplete (the tables are still built in this
25400+ case), or Z_DATA_ERROR if the input is invalid. */
25401+{
25402+
25403+ uInt a; /* counter for codes of length k */
25404+ uInt c[BMAX+1]; /* bit length count table */
25405+ uInt f; /* i repeats in table every f entries */
25406+ int g; /* maximum code length */
25407+ int h; /* table level */
25408+ register uInt i; /* counter, current code */
25409+ register uInt j; /* counter */
25410+ register int k; /* number of bits in current code */
25411+ int l; /* bits per table (returned in m) */
25412+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
25413+ register uIntf *p; /* pointer into c[], b[], or v[] */
25414+ inflate_huft *q; /* points to current table */
25415+ struct inflate_huft_s r; /* table entry for structure assignment */
25416+ inflate_huft *u[BMAX]; /* table stack */
25417+ register int w; /* bits before this table == (l * h) */
25418+ uInt x[BMAX+1]; /* bit offsets, then code stack */
25419+ uIntf *xp; /* pointer into x */
25420+ int y; /* number of dummy codes added */
25421+ uInt z; /* number of entries in current table */
25422+
25423+
25424+ /* Generate counts for each bit length */
25425+ p = c;
25426+#define C0 *p++ = 0;
25427+#define C2 C0 C0 C0 C0
25428+#define C4 C2 C2 C2 C2
25429+ C4 /* clear c[]--assume BMAX+1 is 16 */
25430+ p = b; i = n;
25431+ do {
25432+ c[*p++]++; /* assume all entries <= BMAX */
25433+ } while (--i);
25434+ if (c[0] == n) /* null input--all zero length codes */
25435+ {
25436+ *t = (inflate_huft *)Z_NULL;
25437+ *m = 0;
25438+ return Z_OK;
25439+ }
25440+
25441+
25442+ /* Find minimum and maximum length, bound *m by those */
25443+ l = *m;
25444+ for (j = 1; j <= BMAX; j++)
25445+ if (c[j])
25446+ break;
25447+ k = j; /* minimum code length */
25448+ if ((uInt)l < j)
25449+ l = j;
25450+ for (i = BMAX; i; i--)
25451+ if (c[i])
25452+ break;
25453+ g = i; /* maximum code length */
25454+ if ((uInt)l > i)
25455+ l = i;
25456+ *m = l;
25457+
25458+
25459+ /* Adjust last length count to fill out codes, if needed */
25460+ for (y = 1 << j; j < i; j++, y <<= 1)
25461+ if ((y -= c[j]) < 0)
25462+ return Z_DATA_ERROR;
25463+ if ((y -= c[i]) < 0)
25464+ return Z_DATA_ERROR;
25465+ c[i] += y;
25466+
25467+
25468+ /* Generate starting offsets into the value table for each length */
25469+ x[1] = j = 0;
25470+ p = c + 1; xp = x + 2;
25471+ while (--i) { /* note that i == g from above */
25472+ *xp++ = (j += *p++);
25473+ }
25474+
25475+
25476+ /* Make a table of values in order of bit lengths */
25477+ p = b; i = 0;
25478+ do {
25479+ if ((j = *p++) != 0)
25480+ v[x[j]++] = i;
25481+ } while (++i < n);
25482+ n = x[g]; /* set n to length of v */
25483+
25484+
25485+ /* Generate the Huffman codes and for each, make the table entries */
25486+ x[0] = i = 0; /* first Huffman code is zero */
25487+ p = v; /* grab values in bit order */
25488+ h = -1; /* no tables yet--level -1 */
25489+ w = -l; /* bits decoded == (l * h) */
25490+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
25491+ q = (inflate_huft *)Z_NULL; /* ditto */
25492+ z = 0; /* ditto */
25493+
25494+ /* go through the bit lengths (k already is bits in shortest code) */
25495+ for (; k <= g; k++)
25496+ {
25497+ a = c[k];
25498+ while (a--)
25499+ {
25500+ /* here i is the Huffman code of length k bits for value *p */
25501+ /* make tables up to required level */
25502+ while (k > w + l)
25503+ {
25504+ h++;
25505+ w += l; /* previous table always l bits */
25506+
25507+ /* compute minimum size table less than or equal to l bits */
25508+ z = g - w;
25509+ z = z > (uInt)l ? l : z; /* table size upper limit */
25510+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
25511+ { /* too few codes for k-w bit table */
25512+ f -= a + 1; /* deduct codes from patterns left */
25513+ xp = c + k;
25514+ if (j < z)
25515+ while (++j < z) /* try smaller tables up to z bits */
25516+ {
25517+ if ((f <<= 1) <= *++xp)
25518+ break; /* enough codes to use up j bits */
25519+ f -= *xp; /* else deduct codes from patterns */
25520+ }
25521+ }
25522+ z = 1 << j; /* table entries for j-bit table */
25523+
25524+ /* allocate new table */
25525+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
25526+ return Z_DATA_ERROR; /* overflow of MANY */
25527+ u[h] = q = hp + *hn;
25528+ *hn += z;
25529+
25530+ /* connect to last table, if there is one */
25531+ if (h)
25532+ {
25533+ x[h] = i; /* save pattern for backing up */
25534+ r.bits = (Byte)l; /* bits to dump before this table */
25535+ r.exop = (Byte)j; /* bits in this table */
25536+ j = i >> (w - l);
25537+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
25538+ u[h-1][j] = r; /* connect to last table */
25539+ }
25540+ else
25541+ *t = q; /* first table is returned result */
25542+ }
25543+
25544+ /* set up table entry in r */
25545+ r.bits = (Byte)(k - w);
25546+ if (p >= v + n)
25547+ r.exop = 128 + 64; /* out of values--invalid code */
25548+ else if (*p < s)
25549+ {
25550+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
25551+ r.base = *p++; /* simple code is just the value */
25552+ }
25553+ else
25554+ {
25555+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
25556+ r.base = d[*p++ - s];
25557+ }
25558+
25559+ /* fill code-like entries with r */
25560+ f = 1 << (k - w);
25561+ for (j = i >> w; j < z; j += f)
25562+ q[j] = r;
25563+
25564+ /* backwards increment the k-bit code i */
25565+ for (j = 1 << (k - 1); i & j; j >>= 1)
25566+ i ^= j;
25567+ i ^= j;
25568+
25569+ /* backup over finished tables */
25570+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */
25571+ while ((i & mask) != x[h])
25572+ {
25573+ h--; /* don't need to update q */
25574+ w -= l;
25575+ mask = (1 << w) - 1;
25576+ }
25577+ }
25578+ }
25579+
25580+
25581+ /* Return Z_BUF_ERROR if we were given an incomplete table */
25582+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
25583+}
25584+
25585+
25586+int inflate_trees_bits(c, bb, tb, hp, z)
25587+uIntf *c; /* 19 code lengths */
25588+uIntf *bb; /* bits tree desired/actual depth */
25589+inflate_huft * FAR *tb; /* bits tree result */
25590+inflate_huft *hp; /* space for trees */
25591+z_streamp z; /* for messages */
25592+{
25593+ int r;
25594+ uInt hn = 0; /* hufts used in space */
25595+ uIntf *v; /* work area for huft_build */
25596+
25597+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
25598+ return Z_MEM_ERROR;
25599+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
25600+ tb, bb, hp, &hn, v);
25601+ if (r == Z_DATA_ERROR)
25602+ z->msg = (char*)"oversubscribed dynamic bit lengths tree";
25603+ else if (r == Z_BUF_ERROR || *bb == 0)
25604+ {
25605+ z->msg = (char*)"incomplete dynamic bit lengths tree";
25606+ r = Z_DATA_ERROR;
25607+ }
25608+ ZFREE(z, v);
25609+ return r;
25610+}
25611+
25612+
25613+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
25614+uInt nl; /* number of literal/length codes */
25615+uInt nd; /* number of distance codes */
25616+uIntf *c; /* that many (total) code lengths */
25617+uIntf *bl; /* literal desired/actual bit depth */
25618+uIntf *bd; /* distance desired/actual bit depth */
25619+inflate_huft * FAR *tl; /* literal/length tree result */
25620+inflate_huft * FAR *td; /* distance tree result */
25621+inflate_huft *hp; /* space for trees */
25622+z_streamp z; /* for messages */
25623+{
25624+ int r;
25625+ uInt hn = 0; /* hufts used in space */
25626+ uIntf *v; /* work area for huft_build */
25627+
25628+ /* allocate work area */
25629+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25630+ return Z_MEM_ERROR;
25631+
25632+ /* build literal/length tree */
25633+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
25634+ if (r != Z_OK || *bl == 0)
25635+ {
25636+ if (r == Z_DATA_ERROR)
25637+ z->msg = (char*)"oversubscribed literal/length tree";
25638+ else if (r != Z_MEM_ERROR)
25639+ {
25640+ z->msg = (char*)"incomplete literal/length tree";
25641+ r = Z_DATA_ERROR;
25642+ }
25643+ ZFREE(z, v);
25644+ return r;
25645+ }
25646+
25647+ /* build distance tree */
25648+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
25649+ if (r != Z_OK || (*bd == 0 && nl > 257))
25650+ {
25651+ if (r == Z_DATA_ERROR)
25652+ z->msg = (char*)"oversubscribed distance tree";
25653+ else if (r == Z_BUF_ERROR) {
25654+#ifdef PKZIP_BUG_WORKAROUND
25655+ r = Z_OK;
25656+ }
25657+#else
25658+ z->msg = (char*)"incomplete distance tree";
25659+ r = Z_DATA_ERROR;
25660+ }
25661+ else if (r != Z_MEM_ERROR)
25662+ {
25663+ z->msg = (char*)"empty distance tree with lengths";
25664+ r = Z_DATA_ERROR;
25665+ }
25666+ ZFREE(z, v);
25667+ return r;
25668+#endif
25669+ }
25670+
25671+ /* done */
25672+ ZFREE(z, v);
25673+ return Z_OK;
25674+}
25675+
25676+
25677+/* build fixed tables only once--keep them here */
25678+#ifdef BUILDFIXED
25679+local int fixed_built = 0;
25680+#define FIXEDH 544 /* number of hufts used by fixed tables */
25681+local inflate_huft fixed_mem[FIXEDH];
25682+local uInt fixed_bl;
25683+local uInt fixed_bd;
25684+local inflate_huft *fixed_tl;
25685+local inflate_huft *fixed_td;
25686+#else
25687+#include "inffixed.h"
25688+#endif
25689+
25690+
25691+int inflate_trees_fixed(bl, bd, tl, td, z)
25692+uIntf *bl; /* literal desired/actual bit depth */
25693+uIntf *bd; /* distance desired/actual bit depth */
25694+inflate_huft * FAR *tl; /* literal/length tree result */
25695+inflate_huft * FAR *td; /* distance tree result */
25696+z_streamp z; /* for memory allocation */
25697+{
25698+#ifdef BUILDFIXED
25699+ /* build fixed tables if not already */
25700+ if (!fixed_built)
25701+ {
25702+ int k; /* temporary variable */
25703+ uInt f = 0; /* number of hufts used in fixed_mem */
25704+ uIntf *c; /* length list for huft_build */
25705+ uIntf *v; /* work area for huft_build */
25706+
25707+ /* allocate memory */
25708+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25709+ return Z_MEM_ERROR;
25710+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25711+ {
25712+ ZFREE(z, c);
25713+ return Z_MEM_ERROR;
25714+ }
25715+
25716+ /* literal table */
25717+ for (k = 0; k < 144; k++)
25718+ c[k] = 8;
25719+ for (; k < 256; k++)
25720+ c[k] = 9;
25721+ for (; k < 280; k++)
25722+ c[k] = 7;
25723+ for (; k < 288; k++)
25724+ c[k] = 8;
25725+ fixed_bl = 9;
25726+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
25727+ fixed_mem, &f, v);
25728+
25729+ /* distance table */
25730+ for (k = 0; k < 30; k++)
25731+ c[k] = 5;
25732+ fixed_bd = 5;
25733+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
25734+ fixed_mem, &f, v);
25735+
25736+ /* done */
25737+ ZFREE(z, v);
25738+ ZFREE(z, c);
25739+ fixed_built = 1;
25740+ }
25741+#endif
25742+ *bl = fixed_bl;
25743+ *bd = fixed_bd;
25744+ *tl = fixed_tl;
25745+ *td = fixed_td;
25746+ return Z_OK;
25747+}
25748--- /dev/null Tue Mar 11 13:02:56 2003
25749+++ linux/net/ipsec/inftrees.h Mon Feb 9 13:51:03 2004
25750@@ -0,0 +1,63 @@
25751+/* inftrees.h -- header to use inftrees.c
25752+ * Copyright (C) 1995-2002 Mark Adler
25753+ * For conditions of distribution and use, see copyright notice in zlib.h
25754+ */
25755+
25756+/* WARNING: this file should *not* be used by applications. It is
25757+ part of the implementation of the compression library and is
25758+ subject to change. Applications should only use zlib.h.
25759+ */
25760+
25761+/* Huffman code lookup table entry--this entry is four bytes for machines
25762+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
25763+
25764+#ifndef _INFTREES_H
25765+#define _INFTREES_H
25766+
25767+typedef struct inflate_huft_s FAR inflate_huft;
25768+
25769+struct inflate_huft_s {
25770+ union {
25771+ struct {
25772+ Byte Exop; /* number of extra bits or operation */
25773+ Byte Bits; /* number of bits in this code or subcode */
25774+ } what;
25775+ uInt pad; /* pad structure to a power of 2 (4 bytes for */
25776+ } word; /* 16-bit, 8 bytes for 32-bit int's) */
25777+ uInt base; /* literal, length base, distance base,
25778+ or table offset */
25779+};
25780+
25781+/* Maximum size of dynamic tree. The maximum found in a long but non-
25782+ exhaustive search was 1004 huft structures (850 for length/literals
25783+ and 154 for distances, the latter actually the result of an
25784+ exhaustive search). The actual maximum is not known, but the
25785+ value below is more than safe. */
25786+#define MANY 1440
25787+
25788+extern int inflate_trees_bits OF((
25789+ uIntf *, /* 19 code lengths */
25790+ uIntf *, /* bits tree desired/actual depth */
25791+ inflate_huft * FAR *, /* bits tree result */
25792+ inflate_huft *, /* space for trees */
25793+ z_streamp)); /* for messages */
25794+
25795+extern int inflate_trees_dynamic OF((
25796+ uInt, /* number of literal/length codes */
25797+ uInt, /* number of distance codes */
25798+ uIntf *, /* that many (total) code lengths */
25799+ uIntf *, /* literal desired/actual bit depth */
25800+ uIntf *, /* distance desired/actual bit depth */
25801+ inflate_huft * FAR *, /* literal/length tree result */
25802+ inflate_huft * FAR *, /* distance tree result */
25803+ inflate_huft *, /* space for trees */
25804+ z_streamp)); /* for messages */
25805+
25806+extern int inflate_trees_fixed OF((
25807+ uIntf *, /* literal desired/actual bit depth */
25808+ uIntf *, /* distance desired/actual bit depth */
25809+ inflate_huft * FAR *, /* literal/length tree result */
25810+ inflate_huft * FAR *, /* distance tree result */
25811+ z_streamp)); /* for memory allocation */
25812+
25813+#endif /* _INFTREES_H */
25814--- /dev/null Tue Mar 11 13:02:56 2003
25815+++ linux/net/ipsec/infutil.c Mon Feb 9 13:51:03 2004
25816@@ -0,0 +1,87 @@
25817+/* inflate_util.c -- data and routines common to blocks and codes
25818+ * Copyright (C) 1995-2002 Mark Adler
25819+ * For conditions of distribution and use, see copyright notice in zlib.h
25820+ */
25821+
25822+#include <zlib/zutil.h>
25823+#include "infblock.h"
25824+#include "inftrees.h"
25825+#include "infcodes.h"
25826+#include "infutil.h"
25827+
25828+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
25829+
25830+/* And'ing with mask[n] masks the lower n bits */
25831+uInt inflate_mask[17] = {
25832+ 0x0000,
25833+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
25834+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
25835+};
25836+
25837+
25838+/* copy as much as possible from the sliding window to the output area */
25839+int inflate_flush(s, z, r)
25840+inflate_blocks_statef *s;
25841+z_streamp z;
25842+int r;
25843+{
25844+ uInt n;
25845+ Bytef *p;
25846+ Bytef *q;
25847+
25848+ /* local copies of source and destination pointers */
25849+ p = z->next_out;
25850+ q = s->read;
25851+
25852+ /* compute number of bytes to copy as far as end of window */
25853+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
25854+ if (n > z->avail_out) n = z->avail_out;
25855+ if (n && r == Z_BUF_ERROR) r = Z_OK;
25856+
25857+ /* update counters */
25858+ z->avail_out -= n;
25859+ z->total_out += n;
25860+
25861+ /* update check information */
25862+ if (s->checkfn != Z_NULL)
25863+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
25864+
25865+ /* copy as far as end of window */
25866+ zmemcpy(p, q, n);
25867+ p += n;
25868+ q += n;
25869+
25870+ /* see if more to copy at beginning of window */
25871+ if (q == s->end)
25872+ {
25873+ /* wrap pointers */
25874+ q = s->window;
25875+ if (s->write == s->end)
25876+ s->write = s->window;
25877+
25878+ /* compute bytes to copy */
25879+ n = (uInt)(s->write - q);
25880+ if (n > z->avail_out) n = z->avail_out;
25881+ if (n && r == Z_BUF_ERROR) r = Z_OK;
25882+
25883+ /* update counters */
25884+ z->avail_out -= n;
25885+ z->total_out += n;
25886+
25887+ /* update check information */
25888+ if (s->checkfn != Z_NULL)
25889+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
25890+
25891+ /* copy */
25892+ zmemcpy(p, q, n);
25893+ p += n;
25894+ q += n;
25895+ }
25896+
25897+ /* update pointers */
25898+ z->next_out = p;
25899+ s->read = q;
25900+
25901+ /* done */
25902+ return r;
25903+}
25904--- /dev/null Tue Mar 11 13:02:56 2003
25905+++ linux/net/ipsec/infutil.h Mon Feb 9 13:51:03 2004
25906@@ -0,0 +1,98 @@
25907+/* infutil.h -- types and macros common to blocks and codes
25908+ * Copyright (C) 1995-2002 Mark Adler
25909+ * For conditions of distribution and use, see copyright notice in zlib.h
25910+ */
25911+
25912+/* WARNING: this file should *not* be used by applications. It is
25913+ part of the implementation of the compression library and is
25914+ subject to change. Applications should only use zlib.h.
25915+ */
25916+
25917+#ifndef _INFUTIL_H
25918+#define _INFUTIL_H
25919+
25920+typedef enum {
25921+ TYPE, /* get type bits (3, including end bit) */
25922+ LENS, /* get lengths for stored */
25923+ STORED, /* processing stored block */
25924+ TABLE, /* get table lengths */
25925+ BTREE, /* get bit lengths tree for a dynamic block */
25926+ DTREE, /* get length, distance trees for a dynamic block */
25927+ CODES, /* processing fixed or dynamic block */
25928+ DRY, /* output remaining window bytes */
25929+ DONE, /* finished last block, done */
25930+ BAD} /* got a data error--stuck here */
25931+inflate_block_mode;
25932+
25933+/* inflate blocks semi-private state */
25934+struct inflate_blocks_state {
25935+
25936+ /* mode */
25937+ inflate_block_mode mode; /* current inflate_block mode */
25938+
25939+ /* mode dependent information */
25940+ union {
25941+ uInt left; /* if STORED, bytes left to copy */
25942+ struct {
25943+ uInt table; /* table lengths (14 bits) */
25944+ uInt index; /* index into blens (or border) */
25945+ uIntf *blens; /* bit lengths of codes */
25946+ uInt bb; /* bit length tree depth */
25947+ inflate_huft *tb; /* bit length decoding tree */
25948+ } trees; /* if DTREE, decoding info for trees */
25949+ struct {
25950+ inflate_codes_statef
25951+ *codes;
25952+ } decode; /* if CODES, current state */
25953+ } sub; /* submode */
25954+ uInt last; /* true if this block is the last block */
25955+
25956+ /* mode independent information */
25957+ uInt bitk; /* bits in bit buffer */
25958+ uLong bitb; /* bit buffer */
25959+ inflate_huft *hufts; /* single malloc for tree space */
25960+ Bytef *window; /* sliding window */
25961+ Bytef *end; /* one byte after sliding window */
25962+ Bytef *read; /* window read pointer */
25963+ Bytef *write; /* window write pointer */
25964+ check_func checkfn; /* check function */
25965+ uLong check; /* check on output */
25966+
25967+};
25968+
25969+
25970+/* defines for inflate input/output */
25971+/* update pointers and return */
25972+#define UPDBITS {s->bitb=b;s->bitk=k;}
25973+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
25974+#define UPDOUT {s->write=q;}
25975+#define UPDATE {UPDBITS UPDIN UPDOUT}
25976+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
25977+/* get bytes and bits */
25978+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
25979+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
25980+#define NEXTBYTE (n--,*p++)
25981+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
25982+#define DUMPBITS(j) {b>>=(j);k-=(j);}
25983+/* output bytes */
25984+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
25985+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
25986+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
25987+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
25988+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
25989+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
25990+/* load local pointers */
25991+#define LOAD {LOADIN LOADOUT}
25992+
25993+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
25994+extern uInt inflate_mask[17];
25995+
25996+/* copy as much as possible from the sliding window to the output area */
25997+extern int inflate_flush OF((
25998+ inflate_blocks_statef *,
25999+ z_streamp ,
26000+ int));
26001+
26002+struct internal_state {int dummy;}; /* for buggy compilers */
26003+
26004+#endif /* _INFUTIL_H */
26005--- /dev/null Tue Mar 11 13:02:56 2003
26006+++ linux/net/ipsec/initaddr.c Mon Feb 9 13:51:03 2004
26007@@ -0,0 +1,50 @@
26008+/*
26009+ * initialize address structure
26010+ * Copyright (C) 2000 Henry Spencer.
26011+ *
26012+ * This library is free software; you can redistribute it and/or modify it
26013+ * under the terms of the GNU Library General Public License as published by
26014+ * the Free Software Foundation; either version 2 of the License, or (at your
26015+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
26016+ *
26017+ * This library is distributed in the hope that it will be useful, but
26018+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26019+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
26020+ * License for more details.
26021+ *
26022+ * RCSID $Id: initaddr.c,v 1.6 2004-07-10 07:43:47 mcr Exp $
26023+ */
26024+#include "openswan.h"
26025+
26026+/*
26027+ - initaddr - initialize ip_address from bytes
26028+ */
26029+err_t /* NULL for success, else string literal */
26030+initaddr(src, srclen, af, dst)
26031+const unsigned char *src;
26032+size_t srclen;
26033+int af; /* address family */
26034+ip_address *dst;
26035+{
26036+ switch (af) {
26037+ case AF_INET:
26038+ if (srclen != 4)
26039+ return "IPv4 address must be exactly 4 bytes";
26040+ dst->u.v4.sin_family = af;
26041+ dst->u.v4.sin_port = 0; /* unused */
26042+ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
26043+ break;
26044+ case AF_INET6:
26045+ if (srclen != 16)
26046+ return "IPv6 address must be exactly 16 bytes";
26047+ dst->u.v6.sin6_family = af;
26048+ dst->u.v6.sin6_flowinfo = 0; /* unused */
26049+ dst->u.v6.sin6_port = 0; /* unused */
26050+ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
26051+ break;
26052+ default:
26053+ return "unknown address family in initaddr";
26054+ break;
26055+ }
26056+ return NULL;
26057+}
26058--- /dev/null Tue Mar 11 13:02:56 2003
26059+++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004
26060@@ -0,0 +1,697 @@
26061+/*
26062+ * IPCOMP zlib interface code.
26063+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
26064+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
26065+ *
26066+ * This program is free software; you can redistribute it and/or modify it
26067+ * under the terms of the GNU General Public License as published by the
26068+ * Free Software Foundation; either version 2 of the License, or (at your
26069+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
26070+ *
26071+ * This program is distributed in the hope that it will be useful, but
26072+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26073+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26074+ * for more details.
26075+ */
26076+
26077+char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.41.2.8 2007-10-30 21:33:40 paul Exp $";
26078+
26079+/* SSS */
26080+
26081+#ifndef AUTOCONF_INCLUDED
26082+#include <linux/config.h>
26083+#endif
26084+#include <linux/version.h>
26085+
26086+#define __NO_VERSION__
26087+#include <linux/module.h>
26088+#include <linux/kernel.h> /* printk() */
26089+
26090+#include "openswan/ipsec_param.h"
26091+
26092+#ifdef MALLOC_SLAB
26093+# include <linux/slab.h> /* kmalloc() */
26094+#else /* MALLOC_SLAB */
26095+# include <linux/malloc.h> /* kmalloc() */
26096+#endif /* MALLOC_SLAB */
26097+#include <linux/errno.h> /* error codes */
26098+#include <linux/types.h>
26099+#include <linux/netdevice.h>
26100+#include <linux/ip.h>
26101+#include <linux/skbuff.h>
26102+
26103+#include <linux/netdevice.h> /* struct device, and other headers */
26104+#include <linux/etherdevice.h> /* eth_type_trans */
26105+#include <linux/ip.h> /* struct iphdr */
26106+#include <linux/skbuff.h>
26107+#include <asm/uaccess.h>
26108+#include <asm/checksum.h>
26109+
26110+#include <openswan.h>
26111+
26112+#include <net/ip.h>
26113+
26114+#include "openswan/radij.h"
26115+#include "openswan/ipsec_encap.h"
26116+#include "openswan/ipsec_sa.h"
26117+
26118+#include "openswan/ipsec_xform.h"
26119+#include "openswan/ipsec_tunnel.h"
26120+#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
26121+#include "openswan/ipsec_proto.h"
26122+#include "openswan/ipcomp.h"
26123+#include "zlib/zlib.h"
26124+#include "zlib/zutil.h"
26125+
26126+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
26127+
26128+#ifdef CONFIG_KLIPS_DEBUG
26129+int sysctl_ipsec_debug_ipcomp = 0;
26130+#endif /* CONFIG_KLIPS_DEBUG */
26131+
26132+static
26133+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
26134+
26135+static
26136+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
26137+{
26138+ return (voidpf) kmalloc(items*size, GFP_ATOMIC);
26139+}
26140+
26141+static
26142+void my_zfree(voidpf opaque, voidpf address)
26143+{
26144+ kfree(address);
26145+}
26146+
26147+/*
26148+ * We use this function because sometimes we want to pass a negative offset
26149+ * into skb_put(), this does not work on 64bit platforms because long to
26150+ * unsigned int casting.
26151+ */
26152+static inline unsigned char *
26153+safe_skb_put(struct sk_buff *skb, int extend)
26154+{
26155+ unsigned char *ptr;
26156+
26157+ if (extend>0) {
26158+ // increase the size of the packet
26159+ ptr = skb_put(skb, extend);
26160+ } else {
26161+ // shrink the size of the packet
26162+ ptr = skb_tail_pointer(skb);
26163+ skb_trim (skb, skb->len + extend);
26164+ }
26165+
26166+ return ptr;
26167+}
26168+
26169+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
26170+{
26171+ struct iphdr *iph;
26172+ unsigned int iphlen, pyldsz, cpyldsz;
26173+ unsigned char *buffer;
26174+ z_stream zs;
26175+ int zresult;
26176+
26177+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26178+ "klips_debug:skb_compress: .\n");
26179+
26180+ if(skb == NULL) {
26181+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26182+ "klips_debug:skb_compress: "
26183+ "passed in NULL skb, returning ERROR.\n");
26184+ if(flags != NULL) {
26185+ *flags |= IPCOMP_PARMERROR;
26186+ }
26187+ return skb;
26188+ }
26189+
26190+ if(ips == NULL) {
26191+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26192+ "klips_debug:skb_compress: "
26193+ "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
26194+ if(flags) {
26195+ *flags |= IPCOMP_PARMERROR;
26196+ }
26197+ return skb;
26198+ }
26199+
26200+ if (flags == NULL) {
26201+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26202+ "klips_debug:skb_compress: "
26203+ "passed in NULL flags, returning ERROR.\n");
26204+ ipsec_kfree_skb(skb);
26205+ return NULL;
26206+ }
26207+
26208+#ifdef NET_21
26209+ iph = ip_hdr(skb);
26210+#else /* NET_21 */
26211+ iph = skb->ip_hdr;
26212+#endif /* NET_21 */
26213+
26214+ switch (iph->protocol) {
26215+ case IPPROTO_COMP:
26216+ case IPPROTO_AH:
26217+ case IPPROTO_ESP:
26218+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26219+ "klips_debug:skb_compress: "
26220+ "skipping compression of packet with ip protocol %d.\n",
26221+ iph->protocol);
26222+ *flags |= IPCOMP_UNCOMPRESSABLE;
26223+ return skb;
26224+ }
26225+
26226+ /* Don't compress packets already fragmented */
26227+ if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
26228+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26229+ "klips_debug:skb_compress: "
26230+ "skipping compression of fragmented packet.\n");
26231+ *flags |= IPCOMP_UNCOMPRESSABLE;
26232+ return skb;
26233+ }
26234+
26235+ iphlen = iph->ihl << 2;
26236+ pyldsz = ntohs(iph->tot_len) - iphlen;
26237+
26238+ /* Don't compress less than 90 bytes (rfc 2394) */
26239+ if (pyldsz < 90) {
26240+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26241+ "klips_debug:skb_compress: "
26242+ "skipping compression of tiny packet, len=%d.\n",
26243+ pyldsz);
26244+ *flags |= IPCOMP_UNCOMPRESSABLE;
26245+ return skb;
26246+ }
26247+
26248+ /* Adaptive decision */
26249+ if (ips->ips_comp_adapt_skip) {
26250+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26251+ "klips_debug:skb_compress: "
26252+ "skipping compression: ips_comp_adapt_skip=%d.\n",
26253+ ips->ips_comp_adapt_skip);
26254+ ips->ips_comp_adapt_skip--;
26255+ *flags |= IPCOMP_UNCOMPRESSABLE;
26256+ return skb;
26257+ }
26258+
26259+ zs.zalloc = my_zcalloc;
26260+ zs.zfree = my_zfree;
26261+ zs.opaque = 0;
26262+
26263+ /* We want to use deflateInit2 because we don't want the adler
26264+ header. */
26265+ zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
26266+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
26267+ if (zresult != Z_OK) {
26268+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26269+ "klips_error:skb_compress: "
26270+ "deflateInit2() returned error %d (%s), "
26271+ "skipping compression.\n",
26272+ zresult,
26273+ zs.msg ? zs.msg : zError(zresult));
26274+ *flags |= IPCOMP_COMPRESSIONERROR;
26275+ return skb;
26276+ }
26277+
26278+
26279+ /* Max output size. Result should be max this size.
26280+ * Implementation specific tweak:
26281+ * If it's not at least 32 bytes and 6.25% smaller than
26282+ * the original packet, it's probably not worth wasting
26283+ * the receiver's CPU cycles decompressing it.
26284+ * Your mileage may vary.
26285+ */
26286+ cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
26287+
26288+ buffer = kmalloc(cpyldsz, GFP_ATOMIC);
26289+ if (!buffer) {
26290+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26291+ "klips_error:skb_compress: "
26292+ "unable to kmalloc(%d, GFP_ATOMIC), "
26293+ "skipping compression.\n",
26294+ cpyldsz);
26295+ *flags |= IPCOMP_COMPRESSIONERROR;
26296+ deflateEnd(&zs);
26297+ return skb;
26298+ }
26299+
26300+#ifdef CONFIG_KLIPS_DEBUG
26301+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26302+ __u8 *c;
26303+
26304+ c = (__u8*)iph + iphlen;
26305+ ipsec_dmp_block("compress before", c, pyldsz);
26306+ }
26307+#endif /* CONFIG_KLIPS_DEBUG */
26308+
26309+ zs.next_in = (char *) iph + iphlen; /* start of payload */
26310+ zs.avail_in = pyldsz;
26311+ zs.next_out = buffer; /* start of compressed payload */
26312+ zs.avail_out = cpyldsz;
26313+
26314+ /* Finish compression in one step */
26315+ zresult = deflate(&zs, Z_FINISH);
26316+
26317+ /* Free all dynamically allocated buffers */
26318+ deflateEnd(&zs);
26319+ if (zresult != Z_STREAM_END) {
26320+ *flags |= IPCOMP_UNCOMPRESSABLE;
26321+ kfree(buffer);
26322+
26323+ /* Adjust adaptive counters */
26324+ if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
26325+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26326+ "klips_debug:skb_compress: "
26327+ "first %d packets didn't compress, "
26328+ "skipping next %d\n",
26329+ IPCOMP_ADAPT_INITIAL_TRIES,
26330+ IPCOMP_ADAPT_INITIAL_SKIP);
26331+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
26332+ }
26333+ else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
26334+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26335+ "klips_debug:skb_compress: "
26336+ "next %d packets didn't compress, "
26337+ "skipping next %d\n",
26338+ IPCOMP_ADAPT_SUBSEQ_TRIES,
26339+ IPCOMP_ADAPT_SUBSEQ_SKIP);
26340+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
26341+ ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
26342+ }
26343+
26344+ return skb;
26345+ }
26346+
26347+ /* resulting compressed size */
26348+ cpyldsz -= zs.avail_out;
26349+
26350+ /* Insert IPCOMP header */
26351+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
26352+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
26353+ /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
26354+ for internal reference only. */
26355+ ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
26356+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26357+ "klips_debug:skb_compress: "
26358+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
26359+ ntohl(ips->ips_said.spi),
26360+ ntohl(ips->ips_said.spi) & 0x0000ffff,
26361+ ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
26362+ pyldsz,
26363+ cpyldsz);
26364+
26365+ /* Update IP header */
26366+ iph->protocol = IPPROTO_COMP;
26367+ iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
26368+#if 1 /* XXX checksum is done by ipsec_tunnel ? */
26369+ iph->check = 0;
26370+ iph->check = ip_fast_csum((char *) iph, iph->ihl);
26371+#endif
26372+
26373+ /* Copy compressed payload */
26374+ memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
26375+ buffer,
26376+ cpyldsz);
26377+ kfree(buffer);
26378+
26379+ /* Update skb length/tail by "unputting" the shrinkage */
26380+ safe_skb_put (skb, cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
26381+
26382+#ifdef CONFIG_KLIPS_DEBUG
26383+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26384+ __u8 *c;
26385+
26386+ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
26387+ ipsec_dmp_block("compress result", c, cpyldsz);
26388+ }
26389+#endif /* CONFIG_KLIPS_DEBUG */
26390+
26391+ ips->ips_comp_adapt_skip = 0;
26392+ ips->ips_comp_adapt_tries = 0;
26393+
26394+ return skb;
26395+}
26396+
26397+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
26398+{
26399+ struct sk_buff *nskb = NULL;
26400+
26401+ /* original ip header */
26402+ struct iphdr *oiph, *iph;
26403+ unsigned int iphlen, pyldsz, cpyldsz;
26404+ z_stream zs;
26405+ int zresult;
26406+
26407+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26408+ "klips_debug:skb_decompress: .\n");
26409+
26410+ if(!skb) {
26411+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26412+ "klips_error:skb_decompress: "
26413+ "passed in NULL skb, returning ERROR.\n");
26414+ if (flags) *flags |= IPCOMP_PARMERROR;
26415+ return skb;
26416+ }
26417+
26418+ if(!ips && sysctl_ipsec_inbound_policy_check) {
26419+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26420+ "klips_error:skb_decompress: "
26421+ "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
26422+ if (flags) *flags |= IPCOMP_PARMERROR;
26423+ return skb;
26424+ }
26425+
26426+ if (!flags) {
26427+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26428+ "klips_error:skb_decompress: "
26429+ "passed in NULL flags, returning ERROR.\n");
26430+ ipsec_kfree_skb(skb);
26431+ return NULL;
26432+ }
26433+
26434+#ifdef NET_21
26435+ oiph = ip_hdr(skb);
26436+#else /* NET_21 */
26437+ oiph = skb->ip_hdr;
26438+#endif /* NET_21 */
26439+
26440+ iphlen = oiph->ihl << 2;
26441+
26442+ if (oiph->protocol != IPPROTO_COMP) {
26443+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26444+ "klips_error:skb_decompress: "
26445+ "called with non-IPCOMP packet (protocol=%d),"
26446+ "skipping decompression.\n",
26447+ oiph->protocol);
26448+ *flags |= IPCOMP_PARMERROR;
26449+ return skb;
26450+ }
26451+
26452+ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
26453+ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
26454+ != htons(SADB_X_CALG_DEFLATE))
26455+ && sysctl_ipsec_inbound_policy_check
26456+ && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
26457+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26458+ "klips_error:skb_decompress: "
26459+ "called with incompatible IPCOMP packet (flags=%d, "
26460+ "cpi=%d), ips-compalg=%d, skipping decompression.\n",
26461+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
26462+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
26463+ ips ? ips->ips_encalg : 0);
26464+ *flags |= IPCOMP_PARMERROR;
26465+
26466+ return skb;
26467+ }
26468+
26469+ if (ntohs(oiph->frag_off) & ~0x4000) {
26470+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26471+ "klips_error:skb_decompress: "
26472+ "called with fragmented IPCOMP packet, "
26473+ "skipping decompression.\n");
26474+ *flags |= IPCOMP_PARMERROR;
26475+ return skb;
26476+ }
26477+
26478+ /* original compressed payload size */
26479+ cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
26480+
26481+ zs.zalloc = my_zcalloc;
26482+ zs.zfree = my_zfree;
26483+ zs.opaque = 0;
26484+
26485+ zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
26486+ zs.avail_in = cpyldsz;
26487+
26488+ /* Maybe we should be a bit conservative about memory
26489+ requirements and use inflateInit2 */
26490+ /* Beware, that this might make us unable to decompress packets
26491+ from other implementations - HINT: check PGPnet source code */
26492+ /* We want to use inflateInit2 because we don't want the adler
26493+ header. */
26494+ zresult = inflateInit2(&zs, -15);
26495+ if (zresult != Z_OK) {
26496+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26497+ "klips_error:skb_decompress: "
26498+ "inflateInit2() returned error %d (%s), "
26499+ "skipping decompression.\n",
26500+ zresult,
26501+ zs.msg ? zs.msg : zError(zresult));
26502+ *flags |= IPCOMP_DECOMPRESSIONERROR;
26503+
26504+ return skb;
26505+ }
26506+
26507+ /* We have no way of knowing the exact length of the resulting
26508+ decompressed output before we have actually done the decompression.
26509+ For now, we guess that the packet will not be bigger than the
26510+ attached ipsec device's mtu or 16260, whichever is biggest.
26511+ This may be wrong, since the sender's mtu may be bigger yet.
26512+ XXX This must be dealt with later XXX
26513+ */
26514+
26515+ /* max payload size */
26516+ pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
26517+ : (65520 - iphlen);
26518+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26519+ "klips_debug:skb_decompress: "
26520+ "max payload size: %d\n", pyldsz);
26521+
26522+ while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
26523+ (nskb = skb_copy_ipcomp(skb,
26524+ pyldsz - cpyldsz - sizeof(struct ipcomphdr),
26525+ GFP_ATOMIC)) == NULL) {
26526+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26527+ "klips_error:skb_decompress: "
26528+ "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
26529+ "trying with less payload size.\n",
26530+ (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
26531+ pyldsz >>=1;
26532+ }
26533+
26534+ if (!nskb) {
26535+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26536+ "klips_error:skb_decompress: "
26537+ "unable to allocate memory, dropping packet.\n");
26538+ *flags |= IPCOMP_DECOMPRESSIONERROR;
26539+ inflateEnd(&zs);
26540+
26541+ return skb;
26542+ }
26543+
26544+#ifdef CONFIG_KLIPS_DEBUG
26545+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26546+ __u8 *c;
26547+
26548+ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
26549+ ipsec_dmp_block("decompress before", c, cpyldsz);
26550+ }
26551+#endif /* CONFIG_KLIPS_DEBUG */
26552+
26553+#ifdef NET_21
26554+ iph = ip_hdr(nskb);
26555+#else /* NET_21 */
26556+ iph = nskb->ip_hdr;
26557+#endif /* NET_21 */
26558+ zs.next_out = (char *)iph + iphlen;
26559+ zs.avail_out = pyldsz;
26560+
26561+ zresult = inflate(&zs, Z_SYNC_FLUSH);
26562+
26563+ /* work around a bug in zlib, which sometimes wants to taste an extra
26564+ * byte when being used in the (undocumented) raw deflate mode.
26565+ */
26566+ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
26567+ __u8 zerostuff = 0;
26568+
26569+ zs.next_in = &zerostuff;
26570+ zs.avail_in = 1;
26571+ zresult = inflate(&zs, Z_FINISH);
26572+ }
26573+
26574+ inflateEnd(&zs);
26575+ if (zresult != Z_STREAM_END) {
26576+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26577+ "klips_error:skb_decompress: "
26578+ "inflate() returned error %d (%s), "
26579+ "skipping decompression.\n",
26580+ zresult,
26581+ zs.msg ? zs.msg : zError(zresult));
26582+ *flags |= IPCOMP_DECOMPRESSIONERROR;
26583+ ipsec_kfree_skb(nskb);
26584+
26585+ return skb;
26586+ }
26587+
26588+ /* Update IP header */
26589+ /* resulting decompressed size */
26590+ pyldsz -= zs.avail_out;
26591+ iph->tot_len = htons(iphlen + pyldsz);
26592+ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
26593+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26594+ "klips_debug:skb_decompress: "
26595+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
26596+ ips ? ntohl(ips->ips_said.spi) : 0,
26597+ ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
26598+ ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
26599+ cpyldsz,
26600+ pyldsz,
26601+ iph->protocol);
26602+
26603+#if 1 /* XXX checksum is done by ipsec_rcv ? */
26604+ iph->check = 0;
26605+ iph->check = ip_fast_csum((char*) iph, iph->ihl);
26606+#endif
26607+
26608+ /* Update skb length/tail by "unputting" the unused data area */
26609+ safe_skb_put(nskb, -zs.avail_out);
26610+
26611+ ipsec_kfree_skb(skb);
26612+
26613+ if (iph->protocol == IPPROTO_COMP)
26614+ {
26615+#ifdef CONFIG_KLIPS_DEBUG
26616+ if(sysctl_ipsec_debug_ipcomp)
26617+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26618+ "klips_debug:skb_decompress: "
26619+ "Eh? inner packet is also compressed, dropping.\n");
26620+#endif /* CONFIG_KLIPS_DEBUG */
26621+
26622+ ipsec_kfree_skb(nskb);
26623+ return NULL;
26624+ }
26625+
26626+#ifdef CONFIG_KLIPS_DEBUG
26627+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26628+ __u8 *c;
26629+
26630+ c = (__u8*)iph + iphlen;
26631+ ipsec_dmp_block("decompress result", c, pyldsz);
26632+ }
26633+#endif /* CONFIG_KLIPS_DEBUG */
26634+
26635+ return nskb;
26636+}
26637+
26638+
26639+/* this is derived from skb_copy() in linux 2.2.14 */
26640+/* May be incompatible with other kernel versions!! */
26641+static
26642+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
26643+{
26644+ struct sk_buff *n;
26645+ struct iphdr *iph;
26646+ unsigned long offset;
26647+ unsigned int iphlen;
26648+
26649+ if(!skb) {
26650+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26651+ "klips_debug:skb_copy_ipcomp: "
26652+ "passed in NULL skb, returning NULL.\n");
26653+ return NULL;
26654+ }
26655+
26656+ /*
26657+ * Allocate the copy buffer
26658+ */
26659+
26660+#ifdef NET_21
26661+ iph = ip_hdr(skb);
26662+#else /* NET_21 */
26663+ iph = skb->ip_hdr;
26664+#endif /* NET_21 */
26665+ if (!iph) return NULL;
26666+ iphlen = iph->ihl << 2;
26667+
26668+ n=alloc_skb(skb_end_pointer(skb) - skb->head + data_growth, gfp_mask);
26669+ if(n==NULL)
26670+ return NULL;
26671+
26672+ /*
26673+ * Shift between the two data areas in bytes
26674+ */
26675+
26676+ offset=n->head-skb->head;
26677+
26678+ /* Set the data pointer */
26679+ skb_reserve(n,skb->data-skb->head);
26680+ /* Set the tail pointer and length */
26681+ safe_skb_put(n,skb->len+data_growth);
26682+ /* Copy the bytes up to and including the ip header */
26683+ memcpy(n->head,
26684+ skb->head,
26685+ ((char *)iph - (char *)skb->head) + iphlen);
26686+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
26687+ n->list=NULL;
26688+#endif
26689+ n->next=NULL;
26690+ n->prev=NULL;
26691+ n->sk=NULL;
26692+ n->dev=skb->dev;
26693+ if (skb_transport_header(skb))
26694+ skb_set_transport_header(n, offset);
26695+ n->protocol=skb->protocol;
26696+#ifdef NET_21
26697+ n->csum = 0;
26698+ n->priority=skb->priority;
26699+ n->dst=dst_clone(skb->dst);
26700+ skb_set_network_header(n, offset);
26701+#ifndef NETDEV_23
26702+ n->is_clone=0;
26703+#endif /* NETDEV_23 */
26704+ atomic_set(&n->users, 1);
26705+ n->destructor = NULL;
26706+#ifdef HAVE_SOCK_SECURITY
26707+ n->security=skb->security;
26708+#endif
26709+ memcpy(n->cb, skb->cb, sizeof(skb->cb));
26710+#ifdef CONFIG_IP_FIREWALL
26711+ n->fwmark = skb->fwmark;
26712+#endif
26713+#else /* NET_21 */
26714+ n->link3=NULL;
26715+ n->when=skb->when;
26716+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
26717+ n->saddr=skb->saddr;
26718+ n->daddr=skb->daddr;
26719+ n->raddr=skb->raddr;
26720+ n->seq=skb->seq;
26721+ n->end_seq=skb->end_seq;
26722+ n->ack_seq=skb->ack_seq;
26723+ n->acked=skb->acked;
26724+ n->free=1;
26725+ n->arp=skb->arp;
26726+ n->tries=0;
26727+ n->lock=0;
26728+ n->users=0;
26729+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
26730+#endif /* NET_21 */
26731+ if (skb_mac_header(skb))
26732+ skb_set_mac_header(n, offset);
26733+#ifndef NETDEV_23
26734+ n->used=skb->used;
26735+#endif /* !NETDEV_23 */
26736+ n->pkt_type=skb->pkt_type;
26737+#ifndef NETDEV_23
26738+ n->pkt_bridged=skb->pkt_bridged;
26739+#endif /* NETDEV_23 */
26740+ n->ip_summed=0;
26741+#ifdef HAVE_TSTAMP
26742+ n->tstamp = skb->tstamp;
26743+#else
26744+ n->stamp=skb->stamp;
26745+#endif
26746+#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
26747+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
26748+ n->shapelatency=skb->shapelatency; /* Latency on frame */
26749+ n->shapeclock=skb->shapeclock; /* Time it should go out */
26750+ n->shapelen=skb->shapelen; /* Frame length in clocks */
26751+ n->shapestamp=skb->shapestamp; /* Stamp for shaper */
26752+ n->shapepend=skb->shapepend; /* Pending */
26753+#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
26754+#endif /* NETDEV_23 */
26755+
26756+ return n;
26757+}
26758--- /dev/null Tue Mar 11 13:02:56 2003
26759+++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004
26760@@ -0,0 +1,411 @@
26761+/*
26762+ * processing code for AH
26763+ * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com>
26764+ *
26765+ * This program is free software; you can redistribute it and/or modify it
26766+ * under the terms of the GNU General Public License as published by the
26767+ * Free Software Foundation; either version 2 of the License, or (at your
26768+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
26769+ *
26770+ * This program is distributed in the hope that it will be useful, but
26771+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26772+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26773+ * for more details.
26774+ */
26775+
26776+char ipsec_ah_c_version[] = "RCSID $Id: ipsec_ah.c,v 1.12.2.3 2007-09-05 02:56:09 paul Exp $";
26777+#ifndef AUTOCONF_INCLUDED
26778+#include <linux/config.h>
26779+#endif
26780+#include <linux/version.h>
26781+
26782+#define __NO_VERSION__
26783+#include <linux/module.h>
26784+#include <linux/kernel.h> /* printk() */
26785+
26786+#include "openswan/ipsec_param.h"
26787+
26788+#ifdef MALLOC_SLAB
26789+# include <linux/slab.h> /* kmalloc() */
26790+#else /* MALLOC_SLAB */
26791+# include <linux/malloc.h> /* kmalloc() */
26792+#endif /* MALLOC_SLAB */
26793+#include <linux/errno.h> /* error codes */
26794+#include <linux/types.h> /* size_t */
26795+#include <linux/interrupt.h> /* mark_bh */
26796+
26797+#include <linux/netdevice.h> /* struct device, and other headers */
26798+#include <linux/etherdevice.h> /* eth_type_trans */
26799+#include <linux/ip.h> /* struct iphdr */
26800+#include <linux/skbuff.h>
26801+#include <openswan.h>
26802+#ifdef SPINLOCK
26803+# ifdef SPINLOCK_23
26804+# include <linux/spinlock.h> /* *lock* */
26805+# else /* SPINLOCK_23 */
26806+# include <asm/spinlock.h> /* *lock* */
26807+# endif /* SPINLOCK_23 */
26808+#endif /* SPINLOCK */
26809+
26810+#include <net/ip.h>
26811+#include <net/protocol.h>
26812+
26813+#include "openswan/radij.h"
26814+#include "openswan/ipsec_encap.h"
26815+#include "openswan/ipsec_sa.h"
26816+
26817+#include "openswan/ipsec_radij.h"
26818+#include "openswan/ipsec_xform.h"
26819+#include "openswan/ipsec_tunnel.h"
26820+#include "openswan/ipsec_rcv.h"
26821+#include "openswan/ipsec_xmit.h"
26822+
26823+#include "openswan/ipsec_auth.h"
26824+#include "openswan/ipsec_ah.h"
26825+#include "openswan/ipsec_proto.h"
26826+
26827+__u32 zeroes[AH_AMAX];
26828+
26829+enum ipsec_rcv_value
26830+ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
26831+ struct sk_buff *skb)
26832+{
26833+ int ahminlen;
26834+
26835+ ahminlen = irs->hard_header_len + sizeof(struct iphdr);
26836+
26837+ /* take care not to deref this pointer until we check the minlen though */
26838+ irs->protostuff.ahstuff.ahp = (struct ahhdr *)skb_transport_header(skb);
26839+
26840+ if((skb->len < ahminlen+sizeof(struct ahhdr)) ||
26841+ (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
26842+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26843+ "klips_debug:ipsec_rcv: "
26844+ "runt ah packet of skb->len=%d received from %s, dropped.\n",
26845+ skb->len,
26846+ irs->ipsaddr_txt);
26847+ if(irs->stats) {
26848+ irs->stats->rx_errors++;
26849+ }
26850+ return IPSEC_RCV_BADLEN;
26851+ }
26852+
26853+ irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
26854+
26855+ /* XXX we only support the one 12-byte authenticator for now */
26856+ if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
26857+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26858+ "klips_debug:ipsec_rcv: "
26859+ "bad authenticator length %ld, expected %lu from %s.\n",
26860+ (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
26861+ (unsigned long) sizeof(struct ahhdr),
26862+ irs->ipsaddr_txt);
26863+ if(irs->stats) {
26864+ irs->stats->rx_errors++;
26865+ }
26866+ return IPSEC_RCV_BADLEN;
26867+ }
26868+
26869+ return IPSEC_RCV_OK;
26870+}
26871+
26872+
26873+enum ipsec_rcv_value
26874+ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
26875+ struct sk_buff *skb,
26876+ __u32 *replay,
26877+ unsigned char **authenticator)
26878+{
26879+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26880+
26881+ *replay = ntohl(ahp->ah_rpl);
26882+ *authenticator = ahp->ah_data;
26883+
26884+ return IPSEC_RCV_OK;
26885+}
26886+
26887+enum ipsec_rcv_value
26888+ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
26889+ struct sk_buff *skb)
26890+{
26891+ struct auth_alg *aa;
26892+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26893+ union {
26894+ MD5_CTX md5;
26895+ SHA1_CTX sha1;
26896+ } tctx;
26897+ struct iphdr ipo;
26898+ int ahhlen;
26899+
26900+ aa = irs->authfuncs;
26901+
26902+ /* copy the initialized keying material */
26903+ memcpy(&tctx, irs->ictx, irs->ictx_len);
26904+
26905+ ipo = *irs->ipp;
26906+ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
26907+ ipo.frag_off = 0;
26908+ ipo.ttl = 0;
26909+ ipo.check = 0;
26910+
26911+
26912+ /* do the sanitized header */
26913+ (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
26914+
26915+ /* XXX we didn't do the options here! */
26916+
26917+ /* now do the AH header itself */
26918+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26919+ (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN);
26920+
26921+ /* now, do some zeroes */
26922+ (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN);
26923+
26924+ /* finally, do the packet contents themselves */
26925+ (*aa->update)((void*)&tctx,
26926+ (caddr_t)skb_transport_header(skb) + ahhlen,
26927+ skb->len - ahhlen);
26928+
26929+ (*aa->final)(irs->hash, (void *)&tctx);
26930+
26931+ memcpy(&tctx, irs->octx, irs->octx_len);
26932+
26933+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
26934+ (*aa->final)(irs->hash, (void *)&tctx);
26935+
26936+ return IPSEC_RCV_OK;
26937+}
26938+
26939+enum ipsec_rcv_value
26940+ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
26941+{
26942+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26943+ struct sk_buff *skb;
26944+ int ahhlen;
26945+
26946+ skb=irs->skb;
26947+
26948+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26949+
26950+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
26951+ irs->next_header = ahp->ah_nh;
26952+
26953+ /*
26954+ * move the IP header forward by the size of the AH header, which
26955+ * will remove the the AH header from the packet.
26956+ */
26957+ memmove((void *)(skb_network_header(skb) + ahhlen),
26958+ (void *)(skb_network_header(skb)), irs->iphlen);
26959+
26960+ ipsec_rcv_dmp("ah postmove", skb->data, skb->len);
26961+
26962+ /* skb_pull below, will move up by ahhlen */
26963+
26964+ /* XXX not clear how this can happen, as the message indicates */
26965+ if(skb->len < ahhlen) {
26966+ printk(KERN_WARNING
26967+ "klips_error:ipsec_rcv: "
26968+ "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n",
26969+ ahhlen,
26970+ (int)(skb->len));
26971+ return IPSEC_RCV_DECAPFAIL;
26972+ }
26973+ skb_pull(skb, ahhlen);
26974+
26975+ skb_set_network_header(skb, ahhlen);
26976+ irs->ipp = ip_hdr(skb);
26977+
26978+ ipsec_rcv_dmp("ah postpull", (void *)ip_hdr(skb), skb->len);
26979+
26980+ return IPSEC_RCV_OK;
26981+}
26982+
26983+enum ipsec_xmit_value
26984+ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs)
26985+{
26986+ struct iphdr ipo;
26987+ struct ahhdr *ahp;
26988+ __u8 hash[AH_AMAX];
26989+ union {
26990+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26991+ MD5_CTX md5;
26992+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26993+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26994+ SHA1_CTX sha1;
26995+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26996+ } tctx;
26997+ unsigned char *dat = (unsigned char *)ixs->iph;
26998+
26999+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
27000+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
27001+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
27002+ ahp->ah_rv = 0;
27003+ ahp->ah_nh = ixs->iph->protocol;
27004+ ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32);
27005+ ixs->iph->protocol = IPPROTO_AH;
27006+ ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp));
27007+
27008+ ipo = *ixs->iph;
27009+ ipo.tos = 0;
27010+ ipo.frag_off = 0;
27011+ ipo.ttl = 0;
27012+ ipo.check = 0;
27013+ ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo));
27014+
27015+ switch(ixs->ipsp->ips_authalg) {
27016+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
27017+ case AH_MD5:
27018+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
27019+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
27020+ osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
27021+ ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
27022+ osMD5Update(&tctx.md5, (unsigned char *)ahp,
27023+ sizeof(struct ahhdr) - sizeof(ahp->ah_data));
27024+ ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
27025+ osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
27026+ ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
27027+ osMD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr),
27028+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
27029+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
27030+ osMD5Final(hash, &tctx.md5);
27031+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
27032+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
27033+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
27034+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
27035+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
27036+ osMD5Final(hash, &tctx.md5);
27037+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
27038+
27039+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
27040+
27041+ /* paranoid */
27042+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
27043+ memset((caddr_t)hash, 0, sizeof(*hash));
27044+ break;
27045+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
27046+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
27047+ case AH_SHA:
27048+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
27049+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
27050+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data));
27051+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
27052+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr),
27053+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
27054+ SHA1Final(hash, &tctx.sha1);
27055+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
27056+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
27057+ SHA1Final(hash, &tctx.sha1);
27058+
27059+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
27060+
27061+ /* paranoid */
27062+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
27063+ memset((caddr_t)hash, 0, sizeof(*hash));
27064+ break;
27065+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
27066+ default:
27067+ ixs->stats->tx_errors++;
27068+ return IPSEC_XMIT_AH_BADALG;
27069+ }
27070+#ifdef NET_21
27071+ skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, ahp));
27072+#endif /* NET_21 */
27073+
27074+ return IPSEC_XMIT_OK;
27075+}
27076+
27077+struct xform_functions ah_xform_funcs[]={
27078+ { rcv_checks: ipsec_rcv_ah_checks,
27079+ rcv_setup_auth: ipsec_rcv_ah_setup_auth,
27080+ rcv_calc_auth: ipsec_rcv_ah_authcalc,
27081+ rcv_decrypt: ipsec_rcv_ah_decap,
27082+
27083+ xmit_setup: ipsec_xmit_ah_setup,
27084+ xmit_headroom: sizeof(struct ahhdr),
27085+ xmit_needtailroom: 0,
27086+ },
27087+};
27088+
27089+
27090+#ifdef NET_26
27091+struct inet_protocol ah_protocol = {
27092+ .handler = ipsec_rcv,
27093+ .no_policy = 1,
27094+};
27095+#else
27096+struct inet_protocol ah_protocol =
27097+{
27098+ ipsec_rcv, /* AH handler */
27099+ NULL, /* TUNNEL error control */
27100+#ifdef NETDEV_25
27101+ 1, /* no policy */
27102+#else
27103+ 0, /* next */
27104+ IPPROTO_AH, /* protocol ID */
27105+ 0, /* copy */
27106+ NULL, /* data */
27107+ "AH" /* name */
27108+#endif
27109+};
27110+#endif /* NET_26 */
27111+
27112+/*
27113+ * $Log: ipsec_ah.c,v $
27114+ * Revision 1.12.2.3 2007-09-05 02:56:09 paul
27115+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
27116+ * Fixes based on David McCullough patch.
27117+ *
27118+ * Revision 1.12.2.2 2006/10/06 21:39:26 paul
27119+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
27120+ * set. This is defined through autoconf.h which is included through the
27121+ * linux kernel build macros.
27122+ *
27123+ * Revision 1.12.2.1 2006/02/15 05:35:14 paul
27124+ * Patch by David McCullough <davidm@snapgear.com>
27125+ * If you setup a tunnel without ESP it doesn't work. It used to work in
27126+ * an older openswan version but stopped when klips was modified to deal
27127+ * with the pulled IP header on the received SKB's.
27128+ *
27129+ * The code in ipsec_ah.c still thinks the IP header is there and runs the
27130+ * hash on the incorrect data.
27131+ *
27132+ * Revision 1.12 2005/04/29 05:10:22 mcr
27133+ * removed from extraenous includes to make unit testing easier.
27134+ *
27135+ * Revision 1.11 2005/04/15 19:50:55 mcr
27136+ * adjustments to use proper skb fields for data.
27137+ *
27138+ * Revision 1.10 2004/09/14 00:22:57 mcr
27139+ * adjustment of MD5* functions.
27140+ *
27141+ * Revision 1.9 2004/09/13 02:22:47 mcr
27142+ * #define inet_protocol if necessary.
27143+ *
27144+ * Revision 1.8 2004/09/06 18:35:48 mcr
27145+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
27146+ * so adjust for that.
27147+ *
27148+ * Revision 1.7 2004/08/22 05:00:48 mcr
27149+ * if we choose to compile the file, we want the contents,
27150+ * so don't pull any punches.
27151+ *
27152+ * Revision 1.6 2004/08/17 03:27:23 mcr
27153+ * klips 2.6 edits.
27154+ *
27155+ * Revision 1.5 2004/08/14 03:28:24 mcr
27156+ * fixed log comment to remove warning about embedded comment.
27157+ *
27158+ * Revision 1.4 2004/08/04 15:57:07 mcr
27159+ * moved des .h files to include/des/ *
27160+ * included 2.6 protocol specific things
27161+ * started at NAT-T support, but it will require a kernel patch.
27162+ *
27163+ * Revision 1.3 2004/07/10 19:11:18 mcr
27164+ * CONFIG_IPSEC -> CONFIG_KLIPS.
27165+ *
27166+ * Revision 1.2 2004/04/06 02:49:25 mcr
27167+ * pullup of algo code from alg-branch.
27168+ *
27169+ *
27170+ *
27171+ */
27172--- /dev/null Tue Mar 11 13:02:56 2003
27173+++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004
27174@@ -0,0 +1,1057 @@
27175+/*
27176+ * Modular extensions service and registration functions
27177+ *
27178+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
27179+ *
27180+ * Version: 0.8.1
27181+ *
27182+ * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
27183+ *
27184+ * This program is free software; you can redistribute it and/or modify it
27185+ * under the terms of the GNU General Public License as published by the
27186+ * Free Software Foundation; either version 2 of the License, or (at your
27187+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
27188+ *
27189+ * This program is distributed in the hope that it will be useful, but
27190+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27191+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27192+ * for more details.
27193+ *
27194+ */
27195+#define __NO_VERSION__
27196+
27197+#if defined (MODULE)
27198+#include <linux/module.h>
27199+#endif
27200+
27201+#include <linux/kernel.h> /* printk() */
27202+
27203+#include <linux/netdevice.h> /* struct device, and other headers */
27204+#include <linux/etherdevice.h> /* eth_type_trans */
27205+#include <linux/ip.h> /* struct iphdr */
27206+#include <linux/skbuff.h>
27207+#include <linux/socket.h>
27208+#include <linux/in.h>
27209+#include <linux/types.h>
27210+#include <linux/string.h> /* memcmp() */
27211+#include <linux/random.h> /* get_random_bytes() */
27212+#include <linux/errno.h> /* error codes */
27213+#ifdef SPINLOCK
27214+# ifdef SPINLOCK_23
27215+# include <linux/spinlock.h> /* *lock* */
27216+# else /* SPINLOCK_23 */
27217+# include <asm/spinlock.h> /* *lock* */
27218+# endif /* SPINLOCK_23 */
27219+#endif /* SPINLOCK */
27220+
27221+#include "openswan/ipsec_param.h"
27222+#include <openswan.h>
27223+#include "openswan/ipsec_sa.h"
27224+#include "openswan/radij.h"
27225+#include "openswan/ipsec_encap.h"
27226+#include "openswan/ipsec_radij.h"
27227+#include "openswan/ipsec_xform.h"
27228+#include "openswan/ipsec_tunnel.h"
27229+#include "openswan/ipsec_rcv.h"
27230+#if defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH)
27231+# include "openswan/ipsec_ah.h"
27232+#endif /* defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH) */
27233+#ifdef CONFIG_KLIPS_ESP
27234+# include "openswan/ipsec_esp.h"
27235+#endif /* !CONFIG_KLIPS_ESP */
27236+#ifdef CONFIG_KLIPS_IPCOMP
27237+# include "openswan/ipcomp.h"
27238+#endif /* CONFIG_KLIPS_COMP */
27239+
27240+#include <pfkeyv2.h>
27241+#include <pfkey.h>
27242+
27243+#include "openswan/ipsec_alg.h"
27244+#include "openswan/ipsec_proto.h"
27245+
27246+#if SADB_EALG_MAX < 255
27247+#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
27248+#endif
27249+
27250+static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
27251+#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
27252+static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
27253+
27254+/* Old gcc's will fail here */
27255+#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) \
27256+ ; goto out; } while(0)
27257+
27258+#ifdef NET_26
27259+/*
27260+ * Must be already protected by lock
27261+ */
27262+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt)
27263+{
27264+#ifdef MODULE
27265+ if (ixt->ixt_module)
27266+ try_module_get(ixt->ixt_module);
27267+#endif
27268+ atomic_inc(&ixt->ixt_refcnt);
27269+}
27270+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
27271+ atomic_dec(&ixt->ixt_refcnt);
27272+#ifdef MODULE
27273+ if (ixt->ixt_module)
27274+ module_put(ixt->ixt_module);
27275+#endif
27276+}
27277+
27278+#else
27279+
27280+/*
27281+ * Must be already protected by lock
27282+ */
27283+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
27284+#ifdef MODULE
27285+ if (ixt->ixt_module) {
27286+ __MOD_INC_USE_COUNT(ixt->ixt_module);
27287+ }
27288+#endif
27289+ atomic_inc(&ixt->ixt_refcnt);
27290+}
27291+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
27292+ atomic_dec(&ixt->ixt_refcnt);
27293+#ifdef MODULE
27294+ if (ixt->ixt_module)
27295+ __MOD_DEC_USE_COUNT(ixt->ixt_module);
27296+#endif
27297+}
27298+#endif
27299+
27300+/*
27301+ * simple hash function, optimized for 0-hash (1 list) special
27302+ * case
27303+ */
27304+#if IPSEC_ALG_HASHSZ > 1
27305+static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
27306+ return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
27307+}
27308+#else
27309+#define ipsec_alg_hashfn(x,y) (0)
27310+#endif
27311+
27312+/*****************************************************************
27313+ *
27314+ * INTERNAL table handling: insert, delete, find
27315+ *
27316+ *****************************************************************/
27317+
27318+/*
27319+ * hash table initialization, called from ipsec_alg_init()
27320+ */
27321+static void ipsec_alg_hash_init(void) {
27322+ struct list_head *head = ipsec_alg_hash_table;
27323+ int i = IPSEC_ALG_HASHSZ;
27324+ do {
27325+ INIT_LIST_HEAD(head);
27326+ head++;
27327+ i--;
27328+ } while (i);
27329+}
27330+/*
27331+ * hash list lookup by {alg_type, alg_id} and table head,
27332+ * must be already protected by lock
27333+ */
27334+static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
27335+ struct list_head *p;
27336+ struct ipsec_alg *ixt=NULL;
27337+ for (p=head->next; p!=head; p=p->next) {
27338+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
27339+ if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
27340+ goto out;
27341+ }
27342+ }
27343+ ixt=NULL;
27344+out:
27345+ return ixt;
27346+}
27347+/*
27348+ * inserts (in front) a new entry in hash table,
27349+ * called from ipsec_alg_register() when new algorithm is registered.
27350+ */
27351+static int ipsec_alg_insert(struct ipsec_alg *ixt) {
27352+ int ret=-EINVAL;
27353+ unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
27354+ struct list_head *head= ipsec_alg_hash_table + hashval;
27355+ struct ipsec_alg *ixt_cur;
27356+
27357+ /* new element must be virgin ... */
27358+ if (ixt->ixt_list.next != &ixt->ixt_list ||
27359+ ixt->ixt_list.prev != &ixt->ixt_list) {
27360+ printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
27361+ "list head not initialized\n",
27362+ ixt->ixt_name);
27363+ return ret;
27364+ }
27365+ write_lock_bh(&ipsec_alg_lock);
27366+
27367+ ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
27368+
27369+ /* if previous (current) ipsec_alg found check excl flag of _anyone_ */
27370+ if (ixt_cur
27371+ && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) {
27372+ barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
27373+ "Not loaded (ret=%d).\n",
27374+ ixt->ixt_alg_type,
27375+ ixt->ixt_alg_id, ret=-EEXIST);
27376+ }
27377+ list_add(&ixt->ixt_list, head);
27378+ ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
27379+ ret=0;
27380+out:
27381+ write_unlock_bh(&ipsec_alg_lock);
27382+ return ret;
27383+}
27384+
27385+/*
27386+ * deletes an existing entry in hash table,
27387+ * called from ipsec_alg_unregister() when algorithm is unregistered.
27388+ */
27389+static int ipsec_alg_delete(struct ipsec_alg *ixt) {
27390+ write_lock_bh(&ipsec_alg_lock);
27391+ list_del(&ixt->ixt_list);
27392+ write_unlock_bh(&ipsec_alg_lock);
27393+ return 0;
27394+}
27395+
27396+/*
27397+ * here @user context (read-only when @kernel bh context)
27398+ * -> no bh disabling
27399+ *
27400+ * called from ipsec_sa_init() -> ipsec_alg_sa_init()
27401+ */
27402+static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id)
27403+{
27404+ unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
27405+ struct list_head *head= ipsec_alg_hash_table + hashval;
27406+ struct ipsec_alg *ixt;
27407+
27408+ read_lock(&ipsec_alg_lock);
27409+ ixt=__ipsec_alg_find(alg_type, alg_id, head);
27410+ if (ixt) __ipsec_alg_usage_inc(ixt);
27411+ read_unlock(&ipsec_alg_lock);
27412+
27413+ return ixt;
27414+}
27415+
27416+static void ipsec_alg_put(struct ipsec_alg *ixt) {
27417+ __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
27418+}
27419+
27420+/*****************************************************************
27421+ *
27422+ * INTERFACE for ENC services: key creation, encrypt function
27423+ *
27424+ *****************************************************************/
27425+
27426+/*
27427+ * main encrypt service entry point
27428+ * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
27429+ * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
27430+ */
27431+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat,
27432+ int ilen, const __u8 * iv, int encrypt)
27433+{
27434+ int ret;
27435+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
27436+#ifdef CONFIG_KLIPS_DEBUG
27437+ int debug_flag = (encrypt==IPSEC_ALG_ENCRYPT ?
27438+ debug_tunnel : debug_rcv);
27439+#endif
27440+
27441+ KLIPS_PRINT(debug_flag,
27442+ "klips_debug:ipsec_alg_esp_encrypt: "
27443+ "entering with encalg=%d, ixt_e=%p\n",
27444+ sa_p->ips_encalg, ixt_e);
27445+ if (ixt_e == NULL) {
27446+#ifdef CONFIG_KLIPS_DEBUG
27447+ KLIPS_ERROR(debug_flag,
27448+ "klips_debug:ipsec_alg_esp_encrypt: "
27449+ "NULL ipsec_alg_enc object\n");
27450+#endif
27451+ return -1;
27452+ }
27453+ KLIPS_PRINT(debug_flag,
27454+ "klips_debug:ipsec_alg_esp_encrypt: "
27455+ "calling cbc_encrypt encalg=%d "
27456+ "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
27457+ sa_p->ips_encalg,
27458+ sa_p->ips_key_e, idat, ilen, iv, encrypt);
27459+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat,
27460+ ilen, iv, encrypt);
27461+ KLIPS_PRINT(debug_flag,
27462+ "klips_debug:ipsec_alg_esp_encrypt: "
27463+ "returned ret=%d\n",
27464+ ret);
27465+ return ret;
27466+}
27467+
27468+/*
27469+ * encryption key context creation function
27470+ * called from pfkey_v2_parser.c:pfkey_ips_init()
27471+ */
27472+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
27473+ int ret=-EINVAL;
27474+ int keyminbits, keymaxbits;
27475+ caddr_t ekp;
27476+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
27477+
27478+ KLIPS_PRINT(debug_pfkey,
27479+ "klips_debug:ipsec_alg_enc_key_create: "
27480+ "entering with encalg=%d ixt_e=%p\n",
27481+ sa_p->ips_encalg, ixt_e);
27482+ if (!ixt_e) {
27483+ KLIPS_PRINT(debug_pfkey,
27484+ "klips_debug:ipsec_alg_enc_key_create: "
27485+ "NULL ipsec_alg_enc object\n");
27486+ return -EPROTO;
27487+ }
27488+
27489+ /*
27490+ * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo
27491+ */
27492+ switch(ixt_e->ixt_common.ixt_support.ias_id) {
27493+ case ESP_3DES:
27494+ keyminbits=keymaxbits=192;break;
27495+ case ESP_DES:
27496+ keyminbits=keymaxbits=64;break;
27497+ default:
27498+ keyminbits=ixt_e->ixt_common.ixt_support.ias_keyminbits;
27499+ keymaxbits=ixt_e->ixt_common.ixt_support.ias_keymaxbits;
27500+ }
27501+ if(sa_p->ips_key_bits_e<keyminbits ||
27502+ sa_p->ips_key_bits_e>keymaxbits) {
27503+ KLIPS_PRINT(debug_pfkey,
27504+ "klips_debug:ipsec_alg_enc_key_create: "
27505+ "incorrect encryption key size for id=%d: %d bits -- "
27506+ "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
27507+ ixt_e->ixt_common.ixt_support.ias_id,
27508+ sa_p->ips_key_bits_e, keyminbits, keymaxbits);
27509+ ret=-EINVAL;
27510+ goto ixt_out;
27511+ }
27512+ /* save encryption key pointer */
27513+ ekp = sa_p->ips_key_e;
27514+
27515+
27516+ if (ixt_e->ixt_e_new_key) {
27517+ sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
27518+ ekp, sa_p->ips_key_bits_e/8);
27519+ ret = (sa_p->ips_key_e)? 0 : -EINVAL;
27520+ } else {
27521+ if((sa_p->ips_key_e = (caddr_t)
27522+ kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
27523+ GFP_ATOMIC)) == NULL) {
27524+ ret=-ENOMEM;
27525+ goto ixt_out;
27526+ }
27527+ /* zero-out key_e */
27528+ memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
27529+
27530+ /* I cast here to allow more decoupling in alg module */
27531+ KLIPS_PRINT(debug_pfkey,
27532+ "klips_debug:ipsec_alg_enc_key_create: about to call:"
27533+ "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
27534+ (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27535+ ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27536+ }
27537+ /* paranoid */
27538+ memset(ekp, 0, sa_p->ips_key_bits_e/8);
27539+ kfree(ekp);
27540+ixt_out:
27541+ return ret;
27542+}
27543+
27544+/***************************************************************
27545+ *
27546+ * INTERFACE for AUTH services: key creation, hash functions
27547+ *
27548+ ***************************************************************/
27549+
27550+/*
27551+ * auth key context creation function
27552+ * called from pfkey_v2_parser.c:pfkey_ips_init()
27553+ */
27554+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
27555+ int ret=-EINVAL;
27556+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27557+ int keyminbits, keymaxbits;
27558+ unsigned char *akp;
27559+ unsigned int aks;
27560+ KLIPS_PRINT(debug_pfkey,
27561+ "klips_debug:ipsec_alg_auth_key_create: "
27562+ "entering with authalg=%d ixt_a=%p\n",
27563+ sa_p->ips_authalg, ixt_a);
27564+ if (!ixt_a) {
27565+ KLIPS_PRINT(debug_pfkey,
27566+ "klips_debug:ipsec_alg_auth_key_create: "
27567+ "NULL ipsec_alg_auth object\n");
27568+ return -EPROTO;
27569+ }
27570+ keyminbits=ixt_a->ixt_common.ixt_support.ias_keyminbits;
27571+ keymaxbits=ixt_a->ixt_common.ixt_support.ias_keymaxbits;
27572+ if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
27573+ KLIPS_PRINT(debug_pfkey,
27574+ "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
27575+ "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
27576+ sa_p->ips_key_bits_a, keyminbits, keymaxbits);
27577+ ret=-EINVAL;
27578+ goto ixt_out;
27579+ }
27580+ /* save auth key pointer */
27581+ sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
27582+ akp = sa_p->ips_key_a;
27583+ aks = sa_p->ips_key_a_size;
27584+
27585+ /* will hold: 2 ctx and a blocksize buffer: kb */
27586+ sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
27587+ if((sa_p->ips_key_a =
27588+ (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
27589+ ret=-ENOMEM;
27590+ goto ixt_out;
27591+ }
27592+ ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
27593+ ret=0;
27594+ memset(akp, 0, aks);
27595+ kfree(akp);
27596+
27597+ixt_out:
27598+ return ret;
27599+}
27600+
27601+
27602+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp,
27603+ int len, __u8 *hash, int hashlen)
27604+{
27605+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27606+ if (!ixt_a) {
27607+ KLIPS_PRINT(debug_pfkey,
27608+ "klips_debug:ipsec_sa_esp_hash: "
27609+ "NULL ipsec_alg_auth object\n");
27610+ return -EPROTO;
27611+ }
27612+ KLIPS_PRINT(debug_tunnel|debug_rcv,
27613+ "klips_debug:ipsec_sa_esp_hash: "
27614+ "hashing %p (%d bytes) to %p (%d bytes)\n",
27615+ espp, len,
27616+ hash, hashlen);
27617+ ixt_a->ixt_a_hmac_hash(ixt_a,
27618+ sa_p->ips_key_a,
27619+ espp, len,
27620+ hash, hashlen);
27621+ return 0;
27622+}
27623+
27624+/***************************************************************
27625+ *
27626+ * INTERFACE for module loading,testing, and unloading
27627+ *
27628+ ***************************************************************/
27629+
27630+/* validation for registering (enc) module */
27631+static int check_enc(struct ipsec_alg_enc *ixt)
27632+{
27633+ int ret=-EINVAL;
27634+ if (ixt->ixt_common.ixt_blocksize==0) /* || ixt->ixt_common.ixt_blocksize%2) need for ESP_NULL */
27635+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_common.ixt_blocksize);
27636+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0
27637+ && ixt->ixt_common.ixt_support.ias_keymaxbits==0
27638+ && ixt->ixt_e_keylen==0)
27639+ goto zero_key_ok;
27640+
27641+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27642+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27643+
27644+ if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27645+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27646+
27647+ if (ixt->ixt_e_keylen==0)
27648+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
27649+
27650+zero_key_ok:
27651+ if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
27652+ barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
27653+ if (ixt->ixt_e_cbc_encrypt==NULL)
27654+ barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
27655+ ret=0;
27656+out:
27657+ return ret;
27658+}
27659+
27660+/* validation for registering (auth) module */
27661+static int check_auth(struct ipsec_alg_auth *ixt)
27662+{
27663+ int ret=-EINVAL;
27664+ if (ixt->ixt_common.ixt_support.ias_id==0 || ixt->ixt_common.ixt_support.ias_id > SADB_AALG_MAX)
27665+ barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n",
27666+ ixt->ixt_common.ixt_support.ias_id, SADB_AALG_MAX);
27667+
27668+ if (ixt->ixt_common.ixt_blocksize==0
27669+ || ixt->ixt_common.ixt_blocksize%2)
27670+ barf_out(KERN_ERR "invalid blocksize=%d\n",
27671+ ixt->ixt_common.ixt_blocksize);
27672+
27673+ if (ixt->ixt_common.ixt_blocksize>AH_BLKLEN_MAX)
27674+ barf_out(KERN_ERR "sorry blocksize=%d > %d. "
27675+ "Please increase AH_BLKLEN_MAX and recompile\n",
27676+ ixt->ixt_common.ixt_blocksize,
27677+ AH_BLKLEN_MAX);
27678+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0 && ixt->ixt_common.ixt_support.ias_keymaxbits==0 && ixt->ixt_a_keylen==0)
27679+ goto zero_key_ok;
27680+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27681+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27682+ if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27683+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27684+ if (ixt->ixt_common.ixt_support.ias_keymaxbits!=ixt->ixt_common.ixt_support.ias_keyminbits)
27685+ barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
27686+ if (ixt->ixt_a_keylen==0)
27687+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
27688+zero_key_ok:
27689+ if (ixt->ixt_a_ctx_size==0)
27690+ barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
27691+ if (ixt->ixt_a_hmac_set_key==NULL)
27692+ barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
27693+ if (ixt->ixt_a_hmac_hash==NULL)
27694+ barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
27695+ ret=0;
27696+out:
27697+ return ret;
27698+}
27699+
27700+/*
27701+ * Generic (enc, auth) registration entry point
27702+ */
27703+int register_ipsec_alg(struct ipsec_alg *ixt)
27704+{
27705+ int ret=-EINVAL;
27706+ /* Validation */
27707+ if (ixt==NULL)
27708+ barf_out("NULL ipsec_alg object passed\n");
27709+ if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
27710+ barf_out("incorrect version: %d.%d.%d-%d, "
27711+ "must be %d.%d.%d[-%d]\n",
27712+ IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
27713+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
27714+
27715+ switch(ixt->ixt_alg_type) {
27716+ case IPSEC_ALG_TYPE_AUTH:
27717+ if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
27718+ goto out;
27719+ break;
27720+ case IPSEC_ALG_TYPE_ENCRYPT:
27721+ if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
27722+ goto out;
27723+ /*
27724+ * Adapted two lines below:
27725+ * ivlen == 0 is possible (NULL enc has blocksize==1)
27726+ *
27727+ * fixed NULL support by David De Reu <DeReu@tComLabs.com>
27728+ */
27729+ if (ixt->ixt_support.ias_ivlen == 0
27730+ && ixt->ixt_blocksize > 1) {
27731+ ixt->ixt_support.ias_ivlen = ixt->ixt_blocksize*8;
27732+ }
27733+ break;
27734+ default:
27735+ barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);
27736+ }
27737+ INIT_LIST_HEAD(&ixt->ixt_list);
27738+ ret = ipsec_alg_insert(ixt);
27739+ if (ret<0)
27740+ barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
27741+ "Not loaded (ret=%d).\n",
27742+ ixt->ixt_support.ias_id, ret);
27743+
27744+
27745+ ret = pfkey_list_insert_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27746+ , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27747+
27748+ if (ret==0) {
27749+ ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
27750+ /* send register event to userspace */
27751+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27752+ } else
27753+ printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
27754+ "Loading anyway.\n", ret);
27755+ ret=0;
27756+out:
27757+ return ret;
27758+}
27759+
27760+/*
27761+ * unregister ipsec_alg object from own tables, if
27762+ * success => calls pfkey_list_remove_supported()
27763+ */
27764+int unregister_ipsec_alg(struct ipsec_alg *ixt) {
27765+ int ret= -EINVAL;
27766+ switch(ixt->ixt_alg_type) {
27767+ case IPSEC_ALG_TYPE_AUTH:
27768+ case IPSEC_ALG_TYPE_ENCRYPT:
27769+ break;
27770+ default:
27771+ /* this is not a typo :) */
27772+ barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
27773+ ixt->ixt_name);
27774+ }
27775+
27776+ ret=ipsec_alg_delete(ixt);
27777+ if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
27778+ ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
27779+ pfkey_list_remove_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27780+ , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27781+
27782+ /* send register event to userspace */
27783+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27784+ }
27785+
27786+out:
27787+ return ret;
27788+}
27789+
27790+/*
27791+ * Must be called from user context
27792+ * used at module load type for testing algo implementation
27793+ */
27794+static int ipsec_alg_test_encrypt(int enc_alg, int test) {
27795+ int ret;
27796+ caddr_t buf = NULL;
27797+ int iv_size, keysize, key_e_size;
27798+ struct ipsec_alg_enc *ixt_e;
27799+ void *tmp_key_e = NULL;
27800+ #define BUFSZ 1024
27801+ #define MARGIN 0
27802+ #define test_enc (buf+MARGIN)
27803+ #define test_dec (test_enc+BUFSZ+MARGIN)
27804+ #define test_tmp (test_dec+BUFSZ+MARGIN)
27805+ #define test_key_e (test_tmp+BUFSZ+MARGIN)
27806+ #define test_iv (test_key_e+key_e_size+MARGIN)
27807+ #define test_key (test_iv+iv_size+MARGIN)
27808+ #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
27809+ ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
27810+ if (ixt_e==NULL) {
27811+ KLIPS_PRINT(1,
27812+ "klips_debug: ipsec_alg_test_encrypt: "
27813+ "encalg=%d object not found\n",
27814+ enc_alg);
27815+ ret=-EINVAL;
27816+ goto out;
27817+ }
27818+ iv_size=ixt_e->ixt_common.ixt_support.ias_ivlen / 8;
27819+ key_e_size=ixt_e->ixt_e_ctx_size;
27820+ keysize=ixt_e->ixt_e_keylen;
27821+ KLIPS_PRINT(1,
27822+ "klips_debug: ipsec_alg_test_encrypt: "
27823+ "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
27824+ enc_alg, iv_size, key_e_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+ get_random_bytes(test_iv, iv_size);
27831+ if (ixt_e->ixt_e_new_key) {
27832+ tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
27833+ ret = tmp_key_e ? 0 : -EINVAL;
27834+ } else {
27835+ tmp_key_e = test_key_e;
27836+ ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
27837+ }
27838+ if (ret < 0)
27839+ goto out;
27840+ get_random_bytes(test_enc, BUFSZ);
27841+ memcpy(test_tmp, test_enc, BUFSZ);
27842+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
27843+ printk(KERN_INFO
27844+ "klips_info: ipsec_alg_test_encrypt: "
27845+ "cbc_encrypt=1 ret=%d\n",
27846+ ret);
27847+ ret=memcmp(test_enc, test_tmp, BUFSZ);
27848+ printk(KERN_INFO
27849+ "klips_info: ipsec_alg_test_encrypt: "
27850+ "memcmp(enc, tmp) ret=%d: %s\n", ret,
27851+ ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
27852+ memcpy(test_dec, test_enc, BUFSZ);
27853+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
27854+ printk(KERN_INFO
27855+ "klips_info: ipsec_alg_test_encrypt: "
27856+ "cbc_encrypt=0 ret=%d\n", ret);
27857+ ret=memcmp(test_dec, test_tmp, BUFSZ);
27858+ printk(KERN_INFO
27859+ "klips_info: ipsec_alg_test_encrypt: "
27860+ "memcmp(dec,tmp) ret=%d: %s\n", ret,
27861+ ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
27862+ {
27863+ /* Shamelessly taken from drivers/md sources O:) */
27864+ unsigned long now;
27865+ int i, count, max=0;
27866+ int encrypt, speed;
27867+ for (encrypt=0; encrypt <2;encrypt ++) {
27868+ for (i = 0; i < 5; i++) {
27869+ now = jiffies;
27870+ count = 0;
27871+ while (jiffies == now) {
27872+ mb();
27873+ ixt_e->ixt_e_cbc_encrypt(ixt_e,
27874+ tmp_key_e, test_tmp,
27875+ BUFSZ, test_iv, encrypt);
27876+ mb();
27877+ count++;
27878+ mb();
27879+ }
27880+ if (count > max)
27881+ max = count;
27882+ }
27883+ speed = max * (HZ * BUFSZ / 1024);
27884+ printk(KERN_INFO
27885+ "klips_info: ipsec_alg_test_encrypt: "
27886+ "%s %s speed=%d KB/s\n",
27887+ ixt_e->ixt_common.ixt_name,
27888+ encrypt? "encrypt": "decrypt", speed);
27889+ }
27890+ }
27891+out:
27892+ if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
27893+ if (buf) kfree(buf);
27894+ if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
27895+ return ret;
27896+ #undef test_enc
27897+ #undef test_dec
27898+ #undef test_tmp
27899+ #undef test_key_e
27900+ #undef test_iv
27901+ #undef test_key
27902+ #undef test_size
27903+}
27904+
27905+/*
27906+ * Must be called from user context
27907+ * used at module load type for testing algo implementation
27908+ */
27909+static int ipsec_alg_test_auth(int auth_alg, int test) {
27910+ int ret;
27911+ caddr_t buf = NULL;
27912+ int blocksize, keysize, key_a_size;
27913+ struct ipsec_alg_auth *ixt_a;
27914+ #define BUFSZ 1024
27915+ #define MARGIN 0
27916+ #define test_auth (buf+MARGIN)
27917+ #define test_key_a (test_auth+BUFSZ+MARGIN)
27918+ #define test_key (test_key_a+key_a_size+MARGIN)
27919+ #define test_hash (test_key+keysize+MARGIN)
27920+ #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
27921+ ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
27922+ if (ixt_a==NULL) {
27923+ KLIPS_PRINT(1,
27924+ "klips_debug: ipsec_alg_test_auth: "
27925+ "encalg=%d object not found\n",
27926+ auth_alg);
27927+ ret=-EINVAL;
27928+ goto out;
27929+ }
27930+ blocksize=ixt_a->ixt_common.ixt_blocksize;
27931+ key_a_size=ixt_a->ixt_a_ctx_size;
27932+ keysize=ixt_a->ixt_a_keylen;
27933+ KLIPS_PRINT(1,
27934+ "klips_debug: ipsec_alg_test_auth: "
27935+ "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
27936+ auth_alg, blocksize, key_a_size, keysize);
27937+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27938+ ret= -ENOMEM;
27939+ goto out;
27940+ }
27941+ get_random_bytes(test_key, keysize);
27942+ ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
27943+ if (ret < 0 )
27944+ goto out;
27945+ get_random_bytes(test_auth, BUFSZ);
27946+ ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27947+ printk(KERN_INFO
27948+ "klips_info: ipsec_alg_test_auth: "
27949+ "ret=%d\n", ret);
27950+ {
27951+ /* Shamelessly taken from drivers/md sources O:) */
27952+ unsigned long now;
27953+ int i, count, max=0;
27954+ int speed;
27955+ for (i = 0; i < 5; i++) {
27956+ now = jiffies;
27957+ count = 0;
27958+ while (jiffies == now) {
27959+ mb();
27960+ ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27961+ mb();
27962+ count++;
27963+ mb();
27964+ }
27965+ if (count > max)
27966+ max = count;
27967+ }
27968+ speed = max * (HZ * BUFSZ / 1024);
27969+ printk(KERN_INFO
27970+ "klips_info: ipsec_alg_test_auth: "
27971+ "%s hash speed=%d KB/s\n",
27972+ ixt_a->ixt_common.ixt_name,
27973+ speed);
27974+ }
27975+out:
27976+ if (buf) kfree(buf);
27977+ if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
27978+ return ret;
27979+ #undef test_auth
27980+ #undef test_key_a
27981+ #undef test_key
27982+ #undef test_hash
27983+ #undef test_size
27984+}
27985+
27986+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
27987+ switch(alg_type) {
27988+ case IPSEC_ALG_TYPE_ENCRYPT:
27989+ return ipsec_alg_test_encrypt(alg_id, test);
27990+ break;
27991+ case IPSEC_ALG_TYPE_AUTH:
27992+ return ipsec_alg_test_auth(alg_id, test);
27993+ break;
27994+ }
27995+ printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
27996+ "alg_type=%d alg_id=%d\n",
27997+ alg_type, alg_id);
27998+ return -EINVAL;
27999+}
28000+
28001+int ipsec_alg_init(void) {
28002+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
28003+ "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
28004+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
28005+ SADB_EALG_MAX, SADB_AALG_MAX);
28006+ /* Initialize tables */
28007+ write_lock_bh(&ipsec_alg_lock);
28008+ ipsec_alg_hash_init();
28009+ write_unlock_bh(&ipsec_alg_lock);
28010+
28011+ /* Initialize static algos */
28012+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
28013+ "calling ipsec_alg_static_init()\n");
28014+
28015+ /* If we are suppose to use our AES, and don't have
28016+ * CryptoAPI enabled...
28017+ */
28018+#if defined(CONFIG_KLIPS_ENC_AES) && CONFIG_KLIPS_ENC_AES && !defined(CONFIG_KLIPS_ENC_AES_MODULE)
28019+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
28020+#warning "Using built-in AES rather than CryptoAPI AES"
28021+#endif
28022+ {
28023+ extern int ipsec_aes_init(void);
28024+ ipsec_aes_init();
28025+ }
28026+#endif
28027+
28028+#if defined(CONFIG_KLIPS_ENC_3DES) && CONFIG_KLIPS_ENC_3DES && !defined(CONFIG_KLIPS_ENC_3DES_MODULE)
28029+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
28030+#warning "Using built-in 3des rather than CryptoAPI 3des"
28031+#endif
28032+ {
28033+ extern int ipsec_3des_init(void);
28034+ ipsec_3des_init();
28035+ }
28036+#endif
28037+#if defined(CONFIG_KLIPS_ENC_NULL) && CONFIG_KLIPS_ENC_NULL && !defined(CONFIG_KLIPS_ENC_NULL_MODULE)
28038+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
28039+#warning "Using built-in null cipher rather than CryptoAPI null cipher"
28040+#endif
28041+#warning "Building with null cipher (ESP_NULL), blame on you :-)"
28042+ {
28043+ extern int ipsec_null_init(void);
28044+ ipsec_null_init();
28045+ }
28046+#endif
28047+
28048+
28049+ /* If we are doing CryptoAPI, then init */
28050+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI && !defined(CONFIG_KLIPS_ENC_CRYPTOAPI_MODULE)
28051+ {
28052+ extern int ipsec_cryptoapi_init(void);
28053+ ipsec_cryptoapi_init();
28054+ }
28055+#endif
28056+
28057+
28058+ return 0;
28059+}
28060+
28061+/**********************************************
28062+ *
28063+ * INTERFACE for ipsec_sa init and wipe
28064+ *
28065+ **********************************************/
28066+
28067+/*
28068+ * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
28069+ */
28070+int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
28071+ struct ipsec_alg_enc *ixt_e;
28072+ struct ipsec_alg_auth *ixt_a;
28073+
28074+ /* Only ESP for now ... */
28075+ if (sa_p->ips_said.proto != IPPROTO_ESP)
28076+ return -EPROTONOSUPPORT;
28077+
28078+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
28079+ "entering for encalg=%d, authalg=%d\n",
28080+ sa_p->ips_encalg, sa_p->ips_authalg);
28081+
28082+ if ((ixt_e=(struct ipsec_alg_enc *)
28083+ ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
28084+ KLIPS_PRINT(debug_pfkey,
28085+ "klips_debug: ipsec_alg_sa_init() :"
28086+ "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
28087+ ixt_e, sa_p->ips_encalg);
28088+ sa_p->ips_alg_enc=ixt_e;
28089+ }
28090+
28091+ if ((ixt_a=(struct ipsec_alg_auth *)
28092+ ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
28093+ KLIPS_PRINT(debug_pfkey,
28094+ "klips_debug: ipsec_alg_sa_init() :"
28095+ "found ipsec_alg (ixt_a=%p) for auth=%d\n",
28096+ ixt_a, sa_p->ips_authalg);
28097+ sa_p->ips_alg_auth=ixt_a;
28098+ }
28099+ return 0;
28100+}
28101+
28102+/*
28103+ * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
28104+ */
28105+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
28106+ struct ipsec_alg *ixt;
28107+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
28108+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
28109+ "unlinking for encalg=%d\n",
28110+ ixt->ixt_support.ias_id);
28111+ ipsec_alg_put(ixt);
28112+ }
28113+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
28114+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
28115+ "unlinking for authalg=%d\n",
28116+ ixt->ixt_support.ias_id);
28117+ ipsec_alg_put(ixt);
28118+ }
28119+ return 0;
28120+}
28121+
28122+IPSEC_PROCFS_DEBUG_NO_STATIC
28123+int
28124+ipsec_xform_get_info(char *buffer,
28125+ char **start,
28126+ off_t offset,
28127+ int length IPSEC_PROC_LAST_ARG)
28128+{
28129+ int len = 0;
28130+ off_t begin = 0;
28131+ int i;
28132+ struct list_head *head;
28133+ struct ipsec_alg *ixt;
28134+
28135+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
28136+ "klips_debug:ipsec_tncfg_get_info: "
28137+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
28138+ buffer,
28139+ *start,
28140+ (int)offset,
28141+ length);
28142+
28143+ for(i = 0, head = ipsec_alg_hash_table;
28144+ i<IPSEC_ALG_HASHSZ;
28145+ i++, head++)
28146+ {
28147+ struct list_head *p;
28148+ for (p=head->next; p!=head; p=p->next)
28149+ {
28150+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
28151+ len += ipsec_snprintf(buffer+len, length-len,
28152+ "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
28153+ ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_support.ias_id,
28154+ ixt->ixt_name, ixt->ixt_refcnt);
28155+
28156+ len += ipsec_snprintf(buffer+len, length-len,
28157+ "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
28158+ ixt->ixt_state, ixt->ixt_blocksize,
28159+ ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
28160+
28161+ len += ipsec_snprintf(buffer+len, length-len,
28162+ "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
28163+ ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
28164+
28165+ switch(ixt->ixt_alg_type)
28166+ {
28167+ case IPSEC_ALG_TYPE_AUTH:
28168+ {
28169+ struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
28170+
28171+ len += ipsec_snprintf(buffer+len, length-len,
28172+ "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
28173+ auth->ixt_a_keylen, auth->ixt_a_ctx_size,
28174+ auth->ixt_a_authlen);
28175+ break;
28176+ }
28177+ case IPSEC_ALG_TYPE_ENCRYPT:
28178+ {
28179+ struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
28180+ len += ipsec_snprintf(buffer+len, length-len,
28181+ "KEYLEN=%d CTXSIZE=%d ",
28182+ enc->ixt_e_keylen, enc->ixt_e_ctx_size);
28183+
28184+ break;
28185+ }
28186+ }
28187+
28188+ len += ipsec_snprintf(buffer+len, length-len, "\n");
28189+ }
28190+ }
28191+
28192+ *start = buffer + (offset - begin); /* Start of wanted data */
28193+ len -= (offset - begin); /* Start slop */
28194+ if (len > length)
28195+ len = length;
28196+ return len;
28197+}
28198+
28199+
28200+/*
28201+ * As the author of this module, I ONLY ALLOW using it from
28202+ * GPL (or same LICENSE TERMS as kernel source) modules.
28203+ *
28204+ * In respect to hardware crypto engines this means:
28205+ * * Closed-source device drivers ARE NOT ALLOWED to use
28206+ * this interface.
28207+ * * Closed-source VHDL/Verilog firmware running on
28208+ * the crypto hardware device IS ALLOWED to use this interface
28209+ * via a GPL (or same LICENSE TERMS as kernel source) device driver.
28210+ * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
28211+ */
28212+
28213+/*
28214+ * These symbols can only be used from GPL modules
28215+ * for now, I'm disabling this because it creates false
28216+ * symbol problems for old modutils.
28217+ */
28218+
28219+#ifdef CONFIG_MODULES
28220+#ifndef NET_26
28221+#if 0
28222+#ifndef EXPORT_SYMBOL_GPL
28223+#undef EXPORT_SYMBOL_GPL
28224+#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
28225+#endif
28226+#endif
28227+EXPORT_SYMBOL(register_ipsec_alg);
28228+EXPORT_SYMBOL(unregister_ipsec_alg);
28229+EXPORT_SYMBOL(ipsec_alg_test);
28230+#endif
28231+#endif
28232--- /dev/null Tue Mar 11 13:02:56 2003
28233+++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
28234@@ -0,0 +1,455 @@
28235+/*
28236+ * ipsec_alg to linux cryptoapi GLUE
28237+ *
28238+ * Authors: CODE.ar TEAM
28239+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
28240+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
28241+ * Luciano Ruete <docemeses@softhome.net>
28242+ *
28243+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
28244+ *
28245+ * This program is free software; you can redistribute it and/or modify it
28246+ * under the terms of the GNU General Public License as published by the
28247+ * Free Software Foundation; either version 2 of the License, or (at your
28248+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28249+ *
28250+ * This program is distributed in the hope that it will be useful, but
28251+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28252+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28253+ * for more details.
28254+ *
28255+ * Example usage:
28256+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
28257+ * modprobe ipsec_cryptoapi
28258+ * modprobe ipsec_cryptoapi test=1
28259+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
28260+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
28261+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
28262+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
28263+ */
28264+#ifndef AUTOCONF_INCLUDED
28265+#include <linux/config.h>
28266+#endif
28267+#include <linux/version.h>
28268+
28269+/*
28270+ * special case: ipsec core modular with this static algo inside:
28271+ * must avoid MODULE magic for this file
28272+ */
28273+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_CRYPTOAPI)
28274+#undef MODULE
28275+#endif
28276+
28277+#include <linux/module.h>
28278+#include <linux/init.h>
28279+
28280+#include <linux/kernel.h> /* printk() */
28281+#include <linux/errno.h> /* error codes */
28282+#include <linux/types.h> /* size_t */
28283+#include <linux/string.h>
28284+
28285+/* Check if __exit is defined, if not null it */
28286+#ifndef __exit
28287+#define __exit
28288+#endif
28289+
28290+/* warn the innocent */
28291+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
28292+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
28293+#define NO_CRYPTOAPI_SUPPORT
28294+#endif
28295+
28296+#include "openswan.h"
28297+#include "openswan/ipsec_alg.h"
28298+#include "openswan/ipsec_policy.h"
28299+
28300+#include <linux/crypto.h>
28301+#ifdef CRYPTO_API_VERSION_CODE
28302+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
28303+#define NO_CRYPTOAPI_SUPPORT
28304+#endif
28305+
28306+#ifdef NO_CRYPTOAPI_SUPPORT
28307+#warning "Building an unusable module :P"
28308+/* Catch old CryptoAPI by not allowing module to load */
28309+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
28310+{
28311+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
28312+ return -EINVAL;
28313+}
28314+#else
28315+#include <asm/scatterlist.h>
28316+#include <asm/pgtable.h>
28317+#include <linux/mm.h>
28318+
28319+#define CIPHERNAME_AES "aes"
28320+#define CIPHERNAME_1DES "des"
28321+#define CIPHERNAME_3DES "des3_ede"
28322+#define CIPHERNAME_BLOWFISH "blowfish"
28323+#define CIPHERNAME_CAST "cast5"
28324+#define CIPHERNAME_SERPENT "serpent"
28325+#define CIPHERNAME_TWOFISH "twofish"
28326+
28327+#define ESP_SERPENT 252 /* from ipsec drafts */
28328+#define ESP_TWOFISH 253 /* from ipsec drafts */
28329+
28330+#define DIGESTNAME_MD5 "md5"
28331+#define DIGESTNAME_SHA1 "sha1"
28332+
28333+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
28334+static int debug_crypto=0;
28335+static int test_crypto=0;
28336+static int excl_crypto=0;
28337+
28338+static int noauto = 0;
28339+
28340+#ifdef module_param
28341+module_param(debug_crypto,int,0600)
28342+module_param(test_crypto,int,0600)
28343+module_param(excl_crypto,int,0600)
28344+
28345+module_param(noauto,int,0600)
28346+#else
28347+MODULE_PARM(debug_crypto, "i");
28348+MODULE_PARM(test_crypto, "i");
28349+MODULE_PARM(excl_crypto, "i");
28350+
28351+MODULE_PARM(noauto,"i");
28352+#endif
28353+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
28354+
28355+#ifdef CONFIG_KLIPS_ENC_1DES
28356+static int des_ede1[] = {-1, -1};
28357+#endif
28358+static int des_ede3[] = {-1, -1};
28359+static int aes[] = {-1, -1};
28360+static int blowfish[] = {-1, -1};
28361+static int cast[] = {-1, -1};
28362+static int serpent[] = {-1, -1};
28363+static int twofish[] = {-1, -1};
28364+
28365+#ifdef CONFIG_KLIPS_ENC_1DES
28366+#ifdef module_param
28367+module_param_array(des_ede1,int,NULL,0)
28368+#else
28369+MODULE_PARM(des_ede1,"1-2i");
28370+#endif
28371+#endif
28372+#ifdef module_param
28373+module_param_array(des_ede3,int,NULL,0)
28374+module_param_array(aes,int,NULL,0)
28375+module_param_array(blowfish,int,NULL,0)
28376+module_param_array(cast,int,NULL,0)
28377+module_param_array(serpent,int,NULL,0)
28378+module_param_array(twofish,int,NULL,0)
28379+#else
28380+MODULE_PARM(des_ede3,"1-2i");
28381+MODULE_PARM(aes,"1-2i");
28382+MODULE_PARM(blowfish,"1-2i");
28383+MODULE_PARM(cast,"1-2i");
28384+MODULE_PARM(serpent,"1-2i");
28385+MODULE_PARM(twofish,"1-2i");
28386+#endif
28387+MODULE_PARM_DESC(des_ede1, "0: disable | 1: force_enable | min,max: dontuse");
28388+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
28389+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
28390+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
28391+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
28392+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
28393+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
28394+
28395+struct ipsec_alg_capi_cipher {
28396+ const char *ciphername; /* cryptoapi's ciphername */
28397+ unsigned blocksize;
28398+ unsigned short minbits;
28399+ unsigned short maxbits;
28400+ int *parm; /* lkm param for this cipher */
28401+ struct ipsec_alg_enc alg; /* note it's not a pointer */
28402+};
28403+
28404+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
28405+ { CIPHERNAME_AES, 16, 128, 256, aes, { ixt_common:{ ixt_support:{ ias_id: ESP_AES}}}},
28406+ { CIPHERNAME_TWOFISH, 16, 128, 256, twofish, { ixt_common:{ ixt_support:{ ias_id: ESP_TWOFISH,}}}},
28407+ { CIPHERNAME_SERPENT, 16, 128, 256, serpent, { ixt_common:{ ixt_support:{ ias_id: ESP_SERPENT,}}}},
28408+ { CIPHERNAME_CAST, 8, 128, 128, cast , { ixt_common:{ ixt_support:{ ias_id: ESP_CAST,}}}},
28409+ { CIPHERNAME_BLOWFISH, 8, 96, 448, blowfish, { ixt_common:{ ixt_support:{ ias_id: ESP_BLOWFISH,}}}},
28410+ { CIPHERNAME_3DES, 8, 192, 192, des_ede3, { ixt_common:{ ixt_support:{ ias_id: ESP_3DES,}}}},
28411+#ifdef CONFIG_KLIPS_ENC_1DES
28412+ { CIPHERNAME_1DES, 8, 64, 64, des_ede1, { ixt_common:{ ixt_support:{ ias_id: ESP_DES,}}}},
28413+#endif
28414+ { NULL, 0, 0, 0, NULL, {} }
28415+};
28416+
28417+#ifdef NOT_YET
28418+struct ipsec_alg_capi_digest {
28419+ const char *digestname; /* cryptoapi's digestname */
28420+ struct digest_implementation *di;
28421+ struct ipsec_alg_auth alg; /* note it's not a pointer */
28422+};
28423+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
28424+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
28425+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
28426+ { NULL, NULL, {} }
28427+};
28428+#endif
28429+/*
28430+ * "generic" linux cryptoapi setup_cipher() function
28431+ */
28432+int setup_cipher(const char *ciphername)
28433+{
28434+ return crypto_alg_available(ciphername, 0);
28435+}
28436+
28437+/*
28438+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
28439+ * register_ipsec_alg for cointaned ipsec_alg object
28440+ */
28441+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
28442+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
28443+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
28444+
28445+static int
28446+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
28447+{
28448+ int ret;
28449+ cptr->alg.ixt_common.ixt_version = IPSEC_ALG_VERSION;
28450+ cptr->alg.ixt_common.ixt_module = THIS_MODULE;
28451+ atomic_set (& cptr->alg.ixt_common.ixt_refcnt, 0);
28452+ strncpy (cptr->alg.ixt_common.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_common.ixt_name));
28453+
28454+ cptr->alg.ixt_common.ixt_blocksize=cptr->blocksize;
28455+ cptr->alg.ixt_common.ixt_support.ias_keyminbits=cptr->minbits;
28456+ cptr->alg.ixt_common.ixt_support.ias_keymaxbits=cptr->maxbits;
28457+ cptr->alg.ixt_common.ixt_state = 0;
28458+ if (excl_crypto) cptr->alg.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
28459+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_common.ixt_support.ias_keymaxbits/8;
28460+ cptr->alg.ixt_e_ctx_size = 0;
28461+ cptr->alg.ixt_common.ixt_support.ias_exttype = IPSEC_ALG_TYPE_ENCRYPT;
28462+ cptr->alg.ixt_e_new_key = _capi_new_key;
28463+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
28464+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
28465+ cptr->alg.ixt_common.ixt_data = cptr;
28466+
28467+ ret=register_ipsec_alg_enc(&cptr->alg);
28468+ printk(KERN_INFO "KLIPS cryptoapi interface: "
28469+ "alg_type=%d alg_id=%d name=%s "
28470+ "keyminbits=%d keymaxbits=%d, %s(%d)\n",
28471+ cptr->alg.ixt_common.ixt_support.ias_exttype,
28472+ cptr->alg.ixt_common.ixt_support.ias_id,
28473+ cptr->alg.ixt_common.ixt_name,
28474+ cptr->alg.ixt_common.ixt_support.ias_keyminbits,
28475+ cptr->alg.ixt_common.ixt_support.ias_keymaxbits,
28476+ ret ? "not found" : "found", ret);
28477+ return ret;
28478+}
28479+/*
28480+ * called in ipsec_sa_wipe() time, will destroy key contexts
28481+ * and do 1 unbind()
28482+ */
28483+static void
28484+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
28485+{
28486+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
28487+
28488+ if (debug_crypto > 0)
28489+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
28490+ "name=%s key_e=%p \n",
28491+ alg->ixt_common.ixt_name, key_e);
28492+ if (!key_e) {
28493+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
28494+ "name=%s NULL key_e!\n",
28495+ alg->ixt_common.ixt_name);
28496+ return;
28497+ }
28498+ crypto_free_tfm(tfm);
28499+}
28500+
28501+/*
28502+ * create new key context, need alg->ixt_data to know which
28503+ * (of many) cipher inside this module is the target
28504+ */
28505+static __u8 *
28506+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
28507+{
28508+ struct ipsec_alg_capi_cipher *cptr;
28509+ struct crypto_tfm *tfm=NULL;
28510+
28511+ cptr = alg->ixt_common.ixt_data;
28512+ if (!cptr) {
28513+ printk(KERN_ERR "_capi_new_key(): "
28514+ "NULL ixt_data (?!) for \"%s\" algo\n"
28515+ , alg->ixt_common.ixt_name);
28516+ goto err;
28517+ }
28518+ if (debug_crypto > 0)
28519+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28520+ "name=%s cptr=%p key=%p keysize=%d\n",
28521+ alg->ixt_common.ixt_name, cptr, key, keylen);
28522+
28523+ /*
28524+ * alloc tfm
28525+ */
28526+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
28527+ if (!tfm) {
28528+ printk(KERN_ERR "_capi_new_key(): "
28529+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
28530+ , alg->ixt_common.ixt_name, cptr->ciphername);
28531+ goto err;
28532+ }
28533+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
28534+ printk(KERN_ERR "_capi_new_key(): "
28535+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
28536+ , alg->ixt_common.ixt_name, keylen);
28537+ crypto_free_tfm(tfm);
28538+ tfm=NULL;
28539+ }
28540+err:
28541+ if (debug_crypto > 0)
28542+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28543+ "name=%s key=%p keylen=%d tfm=%p\n",
28544+ alg->ixt_common.ixt_name, key, keylen, tfm);
28545+ return (__u8 *) tfm;
28546+}
28547+/*
28548+ * core encryption function: will use cx->ci to call actual cipher's
28549+ * cbc function
28550+ */
28551+static int
28552+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
28553+ int error =0;
28554+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
28555+ struct scatterlist sg = {
28556+ .page = virt_to_page(in),
28557+ .offset = (unsigned long)(in) % PAGE_SIZE,
28558+ .length=ilen,
28559+ };
28560+ if (debug_crypto > 1)
28561+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28562+ "key_e=%p "
28563+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
28564+ , key_e
28565+ , in, in, ilen, iv, encrypt);
28566+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
28567+ if (encrypt)
28568+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
28569+ else
28570+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
28571+ if (debug_crypto > 1)
28572+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28573+ "error=%d\n"
28574+ , error);
28575+ return (error<0)? error : ilen;
28576+}
28577+/*
28578+ * main initialization loop: for each cipher in list, do
28579+ * 1) setup cryptoapi cipher else continue
28580+ * 2) register ipsec_alg object
28581+ */
28582+static int
28583+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28584+{
28585+ struct ipsec_alg_capi_cipher *cptr;
28586+ /* foreach cipher in list ... */
28587+ for (cptr=clist;cptr->ciphername;cptr++) {
28588+ /*
28589+ * see if cipher has been disabled (0) or
28590+ * if noauto set and not enabled (1)
28591+ */
28592+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
28593+ if (debug_crypto>0)
28594+ printk(KERN_INFO "setup_cipher_list(): "
28595+ "ciphername=%s skipped at user request: "
28596+ "noauto=%d parm[0]=%d parm[1]=%d\n"
28597+ , cptr->ciphername
28598+ , noauto
28599+ , cptr->parm[0]
28600+ , cptr->parm[1]);
28601+ continue;
28602+ }
28603+ /*
28604+ * use a local ci to avoid touching cptr->ci,
28605+ * if register ipsec_alg success then bind cipher
28606+ */
28607+ if(cptr->alg.ixt_common.ixt_support.ias_name == NULL) {
28608+ cptr->alg.ixt_common.ixt_support.ias_name = cptr->ciphername;
28609+ }
28610+
28611+ if( setup_cipher(cptr->ciphername) ) {
28612+ if (debug_crypto > 0)
28613+ printk(KERN_DEBUG "klips_debug:"
28614+ "setup_cipher_list():"
28615+ "ciphername=%s found\n"
28616+ , cptr->ciphername);
28617+
28618+ if (setup_ipsec_alg_capi_cipher(cptr) != 0) {
28619+ printk(KERN_ERR "klips_debug:"
28620+ "setup_cipher_list():"
28621+ "ciphername=%s failed ipsec_alg_register\n"
28622+ , cptr->ciphername);
28623+ }
28624+ } else {
28625+ printk(KERN_INFO "KLIPS: lookup for ciphername=%s: not found \n",
28626+ cptr->ciphername);
28627+ }
28628+ }
28629+ return 0;
28630+}
28631+/*
28632+ * deregister ipsec_alg objects and unbind ciphers
28633+ */
28634+static int
28635+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28636+{
28637+ struct ipsec_alg_capi_cipher *cptr;
28638+ /* foreach cipher in list ... */
28639+ for (cptr=clist;cptr->ciphername;cptr++) {
28640+ if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28641+ unregister_ipsec_alg_enc(&cptr->alg);
28642+ }
28643+ }
28644+ return 0;
28645+}
28646+/*
28647+ * test loop for registered algos
28648+ */
28649+static int
28650+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
28651+{
28652+ int test_ret;
28653+ struct ipsec_alg_capi_cipher *cptr;
28654+ /* foreach cipher in list ... */
28655+ for (cptr=clist;cptr->ciphername;cptr++) {
28656+ if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28657+ test_ret=ipsec_alg_test(
28658+ cptr->alg.ixt_common.ixt_support.ias_exttype,
28659+ cptr->alg.ixt_common.ixt_support.ias_id,
28660+ test_crypto);
28661+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
28662+ cptr->alg.ixt_common.ixt_support.ias_exttype,
28663+ cptr->alg.ixt_common.ixt_support.ias_id,
28664+ test_ret);
28665+ }
28666+ }
28667+ return 0;
28668+}
28669+
28670+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
28671+{
28672+ int ret, test_ret;
28673+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
28674+ return -EPROTONOSUPPORT;
28675+ if (ret==0 && test_crypto) {
28676+ test_ret=test_cipher_list(alg_capi_carray);
28677+ }
28678+ return ret;
28679+}
28680+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini )
28681+{
28682+ unsetup_cipher_list(alg_capi_carray);
28683+ return;
28684+}
28685+#ifdef MODULE_LICENSE
28686+MODULE_LICENSE("GPL");
28687+#endif
28688+
28689+#endif /* NO_CRYPTOAPI_SUPPORT */
28690--- /dev/null Tue Mar 11 13:02:56 2003
28691+++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004
28692@@ -0,0 +1,615 @@
28693+/*
28694+ * processing code for ESP
28695+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
28696+ *
28697+ * This program is free software; you can redistribute it and/or modify it
28698+ * under the terms of the GNU General Public License as published by the
28699+ * Free Software Foundation; either version 2 of the License, or (at your
28700+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28701+ *
28702+ * This program is distributed in the hope that it will be useful, but
28703+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28704+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28705+ * for more details.
28706+ */
28707+
28708+char ipsec_esp_c_version[] = "RCSID $Id: ipsec_esp.c,v 1.13.2.7 2007-09-05 02:56:09 paul Exp $";
28709+#ifndef AUTOCONF_INCLUDED
28710+#include <linux/config.h>
28711+#endif
28712+#include <linux/version.h>
28713+
28714+#define __NO_VERSION__
28715+#include <linux/module.h>
28716+#include <linux/kernel.h> /* printk() */
28717+
28718+#include "openswan/ipsec_param.h"
28719+
28720+#ifdef MALLOC_SLAB
28721+# include <linux/slab.h> /* kmalloc() */
28722+#else /* MALLOC_SLAB */
28723+# include <linux/malloc.h> /* kmalloc() */
28724+#endif /* MALLOC_SLAB */
28725+#include <linux/errno.h> /* error codes */
28726+#include <linux/types.h> /* size_t */
28727+#include <linux/interrupt.h> /* mark_bh */
28728+
28729+#include <linux/netdevice.h> /* struct device, and other headers */
28730+#include <linux/etherdevice.h> /* eth_type_trans */
28731+#include <linux/ip.h> /* struct iphdr */
28732+#include <linux/skbuff.h>
28733+#include <openswan.h>
28734+#ifdef SPINLOCK
28735+# ifdef SPINLOCK_23
28736+# include <linux/spinlock.h> /* *lock* */
28737+# else /* SPINLOCK_23 */
28738+# include <asm/spinlock.h> /* *lock* */
28739+# endif /* SPINLOCK_23 */
28740+#endif /* SPINLOCK */
28741+
28742+#include <net/ip.h>
28743+#include <net/protocol.h>
28744+
28745+#include "openswan/radij.h"
28746+#include "openswan/ipsec_encap.h"
28747+#include "openswan/ipsec_sa.h"
28748+
28749+#include "openswan/ipsec_radij.h"
28750+#include "openswan/ipsec_xform.h"
28751+#include "openswan/ipsec_tunnel.h"
28752+#include "openswan/ipsec_rcv.h"
28753+#include "openswan/ipsec_xmit.h"
28754+
28755+#include "openswan/ipsec_auth.h"
28756+
28757+#ifdef CONFIG_KLIPS_ESP
28758+#include "openswan/ipsec_esp.h"
28759+#endif /* CONFIG_KLIPS_ESP */
28760+
28761+#include "openswan/ipsec_proto.h"
28762+#include "openswan/ipsec_alg.h"
28763+
28764+#ifdef CONFIG_KLIPS_DEBUG
28765+#define ESP_DMP(_x,_y,_z) if(debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
28766+#else
28767+#define ESP_DMP(_x,_y,_z)
28768+#endif
28769+
28770+#ifdef CONFIG_KLIPS_ESP
28771+enum ipsec_rcv_value
28772+ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
28773+ struct sk_buff *skb)
28774+{
28775+ __u8 proto;
28776+ int len; /* packet length */
28777+
28778+ len = skb->len;
28779+ proto = irs->ipp->protocol;
28780+
28781+ /* XXX this will need to be 8 for IPv6 */
28782+ if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
28783+ printk("klips_error:ipsec_rcv: "
28784+ "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
28785+ len - irs->iphlen,
28786+ irs->ipsaddr_txt);
28787+ if(irs->stats) {
28788+ irs->stats->rx_errors++;
28789+ }
28790+ return IPSEC_RCV_BADLEN;
28791+ }
28792+
28793+ if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {
28794+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
28795+ "klips_debug:ipsec_rcv: "
28796+ "runt esp packet of skb->len=%d received from %s, dropped.\n",
28797+ skb->len,
28798+ irs->ipsaddr_txt);
28799+ if(irs->stats) {
28800+ irs->stats->rx_errors++;
28801+ }
28802+ return IPSEC_RCV_BADLEN;
28803+ }
28804+
28805+ irs->protostuff.espstuff.espp = (struct esphdr *)skb_transport_header(skb);
28806+ irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
28807+
28808+ return IPSEC_RCV_OK;
28809+}
28810+
28811+enum ipsec_rcv_value
28812+ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
28813+ struct sk_buff *skb,
28814+ __u32 *replay,
28815+ unsigned char **authenticator)
28816+{
28817+ struct esphdr *espp = irs->protostuff.espstuff.espp;
28818+ //unsigned char *idat = (unsigned char *)espp;
28819+
28820+ KLIPS_PRINT(debug_rcv,
28821+ "klips_debug:ipsec_rcv: "
28822+ "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
28823+ irs->ipsaddr_txt,
28824+ (__u32)ntohl(espp->esp_rpl),
28825+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
28826+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
28827+ irs->len,
28828+ irs->ilen,
28829+ irs->sa_len ? irs->sa : " (error)");
28830+
28831+ *replay = ntohl(espp->esp_rpl);
28832+ *authenticator = &(skb_transport_header(skb)[irs->ilen]);
28833+
28834+ return IPSEC_RCV_OK;
28835+}
28836+
28837+enum ipsec_rcv_value
28838+ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
28839+ struct sk_buff *skb)
28840+{
28841+ struct auth_alg *aa;
28842+ struct esphdr *espp = irs->protostuff.espstuff.espp;
28843+ union {
28844+ MD5_CTX md5;
28845+ SHA1_CTX sha1;
28846+ } tctx;
28847+
28848+#ifdef CONFIG_KLIPS_ALG
28849+ if (irs->ipsp->ips_alg_auth) {
28850+ KLIPS_PRINT(debug_rcv,
28851+ "klips_debug:ipsec_rcv: "
28852+ "ipsec_alg hashing proto=%d... ",
28853+ irs->said.proto);
28854+ if(irs->said.proto == IPPROTO_ESP) {
28855+ ipsec_alg_sa_esp_hash(irs->ipsp,
28856+ (caddr_t)espp, irs->ilen,
28857+ irs->hash, AHHMAC_HASHLEN);
28858+ return IPSEC_RCV_OK;
28859+ }
28860+ return IPSEC_RCV_BADPROTO;
28861+ }
28862+#endif
28863+ aa = irs->authfuncs;
28864+
28865+ /* copy the initialized keying material */
28866+ memcpy(&tctx, irs->ictx, irs->ictx_len);
28867+
28868+#ifdef HASH_DEBUG
28869+ ESP_DMP("ictx", irs->ictx, irs->ictx_len);
28870+
28871+ ESP_DMP("mac_esp", (caddr_t)espp, irs->ilen);
28872+#endif
28873+ (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
28874+
28875+ (*aa->final)(irs->hash, (void *)&tctx);
28876+
28877+#ifdef HASH_DEBUG
28878+ ESP_DMP("hash1", irs->hash, aa->hashlen);
28879+#endif
28880+
28881+ memcpy(&tctx, irs->octx, irs->octx_len);
28882+
28883+#ifdef HASH_DEBUG
28884+ ESP_DMP("octx", irs->octx, irs->octx_len);
28885+#endif
28886+
28887+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
28888+ (*aa->final)(irs->hash, (void *)&tctx);
28889+
28890+ return IPSEC_RCV_OK;
28891+}
28892+
28893+
28894+enum ipsec_rcv_value
28895+ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
28896+{
28897+ struct ipsec_sa *ipsp = irs->ipsp;
28898+ struct esphdr *espp = irs->protostuff.espstuff.espp;
28899+ int i;
28900+ int pad = 0, padlen;
28901+ int badpad = 0;
28902+ int esphlen = 0;
28903+ __u8 *idat; /* pointer to content to be decrypted/authenticated */
28904+ int encaplen = 0;
28905+ struct sk_buff *skb;
28906+ struct ipsec_alg_enc *ixt_e=NULL;
28907+
28908+#ifdef CONFIG_KLIPS_ALG
28909+ skb=irs->skb;
28910+
28911+ idat = skb_transport_header(skb);
28912+
28913+ /* encaplen is the distance between the end of the IP
28914+ * header and the beginning of the ESP header.
28915+ * on ESP headers it is zero, but on UDP-encap ESP
28916+ * it includes the space for the UDP header.
28917+ *
28918+ * Note: UDP-encap code has already moved the
28919+ * skb->data forward to accomodate this.
28920+ */
28921+ encaplen = skb_transport_header(skb) - (skb_network_header(skb) + irs->iphlen);
28922+
28923+ ixt_e=ipsp->ips_alg_enc;
28924+ esphlen = ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
28925+ KLIPS_PRINT(debug_rcv,
28926+ "klips_debug:ipsec_rcv: "
28927+ "encalg=%d esphlen=%d\n",
28928+ ipsp->ips_encalg, esphlen);
28929+
28930+ idat += esphlen;
28931+ irs->ilen -= esphlen;
28932+
28933+ if (ipsec_alg_esp_encrypt(ipsp,
28934+ idat, irs->ilen, espp->esp_iv,
28935+ IPSEC_ALG_DECRYPT) <= 0) {
28936+#ifdef CONFIG_KLIPS_DEBUG
28937+ KLIPS_ERROR(debug_rcv, "klips_error:ipsec_rcv: "
28938+ "got packet with esplen = %d "
28939+ "from %s -- should be on "
28940+ "ENC(%d) octet boundary, "
28941+ "packet dropped\n",
28942+ irs->ilen,
28943+ irs->ipsaddr_txt,
28944+ ipsp->ips_encalg);
28945+#endif
28946+ if(irs->stats) {
28947+ irs->stats->rx_errors++;
28948+ }
28949+ return IPSEC_RCV_BAD_DECRYPT;
28950+#endif /* CONFIG_KLIPS_ALG */
28951+ }
28952+
28953+ ESP_DMP("postdecrypt", idat, irs->ilen);
28954+
28955+ irs->next_header = idat[irs->ilen - 1];
28956+ padlen = idat[irs->ilen - 2];
28957+ pad = padlen + 2 + irs->authlen;
28958+
28959+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28960+ "klips_debug:ipsec_rcv: "
28961+ "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
28962+ padlen);
28963+
28964+ for (i = 1; i <= padlen; i++) {
28965+ if((i % 16) == 1) {
28966+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28967+ "klips_debug: %02x:",
28968+ i - 1);
28969+ }
28970+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28971+ " %02x",
28972+ idat[irs->ilen - 2 - padlen + i - 1]);
28973+ if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
28974+ badpad = 1;
28975+ }
28976+ if((i % 16) == 0) {
28977+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28978+ "\n");
28979+ }
28980+ }
28981+ if((i % 16) != 1) {
28982+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28983+ "\n");
28984+ }
28985+ if(badpad) {
28986+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28987+ "klips_debug:ipsec_rcv: "
28988+ "warning, decrypted packet from %s has bad padding\n",
28989+ irs->ipsaddr_txt);
28990+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28991+ "klips_debug:ipsec_rcv: "
28992+ "...may be bad decryption -- not dropped\n");
28993+ ipsp->ips_errs.ips_encpad_errs += 1;
28994+ }
28995+
28996+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28997+ "klips_debug:ipsec_rcv: "
28998+ "packet decrypted from %s: next_header = %d, padding = %d\n",
28999+ irs->ipsaddr_txt,
29000+ irs->next_header,
29001+ pad - 2 - irs->authlen);
29002+
29003+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad));
29004+
29005+ /*
29006+ * move the IP header forward by the size of the ESP header, which
29007+ * will remove the the ESP header from the packet.
29008+ *
29009+ * XXX this is really unnecessary, since odds we are in tunnel
29010+ * mode, and we will be *removing* this IP header.
29011+ *
29012+ */
29013+ memmove((void *)(idat - irs->iphlen),
29014+ (void *)(skb_network_header(skb)), irs->iphlen);
29015+
29016+ ESP_DMP("esp postmove", (idat - irs->iphlen),
29017+ irs->iphlen + irs->ilen);
29018+
29019+ /* skb_pull below, will move up by esphlen */
29020+
29021+ /* XXX not clear how this can happen, as the message indicates */
29022+ if(skb->len < esphlen) {
29023+ printk(KERN_WARNING
29024+ "klips_error:ipsec_rcv: "
29025+ "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n",
29026+ esphlen, (int)(skb->len));
29027+ return IPSEC_RCV_ESP_DECAPFAIL;
29028+ }
29029+ skb_pull(skb, esphlen);
29030+ skb_set_network_header(skb, ipsec_skb_offset(skb, idat - irs->iphlen));
29031+ irs->ipp = ip_hdr(skb);
29032+
29033+ ESP_DMP("esp postpull", skb->data, skb->len);
29034+
29035+ /* now, trip off the padding from the end */
29036+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
29037+ "klips_debug:ipsec_rcv: "
29038+ "trimming to %d.\n",
29039+ irs->len - esphlen - pad);
29040+ if(pad + esphlen <= irs->len) {
29041+ skb_trim(skb, irs->len - esphlen - pad);
29042+ } else {
29043+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
29044+ "klips_debug:ipsec_rcv: "
29045+ "bogus packet, size is zero or negative, dropping.\n");
29046+ return IPSEC_RCV_DECAPFAIL;
29047+ }
29048+
29049+ return IPSEC_RCV_OK;
29050+}
29051+
29052+/*
29053+ *
29054+ */
29055+enum ipsec_xmit_value
29056+ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs)
29057+{
29058+#ifdef CONFIG_KLIPS_ENC_3DES
29059+ __u32 iv[2];
29060+#endif
29061+ struct esphdr *espp;
29062+ int ilen = 0;
29063+ int padlen = 0, i;
29064+ unsigned char *dat;
29065+ unsigned char *idat, *pad;
29066+ __u8 hash[AH_AMAX];
29067+ union {
29068+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
29069+ MD5_CTX md5;
29070+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
29071+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
29072+ SHA1_CTX sha1;
29073+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
29074+ } tctx;
29075+
29076+ dat = (unsigned char *)ixs->iph;
29077+
29078+ espp = (struct esphdr *)(dat + ixs->iphlen);
29079+ espp->esp_spi = ixs->ipsp->ips_said.spi;
29080+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
29081+
29082+ switch(ixs->ipsp->ips_encalg) {
29083+#if defined(CONFIG_KLIPS_ENC_3DES)
29084+#ifdef CONFIG_KLIPS_ENC_3DES
29085+ case ESP_3DES:
29086+#endif /* CONFIG_KLIPS_ENC_3DES */
29087+ iv[0] = *((__u32*)&(espp->esp_iv) ) =
29088+ ((__u32*)(ixs->ipsp->ips_iv))[0];
29089+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
29090+ ((__u32*)(ixs->ipsp->ips_iv))[1];
29091+ break;
29092+#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
29093+ default:
29094+ ixs->stats->tx_errors++;
29095+ return IPSEC_XMIT_ESP_BADALG;
29096+ }
29097+
29098+ idat = dat + ixs->iphlen + sizeof(struct esphdr);
29099+ ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen);
29100+
29101+ /* Self-describing padding */
29102+ pad = &dat[ixs->skb->len - ixs->tailroom];
29103+ padlen = ixs->tailroom - 2 - ixs->authlen;
29104+ for (i = 0; i < padlen; i++) {
29105+ pad[i] = i + 1;
29106+ }
29107+ dat[ixs->skb->len - ixs->authlen - 2] = padlen;
29108+
29109+ dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol;
29110+ ixs->iph->protocol = IPPROTO_ESP;
29111+
29112+ switch(ixs->ipsp->ips_encalg) {
29113+#ifdef CONFIG_KLIPS_ENC_3DES
29114+ case ESP_3DES:
29115+ des_ede3_cbc_encrypt((des_cblock *)idat,
29116+ (des_cblock *)idat,
29117+ ilen,
29118+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
29119+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
29120+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
29121+ (des_cblock *)iv, 1);
29122+ break;
29123+#endif /* CONFIG_KLIPS_ENC_3DES */
29124+ default:
29125+ ixs->stats->tx_errors++;
29126+ return IPSEC_XMIT_ESP_BADALG;
29127+ }
29128+
29129+ switch(ixs->ipsp->ips_encalg) {
29130+#if defined(CONFIG_KLIPS_ENC_3DES)
29131+#ifdef CONFIG_KLIPS_ENC_3DES
29132+ case ESP_3DES:
29133+#endif /* CONFIG_KLIPS_ENC_3DES */
29134+ /* XXX update IV with the last 8 octets of the encryption */
29135+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
29136+ ((__u32*)(ixs->ipsp->ips_iv))[0] =
29137+ ((__u32 *)(idat))[(ilen >> 2) - 2];
29138+ ((__u32*)(ixs->ipsp->ips_iv))[1] =
29139+ ((__u32 *)(idat))[(ilen >> 2) - 1];
29140+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
29141+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
29142+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
29143+ break;
29144+#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
29145+ default:
29146+ ixs->stats->tx_errors++;
29147+ return IPSEC_XMIT_ESP_BADALG;
29148+ }
29149+
29150+ switch(ixs->ipsp->ips_authalg) {
29151+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
29152+ case AH_MD5:
29153+ ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29154+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
29155+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
29156+ osMD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29157+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
29158+ osMD5Final(hash, &tctx.md5);
29159+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
29160+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
29161+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
29162+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
29163+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
29164+ osMD5Final(hash, &tctx.md5);
29165+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
29166+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
29167+
29168+ /* paranoid */
29169+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
29170+ memset((caddr_t)hash, 0, sizeof(*hash));
29171+ break;
29172+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
29173+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
29174+ case AH_SHA:
29175+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
29176+ SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29177+ SHA1Final(hash, &tctx.sha1);
29178+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
29179+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
29180+ SHA1Final(hash, &tctx.sha1);
29181+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
29182+
29183+ /* paranoid */
29184+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
29185+ memset((caddr_t)hash, 0, sizeof(*hash));
29186+ break;
29187+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
29188+ case AH_NONE:
29189+ break;
29190+ default:
29191+ ixs->stats->tx_errors++;
29192+ return IPSEC_XMIT_AH_BADALG;
29193+ }
29194+
29195+ skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, espp));
29196+
29197+ return IPSEC_XMIT_OK;
29198+}
29199+
29200+
29201+struct xform_functions esp_xform_funcs[]={
29202+ { rcv_checks: ipsec_rcv_esp_checks,
29203+ rcv_setup_auth: ipsec_rcv_esp_decrypt_setup,
29204+ rcv_calc_auth: ipsec_rcv_esp_authcalc,
29205+ rcv_decrypt: ipsec_rcv_esp_decrypt,
29206+
29207+ xmit_setup: ipsec_xmit_esp_setup,
29208+ xmit_headroom: sizeof(struct esphdr),
29209+ xmit_needtailroom: 1,
29210+ },
29211+};
29212+
29213+#ifdef NET_26
29214+struct inet_protocol esp_protocol = {
29215+ .handler = ipsec_rcv,
29216+ .no_policy = 1,
29217+};
29218+#else
29219+struct inet_protocol esp_protocol =
29220+{
29221+ ipsec_rcv, /* ESP handler */
29222+ NULL, /* TUNNEL error control */
29223+#ifdef NETDEV_25
29224+ 1, /* no policy */
29225+#else
29226+ 0, /* next */
29227+ IPPROTO_ESP, /* protocol ID */
29228+ 0, /* copy */
29229+ NULL, /* data */
29230+ "ESP" /* name */
29231+#endif
29232+};
29233+#endif /* NET_26 */
29234+
29235+#endif /* !CONFIG_KLIPS_ESP */
29236+
29237+
29238+/*
29239+ * $Log: ipsec_esp.c,v $
29240+ * Revision 1.13.2.7 2007-09-05 02:56:09 paul
29241+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
29242+ * Fixes based on David McCullough patch.
29243+ *
29244+ * Revision 1.13.2.6 2006/10/06 21:39:26 paul
29245+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
29246+ * set. This is defined through autoconf.h which is included through the
29247+ * linux kernel build macros.
29248+ *
29249+ * Revision 1.13.2.5 2006/08/24 03:02:01 paul
29250+ * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
29251+ *
29252+ * Revision 1.13.2.4 2006/05/06 03:07:38 ken
29253+ * Pull in proper padsize->tailroom fix from #public
29254+ * Need to do correct math on padlen since padsize is not equal to tailroom
29255+ *
29256+ * Revision 1.13.2.3 2006/05/05 03:58:04 ken
29257+ * ixs->padsize becomes ixs->tailroom
29258+ *
29259+ * Revision 1.13.2.2 2006/05/01 14:36:03 mcr
29260+ * use KLIPS_ERROR for fatal things.
29261+ *
29262+ * Revision 1.13.2.1 2006/04/20 16:33:06 mcr
29263+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
29264+ * Fix in-kernel module compilation. Sub-makefiles do not work.
29265+ *
29266+ * Revision 1.13 2005/05/21 03:19:57 mcr
29267+ * hash ctx is not really that interesting most of the time.
29268+ *
29269+ * Revision 1.12 2005/05/11 01:28:49 mcr
29270+ * removed "poor-man"s OOP in favour of proper C structures.
29271+ *
29272+ * Revision 1.11 2005/04/29 05:10:22 mcr
29273+ * removed from extraenous includes to make unit testing easier.
29274+ *
29275+ * Revision 1.10 2005/04/17 04:36:14 mcr
29276+ * code now deals with ESP and UDP-ESP code.
29277+ *
29278+ * Revision 1.9 2005/04/15 19:52:30 mcr
29279+ * adjustments to use proper skb fields for data.
29280+ *
29281+ * Revision 1.8 2004/09/14 00:22:57 mcr
29282+ * adjustment of MD5* functions.
29283+ *
29284+ * Revision 1.7 2004/09/13 02:23:01 mcr
29285+ * #define inet_protocol if necessary.
29286+ *
29287+ * Revision 1.6 2004/09/06 18:35:49 mcr
29288+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
29289+ * so adjust for that.
29290+ *
29291+ * Revision 1.5 2004/08/17 03:27:23 mcr
29292+ * klips 2.6 edits.
29293+ *
29294+ * Revision 1.4 2004/08/04 15:57:07 mcr
29295+ * moved des .h files to include/des/ *
29296+ * included 2.6 protocol specific things
29297+ * started at NAT-T support, but it will require a kernel patch.
29298+ *
29299+ * Revision 1.3 2004/07/10 19:11:18 mcr
29300+ * CONFIG_IPSEC -> CONFIG_KLIPS.
29301+ *
29302+ * Revision 1.2 2004/04/06 02:49:25 mcr
29303+ * pullup of algo code from alg-branch.
29304+ *
29305+ *
29306+ *
29307+ */
29308--- /dev/null Tue Mar 11 13:02:56 2003
29309+++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004
29310@@ -0,0 +1,641 @@
29311+/*
29312+ * @(#) Initialization code.
29313+ * Copyright (C) 1996, 1997 John Ioannidis.
29314+ * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org>
29315+ * 2001 - 2004 Michael Richardson <mcr@xelerance.com>
29316+ *
29317+ * This program is free software; you can redistribute it and/or modify it
29318+ * under the terms of the GNU General Public License as published by the
29319+ * Free Software Foundation; either version 2 of the License, or (at your
29320+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29321+ *
29322+ * This program is distributed in the hope that it will be useful, but
29323+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29324+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29325+ * for more details.
29326+ *
29327+ * /proc system code was split out into ipsec_proc.c after rev. 1.70.
29328+ *
29329+ */
29330+
29331+char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.104.2.6 2007-11-16 03:31:52 paul Exp $";
29332+
29333+#ifndef AUTOCONF_INCLUDED
29334+#include <linux/config.h>
29335+#endif
29336+#include <linux/version.h>
29337+#include <linux/module.h>
29338+#include <linux/kernel.h> /* printk() */
29339+
29340+#include "openswan/ipsec_param.h"
29341+
29342+#ifdef MALLOC_SLAB
29343+# include <linux/slab.h> /* kmalloc() */
29344+#else /* MALLOC_SLAB */
29345+# include <linux/malloc.h> /* kmalloc() */
29346+#endif /* MALLOC_SLAB */
29347+#include <linux/errno.h> /* error codes */
29348+#include <linux/types.h> /* size_t */
29349+#include <linux/interrupt.h> /* mark_bh */
29350+
29351+#include <linux/netdevice.h> /* struct device, and other headers */
29352+#include <linux/etherdevice.h> /* eth_type_trans */
29353+#include <linux/ip.h> /* struct iphdr */
29354+#include <linux/in.h> /* struct sockaddr_in */
29355+#include <linux/skbuff.h>
29356+#include <linux/random.h> /* get_random_bytes() */
29357+#include <net/protocol.h>
29358+
29359+#include <openswan.h>
29360+
29361+#ifdef SPINLOCK
29362+# ifdef SPINLOCK_23
29363+# include <linux/spinlock.h> /* *lock* */
29364+# else /* 23_SPINLOCK */
29365+# include <asm/spinlock.h> /* *lock* */
29366+# endif /* 23_SPINLOCK */
29367+#endif /* SPINLOCK */
29368+
29369+#include <net/ip.h>
29370+
29371+#ifdef CONFIG_PROC_FS
29372+# include <linux/proc_fs.h>
29373+#endif /* CONFIG_PROC_FS */
29374+
29375+#ifdef NETLINK_SOCK
29376+# include <linux/netlink.h>
29377+#else
29378+# include <net/netlink.h>
29379+#endif
29380+
29381+#include "openswan/radij.h"
29382+
29383+#include "openswan/ipsec_life.h"
29384+#include "openswan/ipsec_stats.h"
29385+#include "openswan/ipsec_sa.h"
29386+
29387+#include "openswan/ipsec_encap.h"
29388+#include "openswan/ipsec_radij.h"
29389+#include "openswan/ipsec_xform.h"
29390+#include "openswan/ipsec_tunnel.h"
29391+
29392+#include "openswan/ipsec_rcv.h"
29393+#include "openswan/ipsec_xmit.h"
29394+#include "openswan/ipsec_ah.h"
29395+#include "openswan/ipsec_esp.h"
29396+
29397+#ifdef CONFIG_KLIPS_IPCOMP
29398+# include "openswan/ipcomp.h"
29399+#endif /* CONFIG_KLIPS_IPCOMP */
29400+
29401+#include "openswan/ipsec_proto.h"
29402+#include "openswan/ipsec_alg.h"
29403+
29404+#include <pfkeyv2.h>
29405+#include <pfkey.h>
29406+
29407+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29408+#include <net/xfrmudp.h>
29409+#endif
29410+
29411+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(HAVE_XFRM4_UDP_REGISTER)
29412+#warning "You are trying to build KLIPS2.6 with NAT-T support, but you did not"
29413+#error "properly apply the NAT-T patch to your 2.6 kernel source tree."
29414+#endif
29415+
29416+#if !defined(CONFIG_KLIPS_ESP) && !defined(CONFIG_KLIPS_AH)
29417+#error "kernel configuration must include ESP or AH"
29418+#endif
29419+
29420+/*
29421+ * seems to be present in 2.4.10 (Linus), but also in some RH and other
29422+ * distro kernels of a lower number.
29423+ */
29424+#ifdef MODULE_LICENSE
29425+MODULE_LICENSE("GPL");
29426+#endif
29427+
29428+#ifdef CONFIG_KLIPS_DEBUG
29429+int debug_eroute = 0;
29430+int debug_spi = 0;
29431+int debug_netlink = 0;
29432+#endif /* CONFIG_KLIPS_DEBUG */
29433+
29434+struct prng ipsec_prng;
29435+
29436+
29437+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29438+xfrm4_rcv_encap_t klips_old_encap = NULL;
29439+#endif
29440+
29441+extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
29442+/*
29443+ * the following structure is required so that we receive
29444+ * event notifications when network devices are enabled and
29445+ * disabled (ifconfig up and down).
29446+ */
29447+static struct notifier_block ipsec_dev_notifier={
29448+ ipsec_device_event,
29449+ NULL,
29450+ 0
29451+};
29452+
29453+#ifdef CONFIG_SYSCTL
29454+extern int ipsec_sysctl_register(void);
29455+extern void ipsec_sysctl_unregister(void);
29456+#endif
29457+
29458+/*
29459+ * inet_*_protocol returns void on 2.4.x, int on 2.6.x
29460+ * So we need our own wrapper
29461+ */
29462+#if defined(NET_26) || defined(IPSKB_XFRM_TUNNEL_SIZE)
29463+static inline int
29464+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol,char *protstr)
29465+{
29466+ int err = inet_add_protocol(prot, protocol);
29467+ if (err)
29468+ printk(KERN_ERR "KLIPS: can not register %s protocol - recompile with CONFIG_INET_%s disabled or as module\n", protstr,protstr);
29469+ return err;
29470+
29471+}
29472+
29473+static inline int
29474+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
29475+{
29476+ return inet_del_protocol(prot, protocol);
29477+}
29478+
29479+#else
29480+static inline int
29481+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol, char *protstr)
29482+{
29483+ inet_add_protocol(prot);
29484+ return 0;
29485+}
29486+
29487+static inline int
29488+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
29489+{
29490+ inet_del_protocol(prot);
29491+ return 0;
29492+}
29493+
29494+#endif
29495+
29496+/* void */
29497+int
29498+ipsec_klips_init(void)
29499+{
29500+ int error = 0;
29501+ unsigned char seed[256];
29502+#ifdef CONFIG_KLIPS_ENC_3DES
29503+ extern int des_check_key;
29504+
29505+ /* turn off checking of keys */
29506+ des_check_key=0;
29507+#endif /* CONFIG_KLIPS_ENC_3DES */
29508+
29509+ KLIPS_PRINT(1, "klips_info:ipsec_init: "
29510+ "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n",
29511+ ipsec_version_code());
29512+
29513+ error |= ipsec_proc_init();
29514+
29515+#ifdef SPINLOCK
29516+ ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
29517+#else /* SPINLOCK */
29518+ ipsec_sadb.sadb_lock = 0;
29519+#endif /* SPINLOCK */
29520+
29521+#ifndef SPINLOCK
29522+ tdb_lock.lock = 0;
29523+ eroute_lock.lock = 0;
29524+#endif /* !SPINLOCK */
29525+
29526+ error |= ipsec_sadb_init();
29527+ error |= ipsec_radijinit();
29528+
29529+ error |= pfkey_init();
29530+
29531+ error |= register_netdevice_notifier(&ipsec_dev_notifier);
29532+
29533+#ifdef CONFIG_KLIPS_ESP
29534+ error |= openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP,"ESP");
29535+#endif /* CONFIG_KLIPS_ESP */
29536+
29537+#ifdef CONFIG_KLIPS_AH
29538+ error |= openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH,"AH");
29539+#endif /* CONFIG_KLIPS_AH */
29540+
29541+/* we never actually link IPCOMP to the stack */
29542+#ifdef IPCOMP_USED_ALONE
29543+#ifdef CONFIG_KLIPS_IPCOMP
29544+ error |= openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP,"IPCOMP");
29545+#endif /* CONFIG_KLIPS_IPCOMP */
29546+#endif
29547+
29548+ error |= ipsec_tunnel_init_devices();
29549+
29550+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29551+ /* register our ESP-UDP handler */
29552+ if(udp4_register_esp_rcvencap(klips26_rcv_encap
29553+ , &klips_old_encap)!=0) {
29554+ printk(KERN_ERR "KLIPS: can not register klips_rcv_encap function\n");
29555+ }
29556+#endif
29557+
29558+
29559+#ifdef CONFIG_SYSCTL
29560+ error |= ipsec_sysctl_register();
29561+#endif
29562+
29563+#ifdef CONFIG_KLIPS_ALG
29564+ ipsec_alg_init();
29565+#endif
29566+
29567+ get_random_bytes((void *)seed, sizeof(seed));
29568+ prng_init(&ipsec_prng, seed, sizeof(seed));
29569+
29570+ return error;
29571+}
29572+
29573+
29574+/* void */
29575+int
29576+ipsec_cleanup(void)
29577+{
29578+ int error = 0;
29579+
29580+#ifdef CONFIG_SYSCTL
29581+ ipsec_sysctl_unregister();
29582+#endif
29583+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29584+ if(udp4_unregister_esp_rcvencap(klips_old_encap) < 0) {
29585+ printk(KERN_ERR "KLIPS: can not unregister klips_rcv_encap function\n");
29586+ }
29587+#endif
29588+
29589+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29590+ "klips_debug:ipsec_cleanup: "
29591+ "calling ipsec_tunnel_cleanup_devices.\n");
29592+ error |= ipsec_tunnel_cleanup_devices();
29593+
29594+ KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
29595+
29596+/* we never actually link IPCOMP to the stack */
29597+#ifdef IPCOMP_USED_ALONE
29598+#ifdef CONFIG_KLIPS_IPCOMP
29599+ if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
29600+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29601+ "comp close: can't remove protocol\n");
29602+#endif /* CONFIG_KLIPS_IPCOMP */
29603+#endif /* IPCOMP_USED_ALONE */
29604+
29605+#ifdef CONFIG_KLIPS_AH
29606+ if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
29607+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29608+ "ah close: can't remove protocol\n");
29609+#endif /* CONFIG_KLIPS_AH */
29610+
29611+#ifdef CONFIG_KLIPS_ESP
29612+ if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0)
29613+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29614+ "esp close: can't remove protocol\n");
29615+#endif /* CONFIG_KLIPS_ESP */
29616+
29617+ error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
29618+
29619+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29620+ "klips_debug:ipsec_cleanup: "
29621+ "calling ipsec_sadb_cleanup.\n");
29622+ error |= ipsec_sadb_cleanup(0);
29623+ error |= ipsec_sadb_free();
29624+
29625+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29626+ "klips_debug:ipsec_cleanup: "
29627+ "calling ipsec_radijcleanup.\n");
29628+ error |= ipsec_radijcleanup();
29629+
29630+ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
29631+ "klips_debug:ipsec_cleanup: "
29632+ "calling pfkey_cleanup.\n");
29633+ error |= pfkey_cleanup();
29634+
29635+ ipsec_proc_cleanup();
29636+
29637+ prng_final(&ipsec_prng);
29638+
29639+ return error;
29640+}
29641+
29642+#ifdef MODULE
29643+int
29644+init_module(void)
29645+{
29646+ int error = 0;
29647+
29648+ error |= ipsec_klips_init();
29649+ /*if (error)
29650+ ipsec_cleanup();
29651+ */
29652+ return error;
29653+}
29654+
29655+void
29656+cleanup_module(void)
29657+{
29658+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29659+ "klips_debug:cleanup_module: "
29660+ "calling ipsec_cleanup.\n");
29661+
29662+ ipsec_cleanup();
29663+
29664+ KLIPS_PRINT(1, "klips_info:cleanup_module: "
29665+ "ipsec module unloaded.\n");
29666+}
29667+#endif /* MODULE */
29668+
29669+/*
29670+ * $Log: ipsec_init.c,v $
29671+ * Revision 1.104.2.6 2007-11-16 03:31:52 paul
29672+ * Added log message to openswan_inet_add_protocol() if we fail to register
29673+ * our protocol with KLIPS (eg ESP because esp4 module is already loaded).
29674+ * We didnt notice this failure before. We now return a proper error, but
29675+ *
29676+ * TODO:
29677+ *
29678+ * we still need to do a beter cleanup, as we're leaving files in /proc.
29679+ * (calling cleanup_module() from init_module() if we see an error caused
29680+ * its own kernel oopses).
29681+ *
29682+ * Revision 1.104.2.5 2007/09/05 02:36:57 paul
29683+ * include ipsec_init.h. Added an ifdef. Patch by David McCullough
29684+ *
29685+ * Revision 1.104.2.4 2006/10/06 21:39:26 paul
29686+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
29687+ * set. This is defined through autoconf.h which is included through the
29688+ * linux kernel build macros.
29689+ *
29690+ * Revision 1.104.2.3 2006/07/31 15:25:20 paul
29691+ * Check for NETKEY backport in Debian using IPSKB_XFRM_TUNNEL_SIZE to
29692+ * determine wether inet_add_protocol needs the protocol argument.
29693+ *
29694+ * Revision 1.104.2.2 2006/04/20 16:33:06 mcr
29695+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
29696+ * Fix in-kernel module compilation. Sub-makefiles do not work.
29697+ *
29698+ * Revision 1.104.2.1 2005/08/12 01:18:20 ken
29699+ * Warn people who don't have NAT-T patch applied, but try and compile NAT-T code
29700+ *
29701+ * Revision 1.105 2005/08/12 00:56:33 mcr
29702+ * add warning for people who didn't apply nat-t patch.
29703+ *
29704+ * Revision 1.104 2005/07/08 15:51:41 mcr
29705+ * removed duplicate NAT-T code.
29706+ * if CONFIG_IPSEC_NAT_TRAVERSAL isn't defined, then there is no issue.
29707+ *
29708+ * Revision 1.103 2005/07/08 03:02:05 paul
29709+ * Fixed garbled define that accidentally got commited to the real tree.
29710+ *
29711+ * Revision 1.102 2005/07/08 02:56:37 paul
29712+ * gcc4 fixes that were not commited because vault was down
29713+ *
29714+ * Revision 1.101 2005/04/29 05:10:22 mcr
29715+ * removed from extraenous includes to make unit testing easier.
29716+ *
29717+ * Revision 1.100 2005/04/10 22:56:09 mcr
29718+ * change to udp.c registration API.
29719+ *
29720+ * Revision 1.99 2005/04/08 18:26:13 mcr
29721+ * register with udp.c, the klips26 encap receive function
29722+ *
29723+ * Revision 1.98 2004/09/13 02:23:18 mcr
29724+ * #define inet_protocol if necessary.
29725+ *
29726+ * Revision 1.97 2004/09/06 18:35:49 mcr
29727+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
29728+ * so adjust for that.
29729+ *
29730+ * Revision 1.96 2004/08/17 03:27:23 mcr
29731+ * klips 2.6 edits.
29732+ *
29733+ * Revision 1.95 2004/08/03 18:19:08 mcr
29734+ * in 2.6, use "net_device" instead of #define device->net_device.
29735+ * this probably breaks 2.0 compiles.
29736+ *
29737+ * Revision 1.94 2004/07/10 19:11:18 mcr
29738+ * CONFIG_IPSEC -> CONFIG_KLIPS.
29739+ *
29740+ * Revision 1.93 2004/04/06 02:49:26 mcr
29741+ * pullup of algo code from alg-branch.
29742+ *
29743+ * Revision 1.92 2004/03/30 15:30:39 ken
29744+ * Proper Capitalization
29745+ *
29746+ * Revision 1.91 2004/03/22 01:51:51 ken
29747+ * We are open
29748+ *
29749+ * Revision 1.90.4.2 2004/04/05 04:30:46 mcr
29750+ * patches for alg-branch to compile/work with 2.x openswan
29751+ *
29752+ * Revision 1.90.4.1 2003/12/22 15:25:52 jjo
29753+ * Merged algo-0.8.1-rc11-test1 into alg-branch
29754+ *
29755+ * Revision 1.90 2003/10/31 02:27:55 mcr
29756+ * pulled up port-selector patches and sa_id elimination.
29757+ *
29758+ * Revision 1.89.4.1 2003/10/29 01:30:41 mcr
29759+ * elimited "struct sa_id".
29760+ *
29761+ * Revision 1.89 2003/07/31 22:47:16 mcr
29762+ * preliminary (untested by FS-team) 2.5 patches.
29763+ *
29764+ * Revision 1.88 2003/06/22 20:05:36 mcr
29765+ * clarified why IPCOMP was not being registered, and put a new
29766+ * #ifdef in rather than #if 0.
29767+ *
29768+ * Revision 1.87 2002/09/20 15:40:51 rgb
29769+ * Added a lock to the global ipsec_sadb struct for future use.
29770+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
29771+ * of freeing newly created structures when clearing the reftable upon startup
29772+ * to start from a known state.
29773+ *
29774+ * Revision 1.86 2002/08/15 18:39:15 rgb
29775+ * Move ipsec_prng outside debug code.
29776+ *
29777+ * Revision 1.85 2002/05/14 02:35:29 rgb
29778+ * Change reference to tdb to ipsa.
29779+ *
29780+ * Revision 1.84 2002/04/24 07:55:32 mcr
29781+ * #include patches and Makefiles for post-reorg compilation.
29782+ *
29783+ * Revision 1.83 2002/04/24 07:36:28 mcr
29784+ * Moved from ./klips/net/ipsec/ipsec_init.c,v
29785+ *
29786+ * Revision 1.82 2002/04/20 00:12:25 rgb
29787+ * Added esp IV CBC attack fix, disabled.
29788+ *
29789+ * Revision 1.81 2002/04/09 16:13:32 mcr
29790+ * switch license to straight GPL.
29791+ *
29792+ * Revision 1.80 2002/03/24 07:34:08 rgb
29793+ * Sanity check for at least one of AH or ESP configured.
29794+ *
29795+ * Revision 1.79 2002/02/05 22:55:15 mcr
29796+ * added MODULE_LICENSE declaration.
29797+ * This macro does not appear in all kernel versions (see comment).
29798+ *
29799+ * Revision 1.78 2002/01/29 17:17:55 mcr
29800+ * moved include of ipsec_param.h to after include of linux/kernel.h
29801+ * otherwise, it seems that some option that is set in ipsec_param.h
29802+ * screws up something subtle in the include path to kernel.h, and
29803+ * it complains on the snprintf() prototype.
29804+ *
29805+ * Revision 1.77 2002/01/29 04:00:51 mcr
29806+ * more excise of kversions.h header.
29807+ *
29808+ * Revision 1.76 2002/01/29 02:13:17 mcr
29809+ * introduction of ipsec_kversion.h means that include of
29810+ * ipsec_param.h must preceed any decisions about what files to
29811+ * include to deal with differences in kernel source.
29812+ *
29813+ * Revision 1.75 2001/11/26 09:23:48 rgb
29814+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
29815+ *
29816+ * Revision 1.74 2001/11/22 05:44:11 henry
29817+ * new version stuff
29818+ *
29819+ * Revision 1.71.2.2 2001/10/22 20:51:00 mcr
29820+ * explicitely set des_check_key.
29821+ *
29822+ * Revision 1.71.2.1 2001/09/25 02:19:39 mcr
29823+ * /proc manipulation code moved to new ipsec_proc.c
29824+ *
29825+ * Revision 1.73 2001/11/06 19:47:17 rgb
29826+ * Changed lifetime_packets to uint32 from uint64.
29827+ *
29828+ * Revision 1.72 2001/10/18 04:45:19 rgb
29829+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
29830+ * lib/freeswan.h version macros moved to lib/kversions.h.
29831+ * Other compiler directive cleanups.
29832+ *
29833+ * Revision 1.71 2001/09/20 15:32:45 rgb
29834+ * Minor pfkey lifetime fixes.
29835+ *
29836+ * Revision 1.70 2001/07/06 19:51:21 rgb
29837+ * Added inbound policy checking code for IPIP SAs.
29838+ *
29839+ * Revision 1.69 2001/06/14 19:33:26 rgb
29840+ * Silence startup message for console, but allow it to be logged.
29841+ * Update copyright date.
29842+ *
29843+ * Revision 1.68 2001/05/29 05:14:36 rgb
29844+ * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'.
29845+ *
29846+ * Revision 1.67 2001/05/04 16:34:52 rgb
29847+ * Rremove erroneous checking of return codes for proc_net_* in 2.4.
29848+ *
29849+ * Revision 1.66 2001/05/03 19:40:34 rgb
29850+ * Check error return codes in startup and shutdown.
29851+ *
29852+ * Revision 1.65 2001/02/28 05:03:27 rgb
29853+ * Clean up and rationalise startup messages.
29854+ *
29855+ * Revision 1.64 2001/02/27 22:24:53 rgb
29856+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
29857+ * Check for satoa() return codes.
29858+ *
29859+ * Revision 1.63 2000/11/29 20:14:06 rgb
29860+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
29861+ *
29862+ * Revision 1.62 2000/11/06 04:31:24 rgb
29863+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
29864+ * Fixed longlong for pre-2.4 kernels (Svenning).
29865+ * Add Svenning's adaptive content compression.
29866+ * Disabled registration of ipcomp handler.
29867+ *
29868+ * Revision 1.61 2000/10/11 13:37:54 rgb
29869+ * #ifdef out debug print that causes proc/net/ipsec_version to oops.
29870+ *
29871+ * Revision 1.60 2000/09/20 03:59:01 rgb
29872+ * Change static info functions to DEBUG_NO_STATIC to reveal function names
29873+ * in oopsen.
29874+ *
29875+ * Revision 1.59 2000/09/16 01:06:26 rgb
29876+ * Added cast of var to silence compiler warning about long fed to int
29877+ * format.
29878+ *
29879+ * Revision 1.58 2000/09/15 11:37:01 rgb
29880+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
29881+ * IPCOMP zlib deflate code.
29882+ *
29883+ * Revision 1.57 2000/09/12 03:21:50 rgb
29884+ * Moved radij_c_version printing to ipsec_version_get_info().
29885+ * Reformatted ipsec_version_get_info().
29886+ * Added sysctl_{,un}register() calls.
29887+ *
29888+ * Revision 1.56 2000/09/08 19:16:50 rgb
29889+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
29890+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
29891+ *
29892+ * Revision 1.55 2000/08/30 05:19:03 rgb
29893+ * Cleaned up no longer used spi_next, netlink register/unregister, other
29894+ * minor cleanup.
29895+ * Removed cruft replaced by TDB_XFORM_NAME.
29896+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
29897+ * Moved debug version strings to printk when /proc/net/ipsec_version is
29898+ * called.
29899+ *
29900+ * Revision 1.54 2000/08/20 18:31:05 rgb
29901+ * Changed cosmetic alignment in spi_info.
29902+ * Changed addtime and usetime to use actual value which is relative
29903+ * anyways, as intended. (Momchil)
29904+ *
29905+ * Revision 1.53 2000/08/18 17:37:03 rgb
29906+ * Added an (int) cast to shut up the compiler...
29907+ *
29908+ * Revision 1.52 2000/08/01 14:51:50 rgb
29909+ * Removed _all_ remaining traces of DES.
29910+ *
29911+ * Revision 1.51 2000/07/25 20:41:22 rgb
29912+ * Removed duplicate parameter in spi_getinfo.
29913+ *
29914+ * Revision 1.50 2000/07/17 03:21:45 rgb
29915+ * Removed /proc/net/ipsec_spinew.
29916+ *
29917+ * Revision 1.49 2000/06/28 05:46:51 rgb
29918+ * Renamed ivlen to iv_bits for consistency.
29919+ * Changed output of add and use times to be relative to now.
29920+ *
29921+ * Revision 1.48 2000/05/11 18:26:10 rgb
29922+ * Commented out calls to netlink_attach/detach to avoid activating netlink
29923+ * in the kenrel config.
29924+ *
29925+ * Revision 1.47 2000/05/10 22:35:26 rgb
29926+ * Comment out most of the startup version information.
29927+ *
29928+ * Revision 1.46 2000/03/22 16:15:36 rgb
29929+ * Fixed renaming of dev_get (MB).
29930+ *
29931+ * Revision 1.45 2000/03/16 06:40:48 rgb
29932+ * Hardcode PF_KEYv2 support.
29933+ *
29934+ * Revision 1.44 2000/01/22 23:19:20 rgb
29935+ * Simplified code to use existing macro TDB_XFORM_NAME().
29936+ *
29937+ * Revision 1.43 2000/01/21 06:14:04 rgb
29938+ * Print individual stats only if non-zero.
29939+ * Removed 'bits' from each keylength for brevity.
29940+ * Shortened lifetimes legend for brevity.
29941+ * Changed wording from 'last_used' to the clearer 'idle'.
29942+ *
29943+ * Revision 1.42 1999/12/31 14:57:19 rgb
29944+ * MB fix for new dummy-less proc_get_info in 2.3.35.
29945+ *
29946+ *
29947+ * Local variables:
29948+ * c-file-style: "linux"
29949+ * End:
29950+ *
29951+ */
29952--- /dev/null Tue Mar 11 13:02:56 2003
29953+++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004
29954@@ -0,0 +1,256 @@
29955+/*
29956+ * processing code for IPCOMP
29957+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
29958+ *
29959+ * This program is free software; you can redistribute it and/or modify it
29960+ * under the terms of the GNU General Public License as published by the
29961+ * Free Software Foundation; either version 2 of the License, or (at your
29962+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29963+ *
29964+ * This program is distributed in the hope that it will be useful, but
29965+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29966+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29967+ * for more details.
29968+ */
29969+
29970+char ipsec_ipcomp_c_version[] = "RCSID $Id: ipsec_ipcomp.c,v 1.5.2.3 2007-09-05 02:56:09 paul Exp $";
29971+#ifndef AUTOCONF_INCLUDED
29972+#include <linux/config.h>
29973+#endif
29974+#include <linux/version.h>
29975+
29976+#define __NO_VERSION__
29977+#include <linux/module.h>
29978+#include <linux/kernel.h> /* printk() */
29979+
29980+#include "openswan/ipsec_param.h"
29981+
29982+#ifdef MALLOC_SLAB
29983+# include <linux/slab.h> /* kmalloc() */
29984+#else /* MALLOC_SLAB */
29985+# include <linux/malloc.h> /* kmalloc() */
29986+#endif /* MALLOC_SLAB */
29987+#include <linux/errno.h> /* error codes */
29988+#include <linux/types.h> /* size_t */
29989+#include <linux/interrupt.h> /* mark_bh */
29990+
29991+#include <linux/netdevice.h> /* struct device, and other headers */
29992+#include <linux/etherdevice.h> /* eth_type_trans */
29993+#include <linux/ip.h> /* struct iphdr */
29994+#include <linux/skbuff.h>
29995+#include <openswan.h>
29996+#ifdef SPINLOCK
29997+# ifdef SPINLOCK_23
29998+# include <linux/spinlock.h> /* *lock* */
29999+# else /* SPINLOCK_23 */
30000+# include <asm/spinlock.h> /* *lock* */
30001+# endif /* SPINLOCK_23 */
30002+#endif /* SPINLOCK */
30003+
30004+#include <net/ip.h>
30005+
30006+#include "openswan/radij.h"
30007+#include "openswan/ipsec_encap.h"
30008+#include "openswan/ipsec_sa.h"
30009+
30010+#include "openswan/ipsec_radij.h"
30011+#include "openswan/ipsec_xform.h"
30012+#include "openswan/ipsec_tunnel.h"
30013+#include "openswan/ipsec_rcv.h"
30014+#include "openswan/ipsec_xmit.h"
30015+
30016+#include "openswan/ipsec_auth.h"
30017+
30018+#ifdef CONFIG_KLIPS_IPCOMP
30019+#include "openswan/ipsec_ipcomp.h"
30020+#endif /* CONFIG_KLIPS_IPCOMP */
30021+
30022+#include "openswan/ipsec_proto.h"
30023+
30024+#ifdef CONFIG_KLIPS_DEBUG
30025+int debug_ipcomp = 0;
30026+#endif /* CONFIG_KLIPS_DEBUG */
30027+
30028+
30029+#ifdef CONFIG_KLIPS_IPCOMP
30030+enum ipsec_rcv_value
30031+ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
30032+ struct sk_buff *skb)
30033+{
30034+ int ipcompminlen;
30035+
30036+ ipcompminlen = sizeof(struct iphdr);
30037+
30038+ if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
30039+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
30040+ "klips_debug:ipsec_rcv: "
30041+ "runt comp packet of skb->len=%d received from %s, dropped.\n",
30042+ skb->len,
30043+ irs->ipsaddr_txt);
30044+ if(irs->stats) {
30045+ irs->stats->rx_errors++;
30046+ }
30047+ return IPSEC_RCV_BADLEN;
30048+ }
30049+
30050+ irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)skb_transport_header(skb);
30051+ irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
30052+ return IPSEC_RCV_OK;
30053+}
30054+
30055+enum ipsec_rcv_value
30056+ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
30057+{
30058+ unsigned int flags = 0;
30059+ struct ipsec_sa *ipsp = irs->ipsp;
30060+ struct sk_buff *skb;
30061+
30062+ skb=irs->skb;
30063+
30064+ ipsec_xmit_dmp("ipcomp", skb_transport_header(skb), skb->len);
30065+
30066+ if(ipsp == NULL) {
30067+ return IPSEC_RCV_SAIDNOTFOUND;
30068+ }
30069+
30070+ if(sysctl_ipsec_inbound_policy_check &&
30071+ ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
30072+ (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */
30073+ ))) {
30074+ char sa2[SATOT_BUF];
30075+ size_t sa_len2 = 0;
30076+
30077+ sa_len2 = KLIPS_SATOT(debug_rcv, &ipsp->ips_said, 0, sa2, sizeof(sa2));
30078+
30079+ KLIPS_PRINT(debug_rcv,
30080+ "klips_debug:ipsec_rcv: "
30081+ "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",
30082+ irs->sa_len ? irs->sa : " (error)",
30083+ ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
30084+ ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
30085+ (__u32)ntohl(irs->said.spi),
30086+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
30087+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
30088+ if(irs->stats) {
30089+ irs->stats->rx_dropped++;
30090+ }
30091+ return IPSEC_RCV_SAIDNOTFOUND;
30092+ }
30093+
30094+ ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
30095+ irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
30096+
30097+ skb = skb_decompress(skb, ipsp, &flags);
30098+ if (!skb || flags) {
30099+ spin_unlock(&tdb_lock);
30100+ KLIPS_PRINT(debug_rcv,
30101+ "klips_debug:ipsec_rcv: "
30102+ "skb_decompress() returned error flags=%x, dropped.\n",
30103+ flags);
30104+ if (irs->stats) {
30105+ if (flags)
30106+ irs->stats->rx_errors++;
30107+ else
30108+ irs->stats->rx_dropped++;
30109+ }
30110+ return IPSEC_RCV_IPCOMPFAILED;
30111+ }
30112+
30113+ /* make sure we update the pointer */
30114+ irs->skb = skb;
30115+
30116+#ifdef NET_21
30117+ irs->ipp = ip_hdr(skb);
30118+#else /* NET_21 */
30119+ irs->ipp = skb->ip_hdr;
30120+#endif /* NET_21 */
30121+
30122+ ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
30123+
30124+ KLIPS_PRINT(debug_rcv,
30125+ "klips_debug:ipsec_rcv: "
30126+ "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
30127+ irs->sa_len ? irs->sa : " (error)",
30128+ (__u32)ntohl(irs->said.spi),
30129+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
30130+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
30131+ irs->next_header);
30132+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
30133+
30134+ return IPSEC_RCV_OK;
30135+}
30136+
30137+enum ipsec_xmit_value
30138+ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
30139+{
30140+ unsigned int flags = 0;
30141+#ifdef CONFIG_KLIPS_DEBUG
30142+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
30143+#endif /* CONFIG_KLIPS_DEBUG */
30144+
30145+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
30146+
30147+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
30148+
30149+#ifdef NET_21
30150+ ixs->iph = ip_hdr(ixs->skb);
30151+#else /* NET_21 */
30152+ ixs->iph = ixs->skb->ip_hdr;
30153+#endif /* NET_21 */
30154+
30155+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
30156+
30157+#ifdef CONFIG_KLIPS_DEBUG
30158+ if (debug_tunnel & DB_TN_CROUT)
30159+ {
30160+ if (old_tot_len > ntohs(ixs->iph->tot_len))
30161+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
30162+ "klips_debug:ipsec_xmit_encap_once: "
30163+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
30164+ old_tot_len, ntohs(ixs->iph->tot_len),
30165+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
30166+ ntohl(ixs->ipsp->ips_said.spi),
30167+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
30168+ else
30169+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
30170+ "klips_debug:ipsec_xmit_encap_once: "
30171+ "packet did not compress (flags = %d).\n",
30172+ flags);
30173+ }
30174+#endif /* CONFIG_KLIPS_DEBUG */
30175+
30176+ return IPSEC_XMIT_OK;
30177+}
30178+
30179+struct xform_functions ipcomp_xform_funcs[]={
30180+ {rcv_checks: ipsec_rcv_ipcomp_checks,
30181+ rcv_decrypt: ipsec_rcv_ipcomp_decomp,
30182+ xmit_setup: ipsec_xmit_ipcomp_setup,
30183+ xmit_headroom: 0,
30184+ xmit_needtailroom: 0,
30185+ },
30186+};
30187+
30188+#if 0
30189+/* We probably don't want to install a pure IPCOMP protocol handler, but
30190+ only want to handle IPCOMP if it is encapsulated inside an ESP payload
30191+ (which is already handled) */
30192+#ifdef CONFIG_KLIPS_IPCOMP
30193+struct inet_protocol comp_protocol =
30194+{
30195+ ipsec_rcv, /* COMP handler */
30196+ NULL, /* COMP error control */
30197+#ifdef NETDEV_25
30198+ 1, /* no policy */
30199+#else
30200+ 0, /* next */
30201+ IPPROTO_COMP, /* protocol ID */
30202+ 0, /* copy */
30203+ NULL, /* data */
30204+ "COMP" /* name */
30205+#endif
30206+};
30207+#endif /* CONFIG_KLIPS_IPCOMP */
30208+#endif
30209+
30210+#endif /* CONFIG_KLIPS_IPCOMP */
30211--- /dev/null Tue Mar 11 13:02:56 2003
30212+++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004
30213@@ -0,0 +1,122 @@
30214+/*
30215+ * processing code for IPIP
30216+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
30217+ *
30218+ * This program is free software; you can redistribute it and/or modify it
30219+ * under the terms of the GNU General Public License as published by the
30220+ * Free Software Foundation; either version 2 of the License, or (at your
30221+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30222+ *
30223+ * This program is distributed in the hope that it will be useful, but
30224+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30225+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30226+ * for more details.
30227+ */
30228+
30229+char ipsec_ipip_c_version[] = "RCSID $Id: ipsec_ipip.c,v 1.3.2.4 2007-09-05 02:56:09 paul Exp $";
30230+#ifndef AUTOCONF_INCLUDED
30231+#include <linux/config.h>
30232+#endif
30233+#include <linux/version.h>
30234+
30235+#define __NO_VERSION__
30236+#include <linux/module.h>
30237+#include <linux/kernel.h> /* printk() */
30238+
30239+#include "openswan/ipsec_param.h"
30240+
30241+#ifdef MALLOC_SLAB
30242+# include <linux/slab.h> /* kmalloc() */
30243+#else /* MALLOC_SLAB */
30244+# include <linux/malloc.h> /* kmalloc() */
30245+#endif /* MALLOC_SLAB */
30246+#include <linux/errno.h> /* error codes */
30247+#include <linux/types.h> /* size_t */
30248+#include <linux/interrupt.h> /* mark_bh */
30249+
30250+#include <linux/netdevice.h> /* struct device, and other headers */
30251+#include <linux/etherdevice.h> /* eth_type_trans */
30252+#include <linux/ip.h> /* struct iphdr */
30253+#include <linux/skbuff.h>
30254+#include <openswan.h>
30255+#ifdef SPINLOCK
30256+# ifdef SPINLOCK_23
30257+# include <linux/spinlock.h> /* *lock* */
30258+# else /* SPINLOCK_23 */
30259+# include <asm/spinlock.h> /* *lock* */
30260+# endif /* SPINLOCK_23 */
30261+#endif /* SPINLOCK */
30262+
30263+#include <net/ip.h>
30264+
30265+#include "openswan/radij.h"
30266+#include "openswan/ipsec_encap.h"
30267+#include "openswan/ipsec_sa.h"
30268+
30269+#include "openswan/ipsec_radij.h"
30270+#include "openswan/ipsec_xform.h"
30271+#include "openswan/ipsec_tunnel.h"
30272+#include "openswan/ipsec_rcv.h"
30273+#include "openswan/ipsec_xmit.h"
30274+
30275+#include "openswan/ipsec_auth.h"
30276+#include "openswan/ipsec_ipip.h"
30277+#include "openswan/ipsec_param.h"
30278+
30279+#include "openswan/ipsec_proto.h"
30280+
30281+enum ipsec_xmit_value
30282+ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
30283+{
30284+ ixs->iph->version = 4;
30285+
30286+ switch(sysctl_ipsec_tos) {
30287+ case 0:
30288+#ifdef NET_21
30289+ ixs->iph->tos = ip_hdr(ixs->skb)->tos;
30290+#else /* NET_21 */
30291+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
30292+#endif /* NET_21 */
30293+ break;
30294+ case 1:
30295+ ixs->iph->tos = 0;
30296+ break;
30297+ default:
30298+ break;
30299+ }
30300+ ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
30301+ ixs->iph->frag_off = 0;
30302+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
30303+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
30304+ ixs->iph->protocol = IPPROTO_IPIP;
30305+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
30306+
30307+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
30308+
30309+ ixs->newdst = (__u32)ixs->iph->daddr;
30310+ ixs->newsrc = (__u32)ixs->iph->saddr;
30311+
30312+#ifdef NET_21
30313+ skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, ip_hdr(ixs->skb)));
30314+#endif /* NET_21 */
30315+ return IPSEC_XMIT_OK;
30316+}
30317+
30318+struct xform_functions ipip_xform_funcs[]={
30319+ { rcv_checks: NULL,
30320+ rcv_setup_auth: NULL,
30321+ rcv_calc_auth: NULL,
30322+ rcv_decrypt: NULL,
30323+
30324+ xmit_setup: ipsec_xmit_ipip_setup,
30325+ xmit_headroom: sizeof(struct iphdr),
30326+ xmit_needtailroom: 0,
30327+ },
30328+};
30329+
30330+
30331+
30332+
30333+
30334+
30335+
30336--- /dev/null Tue Mar 11 13:02:56 2003
30337+++ linux/net/ipsec/ipsec_kern24.c Mon Feb 9 13:51:03 2004
30338@@ -0,0 +1,74 @@
30339+/*
30340+ * Copyright 2005 (C) Michael Richardson <mcr@xelerance.com>
30341+ *
30342+ * This is a file of functions which are present in 2.6 kernels,
30343+ * but are not available by default in the 2.4 series.
30344+ *
30345+ * As such this code is usually from the Linux kernel, and is covered by
30346+ * GPL.
30347+ *
30348+ * This program is free software; you can redistribute it and/or modify it
30349+ * under the terms of the GNU General Public License as published by the
30350+ * Free Software Foundation; either version 2 of the License, or (at your
30351+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30352+ *
30353+ * This program is distributed in the hope that it will be useful, but
30354+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30355+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30356+ * for more details.
30357+ *
30358+ * $Id: ipsec_kern24.c,v 1.2 2005-05-20 03:19:18 mcr Exp $
30359+ *
30360+ */
30361+
30362+#include <linux/kernel.h>
30363+#include <linux/mm.h>
30364+#include <linux/spinlock.h>
30365+
30366+/*
30367+ * printk rate limiting, lifted from the networking subsystem.
30368+ *
30369+ * This enforces a rate limit: not more than one kernel message
30370+ * every printk_ratelimit_jiffies to make a denial-of-service
30371+ * attack impossible.
30372+ */
30373+static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
30374+
30375+int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
30376+{
30377+ static unsigned long toks = 10*5*HZ;
30378+ static unsigned long last_msg;
30379+ static int missed;
30380+ unsigned long flags;
30381+ unsigned long now = jiffies;
30382+
30383+ spin_lock_irqsave(&ratelimit_lock, flags);
30384+ toks += now - last_msg;
30385+ last_msg = now;
30386+ if (toks > (ratelimit_burst * ratelimit_jiffies))
30387+ toks = ratelimit_burst * ratelimit_jiffies;
30388+ if (toks >= ratelimit_jiffies) {
30389+ int lost = missed;
30390+ missed = 0;
30391+ toks -= ratelimit_jiffies;
30392+ spin_unlock_irqrestore(&ratelimit_lock, flags);
30393+ if (lost)
30394+ printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
30395+ return 1;
30396+ }
30397+ missed++;
30398+ spin_unlock_irqrestore(&ratelimit_lock, flags);
30399+ return 0;
30400+}
30401+
30402+/* minimum time in jiffies between messages */
30403+int printk_ratelimit_jiffies = 5*HZ;
30404+
30405+/* number of messages we send before ratelimiting */
30406+int printk_ratelimit_burst = 10;
30407+
30408+int printk_ratelimit(void)
30409+{
30410+ return __printk_ratelimit(printk_ratelimit_jiffies,
30411+ printk_ratelimit_burst);
30412+}
30413--- /dev/null Tue Mar 11 13:02:56 2003
30414+++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004
30415@@ -0,0 +1,277 @@
30416+/*
30417+ * @(#) lifetime structure utilities
30418+ *
30419+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
30420+ * and Michael Richardson <mcr@freeswan.org>
30421+ *
30422+ * This program is free software; you can redistribute it and/or modify it
30423+ * under the terms of the GNU General Public License as published by the
30424+ * Free Software Foundation; either version 2 of the License, or (at your
30425+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30426+ *
30427+ * This program is distributed in the hope that it will be useful, but
30428+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30429+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30430+ * for more details.
30431+ *
30432+ * RCSID $Id: ipsec_life.c,v 1.13.10.2 2007-09-05 02:39:38 paul Exp $
30433+ *
30434+ */
30435+
30436+/*
30437+ * This provides series of utility functions for dealing with lifetime
30438+ * structures.
30439+ *
30440+ * ipsec_check_lifetime - returns -1 hard lifetime exceeded
30441+ * 0 soft lifetime exceeded
30442+ * 1 everything is okay
30443+ * based upon whether or not the count exceeds hard/soft
30444+ *
30445+ */
30446+
30447+#define __NO_VERSION__
30448+#include <linux/module.h>
30449+#ifndef AUTOCONF_INCLUDED
30450+#include <linux/config.h>
30451+#endif /* for CONFIG_IP_FORWARD */
30452+#include <linux/version.h>
30453+#include <linux/kernel.h> /* printk() */
30454+
30455+#include "openswan/ipsec_param.h"
30456+
30457+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
30458+#include <linux/etherdevice.h> /* eth_type_trans */
30459+#include <linux/skbuff.h>
30460+#include <linux/ip.h>
30461+#include <openswan.h>
30462+
30463+#include "openswan/radij.h"
30464+#include "openswan/ipsec_life.h"
30465+#include "openswan/ipsec_xform.h"
30466+#include "openswan/ipsec_eroute.h"
30467+#include "openswan/ipsec_encap.h"
30468+#include "openswan/ipsec_radij.h"
30469+
30470+#include "openswan/ipsec_sa.h"
30471+#include "openswan/ipsec_tunnel.h"
30472+#include "openswan/ipsec_ipe4.h"
30473+#include "openswan/ipsec_ah.h"
30474+#include "openswan/ipsec_esp.h"
30475+
30476+#ifdef CONFIG_KLIPS_IPCOMP
30477+#include "openswan/ipcomp.h"
30478+#endif /* CONFIG_KLIPS_IPCOMP */
30479+
30480+#include <pfkeyv2.h>
30481+#include <pfkey.h>
30482+
30483+#include "openswan/ipsec_proto.h"
30484+
30485+
30486+enum ipsec_life_alive
30487+ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
30488+ const char *lifename,
30489+ const char *saname,
30490+ enum ipsec_life_type ilt,
30491+ enum ipsec_direction idir,
30492+ struct ipsec_sa *ips)
30493+{
30494+ __u64 count;
30495+ const char *dir;
30496+
30497+ if(saname == NULL) {
30498+ saname = "unknown-SA";
30499+ }
30500+
30501+ if(idir == ipsec_incoming) {
30502+ dir = "incoming";
30503+ } else {
30504+ dir = "outgoing";
30505+ }
30506+
30507+
30508+ if(ilt == ipsec_life_timebased) {
30509+ count = jiffies/HZ - il64->ipl_count;
30510+ } else {
30511+ count = il64->ipl_count;
30512+ }
30513+
30514+ if(il64->ipl_hard &&
30515+ (count > il64->ipl_hard)) {
30516+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
30517+ "klips_debug:ipsec_lifetime_check: "
30518+ "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
30519+ "%s packet dropped.\n",
30520+ lifename,
30521+ IPS_XFORM_NAME(ips),
30522+ saname,
30523+ dir);
30524+
30525+ pfkey_expire(ips, 1);
30526+ return ipsec_life_harddied;
30527+ }
30528+
30529+ if(il64->ipl_soft &&
30530+ (count > il64->ipl_soft)) {
30531+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
30532+ "klips_debug:ipsec_lifetime_check: "
30533+ "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
30534+ "soft expire message sent up, %s packet still processed.\n",
30535+ lifename,
30536+ IPS_XFORM_NAME(ips),
30537+ saname,
30538+ dir);
30539+
30540+ if(ips->ips_state != SADB_SASTATE_DYING) {
30541+ pfkey_expire(ips, 0);
30542+ }
30543+ ips->ips_state = SADB_SASTATE_DYING;
30544+
30545+ return ipsec_life_softdied;
30546+ }
30547+ return ipsec_life_okay;
30548+}
30549+
30550+
30551+/*
30552+ * This function takes a buffer (with length), a lifetime name and type,
30553+ * and formats a string to represent the current values of the lifetime.
30554+ *
30555+ * It returns the number of bytes that the format took (or would take,
30556+ * if the buffer were large enough: snprintf semantics).
30557+ * This is used in /proc routines and in debug output.
30558+ */
30559+int
30560+ipsec_lifetime_format(char *buffer,
30561+ int buflen,
30562+ char *lifename,
30563+ enum ipsec_life_type timebaselife,
30564+ struct ipsec_lifetime64 *lifetime)
30565+{
30566+ int len = 0;
30567+ __u64 count;
30568+
30569+ if(timebaselife == ipsec_life_timebased) {
30570+ count = jiffies/HZ - lifetime->ipl_count;
30571+ } else {
30572+ count = lifetime->ipl_count;
30573+ }
30574+
30575+ if(lifetime->ipl_count > 1 ||
30576+ lifetime->ipl_soft ||
30577+ lifetime->ipl_hard) {
30578+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
30579+ len = ipsec_snprintf(buffer, buflen,
30580+ "%s(%Lu,%Lu,%Lu)",
30581+ lifename,
30582+ count,
30583+ lifetime->ipl_soft,
30584+ lifetime->ipl_hard);
30585+#else /* XXX high 32 bits are not displayed */
30586+ len = ipsec_snprintf(buffer, buflen,
30587+ "%s(%lu,%lu,%lu)",
30588+ lifename,
30589+ (unsigned long)count,
30590+ (unsigned long)lifetime->ipl_soft,
30591+ (unsigned long)lifetime->ipl_hard);
30592+#endif
30593+ }
30594+
30595+ return len;
30596+}
30597+
30598+void
30599+ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
30600+ __u64 newvalue)
30601+{
30602+ if(newvalue &&
30603+ (!lifetime->ipl_hard ||
30604+ (newvalue < lifetime->ipl_hard))) {
30605+ lifetime->ipl_hard = newvalue;
30606+
30607+ if(!lifetime->ipl_soft &&
30608+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
30609+ lifetime->ipl_soft = lifetime->ipl_hard;
30610+ }
30611+ }
30612+}
30613+
30614+void
30615+ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
30616+ __u64 newvalue)
30617+{
30618+ if(newvalue &&
30619+ (!lifetime->ipl_soft ||
30620+ (newvalue < lifetime->ipl_soft))) {
30621+ lifetime->ipl_soft = newvalue;
30622+
30623+ if(lifetime->ipl_hard &&
30624+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
30625+ lifetime->ipl_soft = lifetime->ipl_hard;
30626+ }
30627+ }
30628+}
30629+
30630+
30631+/*
30632+ * $Log: ipsec_life.c,v $
30633+ * Revision 1.13.10.2 2007-09-05 02:39:38 paul
30634+ * include ip.h to account for header file surgery in 2.6.22 [david]
30635+ *
30636+ * Revision 1.13.10.1 2006/10/06 21:39:26 paul
30637+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
30638+ * set. This is defined through autoconf.h which is included through the
30639+ * linux kernel build macros.
30640+ *
30641+ * Revision 1.13 2004/07/10 19:11:18 mcr
30642+ * CONFIG_IPSEC -> CONFIG_KLIPS.
30643+ *
30644+ * Revision 1.12 2004/04/23 20:44:35 ken
30645+ * Update comments
30646+ *
30647+ * Revision 1.11 2004/04/06 02:49:26 mcr
30648+ * pullup of algo code from alg-branch.
30649+ *
30650+ * Revision 1.10 2004/03/30 11:03:10 paul
30651+ * two more occurances of snprintf, found by Sam from a users oops msg.
30652+ *
30653+ * Revision 1.9 2003/10/31 02:27:55 mcr
30654+ * pulled up port-selector patches and sa_id elimination.
30655+ *
30656+ * Revision 1.8.4.1 2003/10/29 01:30:41 mcr
30657+ * elimited "struct sa_id".
30658+ *
30659+ * Revision 1.8 2003/02/06 02:00:10 rgb
30660+ * Fixed incorrect debugging text label
30661+ *
30662+ * Revision 1.7 2002/05/23 07:16:26 rgb
30663+ * Fixed absolute/relative reference to lifetime count printout.
30664+ *
30665+ * Revision 1.6 2002/04/24 07:55:32 mcr
30666+ * #include patches and Makefiles for post-reorg compilation.
30667+ *
30668+ * Revision 1.5 2002/04/24 07:36:28 mcr
30669+ * Moved from ./klips/net/ipsec/ipsec_life.c,v
30670+ *
30671+ * Revision 1.4 2002/01/29 17:17:55 mcr
30672+ * moved include of ipsec_param.h to after include of linux/kernel.h
30673+ * otherwise, it seems that some option that is set in ipsec_param.h
30674+ * screws up something subtle in the include path to kernel.h, and
30675+ * it complains on the snprintf() prototype.
30676+ *
30677+ * Revision 1.3 2002/01/29 02:13:17 mcr
30678+ * introduction of ipsec_kversion.h means that include of
30679+ * ipsec_param.h must preceed any decisions about what files to
30680+ * include to deal with differences in kernel source.
30681+ *
30682+ * Revision 1.2 2001/11/26 09:16:14 rgb
30683+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
30684+ *
30685+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
30686+ * lifetime structure created and common functions created.
30687+ *
30688+ * Local variables:
30689+ * c-file-style: "linux"
30690+ * End:
30691+ *
30692+ */
30693--- /dev/null Tue Mar 11 13:02:56 2003
30694+++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004
30695@@ -0,0 +1,1099 @@
30696+/*
30697+ * IPSEC MAST code.
30698+ * Copyright (C) 1996, 1997 John Ioannidis.
30699+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
30700+ *
30701+ * This program is free software; you can redistribute it and/or modify it
30702+ * under the terms of the GNU General Public License as published by the
30703+ * Free Software Foundation; either version 2 of the License, or (at your
30704+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30705+ *
30706+ * This program is distributed in the hope that it will be useful, but
30707+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30708+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30709+ * for more details.
30710+ */
30711+
30712+char ipsec_mast_c_version[] = "RCSID $Id: ipsec_mast.c,v 1.7.2.1 2006-10-06 21:39:26 paul Exp $";
30713+
30714+#define __NO_VERSION__
30715+#include <linux/module.h>
30716+#ifndef AUTOCONF_INCLUDED
30717+#include <linux/config.h>
30718+#endif /* for CONFIG_IP_FORWARD */
30719+#include <linux/version.h>
30720+#include <linux/kernel.h> /* printk() */
30721+
30722+#include "freeswan/ipsec_param.h"
30723+
30724+#ifdef MALLOC_SLAB
30725+# include <linux/slab.h> /* kmalloc() */
30726+#else /* MALLOC_SLAB */
30727+# include <linux/malloc.h> /* kmalloc() */
30728+#endif /* MALLOC_SLAB */
30729+#include <linux/errno.h> /* error codes */
30730+#include <linux/types.h> /* size_t */
30731+#include <linux/interrupt.h> /* mark_bh */
30732+
30733+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
30734+#include <linux/etherdevice.h> /* eth_type_trans */
30735+#include <linux/ip.h> /* struct iphdr */
30736+#include <linux/tcp.h> /* struct tcphdr */
30737+#include <linux/udp.h> /* struct udphdr */
30738+#include <linux/skbuff.h>
30739+#include <freeswan.h>
30740+#include <linux/in6.h>
30741+#include <net/dst.h>
30742+#undef dev_kfree_skb
30743+#define dev_kfree_skb(a,b) kfree_skb(a)
30744+#define PHYSDEV_TYPE
30745+#include <net/icmp.h> /* icmp_send() */
30746+#include <net/ip.h>
30747+#include <linux/netfilter_ipv4.h>
30748+
30749+#include <linux/if_arp.h>
30750+
30751+#include "freeswan/radij.h"
30752+#include "freeswan/ipsec_life.h"
30753+#include "freeswan/ipsec_xform.h"
30754+#include "freeswan/ipsec_eroute.h"
30755+#include "freeswan/ipsec_encap.h"
30756+#include "freeswan/ipsec_radij.h"
30757+#include "freeswan/ipsec_sa.h"
30758+#include "freeswan/ipsec_tunnel.h"
30759+#include "freeswan/ipsec_mast.h"
30760+#include "freeswan/ipsec_ipe4.h"
30761+#include "freeswan/ipsec_ah.h"
30762+#include "freeswan/ipsec_esp.h"
30763+
30764+#include <pfkeyv2.h>
30765+#include <pfkey.h>
30766+
30767+#include "freeswan/ipsec_proto.h"
30768+
30769+int ipsec_maxdevice_count = -1;
30770+
30771+DEBUG_NO_STATIC int
30772+ipsec_mast_open(struct net_device *dev)
30773+{
30774+ struct ipsecpriv *prv = dev->priv;
30775+
30776+ /*
30777+ * Can't open until attached.
30778+ */
30779+
30780+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30781+ "klips_debug:ipsec_mast_open: "
30782+ "dev = %s, prv->dev = %s\n",
30783+ dev->name, prv->dev?prv->dev->name:"NONE");
30784+
30785+ if (prv->dev == NULL)
30786+ return -ENODEV;
30787+
30788+ KLIPS_INC_USE;
30789+ return 0;
30790+}
30791+
30792+DEBUG_NO_STATIC int
30793+ipsec_mast_close(struct net_device *dev)
30794+{
30795+ KLIPS_DEC_USE;
30796+ return 0;
30797+}
30798+
30799+static inline int ipsec_mast_xmit2(struct sk_buff *skb)
30800+{
30801+ return ip_send(skb);
30802+}
30803+
30804+enum ipsec_xmit_value
30805+ipsec_mast_send(struct ipsec_xmit_state*ixs)
30806+{
30807+ /* new route/dst cache code from James Morris */
30808+ ixs->skb->dev = ixs->physdev;
30809+ /*skb_orphan(ixs->skb);*/
30810+ if((ixs->error = ip_route_output(&ixs->route,
30811+ ixs->skb->nh.iph->daddr,
30812+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
30813+ RT_TOS(ixs->skb->nh.iph->tos),
30814+ ixs->physdev->iflink /* rgb: should this be 0? */))) {
30815+ ixs->stats->tx_errors++;
30816+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30817+ "klips_debug:ipsec_xmit_send: "
30818+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
30819+ ixs->error,
30820+ ixs->route->u.dst.dev->name);
30821+ return IPSEC_XMIT_ROUTEERR;
30822+ }
30823+ if(ixs->dev == ixs->route->u.dst.dev) {
30824+ ip_rt_put(ixs->route);
30825+ /* This is recursion, drop it. */
30826+ ixs->stats->tx_errors++;
30827+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30828+ "klips_debug:ipsec_xmit_send: "
30829+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
30830+ ixs->dev->name);
30831+ return IPSEC_XMIT_RECURSDETECT;
30832+ }
30833+ dst_release(ixs->skb->dst);
30834+ ixs->skb->dst = &ixs->route->u.dst;
30835+ ixs->stats->tx_bytes += ixs->skb->len;
30836+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
30837+ ixs->stats->tx_errors++;
30838+ printk(KERN_WARNING
30839+ "klips_error:ipsec_xmit_send: "
30840+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
30841+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
30842+ ixs->skb->len);
30843+ return IPSEC_XMIT_PUSHPULLERR;
30844+ }
30845+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
30846+#ifdef SKB_RESET_NFCT
30847+ nf_conntrack_put(ixs->skb->nfct);
30848+ ixs->skb->nfct = NULL;
30849+#ifdef CONFIG_NETFILTER_DEBUG
30850+ ixs->skb->nf_debug = 0;
30851+#endif /* CONFIG_NETFILTER_DEBUG */
30852+#endif /* SKB_RESET_NFCT */
30853+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30854+ "klips_debug:ipsec_xmit_send: "
30855+ "...done, calling ip_send() on device:%s\n",
30856+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
30857+ KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
30858+ {
30859+ int err;
30860+
30861+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
30862+ ipsec_mast_xmit2);
30863+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
30864+ if(net_ratelimit())
30865+ printk(KERN_ERR
30866+ "klips_error:ipsec_xmit_send: "
30867+ "ip_send() failed, err=%d\n",
30868+ -err);
30869+ ixs->stats->tx_errors++;
30870+ ixs->stats->tx_aborted_errors++;
30871+ ixs->skb = NULL;
30872+ return IPSEC_XMIT_IPSENDFAILURE;
30873+ }
30874+ }
30875+ ixs->stats->tx_packets++;
30876+
30877+ ixs->skb = NULL;
30878+
30879+ return IPSEC_XMIT_OK;
30880+}
30881+
30882+void
30883+ipsec_mast_cleanup(struct ipsec_xmit_state*ixs)
30884+{
30885+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
30886+ netif_wake_queue(ixs->dev);
30887+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30888+ ixs->dev->tbusy = 0;
30889+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30890+ if(ixs->saved_header) {
30891+ kfree(ixs->saved_header);
30892+ }
30893+ if(ixs->skb) {
30894+ dev_kfree_skb(ixs->skb, FREE_WRITE);
30895+ }
30896+ if(ixs->oskb) {
30897+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
30898+ }
30899+ if (ixs->ips.ips_ident_s.data) {
30900+ kfree(ixs->ips.ips_ident_s.data);
30901+ }
30902+ if (ixs->ips.ips_ident_d.data) {
30903+ kfree(ixs->ips.ips_ident_d.data);
30904+ }
30905+}
30906+
30907+#if 0
30908+/*
30909+ * This function assumes it is being called from dev_queue_xmit()
30910+ * and that skb is filled properly by that function.
30911+ */
30912+int
30913+ipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev, IPsecSAref_t SAref)
30914+{
30915+ struct ipsec_xmit_state ixs_mem;
30916+ struct ipsec_xmit_state *ixs = &ixs_mem;
30917+ enum ipsec_xmit_value stat = IPSEC_XMIT_OK;
30918+
30919+ /* dev could be a mast device, but should be optional, I think... */
30920+ /* SAref is also optional, but one of the two must be present. */
30921+ /* I wonder if it could accept no device or saref and guess? */
30922+
30923+/* ipsec_xmit_sanity_check_dev(ixs); */
30924+
30925+ ipsec_xmit_sanity_check_skb(ixs);
30926+
30927+ ipsec_xmit_adjust_hard_header(ixs);
30928+
30929+ stat = ipsec_xmit_encap_bundle(ixs);
30930+ if(stat != IPSEC_XMIT_OK) {
30931+ /* SA processing failed */
30932+ }
30933+
30934+ ipsec_xmit_hard_header_restore();
30935+}
30936+#endif
30937+
30938+DEBUG_NO_STATIC struct net_device_stats *
30939+ipsec_mast_get_stats(struct net_device *dev)
30940+{
30941+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
30942+}
30943+
30944+/*
30945+ * Revectored calls.
30946+ * For each of these calls, a field exists in our private structure.
30947+ */
30948+
30949+DEBUG_NO_STATIC int
30950+ipsec_mast_hard_header(struct sk_buff *skb, struct net_device *dev,
30951+ unsigned short type, void *daddr, void *saddr, unsigned len)
30952+{
30953+ struct ipsecpriv *prv = dev->priv;
30954+ struct net_device *tmp;
30955+ int ret;
30956+ struct net_device_stats *stats; /* This device's statistics */
30957+
30958+ if(skb == NULL) {
30959+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30960+ "klips_debug:ipsec_mast_hard_header: "
30961+ "no skb...\n");
30962+ return -ENODATA;
30963+ }
30964+
30965+ if(dev == NULL) {
30966+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30967+ "klips_debug:ipsec_mast_hard_header: "
30968+ "no device...\n");
30969+ return -ENODEV;
30970+ }
30971+
30972+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30973+ "klips_debug:ipsec_mast_hard_header: "
30974+ "skb->dev=%s dev=%s.\n",
30975+ skb->dev ? skb->dev->name : "NULL",
30976+ dev->name);
30977+
30978+ if(prv == NULL) {
30979+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30980+ "klips_debug:ipsec_mast_hard_header: "
30981+ "no private space associated with dev=%s\n",
30982+ dev->name ? dev->name : "NULL");
30983+ return -ENODEV;
30984+ }
30985+
30986+ stats = (struct net_device_stats *) &(prv->mystats);
30987+
30988+ if(prv->dev == NULL) {
30989+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30990+ "klips_debug:ipsec_mast_hard_header: "
30991+ "no physical device associated with dev=%s\n",
30992+ dev->name ? dev->name : "NULL");
30993+ stats->tx_dropped++;
30994+ return -ENODEV;
30995+ }
30996+
30997+ /* check if we have to send a IPv6 packet. It might be a Router
30998+ Solicitation, where the building of the packet happens in
30999+ reverse order:
31000+ 1. ll hdr,
31001+ 2. IPv6 hdr,
31002+ 3. ICMPv6 hdr
31003+ -> skb->nh.raw is still uninitialized when this function is
31004+ called!! If this is no IPv6 packet, we can print debugging
31005+ messages, otherwise we skip all debugging messages and just
31006+ build the ll header */
31007+ if(type != ETH_P_IPV6) {
31008+ /* execute this only, if we don't have to build the
31009+ header for a IPv6 packet */
31010+ if(!prv->hard_header) {
31011+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31012+ "klips_debug:ipsec_mast_hard_header: "
31013+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
31014+ saddr,
31015+ daddr,
31016+ len,
31017+ type,
31018+ dev->name);
31019+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
31020+ "ip=%08x->%08x\n",
31021+ (__u32)ntohl(skb->nh.iph->saddr),
31022+ (__u32)ntohl(skb->nh.iph->daddr) );
31023+ stats->tx_dropped++;
31024+ return -ENODEV;
31025+ }
31026+
31027+#define da ((struct net_device *)(prv->dev))->dev_addr
31028+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31029+ "klips_debug:ipsec_mast_hard_header: "
31030+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
31031+ saddr,
31032+ daddr,
31033+ len,
31034+ type,
31035+ dev->name,
31036+ prv->dev->name,
31037+ da[0], da[1], da[2], da[3], da[4], da[5]);
31038+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
31039+ "ip=%08x->%08x\n",
31040+ (__u32)ntohl(skb->nh.iph->saddr),
31041+ (__u32)ntohl(skb->nh.iph->daddr) );
31042+ } else {
31043+ KLIPS_PRINT(debug_mast,
31044+ "klips_debug:ipsec_mast_hard_header: "
31045+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
31046+ }
31047+ tmp = skb->dev;
31048+ skb->dev = prv->dev;
31049+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
31050+ skb->dev = tmp;
31051+ return ret;
31052+}
31053+
31054+DEBUG_NO_STATIC int
31055+ipsec_mast_rebuild_header(struct sk_buff *skb)
31056+{
31057+ struct ipsecpriv *prv = skb->dev->priv;
31058+ struct net_device *tmp;
31059+ int ret;
31060+ struct net_device_stats *stats; /* This device's statistics */
31061+
31062+ if(skb->dev == NULL) {
31063+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31064+ "klips_debug:ipsec_mast_rebuild_header: "
31065+ "no device...");
31066+ return -ENODEV;
31067+ }
31068+
31069+ if(prv == NULL) {
31070+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31071+ "klips_debug:ipsec_mast_rebuild_header: "
31072+ "no private space associated with dev=%s",
31073+ skb->dev->name ? skb->dev->name : "NULL");
31074+ return -ENODEV;
31075+ }
31076+
31077+ stats = (struct net_device_stats *) &(prv->mystats);
31078+
31079+ if(prv->dev == NULL) {
31080+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31081+ "klips_debug:ipsec_mast_rebuild_header: "
31082+ "no physical device associated with dev=%s",
31083+ skb->dev->name ? skb->dev->name : "NULL");
31084+ stats->tx_dropped++;
31085+ return -ENODEV;
31086+ }
31087+
31088+ if(!prv->rebuild_header) {
31089+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31090+ "klips_debug:ipsec_mast_rebuild_header: "
31091+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
31092+ skb->dev->name);
31093+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31094+ "ip=%08x->%08x\n",
31095+ (__u32)ntohl(skb->nh.iph->saddr),
31096+ (__u32)ntohl(skb->nh.iph->daddr) );
31097+ stats->tx_dropped++;
31098+ return -ENODEV;
31099+ }
31100+
31101+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31102+ "klips_debug:ipsec_mast: "
31103+ "Revectored rebuild_header dev=%s->%s ",
31104+ skb->dev->name, prv->dev->name);
31105+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31106+ "ip=%08x->%08x\n",
31107+ (__u32)ntohl(skb->nh.iph->saddr),
31108+ (__u32)ntohl(skb->nh.iph->daddr) );
31109+ tmp = skb->dev;
31110+ skb->dev = prv->dev;
31111+
31112+ ret = prv->rebuild_header(skb);
31113+ skb->dev = tmp;
31114+ return ret;
31115+}
31116+
31117+DEBUG_NO_STATIC int
31118+ipsec_mast_set_mac_address(struct net_device *dev, void *addr)
31119+{
31120+ struct ipsecpriv *prv = dev->priv;
31121+
31122+ struct net_device_stats *stats; /* This device's statistics */
31123+
31124+ if(dev == NULL) {
31125+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31126+ "klips_debug:ipsec_mast_set_mac_address: "
31127+ "no device...");
31128+ return -ENODEV;
31129+ }
31130+
31131+ if(prv == NULL) {
31132+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31133+ "klips_debug:ipsec_mast_set_mac_address: "
31134+ "no private space associated with dev=%s",
31135+ dev->name ? dev->name : "NULL");
31136+ return -ENODEV;
31137+ }
31138+
31139+ stats = (struct net_device_stats *) &(prv->mystats);
31140+
31141+ if(prv->dev == NULL) {
31142+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31143+ "klips_debug:ipsec_mast_set_mac_address: "
31144+ "no physical device associated with dev=%s",
31145+ dev->name ? dev->name : "NULL");
31146+ stats->tx_dropped++;
31147+ return -ENODEV;
31148+ }
31149+
31150+ if(!prv->set_mac_address) {
31151+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31152+ "klips_debug:ipsec_mast_set_mac_address: "
31153+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
31154+ dev->name);
31155+ return -ENODEV;
31156+ }
31157+
31158+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31159+ "klips_debug:ipsec_mast_set_mac_address: "
31160+ "Revectored dev=%s->%s addr=0p%p\n",
31161+ dev->name, prv->dev->name, addr);
31162+ return prv->set_mac_address(prv->dev, addr);
31163+
31164+}
31165+
31166+DEBUG_NO_STATIC void
31167+ipsec_mast_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
31168+{
31169+ struct ipsecpriv *prv = dev->priv;
31170+
31171+ struct net_device_stats *stats; /* This device's statistics */
31172+
31173+ if(dev == NULL) {
31174+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31175+ "klips_debug:ipsec_mast_cache_update: "
31176+ "no device...");
31177+ return;
31178+ }
31179+
31180+ if(prv == NULL) {
31181+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31182+ "klips_debug:ipsec_mast_cache_update: "
31183+ "no private space associated with dev=%s",
31184+ dev->name ? dev->name : "NULL");
31185+ return;
31186+ }
31187+
31188+ stats = (struct net_device_stats *) &(prv->mystats);
31189+
31190+ if(prv->dev == NULL) {
31191+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31192+ "klips_debug:ipsec_mast_cache_update: "
31193+ "no physical device associated with dev=%s",
31194+ dev->name ? dev->name : "NULL");
31195+ stats->tx_dropped++;
31196+ return;
31197+ }
31198+
31199+ if(!prv->header_cache_update) {
31200+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31201+ "klips_debug:ipsec_mast_cache_update: "
31202+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
31203+ dev->name);
31204+ return;
31205+ }
31206+
31207+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31208+ "klips_debug:ipsec_mast: "
31209+ "Revectored cache_update\n");
31210+ prv->header_cache_update(hh, prv->dev, haddr);
31211+ return;
31212+}
31213+
31214+DEBUG_NO_STATIC int
31215+ipsec_mast_neigh_setup(struct neighbour *n)
31216+{
31217+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31218+ "klips_debug:ipsec_mast_neigh_setup:\n");
31219+
31220+ if (n->nud_state == NUD_NONE) {
31221+ n->ops = &arp_broken_ops;
31222+ n->output = n->ops->output;
31223+ }
31224+ return 0;
31225+}
31226+
31227+DEBUG_NO_STATIC int
31228+ipsec_mast_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
31229+{
31230+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31231+ "klips_debug:ipsec_mast_neigh_setup_dev: "
31232+ "setting up %s\n",
31233+ dev ? dev->name : "NULL");
31234+
31235+ if (p->tbl->family == AF_INET) {
31236+ p->neigh_setup = ipsec_mast_neigh_setup;
31237+ p->ucast_probes = 0;
31238+ p->mcast_probes = 0;
31239+ }
31240+ return 0;
31241+}
31242+
31243+/*
31244+ * We call the attach routine to attach another device.
31245+ */
31246+
31247+DEBUG_NO_STATIC int
31248+ipsec_mast_attach(struct net_device *dev, struct net_device *physdev)
31249+{
31250+ int i;
31251+ struct ipsecpriv *prv = dev->priv;
31252+
31253+ if(dev == NULL) {
31254+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31255+ "klips_debug:ipsec_mast_attach: "
31256+ "no device...");
31257+ return -ENODEV;
31258+ }
31259+
31260+ if(prv == NULL) {
31261+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31262+ "klips_debug:ipsec_mast_attach: "
31263+ "no private space associated with dev=%s",
31264+ dev->name ? dev->name : "NULL");
31265+ return -ENODATA;
31266+ }
31267+
31268+ prv->dev = physdev;
31269+ prv->hard_start_xmit = physdev->hard_start_xmit;
31270+ prv->get_stats = physdev->get_stats;
31271+
31272+ if (physdev->hard_header) {
31273+ prv->hard_header = physdev->hard_header;
31274+ dev->hard_header = ipsec_mast_hard_header;
31275+ } else
31276+ dev->hard_header = NULL;
31277+
31278+ if (physdev->rebuild_header) {
31279+ prv->rebuild_header = physdev->rebuild_header;
31280+ dev->rebuild_header = ipsec_mast_rebuild_header;
31281+ } else
31282+ dev->rebuild_header = NULL;
31283+
31284+ if (physdev->set_mac_address) {
31285+ prv->set_mac_address = physdev->set_mac_address;
31286+ dev->set_mac_address = ipsec_mast_set_mac_address;
31287+ } else
31288+ dev->set_mac_address = NULL;
31289+
31290+ if (physdev->header_cache_update) {
31291+ prv->header_cache_update = physdev->header_cache_update;
31292+ dev->header_cache_update = ipsec_mast_cache_update;
31293+ } else
31294+ dev->header_cache_update = NULL;
31295+
31296+ dev->hard_header_len = physdev->hard_header_len;
31297+
31298+/* prv->neigh_setup = physdev->neigh_setup; */
31299+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
31300+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
31301+ prv->mtu = physdev->mtu;
31302+
31303+#ifdef PHYSDEV_TYPE
31304+ dev->type = physdev->type; /* ARPHRD_MAST; */
31305+#endif /* PHYSDEV_TYPE */
31306+
31307+ dev->addr_len = physdev->addr_len;
31308+ for (i=0; i<dev->addr_len; i++) {
31309+ dev->dev_addr[i] = physdev->dev_addr[i];
31310+ }
31311+#ifdef CONFIG_KLIPS_DEBUG
31312+ if(debug_mast & DB_MAST_INIT) {
31313+ printk(KERN_INFO "klips_debug:ipsec_mast_attach: "
31314+ "physical device %s being attached has HW address: %2x",
31315+ physdev->name, physdev->dev_addr[0]);
31316+ for (i=1; i < physdev->addr_len; i++) {
31317+ printk(":%02x", physdev->dev_addr[i]);
31318+ }
31319+ printk("\n");
31320+ }
31321+#endif /* CONFIG_KLIPS_DEBUG */
31322+
31323+ return 0;
31324+}
31325+
31326+/*
31327+ * We call the detach routine to detach the ipsec mast from another device.
31328+ */
31329+
31330+DEBUG_NO_STATIC int
31331+ipsec_mast_detach(struct net_device *dev)
31332+{
31333+ int i;
31334+ struct ipsecpriv *prv = dev->priv;
31335+
31336+ if(dev == NULL) {
31337+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31338+ "klips_debug:ipsec_mast_detach: "
31339+ "no device...");
31340+ return -ENODEV;
31341+ }
31342+
31343+ if(prv == NULL) {
31344+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31345+ "klips_debug:ipsec_mast_detach: "
31346+ "no private space associated with dev=%s",
31347+ dev->name ? dev->name : "NULL");
31348+ return -ENODATA;
31349+ }
31350+
31351+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31352+ "klips_debug:ipsec_mast_detach: "
31353+ "physical device %s being detached from virtual device %s\n",
31354+ prv->dev ? prv->dev->name : "NULL",
31355+ dev->name);
31356+
31357+ prv->dev = NULL;
31358+ prv->hard_start_xmit = NULL;
31359+ prv->get_stats = NULL;
31360+
31361+ prv->hard_header = NULL;
31362+#ifdef DETACH_AND_DOWN
31363+ dev->hard_header = NULL;
31364+#endif /* DETACH_AND_DOWN */
31365+
31366+ prv->rebuild_header = NULL;
31367+#ifdef DETACH_AND_DOWN
31368+ dev->rebuild_header = NULL;
31369+#endif /* DETACH_AND_DOWN */
31370+
31371+ prv->set_mac_address = NULL;
31372+#ifdef DETACH_AND_DOWN
31373+ dev->set_mac_address = NULL;
31374+#endif /* DETACH_AND_DOWN */
31375+
31376+ prv->header_cache_update = NULL;
31377+#ifdef DETACH_AND_DOWN
31378+ dev->header_cache_update = NULL;
31379+#endif /* DETACH_AND_DOWN */
31380+
31381+#ifdef DETACH_AND_DOWN
31382+ dev->neigh_setup = NULL;
31383+#endif /* DETACH_AND_DOWN */
31384+
31385+ dev->hard_header_len = 0;
31386+#ifdef DETACH_AND_DOWN
31387+ dev->mtu = 0;
31388+#endif /* DETACH_AND_DOWN */
31389+ prv->mtu = 0;
31390+ for (i=0; i<MAX_ADDR_LEN; i++) {
31391+ dev->dev_addr[i] = 0;
31392+ }
31393+ dev->addr_len = 0;
31394+#ifdef PHYSDEV_TYPE
31395+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */
31396+#endif /* PHYSDEV_TYPE */
31397+
31398+ return 0;
31399+}
31400+
31401+/*
31402+ * We call the clear routine to detach all ipsec masts from other devices.
31403+ */
31404+DEBUG_NO_STATIC int
31405+ipsec_mast_clear(void)
31406+{
31407+ int i;
31408+ struct net_device *ipsecdev = NULL, *prvdev;
31409+ struct ipsecpriv *prv;
31410+ char name[9];
31411+ int ret;
31412+
31413+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31414+ "klips_debug:ipsec_mast_clear: .\n");
31415+
31416+ for(i = 0; i < IPSEC_NUM_IF; i++) {
31417+ sprintf(name, IPSEC_DEV_FORMAT, i);
31418+ if((ipsecdev = ipsec_dev_get(name)) != NULL) {
31419+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
31420+ prvdev = (struct net_device *)(prv->dev);
31421+ if(prvdev) {
31422+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31423+ "klips_debug:ipsec_mast_clear: "
31424+ "physical device for device %s is %s\n",
31425+ name, prvdev->name);
31426+ if((ret = ipsec_mast_detach(ipsecdev))) {
31427+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31428+ "klips_debug:ipsec_mast_clear: "
31429+ "error %d detatching device %s from device %s.\n",
31430+ ret, name, prvdev->name);
31431+ return ret;
31432+ }
31433+ }
31434+ }
31435+ }
31436+ }
31437+ return 0;
31438+}
31439+
31440+DEBUG_NO_STATIC int
31441+ipsec_mast_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
31442+{
31443+ struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
31444+ struct ipsecpriv *prv = dev->priv;
31445+ struct net_device *them; /* physical device */
31446+#ifdef CONFIG_IP_ALIAS
31447+ char *colon;
31448+ char realphysname[IFNAMSIZ];
31449+#endif /* CONFIG_IP_ALIAS */
31450+
31451+ if(dev == NULL) {
31452+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31453+ "klips_debug:ipsec_mast_ioctl: "
31454+ "device not supplied.\n");
31455+ return -ENODEV;
31456+ }
31457+
31458+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31459+ "klips_debug:ipsec_mast_ioctl: "
31460+ "tncfg service call #%d for dev=%s\n",
31461+ cmd,
31462+ dev->name ? dev->name : "NULL");
31463+ switch (cmd) {
31464+ /* attach a virtual ipsec? device to a physical device */
31465+ case IPSEC_SET_DEV:
31466+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31467+ "klips_debug:ipsec_mast_ioctl: "
31468+ "calling ipsec_mast_attatch...\n");
31469+#ifdef CONFIG_IP_ALIAS
31470+ /* If this is an IP alias interface, get its real physical name */
31471+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
31472+ realphysname[IFNAMSIZ-1] = 0;
31473+ colon = strchr(realphysname, ':');
31474+ if (colon) *colon = 0;
31475+ them = ipsec_dev_get(realphysname);
31476+#else /* CONFIG_IP_ALIAS */
31477+ them = ipsec_dev_get(cf->cf_name);
31478+#endif /* CONFIG_IP_ALIAS */
31479+
31480+ if (them == NULL) {
31481+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31482+ "klips_debug:ipsec_mast_ioctl: "
31483+ "physical device %s requested is null\n",
31484+ cf->cf_name);
31485+ return -ENXIO;
31486+ }
31487+
31488+#if 0
31489+ if (them->flags & IFF_UP) {
31490+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31491+ "klips_debug:ipsec_mast_ioctl: "
31492+ "physical device %s requested is not up.\n",
31493+ cf->cf_name);
31494+ return -ENXIO;
31495+ }
31496+#endif
31497+
31498+ if (prv && prv->dev) {
31499+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31500+ "klips_debug:ipsec_mast_ioctl: "
31501+ "virtual device is already connected to %s.\n",
31502+ prv->dev->name ? prv->dev->name : "NULL");
31503+ return -EBUSY;
31504+ }
31505+ return ipsec_mast_attach(dev, them);
31506+
31507+ case IPSEC_DEL_DEV:
31508+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31509+ "klips_debug:ipsec_mast_ioctl: "
31510+ "calling ipsec_mast_detatch.\n");
31511+ if (! prv->dev) {
31512+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31513+ "klips_debug:ipsec_mast_ioctl: "
31514+ "physical device not connected.\n");
31515+ return -ENODEV;
31516+ }
31517+ return ipsec_mast_detach(dev);
31518+
31519+ case IPSEC_CLR_DEV:
31520+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31521+ "klips_debug:ipsec_mast_ioctl: "
31522+ "calling ipsec_mast_clear.\n");
31523+ return ipsec_mast_clear();
31524+
31525+ default:
31526+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31527+ "klips_debug:ipsec_mast_ioctl: "
31528+ "unknown command %d.\n",
31529+ cmd);
31530+ return -EOPNOTSUPP;
31531+ }
31532+}
31533+
31534+int
31535+ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
31536+{
31537+ struct net_device *dev = ptr;
31538+ struct net_device *ipsec_dev;
31539+ struct ipsecpriv *priv;
31540+ char name[9];
31541+ int i;
31542+
31543+ if (dev == NULL) {
31544+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31545+ "klips_debug:ipsec_mast_device_event: "
31546+ "dev=NULL for event type %ld.\n",
31547+ event);
31548+ return(NOTIFY_DONE);
31549+ }
31550+
31551+ /* check for loopback devices */
31552+ if (dev && (dev->flags & IFF_LOOPBACK)) {
31553+ return(NOTIFY_DONE);
31554+ }
31555+
31556+ switch (event) {
31557+ case NETDEV_DOWN:
31558+ /* look very carefully at the scope of these compiler
31559+ directives before changing anything... -- RGB */
31560+
31561+ case NETDEV_UNREGISTER:
31562+ switch (event) {
31563+ case NETDEV_DOWN:
31564+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31565+ "klips_debug:ipsec_mast_device_event: "
31566+ "NETDEV_DOWN dev=%s flags=%x\n",
31567+ dev->name,
31568+ dev->flags);
31569+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
31570+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
31571+ dev->name);
31572+ }
31573+ break;
31574+ case NETDEV_UNREGISTER:
31575+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31576+ "klips_debug:ipsec_mast_device_event: "
31577+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
31578+ dev->name,
31579+ dev->flags);
31580+ break;
31581+ }
31582+
31583+ /* find the attached physical device and detach it. */
31584+ for(i = 0; i < IPSEC_NUM_IF; i++) {
31585+ sprintf(name, IPSEC_DEV_FORMAT, i);
31586+ ipsec_dev = ipsec_dev_get(name);
31587+ if(ipsec_dev) {
31588+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
31589+ if(priv) {
31590+ ;
31591+ if(((struct net_device *)(priv->dev)) == dev) {
31592+ /* dev_close(ipsec_dev); */
31593+ /* return */ ipsec_mast_detach(ipsec_dev);
31594+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31595+ "klips_debug:ipsec_mast_device_event: "
31596+ "device '%s' has been detached.\n",
31597+ ipsec_dev->name);
31598+ break;
31599+ }
31600+ } else {
31601+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31602+ "klips_debug:ipsec_mast_device_event: "
31603+ "device '%s' has no private data space!\n",
31604+ ipsec_dev->name);
31605+ }
31606+ }
31607+ }
31608+ break;
31609+ case NETDEV_UP:
31610+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31611+ "klips_debug:ipsec_mast_device_event: "
31612+ "NETDEV_UP dev=%s\n",
31613+ dev->name);
31614+ break;
31615+ case NETDEV_REBOOT:
31616+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31617+ "klips_debug:ipsec_mast_device_event: "
31618+ "NETDEV_REBOOT dev=%s\n",
31619+ dev->name);
31620+ break;
31621+ case NETDEV_CHANGE:
31622+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31623+ "klips_debug:ipsec_mast_device_event: "
31624+ "NETDEV_CHANGE dev=%s flags=%x\n",
31625+ dev->name,
31626+ dev->flags);
31627+ break;
31628+ case NETDEV_REGISTER:
31629+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31630+ "klips_debug:ipsec_mast_device_event: "
31631+ "NETDEV_REGISTER dev=%s\n",
31632+ dev->name);
31633+ break;
31634+ case NETDEV_CHANGEMTU:
31635+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31636+ "klips_debug:ipsec_mast_device_event: "
31637+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
31638+ dev->name,
31639+ dev->mtu);
31640+ break;
31641+ case NETDEV_CHANGEADDR:
31642+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31643+ "klips_debug:ipsec_mast_device_event: "
31644+ "NETDEV_CHANGEADDR dev=%s\n",
31645+ dev->name);
31646+ break;
31647+ case NETDEV_GOING_DOWN:
31648+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31649+ "klips_debug:ipsec_mast_device_event: "
31650+ "NETDEV_GOING_DOWN dev=%s\n",
31651+ dev->name);
31652+ break;
31653+ case NETDEV_CHANGENAME:
31654+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31655+ "klips_debug:ipsec_mast_device_event: "
31656+ "NETDEV_CHANGENAME dev=%s\n",
31657+ dev->name);
31658+ break;
31659+ default:
31660+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31661+ "klips_debug:ipsec_mast_device_event: "
31662+ "event type %ld unrecognised for dev=%s\n",
31663+ event,
31664+ dev->name);
31665+ break;
31666+ }
31667+ return NOTIFY_DONE;
31668+}
31669+
31670+/*
31671+ * Called when an ipsec mast device is initialized.
31672+ * The ipsec mast device structure is passed to us.
31673+ */
31674+
31675+int
31676+ipsec_mast_init(struct net_device *dev)
31677+{
31678+ int i;
31679+
31680+ KLIPS_PRINT(debug_mast,
31681+ "klips_debug:ipsec_mast_init: "
31682+ "allocating %lu bytes initialising device: %s\n",
31683+ (unsigned long) sizeof(struct ipsecpriv),
31684+ dev->name ? dev->name : "NULL");
31685+
31686+ /* Add our mast functions to the device */
31687+ dev->open = ipsec_mast_open;
31688+ dev->stop = ipsec_mast_close;
31689+ dev->hard_start_xmit = ipsec_mast_start_xmit;
31690+ dev->get_stats = ipsec_mast_get_stats;
31691+
31692+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
31693+ if (dev->priv == NULL)
31694+ return -ENOMEM;
31695+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
31696+
31697+ for(i = 0; i < sizeof(zeroes); i++) {
31698+ ((__u8*)(zeroes))[i] = 0;
31699+ }
31700+
31701+ dev->set_multicast_list = NULL;
31702+ dev->do_ioctl = ipsec_mast_ioctl;
31703+ dev->hard_header = NULL;
31704+ dev->rebuild_header = NULL;
31705+ dev->set_mac_address = NULL;
31706+ dev->header_cache_update= NULL;
31707+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
31708+ dev->hard_header_len = 0;
31709+ dev->mtu = 0;
31710+ dev->addr_len = 0;
31711+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */
31712+ dev->tx_queue_len = 10; /* Small queue */
31713+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
31714+
31715+ /* New-style flags. */
31716+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
31717+ dev_init_buffers(dev);
31718+
31719+ /* We're done. Have I forgotten anything? */
31720+ return 0;
31721+}
31722+
31723+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31724+/* Module specific interface (but it links with the rest of IPSEC) */
31725+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31726+
31727+int
31728+ipsec_mast_probe(struct net_device *dev)
31729+{
31730+ ipsec_mast_init(dev);
31731+ return 0;
31732+}
31733+
31734+int
31735+ipsec_mast_init_devices(void)
31736+{
31737+ return 0;
31738+}
31739+
31740+/* void */
31741+int
31742+ipsec_mast_cleanup_devices(void)
31743+{
31744+ int error = 0;
31745+ int i;
31746+ char name[10];
31747+ struct net_device *dev_mast;
31748+
31749+ for(i = 0; i < ipsec_mastdevice_count; i++) {
31750+ sprintf(name, MAST_DEV_FORMAT, i);
31751+ if((dev_mast = ipsec_dev_get(name)) == NULL) {
31752+ break;
31753+ }
31754+ unregister_netdev(dev_mast);
31755+ kfree(dev_mast->priv);
31756+ dev_mast->priv=NULL;
31757+ }
31758+ return error;
31759+}
31760+
31761+/*
31762+ * $Log: ipsec_mast.c,v $
31763+ * Revision 1.7.2.1 2006-10-06 21:39:26 paul
31764+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
31765+ * set. This is defined through autoconf.h which is included through the
31766+ * linux kernel build macros.
31767+ *
31768+ * Revision 1.7 2005/04/29 05:10:22 mcr
31769+ * removed from extraenous includes to make unit testing easier.
31770+ *
31771+ * Revision 1.6 2004/12/03 21:25:57 mcr
31772+ * compile time fixes for running on 2.6.
31773+ * still experimental.
31774+ *
31775+ * Revision 1.5 2004/08/03 18:19:08 mcr
31776+ * in 2.6, use "net_device" instead of #define device->net_device.
31777+ * this probably breaks 2.0 compiles.
31778+ *
31779+ * Revision 1.4 2004/07/10 19:11:18 mcr
31780+ * CONFIG_IPSEC -> CONFIG_KLIPS.
31781+ *
31782+ * Revision 1.3 2003/10/31 02:27:55 mcr
31783+ * pulled up port-selector patches and sa_id elimination.
31784+ *
31785+ * Revision 1.2.4.1 2003/10/29 01:30:41 mcr
31786+ * elimited "struct sa_id".
31787+ *
31788+ * Revision 1.2 2003/06/22 20:06:17 mcr
31789+ * refactored mast code still had lots of ipsecX junk in it.
31790+ *
31791+ * Revision 1.1 2003/02/12 19:31:12 rgb
31792+ * Refactored from ipsec_tunnel.c
31793+ *
31794+ */
31795--- /dev/null Tue Mar 11 13:02:56 2003
31796+++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004
31797@@ -0,0 +1,453 @@
31798+/*
31799+ * RCSID $Id: ipsec_md5c.c,v 1.10 2005-04-15 01:25:57 mcr Exp $
31800+ */
31801+
31802+/*
31803+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
31804+ * changes to accomodate it in the kernel by ji.
31805+ */
31806+
31807+#include <asm/byteorder.h>
31808+#include <linux/string.h>
31809+
31810+#include "openswan/ipsec_md5h.h"
31811+
31812+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
31813+ */
31814+
31815+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
31816+rights reserved.
31817+
31818+License to copy and use this software is granted provided that it
31819+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
31820+Algorithm" in all material mentioning or referencing this software
31821+or this function.
31822+
31823+License is also granted to make and use derivative works provided
31824+that such works are identified as "derived from the RSA Data
31825+Security, Inc. MD5 Message-Digest Algorithm" in all material
31826+mentioning or referencing the derived work.
31827+
31828+RSA Data Security, Inc. makes no representations concerning either
31829+the merchantability of this software or the suitability of this
31830+software for any particular purpose. It is provided "as is"
31831+without express or implied warranty of any kind.
31832+
31833+These notices must be retained in any copies of any part of this
31834+documentation and/or software.
31835+ */
31836+
31837+/*
31838+ * Additions by JI
31839+ *
31840+ * HAVEMEMCOPY is defined if mem* routines are available
31841+ *
31842+ * HAVEHTON is defined if htons() and htonl() can be used
31843+ * for big/little endian conversions
31844+ *
31845+ */
31846+
31847+#define HAVEMEMCOPY
31848+#ifdef __LITTLE_ENDIAN
31849+#define LITTLENDIAN
31850+#endif
31851+#ifdef __BIG_ENDIAN
31852+#define BIGENDIAN
31853+#endif
31854+
31855+/* Constants for MD5Transform routine.
31856+ */
31857+
31858+#define S11 7
31859+#define S12 12
31860+#define S13 17
31861+#define S14 22
31862+#define S21 5
31863+#define S22 9
31864+#define S23 14
31865+#define S24 20
31866+#define S31 4
31867+#define S32 11
31868+#define S33 16
31869+#define S34 23
31870+#define S41 6
31871+#define S42 10
31872+#define S43 15
31873+#define S44 21
31874+
31875+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
31876+
31877+#ifdef LITTLEENDIAN
31878+#define Encode MD5_memcpy
31879+#define Decode MD5_memcpy
31880+#else
31881+static void Encode PROTO_LIST
31882+ ((unsigned char *, UINT4 *, unsigned int));
31883+static void Decode PROTO_LIST
31884+ ((UINT4 *, unsigned char *, unsigned int));
31885+#endif
31886+
31887+#ifdef HAVEMEMCOPY
31888+/* no need to include <memory.h> here; <linux/string.h> defines these */
31889+#define MD5_memcpy memcpy
31890+#define MD5_memset memset
31891+#else
31892+#ifdef HAVEBCOPY
31893+#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
31894+#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
31895+#else
31896+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
31897+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
31898+#endif
31899+#endif
31900+static unsigned char PADDING[64] = {
31901+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31902+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31903+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
31904+};
31905+
31906+/* F, G, H and I are basic MD5 functions.
31907+ */
31908+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
31909+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
31910+#define H(x, y, z) ((x) ^ (y) ^ (z))
31911+#define I(x, y, z) ((y) ^ ((x) | (~z)))
31912+
31913+/* ROTATE_LEFT rotates x left n bits.
31914+ */
31915+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
31916+
31917+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
31918+Rotation is separate from addition to prevent recomputation.
31919+ */
31920+#define FF(a, b, c, d, x, s, ac) { \
31921+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
31922+ (a) = ROTATE_LEFT ((a), (s)); \
31923+ (a) += (b); \
31924+ }
31925+#define GG(a, b, c, d, x, s, ac) { \
31926+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
31927+ (a) = ROTATE_LEFT ((a), (s)); \
31928+ (a) += (b); \
31929+ }
31930+#define HH(a, b, c, d, x, s, ac) { \
31931+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
31932+ (a) = ROTATE_LEFT ((a), (s)); \
31933+ (a) += (b); \
31934+ }
31935+#define II(a, b, c, d, x, s, ac) { \
31936+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
31937+ (a) = ROTATE_LEFT ((a), (s)); \
31938+ (a) += (b); \
31939+ }
31940+
31941+/*
31942+ * MD5 initialization. Begins an MD5 operation, writing a new context.
31943+ */
31944+void osMD5Init(void *vcontext)
31945+{
31946+ MD5_CTX *context = vcontext;
31947+
31948+ context->count[0] = context->count[1] = 0;
31949+ /* Load magic initialization constants.*/
31950+ context->state[0] = 0x67452301;
31951+ context->state[1] = 0xefcdab89;
31952+ context->state[2] = 0x98badcfe;
31953+ context->state[3] = 0x10325476;
31954+}
31955+
31956+/* MD5 block update operation. Continues an MD5 message-digest
31957+ operation, processing another message block, and updating the
31958+ context.
31959+ */
31960+void osMD5Update (vcontext, input, inputLen)
31961+ void *vcontext;
31962+ unsigned char *input; /* input block */
31963+ __u32 inputLen; /* length of input block */
31964+{
31965+ MD5_CTX *context = vcontext;
31966+ __u32 i;
31967+ unsigned int index, partLen;
31968+
31969+ /* Compute number of bytes mod 64 */
31970+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
31971+
31972+ /* Update number of bits */
31973+ if ((context->count[0] += ((UINT4)inputLen << 3))
31974+ < ((UINT4)inputLen << 3))
31975+ context->count[1]++;
31976+ context->count[1] += ((UINT4)inputLen >> 29);
31977+
31978+ partLen = 64 - index;
31979+
31980+ /* Transform as many times as possible.
31981+*/
31982+ if (inputLen >= partLen) {
31983+ MD5_memcpy
31984+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
31985+ MD5Transform (context->state, context->buffer);
31986+
31987+ for (i = partLen; i + 63 < inputLen; i += 64)
31988+ MD5Transform (context->state, &input[i]);
31989+
31990+ index = 0;
31991+ }
31992+ else
31993+ i = 0;
31994+
31995+ /* Buffer remaining input */
31996+ MD5_memcpy
31997+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
31998+ inputLen-i);
31999+}
32000+
32001+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
32002+ the message digest and zeroizing the context.
32003+ */
32004+void osMD5Final (digest, vcontext)
32005+unsigned char digest[16]; /* message digest */
32006+void *vcontext; /* context */
32007+{
32008+ MD5_CTX *context = vcontext;
32009+ unsigned char bits[8];
32010+ unsigned int index, padLen;
32011+
32012+ /* Save number of bits */
32013+ Encode (bits, context->count, 8);
32014+
32015+ /* Pad out to 56 mod 64.
32016+*/
32017+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
32018+ padLen = (index < 56) ? (56 - index) : (120 - index);
32019+ osMD5Update (context, PADDING, padLen);
32020+
32021+ /* Append length (before padding) */
32022+ osMD5Update (context, bits, 8);
32023+
32024+ if (digest != NULL) /* Bill Simpson's padding */
32025+ {
32026+ /* store state in digest */
32027+ Encode (digest, context->state, 16);
32028+
32029+ /* Zeroize sensitive information.
32030+ */
32031+ MD5_memset ((POINTER)context, 0, sizeof (*context));
32032+ }
32033+}
32034+
32035+/* MD5 basic transformation. Transforms state based on block.
32036+ */
32037+static void MD5Transform (state, block)
32038+UINT4 state[4];
32039+unsigned char block[64];
32040+{
32041+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
32042+
32043+ Decode (x, block, 64);
32044+
32045+ /* Round 1 */
32046+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
32047+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
32048+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
32049+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
32050+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
32051+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
32052+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
32053+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
32054+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
32055+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
32056+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
32057+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
32058+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
32059+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
32060+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
32061+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
32062+
32063+ /* Round 2 */
32064+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
32065+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
32066+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
32067+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
32068+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
32069+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
32070+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
32071+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
32072+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
32073+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
32074+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
32075+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
32076+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
32077+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
32078+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
32079+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
32080+
32081+ /* Round 3 */
32082+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
32083+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
32084+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
32085+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
32086+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
32087+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
32088+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
32089+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
32090+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
32091+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
32092+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
32093+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
32094+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
32095+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
32096+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
32097+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
32098+
32099+ /* Round 4 */
32100+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
32101+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
32102+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
32103+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
32104+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
32105+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
32106+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
32107+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
32108+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
32109+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
32110+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
32111+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
32112+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
32113+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
32114+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
32115+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
32116+
32117+ state[0] += a;
32118+ state[1] += b;
32119+ state[2] += c;
32120+ state[3] += d;
32121+
32122+ /* Zeroize sensitive information.
32123+*/
32124+ MD5_memset ((POINTER)x, 0, sizeof (x));
32125+}
32126+
32127+#ifndef LITTLEENDIAN
32128+
32129+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
32130+ a multiple of 4.
32131+ */
32132+static void Encode (output, input, len)
32133+unsigned char *output;
32134+UINT4 *input;
32135+unsigned int len;
32136+{
32137+ unsigned int i, j;
32138+
32139+ for (i = 0, j = 0; j < len; i++, j += 4) {
32140+ output[j] = (unsigned char)(input[i] & 0xff);
32141+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
32142+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
32143+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
32144+ }
32145+}
32146+
32147+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
32148+ a multiple of 4.
32149+ */
32150+static void Decode (output, input, len)
32151+UINT4 *output;
32152+unsigned char *input;
32153+unsigned int len;
32154+{
32155+ unsigned int i, j;
32156+
32157+ for (i = 0, j = 0; j < len; i++, j += 4)
32158+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
32159+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
32160+}
32161+
32162+#endif
32163+
32164+#ifndef HAVEMEMCOPY
32165+#ifndef HAVEBCOPY
32166+/* Note: Replace "for loop" with standard memcpy if possible.
32167+ */
32168+
32169+static void MD5_memcpy (output, input, len)
32170+POINTER output;
32171+POINTER input;
32172+unsigned int len;
32173+{
32174+ unsigned int i;
32175+
32176+ for (i = 0; i < len; i++)
32177+
32178+ output[i] = input[i];
32179+}
32180+
32181+/* Note: Replace "for loop" with standard memset if possible.
32182+ */
32183+
32184+static void MD5_memset (output, value, len)
32185+POINTER output;
32186+int value;
32187+unsigned int len;
32188+{
32189+ unsigned int i;
32190+
32191+ for (i = 0; i < len; i++)
32192+ ((char *)output)[i] = (char)value;
32193+}
32194+#endif
32195+#endif
32196+
32197+/*
32198+ * $Log: ipsec_md5c.c,v $
32199+ * Revision 1.10 2005-04-15 01:25:57 mcr
32200+ * minor fix to comments.
32201+ *
32202+ * Revision 1.9 2004/09/08 17:21:36 ken
32203+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
32204+ *
32205+ * Revision 1.8 2004/04/06 02:49:26 mcr
32206+ * pullup of algo code from alg-branch.
32207+ *
32208+ * Revision 1.7 2002/09/10 01:45:14 mcr
32209+ * changed type of MD5_CTX and SHA1_CTX to void * so that
32210+ * the function prototypes would match, and could be placed
32211+ * into a pointer to a function.
32212+ *
32213+ * Revision 1.6 2002/04/24 07:55:32 mcr
32214+ * #include patches and Makefiles for post-reorg compilation.
32215+ *
32216+ * Revision 1.5 2002/04/24 07:36:28 mcr
32217+ * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
32218+ *
32219+ * Revision 1.4 1999/12/13 13:59:12 rgb
32220+ * Quick fix to argument size to Update bugs.
32221+ *
32222+ * Revision 1.3 1999/05/21 18:09:28 henry
32223+ * unnecessary <memory.h> include causes trouble in 2.2
32224+ *
32225+ * Revision 1.2 1999/04/06 04:54:26 rgb
32226+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
32227+ * patch shell fixes.
32228+ *
32229+ * Revision 1.1 1998/06/18 21:27:48 henry
32230+ * move sources from klips/src to klips/net/ipsec, to keep stupid
32231+ * kernel-build scripts happier in the presence of symlinks
32232+ *
32233+ * Revision 1.2 1998/04/23 20:54:02 rgb
32234+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
32235+ * verified.
32236+ *
32237+ * Revision 1.1 1998/04/09 03:06:08 henry
32238+ * sources moved up from linux/net/ipsec
32239+ *
32240+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
32241+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
32242+ *
32243+ * Revision 0.3 1996/11/20 14:48:53 ji
32244+ * Release update only.
32245+ *
32246+ * Revision 0.2 1996/11/02 00:18:33 ji
32247+ * First limited release.
32248+ *
32249+ *
32250+ */
32251--- /dev/null Tue Mar 11 13:02:56 2003
32252+++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004
32253@@ -0,0 +1,1206 @@
32254+/*
32255+ * @(#) /proc file system interface code.
32256+ *
32257+ * Copyright (C) 1996, 1997 John Ioannidis.
32258+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
32259+ * 2001 Michael Richardson <mcr@freeswan.org>
32260+ *
32261+ * This program is free software; you can redistribute it and/or modify it
32262+ * under the terms of the GNU General Public License as published by the
32263+ * Free Software Foundation; either version 2 of the License, or (at your
32264+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
32265+ *
32266+ * This program is distributed in the hope that it will be useful, but
32267+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
32268+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32269+ * for more details.
32270+ *
32271+ * Split out from ipsec_init.c version 1.70.
32272+ */
32273+
32274+char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.39.2.7 2007-11-06 18:24:44 paul Exp $";
32275+
32276+
32277+#ifndef AUTOCONF_INCLUDED
32278+#include <linux/config.h>
32279+#endif
32280+#include <linux/version.h>
32281+#define __NO_VERSION__
32282+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
32283+#include <linux/moduleparam.h>
32284+#endif
32285+#include <linux/module.h>
32286+#include <linux/kernel.h> /* printk() */
32287+#include <linux/ip.h> /* struct iphdr */
32288+
32289+#include "openswan/ipsec_kversion.h"
32290+#include "openswan/ipsec_param.h"
32291+
32292+#ifdef MALLOC_SLAB
32293+# include <linux/slab.h> /* kmalloc() */
32294+#else /* MALLOC_SLAB */
32295+# include <linux/malloc.h> /* kmalloc() */
32296+#endif /* MALLOC_SLAB */
32297+#include <linux/errno.h> /* error codes */
32298+#include <linux/types.h> /* size_t */
32299+#include <linux/interrupt.h> /* mark_bh */
32300+
32301+#include <linux/netdevice.h> /* struct device, and other headers */
32302+#include <linux/etherdevice.h> /* eth_type_trans */
32303+#include <linux/in.h> /* struct sockaddr_in */
32304+#include <linux/skbuff.h>
32305+#include <asm/uaccess.h> /* copy_from_user */
32306+#include <openswan.h>
32307+#ifdef SPINLOCK
32308+#ifdef SPINLOCK_23
32309+#include <linux/spinlock.h> /* *lock* */
32310+#else /* SPINLOCK_23 */
32311+#include <asm/spinlock.h> /* *lock* */
32312+#endif /* SPINLOCK_23 */
32313+#endif /* SPINLOCK */
32314+
32315+#include <net/ip.h>
32316+#ifdef CONFIG_PROC_FS
32317+#include <linux/proc_fs.h>
32318+#endif /* CONFIG_PROC_FS */
32319+#ifdef NETLINK_SOCK
32320+#include <linux/netlink.h>
32321+#else
32322+#include <net/netlink.h>
32323+#endif
32324+
32325+#include "openswan/radij.h"
32326+
32327+#include "openswan/ipsec_life.h"
32328+#include "openswan/ipsec_stats.h"
32329+#include "openswan/ipsec_sa.h"
32330+
32331+#include "openswan/ipsec_encap.h"
32332+#include "openswan/ipsec_radij.h"
32333+#include "openswan/ipsec_xform.h"
32334+#include "openswan/ipsec_tunnel.h"
32335+#include "openswan/ipsec_xmit.h"
32336+
32337+#include "openswan/ipsec_rcv.h"
32338+#include "openswan/ipsec_ah.h"
32339+#include "openswan/ipsec_esp.h"
32340+#include "openswan/ipsec_kern24.h"
32341+
32342+#ifdef CONFIG_KLIPS_IPCOMP
32343+#include "openswan/ipcomp.h"
32344+#endif /* CONFIG_KLIPS_IPCOMP */
32345+
32346+#include "openswan/ipsec_proto.h"
32347+
32348+#include <pfkeyv2.h>
32349+#include <pfkey.h>
32350+
32351+#ifdef CONFIG_PROC_FS
32352+
32353+#ifdef IPSEC_PROC_SUBDIRS
32354+static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
32355+static struct proc_dir_entry *proc_eroute_dir = NULL;
32356+static struct proc_dir_entry *proc_spi_dir = NULL;
32357+static struct proc_dir_entry *proc_spigrp_dir = NULL;
32358+static struct proc_dir_entry *proc_birth_dir = NULL;
32359+static struct proc_dir_entry *proc_stats_dir = NULL;
32360+#endif
32361+
32362+struct ipsec_birth_reply ipsec_ipv4_birth_packet;
32363+struct ipsec_birth_reply ipsec_ipv6_birth_packet;
32364+
32365+#ifdef CONFIG_KLIPS_DEBUG
32366+int debug_esp = 0;
32367+int debug_ah = 0;
32368+#endif /* CONFIG_KLIPS_DEBUG */
32369+
32370+#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)
32371+
32372+#ifdef CONFIG_KLIPS_ALG
32373+extern int ipsec_xform_get_info(char *buffer, char **start,
32374+ off_t offset, int length IPSEC_PROC_LAST_ARG);
32375+#endif /* CONFIG_KLIPS_ALG */
32376+
32377+
32378+IPSEC_PROCFS_DEBUG_NO_STATIC
32379+int
32380+ipsec_eroute_get_info(char *buffer,
32381+ char **start,
32382+ off_t offset,
32383+ int length IPSEC_PROC_LAST_ARG)
32384+{
32385+ struct wsbuf w = {buffer, length, offset, 0, 0};
32386+
32387+#ifdef CONFIG_KLIPS_DEBUG
32388+ if (debug_radij & DB_RJ_DUMPTREES)
32389+ rj_dumptrees(); /* XXXXXXXXX */
32390+#endif /* CONFIG_KLIPS_DEBUG */
32391+
32392+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32393+ "klips_debug:ipsec_eroute_get_info: "
32394+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32395+ buffer,
32396+ *start,
32397+ (int)offset,
32398+ length);
32399+
32400+ spin_lock_bh(&eroute_lock);
32401+
32402+ rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
32403+/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
32404+
32405+ spin_unlock_bh(&eroute_lock);
32406+
32407+ *start = buffer + (offset - w.begin); /* Start of wanted data */
32408+ return w.len - (offset - w.begin);
32409+}
32410+
32411+IPSEC_PROCFS_DEBUG_NO_STATIC
32412+int
32413+ipsec_spi_get_info(char *buffer,
32414+ char **start,
32415+ off_t offset,
32416+ int length IPSEC_PROC_LAST_ARG)
32417+{
32418+ const int max_content = length > 0? length-1 : 0;
32419+ int len = 0;
32420+ off_t begin = 0;
32421+ int i;
32422+ struct ipsec_sa *sa_p;
32423+ char sa[SATOT_BUF];
32424+ char buf_s[SUBNETTOA_BUF];
32425+ char buf_d[SUBNETTOA_BUF];
32426+ size_t sa_len;
32427+
32428+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32429+ "klips_debug:ipsec_spi_get_info: "
32430+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32431+ buffer,
32432+ *start,
32433+ (int)offset,
32434+ length);
32435+
32436+ spin_lock_bh(&tdb_lock);
32437+
32438+ for (i = 0; i < SADB_HASHMOD; i++) {
32439+ for (sa_p = ipsec_sadb_hash[i];
32440+ sa_p;
32441+ sa_p = sa_p->ips_hnext) {
32442+ atomic_inc(&sa_p->ips_refcount);
32443+ sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
32444+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
32445+ sa_len ? sa : " (error)");
32446+
32447+ len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
32448+ IPS_XFORM_NAME(sa_p));
32449+
32450+ len += ipsec_snprintf(buffer+len, length-len, ": dir=%s",
32451+ (sa_p->ips_flags & EMT_INBOUND) ?
32452+ "in " : "out");
32453+
32454+ if(sa_p->ips_addr_s) {
32455+ addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
32456+ 0, buf_s, sizeof(buf_s));
32457+ len += ipsec_snprintf(buffer+len, length-len, " src=%s",
32458+ buf_s);
32459+ }
32460+
32461+ if((sa_p->ips_said.proto == IPPROTO_IPIP)
32462+ && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
32463+ subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
32464+ sa_p->ips_mask_s.u.v4.sin_addr,
32465+ 0,
32466+ buf_s,
32467+ sizeof(buf_s));
32468+
32469+ subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
32470+ sa_p->ips_mask_d.u.v4.sin_addr,
32471+ 0,
32472+ buf_d,
32473+ sizeof(buf_d));
32474+
32475+ len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
32476+ buf_s, buf_d);
32477+ }
32478+
32479+ if(sa_p->ips_iv_bits) {
32480+ int j;
32481+ len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
32482+ sa_p->ips_iv_bits);
32483+
32484+ for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
32485+ len += ipsec_snprintf(buffer+len, length-len, "%02x",
32486+ (__u32)((__u8*)(sa_p->ips_iv))[j]);
32487+ }
32488+ }
32489+
32490+ if(sa_p->ips_encalg || sa_p->ips_authalg) {
32491+ if(sa_p->ips_replaywin) {
32492+ len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
32493+ sa_p->ips_replaywin);
32494+ }
32495+ if(sa_p->ips_errs.ips_replaywin_errs) {
32496+ len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
32497+ sa_p->ips_errs.ips_replaywin_errs);
32498+ }
32499+ if(sa_p->ips_replaywin_lastseq) {
32500+ len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
32501+ sa_p->ips_replaywin_lastseq);
32502+ }
32503+ if(sa_p->ips_replaywin_bitmap) {
32504+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32505+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
32506+ sa_p->ips_replaywin_bitmap);
32507+#else
32508+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x",
32509+ (__u32)(sa_p->ips_replaywin_bitmap >> 32),
32510+ (__u32)sa_p->ips_replaywin_bitmap);
32511+#endif
32512+ }
32513+ if(sa_p->ips_replaywin_maxdiff) {
32514+ len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
32515+ sa_p->ips_replaywin_maxdiff);
32516+ }
32517+ }
32518+ if(sa_p->ips_flags & ~EMT_INBOUND) {
32519+ len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
32520+ sa_p->ips_flags & ~EMT_INBOUND);
32521+ len += ipsec_snprintf(buffer+len, length-len, "<");
32522+ /* flag printing goes here */
32523+ len += ipsec_snprintf(buffer+len, length-len, ">");
32524+ }
32525+ if(sa_p->ips_auth_bits) {
32526+ len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
32527+ sa_p->ips_auth_bits);
32528+ }
32529+ if(sa_p->ips_key_bits_a) {
32530+ len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
32531+ sa_p->ips_key_bits_a);
32532+ }
32533+ if(sa_p->ips_errs.ips_auth_errs) {
32534+ len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
32535+ sa_p->ips_errs.ips_auth_errs);
32536+ }
32537+ if(sa_p->ips_key_bits_e) {
32538+ len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
32539+ sa_p->ips_key_bits_e);
32540+ }
32541+ if(sa_p->ips_errs.ips_encsize_errs) {
32542+ len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
32543+ sa_p->ips_errs.ips_encsize_errs);
32544+ }
32545+ if(sa_p->ips_errs.ips_encpad_errs) {
32546+ len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
32547+ sa_p->ips_errs.ips_encpad_errs);
32548+ }
32549+
32550+ len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)=");
32551+
32552+ len += ipsec_lifetime_format(buffer + len,
32553+ length - len,
32554+ "alloc",
32555+ ipsec_life_countbased,
32556+ &sa_p->ips_life.ipl_allocations);
32557+
32558+ len += ipsec_lifetime_format(buffer + len,
32559+ length - len,
32560+ "bytes",
32561+ ipsec_life_countbased,
32562+ &sa_p->ips_life.ipl_bytes);
32563+
32564+ len += ipsec_lifetime_format(buffer + len,
32565+ length - len,
32566+ "addtime",
32567+ ipsec_life_timebased,
32568+ &sa_p->ips_life.ipl_addtime);
32569+
32570+ len += ipsec_lifetime_format(buffer + len,
32571+ length - len,
32572+ "usetime",
32573+ ipsec_life_timebased,
32574+ &sa_p->ips_life.ipl_usetime);
32575+
32576+ len += ipsec_lifetime_format(buffer + len,
32577+ length - len,
32578+ "packets",
32579+ ipsec_life_countbased,
32580+ &sa_p->ips_life.ipl_packets);
32581+
32582+ if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
32583+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32584+ len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
32585+ jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
32586+#else
32587+ len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
32588+ jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
32589+#endif
32590+ }
32591+
32592+#ifdef CONFIG_KLIPS_IPCOMP
32593+ if(sa_p->ips_said.proto == IPPROTO_COMP &&
32594+ (sa_p->ips_comp_ratio_dbytes ||
32595+ sa_p->ips_comp_ratio_cbytes)) {
32596+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32597+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
32598+ sa_p->ips_comp_ratio_dbytes,
32599+ sa_p->ips_comp_ratio_cbytes);
32600+#else
32601+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
32602+ (unsigned long)sa_p->ips_comp_ratio_dbytes,
32603+ (unsigned long)sa_p->ips_comp_ratio_cbytes);
32604+#endif
32605+ }
32606+#endif /* CONFIG_KLIPS_IPCOMP */
32607+
32608+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32609+ {
32610+ char *natttype_name;
32611+
32612+ switch(sa_p->ips_natt_type)
32613+ {
32614+ case 0:
32615+ natttype_name="none";
32616+ break;
32617+ case ESPINUDP_WITH_NON_IKE:
32618+ natttype_name="nonike";
32619+ break;
32620+ case ESPINUDP_WITH_NON_ESP:
32621+ natttype_name="nonesp";
32622+ break;
32623+ default:
32624+ natttype_name = "unknown";
32625+ break;
32626+ }
32627+
32628+ len += ipsec_snprintf(buffer + len, length-len, " natencap=%s",
32629+ natttype_name);
32630+
32631+ len += ipsec_snprintf(buffer + len, length-len, " natsport=%d",
32632+ sa_p->ips_natt_sport);
32633+
32634+ len += ipsec_snprintf(buffer + len,length-len, " natdport=%d",
32635+ sa_p->ips_natt_dport);
32636+ }
32637+#else
32638+ len += ipsec_snprintf(buffer + len, length-len, " natencap=na");
32639+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
32640+
32641+ len += ipsec_snprintf(buffer + len,length-len, " refcount=%d",
32642+ atomic_read(&sa_p->ips_refcount));
32643+
32644+ len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
32645+ sa_p->ips_ref);
32646+#ifdef CONFIG_KLIPS_DEBUG
32647+ if(debug_xform) {
32648+ len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
32649+ (unsigned long)IPsecSAref2table(sa_p->ips_ref),
32650+ (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
32651+ }
32652+#endif /* CONFIG_KLIPS_DEBUG */
32653+
32654+ len += ipsec_snprintf(buffer+len, length-len, "\n");
32655+
32656+ atomic_dec(&sa_p->ips_refcount);
32657+
32658+ if (len >= max_content) {
32659+ /* we've done all that can fit -- stop loops */
32660+ len = max_content; /* truncate crap */
32661+ goto done_spi_i;
32662+ } else {
32663+ const off_t pos = begin + len; /* file position of end of what we've generated */
32664+
32665+ if (pos <= offset) {
32666+ /* all is before first interesting character:
32667+ * discard, but note where we are.
32668+ */
32669+ len = 0;
32670+ begin = pos;
32671+ }
32672+ }
32673+ }
32674+ }
32675+
32676+done_spi_i:
32677+ spin_unlock_bh(&tdb_lock);
32678+
32679+ *start = buffer + (offset - begin); /* Start of wanted data */
32680+ return len - (offset - begin);
32681+}
32682+
32683+IPSEC_PROCFS_DEBUG_NO_STATIC
32684+int
32685+ipsec_spigrp_get_info(char *buffer,
32686+ char **start,
32687+ off_t offset,
32688+ int length IPSEC_PROC_LAST_ARG)
32689+{
32690+ /* Limit of useful snprintf output */
32691+ const int max_content = length > 0? length-1 : 0;
32692+
32693+ int len = 0;
32694+ off_t begin = 0;
32695+ int i;
32696+ struct ipsec_sa *sa_p, *sa_p2;
32697+ char sa[SATOT_BUF];
32698+ size_t sa_len;
32699+
32700+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32701+ "klips_debug:ipsec_spigrp_get_info: "
32702+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32703+ buffer,
32704+ *start,
32705+ (int)offset,
32706+ length);
32707+
32708+ spin_lock_bh(&tdb_lock);
32709+
32710+ for (i = 0; i < SADB_HASHMOD; i++) {
32711+ for (sa_p = ipsec_sadb_hash[i];
32712+ sa_p != NULL;
32713+ sa_p = sa_p->ips_hnext)
32714+ {
32715+ atomic_inc(&sa_p->ips_refcount);
32716+ if(sa_p->ips_inext == NULL) {
32717+ sa_p2 = sa_p;
32718+ while(sa_p2 != NULL) {
32719+ atomic_inc(&sa_p2->ips_refcount);
32720+ sa_len = satot(&sa_p2->ips_said,
32721+ 'x', sa, sizeof(sa));
32722+
32723+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
32724+ sa_len ? sa : " (error)");
32725+ atomic_dec(&sa_p2->ips_refcount);
32726+ sa_p2 = sa_p2->ips_onext;
32727+ }
32728+ len += ipsec_snprintf(buffer+len, length-len, "\n");
32729+ }
32730+
32731+ atomic_dec(&sa_p->ips_refcount);
32732+
32733+ if (len >= max_content) {
32734+ /* we've done all that can fit -- stop loops */
32735+ len = max_content; /* truncate crap */
32736+ goto done_spigrp_i;
32737+ } else {
32738+ const off_t pos = begin + len;
32739+
32740+ if (pos <= offset) {
32741+ /* all is before first interesting character:
32742+ * discard, but note where we are.
32743+ */
32744+ len = 0;
32745+ begin = pos;
32746+ }
32747+ }
32748+ }
32749+ }
32750+
32751+done_spigrp_i:
32752+ spin_unlock_bh(&tdb_lock);
32753+
32754+ *start = buffer + (offset - begin); /* Start of wanted data */
32755+ return len - (offset - begin);
32756+}
32757+
32758+
32759+IPSEC_PROCFS_DEBUG_NO_STATIC
32760+int
32761+ipsec_tncfg_get_info(char *buffer,
32762+ char **start,
32763+ off_t offset,
32764+ int length IPSEC_PROC_LAST_ARG)
32765+{
32766+ /* limit of useful snprintf output */
32767+ const int max_content = length > 0? length-1 : 0;
32768+ int len = 0;
32769+ off_t begin = 0;
32770+ int i;
32771+ char name[9];
32772+ struct net_device *dev, *privdev;
32773+ struct ipsecpriv *priv;
32774+
32775+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32776+ "klips_debug:ipsec_tncfg_get_info: "
32777+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32778+ buffer,
32779+ *start,
32780+ (int)offset,
32781+ length);
32782+
32783+ for(i = 0; i < IPSEC_NUM_IF; i++) {
32784+ ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i);
32785+ dev = __ipsec_dev_get(name);
32786+ if(dev) {
32787+ priv = (struct ipsecpriv *)(dev->priv);
32788+ len += ipsec_snprintf(buffer+len, length-len, "%s",
32789+ dev->name);
32790+ if(priv) {
32791+ privdev = (struct net_device *)(priv->dev);
32792+ len += ipsec_snprintf(buffer+len, length-len, " -> %s",
32793+ privdev ? privdev->name : "NULL");
32794+ len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d",
32795+ dev->mtu,
32796+ priv->mtu,
32797+ privdev ? privdev->mtu : 0);
32798+ } else {
32799+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32800+ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
32801+ dev->name);
32802+ }
32803+ len += ipsec_snprintf(buffer+len, length-len, "\n");
32804+
32805+ if (len >= max_content) {
32806+ /* we've done all that can fit -- stop loop */
32807+ len = max_content; /* truncate crap */
32808+ break;
32809+ } else {
32810+ const off_t pos = begin + len;
32811+ if (pos <= offset) {
32812+ len = 0;
32813+ begin = pos;
32814+ }
32815+ }
32816+ }
32817+ }
32818+ *start = buffer + (offset - begin); /* Start of wanted data */
32819+ len -= (offset - begin); /* Start slop */
32820+ if (len > length)
32821+ len = length;
32822+ return len;
32823+}
32824+
32825+IPSEC_PROCFS_DEBUG_NO_STATIC
32826+int
32827+ipsec_version_get_info(char *buffer,
32828+ char **start,
32829+ off_t offset,
32830+ int length IPSEC_PROC_LAST_ARG)
32831+{
32832+ int len = 0;
32833+ off_t begin = 0;
32834+
32835+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32836+ "klips_debug:ipsec_version_get_info: "
32837+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32838+ buffer,
32839+ *start,
32840+ (int)offset,
32841+ length);
32842+
32843+ len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n",
32844+ ipsec_version_code());
32845+#if 0
32846+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32847+ "klips_debug:ipsec_version_get_info: "
32848+ "ipsec_init version: %s\n",
32849+ ipsec_init_c_version);
32850+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32851+ "klips_debug:ipsec_version_get_info: "
32852+ "ipsec_tunnel version: %s\n",
32853+ ipsec_tunnel_c_version);
32854+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32855+ "klips_debug:ipsec_version_get_info: "
32856+ "ipsec_netlink version: %s\n",
32857+ ipsec_netlink_c_version);
32858+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32859+ "klips_debug:ipsec_version_get_info: "
32860+ "radij_c_version: %s\n",
32861+ radij_c_version);
32862+#endif
32863+
32864+
32865+ *start = buffer + (offset - begin); /* Start of wanted data */
32866+ len -= (offset - begin); /* Start slop */
32867+ if (len > length)
32868+ len = length;
32869+ return len;
32870+}
32871+
32872+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32873+unsigned int natt_available = 1;
32874+#else
32875+unsigned int natt_available = 0;
32876+#endif
32877+#ifdef module_param
32878+module_param(natt_available, int, 0444);
32879+#else
32880+MODULE_PARM("natt_available","i");
32881+#endif
32882+
32883+IPSEC_PROCFS_DEBUG_NO_STATIC
32884+int
32885+ipsec_natt_get_info(char *buffer,
32886+ char **start,
32887+ off_t offset,
32888+ int length IPSEC_PROC_LAST_ARG)
32889+{
32890+ int len = 0;
32891+ off_t begin = 0;
32892+
32893+ len += ipsec_snprintf(buffer + len,
32894+ length-len, "%d\n",
32895+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32896+ 1
32897+#else
32898+ 0
32899+#endif
32900+ );
32901+
32902+ *start = buffer + (offset - begin); /* Start of wanted data */
32903+ len -= (offset - begin); /* Start slop */
32904+ if (len > length)
32905+ len = length;
32906+ return len;
32907+}
32908+
32909+IPSEC_PROCFS_DEBUG_NO_STATIC
32910+int
32911+ipsec_birth_info(char *page,
32912+ char **start,
32913+ off_t offset,
32914+ int count,
32915+ int *eof,
32916+ void *data)
32917+{
32918+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32919+ int len;
32920+
32921+ if(offset >= ibr->packet_template_len) {
32922+ if(eof) {
32923+ *eof=1;
32924+ }
32925+ return 0;
32926+ }
32927+
32928+ len = ibr->packet_template_len;
32929+ len -= offset;
32930+ if (len > count)
32931+ len = count;
32932+
32933+ memcpy(page + offset, ibr->packet_template+offset, len);
32934+
32935+ return len;
32936+}
32937+
32938+IPSEC_PROCFS_DEBUG_NO_STATIC
32939+int
32940+ipsec_birth_set(struct file *file, const char *buffer,
32941+ unsigned long count, void *data)
32942+{
32943+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32944+ int len;
32945+
32946+ KLIPS_INC_USE;
32947+ if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
32948+ len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
32949+ } else {
32950+ len = count;
32951+ }
32952+
32953+ if(copy_from_user(ibr->packet_template, buffer, len)) {
32954+ KLIPS_DEC_USE;
32955+ return -EFAULT;
32956+ }
32957+ ibr->packet_template_len = len;
32958+
32959+ KLIPS_DEC_USE;
32960+
32961+ return len;
32962+}
32963+
32964+
32965+#ifdef CONFIG_KLIPS_DEBUG
32966+IPSEC_PROCFS_DEBUG_NO_STATIC
32967+int
32968+ipsec_klipsdebug_get_info(char *buffer,
32969+ char **start,
32970+ off_t offset,
32971+ int length IPSEC_PROC_LAST_ARG)
32972+{
32973+ int len = 0;
32974+ off_t begin = 0;
32975+
32976+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32977+ "klips_debug:ipsec_klipsdebug_get_info: "
32978+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32979+ buffer,
32980+ *start,
32981+ (int)offset,
32982+ length);
32983+
32984+ len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
32985+ len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
32986+ len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
32987+ len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
32988+ len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
32989+ len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
32990+ len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah);
32991+ len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
32992+ len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
32993+
32994+ *start = buffer + (offset - begin); /* Start of wanted data */
32995+ len -= (offset - begin); /* Start slop */
32996+ if (len > length)
32997+ len = length;
32998+ return len;
32999+}
33000+#endif /* CONFIG_KLIPS_DEBUG */
33001+
33002+IPSEC_PROCFS_DEBUG_NO_STATIC
33003+int
33004+ipsec_stats_get_int_info(char *buffer,
33005+ char **start,
33006+ off_t offset,
33007+ int length,
33008+ int *eof,
33009+ void *data)
33010+{
33011+
33012+ const int max_content = length > 0? length-1 : 0;
33013+ int len = 0;
33014+ int *thing;
33015+
33016+ thing = (int *)data;
33017+
33018+ len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing);
33019+
33020+ if (len >= max_content)
33021+ len = max_content; /* truncate crap */
33022+
33023+ *start = buffer + offset; /* Start of wanted data */
33024+ return len > offset? len - offset : 0;
33025+
33026+}
33027+
33028+#ifndef PROC_FS_2325
33029+struct proc_dir_entry ipsec_eroute =
33030+{
33031+ 0,
33032+ 12, "ipsec_eroute",
33033+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
33034+ &proc_net_inode_operations,
33035+ ipsec_eroute_get_info,
33036+ NULL, NULL, NULL, NULL, NULL
33037+};
33038+
33039+struct proc_dir_entry ipsec_spi =
33040+{
33041+ 0,
33042+ 9, "ipsec_spi",
33043+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
33044+ &proc_net_inode_operations,
33045+ ipsec_spi_get_info,
33046+ NULL, NULL, NULL, NULL, NULL
33047+};
33048+
33049+struct proc_dir_entry ipsec_spigrp =
33050+{
33051+ 0,
33052+ 12, "ipsec_spigrp",
33053+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
33054+ &proc_net_inode_operations,
33055+ ipsec_spigrp_get_info,
33056+ NULL, NULL, NULL, NULL, NULL
33057+};
33058+
33059+struct proc_dir_entry ipsec_tncfg =
33060+{
33061+ 0,
33062+ 11, "ipsec_tncfg",
33063+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
33064+ &proc_net_inode_operations,
33065+ ipsec_tncfg_get_info,
33066+ NULL, NULL, NULL, NULL, NULL
33067+};
33068+
33069+struct proc_dir_entry ipsec_version =
33070+{
33071+ 0,
33072+ 13, "ipsec_version",
33073+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
33074+ &proc_net_inode_operations,
33075+ ipsec_version_get_info,
33076+ NULL, NULL, NULL, NULL, NULL
33077+};
33078+
33079+#ifdef CONFIG_KLIPS_DEBUG
33080+struct proc_dir_entry ipsec_klipsdebug =
33081+{
33082+ 0,
33083+ 16, "ipsec_klipsdebug",
33084+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
33085+ &proc_net_inode_operations,
33086+ ipsec_klipsdebug_get_info,
33087+ NULL, NULL, NULL, NULL, NULL
33088+};
33089+#endif /* CONFIG_KLIPS_DEBUG */
33090+#endif /* !PROC_FS_2325 */
33091+#endif /* CONFIG_PROC_FS */
33092+
33093+#if defined(PROC_FS_2325)
33094+struct ipsec_proc_list {
33095+ char *name;
33096+ struct proc_dir_entry **parent;
33097+ struct proc_dir_entry **dir;
33098+ read_proc_t *readthing;
33099+ write_proc_t *writething;
33100+ void *data;
33101+};
33102+static struct ipsec_proc_list proc_items[]={
33103+#ifdef CONFIG_KLIPS_DEBUG
33104+ {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL},
33105+#endif
33106+ {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
33107+ {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL},
33108+ {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL},
33109+ {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL},
33110+ {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
33111+ {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL},
33112+ {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL},
33113+ {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
33114+ {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
33115+ {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL},
33116+#ifdef CONFIG_KLIPS_ALG
33117+ {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL},
33118+#endif /* CONFIG_KLIPS_ALG */
33119+ {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL},
33120+ {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
33121+ {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
33122+ {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL},
33123+ {NULL, NULL, NULL, NULL, NULL, NULL}
33124+};
33125+#endif
33126+
33127+int
33128+ipsec_proc_init()
33129+{
33130+ int error = 0;
33131+#ifdef IPSEC_PROC_SUBDIRS
33132+ struct proc_dir_entry *item;
33133+#endif
33134+
33135+ /*
33136+ * just complain because pluto won't run without /proc!
33137+ */
33138+#ifndef CONFIG_PROC_FS
33139+#error You must have PROC_FS built in to use KLIPS
33140+#endif
33141+
33142+ /* for 2.0 kernels */
33143+#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
33144+ error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
33145+ error |= proc_register_dynamic(&proc_net, &ipsec_spi);
33146+ error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
33147+ error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
33148+ error |= proc_register_dynamic(&proc_net, &ipsec_version);
33149+#ifdef CONFIG_KLIPS_DEBUG
33150+ error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
33151+#endif /* CONFIG_KLIPS_DEBUG */
33152+#endif
33153+
33154+ /* for 2.2 kernels */
33155+#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
33156+ error |= proc_register(proc_net, &ipsec_eroute);
33157+ error |= proc_register(proc_net, &ipsec_spi);
33158+ error |= proc_register(proc_net, &ipsec_spigrp);
33159+ error |= proc_register(proc_net, &ipsec_tncfg);
33160+ error |= proc_register(proc_net, &ipsec_version);
33161+#ifdef CONFIG_KLIPS_DEBUG
33162+ error |= proc_register(proc_net, &ipsec_klipsdebug);
33163+#endif /* CONFIG_KLIPS_DEBUG */
33164+#endif
33165+
33166+ /* for 2.4 kernels */
33167+#if defined(PROC_FS_2325)
33168+ /* create /proc/net/ipsec */
33169+
33170+ /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
33171+ memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
33172+ memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
33173+
33174+ proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
33175+ if(proc_net_ipsec_dir == NULL) {
33176+ /* no point in continuing */
33177+ return 1;
33178+ }
33179+
33180+ {
33181+ struct ipsec_proc_list *it;
33182+
33183+ it=proc_items;
33184+ while(it->name!=NULL) {
33185+ if(it->dir) {
33186+ /* make a dir instead */
33187+ item = proc_mkdir(it->name, *it->parent);
33188+ *it->dir = item;
33189+ } else {
33190+ item = create_proc_entry(it->name, 0400, *it->parent);
33191+ }
33192+ if(item) {
33193+ item->read_proc = it->readthing;
33194+ item->write_proc = it->writething;
33195+ item->data = it->data;
33196+#ifdef MODULE
33197+ item->owner = THIS_MODULE;
33198+#endif
33199+ } else {
33200+ error |= 1;
33201+ }
33202+ it++;
33203+ }
33204+ }
33205+
33206+ /* now create some symlinks to provide compatibility */
33207+ proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
33208+ proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all");
33209+ proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
33210+ proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg");
33211+ proc_symlink("ipsec_version",proc_net, "ipsec/version");
33212+ proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
33213+
33214+#endif /* !PROC_FS_2325 */
33215+
33216+ return error;
33217+}
33218+
33219+void
33220+ipsec_proc_cleanup()
33221+{
33222+
33223+ /* for 2.0 and 2.2 kernels */
33224+#if !defined(PROC_FS_2325)
33225+
33226+#ifdef CONFIG_KLIPS_DEBUG
33227+ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
33228+ printk("klips_debug:ipsec_cleanup: "
33229+ "cannot unregister /proc/net/ipsec_klipsdebug\n");
33230+#endif /* CONFIG_KLIPS_DEBUG */
33231+
33232+ if (proc_net_unregister(ipsec_version.low_ino) != 0)
33233+ printk("klips_debug:ipsec_cleanup: "
33234+ "cannot unregister /proc/net/ipsec_version\n");
33235+ if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
33236+ printk("klips_debug:ipsec_cleanup: "
33237+ "cannot unregister /proc/net/ipsec_eroute\n");
33238+ if (proc_net_unregister(ipsec_spi.low_ino) != 0)
33239+ printk("klips_debug:ipsec_cleanup: "
33240+ "cannot unregister /proc/net/ipsec_spi\n");
33241+ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
33242+ printk("klips_debug:ipsec_cleanup: "
33243+ "cannot unregister /proc/net/ipsec_spigrp\n");
33244+ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
33245+ printk("klips_debug:ipsec_cleanup: "
33246+ "cannot unregister /proc/net/ipsec_tncfg\n");
33247+#endif
33248+
33249+ /* for 2.4 kernels */
33250+#if defined(PROC_FS_2325)
33251+ {
33252+ struct ipsec_proc_list *it;
33253+
33254+ /* find end of list */
33255+ it=proc_items;
33256+ while(it->name!=NULL) {
33257+ it++;
33258+ }
33259+ it--;
33260+
33261+ do {
33262+ remove_proc_entry(it->name, *it->parent);
33263+ it--;
33264+ } while(it >= proc_items);
33265+ }
33266+
33267+
33268+#ifdef CONFIG_KLIPS_DEBUG
33269+ remove_proc_entry("ipsec_klipsdebug", proc_net);
33270+#endif /* CONFIG_KLIPS_DEBUG */
33271+ remove_proc_entry("ipsec_eroute", proc_net);
33272+ remove_proc_entry("ipsec_spi", proc_net);
33273+ remove_proc_entry("ipsec_spigrp", proc_net);
33274+ remove_proc_entry("ipsec_tncfg", proc_net);
33275+ remove_proc_entry("ipsec_version", proc_net);
33276+ remove_proc_entry("ipsec", proc_net);
33277+#endif /* 2.4 kernel */
33278+}
33279+
33280+/*
33281+ * $Log: ipsec_proc.c,v $
33282+ * Revision 1.39.2.7 2007-11-06 18:24:44 paul
33283+ * include linux/moduleparam.h on linux 2.4.x kernels.
33284+ *
33285+ * Revision 1.39.2.6 2007/09/05 02:41:20 paul
33286+ * Added xforms info to /proc file. Patch by David McCullough
33287+ *
33288+ * Revision 1.39.2.5 2007/08/09 14:37:45 paul
33289+ * Patch by sergeil to compile on 2.4.35.
33290+ *
33291+ * Revision 1.39.2.4 2006/11/15 22:21:39 paul
33292+ * backport of creating a /sys/ file to test for nat-t capability in kernel.
33293+ *
33294+ * Revision 1.39.2.3 2006/10/06 21:39:26 paul
33295+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
33296+ * set. This is defined through autoconf.h which is included through the
33297+ * linux kernel build macros.
33298+ *
33299+ * Revision 1.39.2.2 2006/02/13 18:48:12 paul
33300+ * Fix by Ankit Desai <ankit@elitecore.com> for module unloading.
33301+ *
33302+ * Revision 1.39.2.1 2005/09/07 00:45:59 paul
33303+ * pull up of mcr's nat-t klips detection patch from head
33304+ *
33305+ * Revision 1.39 2005/05/20 03:19:18 mcr
33306+ * modifications for use on 2.4.30 kernel, with backported
33307+ * printk_ratelimit(). all warnings removed.
33308+ *
33309+ * Revision 1.38 2005/04/29 05:10:22 mcr
33310+ * removed from extraenous includes to make unit testing easier.
33311+ *
33312+ * Revision 1.37 2005/04/13 22:49:49 mcr
33313+ * moved KLIPS specific snprintf() wrapper to seperate file.
33314+ *
33315+ * Revision 1.36 2005/04/06 17:44:36 mcr
33316+ * when NAT-T is compiled out, show encap as "NA"
33317+ *
33318+ * Revision 1.35 2005/01/26 00:50:35 mcr
33319+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
33320+ * and make sure that NAT_TRAVERSAL is set as well to match
33321+ * userspace compiles of code.
33322+ *
33323+ * Revision 1.34 2004/12/03 21:25:57 mcr
33324+ * compile time fixes for running on 2.6.
33325+ * still experimental.
33326+ *
33327+ * Revision 1.33 2004/08/17 03:27:23 mcr
33328+ * klips 2.6 edits.
33329+ *
33330+ * Revision 1.32 2004/08/03 18:19:08 mcr
33331+ * in 2.6, use "net_device" instead of #define device->net_device.
33332+ * this probably breaks 2.0 compiles.
33333+ *
33334+ * Revision 1.31 2004/07/10 19:11:18 mcr
33335+ * CONFIG_IPSEC -> CONFIG_KLIPS.
33336+ *
33337+ * Revision 1.30 2004/04/25 21:23:11 ken
33338+ * Pull in dhr's changes from FreeS/WAN 2.06
33339+ *
33340+ * Revision 1.29 2004/04/06 02:49:26 mcr
33341+ * pullup of algo code from alg-branch.
33342+ *
33343+ * Revision 1.28 2004/03/28 20:29:58 paul
33344+ * <hugh_> ssize_t, not ssized_t
33345+ *
33346+ * Revision 1.27 2004/03/28 20:27:20 paul
33347+ * Included tested and confirmed fixes mcr made and dhr verified for
33348+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
33349+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
33350+ * dhr. (thanks dhr!)
33351+ *
33352+ * Revision 1.26 2004/02/09 22:07:06 mcr
33353+ * added information about nat-traversal setting to spi-output.
33354+ *
33355+ * Revision 1.25.4.1 2004/04/05 04:30:46 mcr
33356+ * patches for alg-branch to compile/work with 2.x openswan
33357+ *
33358+ * Revision 1.25 2003/10/31 02:27:55 mcr
33359+ * pulled up port-selector patches and sa_id elimination.
33360+ *
33361+ * Revision 1.24.4.1 2003/10/29 01:30:41 mcr
33362+ * elimited "struct sa_id".
33363+ *
33364+ * Revision 1.24 2003/06/20 01:42:21 mcr
33365+ * added counters to measure how many ACQUIREs we send to pluto,
33366+ * and how many are successfully sent.
33367+ *
33368+ * Revision 1.23 2003/04/03 17:38:09 rgb
33369+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
33370+ *
33371+ * Revision 1.22 2002/09/20 15:40:57 rgb
33372+ * Renamed saref macros for consistency and brevity.
33373+ *
33374+ * Revision 1.21 2002/09/20 05:01:35 rgb
33375+ * Print ref and reftable, refentry seperately.
33376+ *
33377+ * Revision 1.20 2002/09/19 02:35:39 mcr
33378+ * do not define structures needed by /proc/net/ipsec/ if we
33379+ * aren't going create that directory.
33380+ *
33381+ * Revision 1.19 2002/09/10 01:43:25 mcr
33382+ * fixed problem in /-* comment.
33383+ *
33384+ * Revision 1.18 2002/09/03 16:22:11 mcr
33385+ * fixed initialization of birth/stuff values - some simple
33386+ * screw ups in the code.
33387+ * removed debugging that was left in by mistake.
33388+ *
33389+ * Revision 1.17 2002/09/02 17:54:53 mcr
33390+ * changed how the table driven /proc entries are created so that
33391+ * making subdirs is now explicit rather than implicit.
33392+ *
33393+ * Revision 1.16 2002/08/30 01:23:37 mcr
33394+ * reorganized /proc creating code to clear up ifdefs,
33395+ * make the 2.4 code table driven, and put things into
33396+ * /proc/net/ipsec subdir. Symlinks are left for compatibility.
33397+ *
33398+ * Revision 1.15 2002/08/13 19:01:25 mcr
33399+ * patches from kenb to permit compilation of FreeSWAN on ia64.
33400+ * des library patched to use proper DES_LONG type for ia64.
33401+ *
33402+ * Revision 1.14 2002/07/26 08:48:31 rgb
33403+ * Added SA ref table code.
33404+ *
33405+ * Revision 1.13 2002/07/24 18:44:54 rgb
33406+ * Type fiddling to tame ia64 compiler.
33407+ *
33408+ * Revision 1.12 2002/05/27 18:56:07 rgb
33409+ * Convert to dynamic ipsec device allocation.
33410+ *
33411+ * Revision 1.11 2002/05/23 07:14:50 rgb
33412+ * Added refcount code.
33413+ * Cleaned up %p variants to 0p%p for test suite cleanup.
33414+ * Convert "usecount" to "refcount" to remove ambiguity.
33415+ *
33416+ * Revision 1.10 2002/04/24 07:55:32 mcr
33417+ * #include patches and Makefiles for post-reorg compilation.
33418+ *
33419+ * Revision 1.9 2002/04/24 07:36:28 mcr
33420+ * Moved from ./klips/net/ipsec/ipsec_proc.c,v
33421+ *
33422+ * Revision 1.8 2002/01/29 17:17:55 mcr
33423+ * moved include of ipsec_param.h to after include of linux/kernel.h
33424+ * otherwise, it seems that some option that is set in ipsec_param.h
33425+ * screws up something subtle in the include path to kernel.h, and
33426+ * it complains on the snprintf() prototype.
33427+ *
33428+ * Revision 1.7 2002/01/29 04:00:52 mcr
33429+ * more excise of kversions.h header.
33430+ *
33431+ * Revision 1.6 2002/01/29 02:13:17 mcr
33432+ * introduction of ipsec_kversion.h means that include of
33433+ * ipsec_param.h must preceed any decisions about what files to
33434+ * include to deal with differences in kernel source.
33435+ *
33436+ * Revision 1.5 2002/01/12 02:54:30 mcr
33437+ * beginnings of /proc/net/ipsec dir.
33438+ *
33439+ * Revision 1.4 2001/12/11 02:21:05 rgb
33440+ * Don't include module version here, fixing 2.2 compile bug.
33441+ *
33442+ * Revision 1.3 2001/12/05 07:19:44 rgb
33443+ * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
33444+ *
33445+ * Revision 1.2 2001/11/26 09:16:14 rgb
33446+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
33447+ *
33448+ * Revision 1.74 2001/11/22 05:44:11 henry
33449+ * new version stuff
33450+ *
33451+ * Revision 1.1.2.1 2001/09/25 02:19:40 mcr
33452+ * /proc manipulation code moved to new ipsec_proc.c
33453+ *
33454+ *
33455+ * Local variables:
33456+ * c-file-style: "linux"
33457+ * End:
33458+ *
33459+ */
33460--- /dev/null Tue Mar 11 13:02:56 2003
33461+++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004
33462@@ -0,0 +1,893 @@
33463+/*
33464+ * Interface between the IPSEC code and the radix (radij) tree code
33465+ * Copyright (C) 1996, 1997 John Ioannidis.
33466+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
33467+ *
33468+ * This program is free software; you can redistribute it and/or modify it
33469+ * under the terms of the GNU General Public License as published by the
33470+ * Free Software Foundation; either version 2 of the License, or (at your
33471+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
33472+ *
33473+ * This program is distributed in the hope that it will be useful, but
33474+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
33475+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33476+ * for more details.
33477+ *
33478+ * RCSID $Id: ipsec_radij.c,v 1.73.2.2 2007-09-05 02:56:09 paul Exp $
33479+ */
33480+
33481+#ifndef AUTOCONF_INCLUDED
33482+#include <linux/config.h>
33483+#endif
33484+#include <linux/version.h>
33485+#include <linux/kernel.h> /* printk() */
33486+
33487+#include "openswan/ipsec_param.h"
33488+
33489+#ifdef MALLOC_SLAB
33490+# include <linux/slab.h> /* kmalloc() */
33491+#else /* MALLOC_SLAB */
33492+# include <linux/malloc.h> /* kmalloc() */
33493+#endif /* MALLOC_SLAB */
33494+#include <linux/errno.h> /* error codes */
33495+#include <linux/types.h> /* size_t */
33496+#include <linux/interrupt.h> /* mark_bh */
33497+
33498+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
33499+#include <linux/etherdevice.h> /* eth_type_trans */
33500+#include <linux/ip.h> /* struct iphdr */
33501+#include <linux/skbuff.h>
33502+#include <openswan.h>
33503+#ifdef SPINLOCK
33504+# ifdef SPINLOCK_23
33505+# include <linux/spinlock.h> /* *lock* */
33506+# else /* 23_SPINLOCK */
33507+# include <asm/spinlock.h> /* *lock* */
33508+# endif /* 23_SPINLOCK */
33509+#endif /* SPINLOCK */
33510+
33511+#include <net/ip.h>
33512+
33513+#include "openswan/ipsec_eroute.h"
33514+#include "openswan/ipsec_sa.h"
33515+
33516+#include "openswan/radij.h"
33517+#include "openswan/ipsec_encap.h"
33518+#include "openswan/radij.h"
33519+#include "openswan/ipsec_encap.h"
33520+#include "openswan/ipsec_radij.h"
33521+#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */
33522+#include "openswan/ipsec_xform.h"
33523+
33524+#include <pfkeyv2.h>
33525+#include <pfkey.h>
33526+
33527+#include "openswan/ipsec_proto.h"
33528+
33529+#ifdef CONFIG_KLIPS_DEBUG
33530+int debug_radij = 0;
33531+#endif /* CONFIG_KLIPS_DEBUG */
33532+
33533+struct radij_node_head *rnh = NULL;
33534+#ifdef SPINLOCK
33535+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
33536+#else /* SPINLOCK */
33537+spinlock_t eroute_lock;
33538+#endif /* SPINLOCK */
33539+
33540+int
33541+ipsec_radijinit(void)
33542+{
33543+ maj_keylen = sizeof (struct sockaddr_encap);
33544+
33545+ rj_init();
33546+
33547+ if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
33548+ return -1;
33549+ return 0;
33550+}
33551+
33552+int
33553+ipsec_radijcleanup(void)
33554+{
33555+ int error;
33556+
33557+ spin_lock_bh(&eroute_lock);
33558+
33559+ error = radijcleanup();
33560+
33561+ spin_unlock_bh(&eroute_lock);
33562+
33563+ return error;
33564+}
33565+
33566+int
33567+ipsec_cleareroutes(void)
33568+{
33569+ int error;
33570+
33571+ spin_lock_bh(&eroute_lock);
33572+
33573+ error = radijcleartree();
33574+
33575+ spin_unlock_bh(&eroute_lock);
33576+
33577+ return error;
33578+}
33579+
33580+int
33581+ipsec_breakroute(struct sockaddr_encap *eaddr,
33582+ struct sockaddr_encap *emask,
33583+ struct sk_buff **first,
33584+ struct sk_buff **last)
33585+{
33586+ struct eroute *ro;
33587+ struct radij_node *rn;
33588+ int error;
33589+#ifdef CONFIG_KLIPS_DEBUG
33590+
33591+ if (debug_eroute) {
33592+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33593+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33594+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33595+ KLIPS_PRINT(debug_eroute,
33596+ "klips_debug:ipsec_breakroute: "
33597+ "attempting to delete eroute for %s:%d->%s:%d %d\n",
33598+ buf1, ntohs(eaddr->sen_sport),
33599+ buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
33600+ }
33601+#endif /* CONFIG_KLIPS_DEBUG */
33602+
33603+ spin_lock_bh(&eroute_lock);
33604+
33605+ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
33606+ spin_unlock_bh(&eroute_lock);
33607+ KLIPS_PRINT(debug_eroute,
33608+ "klips_debug:ipsec_breakroute: "
33609+ "node not found, eroute delete failed.\n");
33610+ return error;
33611+ }
33612+
33613+ spin_unlock_bh(&eroute_lock);
33614+
33615+ ro = (struct eroute *)rn;
33616+
33617+ KLIPS_PRINT(debug_eroute,
33618+ "klips_debug:ipsec_breakroute: "
33619+ "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
33620+ ro,
33621+ ro->er_ident_s.data,
33622+ ro->er_ident_d.data,
33623+ ro->er_first,
33624+ ro->er_last);
33625+
33626+ if (ro->er_ident_s.data != NULL) {
33627+ kfree(ro->er_ident_s.data);
33628+ }
33629+ if (ro->er_ident_d.data != NULL) {
33630+ kfree(ro->er_ident_d.data);
33631+ }
33632+ if (ro->er_first != NULL) {
33633+#if 0
33634+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
33635+ stats->tx_dropped--;
33636+#endif
33637+ *first = ro->er_first;
33638+ }
33639+ if (ro->er_last != NULL) {
33640+#if 0
33641+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
33642+ stats->tx_dropped--;
33643+#endif
33644+ *last = ro->er_last;
33645+ }
33646+
33647+ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
33648+ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
33649+ memset((caddr_t)rn, 0, sizeof (struct eroute));
33650+ kfree(rn);
33651+
33652+ return 0;
33653+}
33654+
33655+int
33656+ipsec_makeroute(struct sockaddr_encap *eaddr,
33657+ struct sockaddr_encap *emask,
33658+ ip_said said,
33659+ uint32_t pid,
33660+ struct sk_buff *skb,
33661+ struct ident *ident_s,
33662+ struct ident *ident_d)
33663+{
33664+ struct eroute *retrt;
33665+ int error;
33666+ char sa[SATOT_BUF];
33667+ size_t sa_len;
33668+
33669+#ifdef CONFIG_KLIPS_DEBUG
33670+
33671+ if (debug_eroute) {
33672+
33673+ {
33674+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33675+
33676+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33677+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33678+ sa_len = satot(&said, 0, sa, sizeof(sa));
33679+ KLIPS_PRINT(debug_eroute,
33680+ "klips_debug:ipsec_makeroute: "
33681+ "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
33682+ (unsigned long) sizeof(struct eroute),
33683+ buf1,
33684+ buf2,
33685+ sa_len ? sa : " (error)",
33686+ pid,
33687+ skb,
33688+ (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
33689+ (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
33690+ }
33691+ {
33692+ char buf1[sizeof(struct sockaddr_encap)*2 + 1],
33693+ buf2[sizeof(struct sockaddr_encap)*2 + 1];
33694+ int i;
33695+ unsigned char *b1 = buf1,
33696+ *b2 = buf2,
33697+ *ea = (unsigned char *)eaddr,
33698+ *em = (unsigned char *)emask;
33699+
33700+
33701+ for (i=0; i<sizeof(struct sockaddr_encap); i++) {
33702+ sprintf(b1, "%02x", ea[i]);
33703+ sprintf(b2, "%02x", em[i]);
33704+ b1+=2;
33705+ b2+=2;
33706+ }
33707+ KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
33708+ }
33709+
33710+ }
33711+#endif /* CONFIG_KLIPS_DEBUG */
33712+
33713+ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
33714+ if (retrt == NULL) {
33715+ printk("klips_error:ipsec_makeroute: "
33716+ "not able to allocate kernel memory");
33717+ return -ENOMEM;
33718+ }
33719+ memset((caddr_t)retrt, 0, sizeof (struct eroute));
33720+
33721+ retrt->er_eaddr = *eaddr;
33722+ retrt->er_emask = *emask;
33723+ retrt->er_said = said;
33724+ retrt->er_pid = pid;
33725+ retrt->er_count = 0;
33726+ retrt->er_lasttime = jiffies/HZ;
33727+
33728+ {
33729+ /* this is because gcc 3. doesn't like cast's as lvalues */
33730+ struct rjtentry *rje = (struct rjtentry *)&(retrt->er_rjt);
33731+ caddr_t er = (caddr_t)&(retrt->er_eaddr);
33732+
33733+ rje->rd_nodes->rj_key= er;
33734+ }
33735+
33736+ if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
33737+ int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33738+
33739+ retrt->er_ident_s.type = ident_s->type;
33740+ retrt->er_ident_s.id = ident_s->id;
33741+ retrt->er_ident_s.len = ident_s->len;
33742+ if(data_len) {
33743+ KLIPS_PRINT(debug_eroute,
33744+ "klips_debug:ipsec_makeroute: "
33745+ "attempting to allocate %u bytes for ident_s.\n",
33746+ data_len);
33747+ if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
33748+ kfree(retrt);
33749+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33750+ return ENOMEM;
33751+ }
33752+ memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
33753+ } else {
33754+ retrt->er_ident_s.data = NULL;
33755+ }
33756+ }
33757+
33758+ if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
33759+ int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33760+
33761+ retrt->er_ident_d.type = ident_d->type;
33762+ retrt->er_ident_d.id = ident_d->id;
33763+ retrt->er_ident_d.len = ident_d->len;
33764+ if(data_len) {
33765+ KLIPS_PRINT(debug_eroute,
33766+ "klips_debug:ipsec_makeroute: "
33767+ "attempting to allocate %u bytes for ident_d.\n",
33768+ data_len);
33769+ if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
33770+ if (retrt->er_ident_s.data)
33771+ kfree(retrt->er_ident_s.data);
33772+ kfree(retrt);
33773+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33774+ return ENOMEM;
33775+ }
33776+ memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
33777+ } else {
33778+ retrt->er_ident_d.data = NULL;
33779+ }
33780+ }
33781+ retrt->er_first = skb;
33782+ retrt->er_last = NULL;
33783+
33784+ KLIPS_PRINT(debug_eroute,
33785+ "klips_debug:ipsec_makeroute: "
33786+ "calling rj_addroute now\n");
33787+
33788+ spin_lock_bh(&eroute_lock);
33789+
33790+ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
33791+ rnh, retrt->er_rjt.rd_nodes);
33792+
33793+ spin_unlock_bh(&eroute_lock);
33794+
33795+ if(error) {
33796+ sa_len = KLIPS_SATOT(debug_eroute, &said, 0, sa, sizeof(sa));
33797+ KLIPS_PRINT(debug_eroute,
33798+ "klips_debug:ipsec_makeroute: "
33799+ "rj_addroute not able to insert eroute for SA:%s (error:%d)\n",
33800+ sa_len ? sa : " (error)", error);
33801+ if (retrt->er_ident_s.data)
33802+ kfree(retrt->er_ident_s.data);
33803+ if (retrt->er_ident_d.data)
33804+ kfree(retrt->er_ident_d.data);
33805+
33806+ kfree(retrt);
33807+
33808+ return error;
33809+ }
33810+
33811+#ifdef CONFIG_KLIPS_DEBUG
33812+ if (debug_eroute) {
33813+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33814+/*
33815+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33816+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33817+*/
33818+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
33819+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
33820+ sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa));
33821+
33822+ KLIPS_PRINT(debug_eroute,
33823+ "klips_debug:ipsec_makeroute: "
33824+ "pid=%05d "
33825+ "count=%10d "
33826+ "lasttime=%6d "
33827+ "%-18s -> %-18s => %s\n",
33828+ retrt->er_pid,
33829+ retrt->er_count,
33830+ (int)(jiffies/HZ - retrt->er_lasttime),
33831+ buf1,
33832+ buf2,
33833+ sa_len ? sa : " (error)");
33834+ }
33835+#endif /* CONFIG_KLIPS_DEBUG */
33836+ KLIPS_PRINT(debug_eroute,
33837+ "klips_debug:ipsec_makeroute: "
33838+ "succeeded.\n");
33839+ return 0;
33840+}
33841+
33842+struct eroute *
33843+ipsec_findroute(struct sockaddr_encap *eaddr)
33844+{
33845+ struct radij_node *rn;
33846+#ifdef CONFIG_KLIPS_DEBUG
33847+ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
33848+
33849+ if (debug_radij & DB_RJ_FINDROUTE) {
33850+ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
33851+ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
33852+ KLIPS_PRINT(debug_eroute,
33853+ "klips_debug:ipsec_findroute: "
33854+ "%s:%d->%s:%d %d\n",
33855+ buf1, ntohs(eaddr->sen_sport),
33856+ buf2, ntohs(eaddr->sen_dport),
33857+ eaddr->sen_proto);
33858+ }
33859+#endif /* CONFIG_KLIPS_DEBUG */
33860+ rn = rj_match((caddr_t)eaddr, rnh);
33861+ if(rn) {
33862+ KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
33863+ "klips_debug:ipsec_findroute: "
33864+ "found, points to proto=%d, spi=%x, dst=%x.\n",
33865+ ((struct eroute*)rn)->er_said.proto,
33866+ ntohl(((struct eroute*)rn)->er_said.spi),
33867+ ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr));
33868+ }
33869+ return (struct eroute *)rn;
33870+}
33871+
33872+#ifdef CONFIG_PROC_FS
33873+/** ipsec_rj_walker_procprint: print one line of eroute table output.
33874+ *
33875+ * Theoretical BUG: if w->length is less than the length
33876+ * of some line we should produce, that line will never
33877+ * be finished. In effect, the "file" will stop part way
33878+ * through that line.
33879+ */
33880+int
33881+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
33882+{
33883+ struct eroute *ro = (struct eroute *)rn;
33884+ struct rjtentry *rd = (struct rjtentry *)rn;
33885+ struct wsbuf *w = (struct wsbuf *)w0;
33886+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33887+ char buf3[16];
33888+ char sa[SATOT_BUF];
33889+ size_t sa_len, buf_len;
33890+ struct sockaddr_encap *key, *mask;
33891+
33892+ KLIPS_PRINT(debug_radij,
33893+ "klips_debug:ipsec_rj_walker_procprint: "
33894+ "rn=0p%p, w0=0p%p\n",
33895+ rn,
33896+ w0);
33897+ if (rn->rj_b >= 0) {
33898+ return 0;
33899+ }
33900+
33901+ key = rd_key(rd);
33902+ mask = rd_mask(rd);
33903+
33904+ if (key == NULL || mask == NULL) {
33905+ return 0;
33906+ }
33907+
33908+ buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33909+ if(key->sen_sport != 0) {
33910+ sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
33911+ }
33912+
33913+ buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33914+ if(key->sen_dport != 0) {
33915+ sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
33916+ }
33917+
33918+ buf3[0]='\0';
33919+ if(key->sen_proto != 0) {
33920+ sprintf(buf3, ":%d", key->sen_proto);
33921+ }
33922+
33923+ sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa));
33924+ w->len += ipsec_snprintf(w->buffer + w->len,
33925+ w->length - w->len,
33926+ "%-10d "
33927+ "%-18s -> %-18s => %s%s\n",
33928+ ro->er_count,
33929+ buf1,
33930+ buf2,
33931+ sa_len ? sa : " (error)",
33932+ buf3);
33933+
33934+ {
33935+ /* snprintf can only fill the last character with NUL
33936+ * so the maximum useful character is w->length-1.
33937+ * However, if w->length == 0, we cannot go back.
33938+ * (w->length surely cannot be negative.)
33939+ */
33940+ int max_content = w->length > 0? w->length-1 : 0;
33941+
33942+ if (w->len >= max_content) {
33943+ /* we've done all that can fit -- stop treewalking */
33944+ w->len = max_content; /* truncate crap */
33945+ return -ENOBUFS;
33946+ } else {
33947+ const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
33948+
33949+ if (pos <= w->offset) {
33950+ /* all is before first interesting character:
33951+ * discard, but note where we are.
33952+ */
33953+ w->len = 0;
33954+ w->begin = pos;
33955+ }
33956+ return 0;
33957+ }
33958+ }
33959+}
33960+#endif /* CONFIG_PROC_FS */
33961+
33962+int
33963+ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
33964+{
33965+ struct eroute *ro;
33966+ struct rjtentry *rd = (struct rjtentry *)rn;
33967+ struct radij_node *rn2;
33968+ int error;
33969+ struct sockaddr_encap *key, *mask;
33970+
33971+ key = rd_key(rd);
33972+ mask = rd_mask(rd);
33973+
33974+ if(!key || !mask) {
33975+ return -ENODATA;
33976+ }
33977+#ifdef CONFIG_KLIPS_DEBUG
33978+ if(debug_radij) {
33979+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33980+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33981+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33982+ KLIPS_PRINT(debug_radij,
33983+ "klips_debug:ipsec_rj_walker_delete: "
33984+ "deleting: %s -> %s\n",
33985+ buf1,
33986+ buf2);
33987+ }
33988+#endif /* CONFIG_KLIPS_DEBUG */
33989+
33990+ if((error = rj_delete(key, mask, rnh, &rn2))) {
33991+ KLIPS_PRINT(debug_radij,
33992+ "klips_debug:ipsec_rj_walker_delete: "
33993+ "rj_delete failed with error=%d.\n", error);
33994+ return error;
33995+ }
33996+
33997+ if(rn2 != rn) {
33998+ printk("klips_debug:ipsec_rj_walker_delete: "
33999+ "tried to delete a different node?!? This should never happen!\n");
34000+ }
34001+
34002+ ro = (struct eroute *)rn;
34003+
34004+ if (ro->er_ident_s.data)
34005+ kfree(ro->er_ident_s.data);
34006+ if (ro->er_ident_d.data)
34007+ kfree(ro->er_ident_d.data);
34008+
34009+ memset((caddr_t)rn, 0, sizeof (struct eroute));
34010+ kfree(rn);
34011+
34012+ return 0;
34013+}
34014+
34015+/*
34016+ * $Log: ipsec_radij.c,v $
34017+ * Revision 1.73.2.2 2007-09-05 02:56:09 paul
34018+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
34019+ * Fixes based on David McCullough patch.
34020+ *
34021+ * Revision 1.73.2.1 2006/10/06 21:39:26 paul
34022+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
34023+ * set. This is defined through autoconf.h which is included through the
34024+ * linux kernel build macros.
34025+ *
34026+ * Revision 1.73 2005/04/29 05:10:22 mcr
34027+ * removed from extraenous includes to make unit testing easier.
34028+ *
34029+ * Revision 1.72 2004/12/03 21:25:57 mcr
34030+ * compile time fixes for running on 2.6.
34031+ * still experimental.
34032+ *
34033+ * Revision 1.71 2004/07/10 19:11:18 mcr
34034+ * CONFIG_IPSEC -> CONFIG_KLIPS.
34035+ *
34036+ * Revision 1.70 2004/04/25 21:10:52 ken
34037+ * Pull in dhr's changes from FreeS/WAN 2.06
34038+ *
34039+ * Revision 1.69 2004/04/06 02:49:26 mcr
34040+ * pullup of algo code from alg-branch.
34041+ *
34042+ * Revision 1.68 2004/03/28 20:27:20 paul
34043+ * Included tested and confirmed fixes mcr made and dhr verified for
34044+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
34045+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
34046+ * dhr. (thanks dhr!)
34047+ *
34048+ * Revision 1.67.4.1 2004/04/05 04:30:46 mcr
34049+ * patches for alg-branch to compile/work with 2.x openswan
34050+ *
34051+ * Revision 1.67 2003/10/31 02:27:55 mcr
34052+ * pulled up port-selector patches and sa_id elimination.
34053+ *
34054+ * Revision 1.66.24.2 2003/10/29 01:30:41 mcr
34055+ * elimited "struct sa_id".
34056+ *
34057+ * Revision 1.66.24.1 2003/09/21 13:59:56 mcr
34058+ * pre-liminary X.509 patch - does not yet pass tests.
34059+ *
34060+ * Revision 1.66 2002/10/12 23:11:53 dhr
34061+ *
34062+ * [KenB + DHR] more 64-bit cleanup
34063+ *
34064+ * Revision 1.65 2002/09/20 05:01:40 rgb
34065+ * Added memory allocation debugging.
34066+ *
34067+ * Revision 1.64 2002/05/31 01:46:05 mcr
34068+ * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute
34069+ * as requested in PR#14.
34070+ *
34071+ * Revision 1.63 2002/05/23 07:14:11 rgb
34072+ * Cleaned up %p variants to 0p%p for test suite cleanup.
34073+ *
34074+ * Revision 1.62 2002/04/24 07:55:32 mcr
34075+ * #include patches and Makefiles for post-reorg compilation.
34076+ *
34077+ * Revision 1.61 2002/04/24 07:36:29 mcr
34078+ * Moved from ./klips/net/ipsec/ipsec_radij.c,v
34079+ *
34080+ * Revision 1.60 2002/02/19 23:59:45 rgb
34081+ * Removed redundant compiler directives.
34082+ *
34083+ * Revision 1.59 2002/02/06 04:13:47 mcr
34084+ * missing #ifdef CONFIG_IPSEC_DEBUG.
34085+ *
34086+ * Revision 1.58 2002/01/29 17:17:56 mcr
34087+ * moved include of ipsec_param.h to after include of linux/kernel.h
34088+ * otherwise, it seems that some option that is set in ipsec_param.h
34089+ * screws up something subtle in the include path to kernel.h, and
34090+ * it complains on the snprintf() prototype.
34091+ *
34092+ * Revision 1.57 2002/01/29 04:00:52 mcr
34093+ * more excise of kversions.h header.
34094+ *
34095+ * Revision 1.56 2002/01/29 02:13:17 mcr
34096+ * introduction of ipsec_kversion.h means that include of
34097+ * ipsec_param.h must preceed any decisions about what files to
34098+ * include to deal with differences in kernel source.
34099+ *
34100+ * Revision 1.55 2001/11/26 09:23:48 rgb
34101+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
34102+ *
34103+ * Revision 1.53.2.1 2001/09/25 02:26:32 mcr
34104+ * headers adjusted for new usage.
34105+ *
34106+ * Revision 1.54 2001/10/18 04:45:20 rgb
34107+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
34108+ * lib/freeswan.h version macros moved to lib/kversions.h.
34109+ * Other compiler directive cleanups.
34110+ *
34111+ * Revision 1.53 2001/09/19 17:19:40 rgb
34112+ * Debug output bugfix for NetCelo's PF_KEY ident patch.
34113+ *
34114+ * Revision 1.52 2001/09/19 16:33:37 rgb
34115+ * Temporarily disable ident fields to /proc/net/ipsec_eroute.
34116+ *
34117+ * Revision 1.51 2001/09/15 16:24:04 rgb
34118+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
34119+ *
34120+ * Revision 1.50 2001/09/14 16:58:36 rgb
34121+ * Added support for storing the first and last packets through a HOLD.
34122+ *
34123+ * Revision 1.49 2001/09/08 21:13:32 rgb
34124+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
34125+ *
34126+ * Revision 1.48 2001/06/15 04:12:56 rgb
34127+ * Fixed kernel memory allocation error return code polarity bug.
34128+ *
34129+ * Revision 1.47 2001/06/14 19:35:09 rgb
34130+ * Update copyright date.
34131+ *
34132+ * Revision 1.46 2001/06/08 08:47:18 rgb
34133+ * Fixed for debug disabled.
34134+ *
34135+ * Revision 1.45 2001/05/27 06:12:11 rgb
34136+ * Added structures for pid, packet count and last access time to eroute.
34137+ * Added packet count to beginning of /proc/net/ipsec_eroute.
34138+ *
34139+ * Revision 1.44 2001/05/03 19:41:01 rgb
34140+ * Initialise error return variable.
34141+ * Use more appropriate return value for ipsec_rj_walker_delete().
34142+ *
34143+ * Revision 1.43 2001/02/27 22:24:54 rgb
34144+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
34145+ * Check for satoa() return codes.
34146+ *
34147+ * Revision 1.42 2001/02/27 06:21:57 rgb
34148+ * Added findroute success instrumentation.
34149+ *
34150+ * Revision 1.41 2000/11/06 04:32:08 rgb
34151+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
34152+ *
34153+ * Revision 1.40 2000/09/08 19:12:56 rgb
34154+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
34155+ *
34156+ * Revision 1.39 2000/08/30 05:25:20 rgb
34157+ * Correct debug text in ipsec_breakroute() from incorrect
34158+ * "ipsec_callback".
34159+ *
34160+ * Revision 1.38 2000/07/28 14:58:31 rgb
34161+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
34162+ *
34163+ * Revision 1.37 2000/03/16 14:02:50 rgb
34164+ * Fixed debug scope to enable compilation with debug off.
34165+ *
34166+ * Revision 1.36 2000/01/21 06:14:46 rgb
34167+ * Added debugging text to ipsec_rj_walker_delete().
34168+ * Set return code to negative for consistency.
34169+ *
34170+ * Revision 1.35 1999/11/23 23:05:24 rgb
34171+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
34172+ *
34173+ * Revision 1.34 1999/11/18 04:13:56 rgb
34174+ * Replaced all kernel version macros to shorter, readable form.
34175+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
34176+ *
34177+ * Revision 1.33 1999/11/17 15:53:39 rgb
34178+ * Changed all occurrences of #include "../../../lib/freeswan.h"
34179+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
34180+ * klips/net/ipsec/Makefile.
34181+ *
34182+ * Revision 1.32 1999/10/26 13:58:33 rgb
34183+ * Put spinlock flags variable declaration outside the debug compiler
34184+ * directive to enable compilation with debug shut off.
34185+ *
34186+ * Revision 1.31 1999/10/15 22:13:29 rgb
34187+ * Clean out cruft.
34188+ * Align /proc/net/ipsec_eroute output for easier readability.
34189+ * Fix double linefeed in radij debug output.
34190+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
34191+ *
34192+ * Revision 1.30 1999/10/08 18:37:33 rgb
34193+ * Fix end-of-line spacing to sate whining PHMs.
34194+ *
34195+ * Revision 1.29 1999/10/03 18:52:45 rgb
34196+ * Spinlock support for 2.0.xx.
34197+ * Dumb return code spin_unlock fix.
34198+ *
34199+ * Revision 1.28 1999/10/01 16:22:24 rgb
34200+ * Switch from assignment init. to functional init. of spinlocks.
34201+ *
34202+ * Revision 1.27 1999/10/01 15:44:53 rgb
34203+ * Move spinlock header include to 2.1> scope.
34204+ *
34205+ * Revision 1.26 1999/10/01 00:01:23 rgb
34206+ * Added eroute structure locking.
34207+ *
34208+ * Revision 1.25 1999/06/10 16:07:30 rgb
34209+ * Silence delete eroute on no debug.
34210+ *
34211+ * Revision 1.24 1999/05/09 03:25:36 rgb
34212+ * Fix bug introduced by 2.2 quick-and-dirty patch.
34213+ *
34214+ * Revision 1.23 1999/05/05 22:02:31 rgb
34215+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
34216+ *
34217+ * Revision 1.22 1999/04/29 15:17:23 rgb
34218+ * Add return values to init and cleanup functions.
34219+ * Add sanity checking for null pointer arguments.
34220+ *
34221+ * Revision 1.21 1999/04/11 00:28:58 henry
34222+ * GPL boilerplate
34223+ *
34224+ * Revision 1.20 1999/04/06 04:54:26 rgb
34225+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
34226+ * patch shell fixes.
34227+ *
34228+ * Revision 1.19 1999/02/17 16:50:35 rgb
34229+ * Clean out unused cruft.
34230+ * Consolidate for space and speed efficiency.
34231+ * Convert DEBUG_IPSEC to KLIPS_PRINT
34232+ *
34233+ * Revision 1.18 1999/01/22 06:22:06 rgb
34234+ * Cruft clean-out.
34235+ * 64-bit clean-up.
34236+ *
34237+ * Revision 1.17 1998/12/02 03:09:39 rgb
34238+ * Clean up debug printing conditionals to compile with debugging off.
34239+ *
34240+ * Revision 1.16 1998/12/01 13:49:39 rgb
34241+ * Wrap version info printing in debug switches.
34242+ *
34243+ * Revision 1.15 1998/11/30 13:22:54 rgb
34244+ * Rationalised all the klips kernel file headers. They are much shorter
34245+ * now and won't conflict under RH5.2.
34246+ *
34247+ * Revision 1.14 1998/10/31 06:48:17 rgb
34248+ * Fixed up comments in #endif directives.
34249+ *
34250+ * Revision 1.13 1998/10/27 13:48:09 rgb
34251+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
34252+ * Fixed less(1) truncated output bug.
34253+ * Code clean-up.
34254+ *
34255+ * Revision 1.12 1998/10/25 02:41:36 rgb
34256+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
34257+ * argument to be able to transmit more infomation about errors.
34258+ * Fix cut-and-paste debug statement identifier.
34259+ *
34260+ * Revision 1.11 1998/10/22 06:45:39 rgb
34261+ * Cleaned up cruft.
34262+ * Convert to use satoa for printk.
34263+ *
34264+ * Revision 1.10 1998/10/19 14:44:28 rgb
34265+ * Added inclusion of freeswan.h.
34266+ * sa_id structure implemented and used: now includes protocol.
34267+ *
34268+ * Revision 1.9 1998/10/09 04:30:52 rgb
34269+ * Added 'klips_debug' prefix to all klips printk debug statements.
34270+ * Deleted old commented out cruft.
34271+ *
34272+ * Revision 1.8 1998/08/06 17:24:23 rgb
34273+ * Fix addrtoa return code bug from stale manpage advice preventing packets
34274+ * from being erouted.
34275+ *
34276+ * Revision 1.7 1998/08/06 07:44:59 rgb
34277+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
34278+ * ended up in nothing being printed.
34279+ *
34280+ * Revision 1.6 1998/08/05 22:16:41 rgb
34281+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
34282+ *
34283+ * Revision 1.5 1998/07/29 20:38:44 rgb
34284+ * Debug and fix subnettoa and addrtoa output.
34285+ *
34286+ * Revision 1.4 1998/07/28 00:02:39 rgb
34287+ * Converting to exclusive use of addrtoa.
34288+ * Fix eroute delete.
34289+ *
34290+ * Revision 1.3 1998/07/14 18:21:26 rgb
34291+ * Add function to clear the eroute table.
34292+ *
34293+ * Revision 1.2 1998/06/23 02:59:14 rgb
34294+ * Added debugging output to eroute add/delete routines.
34295+ *
34296+ * Revision 1.9 1998/06/18 21:29:06 henry
34297+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
34298+ * build scripts happier in presence of symbolic links
34299+ *
34300+ * Revision 1.8 1998/06/05 02:32:26 rgb
34301+ * Fix spi ntoh kernel debug output.
34302+ *
34303+ * Revision 1.7 1998/05/25 20:30:37 rgb
34304+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
34305+ *
34306+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
34307+ * add ipsec_rj_walker_delete.
34308+ *
34309+ * Revision 1.6 1998/05/21 13:08:57 rgb
34310+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
34311+ * information is available for printout.
34312+ *
34313+ * Revision 1.5 1998/05/18 21:35:55 rgb
34314+ * Clean up output for numerical consistency and readability. Zero freed
34315+ * eroute memory.
34316+ *
34317+ * Revision 1.4 1998/04/21 21:28:58 rgb
34318+ * Rearrange debug switches to change on the fly debug output from user
34319+ * space. Only kernel changes checked in at this time. radij.c was also
34320+ * changed to temporarily remove buggy debugging code in rj_delete causing
34321+ * an OOPS and hence, netlink device open errors.
34322+ *
34323+ * Revision 1.3 1998/04/14 17:30:39 rgb
34324+ * Fix up compiling errors for radij tree memory reclamation.
34325+ *
34326+ * Revision 1.2 1998/04/12 22:03:23 rgb
34327+ * Updated ESP-3DES-HMAC-MD5-96,
34328+ * ESP-DES-HMAC-MD5-96,
34329+ * AH-HMAC-MD5-96,
34330+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
34331+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
34332+ *
34333+ * Fixed eroute references in /proc/net/ipsec*.
34334+ *
34335+ * Started to patch module unloading memory leaks in ipsec_netlink and
34336+ * radij tree unloading.
34337+ *
34338+ * Revision 1.1 1998/04/09 03:06:10 henry
34339+ * sources moved up from linux/net/ipsec
34340+ *
34341+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
34342+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
34343+ *
34344+ * Revision 0.4 1997/01/15 01:28:15 ji
34345+ * No changes.
34346+ *
34347+ * Revision 0.3 1996/11/20 14:39:04 ji
34348+ * Minor cleanups.
34349+ * Rationalized debugging code.
34350+ *
34351+ * Revision 0.2 1996/11/02 00:18:33 ji
34352+ * First limited release.
34353+ *
34354+ *
34355+ */
34356--- /dev/null Tue Mar 11 13:02:56 2003
34357+++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004
34358@@ -0,0 +1,2340 @@
34359+/*
34360+ * receive code
34361+ * Copyright (C) 1996, 1997 John Ioannidis.
34362+ * Copyright (C) 1998-2003 Richard Guy Briggs.
34363+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
34364+ *
34365+ * This program is free software; you can redistribute it and/or modify it
34366+ * under the terms of the GNU General Public License as published by the
34367+ * Free Software Foundation; either version 2 of the License, or (at your
34368+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
34369+ *
34370+ * This program is distributed in the hope that it will be useful, but
34371+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
34372+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34373+ * for more details.
34374+ */
34375+
34376+char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.171.2.15 2007-10-30 21:37:45 paul Exp $";
34377+
34378+#ifndef AUTOCONF_INCLUDED
34379+#include <linux/config.h>
34380+#endif
34381+#include <linux/version.h>
34382+
34383+#define __NO_VERSION__
34384+#include <linux/module.h>
34385+#include <linux/kernel.h> /* printk() */
34386+
34387+#include "openswan/ipsec_param.h"
34388+
34389+#ifdef MALLOC_SLAB
34390+# include <linux/slab.h> /* kmalloc() */
34391+#else /* MALLOC_SLAB */
34392+# include <linux/malloc.h> /* kmalloc() */
34393+#endif /* MALLOC_SLAB */
34394+#include <linux/errno.h> /* error codes */
34395+#include <linux/types.h> /* size_t */
34396+#include <linux/interrupt.h> /* mark_bh */
34397+
34398+#include <linux/netdevice.h> /* struct device, and other headers */
34399+#include <linux/etherdevice.h> /* eth_type_trans */
34400+#include <linux/ip.h> /* struct iphdr */
34401+
34402+#include <net/tcp.h>
34403+#include <net/udp.h>
34404+#include <linux/skbuff.h>
34405+#include <openswan.h>
34406+#ifdef SPINLOCK
34407+# ifdef SPINLOCK_23
34408+# include <linux/spinlock.h> /* *lock* */
34409+# else /* SPINLOCK_23 */
34410+# include <asm/spinlock.h> /* *lock* */
34411+# endif /* SPINLOCK_23 */
34412+#endif /* SPINLOCK */
34413+
34414+#include <net/ip.h>
34415+
34416+#include "openswan/ipsec_kern24.h"
34417+#include "openswan/radij.h"
34418+#include "openswan/ipsec_encap.h"
34419+#include "openswan/ipsec_sa.h"
34420+
34421+#include "openswan/ipsec_radij.h"
34422+#include "openswan/ipsec_xform.h"
34423+#include "openswan/ipsec_tunnel.h"
34424+#include "openswan/ipsec_rcv.h"
34425+
34426+#include "openswan/ipsec_auth.h"
34427+
34428+#include "openswan/ipsec_esp.h"
34429+
34430+#ifdef CONFIG_KLIPS_AH
34431+#include "openswan/ipsec_ah.h"
34432+#endif /* CONFIG_KLIPS_AH */
34433+
34434+#ifdef CONFIG_KLIPS_IPCOMP
34435+#include "openswan/ipsec_ipcomp.h"
34436+#endif /* CONFIG_KLIPS_COMP */
34437+
34438+#include <pfkeyv2.h>
34439+#include <pfkey.h>
34440+
34441+#include "openswan/ipsec_proto.h"
34442+#include "openswan/ipsec_alg.h"
34443+#include "openswan/ipsec_kern24.h"
34444+
34445+#ifdef CONFIG_KLIPS_DEBUG
34446+int debug_rcv = 0;
34447+#endif /* CONFIG_KLIPS_DEBUG */
34448+
34449+int sysctl_ipsec_inbound_policy_check = 1;
34450+
34451+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34452+#include <linux/udp.h>
34453+#endif
34454+
34455+/* This is a private use protocol, and AT&T should be ashamed. They should have
34456+ * used protocol # 59, which is "no next header" instead of 0xFE.
34457+ */
34458+#ifndef IPPROTO_ATT_HEARTBEAT
34459+#define IPPROTO_ATT_HEARTBEAT 0xFE
34460+#endif
34461+
34462+/*
34463+ * Check-replay-window routine, adapted from the original
34464+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
34465+ *
34466+ * This is a routine that implements a 64 packet window. This is intend-
34467+ * ed on being an implementation sample.
34468+ */
34469+
34470+DEBUG_NO_STATIC int
34471+ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
34472+{
34473+ __u32 diff;
34474+
34475+ if (ipsp->ips_replaywin == 0) /* replay shut off */
34476+ return 1;
34477+ if (seq == 0)
34478+ return 0; /* first == 0 or wrapped */
34479+
34480+ /* new larger sequence number */
34481+ if (seq > ipsp->ips_replaywin_lastseq) {
34482+ return 1; /* larger is good */
34483+ }
34484+ diff = ipsp->ips_replaywin_lastseq - seq;
34485+
34486+ /* too old or wrapped */ /* if wrapped, kill off SA? */
34487+ if (diff >= ipsp->ips_replaywin) {
34488+ return 0;
34489+ }
34490+ /* this packet already seen */
34491+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
34492+ return 0;
34493+ return 1; /* out of order but good */
34494+}
34495+
34496+DEBUG_NO_STATIC int
34497+ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
34498+{
34499+ __u32 diff;
34500+
34501+ if (ipsp->ips_replaywin == 0) /* replay shut off */
34502+ return 1;
34503+ if (seq == 0)
34504+ return 0; /* first == 0 or wrapped */
34505+
34506+ /* new larger sequence number */
34507+ if (seq > ipsp->ips_replaywin_lastseq) {
34508+ diff = seq - ipsp->ips_replaywin_lastseq;
34509+
34510+ /* In win, set bit for this pkt */
34511+ if (diff < ipsp->ips_replaywin)
34512+ ipsp->ips_replaywin_bitmap =
34513+ (ipsp->ips_replaywin_bitmap << diff) | 1;
34514+ else
34515+ /* This packet has way larger seq num */
34516+ ipsp->ips_replaywin_bitmap = 1;
34517+
34518+ if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
34519+ ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
34520+ }
34521+ ipsp->ips_replaywin_lastseq = seq;
34522+ return 1; /* larger is good */
34523+ }
34524+ diff = ipsp->ips_replaywin_lastseq - seq;
34525+
34526+ /* too old or wrapped */ /* if wrapped, kill off SA? */
34527+ if (diff >= ipsp->ips_replaywin) {
34528+/*
34529+ if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
34530+ ipsec_sa_delchain(ipsp);
34531+ }
34532+*/
34533+ return 0;
34534+ }
34535+ /* this packet already seen */
34536+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
34537+ return 0;
34538+ ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */
34539+ return 1; /* out of order but good */
34540+}
34541+
34542+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34543+struct auth_alg ipsec_rcv_md5[]={
34544+ {osMD5Init, osMD5Update, osMD5Final, AHMD596_ALEN}
34545+};
34546+
34547+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34548+
34549+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34550+struct auth_alg ipsec_rcv_sha1[]={
34551+ {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
34552+};
34553+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34554+
34555+/*
34556+ * decapsulate a single layer of the system
34557+ *
34558+ * the following things should be setup to enter this function.
34559+ *
34560+ * irs->stats == stats structure (or NULL)
34561+ * irs->ipp = IP header.
34562+ * irs->len = total length of packet
34563+ * skb->nh.iph = ipp;
34564+ * skb->h.raw = start of payload
34565+ * irs->ipsp = NULL.
34566+ * irs->iphlen = N/A = is recalculated.
34567+ * irs->ilen = 0;
34568+ * irs->authlen = 0;
34569+ * irs->authfuncs = NULL;
34570+ * irs->skb = the skb;
34571+ *
34572+ * proto_funcs should be from ipsec_esp.c, ipsec_ah.c or ipsec_ipcomp.c.
34573+ *
34574+ */
34575+enum ipsec_rcv_value
34576+ipsec_rcv_decap_once(struct ipsec_rcv_state *irs
34577+ , struct xform_functions *proto_funcs)
34578+{
34579+ int iphlen;
34580+ __u8 proto;
34581+ struct in_addr ipsaddr;
34582+ struct in_addr ipdaddr;
34583+ int replay = 0; /* replay value in AH or ESP packet */
34584+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
34585+ struct ipsec_sa *newipsp;
34586+ struct iphdr *ipp;
34587+ struct sk_buff *skb;
34588+ struct ipsec_alg_auth *ixt_a=NULL;
34589+
34590+ skb = irs->skb;
34591+ irs->len = skb->len;
34592+ ipp = irs->ipp;
34593+ proto = ipp->protocol;
34594+ ipsaddr.s_addr = ipp->saddr;
34595+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
34596+ ipdaddr.s_addr = ipp->daddr;
34597+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
34598+
34599+ iphlen = ipp->ihl << 2;
34600+ irs->iphlen=iphlen;
34601+ ipp->check = 0; /* we know the sum is good */
34602+
34603+ KLIPS_PRINT(debug_rcv,
34604+ "klips_debug:ipsec_rcv_decap_once: "
34605+ "decap (%d) from %s -> %s\n",
34606+ proto, irs->ipsaddr_txt, irs->ipdaddr_txt);
34607+
34608+ /*
34609+ * Find tunnel control block and (indirectly) call the
34610+ * appropriate tranform routine. The resulting sk_buf
34611+ * is a valid IP packet ready to go through input processing.
34612+ */
34613+
34614+ irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr;
34615+ irs->said.dst.u.v4.sin_family = AF_INET;
34616+
34617+ /* note: rcv_checks set up the said.spi value, if appropriate */
34618+ if(proto_funcs->rcv_checks) {
34619+ enum ipsec_rcv_value retval =
34620+ (*proto_funcs->rcv_checks)(irs, skb);
34621+
34622+ if(retval < 0) {
34623+ return retval;
34624+ }
34625+ }
34626+
34627+ irs->said.proto = proto;
34628+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
34629+ if(irs->sa_len == 0) {
34630+ strcpy(irs->sa, "(error)");
34631+ }
34632+
34633+ newipsp = ipsec_sa_getbyid(&irs->said);
34634+ if (newipsp == NULL) {
34635+ KLIPS_PRINT(debug_rcv,
34636+ "klips_debug:ipsec_rcv: "
34637+ "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
34638+ irs->sa_len ? irs->sa : " (error)");
34639+ if(irs->stats) {
34640+ irs->stats->rx_dropped++;
34641+ }
34642+ return IPSEC_RCV_SAIDNOTFOUND;
34643+ }
34644+
34645+ /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having
34646+ * incremented the refcount, why in the world would we decrement it
34647+ * here? */
34648+ /* ipsec_sa_put(irs->ipsp);*/ /* incomplete */
34649+
34650+ /* If it is in larval state, drop the packet, we cannot process yet. */
34651+ if(newipsp->ips_state == SADB_SASTATE_LARVAL) {
34652+ KLIPS_PRINT(debug_rcv,
34653+ "klips_debug:ipsec_rcv: "
34654+ "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
34655+ if(irs->stats) {
34656+ irs->stats->rx_dropped++;
34657+ }
34658+ ipsec_sa_put(newipsp);
34659+ return IPSEC_RCV_SAIDNOTLIVE;
34660+ }
34661+
34662+ if(newipsp->ips_state == SADB_SASTATE_DEAD) {
34663+ KLIPS_PRINT(debug_rcv,
34664+ "klips_debug:ipsec_rcv: "
34665+ "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
34666+ if(irs->stats) {
34667+ irs->stats->rx_dropped++;
34668+ }
34669+ ipsec_sa_put(newipsp);
34670+ return IPSEC_RCV_SAIDNOTLIVE;
34671+ }
34672+
34673+ if(sysctl_ipsec_inbound_policy_check) {
34674+ if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
34675+ KLIPS_PRINT(debug_rcv,
34676+ "klips_debug:ipsec_rcv: "
34677+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
34678+ irs->sa_len ? irs->sa : " (error)",
34679+ irs->ipsaddr_txt);
34680+ if(irs->stats) {
34681+ irs->stats->rx_dropped++;
34682+ }
34683+ ipsec_sa_put(newipsp);
34684+ return IPSEC_RCV_FAILEDINBOUND;
34685+ }
34686+
34687+ KLIPS_PRINT(debug_rcv,
34688+ "klips_debug:ipsec_rcv: "
34689+ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
34690+ irs->sa_len ? irs->sa : " (error)",
34691+ irs->ipsaddr_txt);
34692+
34693+ /*
34694+ * at this point, we have looked up a new SA, and we want to make sure that if this
34695+ * isn't the first SA in the list, that the previous SA actually points at this one.
34696+ */
34697+ if(irs->ipsp) {
34698+ if(irs->ipsp->ips_inext != newipsp) {
34699+ KLIPS_PRINT(debug_rcv,
34700+ "klips_debug:ipsec_rcv: "
34701+ "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
34702+ irs->sa_len ? irs->sa : " (error)");
34703+ if(irs->stats) {
34704+ irs->stats->rx_dropped++;
34705+ }
34706+ ipsec_sa_put(newipsp);
34707+ return IPSEC_RCV_FAILEDINBOUND;
34708+ }
34709+ KLIPS_PRINT(debug_rcv,
34710+ "klips_debug:ipsec_rcv: "
34711+ "SA:%s grouping from previous SA is OK.\n",
34712+ irs->sa_len ? irs->sa : " (error)");
34713+ } else {
34714+ KLIPS_PRINT(debug_rcv,
34715+ "klips_debug:ipsec_rcv: "
34716+ "SA:%s First SA in group.\n",
34717+ irs->sa_len ? irs->sa : " (error)");
34718+ }
34719+
34720+
34721+
34722+
34723+
34724+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34725+ if (proto == IPPROTO_ESP) {
34726+ KLIPS_PRINT(debug_rcv,
34727+ "klips_debug:ipsec_rcv: "
34728+ "natt_type=%u tdbp->ips_natt_type=%u : %s\n",
34729+ irs->natt_type, newipsp->ips_natt_type,
34730+ (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad");
34731+ if (irs->natt_type != newipsp->ips_natt_type) {
34732+ KLIPS_PRINT(debug_rcv,
34733+ "klips_debug:ipsec_rcv: "
34734+ "SA:%s does not agree with expected NAT-T policy.\n",
34735+ irs->sa_len ? irs->sa : " (error)");
34736+ if(irs->stats) {
34737+ irs->stats->rx_dropped++;
34738+ }
34739+ ipsec_sa_put(newipsp);
34740+ return IPSEC_RCV_FAILEDINBOUND;
34741+ }
34742+ }
34743+#endif
34744+ }
34745+
34746+ /* okay, SA checks out, so free any previous SA, and record a new one*/
34747+
34748+ if(irs->ipsp) {
34749+ ipsec_sa_put(irs->ipsp);
34750+ }
34751+ irs->ipsp=newipsp;
34752+
34753+ /* note that the outer code will free the irs->ipsp
34754+ if there is an error */
34755+
34756+
34757+ /* now check the lifetimes */
34758+ if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes",
34759+ irs->sa, ipsec_life_countbased, ipsec_incoming,
34760+ irs->ipsp) == ipsec_life_harddied ||
34761+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",
34762+ irs->sa, ipsec_life_timebased, ipsec_incoming,
34763+ irs->ipsp) == ipsec_life_harddied ||
34764+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",
34765+ irs->sa, ipsec_life_timebased, ipsec_incoming,
34766+ irs->ipsp) == ipsec_life_harddied ||
34767+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",
34768+ irs->sa, ipsec_life_countbased, ipsec_incoming,
34769+ irs->ipsp) == ipsec_life_harddied) {
34770+ ipsec_sa_delchain(irs->ipsp);
34771+ if(irs->stats) {
34772+ irs->stats->rx_dropped++;
34773+ }
34774+
34775+ KLIPS_PRINT(debug_rcv,
34776+ "klips_debug:ipsec_rcv_decap_once: "
34777+ "decap (%d) failed lifetime check\n",
34778+ proto);
34779+
34780+ return IPSEC_RCV_LIFETIMEFAILED;
34781+ }
34782+
34783+#if 0
34784+ /*
34785+ * This is removed for some reasons:
34786+ * 1) it needs to happen *after* authentication.
34787+ * 2) do we really care, if it authenticates, if it came
34788+ * from the wrong location?
34789+ * 3) the NAT_KA messages in IKE will also get to pluto
34790+ * and it will figure out that stuff has moved.
34791+ * 4) the 2.6 udp-esp encap function does not pass us
34792+ * the originating port number, and I can't tell
34793+ * if skb->sk is guaranteed to be valid here.
34794+ * 2005-04-16: mcr@xelerance.com
34795+ */
34796+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34797+ /*
34798+ *
34799+ * XXX we should ONLY update pluto if the SA passes all checks,
34800+ * which we clearly do not now.
34801+ */
34802+ if ((irs->natt_type) &&
34803+ ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) ||
34804+ (irs->natt_sport != newipsp->ips_natt_sport)
34805+ )) {
34806+ struct sockaddr sipaddr;
34807+ struct sockaddr_in *psin = (struct sockaddr_in*)(newipsp->ips_addr_s);
34808+
34809+ /** Advertise NAT-T addr change to pluto **/
34810+ sipaddr.sa_family = AF_INET;
34811+ ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr;
34812+ ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport);
34813+ pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport);
34814+
34815+ /**
34816+ * Then allow or block packet depending on
34817+ * sysctl_ipsec_inbound_policy_check.
34818+ *
34819+ * In all cases, pluto will update SA if new mapping is
34820+ * accepted.
34821+ */
34822+ if (sysctl_ipsec_inbound_policy_check) {
34823+ KLIPS_PRINT(debug_rcv,
34824+ "klips_debug:ipsec_rcv: "
34825+ "SA:%s, src=%s:%u of pkt does not agree with expected "
34826+ "SA source address [%08x:%u] (notifying pluto of change).\n",
34827+ irs->sa_len ? irs->sa : " (error)",
34828+ irs->ipsaddr_txt, irs->natt_sport,
34829+ psin->sin_addr.s_addr,
34830+ newipsp->ips_natt_sport);
34831+ if(irs->stats) {
34832+ irs->stats->rx_dropped++;
34833+ }
34834+ ipsec_sa_put(newipsp);
34835+ return IPSEC_RCV_FAILEDINBOUND;
34836+ }
34837+ }
34838+#endif
34839+#endif
34840+
34841+ irs->authfuncs=NULL;
34842+
34843+ /* authenticate, if required */
34844+ if ((ixt_a=irs->ipsp->ips_alg_auth)) {
34845+ irs->authlen = AHHMAC_HASHLEN;
34846+ irs->authfuncs = NULL;
34847+ irs->ictx = NULL;
34848+ irs->octx = NULL;
34849+ irs->ictx_len = 0;
34850+ irs->octx_len = 0;
34851+ KLIPS_PRINT(debug_rcv,
34852+ "klips_debug:ipsec_rcv: "
34853+ "authalg=%d authlen=%d\n",
34854+ irs->ipsp->ips_authalg,
34855+ irs->authlen);
34856+ } else
34857+ switch(irs->ipsp->ips_authalg) {
34858+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34859+ case AH_MD5:
34860+ irs->authlen = AHHMAC_HASHLEN;
34861+ irs->authfuncs = ipsec_rcv_md5;
34862+ irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
34863+ irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
34864+ irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
34865+ irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
34866+ break;
34867+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34868+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34869+ case AH_SHA:
34870+ irs->authlen = AHHMAC_HASHLEN;
34871+ irs->authfuncs = ipsec_rcv_sha1;
34872+ irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
34873+ irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
34874+ irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
34875+ irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
34876+ break;
34877+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
34878+ case AH_NONE:
34879+ irs->authlen = 0;
34880+ irs->authfuncs = NULL;
34881+ irs->ictx = NULL;
34882+ irs->octx = NULL;
34883+ irs->ictx_len = 0;
34884+ irs->octx_len = 0;
34885+ break;
34886+ default:
34887+ irs->ipsp->ips_errs.ips_alg_errs += 1;
34888+ if(irs->stats) {
34889+ irs->stats->rx_errors++;
34890+ }
34891+ return IPSEC_RCV_BADAUTH;
34892+ }
34893+
34894+ /* ilen counts number of bytes in ESP portion */
34895+ irs->ilen = ((irs->skb->data + irs->skb->len) - skb_transport_header(irs->skb)) - irs->authlen;
34896+ if(irs->ilen <= 0) {
34897+ KLIPS_PRINT(debug_rcv,
34898+ "klips_debug:ipsec_rcv: "
34899+ "runt %s packet with no data, dropping.\n",
34900+ (proto == IPPROTO_ESP ? "esp" : "ah"));
34901+ if(irs->stats) {
34902+ irs->stats->rx_dropped++;
34903+ }
34904+ return IPSEC_RCV_BADLEN;
34905+ }
34906+
34907+ if(irs->authfuncs || ixt_a) {
34908+ unsigned char *authenticator = NULL;
34909+
34910+ if(proto_funcs->rcv_setup_auth) {
34911+ enum ipsec_rcv_value retval
34912+ = (*proto_funcs->rcv_setup_auth)(irs, skb,
34913+ &replay,
34914+ &authenticator);
34915+ if(retval < 0) {
34916+ return retval;
34917+ }
34918+ }
34919+
34920+ if(!authenticator) {
34921+ irs->ipsp->ips_errs.ips_auth_errs += 1;
34922+ if(irs->stats) {
34923+ irs->stats->rx_dropped++;
34924+ }
34925+ return IPSEC_RCV_BADAUTH;
34926+ }
34927+
34928+ if(!ipsec_checkreplaywindow(irs->ipsp, replay)) {
34929+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34930+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34931+ "klips_debug:ipsec_rcv: "
34932+ "duplicate frame from %s, packet dropped\n",
34933+ irs->ipsaddr_txt);
34934+ if(irs->stats) {
34935+ irs->stats->rx_dropped++;
34936+ }
34937+ return IPSEC_RCV_REPLAYFAILED;
34938+ }
34939+
34940+ /*
34941+ * verify authenticator
34942+ */
34943+
34944+ KLIPS_PRINT(debug_rcv,
34945+ "klips_debug:ipsec_rcv: "
34946+ "encalg = %d, authalg = %d.\n",
34947+ irs->ipsp->ips_encalg,
34948+ irs->ipsp->ips_authalg);
34949+
34950+ /* calculate authenticator */
34951+ if(proto_funcs->rcv_calc_auth == NULL) {
34952+ return IPSEC_RCV_BADAUTH;
34953+ }
34954+ (*proto_funcs->rcv_calc_auth)(irs, skb);
34955+
34956+ if (memcmp(irs->hash, authenticator, irs->authlen)) {
34957+ irs->ipsp->ips_errs.ips_auth_errs += 1;
34958+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
34959+ "klips_debug:ipsec_rcv: "
34960+ "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
34961+ irs->ipsaddr_txt,
34962+ ntohl(*(__u32*)&irs->hash[0]),
34963+ ntohl(*(__u32*)&irs->hash[4]),
34964+ ntohl(*(__u32*)&irs->hash[8]),
34965+ ntohl(*(__u32*)authenticator),
34966+ ntohl(*((__u32*)authenticator + 1)),
34967+ ntohl(*((__u32*)authenticator + 2)));
34968+ if(irs->stats) {
34969+ irs->stats->rx_dropped++;
34970+ }
34971+ return IPSEC_RCV_AUTHFAILED;
34972+ } else {
34973+ KLIPS_PRINT(debug_rcv,
34974+ "klips_debug:ipsec_rcv: "
34975+ "authentication successful.\n");
34976+ }
34977+
34978+ /* Crypto hygiene: clear memory used to calculate autheticator.
34979+ * The length varies with the algorithm.
34980+ */
34981+ memset(irs->hash, 0, irs->authlen);
34982+
34983+ /* If the sequence number == 0, expire SA, it had rolled */
34984+ if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) {
34985+ ipsec_sa_delchain(irs->ipsp);
34986+ KLIPS_PRINT(debug_rcv,
34987+ "klips_debug:ipsec_rcv: "
34988+ "replay window counter rolled, expiring SA.\n");
34989+ if(irs->stats) {
34990+ irs->stats->rx_dropped++;
34991+ }
34992+ return IPSEC_RCV_REPLAYROLLED;
34993+ }
34994+
34995+ /* now update the replay counter */
34996+ if (!ipsec_updatereplaywindow(irs->ipsp, replay)) {
34997+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34998+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34999+ "klips_debug:ipsec_rcv: "
35000+ "duplicate frame from %s, packet dropped\n",
35001+ irs->ipsaddr_txt);
35002+ if(irs->stats) {
35003+ irs->stats->rx_dropped++;
35004+ }
35005+ return IPSEC_RCV_REPLAYROLLED;
35006+ }
35007+ }
35008+
35009+ if(proto_funcs->rcv_decrypt) {
35010+ enum ipsec_rcv_value retval =
35011+ (*proto_funcs->rcv_decrypt)(irs);
35012+
35013+ if(retval != IPSEC_RCV_OK) {
35014+ return retval;
35015+ }
35016+ }
35017+
35018+ /*
35019+ * Adjust pointers
35020+ */
35021+ skb = irs->skb;
35022+ irs->len = skb->len;
35023+ ipp = irs->ipp = ip_hdr(skb);
35024+ irs->iphlen = ipp->ihl<<2;
35025+ skb_set_transport_header(skb, ipsec_skb_offset(skb, skb_network_header(skb) + irs->iphlen));
35026+
35027+ /* zero any options that there might be */
35028+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
35029+
35030+ ipsaddr.s_addr = ipp->saddr;
35031+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
35032+ ipdaddr.s_addr = ipp->daddr;
35033+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
35034+
35035+ /*
35036+ * Discard the original ESP/AH header
35037+ */
35038+ ipp->protocol = irs->next_header;
35039+
35040+ ipp->check = 0; /* NOTE: this will be included in checksum */
35041+ ipp->check = ip_fast_csum((unsigned char *)ip_hdr(skb), irs->iphlen >> 2);
35042+
35043+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35044+ "klips_debug:ipsec_rcv: "
35045+ "after <%s%s%s>, SA:%s:\n",
35046+ IPS_XFORM_NAME(irs->ipsp),
35047+ irs->sa_len ? irs->sa : " (error)");
35048+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
35049+
35050+ skb->protocol = htons(ETH_P_IP);
35051+ skb->ip_summed = 0;
35052+
35053+ ipsnext = irs->ipsp->ips_inext;
35054+ if(sysctl_ipsec_inbound_policy_check) {
35055+ if(ipsnext) {
35056+ if(
35057+ ipp->protocol != IPPROTO_AH
35058+ && ipp->protocol != IPPROTO_ESP
35059+#ifdef CONFIG_KLIPS_IPCOMP
35060+ && ipp->protocol != IPPROTO_COMP
35061+ && (ipsnext->ips_said.proto != IPPROTO_COMP
35062+ || ipsnext->ips_inext)
35063+#endif /* CONFIG_KLIPS_IPCOMP */
35064+ && ipp->protocol != IPPROTO_IPIP
35065+ && ipp->protocol != IPPROTO_ATT_HEARTBEAT /* heartbeats to AT&T SIG/GIG */
35066+ ) {
35067+ KLIPS_PRINT(debug_rcv,
35068+ "klips_debug:ipsec_rcv: "
35069+ "packet with incomplete policy dropped, last successful SA:%s.\n",
35070+ irs->sa_len ? irs->sa : " (error)");
35071+ if(irs->stats) {
35072+ irs->stats->rx_dropped++;
35073+ }
35074+ return IPSEC_RCV_FAILEDINBOUND;
35075+ }
35076+ KLIPS_PRINT(debug_rcv,
35077+ "klips_debug:ipsec_rcv: "
35078+ "SA:%s, Another IPSEC header to process.\n",
35079+ irs->sa_len ? irs->sa : " (error)");
35080+ } else {
35081+ KLIPS_PRINT(debug_rcv,
35082+ "klips_debug:ipsec_rcv: "
35083+ "No ips_inext from this SA:%s.\n",
35084+ irs->sa_len ? irs->sa : " (error)");
35085+ }
35086+ }
35087+
35088+#ifdef CONFIG_KLIPS_IPCOMP
35089+ /* update ipcomp ratio counters, even if no ipcomp packet is present */
35090+ if (ipsnext
35091+ && ipsnext->ips_said.proto == IPPROTO_COMP
35092+ && ipp->protocol != IPPROTO_COMP) {
35093+ ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
35094+ ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
35095+ }
35096+#endif /* CONFIG_KLIPS_IPCOMP */
35097+
35098+ irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
35099+ irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len;
35100+
35101+ if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
35102+ irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
35103+ }
35104+ irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
35105+ irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
35106+
35107+#ifdef CONFIG_NETFILTER
35108+ if(proto == IPPROTO_ESP || proto == IPPROTO_AH) {
35109+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
35110+ | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
35111+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35112+ "klips_debug:ipsec_rcv: "
35113+ "%s SA sets skb->nfmark=0x%x.\n",
35114+ proto == IPPROTO_ESP ? "ESP" : "AH",
35115+ (unsigned)skb->nfmark);
35116+ }
35117+#endif /* CONFIG_NETFILTER */
35118+
35119+ return IPSEC_RCV_OK;
35120+}
35121+
35122+
35123+/*
35124+ * core decapsulation loop for all protocols.
35125+ *
35126+ * the following things should be setup to enter this function.
35127+ *
35128+ * irs->stats == stats structure (or NULL)
35129+ * irs->ipp = IP header.
35130+ * irs->ipsp = NULL.
35131+ * irs->ilen = 0;
35132+ * irs->authlen = 0;
35133+ * irs->authfuncs = NULL;
35134+ * irs->skb = skb;
35135+ * skb->nh.iph = ipp;
35136+ * skb->h.raw = start of payload
35137+ *
35138+ */
35139+int ipsec_rcv_decap(struct ipsec_rcv_state *irs)
35140+{
35141+ struct ipsec_sa *ipsp = NULL;
35142+ struct ipsec_sa* ipsnext = NULL;
35143+ struct in_addr ipsaddr;
35144+ struct in_addr ipdaddr;
35145+ struct iphdr *ipp;
35146+ struct sk_buff *skb = NULL;
35147+
35148+ /* begin decapsulating loop here */
35149+
35150+ /*
35151+ The spinlock is to prevent any other process from
35152+ accessing or deleting the ipsec_sa hash table or any of the
35153+ ipsec_sa s while we are using and updating them.
35154+
35155+ This is not optimal, but was relatively straightforward
35156+ at the time. A better way to do it has been planned for
35157+ more than a year, to lock the hash table and put reference
35158+ counts on each ipsec_sa instead. This is not likely to happen
35159+ in KLIPS1 unless a volunteer contributes it, but will be
35160+ designed into KLIPS2.
35161+ */
35162+ spin_lock(&tdb_lock);
35163+
35164+ do {
35165+ int decap_stat;
35166+ struct xform_functions *proto_funcs;
35167+
35168+ switch(irs->ipp->protocol) {
35169+ case IPPROTO_ESP:
35170+ proto_funcs = esp_xform_funcs;
35171+ break;
35172+
35173+#ifdef CONFIG_KLIPS_AH
35174+ case IPPROTO_AH:
35175+ proto_funcs = ah_xform_funcs;
35176+ break;
35177+#endif /* !CONFIG_KLIPS_AH */
35178+
35179+#ifdef CONFIG_KLIPS_IPCOMP
35180+ case IPPROTO_COMP:
35181+ proto_funcs = ipcomp_xform_funcs;
35182+ break;
35183+#endif /* !CONFIG_KLIPS_IPCOMP */
35184+ default:
35185+ if(irs->stats) {
35186+ irs->stats->rx_errors++;
35187+ }
35188+ decap_stat = IPSEC_RCV_BADPROTO;
35189+ goto rcvleave;
35190+ }
35191+
35192+ decap_stat = ipsec_rcv_decap_once(irs, proto_funcs);
35193+
35194+ if(decap_stat != IPSEC_RCV_OK) {
35195+ spin_unlock(&tdb_lock);
35196+ KLIPS_PRINT(debug_rcv,
35197+ "klips_debug:ipsec_rcv: decap_once failed: %d\n",
35198+ decap_stat);
35199+
35200+ goto rcvleave;
35201+ }
35202+ /* end decapsulation loop here */
35203+ } while( (irs->ipp->protocol == IPPROTO_ESP )
35204+ || (irs->ipp->protocol == IPPROTO_AH )
35205+#ifdef CONFIG_KLIPS_IPCOMP
35206+ || (irs->ipp->protocol == IPPROTO_COMP)
35207+#endif /* CONFIG_KLIPS_IPCOMP */
35208+ );
35209+
35210+ /* set up for decap loop */
35211+ ipp =irs->ipp;
35212+ ipsp =irs->ipsp;
35213+ ipsnext = ipsp->ips_inext;
35214+ skb = irs->skb;
35215+
35216+ /* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
35217+ * then we can just skip it
35218+ */
35219+#ifdef CONFIG_KLIPS_IPCOMP
35220+ if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) {
35221+ ipsp = ipsnext;
35222+ ipsnext = ipsp->ips_inext;
35223+ }
35224+#endif /* CONFIG_KLIPS_IPCOMP */
35225+
35226+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35227+ if ((irs->natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
35228+ /**
35229+ * NAT-Traversal and Transport Mode:
35230+ * we need to correct TCP/UDP checksum
35231+ *
35232+ * If we've got NAT-OA, we can fix checksum without recalculation.
35233+ */
35234+ __u32 natt_oa = ipsp->ips_natt_oa ?
35235+ ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
35236+ __u16 pkt_len = skb_tail_pointer(skb) - (unsigned char *)ipp;
35237+ __u16 data_len = pkt_len - (ipp->ihl << 2);
35238+
35239+ switch (ipp->protocol) {
35240+ case IPPROTO_TCP:
35241+ if (data_len >= sizeof(struct tcphdr)) {
35242+ struct tcphdr *tcp = tcp_hdr(skb);
35243+ if (natt_oa) {
35244+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
35245+ KLIPS_PRINT(debug_rcv,
35246+ "klips_debug:ipsec_rcv: "
35247+ "NAT-T & TRANSPORT: "
35248+ "fix TCP checksum using NAT-OA\n");
35249+ tcp->check = csum_fold(
35250+ csum_partial((unsigned char *)buff, sizeof(buff),
35251+ tcp->check^0xffff));
35252+ }
35253+ else {
35254+ KLIPS_PRINT(debug_rcv,
35255+ "klips_debug:ipsec_rcv: "
35256+ "NAT-T & TRANSPORT: recalc TCP checksum\n");
35257+ if (pkt_len > (ntohs(ipp->tot_len)))
35258+ data_len -= (pkt_len - ntohs(ipp->tot_len));
35259+ tcp->check = 0;
35260+ tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr,
35261+ data_len, IPPROTO_TCP,
35262+ csum_partial((unsigned char *)tcp, data_len, 0));
35263+ }
35264+ }
35265+ else {
35266+ KLIPS_PRINT(debug_rcv,
35267+ "klips_debug:ipsec_rcv: "
35268+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
35269+ }
35270+ break;
35271+ case IPPROTO_UDP:
35272+ if (data_len >= sizeof(struct udphdr)) {
35273+ struct udphdr *udp = udp_hdr(skb);
35274+ if (udp->check == 0) {
35275+ KLIPS_PRINT(debug_rcv,
35276+ "klips_debug:ipsec_rcv: "
35277+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
35278+ }
35279+ else if (natt_oa) {
35280+ KLIPS_PRINT(debug_rcv,
35281+ "klips_debug:ipsec_rcv: "
35282+ "NAT-T & TRANSPORT: "
35283+ "fix UDP checksum using NAT-OA\n");
35284+#ifdef DISABLE_UDP_CHECKSUM
35285+ udp->check=0;
35286+ KLIPS_PRINT(debug_rcv,
35287+ "klips_debug:ipsec_rcv: "
35288+ "NAT-T & TRANSPORT: "
35289+ "UDP checksum using NAT-OA disabled at compile time\n");
35290+#else
35291+ {
35292+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
35293+
35294+ udp->check = csum_fold(
35295+ csum_partial((unsigned char *)buff, sizeof(buff),
35296+ udp->check^0xffff));
35297+ }
35298+#endif
35299+ }
35300+ else {
35301+ KLIPS_PRINT(debug_rcv,
35302+ "klips_debug:ipsec_rcv: "
35303+ "NAT-T & TRANSPORT: zero UDP checksum\n");
35304+ udp->check = 0;
35305+ }
35306+ }
35307+ else {
35308+ KLIPS_PRINT(debug_rcv,
35309+ "klips_debug:ipsec_rcv: "
35310+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
35311+ }
35312+ break;
35313+ default:
35314+ KLIPS_PRINT(debug_rcv,
35315+ "klips_debug:ipsec_rcv: "
35316+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
35317+ break;
35318+ }
35319+ }
35320+#endif
35321+
35322+ /*
35323+ * XXX this needs to be locked from when it was first looked
35324+ * up in the decapsulation loop. Perhaps it is better to put
35325+ * the IPIP decap inside the loop.
35326+ */
35327+ if(ipsnext) {
35328+ ipsp = ipsnext;
35329+ irs->sa_len = KLIPS_SATOT(debug_rcv, &irs->said, 0, irs->sa, sizeof(irs->sa));
35330+ if((ipp->protocol != IPPROTO_IPIP) &&
35331+ (ipp->protocol != IPPROTO_ATT_HEARTBEAT)) { /* AT&T heartbeats to SIG/GIG */
35332+ spin_unlock(&tdb_lock);
35333+ KLIPS_PRINT(debug_rcv,
35334+ "klips_debug:ipsec_rcv: "
35335+ "SA:%s, Hey! How did this get through? Dropped.\n",
35336+ irs->sa_len ? irs->sa : " (error)");
35337+ if(irs->stats) {
35338+ irs->stats->rx_dropped++;
35339+ }
35340+ goto rcvleave;
35341+ }
35342+ if(sysctl_ipsec_inbound_policy_check) {
35343+ struct sockaddr_in *psin = (struct sockaddr_in*)(ipsp->ips_addr_s);
35344+ if((ipsnext = ipsp->ips_inext)) {
35345+ char sa2[SATOT_BUF];
35346+ size_t sa_len2;
35347+ sa_len2 = KLIPS_SATOT(debug_rcv, &ipsnext->ips_said, 0, sa2, sizeof(sa2));
35348+ spin_unlock(&tdb_lock);
35349+ KLIPS_PRINT(debug_rcv,
35350+ "klips_debug:ipsec_rcv: "
35351+ "unexpected SA:%s after IPIP SA:%s\n",
35352+ sa_len2 ? sa2 : " (error)",
35353+ irs->sa_len ? irs->sa : " (error)");
35354+ if(irs->stats) {
35355+ irs->stats->rx_dropped++;
35356+ }
35357+ goto rcvleave;
35358+ }
35359+ if(ipp->saddr != psin->sin_addr.s_addr) {
35360+ spin_unlock(&tdb_lock);
35361+ KLIPS_PRINT(debug_rcv,
35362+ "klips_debug:ipsec_rcv: "
35363+ "SA:%s, src=%s(%08x) does not match expected 0x%08x.\n",
35364+ irs->sa_len ? irs->sa : " (error)",
35365+ irs->ipsaddr_txt,
35366+ ipp->saddr, psin->sin_addr.s_addr);
35367+ if(irs->stats) {
35368+ irs->stats->rx_dropped++;
35369+ }
35370+ goto rcvleave;
35371+ }
35372+ }
35373+
35374+ if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */
35375+ {
35376+ /*
35377+ * XXX this needs to be locked from when it was first looked
35378+ * up in the decapsulation loop. Perhaps it is better to put
35379+ * the IPIP decap inside the loop.
35380+ */
35381+ ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
35382+ ipsp->ips_life.ipl_bytes.ipl_last = skb->len;
35383+
35384+ if(!ipsp->ips_life.ipl_usetime.ipl_count) {
35385+ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
35386+ }
35387+ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
35388+ ipsp->ips_life.ipl_packets.ipl_count += 1;
35389+
35390+ if(skb->len < irs->iphlen) {
35391+ spin_unlock(&tdb_lock);
35392+ printk(KERN_WARNING "klips_debug:ipsec_rcv: "
35393+ "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n",
35394+ irs->iphlen,
35395+ (int)(skb->len));
35396+
35397+ goto rcvleave;
35398+ }
35399+
35400+ /*
35401+ * we need to pull up by size of IP header,
35402+ * options, but also by any UDP/ESP encap there might
35403+ * have been, and this deals with all cases.
35404+ */
35405+ skb_pull(skb, (skb_transport_header(skb) - skb_network_header(skb)));
35406+
35407+ /* new L3 header is where L4 payload was */
35408+ skb_set_network_header(skb, ipsec_skb_offset(skb, skb_transport_header(skb)));
35409+
35410+ /* now setup new L4 payload location */
35411+ ipp = (struct iphdr *)skb_network_header(skb);
35412+ skb_set_transport_header(skb, ipsec_skb_offset(skb, skb_network_header(skb) + (ipp->ihl << 2)));
35413+
35414+
35415+ /* remove any saved options that we might have,
35416+ * since we have a new IP header.
35417+ */
35418+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
35419+
35420+#if 0
35421+ KLIPS_PRINT(debug_rcv, "csum: %d\n", ip_fast_csum((u8 *)ipp, ipp->ihl));
35422+#endif
35423+
35424+ /* re-do any strings for debugging */
35425+ ipsaddr.s_addr = ipp->saddr;
35426+ if (debug_rcv)
35427+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
35428+ ipdaddr.s_addr = ipp->daddr;
35429+ if (debug_rcv)
35430+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
35431+
35432+ skb->protocol = htons(ETH_P_IP);
35433+ skb->ip_summed = 0;
35434+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35435+ "klips_debug:ipsec_rcv: "
35436+ "IPIP tunnel stripped.\n");
35437+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
35438+ }
35439+
35440+ if(sysctl_ipsec_inbound_policy_check
35441+ /*
35442+ Note: "xor" (^) logically replaces "not equal"
35443+ (!=) and "bitwise or" (|) logically replaces
35444+ "boolean or" (||). This is done to speed up
35445+ execution by doing only bitwise operations and
35446+ no branch operations
35447+ */
35448+ && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
35449+ ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
35450+ | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
35451+ ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
35452+ {
35453+ char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
35454+
35455+ subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
35456+ ipsp->ips_mask_s.u.v4.sin_addr,
35457+ 0, sflow_txt, sizeof(sflow_txt));
35458+ subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
35459+ ipsp->ips_mask_d.u.v4.sin_addr,
35460+ 0, dflow_txt, sizeof(dflow_txt));
35461+ spin_unlock(&tdb_lock);
35462+ KLIPS_PRINT(debug_rcv,
35463+ "klips_debug:ipsec_rcv: "
35464+ "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
35465+ irs->sa_len ? irs->sa : " (error)",
35466+ sflow_txt,
35467+ dflow_txt,
35468+ irs->ipsaddr_txt,
35469+ irs->ipdaddr_txt);
35470+ if(irs->stats) {
35471+ irs->stats->rx_dropped++;
35472+ }
35473+ goto rcvleave;
35474+ }
35475+#ifdef CONFIG_NETFILTER
35476+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
35477+ | IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
35478+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35479+ "klips_debug:ipsec_rcv: "
35480+ "IPIP SA sets skb->nfmark=0x%x.\n",
35481+ (unsigned)skb->nfmark);
35482+#endif /* CONFIG_NETFILTER */
35483+ }
35484+
35485+ spin_unlock(&tdb_lock);
35486+
35487+ if(irs->stats) {
35488+ irs->stats->rx_bytes += skb->len;
35489+ }
35490+ if(skb->dst) {
35491+ dst_release(skb->dst);
35492+ skb->dst = NULL;
35493+ }
35494+ skb->pkt_type = PACKET_HOST;
35495+ if(irs->hard_header_len &&
35496+ (skb_mac_header(skb) != (skb_network_header(skb) - irs->hard_header_len)) &&
35497+ (irs->hard_header_len <= skb_headroom(skb))) {
35498+ /* copy back original MAC header */
35499+ memmove(skb_network_header(skb) - irs->hard_header_len,
35500+ skb_mac_header(skb), irs->hard_header_len);
35501+ skb_set_mac_header(skb, ipsec_skb_offset(skb, skb_network_header(skb) - irs->hard_header_len));
35502+ }
35503+
35504+#ifdef CONFIG_KLIPS_IPCOMP
35505+ if(ipp->protocol == IPPROTO_COMP) {
35506+ unsigned int flags = 0;
35507+
35508+ if(sysctl_ipsec_inbound_policy_check) {
35509+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35510+ "klips_debug:ipsec_rcv: "
35511+ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
35512+ if (irs->stats) {
35513+ irs->stats->rx_errors++;
35514+ }
35515+ goto rcvleave;
35516+ }
35517+ /*
35518+ XXX need a ipsec_sa for updating ratio counters but it is not
35519+ following policy anyways so it is not a priority
35520+ */
35521+ skb = skb_decompress(skb, NULL, &flags);
35522+ if (!skb || flags) {
35523+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35524+ "klips_debug:ipsec_rcv: "
35525+ "skb_decompress() returned error flags: %d, dropped.\n",
35526+ flags);
35527+ if (irs->stats) {
35528+ irs->stats->rx_errors++;
35529+ }
35530+ goto rcvleave;
35531+ }
35532+ }
35533+#endif /* CONFIG_KLIPS_IPCOMP */
35534+
35535+ /*
35536+ * make sure that data now starts at IP header, since we are going
35537+ * to pass this back to ip_input (aka netif_rx). Rules for what the
35538+ * pointers wind up a different for 2.6 vs 2.4, so we just fudge it here.
35539+ */
35540+#ifdef NET_26
35541+ irs->skb->data = skb_push(irs->skb, skb_transport_header(irs->skb) - skb_network_header(irs->skb));
35542+#else
35543+ irs->skb->data = skb_network_header(irs->skb);
35544+ {
35545+ struct iphdr *iph = ip_hdr(irs->skb);
35546+ int len = ntohs(iph->tot_len);
35547+ irs->skb->len = len;
35548+ }
35549+#endif
35550+
35551+#ifdef SKB_RESET_NFCT
35552+ nf_conntrack_put(skb->nfct);
35553+ skb->nfct = NULL;
35554+#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
35555+ skb->nf_debug = 0;
35556+#endif /* CONFIG_NETFILTER_DEBUG */
35557+#endif /* SKB_RESET_NFCT */
35558+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35559+ "klips_debug:ipsec_rcv: "
35560+ "netif_rx() called.\n");
35561+ netif_rx(skb);
35562+ skb=NULL;
35563+
35564+ rcvleave:
35565+ if(skb) {
35566+ ipsec_kfree_skb(skb);
35567+ }
35568+
35569+ /* KLIPS_DEC_USE; Artifact from refactor? bug # 454 */
35570+ return(0);
35571+}
35572+
35573+struct sk_buff *ipsec_rcv_unclone(struct sk_buff *skb,
35574+ struct ipsec_rcv_state *irs)
35575+{
35576+ /* if skb was cloned (most likely due to a packet sniffer such as
35577+ tcpdump being momentarily attached to the interface), make
35578+ a copy of our own to modify */
35579+ if(skb_cloned(skb)) {
35580+ /* include any mac header while copying.. */
35581+ if(skb_headroom(skb) < irs->hard_header_len) {
35582+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
35583+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
35584+ irs->hard_header_len,
35585+ skb_headroom(skb));
35586+ goto rcvleave;
35587+ }
35588+ skb_push(skb, irs->hard_header_len);
35589+ if
35590+#ifdef SKB_COW_NEW
35591+ (skb_cow(skb, skb_headroom(skb)) != 0)
35592+#else /* SKB_COW_NEW */
35593+ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
35594+#endif /* SKB_COW_NEW */
35595+ {
35596+ goto rcvleave;
35597+ }
35598+ if(skb->len < irs->hard_header_len) {
35599+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
35600+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
35601+ irs->hard_header_len,
35602+ skb->len);
35603+ goto rcvleave;
35604+ }
35605+ skb_pull(skb, irs->hard_header_len);
35606+ }
35607+ return skb;
35608+
35609+rcvleave:
35610+ ipsec_kfree_skb(skb);
35611+ return NULL;
35612+}
35613+
35614+
35615+#if !defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
35616+/*
35617+ * decapsulate a UDP encapsulated ESP packet
35618+ */
35619+struct sk_buff *ipsec_rcv_natt_decap(struct sk_buff *skb
35620+ , struct ipsec_rcv_state *irs
35621+ , int *udp_decap_ret_p)
35622+{
35623+ *udp_decap_ret_p = 0;
35624+ if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) {
35625+ /**
35626+ * Packet comes from udp_queue_rcv_skb so it is already defrag,
35627+ * checksum verified, ... (ie safe to use)
35628+ *
35629+ * If the packet is not for us, return -1 and udp_queue_rcv_skb
35630+ * will continue to handle it (do not kfree skb !!).
35631+ */
35632+
35633+#ifndef UDP_OPT_IN_SOCK
35634+ struct udp_opt {
35635+ __u32 esp_in_udp;
35636+ };
35637+ struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);
35638+#else
35639+ struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp);
35640+#endif
35641+
35642+ struct iphdr *ip = (struct iphdr *)skb->nh.iph;
35643+ struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
35644+ __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
35645+ __u32 *udpdata32 = (__u32 *)udpdata;
35646+
35647+ irs->natt_sport = ntohs(udp->source);
35648+ irs->natt_dport = ntohs(udp->dest);
35649+
35650+ KLIPS_PRINT(debug_rcv,
35651+ "klips_debug:ipsec_rcv: "
35652+ "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
35653+ tp->esp_in_udp);
35654+ KLIPS_IP_PRINT(debug_rcv, ip);
35655+
35656+ if (udpdata < skb->tail) {
35657+ unsigned int len = skb->tail - udpdata;
35658+ if ((len==1) && (udpdata[0]==0xff)) {
35659+ KLIPS_PRINT(debug_rcv,
35660+ "klips_debug:ipsec_rcv: "
35661+ /* not IPv6 compliant message */
35662+ "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
35663+ *udp_decap_ret_p = 0;
35664+ return NULL;
35665+ }
35666+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
35667+ (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&
35668+ (udpdata32[0]==0) && (udpdata32[1]==0) ) {
35669+ /* ESP Packet with Non-IKE header */
35670+ KLIPS_PRINT(debug_rcv,
35671+ "klips_debug:ipsec_rcv: "
35672+ "ESPinUDP pkt with Non-IKE - spi=0x%x\n",
35673+ ntohl(udpdata32[2]));
35674+ irs->natt_type = ESPINUDP_WITH_NON_IKE;
35675+ irs->natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
35676+ }
35677+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
35678+ (len > sizeof(struct esphdr)) &&
35679+ (udpdata32[0]!=0) ) {
35680+ /* ESP Packet without Non-ESP header */
35681+ irs->natt_type = ESPINUDP_WITH_NON_ESP;
35682+ irs->natt_len = sizeof(struct udphdr);
35683+ KLIPS_PRINT(debug_rcv,
35684+ "klips_debug:ipsec_rcv: "
35685+ "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
35686+ ntohl(udpdata32[0]));
35687+ }
35688+ else {
35689+ KLIPS_PRINT(debug_rcv,
35690+ "klips_debug:ipsec_rcv: "
35691+ "IKE packet - not handled here\n");
35692+ *udp_decap_ret_p = -1;
35693+ return NULL;
35694+ }
35695+ }
35696+ else {
35697+ return NULL;
35698+ }
35699+ }
35700+ return skb;
35701+}
35702+#endif
35703+
35704+
35705+int
35706+ipsec_rcv(struct sk_buff *skb
35707+#ifndef PROTO_HANDLER_SINGLE_PARM
35708+ unsigned short xlen
35709+#endif /* PROTO_HANDLER_SINGLE_PARM */
35710+ )
35711+{
35712+#ifdef CONFIG_KLIPS_DEBUG
35713+ struct net_device *dev = skb->dev;
35714+#endif /* CONFIG_KLIPS_DEBUG */
35715+ unsigned char protoc;
35716+ struct net_device_stats *stats = NULL; /* This device's statistics */
35717+ struct net_device *ipsecdev = NULL, *prvdev;
35718+ struct ipsecpriv *prv;
35719+ struct ipsec_rcv_state nirs, *irs = &nirs;
35720+ struct iphdr *ipp;
35721+ char name[9];
35722+ int i;
35723+
35724+ /* Don't unlink in the middle of a turnaround */
35725+ KLIPS_INC_USE;
35726+
35727+ memset(&nirs, 0, sizeof(struct ipsec_rcv_state));
35728+
35729+ if (skb == NULL) {
35730+ KLIPS_PRINT(debug_rcv,
35731+ "klips_debug:ipsec_rcv: "
35732+ "NULL skb passed in.\n");
35733+ goto rcvleave;
35734+ }
35735+
35736+ if (skb->data == NULL) {
35737+ KLIPS_PRINT(debug_rcv,
35738+ "klips_debug:ipsec_rcv: "
35739+ "NULL skb->data passed in, packet is bogus, dropping.\n");
35740+ goto rcvleave;
35741+ }
35742+
35743+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35744+ {
35745+ /* NET_26 NAT-T is handled by seperate function */
35746+ struct sk_buff *nskb;
35747+ int udp_decap_ret = 0;
35748+
35749+ nskb = ipsec_rcv_natt_decap(skb, irs, &udp_decap_ret);
35750+ if(nskb == NULL) {
35751+ /* return with non-zero, because UDP.c code
35752+ * need to send it upstream.
35753+ */
35754+ if(skb && udp_decap_ret == 0) {
35755+ ipsec_kfree_skb(skb);
35756+ }
35757+ KLIPS_DEC_USE;
35758+ return(udp_decap_ret);
35759+ }
35760+ skb = nskb;
35761+ }
35762+#endif /* NAT_T */
35763+
35764+ /* dev->hard_header_len is unreliable and should not be used */
35765+ /* klips26_rcv_encap will have already set hard_header_len for us?? */
35766+ if (irs->hard_header_len == 0) {
35767+ irs->hard_header_len = skb_mac_header(skb) ? (skb_network_header(skb) - skb_mac_header(skb)) : 0;
35768+ if((irs->hard_header_len < 0) || (irs->hard_header_len > skb_headroom(skb)))
35769+ irs->hard_header_len = 0;
35770+ }
35771+
35772+ skb = ipsec_rcv_unclone(skb, irs);
35773+ if(skb == NULL) {
35774+ goto rcvleave;
35775+ }
35776+
35777+#if IP_FRAGMENT_LINEARIZE
35778+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
35779+ not assembled automatically to save TCP from having to copy
35780+ twice.
35781+ */
35782+ if (skb_is_nonlinear(skb)) {
35783+#ifdef HAVE_NEW_SKB_LINEARIZE
35784+ if (skb_linearize_cow(skb) != 0)
35785+#else
35786+ if (skb_linearize(skb, GFP_ATOMIC) != 0)
35787+#endif
35788+ {
35789+ goto rcvleave;
35790+ }
35791+ }
35792+#endif /* IP_FRAGMENT_LINEARIZE */
35793+
35794+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35795+ if (irs->natt_len) {
35796+ /**
35797+ * Now, we are sure packet is ESPinUDP, and we have a private
35798+ * copy that has been linearized, remove natt_len bytes
35799+ * from packet and modify protocol to ESP.
35800+ */
35801+ if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph)
35802+ && ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head))
35803+ {
35804+ unsigned int _len = (unsigned char *)skb->data -
35805+ (unsigned char *)skb->nh.iph;
35806+ KLIPS_PRINT(debug_rcv,
35807+ "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
35808+ _len);
35809+ skb_push(skb, _len);
35810+ }
35811+ KLIPS_PRINT(debug_rcv,
35812+ "klips_debug:ipsec_rcv: "
35813+ "removing %d bytes from ESPinUDP packet\n", irs->natt_len);
35814+ ipp = skb->nh.iph;
35815+ irs->iphlen = ipp->ihl << 2;
35816+ ipp->tot_len = htons(ntohs(ipp->tot_len) - irs->natt_len);
35817+ if (skb->len < irs->iphlen + irs->natt_len) {
35818+ printk(KERN_WARNING
35819+ "klips_error:ipsec_rcv: "
35820+ "ESPinUDP packet is too small (%d < %d+%d). "
35821+ "This should never happen, please report.\n",
35822+ (int)(skb->len), irs->iphlen, irs->natt_len);
35823+ goto rcvleave;
35824+ }
35825+
35826+ /* advance payload pointer to point past the UDP header */
35827+ skb->h.raw = skb->h.raw + irs->natt_len;
35828+
35829+ /* modify protocol */
35830+ ipp->protocol = IPPROTO_ESP;
35831+
35832+ skb->sk = NULL;
35833+
35834+ KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);
35835+ }
35836+#endif
35837+
35838+ /* ipp = skb->nh.iph; */
35839+ ipp = ip_hdr(skb);
35840+
35841+ {
35842+ struct in_addr ipsaddr;
35843+ struct in_addr ipdaddr;
35844+
35845+ ipsaddr.s_addr = ipp->saddr;
35846+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt
35847+ , sizeof(irs->ipsaddr_txt));
35848+ ipdaddr.s_addr = ipp->daddr;
35849+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt
35850+ , sizeof(irs->ipdaddr_txt));
35851+ }
35852+
35853+ irs->iphlen = ipp->ihl << 2;
35854+
35855+ KLIPS_PRINT(debug_rcv,
35856+ "klips_debug:ipsec_rcv: "
35857+ "<<< Info -- ");
35858+ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
35859+ skb->dev->name ? skb->dev->name : "NULL");
35860+ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
35861+ dev->name ? dev->name : "NULL");
35862+ KLIPS_PRINTMORE(debug_rcv, "\n");
35863+
35864+ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
35865+ "klips_debug:ipsec_rcv: "
35866+ "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
35867+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
35868+ dev ? (dev->name ? dev->name : "NULL") : "NULL");
35869+
35870+ protoc = ipp->protocol;
35871+#ifndef NET_21
35872+ if((!protocol) || (protocol->protocol != protoc)) {
35873+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35874+ "klips_debug:ipsec_rcv: "
35875+ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
35876+ }
35877+#endif /* !NET_21 */
35878+
35879+ if( (protoc != IPPROTO_AH) &&
35880+#ifdef CONFIG_KLIPS_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
35881+ (protoc != IPPROTO_COMP) &&
35882+#endif /* CONFIG_KLIPS_IPCOMP */
35883+ (protoc != IPPROTO_ESP) ) {
35884+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35885+ "klips_debug:ipsec_rcv: Why the hell is someone "
35886+ "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
35887+ protoc);
35888+ goto rcvleave;
35889+ }
35890+
35891+ if(skb->dev) {
35892+ for(i = 0; i < IPSEC_NUM_IF; i++) {
35893+ sprintf(name, IPSEC_DEV_FORMAT, i);
35894+ if(!strcmp(name, skb->dev->name)) {
35895+ prv = (struct ipsecpriv *)(skb->dev->priv);
35896+ if(prv) {
35897+ stats = (struct net_device_stats *) &(prv->mystats);
35898+ }
35899+ ipsecdev = skb->dev;
35900+ KLIPS_PRINT(debug_rcv,
35901+ "klips_debug:ipsec_rcv: "
35902+ "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
35903+ break;
35904+ }
35905+ if((ipsecdev = __ipsec_dev_get(name)) == NULL) {
35906+ KLIPS_PRINT(debug_rcv,
35907+ "klips_error:ipsec_rcv: "
35908+ "device %s does not exist\n",
35909+ name);
35910+ }
35911+ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
35912+ prvdev = prv ? (struct net_device *)(prv->dev) : NULL;
35913+
35914+#if 0
35915+ KLIPS_PRINT(debug_rcv && prvdev,
35916+ "klips_debug:ipsec_rcv: "
35917+ "physical device for device %s is %s\n",
35918+ name,
35919+ prvdev->name);
35920+#endif
35921+ if(prvdev && skb->dev &&
35922+ !strcmp(prvdev->name, skb->dev->name)) {
35923+ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
35924+ skb->dev = ipsecdev;
35925+ KLIPS_PRINT(debug_rcv && prvdev,
35926+ "klips_debug:ipsec_rcv: "
35927+ "assigning packet ownership to virtual device %s from physical device %s.\n",
35928+ name, prvdev->name);
35929+ if(stats) {
35930+ stats->rx_packets++;
35931+ }
35932+ break;
35933+ }
35934+ }
35935+ } else {
35936+ KLIPS_PRINT(debug_rcv,
35937+ "klips_debug:ipsec_rcv: "
35938+ "device supplied with skb is NULL\n");
35939+ }
35940+
35941+ if(stats == NULL) {
35942+ KLIPS_PRINT((debug_rcv),
35943+ "klips_error:ipsec_rcv: "
35944+ "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",
35945+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
35946+ }
35947+
35948+ KLIPS_IP_PRINT(debug_rcv, ipp);
35949+
35950+ /* set up for decap loop */
35951+ irs->stats= stats;
35952+ irs->ipp = ipp;
35953+ irs->ipsp = NULL;
35954+ irs->ilen = 0;
35955+ irs->authlen=0;
35956+ irs->authfuncs=NULL;
35957+ irs->skb = skb;
35958+
35959+ ipsec_rcv_decap(irs);
35960+ KLIPS_DEC_USE;
35961+ return(0);
35962+
35963+ rcvleave:
35964+ if(skb) {
35965+ ipsec_kfree_skb(skb);
35966+ }
35967+ KLIPS_DEC_USE;
35968+ return(0);
35969+
35970+}
35971+
35972+#ifdef NET_26
35973+/*
35974+ * this entry point is not a protocol entry point, so the entry
35975+ * is a bit different.
35976+ *
35977+ * skb->iph->tot_len has been byte-swapped, and reduced by the size of
35978+ * the IP header (and options).
35979+ *
35980+ * skb->h.raw has been pulled up the ESP header.
35981+ *
35982+ * skb->iph->protocol = 50 IPPROTO_ESP;
35983+ *
35984+ */
35985+int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type)
35986+{
35987+ struct ipsec_rcv_state nirs, *irs = &nirs;
35988+ struct iphdr *ipp;
35989+
35990+ /* Don't unlink in the middle of a turnaround */
35991+ KLIPS_INC_USE;
35992+
35993+ memset(irs, 0, sizeof(*irs));
35994+
35995+ /* XXX fudge it so that all nat-t stuff comes from ipsec0 */
35996+ /* eventually, the SA itself will determine which device
35997+ * it comes from
35998+ */
35999+ {
36000+ skb->dev = ipsec_get_device(0);
36001+ }
36002+
36003+ /* set up for decap loop */
36004+ irs->hard_header_len = skb->dev->hard_header_len;
36005+
36006+ skb = ipsec_rcv_unclone(skb, irs);
36007+
36008+#if IP_FRAGMENT_LINEARIZE
36009+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
36010+ not assembled automatically to save TCP from having to copy
36011+ twice.
36012+ */
36013+ if (skb_is_nonlinear(skb)) {
36014+#ifdef HAVE_NEW_SKB_LINEARIZE
36015+ if (skb_linearize_cow(skb) != 0)
36016+#else
36017+ if (skb_linearize(skb, GFP_ATOMIC) != 0)
36018+#endif
36019+ {
36020+ goto rcvleave;
36021+ }
36022+ }
36023+#endif /* IP_FRAGMENT_LINEARIZE */
36024+
36025+ /* ipp = skb->nh.iph; */
36026+ ipp =ip_hdr(skb);
36027+
36028+ {
36029+ struct in_addr ipsaddr;
36030+ struct in_addr ipdaddr;
36031+
36032+ ipsaddr.s_addr = ipp->saddr;
36033+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt
36034+ , sizeof(irs->ipsaddr_txt));
36035+ ipdaddr.s_addr = ipp->daddr;
36036+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt
36037+ , sizeof(irs->ipdaddr_txt));
36038+ }
36039+
36040+ irs->iphlen = ipp->ihl << 2;
36041+
36042+ KLIPS_IP_PRINT(debug_rcv, ipp);
36043+
36044+ irs->stats= NULL;
36045+ irs->ipp = ipp;
36046+ irs->ipsp = NULL;
36047+ irs->ilen = 0;
36048+ irs->authlen=0;
36049+ irs->authfuncs=NULL;
36050+ irs->skb = skb;
36051+
36052+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
36053+ switch(encap_type) {
36054+ case UDP_ENCAP_ESPINUDP:
36055+ irs->natt_type = ESPINUDP_WITH_NON_ESP;
36056+ break;
36057+
36058+ case UDP_ENCAP_ESPINUDP_NON_IKE:
36059+ irs->natt_type = ESPINUDP_WITH_NON_IKE;
36060+ break;
36061+
36062+ default:
36063+ if(printk_ratelimit()) {
36064+ printk(KERN_INFO "KLIPS received unknown UDP-ESP encap type %u\n",
36065+ encap_type);
36066+ }
36067+ return -1;
36068+ }
36069+
36070+#endif
36071+ ipsec_rcv_decap(irs);
36072+ KLIPS_DEC_USE;
36073+ return 0;
36074+
36075+rcvleave:
36076+ if(skb) {
36077+ ipsec_kfree_skb(skb);
36078+ }
36079+ KLIPS_DEC_USE;
36080+ return 0;
36081+}
36082+#endif
36083+
36084+
36085+/*
36086+ * $Log: ipsec_rcv.c,v $
36087+ * Revision 1.171.2.15 2007-10-30 21:37:45 paul
36088+ * Use skb_tail_pointer() [dhr]
36089+ *
36090+ * Revision 1.171.2.14 2007-10-22 14:54:38 paul
36091+ * Fix identation
36092+ *
36093+ * Revision 1.171.2.13 2007/10/15 22:16:34 paul
36094+ * Adding missing ; in DISABLE_UDP_CHECKSUM code
36095+ *
36096+ * Revision 1.171.2.12 2007/09/05 02:56:09 paul
36097+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
36098+ * Fixes based on David McCullough patch.
36099+ *
36100+ * Revision 1.171.2.11 2007/04/28 20:46:40 paul
36101+ * Added compile time switch for -DDISABLE_UDP_CHECKSUM that seems to be
36102+ * breaking IPsec+NAT+Transport mode with NAT-OA. Enabled this per default
36103+ * via Makefile.inc's USERCOMPILE flags.
36104+ *
36105+ * Revision 1.171.2.10 2006/10/06 21:39:26 paul
36106+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
36107+ * set. This is defined through autoconf.h which is included through the
36108+ * linux kernel build macros.
36109+ *
36110+ * Revision 1.171.2.9 2006/07/30 02:09:33 paul
36111+ * Author: Bart Trojanowski <bart@xelerance.com>
36112+ * This fixes a NATT+ESP bug in rcv path.
36113+ *
36114+ * We only want to test NATT policy on the ESP packet. Doing so on the
36115+ * bundled SA breaks because the next layer does not know anything about
36116+ * NATT.
36117+ *
36118+ * Fix just puts an if(proto == IPPROTO_ESP) around the NATT policy check.
36119+ *
36120+ * Revision 1.171.2.8 2006/07/29 05:03:04 paul
36121+ * Added check for new version of skb_linearize that only takes 1 argument,
36122+ * for 2.6.18+ kernels.
36123+ *
36124+ * Revision 1.171.2.7 2006/04/20 16:33:07 mcr
36125+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
36126+ * Fix in-kernel module compilation. Sub-makefiles do not work.
36127+ *
36128+ * Revision 1.171.2.6 2005/12/07 06:07:04 paul
36129+ * comment out KLIPS_DEC_USE in ipsec_rcv_decap. Likely an artifact from
36130+ * refactoring. http://bugs.xelerance.com/view.php?id=454
36131+ *
36132+ * Revision 1.171.2.5 2005/10/21 02:22:29 mcr
36133+ * pull up of another try at 2.4.x kernel fix
36134+ *
36135+ * Revision 1.171.2.4 2005/10/21 01:39:56 mcr
36136+ * nat-t fix is 2.4/2.6 specific
36137+ *
36138+ * Revision 1.178 2005/10/21 02:19:34 mcr
36139+ * on 2.4 systems, we have to fix up the length as well.
36140+ *
36141+ * Revision 1.177 2005/10/21 00:18:31 mcr
36142+ * nat-t fix is 2.4 specific.
36143+ *
36144+ * Revision 1.176 2005/10/20 21:06:11 mcr
36145+ * possible fix for nat-t problem on 2.4 kernels.
36146+ *
36147+ * Revision 1.175 2005/10/13 02:49:24 mcr
36148+ * tested UDP-encapsulated ESP packets that were not actually ESP,
36149+ * (but IKE) were being eaten.
36150+ *
36151+ * Revision 1.174 2005/10/13 01:25:22 mcr
36152+ * UDP-encapsulated ESP packets that were not actually ESP,
36153+ * (but IKE) were being eaten.
36154+ *
36155+ * Revision 1.173 2005/08/31 23:26:11 mcr
36156+ * fixes for 2.6.13
36157+ *
36158+ * Revision 1.172 2005/08/05 08:44:54 mcr
36159+ * ipsec_kern24.h (compat code for 2.4) must be include
36160+ * explicitely now.
36161+ *
36162+ * Revision 1.171 2005/07/08 23:56:06 ken
36163+ * #ifdef
36164+ *
36165+ * Revision 1.170 2005/07/08 23:50:05 ken
36166+ * Don't attempt to decapsulate if NAT-T isn't available in the code
36167+ *
36168+ * Revision 1.169 2005/06/06 00:27:31 mcr
36169+ * fix for making tcpdump (packet capture) work correctly for
36170+ * nat-t received packets.
36171+ *
36172+ * Revision 1.168 2005/06/04 16:06:06 mcr
36173+ * better patch for nat-t rcv-device code.
36174+ *
36175+ * Revision 1.167 2005/06/03 17:04:46 mcr
36176+ * nat-t packets are forced to arrive from ipsec0.
36177+ *
36178+ * Revision 1.166 2005/04/29 05:10:22 mcr
36179+ * removed from extraenous includes to make unit testing easier.
36180+ *
36181+ * Revision 1.165 2005/04/20 17:11:32 mcr
36182+ * fixed to compile on 2.4.
36183+ *
36184+ * Revision 1.164 2005/04/18 03:09:50 ken
36185+ * Fix typo
36186+ *
36187+ * Revision 1.163 2005/04/17 05:32:58 mcr
36188+ * remove extraneous debugging
36189+ * make sure to return success from klips26_encap_rcv().
36190+ *
36191+ * Revision 1.162 2005/04/17 04:37:01 mcr
36192+ * make sure that irs->ipp is still set.
36193+ *
36194+ * Revision 1.161 2005/04/17 03:51:52 mcr
36195+ * removed old comment about removed code.
36196+ * added translation from udp.c/2.6 to KLIPS NAT-ESP naming.
36197+ * comment about check for origin address/port for incoming NAT-ESP packets.
36198+ *
36199+ * Revision 1.160 2005/04/15 19:55:58 mcr
36200+ * adjustments to use proper skb fields for data.
36201+ *
36202+ * Revision 1.159 2005/04/10 22:58:20 mcr
36203+ * refactoring of receive functions to make it easier to
36204+ * call the ESP decap.
36205+ *
36206+ * Revision 1.158 2005/04/08 18:27:53 mcr
36207+ * refactored ipsec_rcv() into ipsec_rcv() and ipsec_rcv_decap().
36208+ *
36209+ * Revision 1.157 2004/12/28 23:13:09 mcr
36210+ * use consistent CONFIG_IPSEC_NAT_TRAVERSAL.
36211+ *
36212+ * Revision 1.156 2004/12/03 21:34:51 mcr
36213+ * mistype of KLIPS_USE_COUNT -> KLIPS_INC_USE;
36214+ *
36215+ * Revision 1.155 2004/12/03 21:25:57 mcr
36216+ * compile time fixes for running on 2.6.
36217+ * still experimental.
36218+ *
36219+ * Revision 1.154 2004/09/08 17:21:36 ken
36220+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
36221+ *
36222+ * Revision 1.153 2004/08/22 20:10:00 mcr
36223+ * removed check for incorrect setting of NET_26.
36224+ *
36225+ * Revision 1.152 2004/08/21 15:22:39 mcr
36226+ * added #defines for ATT heartbeat.
36227+ *
36228+ * Revision 1.151 2004/08/21 02:16:32 ken
36229+ * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support
36230+ *
36231+ * Revision 1.150 2004/08/21 00:44:48 mcr
36232+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
36233+ *
36234+ * Revision 1.149 2004/08/20 21:45:45 mcr
36235+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
36236+ * be 26sec compatible. But, some defines where changed.
36237+ *
36238+ * Revision 1.148 2004/08/17 03:27:23 mcr
36239+ * klips 2.6 edits.
36240+ *
36241+ * Revision 1.147 2004/08/05 23:29:27 mcr
36242+ * fixed nesting of #ifdef vs {} in ipsec_rcv().
36243+ *
36244+ * Revision 1.146 2004/08/04 15:57:07 mcr
36245+ * moved des .h files to include/des/ *
36246+ * included 2.6 protocol specific things
36247+ * started at NAT-T support, but it will require a kernel patch.
36248+ *
36249+ * Revision 1.145 2004/08/03 18:19:08 mcr
36250+ * in 2.6, use "net_device" instead of #define device->net_device.
36251+ * this probably breaks 2.0 compiles.
36252+ *
36253+ * Revision 1.144 2004/07/10 19:11:18 mcr
36254+ * CONFIG_IPSEC -> CONFIG_KLIPS.
36255+ *
36256+ * Revision 1.143 2004/05/10 22:27:00 mcr
36257+ * fix for ESP-3DES-noauth test case.
36258+ *
36259+ * Revision 1.142 2004/05/10 22:25:57 mcr
36260+ * reformat of calls to ipsec_lifetime_check().
36261+ *
36262+ * Revision 1.141 2004/04/06 02:49:26 mcr
36263+ * pullup of algo code from alg-branch.
36264+ *
36265+ * Revision 1.140 2004/02/03 03:12:53 mcr
36266+ * removed erroneously, double patched code.
36267+ *
36268+ * Revision 1.139 2004/01/05 23:21:29 mcr
36269+ * initialize sin_family in ipsec_rcv.c
36270+ *
36271+ * Revision 1.138 2003/12/24 19:46:52 mcr
36272+ * if sock.h patch has not been applied, then define appropriate
36273+ * structure so we can use it. This is serious inferior, and
36274+ * depends upon the concept that the structure in question is
36275+ * smaller than the other members of that union.
36276+ * getting rid of differing methods is a better solution.
36277+ *
36278+ * Revision 1.137 2003/12/22 19:40:57 mcr
36279+ * NAT-T patches 0.6c.
36280+ *
36281+ * Revision 1.136 2003/12/15 18:13:12 mcr
36282+ * when compiling with NAT traversal, don't assume that the
36283+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
36284+ * is set.
36285+ *
36286+ * Revision 1.135 2003/12/13 19:10:21 mcr
36287+ * refactored rcv and xmit code - same as FS 2.05.
36288+ *
36289+ * Revision 1.134.2.1 2003/12/22 15:25:52 jjo
36290+ * Merged algo-0.8.1-rc11-test1 into alg-branch
36291+ *
36292+ * Revision 1.134 2003/12/10 01:14:27 mcr
36293+ * NAT-traversal patches to KLIPS.
36294+ *
36295+ * Revision 1.133 2003/10/31 02:27:55 mcr
36296+ * pulled up port-selector patches and sa_id elimination.
36297+ *
36298+ * Revision 1.132.2.1 2003/10/29 01:30:41 mcr
36299+ * elimited "struct sa_id".
36300+ *
36301+ * Revision 1.132 2003/09/02 19:51:48 mcr
36302+ * fixes for PR#252.
36303+ *
36304+ * Revision 1.131 2003/07/31 22:47:16 mcr
36305+ * preliminary (untested by FS-team) 2.5 patches.
36306+ *
36307+ * Revision 1.130 2003/04/03 17:38:25 rgb
36308+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
36309+ * Clarified logic for non-connected devices.
36310+ *
36311+ * Revision 1.129 2003/02/06 02:21:34 rgb
36312+ *
36313+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
36314+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
36315+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
36316+ *
36317+ * Revision 1.128 2002/12/13 20:58:03 rgb
36318+ * Relegated MCR's recent "_dmp" routine to debug_verbose.
36319+ * Cleaned up printing of source and destination addresses in debug output.
36320+ *
36321+ * Revision 1.127 2002/12/04 16:00:16 rgb
36322+ *
36323+ * Fixed AH decapsulation pointer update bug and added some comments and
36324+ * debugging.
36325+ * This bug was caught by west-ah-0[12].
36326+ *
36327+ * Revision 1.126 2002/11/04 05:03:43 mcr
36328+ * fixes for IPCOMP. There were two problems:
36329+ * 1) the irs->ipp pointer was not being updated properly after
36330+ * the ESP descryption. The meant nothing for IPIP, as the
36331+ * later IP header overwrote the earlier one.
36332+ * 2) the more serious problem was that skb_decompress will
36333+ * usually allocate a new SKB, so we have to make sure that
36334+ * it doesn't get lost.
36335+ * #2 meant removing the skb argument from the ->decrypt routine
36336+ * and moving it to the irs->skb, so it could be value/result.
36337+ *
36338+ * Revision 1.125 2002/11/01 01:53:35 dhr
36339+ *
36340+ * fix typo
36341+ *
36342+ * Revision 1.124 2002/10/31 22:49:01 dhr
36343+ *
36344+ * - eliminate unused variable "hash"
36345+ * - reduce scope of variable "authenticator"
36346+ * - add comment on a couple of tricky bits
36347+ *
36348+ * Revision 1.123 2002/10/31 22:39:56 dhr
36349+ *
36350+ * use correct type for result of function calls
36351+ *
36352+ * Revision 1.122 2002/10/31 22:36:25 dhr
36353+ *
36354+ * simplify complex test
36355+ *
36356+ * Revision 1.121 2002/10/31 22:34:04 dhr
36357+ *
36358+ * ipsprev is never used: ditch it
36359+ *
36360+ * Revision 1.120 2002/10/31 22:30:21 dhr
36361+ *
36362+ * eliminate redundant assignments
36363+ *
36364+ * Revision 1.119 2002/10/31 22:27:43 dhr
36365+ *
36366+ * make whitespace canonical
36367+ *
36368+ * Revision 1.118 2002/10/30 05:47:17 rgb
36369+ * Fixed cut-and-paste error mis-identifying comp runt as ah.
36370+ *
36371+ * Revision 1.117 2002/10/17 16:37:45 rgb
36372+ * Remove compp intermediate variable and in-line its contents
36373+ * where used
36374+ *
36375+ * Revision 1.116 2002/10/12 23:11:53 dhr
36376+ *
36377+ * [KenB + DHR] more 64-bit cleanup
36378+ *
36379+ * Revision 1.115 2002/10/07 19:06:58 rgb
36380+ * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming.
36381+ *
36382+ * Revision 1.114 2002/10/07 18:31:31 rgb
36383+ * Set saref on incoming packets.
36384+ *
36385+ * Revision 1.113 2002/09/16 21:28:12 mcr
36386+ * adjust hash length for HMAC calculation - must look at whether
36387+ * it is MD5 or SHA1.
36388+ *
36389+ * Revision 1.112 2002/09/16 21:19:15 mcr
36390+ * fixes for west-ah-icmp-01 - length of AH header must be
36391+ * calculated properly, and next_header field properly copied.
36392+ *
36393+ * Revision 1.111 2002/09/10 02:45:56 mcr
36394+ * re-factored the ipsec_rcv function into several functions,
36395+ * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP.
36396+ * In addition, the MD5 and SHA1 functions are replaced with pointers.
36397+ *
36398+ * Revision 1.110 2002/08/30 06:34:33 rgb
36399+ * Fix scope of shift in AH header length check.
36400+ *
36401+ * Revision 1.109 2002/08/27 16:49:20 rgb
36402+ * Fixed ESP short packet DOS (and AH and IPCOMP).
36403+ *
36404+ * Revision 1.108 2002/07/24 18:44:54 rgb
36405+ * Type fiddling to tame ia64 compiler.
36406+ *
36407+ * Revision 1.107 2002/05/27 18:58:18 rgb
36408+ * Convert to dynamic ipsec device allocation.
36409+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
36410+ *
36411+ * Revision 1.106 2002/05/23 07:15:21 rgb
36412+ * Pointer clean-up.
36413+ * Added refcount code.
36414+ *
36415+ * Revision 1.105 2002/05/14 02:35:06 rgb
36416+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
36417+ * ipsec_sa or ipsec_sa.
36418+ * Change references to _TDB to _IPSA.
36419+ *
36420+ * Revision 1.104 2002/04/24 07:55:32 mcr
36421+ * #include patches and Makefiles for post-reorg compilation.
36422+ *
36423+ * Revision 1.103 2002/04/24 07:36:30 mcr
36424+ * Moved from ./klips/net/ipsec/ipsec_rcv.c,v
36425+ *
36426+ * Revision 1.102 2002/01/29 17:17:56 mcr
36427+ * moved include of ipsec_param.h to after include of linux/kernel.h
36428+ * otherwise, it seems that some option that is set in ipsec_param.h
36429+ * screws up something subtle in the include path to kernel.h, and
36430+ * it complains on the snprintf() prototype.
36431+ *
36432+ * Revision 1.101 2002/01/29 04:00:52 mcr
36433+ * more excise of kversions.h header.
36434+ *
36435+ * Revision 1.100 2002/01/29 02:13:17 mcr
36436+ * introduction of ipsec_kversion.h means that include of
36437+ * ipsec_param.h must preceed any decisions about what files to
36438+ * include to deal with differences in kernel source.
36439+ *
36440+ * Revision 1.99 2002/01/28 21:40:59 mcr
36441+ * should use #if to test boolean option rather than #ifdef.
36442+ *
36443+ * Revision 1.98 2002/01/20 20:19:36 mcr
36444+ * renamed option to IP_FRAGMENT_LINEARIZE.
36445+ *
36446+ * Revision 1.97 2002/01/12 02:55:36 mcr
36447+ * fix for post-2.4.4 to linearize skb's when ESP packet
36448+ * was assembled from fragments.
36449+ *
36450+ * Revision 1.96 2001/11/26 09:23:49 rgb
36451+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
36452+ *
36453+ * Revision 1.93.2.2 2001/10/22 20:54:07 mcr
36454+ * include des.h, removed phony prototypes and fixed calling
36455+ * conventions to match real prototypes.
36456+ *
36457+ * Revision 1.93.2.1 2001/09/25 02:22:22 mcr
36458+ * struct tdb -> struct ipsec_sa.
36459+ * lifetime checks moved to ipsec_life.c
36460+ * some sa(tdb) manipulation functions renamed.
36461+ *
36462+ * Revision 1.95 2001/11/06 19:49:07 rgb
36463+ * Added variable descriptions.
36464+ * Removed unauthenticated sequence==0 check to prevent DoS.
36465+ *
36466+ * Revision 1.94 2001/10/18 04:45:20 rgb
36467+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
36468+ * lib/freeswan.h version macros moved to lib/kversions.h.
36469+ * Other compiler directive cleanups.
36470+ *
36471+ * Revision 1.93 2001/09/07 22:17:24 rgb
36472+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
36473+ * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
36474+ *
36475+ * Revision 1.92 2001/08/27 19:44:41 rgb
36476+ * Fix error in comment.
36477+ *
36478+ * Revision 1.91 2001/07/20 19:31:48 dhr
36479+ * [DHR] fix source and destination subnets of policy in diagnostic
36480+ *
36481+ * Revision 1.90 2001/07/06 19:51:09 rgb
36482+ * Added inbound policy checking code for IPIP SAs.
36483+ * Renamed unused function argument for ease and intuitive naming.
36484+ *
36485+ * Revision 1.89 2001/06/22 19:35:23 rgb
36486+ * Disable ipcomp processing if we are handed a ipcomp packet with no esp
36487+ * or ah header.
36488+ * Print protocol if we are handed a non-ipsec packet.
36489+ *
36490+ * Revision 1.88 2001/06/20 06:30:47 rgb
36491+ * Fixed transport mode IPCOMP policy check bug.
36492+ *
36493+ * Revision 1.87 2001/06/13 20:58:40 rgb
36494+ * Added parentheses around assignment used as truth value to silence
36495+ * compiler.
36496+ *
36497+ * Revision 1.86 2001/06/07 22:25:23 rgb
36498+ * Added a source address policy check for tunnel mode. It still does
36499+ * not check client addresses and masks.
36500+ * Only decapsulate IPIP if it is expected.
36501+ *
36502+ * Revision 1.85 2001/05/30 08:14:02 rgb
36503+ * Removed vestiges of esp-null transforms.
36504+ *
36505+ * Revision 1.84 2001/05/27 06:12:11 rgb
36506+ * Added structures for pid, packet count and last access time to eroute.
36507+ * Added packet count to beginning of /proc/net/ipsec_eroute.
36508+ *
36509+ * Revision 1.83 2001/05/04 16:45:47 rgb
36510+ * Remove unneeded code. ipp is not used after this point.
36511+ *
36512+ * Revision 1.82 2001/05/04 16:36:00 rgb
36513+ * Fix skb_cow() call for 2.4.4. (SS)
36514+ *
36515+ * Revision 1.81 2001/05/02 14:46:53 rgb
36516+ * Fix typo for compiler directive to pull IPH back.
36517+ *
36518+ * Revision 1.80 2001/04/30 19:46:34 rgb
36519+ * Update for 2.4.4. We now receive the skb with skb->data pointing to
36520+ * h.raw.
36521+ *
36522+ * Revision 1.79 2001/04/23 15:01:15 rgb
36523+ * Added spin_lock() check to prevent double-locking for multiple
36524+ * transforms and hence kernel lock-ups with SMP kernels.
36525+ * Minor spin_unlock() adjustments to unlock before non-dependant prints
36526+ * and IPSEC device stats updates.
36527+ *
36528+ * Revision 1.78 2001/04/21 23:04:24 rgb
36529+ * Check if soft expire has already been sent before sending another to
36530+ * prevent ACQUIRE flooding.
36531+ *
36532+ * Revision 1.77 2001/03/16 07:35:20 rgb
36533+ * Ditch extra #if 1 around now permanent policy checking code.
36534+ *
36535+ * Revision 1.76 2001/02/27 22:24:54 rgb
36536+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
36537+ * Check for satoa() return codes.
36538+ *
36539+ * Revision 1.75 2001/02/19 22:28:30 rgb
36540+ * Minor change to virtual device discovery code to assert which I/F has
36541+ * been found.
36542+ *
36543+ * Revision 1.74 2000/11/25 03:50:36 rgb
36544+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
36545+ *
36546+ * Revision 1.73 2000/11/09 20:52:15 rgb
36547+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
36548+ * include ipcomp and prevent races, renaming some tdb variables that got
36549+ * forgotten, moving some unlocks to include tdbs and adding a missing
36550+ * unlock. Thanks to Svenning for some of these.
36551+ *
36552+ * Revision 1.72 2000/11/09 20:11:22 rgb
36553+ * Minor shuffles to fix non-standard kernel config option selection.
36554+ *
36555+ * Revision 1.71 2000/11/06 04:36:18 rgb
36556+ * Ditched spin_lock_irqsave in favour of spin_lock.
36557+ * Minor initial protocol check rewrite.
36558+ * Clean up debug printing.
36559+ * Clean up tdb handling on ipcomp.
36560+ * Fixed transport mode null pointer de-reference without ipcomp.
36561+ * Add Svenning's adaptive content compression.
36562+ * Disabled registration of ipcomp handler.
36563+ *
36564+ * Revision 1.70 2000/10/30 23:41:43 henry
36565+ * Hans-Joerg Hoexer's null-pointer fix
36566+ *
36567+ * Revision 1.69 2000/10/10 18:54:16 rgb
36568+ * Added a fix for incoming policy check with ipcomp enabled but
36569+ * uncompressible.
36570+ *
36571+ * Revision 1.68 2000/09/22 17:53:12 rgb
36572+ * Fixed ipcomp tdb pointers update for policy checking.
36573+ *
36574+ * Revision 1.67 2000/09/21 03:40:58 rgb
36575+ * Added more debugging to try and track down the cpi outward copy problem.
36576+ *
36577+ * Revision 1.66 2000/09/20 04:00:10 rgb
36578+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for
36579+ * debugging oopsen.
36580+ *
36581+ * Revision 1.65 2000/09/19 07:07:16 rgb
36582+ * Added debugging to inbound policy check for ipcomp.
36583+ * Added missing spin_unlocks (thanks Svenning!).
36584+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
36585+ * Protect ipcomp policy check following ipip decap with sysctl switch.
36586+ *
36587+ * Revision 1.64 2000/09/18 21:27:29 rgb
36588+ * 2.0 fixes.
36589+ *
36590+ * Revision 1.63 2000/09/18 02:35:50 rgb
36591+ * Added policy checking to ipcomp and re-enabled policy checking by
36592+ * default.
36593+ * Optimised satoa calls.
36594+ *
36595+ * Revision 1.62 2000/09/17 21:02:32 rgb
36596+ * Clean up debugging, removing slow timestamp debug code.
36597+ *
36598+ * Revision 1.61 2000/09/16 01:07:55 rgb
36599+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
36600+ *
36601+ * Revision 1.60 2000/09/15 11:37:01 rgb
36602+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
36603+ * IPCOMP zlib deflate code.
36604+ *
36605+ * Revision 1.59 2000/09/15 04:56:20 rgb
36606+ * Remove redundant satoa() call, reformat comment.
36607+ *
36608+ * Revision 1.58 2000/09/13 08:00:52 rgb
36609+ * Flick on inbound policy checking.
36610+ *
36611+ * Revision 1.57 2000/09/12 03:22:19 rgb
36612+ * Converted inbound_policy_check to sysctl.
36613+ * Re-enabled policy backcheck.
36614+ * Moved policy checks to top and within tdb lock.
36615+ *
36616+ * Revision 1.56 2000/09/08 19:12:56 rgb
36617+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
36618+ *
36619+ * Revision 1.55 2000/08/28 18:15:46 rgb
36620+ * Added MB's nf-debug reset patch.
36621+ *
36622+ * Revision 1.54 2000/08/27 01:41:26 rgb
36623+ * More minor tweaks to the bad padding debug code.
36624+ *
36625+ * Revision 1.53 2000/08/24 16:54:16 rgb
36626+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
36627+ * info.
36628+ * Tidied up device reporting at the start of ipsec_rcv.
36629+ * Tidied up bad padding debugging and processing.
36630+ *
36631+ * Revision 1.52 2000/08/20 21:36:03 rgb
36632+ * Activated pfkey_expire() calls.
36633+ * Added a hard/soft expiry parameter to pfkey_expire().
36634+ * Added sanity checking to avoid propagating zero or smaller-length skbs
36635+ * from a bogus decryption.
36636+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
36637+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
36638+ *
36639+ * Revision 1.51 2000/08/18 21:23:30 rgb
36640+ * Improve bad padding warning so that the printk buffer doesn't get
36641+ * trampled.
36642+ *
36643+ * Revision 1.50 2000/08/01 14:51:51 rgb
36644+ * Removed _all_ remaining traces of DES.
36645+ *
36646+ * Revision 1.49 2000/07/28 13:50:53 rgb
36647+ * Changed enet_statistics to net_device_stats and added back compatibility
36648+ * for pre-2.1.19.
36649+ *
36650+ * Revision 1.48 2000/05/10 19:14:40 rgb
36651+ * Only check usetime against soft and hard limits if the tdb has been
36652+ * used.
36653+ * Cast output of ntohl so that the broken prototype doesn't make our
36654+ * compile noisy.
36655+ *
36656+ * Revision 1.47 2000/05/09 17:45:43 rgb
36657+ * Fix replay bitmap corruption bug upon receipt of bogus packet
36658+ * with correct SPI. This was a DoS.
36659+ *
36660+ * Revision 1.46 2000/03/27 02:31:58 rgb
36661+ * Fixed authentication failure printout bug.
36662+ *
36663+ * Revision 1.45 2000/03/22 16:15:37 rgb
36664+ * Fixed renaming of dev_get (MB).
36665+ *
36666+ * Revision 1.44 2000/03/16 08:17:24 rgb
36667+ * Hardcode PF_KEYv2 support.
36668+ * Fixed minor bug checking AH header length.
36669+ *
36670+ * Revision 1.43 2000/03/14 12:26:59 rgb
36671+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
36672+ *
36673+ * Revision 1.42 2000/01/26 10:04:04 rgb
36674+ * Fixed inbound policy checking on transport mode bug.
36675+ * Fixed noisy 2.0 printk arguments.
36676+ *
36677+ * Revision 1.41 2000/01/24 20:58:02 rgb
36678+ * Improve debugging/reporting support for (disabled) inbound
36679+ * policy checking.
36680+ *
36681+ * Revision 1.40 2000/01/22 23:20:10 rgb
36682+ * Fixed up inboud policy checking code.
36683+ * Cleaned out unused crud.
36684+ *
36685+ * Revision 1.39 2000/01/21 06:15:29 rgb
36686+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
36687+ * Fixed cut-and-paste debug_tunnel to debug_rcv.
36688+ * Added inbound policy checking code, disabled.
36689+ * Simplified output code by updating ipp to post-IPIP decapsulation.
36690+ *
36691+ * elided pre-2000 comments. Use "cvs log"
36692+ *
36693+ *
36694+ * Local Variables:
36695+ * c-set-style: linux
36696+ * End:
36697+ *
36698+ */
36699--- /dev/null Tue Mar 11 13:02:56 2003
36700+++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004
36701@@ -0,0 +1,1880 @@
36702+/*
36703+ * Common routines for IPsec SA maintenance routines.
36704+ *
36705+ * Copyright (C) 1996, 1997 John Ioannidis.
36706+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
36707+ *
36708+ * This program is free software; you can redistribute it and/or modify it
36709+ * under the terms of the GNU General Public License as published by the
36710+ * Free Software Foundation; either version 2 of the License, or (at your
36711+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
36712+ *
36713+ * This program is distributed in the hope that it will be useful, but
36714+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
36715+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36716+ * for more details.
36717+ *
36718+ * RCSID $Id: ipsec_sa.c,v 1.30.2.3 2007-09-05 02:56:10 paul Exp $
36719+ *
36720+ * This is the file formerly known as "ipsec_xform.h"
36721+ *
36722+ */
36723+
36724+#ifndef AUTOCONF_INCLUDED
36725+#include <linux/config.h>
36726+#endif
36727+#include <linux/version.h>
36728+#include <linux/kernel.h> /* printk() */
36729+
36730+#include "openswan/ipsec_param.h"
36731+
36732+#ifdef MALLOC_SLAB
36733+# include <linux/slab.h> /* kmalloc() */
36734+#else /* MALLOC_SLAB */
36735+# include <linux/malloc.h> /* kmalloc() */
36736+#endif /* MALLOC_SLAB */
36737+#include <linux/vmalloc.h> /* vmalloc() */
36738+#include <linux/errno.h> /* error codes */
36739+#include <linux/types.h> /* size_t */
36740+#include <linux/interrupt.h> /* mark_bh */
36741+
36742+#include <linux/netdevice.h> /* struct device, and other headers */
36743+#include <linux/etherdevice.h> /* eth_type_trans */
36744+#include <linux/ip.h> /* struct iphdr */
36745+#include <linux/skbuff.h>
36746+#include <openswan.h>
36747+#ifdef SPINLOCK
36748+#ifdef SPINLOCK_23
36749+#include <linux/spinlock.h> /* *lock* */
36750+#else /* SPINLOCK_23 */
36751+#include <asm/spinlock.h> /* *lock* */
36752+#endif /* SPINLOCK_23 */
36753+#endif /* SPINLOCK */
36754+
36755+#include <net/ip.h>
36756+
36757+#include "openswan/radij.h"
36758+
36759+#include "openswan/ipsec_stats.h"
36760+#include "openswan/ipsec_life.h"
36761+#include "openswan/ipsec_sa.h"
36762+#include "openswan/ipsec_xform.h"
36763+
36764+#include "openswan/ipsec_encap.h"
36765+#include "openswan/ipsec_radij.h"
36766+#include "openswan/ipsec_xform.h"
36767+#include "openswan/ipsec_ipe4.h"
36768+#include "openswan/ipsec_ah.h"
36769+#include "openswan/ipsec_esp.h"
36770+
36771+#include <pfkeyv2.h>
36772+#include <pfkey.h>
36773+
36774+#include "openswan/ipsec_proto.h"
36775+#include "openswan/ipsec_alg.h"
36776+
36777+
36778+#ifdef CONFIG_KLIPS_DEBUG
36779+int debug_xform = 0;
36780+#endif /* CONFIG_KLIPS_DEBUG */
36781+
36782+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
36783+
36784+struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
36785+#ifdef SPINLOCK
36786+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
36787+#else /* SPINLOCK */
36788+spinlock_t tdb_lock;
36789+#endif /* SPINLOCK */
36790+
36791+struct ipsec_sadb ipsec_sadb;
36792+
36793+#if IPSEC_SA_REF_CODE
36794+
36795+/* the sub table must be narrower (or equal) in bits than the variable type
36796+ in the main table to count the number of unused entries in it. */
36797+typedef struct {
36798+ int testSizeOf_refSubTable :
36799+ ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
36800+} dummy;
36801+
36802+
36803+/* The field where the saref will be hosted in the skb must be wide enough to
36804+ accomodate the information it needs to store. */
36805+typedef struct {
36806+ int testSizeOf_refField :
36807+ (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
36808+} dummy2;
36809+
36810+
36811+#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
36812+
36813+
36814+void
36815+ipsec_SAtest(void)
36816+{
36817+ IPsecSAref_t SAref = 258;
36818+ struct ipsec_sa ips;
36819+ ips.ips_ref = 772;
36820+
36821+ printk("klips_debug:ipsec_SAtest: "
36822+ "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
36823+ "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
36824+ "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
36825+ "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
36826+ "IPSEC_SA_REF_TABLE_MASK=%x\n"
36827+ "IPSEC_SA_REF_ENTRY_MASK=%x\n"
36828+ "IPsecSAref2table(%d)=%u\n"
36829+ "IPsecSAref2entry(%d)=%u\n"
36830+ "IPsecSAref2NFmark(%d)=%u\n"
36831+ "IPsecSAref2SA(%d)=%p\n"
36832+ "IPsecSA2SAref(%p)=%d\n"
36833+ ,
36834+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36835+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
36836+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36837+ (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH,
36838+ IPSEC_SA_REF_TABLE_MASK,
36839+ IPSEC_SA_REF_ENTRY_MASK,
36840+ SAref, IPsecSAref2table(SAref),
36841+ SAref, IPsecSAref2entry(SAref),
36842+ SAref, IPsecSAref2NFmark(SAref),
36843+ SAref, IPsecSAref2SA(SAref),
36844+ (&ips), IPsecSA2SAref((&ips))
36845+ );
36846+ return;
36847+}
36848+
36849+int
36850+ipsec_SAref_recycle(void)
36851+{
36852+ int table;
36853+ int entry;
36854+ int error = 0;
36855+
36856+ ipsec_sadb.refFreeListHead = -1;
36857+ ipsec_sadb.refFreeListTail = -1;
36858+
36859+ if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
36860+ KLIPS_PRINT(debug_xform,
36861+ "klips_debug:ipsec_SAref_recycle: "
36862+ "end of table reached, continuing at start..\n");
36863+ ipsec_sadb.refFreeListCont = 0;
36864+ }
36865+
36866+ KLIPS_PRINT(debug_xform,
36867+ "klips_debug:ipsec_SAref_recycle: "
36868+ "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
36869+ ipsec_sadb.refFreeListCont,
36870+ (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
36871+ IPsecSAref2table(ipsec_sadb.refFreeListCont),
36872+ IPsecSAref2entry(ipsec_sadb.refFreeListCont));
36873+
36874+ for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
36875+ table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
36876+ table++) {
36877+ if(ipsec_sadb.refTable[table] == NULL) {
36878+ error = ipsec_SArefSubTable_alloc(table);
36879+ if(error) {
36880+ return error;
36881+ }
36882+ }
36883+ for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
36884+ entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
36885+ entry++) {
36886+ if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
36887+ ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
36888+ if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
36889+ ipsec_sadb.refFreeListHead = 0;
36890+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
36891+ KLIPS_PRINT(debug_xform,
36892+ "klips_debug:ipsec_SAref_recycle: "
36893+ "SArefFreeList refilled.\n");
36894+ return 0;
36895+ }
36896+ }
36897+ }
36898+ }
36899+
36900+ if(ipsec_sadb.refFreeListTail == -1) {
36901+ KLIPS_PRINT(debug_xform,
36902+ "klips_debug:ipsec_SAref_recycle: "
36903+ "out of room in the SArefTable.\n");
36904+
36905+ return(-ENOSPC);
36906+ }
36907+
36908+ ipsec_sadb.refFreeListHead = 0;
36909+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
36910+ KLIPS_PRINT(debug_xform,
36911+ "klips_debug:ipsec_SAref_recycle: "
36912+ "SArefFreeList partly refilled to %d of %d.\n",
36913+ ipsec_sadb.refFreeListTail,
36914+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36915+ return 0;
36916+}
36917+
36918+int
36919+ipsec_SArefSubTable_alloc(unsigned table)
36920+{
36921+ unsigned entry;
36922+ struct IPsecSArefSubTable* SArefsub;
36923+
36924+ KLIPS_PRINT(debug_xform,
36925+ "klips_debug:ipsec_SArefSubTable_alloc: "
36926+ "allocating %lu bytes for table %u of %u.\n",
36927+ (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
36928+ table,
36929+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36930+
36931+ /* allocate another sub-table */
36932+ SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
36933+ if(SArefsub == NULL) {
36934+ KLIPS_PRINT(debug_xform,
36935+ "klips_debug:ipsec_SArefSubTable_alloc: "
36936+ "error allocating memory for table %u of %u!\n",
36937+ table,
36938+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36939+ return -ENOMEM;
36940+ }
36941+
36942+ /* add this sub-table to the main table */
36943+ ipsec_sadb.refTable[table] = SArefsub;
36944+
36945+ /* initialise each element to NULL */
36946+ KLIPS_PRINT(debug_xform,
36947+ "klips_debug:ipsec_SArefSubTable_alloc: "
36948+ "initialising %u elements (2 ^ %u) of table %u.\n",
36949+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36950+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36951+ table);
36952+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36953+ SArefsub->entry[entry] = NULL;
36954+ }
36955+
36956+ return 0;
36957+}
36958+#endif /* IPSEC_SA_REF_CODE */
36959+
36960+int
36961+ipsec_saref_freelist_init(void)
36962+{
36963+ int i;
36964+
36965+ KLIPS_PRINT(debug_xform,
36966+ "klips_debug:ipsec_saref_freelist_init: "
36967+ "initialising %u elements of FreeList.\n",
36968+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36969+
36970+ for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
36971+ ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
36972+ }
36973+ ipsec_sadb.refFreeListHead = -1;
36974+ ipsec_sadb.refFreeListCont = 0;
36975+ ipsec_sadb.refFreeListTail = -1;
36976+
36977+ return 0;
36978+}
36979+
36980+int
36981+ipsec_sadb_init(void)
36982+{
36983+ int error = 0;
36984+ unsigned i;
36985+
36986+ for(i = 0; i < SADB_HASHMOD; i++) {
36987+ ipsec_sadb_hash[i] = NULL;
36988+ }
36989+ /* parts above are for the old style SADB hash table */
36990+
36991+
36992+#if IPSEC_SA_REF_CODE
36993+ /* initialise SA reference table */
36994+
36995+ /* initialise the main table */
36996+ KLIPS_PRINT(debug_xform,
36997+ "klips_debug:ipsec_sadb_init: "
36998+ "initialising main table of size %u (2 ^ %u).\n",
36999+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
37000+ IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
37001+ {
37002+ unsigned table;
37003+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
37004+ ipsec_sadb.refTable[table] = NULL;
37005+ }
37006+ }
37007+
37008+ /* allocate the first sub-table */
37009+ error = ipsec_SArefSubTable_alloc(0);
37010+ if(error) {
37011+ return error;
37012+ }
37013+
37014+ error = ipsec_saref_freelist_init();
37015+#endif /* IPSEC_SA_REF_CODE */
37016+ return error;
37017+}
37018+
37019+#if IPSEC_SA_REF_CODE
37020+IPsecSAref_t
37021+ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
37022+{
37023+ IPsecSAref_t SAref;
37024+
37025+ KLIPS_PRINT(debug_xform,
37026+ "klips_debug:ipsec_SAref_alloc: "
37027+ "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
37028+ ipsec_sadb.refFreeListHead,
37029+ ipsec_sadb.refFreeListCont,
37030+ ipsec_sadb.refFreeListTail,
37031+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
37032+
37033+ if(ipsec_sadb.refFreeListHead == -1) {
37034+ KLIPS_PRINT(debug_xform,
37035+ "klips_debug:ipsec_SAref_alloc: "
37036+ "FreeList empty, recycling...\n");
37037+ *error = ipsec_SAref_recycle();
37038+ if(*error) {
37039+ return IPSEC_SAREF_NULL;
37040+ }
37041+ }
37042+
37043+ SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
37044+ if(SAref == IPSEC_SAREF_NULL) {
37045+ KLIPS_PRINT(debug_xform,
37046+ "klips_debug:ipsec_SAref_alloc: "
37047+ "unexpected error, refFreeListHead = %d points to invalid entry.\n",
37048+ ipsec_sadb.refFreeListHead);
37049+ *error = -ESPIPE;
37050+ return IPSEC_SAREF_NULL;
37051+ }
37052+
37053+ KLIPS_PRINT(debug_xform,
37054+ "klips_debug:ipsec_SAref_alloc: "
37055+ "allocating SAref=%d, table=%u, entry=%u of %u.\n",
37056+ SAref,
37057+ IPsecSAref2table(SAref),
37058+ IPsecSAref2entry(SAref),
37059+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
37060+
37061+ ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
37062+ ipsec_sadb.refFreeListHead++;
37063+ if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
37064+ KLIPS_PRINT(debug_xform,
37065+ "klips_debug:ipsec_SAref_alloc: "
37066+ "last FreeList entry allocated, resetting list head to empty.\n");
37067+ ipsec_sadb.refFreeListHead = -1;
37068+ }
37069+
37070+ return SAref;
37071+}
37072+#endif /* IPSEC_SA_REF_CODE */
37073+
37074+int
37075+ipsec_sa_print(struct ipsec_sa *ips)
37076+{
37077+ char sa[SATOT_BUF];
37078+ size_t sa_len;
37079+
37080+ printk(KERN_INFO "klips_debug: SA:");
37081+ if(ips == NULL) {
37082+ printk("NULL\n");
37083+ return -ENOENT;
37084+ }
37085+ printk(" ref=%d", ips->ips_ref);
37086+ printk(" refcount=%d", atomic_read(&ips->ips_refcount));
37087+ if(ips->ips_hnext != NULL) {
37088+ printk(" hnext=0p%p", ips->ips_hnext);
37089+ }
37090+ if(ips->ips_inext != NULL) {
37091+ printk(" inext=0p%p", ips->ips_inext);
37092+ }
37093+ if(ips->ips_onext != NULL) {
37094+ printk(" onext=0p%p", ips->ips_onext);
37095+ }
37096+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37097+ printk(" said=%s", sa_len ? sa : " (error)");
37098+ if(ips->ips_seq) {
37099+ printk(" seq=%u", ips->ips_seq);
37100+ }
37101+ if(ips->ips_pid) {
37102+ printk(" pid=%u", ips->ips_pid);
37103+ }
37104+ if(ips->ips_authalg) {
37105+ printk(" authalg=%u", ips->ips_authalg);
37106+ }
37107+ if(ips->ips_encalg) {
37108+ printk(" encalg=%u", ips->ips_encalg);
37109+ }
37110+ printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
37111+ if(ips->ips_replaywin) {
37112+ printk(" ooowin=%u", ips->ips_replaywin);
37113+ }
37114+ if(ips->ips_flags) {
37115+ printk(" flags=%u", ips->ips_flags);
37116+ }
37117+ if(ips->ips_addr_s) {
37118+ char buf[SUBNETTOA_BUF];
37119+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
37120+ 0, buf, sizeof(buf));
37121+ printk(" src=%s", buf);
37122+ }
37123+ if(ips->ips_addr_d) {
37124+ char buf[SUBNETTOA_BUF];
37125+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
37126+ 0, buf, sizeof(buf));
37127+ printk(" dst=%s", buf);
37128+ }
37129+ if(ips->ips_addr_p) {
37130+ char buf[SUBNETTOA_BUF];
37131+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
37132+ 0, buf, sizeof(buf));
37133+ printk(" proxy=%s", buf);
37134+ }
37135+ if(ips->ips_key_bits_a) {
37136+ printk(" key_bits_a=%u", ips->ips_key_bits_a);
37137+ }
37138+ if(ips->ips_key_bits_e) {
37139+ printk(" key_bits_e=%u", ips->ips_key_bits_e);
37140+ }
37141+
37142+ printk("\n");
37143+ return 0;
37144+}
37145+
37146+struct ipsec_sa*
37147+ipsec_sa_alloc(int*error) /* pass in error var by pointer */
37148+{
37149+ struct ipsec_sa* ips;
37150+
37151+ if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
37152+ KLIPS_PRINT(debug_xform,
37153+ "klips_debug:ipsec_sa_alloc: "
37154+ "memory allocation error\n");
37155+ *error = -ENOMEM;
37156+ return NULL;
37157+ }
37158+ memset((caddr_t)ips, 0, sizeof(*ips));
37159+#if IPSEC_SA_REF_CODE
37160+ ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */
37161+ KLIPS_PRINT(debug_xform,
37162+ "klips_debug:ipsec_sa_alloc: "
37163+ "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
37164+ (unsigned long) sizeof(*ips),
37165+ ips,
37166+ ips->ips_ref);
37167+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
37168+ kfree(ips);
37169+ KLIPS_PRINT(debug_xform,
37170+ "klips_debug:ipsec_sa_alloc: "
37171+ "SAref allocation error\n");
37172+ return NULL;
37173+ }
37174+
37175+ atomic_inc(&ips->ips_refcount);
37176+ IPsecSAref2SA(ips->ips_ref) = ips;
37177+#endif /* IPSEC_SA_REF_CODE */
37178+
37179+ *error = 0;
37180+ return(ips);
37181+}
37182+
37183+int
37184+ipsec_sa_free(struct ipsec_sa* ips)
37185+{
37186+ return ipsec_sa_wipe(ips);
37187+}
37188+
37189+struct ipsec_sa *
37190+ipsec_sa_getbyid(ip_said *said)
37191+{
37192+ int hashval;
37193+ struct ipsec_sa *ips;
37194+ char sa[SATOT_BUF];
37195+ size_t sa_len;
37196+
37197+ if(said == NULL) {
37198+ KLIPS_PRINT(debug_xform,
37199+ "klips_error:ipsec_sa_getbyid: "
37200+ "null pointer passed in!\n");
37201+ return NULL;
37202+ }
37203+
37204+ sa_len = KLIPS_SATOT(debug_xform, said, 0, sa, sizeof(sa));
37205+
37206+ hashval = IPS_HASH(said);
37207+
37208+ KLIPS_PRINT(debug_xform,
37209+ "klips_debug:ipsec_sa_getbyid: "
37210+ "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
37211+ hashval,
37212+ sa_len ? sa : " (error)");
37213+
37214+ if((ips = ipsec_sadb_hash[hashval]) == NULL) {
37215+ KLIPS_PRINT(debug_xform,
37216+ "klips_debug:ipsec_sa_getbyid: "
37217+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
37218+ hashval,
37219+ sa_len ? sa : " (error)");
37220+ return NULL;
37221+ }
37222+
37223+ for (; ips; ips = ips->ips_hnext) {
37224+ if ((ips->ips_said.spi == said->spi) &&
37225+ (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
37226+ (ips->ips_said.proto == said->proto)) {
37227+ atomic_inc(&ips->ips_refcount);
37228+ return ips;
37229+ }
37230+ }
37231+
37232+ KLIPS_PRINT(debug_xform,
37233+ "klips_debug:ipsec_sa_getbyid: "
37234+ "no entry in linked list for hash=%d of SA:%s.\n",
37235+ hashval,
37236+ sa_len ? sa : " (error)");
37237+ return NULL;
37238+}
37239+
37240+int
37241+ipsec_sa_put(struct ipsec_sa *ips)
37242+{
37243+ char sa[SATOT_BUF];
37244+ size_t sa_len;
37245+
37246+ if(ips == NULL) {
37247+ KLIPS_PRINT(debug_xform,
37248+ "klips_error:ipsec_sa_put: "
37249+ "null pointer passed in!\n");
37250+ return -1;
37251+ }
37252+
37253+ sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
37254+
37255+ KLIPS_PRINT(debug_xform,
37256+ "klips_debug:ipsec_sa_put: "
37257+ "ipsec_sa SA:%s, ref:%d reference count decremented.\n",
37258+ sa_len ? sa : " (error)",
37259+ ips->ips_ref);
37260+
37261+ atomic_dec(&ips->ips_refcount);
37262+
37263+ return 0;
37264+}
37265+
37266+/*
37267+ The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
37268+*/
37269+int
37270+ipsec_sa_add(struct ipsec_sa *ips)
37271+{
37272+ int error = 0;
37273+ unsigned int hashval;
37274+
37275+ if(ips == NULL) {
37276+ KLIPS_PRINT(debug_xform,
37277+ "klips_error:ipsec_sa_add: "
37278+ "null pointer passed in!\n");
37279+ return -ENODATA;
37280+ }
37281+ hashval = IPS_HASH(&ips->ips_said);
37282+
37283+ atomic_inc(&ips->ips_refcount);
37284+ spin_lock_bh(&tdb_lock);
37285+
37286+ ips->ips_hnext = ipsec_sadb_hash[hashval];
37287+ ipsec_sadb_hash[hashval] = ips;
37288+
37289+ spin_unlock_bh(&tdb_lock);
37290+
37291+ return error;
37292+}
37293+
37294+/*
37295+ The ipsec_sa table better be locked before it is handed in, or races might happen
37296+*/
37297+int
37298+ipsec_sa_del(struct ipsec_sa *ips)
37299+{
37300+ unsigned int hashval;
37301+ struct ipsec_sa *ipstp;
37302+ char sa[SATOT_BUF];
37303+ size_t sa_len;
37304+
37305+ if(ips == NULL) {
37306+ KLIPS_PRINT(debug_xform,
37307+ "klips_error:ipsec_sa_del: "
37308+ "null pointer passed in!\n");
37309+ return -ENODATA;
37310+ }
37311+
37312+ sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
37313+ if(ips->ips_inext || ips->ips_onext) {
37314+ KLIPS_PRINT(debug_xform,
37315+ "klips_error:ipsec_sa_del: "
37316+ "SA:%s still linked!\n",
37317+ sa_len ? sa : " (error)");
37318+ return -EMLINK;
37319+ }
37320+
37321+ hashval = IPS_HASH(&ips->ips_said);
37322+
37323+ KLIPS_PRINT(debug_xform,
37324+ "klips_debug:ipsec_sa_del: "
37325+ "deleting SA:%s, hashval=%d.\n",
37326+ sa_len ? sa : " (error)",
37327+ hashval);
37328+ if(ipsec_sadb_hash[hashval] == NULL) {
37329+ KLIPS_PRINT(debug_xform,
37330+ "klips_debug:ipsec_sa_del: "
37331+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
37332+ hashval,
37333+ sa_len ? sa : " (error)");
37334+ return -ENOENT;
37335+ }
37336+
37337+ if (ips == ipsec_sadb_hash[hashval]) {
37338+ ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
37339+ ips->ips_hnext = NULL;
37340+ atomic_dec(&ips->ips_refcount);
37341+ KLIPS_PRINT(debug_xform,
37342+ "klips_debug:ipsec_sa_del: "
37343+ "successfully deleted first ipsec_sa in chain.\n");
37344+ return 0;
37345+ } else {
37346+ for (ipstp = ipsec_sadb_hash[hashval];
37347+ ipstp;
37348+ ipstp = ipstp->ips_hnext) {
37349+ if (ipstp->ips_hnext == ips) {
37350+ ipstp->ips_hnext = ips->ips_hnext;
37351+ ips->ips_hnext = NULL;
37352+ atomic_dec(&ips->ips_refcount);
37353+ KLIPS_PRINT(debug_xform,
37354+ "klips_debug:ipsec_sa_del: "
37355+ "successfully deleted link in ipsec_sa chain.\n");
37356+ return 0;
37357+ }
37358+ }
37359+ }
37360+
37361+ KLIPS_PRINT(debug_xform,
37362+ "klips_debug:ipsec_sa_del: "
37363+ "no entries in linked list for hash=%d of SA:%s.\n",
37364+ hashval,
37365+ sa_len ? sa : " (error)");
37366+ return -ENOENT;
37367+}
37368+
37369+/*
37370+ The ipsec_sa table better be locked before it is handed in, or races
37371+ might happen
37372+*/
37373+int
37374+ipsec_sa_delchain(struct ipsec_sa *ips)
37375+{
37376+ struct ipsec_sa *ipsdel;
37377+ int error = 0;
37378+ char sa[SATOT_BUF];
37379+ size_t sa_len;
37380+
37381+ if(ips == NULL) {
37382+ KLIPS_PRINT(debug_xform,
37383+ "klips_error:ipsec_sa_delchain: "
37384+ "null pointer passed in!\n");
37385+ return -ENODATA;
37386+ }
37387+
37388+ sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
37389+ KLIPS_PRINT(debug_xform,
37390+ "klips_debug:ipsec_sa_delchain: "
37391+ "passed SA:%s\n",
37392+ sa_len ? sa : " (error)");
37393+ while(ips->ips_onext != NULL) {
37394+ ips = ips->ips_onext;
37395+ }
37396+
37397+ while(ips) {
37398+ /* XXX send a pfkey message up to advise of deleted ipsec_sa */
37399+ sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
37400+ KLIPS_PRINT(debug_xform,
37401+ "klips_debug:ipsec_sa_delchain: "
37402+ "unlinking and delting SA:%s",
37403+ sa_len ? sa : " (error)");
37404+ ipsdel = ips;
37405+ ips = ips->ips_inext;
37406+ if(ips != NULL) {
37407+ sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
37408+ KLIPS_PRINT(debug_xform,
37409+ ", inext=%s",
37410+ sa_len ? sa : " (error)");
37411+ atomic_dec(&ipsdel->ips_refcount);
37412+ ipsdel->ips_inext = NULL;
37413+ atomic_dec(&ips->ips_refcount);
37414+ ips->ips_onext = NULL;
37415+ }
37416+ KLIPS_PRINT(debug_xform,
37417+ ".\n");
37418+ if((error = ipsec_sa_del(ipsdel))) {
37419+ KLIPS_PRINT(debug_xform,
37420+ "klips_debug:ipsec_sa_delchain: "
37421+ "ipsec_sa_del returned error %d.\n", -error);
37422+ return error;
37423+ }
37424+ if((error = ipsec_sa_wipe(ipsdel))) {
37425+ KLIPS_PRINT(debug_xform,
37426+ "klips_debug:ipsec_sa_delchain: "
37427+ "ipsec_sa_wipe returned error %d.\n", -error);
37428+ return error;
37429+ }
37430+ }
37431+ return error;
37432+}
37433+
37434+int
37435+ipsec_sadb_cleanup(__u8 proto)
37436+{
37437+ unsigned i;
37438+ int error = 0;
37439+ struct ipsec_sa *ips, **ipsprev, *ipsdel;
37440+ char sa[SATOT_BUF];
37441+ size_t sa_len;
37442+
37443+ KLIPS_PRINT(debug_xform,
37444+ "klips_debug:ipsec_sadb_cleanup: "
37445+ "cleaning up proto=%d.\n",
37446+ proto);
37447+
37448+ spin_lock_bh(&tdb_lock);
37449+
37450+ for (i = 0; i < SADB_HASHMOD; i++) {
37451+ ipsprev = &(ipsec_sadb_hash[i]);
37452+ ips = ipsec_sadb_hash[i];
37453+ if(ips != NULL) {
37454+ atomic_inc(&ips->ips_refcount);
37455+ }
37456+ for(; ips != NULL;) {
37457+ sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
37458+ KLIPS_PRINT(debug_xform,
37459+ "klips_debug:ipsec_sadb_cleanup: "
37460+ "checking SA:%s, hash=%d, ref=%d",
37461+ sa_len ? sa : " (error)",
37462+ i,
37463+ ips->ips_ref);
37464+ ipsdel = ips;
37465+ ips = ipsdel->ips_hnext;
37466+ if(ips != NULL) {
37467+ atomic_inc(&ips->ips_refcount);
37468+ sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
37469+ KLIPS_PRINT(debug_xform,
37470+ ", hnext=%s",
37471+ sa_len ? sa : " (error)");
37472+ }
37473+ if(*ipsprev != NULL) {
37474+ sa_len = KLIPS_SATOT(debug_xform, &(*ipsprev)->ips_said, 0, sa, sizeof(sa));
37475+ KLIPS_PRINT(debug_xform,
37476+ ", *ipsprev=%s",
37477+ sa_len ? sa : " (error)");
37478+ if((*ipsprev)->ips_hnext) {
37479+ sa_len = KLIPS_SATOT(debug_xform, &(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
37480+ KLIPS_PRINT(debug_xform,
37481+ ", *ipsprev->ips_hnext=%s",
37482+ sa_len ? sa : " (error)");
37483+ }
37484+ }
37485+ KLIPS_PRINT(debug_xform,
37486+ ".\n");
37487+ if(proto == 0 || (proto == ipsdel->ips_said.proto)) {
37488+ sa_len = KLIPS_SATOT(debug_xform, &ipsdel->ips_said, 0, sa, sizeof(sa));
37489+ KLIPS_PRINT(debug_xform,
37490+ "klips_debug:ipsec_sadb_cleanup: "
37491+ "deleting SA chain:%s.\n",
37492+ sa_len ? sa : " (error)");
37493+ if((error = ipsec_sa_delchain(ipsdel))) {
37494+ SENDERR(-error);
37495+ }
37496+ ipsprev = &(ipsec_sadb_hash[i]);
37497+ ips = ipsec_sadb_hash[i];
37498+
37499+ KLIPS_PRINT(debug_xform,
37500+ "klips_debug:ipsec_sadb_cleanup: "
37501+ "deleted SA chain:%s",
37502+ sa_len ? sa : " (error)");
37503+ if(ips != NULL) {
37504+ sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
37505+ KLIPS_PRINT(debug_xform,
37506+ ", ipsec_sadb_hash[%d]=%s",
37507+ i,
37508+ sa_len ? sa : " (error)");
37509+ }
37510+ if(*ipsprev != NULL) {
37511+ sa_len = KLIPS_SATOT(debug_xform, &(*ipsprev)->ips_said, 0, sa, sizeof(sa));
37512+ KLIPS_PRINT(debug_xform,
37513+ ", *ipsprev=%s",
37514+ sa_len ? sa : " (error)");
37515+ if((*ipsprev)->ips_hnext != NULL) {
37516+ sa_len = KLIPS_SATOT(debug_xform, &(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
37517+ KLIPS_PRINT(debug_xform,
37518+ ", *ipsprev->ips_hnext=%s",
37519+ sa_len ? sa : " (error)");
37520+ }
37521+ }
37522+ KLIPS_PRINT(debug_xform,
37523+ ".\n");
37524+ } else {
37525+ ipsprev = &ipsdel;
37526+ }
37527+ if(ipsdel != NULL) {
37528+ ipsec_sa_put(ipsdel);
37529+ }
37530+ }
37531+ }
37532+ errlab:
37533+
37534+ spin_unlock_bh(&tdb_lock);
37535+
37536+
37537+#if IPSEC_SA_REF_CODE
37538+ /* clean up SA reference table */
37539+
37540+ /* go through the ref table and clean out all the SAs */
37541+ KLIPS_PRINT(debug_xform,
37542+ "klips_debug:ipsec_sadb_cleanup: "
37543+ "removing SAref entries and tables.");
37544+ {
37545+ unsigned table, entry;
37546+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
37547+ KLIPS_PRINT(debug_xform,
37548+ "klips_debug:ipsec_sadb_cleanup: "
37549+ "cleaning SAref table=%u.\n",
37550+ table);
37551+ if(ipsec_sadb.refTable[table] == NULL) {
37552+ printk("\n");
37553+ KLIPS_PRINT(debug_xform,
37554+ "klips_debug:ipsec_sadb_cleanup: "
37555+ "cleaned %u used refTables.\n",
37556+ table);
37557+ break;
37558+ }
37559+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
37560+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
37561+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
37562+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
37563+ }
37564+ }
37565+ }
37566+ }
37567+#endif /* IPSEC_SA_REF_CODE */
37568+
37569+ return(error);
37570+}
37571+
37572+int
37573+ipsec_sadb_free(void)
37574+{
37575+ int error = 0;
37576+
37577+ KLIPS_PRINT(debug_xform,
37578+ "klips_debug:ipsec_sadb_free: "
37579+ "freeing SArefTable memory.\n");
37580+
37581+ /* clean up SA reference table */
37582+
37583+ /* go through the ref table and clean out all the SAs if any are
37584+ left and free table memory */
37585+ KLIPS_PRINT(debug_xform,
37586+ "klips_debug:ipsec_sadb_free: "
37587+ "removing SAref entries and tables.\n");
37588+ {
37589+ unsigned table, entry;
37590+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
37591+ KLIPS_PRINT(debug_xform,
37592+ "klips_debug:ipsec_sadb_free: "
37593+ "removing SAref table=%u.\n",
37594+ table);
37595+ if(ipsec_sadb.refTable[table] == NULL) {
37596+ KLIPS_PRINT(debug_xform,
37597+ "klips_debug:ipsec_sadb_free: "
37598+ "removed %u used refTables.\n",
37599+ table);
37600+ break;
37601+ }
37602+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
37603+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
37604+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
37605+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
37606+ }
37607+ }
37608+ vfree(ipsec_sadb.refTable[table]);
37609+ ipsec_sadb.refTable[table] = NULL;
37610+ }
37611+ }
37612+
37613+ return(error);
37614+}
37615+
37616+int
37617+ipsec_sa_wipe(struct ipsec_sa *ips)
37618+{
37619+ if(ips == NULL) {
37620+ return -ENODATA;
37621+ }
37622+
37623+ /* if(atomic_dec_and_test(ips)) {
37624+ }; */
37625+
37626+#if IPSEC_SA_REF_CODE
37627+ /* remove me from the SArefTable */
37628+ {
37629+ char sa[SATOT_BUF];
37630+ size_t sa_len;
37631+ sa_len = KLIPS_SATOT(debug_xform, &ips->ips_said, 0, sa, sizeof(sa));
37632+ KLIPS_PRINT(debug_xform,
37633+ "klips_debug:ipsec_sa_wipe: "
37634+ "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
37635+ sa_len ? sa : " (error)",
37636+ ips,
37637+ ips->ips_ref,
37638+ IPsecSAref2table(IPsecSA2SAref(ips)),
37639+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
37640+ IPsecSAref2entry(IPsecSA2SAref(ips)));
37641+ }
37642+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
37643+ KLIPS_PRINT(debug_xform,
37644+ "klips_debug:ipsec_sa_wipe: "
37645+ "why does this SA not have a valid SAref?.\n");
37646+ }
37647+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
37648+ ips->ips_ref = IPSEC_SAREF_NULL;
37649+ ipsec_sa_put(ips);
37650+#endif /* IPSEC_SA_REF_CODE */
37651+
37652+ /* paranoid clean up */
37653+ if(ips->ips_addr_s != NULL) {
37654+ memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
37655+ kfree(ips->ips_addr_s);
37656+ }
37657+ ips->ips_addr_s = NULL;
37658+
37659+ if(ips->ips_addr_d != NULL) {
37660+ memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
37661+ kfree(ips->ips_addr_d);
37662+ }
37663+ ips->ips_addr_d = NULL;
37664+
37665+ if(ips->ips_addr_p != NULL) {
37666+ memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
37667+ kfree(ips->ips_addr_p);
37668+ }
37669+ ips->ips_addr_p = NULL;
37670+
37671+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
37672+ if(ips->ips_natt_oa) {
37673+ memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
37674+ kfree(ips->ips_natt_oa);
37675+ }
37676+ ips->ips_natt_oa = NULL;
37677+#endif
37678+
37679+ if(ips->ips_key_a != NULL) {
37680+ memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
37681+ kfree(ips->ips_key_a);
37682+ }
37683+ ips->ips_key_a = NULL;
37684+
37685+ if(ips->ips_key_e != NULL) {
37686+ if (ips->ips_alg_enc &&
37687+ ips->ips_alg_enc->ixt_e_destroy_key)
37688+ {
37689+ ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
37690+ ips->ips_key_e);
37691+ } else
37692+ {
37693+ memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
37694+ kfree(ips->ips_key_e);
37695+ }
37696+ }
37697+ ips->ips_key_e = NULL;
37698+
37699+ if(ips->ips_iv != NULL) {
37700+ memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
37701+ kfree(ips->ips_iv);
37702+ }
37703+ ips->ips_iv = NULL;
37704+
37705+ if(ips->ips_ident_s.data != NULL) {
37706+ memset((caddr_t)(ips->ips_ident_s.data),
37707+ 0,
37708+ ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37709+ kfree(ips->ips_ident_s.data);
37710+ }
37711+ ips->ips_ident_s.data = NULL;
37712+
37713+ if(ips->ips_ident_d.data != NULL) {
37714+ memset((caddr_t)(ips->ips_ident_d.data),
37715+ 0,
37716+ ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37717+ kfree(ips->ips_ident_d.data);
37718+ }
37719+ ips->ips_ident_d.data = NULL;
37720+
37721+#ifdef CONFIG_KLIPS_ALG
37722+ if (ips->ips_alg_enc||ips->ips_alg_auth) {
37723+ ipsec_alg_sa_wipe(ips);
37724+ }
37725+#endif /* CONFIG_KLIPS_ALG */
37726+
37727+ memset((caddr_t)ips, 0, sizeof(*ips));
37728+ kfree(ips);
37729+ ips = NULL;
37730+
37731+ return 0;
37732+}
37733+
37734+extern int sysctl_ipsec_debug_verbose;
37735+
37736+int ipsec_sa_init(struct ipsec_sa *ipsp)
37737+{
37738+ int i;
37739+ int error = 0;
37740+ char sa[SATOT_BUF];
37741+ size_t sa_len;
37742+ char ipaddr_txt[ADDRTOA_BUF];
37743+ char ipaddr2_txt[ADDRTOA_BUF];
37744+#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37745+ unsigned char kb[AHMD596_BLKLEN];
37746+#endif
37747+#if defined CONFIG_KLIPS_ALG
37748+ struct ipsec_alg_enc *ixt_e = NULL;
37749+ struct ipsec_alg_auth *ixt_a = NULL;
37750+#endif /* CONFIG_KLIPS_ALG */
37751+
37752+ if(ipsp == NULL) {
37753+ KLIPS_PRINT(debug_pfkey,
37754+ "ipsec_sa_init: "
37755+ "ipsp is NULL, fatal\n");
37756+ SENDERR(EINVAL);
37757+ }
37758+
37759+ sa_len = KLIPS_SATOT(debug_pfkey, &ipsp->ips_said, 0, sa, sizeof(sa));
37760+
37761+ KLIPS_PRINT(debug_pfkey,
37762+ "ipsec_sa_init: "
37763+ "(pfkey defined) called for SA:%s\n",
37764+ sa_len ? sa : " (error)");
37765+
37766+ KLIPS_PRINT(debug_pfkey,
37767+ "ipsec_sa_init: "
37768+ "calling init routine of %s%s%s\n",
37769+ IPS_XFORM_NAME(ipsp));
37770+
37771+ switch(ipsp->ips_said.proto) {
37772+
37773+#ifdef CONFIG_KLIPS_IPIP
37774+ case IPPROTO_IPIP: {
37775+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
37776+ 0,
37777+ ipaddr_txt, sizeof(ipaddr_txt));
37778+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
37779+ 0,
37780+ ipaddr2_txt, sizeof(ipaddr_txt));
37781+ KLIPS_PRINT(debug_pfkey,
37782+ "ipsec_sa_init: "
37783+ "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
37784+ ipaddr_txt,
37785+ ipaddr2_txt);
37786+ }
37787+ break;
37788+#endif /* !CONFIG_KLIPS_IPIP */
37789+
37790+#ifdef CONFIG_KLIPS_AH
37791+ case IPPROTO_AH:
37792+ switch(ipsp->ips_authalg) {
37793+# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37794+ case AH_MD5: {
37795+ unsigned char *akp;
37796+ unsigned int aks;
37797+ MD5_CTX *ictx;
37798+ MD5_CTX *octx;
37799+
37800+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37801+ KLIPS_PRINT(debug_pfkey,
37802+ "ipsec_sa_init: "
37803+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37804+ ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
37805+ SENDERR(EINVAL);
37806+ }
37807+
37808+# if KLIPS_DIVULGE_HMAC_KEY
37809+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37810+ "ipsec_sa_init: "
37811+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37812+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37813+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37814+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37815+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37816+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37817+
37818+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37819+
37820+ /* save the pointer to the key material */
37821+ akp = ipsp->ips_key_a;
37822+ aks = ipsp->ips_key_a_size;
37823+
37824+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37825+ "ipsec_sa_init: "
37826+ "allocating %lu bytes for md5_ctx.\n",
37827+ (unsigned long) sizeof(struct md5_ctx));
37828+ if((ipsp->ips_key_a = (caddr_t)
37829+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37830+ ipsp->ips_key_a = akp;
37831+ SENDERR(ENOMEM);
37832+ }
37833+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37834+
37835+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37836+ kb[i] = akp[i] ^ HMAC_IPAD;
37837+ }
37838+ for (; i < AHMD596_BLKLEN; i++) {
37839+ kb[i] = HMAC_IPAD;
37840+ }
37841+
37842+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37843+ osMD5Init(ictx);
37844+ osMD5Update(ictx, kb, AHMD596_BLKLEN);
37845+
37846+ for (i = 0; i < AHMD596_BLKLEN; i++) {
37847+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37848+ }
37849+
37850+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37851+ osMD5Init(octx);
37852+ osMD5Update(octx, kb, AHMD596_BLKLEN);
37853+
37854+# if KLIPS_DIVULGE_HMAC_KEY
37855+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37856+ "ipsec_sa_init: "
37857+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37858+ ((__u32*)ictx)[0],
37859+ ((__u32*)ictx)[1],
37860+ ((__u32*)ictx)[2],
37861+ ((__u32*)ictx)[3],
37862+ ((__u32*)octx)[0],
37863+ ((__u32*)octx)[1],
37864+ ((__u32*)octx)[2],
37865+ ((__u32*)octx)[3] );
37866+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37867+
37868+ /* zero key buffer -- paranoid */
37869+ memset(akp, 0, aks);
37870+ kfree(akp);
37871+ }
37872+ break;
37873+# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37874+# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37875+ case AH_SHA: {
37876+ unsigned char *akp;
37877+ unsigned int aks;
37878+ SHA1_CTX *ictx;
37879+ SHA1_CTX *octx;
37880+
37881+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37882+ KLIPS_PRINT(debug_pfkey,
37883+ "ipsec_sa_init: "
37884+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37885+ ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
37886+ SENDERR(EINVAL);
37887+ }
37888+
37889+# if KLIPS_DIVULGE_HMAC_KEY
37890+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37891+ "ipsec_sa_init: "
37892+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37893+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37894+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37895+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37896+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37897+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37898+
37899+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37900+
37901+ /* save the pointer to the key material */
37902+ akp = ipsp->ips_key_a;
37903+ aks = ipsp->ips_key_a_size;
37904+
37905+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37906+ "ipsec_sa_init: "
37907+ "allocating %lu bytes for sha1_ctx.\n",
37908+ (unsigned long) sizeof(struct sha1_ctx));
37909+ if((ipsp->ips_key_a = (caddr_t)
37910+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37911+ ipsp->ips_key_a = akp;
37912+ SENDERR(ENOMEM);
37913+ }
37914+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37915+
37916+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37917+ kb[i] = akp[i] ^ HMAC_IPAD;
37918+ }
37919+ for (; i < AHMD596_BLKLEN; i++) {
37920+ kb[i] = HMAC_IPAD;
37921+ }
37922+
37923+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37924+ SHA1Init(ictx);
37925+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37926+
37927+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
37928+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37929+ }
37930+
37931+ octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
37932+ SHA1Init(octx);
37933+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
37934+
37935+# if KLIPS_DIVULGE_HMAC_KEY
37936+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37937+ "ipsec_sa_init: "
37938+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37939+ ((__u32*)ictx)[0],
37940+ ((__u32*)ictx)[1],
37941+ ((__u32*)ictx)[2],
37942+ ((__u32*)ictx)[3],
37943+ ((__u32*)octx)[0],
37944+ ((__u32*)octx)[1],
37945+ ((__u32*)octx)[2],
37946+ ((__u32*)octx)[3] );
37947+# endif /* KLIPS_DIVULGE_HMAC_KEY */
37948+ /* zero key buffer -- paranoid */
37949+ memset(akp, 0, aks);
37950+ kfree(akp);
37951+ }
37952+ break;
37953+# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37954+ default:
37955+ KLIPS_PRINT(debug_pfkey,
37956+ "ipsec_sa_init: "
37957+ "authalg=%d support not available in the kernel",
37958+ ipsp->ips_authalg);
37959+ SENDERR(EINVAL);
37960+ }
37961+ break;
37962+#endif /* CONFIG_KLIPS_AH */
37963+
37964+#ifdef CONFIG_KLIPS_ESP
37965+ case IPPROTO_ESP:
37966+ {
37967+#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37968+ unsigned char *akp;
37969+ unsigned int aks;
37970+#endif
37971+ ipsp->ips_iv_size = 0;
37972+#ifdef CONFIG_KLIPS_ALG
37973+ ipsec_alg_sa_init(ipsp);
37974+ ixt_e=ipsp->ips_alg_enc;
37975+
37976+ if (ixt_e == NULL) {
37977+ if(printk_ratelimit()) {
37978+ printk(KERN_INFO
37979+ "ipsec_sa_init: "
37980+ "encalg=%d support not available in the kernel",
37981+ ipsp->ips_encalg);
37982+ }
37983+ SENDERR(ENOENT);
37984+ }
37985+
37986+ ipsp->ips_iv_size = ixt_e->ixt_common.ixt_support.ias_ivlen/8;
37987+
37988+ /* Create IV */
37989+ if (ipsp->ips_iv_size) {
37990+ if((ipsp->ips_iv = (caddr_t)
37991+ kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) {
37992+ SENDERR(ENOMEM);
37993+ }
37994+ prng_bytes(&ipsec_prng,
37995+ (char *)ipsp->ips_iv,
37996+ ipsp->ips_iv_size);
37997+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
37998+ }
37999+
38000+ if ((error=ipsec_alg_enc_key_create(ipsp)) < 0)
38001+ SENDERR(-error);
38002+
38003+ if ((ixt_a=ipsp->ips_alg_auth)) {
38004+ if ((error=ipsec_alg_auth_key_create(ipsp)) < 0)
38005+ SENDERR(-error);
38006+ } else
38007+#endif /* CONFIG_KLIPS_ALG */
38008+
38009+ switch(ipsp->ips_authalg) {
38010+# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
38011+ case AH_MD5: {
38012+ MD5_CTX *ictx;
38013+ MD5_CTX *octx;
38014+
38015+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
38016+ KLIPS_PRINT(debug_pfkey,
38017+ "ipsec_sa_init: "
38018+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
38019+ ipsp->ips_key_bits_a,
38020+ AHMD596_KLEN * 8);
38021+ SENDERR(EINVAL);
38022+ }
38023+
38024+# if KLIPS_DIVULGE_HMAC_KEY
38025+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
38026+ "ipsec_sa_init: "
38027+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
38028+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
38029+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
38030+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
38031+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
38032+# endif /* KLIPS_DIVULGE_HMAC_KEY */
38033+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
38034+
38035+ /* save the pointer to the key material */
38036+ akp = ipsp->ips_key_a;
38037+ aks = ipsp->ips_key_a_size;
38038+
38039+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
38040+ "ipsec_sa_init: "
38041+ "allocating %lu bytes for md5_ctx.\n",
38042+ (unsigned long) sizeof(struct md5_ctx));
38043+ if((ipsp->ips_key_a = (caddr_t)
38044+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
38045+ ipsp->ips_key_a = akp;
38046+ SENDERR(ENOMEM);
38047+ }
38048+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
38049+
38050+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
38051+ kb[i] = akp[i] ^ HMAC_IPAD;
38052+ }
38053+ for (; i < AHMD596_BLKLEN; i++) {
38054+ kb[i] = HMAC_IPAD;
38055+ }
38056+
38057+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
38058+ osMD5Init(ictx);
38059+ osMD5Update(ictx, kb, AHMD596_BLKLEN);
38060+
38061+ for (i = 0; i < AHMD596_BLKLEN; i++) {
38062+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
38063+ }
38064+
38065+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
38066+ osMD5Init(octx);
38067+ osMD5Update(octx, kb, AHMD596_BLKLEN);
38068+
38069+# if KLIPS_DIVULGE_HMAC_KEY
38070+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
38071+ "ipsec_sa_init: "
38072+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
38073+ ((__u32*)ictx)[0],
38074+ ((__u32*)ictx)[1],
38075+ ((__u32*)ictx)[2],
38076+ ((__u32*)ictx)[3],
38077+ ((__u32*)octx)[0],
38078+ ((__u32*)octx)[1],
38079+ ((__u32*)octx)[2],
38080+ ((__u32*)octx)[3] );
38081+# endif /* KLIPS_DIVULGE_HMAC_KEY */
38082+ /* paranoid */
38083+ memset(akp, 0, aks);
38084+ kfree(akp);
38085+ break;
38086+ }
38087+# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
38088+# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
38089+ case AH_SHA: {
38090+ SHA1_CTX *ictx;
38091+ SHA1_CTX *octx;
38092+
38093+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
38094+ KLIPS_PRINT(debug_pfkey,
38095+ "ipsec_sa_init: "
38096+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
38097+ ipsp->ips_key_bits_a,
38098+ AHSHA196_KLEN * 8);
38099+ SENDERR(EINVAL);
38100+ }
38101+
38102+# if KLIPS_DIVULGE_HMAC_KEY
38103+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
38104+ "ipsec_sa_init: "
38105+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
38106+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
38107+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
38108+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
38109+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
38110+# endif /* KLIPS_DIVULGE_HMAC_KEY */
38111+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
38112+
38113+ /* save the pointer to the key material */
38114+ akp = ipsp->ips_key_a;
38115+ aks = ipsp->ips_key_a_size;
38116+
38117+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
38118+ "ipsec_sa_init: "
38119+ "allocating %lu bytes for sha1_ctx.\n",
38120+ (unsigned long) sizeof(struct sha1_ctx));
38121+ if((ipsp->ips_key_a = (caddr_t)
38122+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
38123+ ipsp->ips_key_a = akp;
38124+ SENDERR(ENOMEM);
38125+ }
38126+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
38127+
38128+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
38129+ kb[i] = akp[i] ^ HMAC_IPAD;
38130+ }
38131+ for (; i < AHMD596_BLKLEN; i++) {
38132+ kb[i] = HMAC_IPAD;
38133+ }
38134+
38135+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
38136+ SHA1Init(ictx);
38137+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
38138+
38139+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
38140+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
38141+ }
38142+
38143+ octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
38144+ SHA1Init(octx);
38145+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
38146+
38147+# if KLIPS_DIVULGE_HMAC_KEY
38148+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
38149+ "ipsec_sa_init: "
38150+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
38151+ ((__u32*)ictx)[0],
38152+ ((__u32*)ictx)[1],
38153+ ((__u32*)ictx)[2],
38154+ ((__u32*)ictx)[3],
38155+ ((__u32*)octx)[0],
38156+ ((__u32*)octx)[1],
38157+ ((__u32*)octx)[2],
38158+ ((__u32*)octx)[3] );
38159+# endif /* KLIPS_DIVULGE_HMAC_KEY */
38160+ memset(akp, 0, aks);
38161+ kfree(akp);
38162+ break;
38163+ }
38164+# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
38165+ case AH_NONE:
38166+ break;
38167+ default:
38168+ KLIPS_PRINT(debug_pfkey,
38169+ "ipsec_sa_init: "
38170+ "authalg=%d support not available in the kernel.\n",
38171+ ipsp->ips_authalg);
38172+ SENDERR(EINVAL);
38173+ }
38174+ }
38175+ break;
38176+#endif /* !CONFIG_KLIPS_ESP */
38177+#ifdef CONFIG_KLIPS_IPCOMP
38178+ case IPPROTO_COMP:
38179+ ipsp->ips_comp_adapt_tries = 0;
38180+ ipsp->ips_comp_adapt_skip = 0;
38181+ ipsp->ips_comp_ratio_cbytes = 0;
38182+ ipsp->ips_comp_ratio_dbytes = 0;
38183+ break;
38184+#endif /* CONFIG_KLIPS_IPCOMP */
38185+ default:
38186+ printk(KERN_ERR "KLIPS sa initialization: "
38187+ "proto=%d unknown.\n",
38188+ ipsp->ips_said.proto);
38189+ SENDERR(EINVAL);
38190+ }
38191+
38192+ errlab:
38193+ return(error);
38194+}
38195+
38196+
38197+
38198+/*
38199+ * $Log: ipsec_sa.c,v $
38200+ * Revision 1.30.2.3 2007-09-05 02:56:10 paul
38201+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
38202+ * Fixes based on David McCullough patch.
38203+ *
38204+ * Revision 1.30.2.2 2006/10/06 21:39:26 paul
38205+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
38206+ * set. This is defined through autoconf.h which is included through the
38207+ * linux kernel build macros.
38208+ *
38209+ * Revision 1.30.2.1 2006/04/20 16:33:07 mcr
38210+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
38211+ * Fix in-kernel module compilation. Sub-makefiles do not work.
38212+ *
38213+ * Revision 1.30 2005/05/24 01:02:35 mcr
38214+ * some refactoring/simplification of situation where alg
38215+ * is not found.
38216+ *
38217+ * Revision 1.29 2005/05/18 19:13:28 mcr
38218+ * rename debug messages. make sure that algo not found is not
38219+ * a debug message.
38220+ *
38221+ * Revision 1.28 2005/05/11 01:30:20 mcr
38222+ * removed "poor-man"s OOP in favour of proper C structures.
38223+ *
38224+ * Revision 1.27 2005/04/29 05:10:22 mcr
38225+ * removed from extraenous includes to make unit testing easier.
38226+ *
38227+ * Revision 1.26 2005/04/14 20:56:24 mcr
38228+ * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
38229+ *
38230+ * Revision 1.25 2004/08/22 20:12:16 mcr
38231+ * one more KLIPS_NAT->IPSEC_NAT.
38232+ *
38233+ * Revision 1.24 2004/07/10 19:11:18 mcr
38234+ * CONFIG_IPSEC -> CONFIG_KLIPS.
38235+ *
38236+ * Revision 1.23 2004/04/06 02:49:26 mcr
38237+ * pullup of algo code from alg-branch.
38238+ *
38239+ * Revision 1.22.2.1 2003/12/22 15:25:52 jjo
38240+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
38241+ *
38242+ * Revision 1.22 2003/12/10 01:14:27 mcr
38243+ * NAT-traversal patches to KLIPS.
38244+ *
38245+ * Revision 1.21 2003/10/31 02:27:55 mcr
38246+ * pulled up port-selector patches and sa_id elimination.
38247+ *
38248+ * Revision 1.20.4.1 2003/10/29 01:30:41 mcr
38249+ * elimited "struct sa_id".
38250+ *
38251+ * Revision 1.20 2003/02/06 01:50:34 rgb
38252+ * Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0.
38253+ *
38254+ * Revision 1.19 2003/01/30 02:32:22 rgb
38255+ *
38256+ * Rename SAref table macro names for clarity.
38257+ * Transmit error code through to caller from callee for better diagnosis of problems.
38258+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
38259+ *
38260+ * Revision 1.18 2002/10/12 23:11:53 dhr
38261+ *
38262+ * [KenB + DHR] more 64-bit cleanup
38263+ *
38264+ * Revision 1.17 2002/10/07 18:31:43 rgb
38265+ * Move field width sanity checks to ipsec_sa.c
38266+ *
38267+ * Revision 1.16 2002/09/20 15:41:02 rgb
38268+ * Re-wrote most of the SAref code to eliminate Entry pointers.
38269+ * Added SAref code compiler directive switch.
38270+ * Added a saref test function for testing macros.
38271+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
38272+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
38273+ * of freeing newly created structures when clearing the reftable upon startup
38274+ * to start from a known state.
38275+ * Place all ipsec sadb globals into one struct.
38276+ * Rework saref freelist.
38277+ * Added memory allocation debugging.
38278+ *
38279+ * Revision 1.15 2002/09/20 05:01:44 rgb
38280+ * Update copyright date.
38281+ *
38282+ * Revision 1.14 2002/08/13 19:01:25 mcr
38283+ * patches from kenb to permit compilation of FreeSWAN on ia64.
38284+ * des library patched to use proper DES_LONG type for ia64.
38285+ *
38286+ * Revision 1.13 2002/07/29 03:06:20 mcr
38287+ * get rid of variable not used warnings.
38288+ *
38289+ * Revision 1.12 2002/07/26 08:48:31 rgb
38290+ * Added SA ref table code.
38291+ *
38292+ * Revision 1.11 2002/06/04 16:48:49 rgb
38293+ * Tidied up pointer code for processor independance.
38294+ *
38295+ * Revision 1.10 2002/05/23 07:16:17 rgb
38296+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
38297+ * Pointer clean-up.
38298+ * Added refcount code.
38299+ * Convert "usecount" to "refcount" to remove ambiguity.
38300+ *
38301+ * Revision 1.9 2002/05/14 02:34:49 rgb
38302+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
38303+ * with "put" usage in the kernel.
38304+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
38305+ * ipsec_sa or ipsec_sa.
38306+ * Added some preliminary refcount code.
38307+ *
38308+ * Revision 1.8 2002/04/24 07:55:32 mcr
38309+ * #include patches and Makefiles for post-reorg compilation.
38310+ *
38311+ * Revision 1.7 2002/04/24 07:36:30 mcr
38312+ * Moved from ./klips/net/ipsec/ipsec_sa.c,v
38313+ *
38314+ * Revision 1.6 2002/04/20 00:12:25 rgb
38315+ * Added esp IV CBC attack fix, disabled.
38316+ *
38317+ * Revision 1.5 2002/01/29 17:17:56 mcr
38318+ * moved include of ipsec_param.h to after include of linux/kernel.h
38319+ * otherwise, it seems that some option that is set in ipsec_param.h
38320+ * screws up something subtle in the include path to kernel.h, and
38321+ * it complains on the snprintf() prototype.
38322+ *
38323+ * Revision 1.4 2002/01/29 04:00:52 mcr
38324+ * more excise of kversions.h header.
38325+ *
38326+ * Revision 1.3 2002/01/29 02:13:18 mcr
38327+ * introduction of ipsec_kversion.h means that include of
38328+ * ipsec_param.h must preceed any decisions about what files to
38329+ * include to deal with differences in kernel source.
38330+ *
38331+ * Revision 1.2 2001/11/26 09:16:15 rgb
38332+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
38333+ *
38334+ * Revision 1.1.2.2 2001/10/22 21:05:41 mcr
38335+ * removed phony prototype for des_set_key.
38336+ *
38337+ * Revision 1.1.2.1 2001/09/25 02:24:57 mcr
38338+ * struct tdb -> struct ipsec_sa.
38339+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
38340+ * ipsec_xform.c removed. header file still contains useful things.
38341+ *
38342+ *
38343+ *
38344+ * CLONED from ipsec_xform.c:
38345+ * Revision 1.53 2001/09/08 21:13:34 rgb
38346+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
38347+ *
38348+ * Revision 1.52 2001/06/14 19:35:11 rgb
38349+ * Update copyright date.
38350+ *
38351+ * Revision 1.51 2001/05/30 08:14:03 rgb
38352+ * Removed vestiges of esp-null transforms.
38353+ *
38354+ * Revision 1.50 2001/05/03 19:43:18 rgb
38355+ * Initialise error return variable.
38356+ * Update SENDERR macro.
38357+ * Fix sign of error return code for ipsec_tdbcleanup().
38358+ * Use more appropriate return code for ipsec_tdbwipe().
38359+ *
38360+ * Revision 1.49 2001/04/19 18:56:17 rgb
38361+ * Fixed tdb table locking comments.
38362+ *
38363+ * Revision 1.48 2001/02/27 22:24:55 rgb
38364+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
38365+ * Check for satoa() return codes.
38366+ *
38367+ * Revision 1.47 2000/11/06 04:32:08 rgb
38368+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
38369+ *
38370+ * Revision 1.46 2000/09/20 16:21:57 rgb
38371+ * Cleaned up ident string alloc/free.
38372+ *
38373+ * Revision 1.45 2000/09/08 19:16:51 rgb
38374+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
38375+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
38376+ *
38377+ * Revision 1.44 2000/08/30 05:29:04 rgb
38378+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
38379+ *
38380+ * Revision 1.43 2000/08/18 21:30:41 rgb
38381+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
38382+ *
38383+ * Revision 1.42 2000/08/01 14:51:51 rgb
38384+ * Removed _all_ remaining traces of DES.
38385+ *
38386+ * Revision 1.41 2000/07/28 14:58:31 rgb
38387+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
38388+ *
38389+ * Revision 1.40 2000/06/28 05:50:11 rgb
38390+ * Actually set iv_bits.
38391+ *
38392+ * Revision 1.39 2000/05/10 23:11:09 rgb
38393+ * Added netlink debugging output.
38394+ * Added a cast to quiet down the ntohl bug.
38395+ *
38396+ * Revision 1.38 2000/05/10 19:18:42 rgb
38397+ * Cast output of ntohl so that the broken prototype doesn't make our
38398+ * compile noisy.
38399+ *
38400+ * Revision 1.37 2000/03/16 14:04:59 rgb
38401+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
38402+ *
38403+ * Revision 1.36 2000/01/26 10:11:28 rgb
38404+ * Fixed spacing in error text causing run-in words.
38405+ *
38406+ * Revision 1.35 2000/01/21 06:17:16 rgb
38407+ * Tidied up compiler directive indentation for readability.
38408+ * Added ictx,octx vars for simplification.(kravietz)
38409+ * Added macros for HMAC padding magic numbers.(kravietz)
38410+ * Fixed missing key length reporting bug.
38411+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
38412+ *
38413+ * Revision 1.34 1999/12/08 00:04:19 rgb
38414+ * Fixed SA direction overwriting bug for netlink users.
38415+ *
38416+ * Revision 1.33 1999/12/01 22:16:44 rgb
38417+ * Minor formatting changes in ESP MD5 initialisation.
38418+ *
38419+ * Revision 1.32 1999/11/25 09:06:36 rgb
38420+ * Fixed error return messages, should be returning negative numbers.
38421+ * Implemented SENDERR macro for propagating error codes.
38422+ * Added debug message and separate error code for algorithms not compiled
38423+ * in.
38424+ *
38425+ * Revision 1.31 1999/11/23 23:06:26 rgb
38426+ * Sort out pfkey and freeswan headers, putting them in a library path.
38427+ *
38428+ * Revision 1.30 1999/11/18 04:09:20 rgb
38429+ * Replaced all kernel version macros to shorter, readable form.
38430+ *
38431+ * Revision 1.29 1999/11/17 15:53:40 rgb
38432+ * Changed all occurrences of #include "../../../lib/freeswan.h"
38433+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
38434+ * klips/net/ipsec/Makefile.
38435+ *
38436+ * Revision 1.28 1999/10/18 20:04:01 rgb
38437+ * Clean-out unused cruft.
38438+ *
38439+ * Revision 1.27 1999/10/03 19:01:03 rgb
38440+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
38441+ *
38442+ * Revision 1.26 1999/10/01 16:22:24 rgb
38443+ * Switch from assignment init. to functional init. of spinlocks.
38444+ *
38445+ * Revision 1.25 1999/10/01 15:44:54 rgb
38446+ * Move spinlock header include to 2.1> scope.
38447+ *
38448+ * Revision 1.24 1999/10/01 00:03:46 rgb
38449+ * Added tdb structure locking.
38450+ * Minor formatting changes.
38451+ * Add function to initialize tdb hash table.
38452+ *
38453+ * Revision 1.23 1999/05/25 22:42:12 rgb
38454+ * Add deltdbchain() debugging.
38455+ *
38456+ * Revision 1.22 1999/05/25 21:24:31 rgb
38457+ * Add debugging statements to deltdbchain().
38458+ *
38459+ * Revision 1.21 1999/05/25 03:51:48 rgb
38460+ * Refix error return code.
38461+ *
38462+ * Revision 1.20 1999/05/25 03:34:07 rgb
38463+ * Fix error return for flush.
38464+ *
38465+ * Revision 1.19 1999/05/09 03:25:37 rgb
38466+ * Fix bug introduced by 2.2 quick-and-dirty patch.
38467+ *
38468+ * Revision 1.18 1999/05/05 22:02:32 rgb
38469+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
38470+ *
38471+ * Revision 1.17 1999/04/29 15:20:16 rgb
38472+ * Change gettdb parameter to a pointer to reduce stack loading and
38473+ * facilitate parameter sanity checking.
38474+ * Add sanity checking for null pointer arguments.
38475+ * Add debugging instrumentation.
38476+ * Add function deltdbchain() which will take care of unlinking,
38477+ * zeroing and deleting a chain of tdbs.
38478+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
38479+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
38480+ * structures.
38481+ *
38482+ * Revision 1.16 1999/04/16 15:36:29 rgb
38483+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
38484+ *
38485+ * Revision 1.15 1999/04/11 00:29:01 henry
38486+ * GPL boilerplate
38487+ *
38488+ * Revision 1.14 1999/04/06 04:54:28 rgb
38489+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
38490+ * patch shell fixes.
38491+ *
38492+ * Revision 1.13 1999/02/19 18:23:01 rgb
38493+ * Nix debug off compile warning.
38494+ *
38495+ * Revision 1.12 1999/02/17 16:52:16 rgb
38496+ * Consolidate satoa()s for space and speed efficiency.
38497+ * Convert DEBUG_IPSEC to KLIPS_PRINT
38498+ * Clean out unused cruft.
38499+ * Ditch NET_IPIP dependancy.
38500+ * Loop for 3des key setting.
38501+ *
38502+ * Revision 1.11 1999/01/26 02:09:05 rgb
38503+ * Remove ah/esp/IPIP switching on include files.
38504+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
38505+ * Removed dead code.
38506+ * Clean up debug code when switched off.
38507+ * Remove references to INET_GET_PROTOCOL.
38508+ * Added code exclusion macros to reduce code from unused algorithms.
38509+ *
38510+ * Revision 1.10 1999/01/22 06:28:55 rgb
38511+ * Cruft clean-out.
38512+ * Put random IV generation in kernel.
38513+ * Added algorithm switch code.
38514+ * Enhanced debugging.
38515+ * 64-bit clean-up.
38516+ *
38517+ * Revision 1.9 1998/11/30 13:22:55 rgb
38518+ * Rationalised all the klips kernel file headers. They are much shorter
38519+ * now and won't conflict under RH5.2.
38520+ *
38521+ * Revision 1.8 1998/11/25 04:59:06 rgb
38522+ * Add conditionals for no IPIP tunnel code.
38523+ * Delete commented out code.
38524+ *
38525+ * Revision 1.7 1998/10/31 06:50:41 rgb
38526+ * Convert xform ASCII names to no spaces.
38527+ * Fixed up comments in #endif directives.
38528+ *
38529+ * Revision 1.6 1998/10/19 14:44:28 rgb
38530+ * Added inclusion of freeswan.h.
38531+ * sa_id structure implemented and used: now includes protocol.
38532+ *
38533+ * Revision 1.5 1998/10/09 04:32:19 rgb
38534+ * Added 'klips_debug' prefix to all klips printk debug statements.
38535+ *
38536+ * Revision 1.4 1998/08/12 00:11:31 rgb
38537+ * Added new xform functions to the xform table.
38538+ * Fixed minor debug output spelling error.
38539+ *
38540+ * Revision 1.3 1998/07/09 17:45:31 rgb
38541+ * Clarify algorithm not available message.
38542+ *
38543+ * Revision 1.2 1998/06/23 03:00:51 rgb
38544+ * Check for presence of IPIP protocol if it is setup one way (we don't
38545+ * know what has been set up the other way and can only assume it will be
38546+ * symmetrical with the exception of keys).
38547+ *
38548+ * Revision 1.1 1998/06/18 21:27:51 henry
38549+ * move sources from klips/src to klips/net/ipsec, to keep stupid
38550+ * kernel-build scripts happier in the presence of symlinks
38551+ *
38552+ * Revision 1.3 1998/06/11 05:54:59 rgb
38553+ * Added transform version string pointer to xformsw initialisations.
38554+ *
38555+ * Revision 1.2 1998/04/21 21:28:57 rgb
38556+ * Rearrange debug switches to change on the fly debug output from user
38557+ * space. Only kernel changes checked in at this time. radij.c was also
38558+ * changed to temporarily remove buggy debugging code in rj_delete causing
38559+ * an OOPS and hence, netlink device open errors.
38560+ *
38561+ * Revision 1.1 1998/04/09 03:06:13 henry
38562+ * sources moved up from linux/net/ipsec
38563+ *
38564+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
38565+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
38566+ *
38567+ * Revision 0.5 1997/06/03 04:24:48 ji
38568+ * Added ESP-3DES-MD5-96
38569+ *
38570+ * Revision 0.4 1997/01/15 01:28:15 ji
38571+ * Added new transforms.
38572+ *
38573+ * Revision 0.3 1996/11/20 14:39:04 ji
38574+ * Minor cleanups.
38575+ * Rationalized debugging code.
38576+ *
38577+ * Revision 0.2 1996/11/02 00:18:33 ji
38578+ * First limited release.
38579+ *
38580+ *
38581+ */
38582--- /dev/null Tue Mar 11 13:02:56 2003
38583+++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004
38584@@ -0,0 +1,219 @@
38585+/*
38586+ * RCSID $Id: ipsec_sha1.c,v 1.9 2004-04-06 02:49:26 mcr Exp $
38587+ */
38588+
38589+/*
38590+ * The rest of the code is derived from sha1.c by Steve Reid, which is
38591+ * public domain.
38592+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
38593+ */
38594+
38595+#include <asm/byteorder.h>
38596+#include <linux/string.h>
38597+
38598+#include "openswan/ipsec_sha1.h"
38599+
38600+#if defined(rol)
38601+#undef rol
38602+#endif
38603+
38604+#define SHA1HANDSOFF
38605+
38606+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
38607+
38608+/* blk0() and blk() perform the initial expand. */
38609+/* I got the idea of expanding during the round function from SSLeay */
38610+#ifdef __LITTLE_ENDIAN
38611+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
38612+ |(rol(block->l[i],8)&0x00FF00FF))
38613+#else
38614+#define blk0(i) block->l[i]
38615+#endif
38616+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
38617+ ^block->l[(i+2)&15]^block->l[i&15],1))
38618+
38619+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
38620+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
38621+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
38622+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
38623+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
38624+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
38625+
38626+
38627+/* Hash a single 512-bit block. This is the core of the algorithm. */
38628+
38629+void SHA1Transform(__u32 state[5], __u8 buffer[64])
38630+{
38631+__u32 a, b, c, d, e;
38632+typedef union {
38633+ unsigned char c[64];
38634+ __u32 l[16];
38635+} CHAR64LONG16;
38636+CHAR64LONG16* block;
38637+#ifdef SHA1HANDSOFF
38638+static unsigned char workspace[64];
38639+ block = (CHAR64LONG16*)workspace;
38640+ memcpy(block, buffer, 64);
38641+#else
38642+ block = (CHAR64LONG16*)buffer;
38643+#endif
38644+ /* Copy context->state[] to working vars */
38645+ a = state[0];
38646+ b = state[1];
38647+ c = state[2];
38648+ d = state[3];
38649+ e = state[4];
38650+ /* 4 rounds of 20 operations each. Loop unrolled. */
38651+ 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);
38652+ 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);
38653+ 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);
38654+ 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);
38655+ 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);
38656+ 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);
38657+ 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);
38658+ 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);
38659+ 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);
38660+ 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);
38661+ 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);
38662+ 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);
38663+ 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);
38664+ 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);
38665+ 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);
38666+ 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);
38667+ 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);
38668+ 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);
38669+ 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);
38670+ 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);
38671+ /* Add the working vars back into context.state[] */
38672+ state[0] += a;
38673+ state[1] += b;
38674+ state[2] += c;
38675+ state[3] += d;
38676+ state[4] += e;
38677+ /* Wipe variables */
38678+ a = b = c = d = e = 0;
38679+}
38680+
38681+
38682+/* SHA1Init - Initialize new context */
38683+
38684+void SHA1Init(void *vcontext)
38685+{
38686+ SHA1_CTX* context = vcontext;
38687+
38688+ /* SHA1 initialization constants */
38689+ context->state[0] = 0x67452301;
38690+ context->state[1] = 0xEFCDAB89;
38691+ context->state[2] = 0x98BADCFE;
38692+ context->state[3] = 0x10325476;
38693+ context->state[4] = 0xC3D2E1F0;
38694+ context->count[0] = context->count[1] = 0;
38695+}
38696+
38697+
38698+/* Run your data through this. */
38699+
38700+void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
38701+{
38702+ SHA1_CTX* context = vcontext;
38703+ __u32 i, j;
38704+
38705+ j = context->count[0];
38706+ if ((context->count[0] += len << 3) < j)
38707+ context->count[1]++;
38708+ context->count[1] += (len>>29);
38709+ j = (j >> 3) & 63;
38710+ if ((j + len) > 63) {
38711+ memcpy(&context->buffer[j], data, (i = 64-j));
38712+ SHA1Transform(context->state, context->buffer);
38713+ for ( ; i + 63 < len; i += 64) {
38714+ SHA1Transform(context->state, &data[i]);
38715+ }
38716+ j = 0;
38717+ }
38718+ else i = 0;
38719+ memcpy(&context->buffer[j], &data[i], len - i);
38720+}
38721+
38722+
38723+/* Add padding and return the message digest. */
38724+
38725+void SHA1Final(unsigned char digest[20], void *vcontext)
38726+{
38727+ __u32 i, j;
38728+ unsigned char finalcount[8];
38729+ SHA1_CTX* context = vcontext;
38730+
38731+ for (i = 0; i < 8; i++) {
38732+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
38733+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
38734+ }
38735+ SHA1Update(context, (unsigned char *)"\200", 1);
38736+ while ((context->count[0] & 504) != 448) {
38737+ SHA1Update(context, (unsigned char *)"\0", 1);
38738+ }
38739+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
38740+ for (i = 0; i < 20; i++) {
38741+ digest[i] = (unsigned char)
38742+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
38743+ }
38744+ /* Wipe variables */
38745+ i = j = 0;
38746+ memset(context->buffer, 0, 64);
38747+ memset(context->state, 0, 20);
38748+ memset(context->count, 0, 8);
38749+ memset(&finalcount, 0, 8);
38750+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
38751+ SHA1Transform(context->state, context->buffer);
38752+#endif
38753+}
38754+
38755+
38756+/*
38757+ * $Log: ipsec_sha1.c,v $
38758+ * Revision 1.9 2004-04-06 02:49:26 mcr
38759+ * pullup of algo code from alg-branch.
38760+ *
38761+ * Revision 1.8 2002/09/10 01:45:14 mcr
38762+ * changed type of MD5_CTX and SHA1_CTX to void * so that
38763+ * the function prototypes would match, and could be placed
38764+ * into a pointer to a function.
38765+ *
38766+ * Revision 1.7 2002/04/24 07:55:32 mcr
38767+ * #include patches and Makefiles for post-reorg compilation.
38768+ *
38769+ * Revision 1.6 2002/04/24 07:36:30 mcr
38770+ * Moved from ./klips/net/ipsec/ipsec_sha1.c,v
38771+ *
38772+ * Revision 1.5 1999/12/13 13:59:13 rgb
38773+ * Quick fix to argument size to Update bugs.
38774+ *
38775+ * Revision 1.4 1999/04/11 00:29:00 henry
38776+ * GPL boilerplate
38777+ *
38778+ * Revision 1.3 1999/04/06 04:54:27 rgb
38779+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
38780+ * patch shell fixes.
38781+ *
38782+ * Revision 1.2 1999/01/22 06:55:50 rgb
38783+ * 64-bit clean-up.
38784+ *
38785+ * Revision 1.1 1998/06/18 21:27:50 henry
38786+ * move sources from klips/src to klips/net/ipsec, to keep stupid
38787+ * kernel-build scripts happier in the presence of symlinks
38788+ *
38789+ * Revision 1.2 1998/04/23 20:54:04 rgb
38790+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
38791+ * verified.
38792+ *
38793+ * Revision 1.1 1998/04/09 03:06:11 henry
38794+ * sources moved up from linux/net/ipsec
38795+ *
38796+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
38797+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
38798+ *
38799+ * Revision 0.4 1997/01/15 01:28:15 ji
38800+ * New transform
38801+ *
38802+ *
38803+ */
38804--- /dev/null Tue Mar 11 13:02:56 2003
38805+++ linux/net/ipsec/ipsec_snprintf.c Mon Feb 9 13:51:03 2004
38806@@ -0,0 +1,135 @@
38807+/*
38808+ * @(#) ipsec_snprintf() function
38809+ *
38810+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
38811+ * 2001 Michael Richardson <mcr@freeswan.org>
38812+ * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
38813+ *
38814+ * This program is free software; you can redistribute it and/or modify it
38815+ * under the terms of the GNU General Public License as published by the
38816+ * Free Software Foundation; either version 2 of the License, or (at your
38817+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
38818+ *
38819+ * This program is distributed in the hope that it will be useful, but
38820+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
38821+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38822+ * for more details.
38823+ *
38824+ * Split out from ipsec_proc.c.
38825+ */
38826+
38827+#ifndef AUTOCONF_INCLUDED
38828+#include <linux/config.h>
38829+#endif
38830+#include <linux/version.h>
38831+#define __NO_VERSION__
38832+#include <linux/module.h>
38833+#include <linux/kernel.h> /* printk() */
38834+
38835+#include "openswan/ipsec_kversion.h"
38836+#include "openswan/ipsec_param.h"
38837+
38838+#include <net/ip.h>
38839+
38840+#include "openswan/radij.h"
38841+
38842+#include "openswan/ipsec_life.h"
38843+#include "openswan/ipsec_stats.h"
38844+#include "openswan/ipsec_sa.h"
38845+
38846+#include "openswan/ipsec_encap.h"
38847+#include "openswan/ipsec_radij.h"
38848+#include "openswan/ipsec_xform.h"
38849+#include "openswan/ipsec_tunnel.h"
38850+#include "openswan/ipsec_xmit.h"
38851+
38852+#include "openswan/ipsec_rcv.h"
38853+#include "openswan/ipsec_ah.h"
38854+#include "openswan/ipsec_esp.h"
38855+#include "openswan/ipsec_kern24.h"
38856+
38857+#ifdef CONFIG_KLIPS_IPCOMP
38858+#include "openswan/ipcomp.h"
38859+#endif /* CONFIG_KLIPS_IPCOMP */
38860+
38861+#include "openswan/ipsec_proto.h"
38862+
38863+#include <pfkeyv2.h>
38864+#include <pfkey.h>
38865+
38866+/* ipsec_snprintf: like snprintf except
38867+ * - size is signed and a negative value is treated as if it were 0
38868+ * - the returned result is never negative --
38869+ * an error generates a "?" or null output (depending on space).
38870+ * (Our callers are too lazy to check for an error return.)
38871+ *
38872+ * @param buf String buffer
38873+ * @param size Size of the string
38874+ * @param fmt printf string
38875+ * @param ... Variables to be displayed in fmt
38876+ * @return int Return code
38877+ */
38878+int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
38879+{
38880+ va_list args;
38881+ int i;
38882+ size_t possize = size < 0? 0 : size;
38883+ va_start(args, fmt);
38884+ i = vsnprintf(buf,possize,fmt,args);
38885+ va_end(args);
38886+ if (i < 0) {
38887+ /* create empty output in place of error */
38888+ i = 0;
38889+ if (size > 0) {
38890+ *buf = '\0';
38891+ }
38892+ }
38893+ return i;
38894+}
38895+
38896+
38897+void ipsec_dmp_block(char *s, caddr_t bb, int len)
38898+{
38899+ int i;
38900+ unsigned char *b = bb;
38901+
38902+ printk(KERN_INFO "klips_dmp: "
38903+ "at %s, len=%d:\n", s, len);
38904+
38905+ for(i = 0; i < len; i++ /*, c++*/) {
38906+ if(!(i % 16)) {
38907+ printk(KERN_INFO
38908+ "klips_debug: @%03x:",
38909+ i);
38910+ }
38911+ printk(" %02x", b[i]);
38912+ if(!((i + 1) % 16)) {
38913+ printk("\n");
38914+ }
38915+ }
38916+ if(i % 16) {
38917+ printk("\n");
38918+ }
38919+}
38920+
38921+/*
38922+ *
38923+ * $Log: ipsec_snprintf.c,v $
38924+ * Revision 1.3.2.1 2006-10-06 21:39:26 paul
38925+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
38926+ * set. This is defined through autoconf.h which is included through the
38927+ * linux kernel build macros.
38928+ *
38929+ * Revision 1.3 2005/04/29 05:10:22 mcr
38930+ * removed from extraenous includes to make unit testing easier.
38931+ *
38932+ * Revision 1.2 2005/04/15 00:32:01 mcr
38933+ * added ipsec_dmp_block routine.
38934+ *
38935+ *
38936+ * Local Variables:
38937+ * c-file-style: "linux"
38938+ * End:
38939+ *
38940+ */
38941+
38942--- /dev/null Tue Mar 11 13:02:56 2003
38943+++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004
38944@@ -0,0 +1,2893 @@
38945+/*
38946+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
38947+ * Copyright (C) 1996, 1997 John Ioannidis.
38948+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
38949+ *
38950+ * This program is free software; you can redistribute it and/or modify it
38951+ * under the terms of the GNU General Public License as published by the
38952+ * Free Software Foundation; either version 2 of the License, or (at your
38953+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
38954+ *
38955+ * This program is distributed in the hope that it will be useful, but
38956+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
38957+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38958+ * for more details.
38959+ */
38960+
38961+char ipsec_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.232.2.7 2007-09-18 18:26:18 paul Exp $";
38962+
38963+#define __NO_VERSION__
38964+#include <linux/module.h>
38965+#ifndef AUTOCONF_INCLUDED
38966+#include <linux/config.h>
38967+#endif /* for CONFIG_IP_FORWARD */
38968+#include <linux/version.h>
38969+#include <linux/kernel.h> /* printk() */
38970+
38971+#include "openswan/ipsec_param.h"
38972+
38973+#ifdef MALLOC_SLAB
38974+# include <linux/slab.h> /* kmalloc() */
38975+#else /* MALLOC_SLAB */
38976+# include <linux/malloc.h> /* kmalloc() */
38977+#endif /* MALLOC_SLAB */
38978+#include <linux/errno.h> /* error codes */
38979+#include <linux/types.h> /* size_t */
38980+#include <linux/interrupt.h> /* mark_bh */
38981+
38982+#include <net/tcp.h>
38983+#include <net/udp.h>
38984+#include <linux/skbuff.h>
38985+
38986+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
38987+#include <linux/etherdevice.h> /* eth_type_trans */
38988+#include <linux/ip.h> /* struct iphdr */
38989+#include <net/arp.h>
38990+#include <linux/skbuff.h>
38991+
38992+#include <openswan.h>
38993+
38994+#ifdef NET_21
38995+# include <linux/in6.h>
38996+# define ip_chk_addr inet_addr_type
38997+# define IS_MYADDR RTN_LOCAL
38998+# include <net/dst.h>
38999+# undef dev_kfree_skb
39000+# define dev_kfree_skb(a,b) kfree_skb(a)
39001+# define PHYSDEV_TYPE
39002+#endif /* NET_21 */
39003+
39004+#include <net/icmp.h> /* icmp_send() */
39005+#include <net/ip.h>
39006+#ifdef NETDEV_23
39007+# include <linux/netfilter_ipv4.h>
39008+#endif /* NETDEV_23 */
39009+
39010+#include <linux/if_arp.h>
39011+#include <net/arp.h>
39012+
39013+#include "openswan/ipsec_kversion.h"
39014+#include "openswan/radij.h"
39015+#include "openswan/ipsec_life.h"
39016+#include "openswan/ipsec_xform.h"
39017+#include "openswan/ipsec_eroute.h"
39018+#include "openswan/ipsec_encap.h"
39019+#include "openswan/ipsec_radij.h"
39020+#include "openswan/ipsec_sa.h"
39021+#include "openswan/ipsec_tunnel.h"
39022+#include "openswan/ipsec_xmit.h"
39023+#include "openswan/ipsec_ipe4.h"
39024+#include "openswan/ipsec_ah.h"
39025+#include "openswan/ipsec_esp.h"
39026+#include "openswan/ipsec_kern24.h"
39027+
39028+#include <pfkeyv2.h>
39029+#include <pfkey.h>
39030+
39031+#include "openswan/ipsec_proto.h"
39032+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39033+#include <linux/udp.h>
39034+#endif
39035+
39036+static __u32 zeroes[64];
39037+
39038+#ifdef CONFIG_KLIPS_DEBUG
39039+int debug_tunnel = 0;
39040+#endif /* CONFIG_KLIPS_DEBUG */
39041+
39042+DEBUG_NO_STATIC int
39043+ipsec_tunnel_open(struct net_device *dev)
39044+{
39045+ struct ipsecpriv *prv = dev->priv;
39046+
39047+ /*
39048+ * Can't open until attached.
39049+ */
39050+
39051+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
39052+ "klips_debug:ipsec_tunnel_open: "
39053+ "dev = %s, prv->dev = %s\n",
39054+ dev->name, prv->dev?prv->dev->name:"NONE");
39055+
39056+ if (prv->dev == NULL)
39057+ return -ENODEV;
39058+
39059+ KLIPS_INC_USE;
39060+ return 0;
39061+}
39062+
39063+DEBUG_NO_STATIC int
39064+ipsec_tunnel_close(struct net_device *dev)
39065+{
39066+ KLIPS_DEC_USE;
39067+ return 0;
39068+}
39069+
39070+#ifdef NETDEV_23
39071+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
39072+{
39073+#ifdef NETDEV_25 /* 2.6 kernels */
39074+ return dst_output(skb);
39075+#else
39076+ return ip_send(skb);
39077+#endif
39078+}
39079+#endif /* NETDEV_23 */
39080+
39081+enum ipsec_xmit_value
39082+ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs)
39083+{
39084+ /* ixs->physdev->hard_header_len is unreliable and should not be used */
39085+ ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data;
39086+
39087+ if(ixs->hard_header_len < 0) {
39088+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39089+ "klips_error:ipsec_xmit_strip_hard_header: "
39090+ "Negative hard_header_len (%d)?!\n", ixs->hard_header_len);
39091+ ixs->stats->tx_dropped++;
39092+ return IPSEC_XMIT_BADHHLEN;
39093+ }
39094+
39095+ /* while ixs->physdev->hard_header_len is unreliable and
39096+ * should not be trusted, it accurate and required for ATM, GRE and
39097+ * some other interfaces to work. Thanks to Willy Tarreau
39098+ * <willy@w.ods.org>.
39099+ */
39100+ if(ixs->hard_header_len == 0) { /* no hard header present */
39101+ ixs->hard_header_stripped = 1;
39102+ ixs->hard_header_len = ixs->physdev->hard_header_len;
39103+ }
39104+
39105+#ifdef CONFIG_KLIPS_DEBUG
39106+ if (debug_tunnel & DB_TN_XMIT) {
39107+ int i;
39108+ char c;
39109+
39110+ printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: "
39111+ ">>> skb->len=%ld hard_header_len:%d",
39112+ (unsigned long int)ixs->skb->len, ixs->hard_header_len);
39113+ c = ' ';
39114+ for (i=0; i < ixs->hard_header_len; i++) {
39115+ printk("%c%02x", c, ixs->skb->data[i]);
39116+ c = ':';
39117+ }
39118+ printk(" \n");
39119+ }
39120+#endif /* CONFIG_KLIPS_DEBUG */
39121+
39122+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
39123+
39124+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39125+ "klips_debug:ipsec_xmit_strip_hard_header: "
39126+ "Original head,tailroom: %d,%d\n",
39127+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
39128+
39129+ return IPSEC_XMIT_OK;
39130+}
39131+
39132+enum ipsec_xmit_value
39133+ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs)
39134+{
39135+ unsigned int bypass;
39136+
39137+ bypass = FALSE;
39138+
39139+ /*
39140+ * First things first -- look us up in the erouting tables.
39141+ */
39142+ ixs->matcher.sen_len = sizeof (struct sockaddr_encap);
39143+ ixs->matcher.sen_family = AF_ENCAP;
39144+ ixs->matcher.sen_type = SENT_IP4;
39145+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
39146+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
39147+ ixs->matcher.sen_proto = ixs->iph->protocol;
39148+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
39149+
39150+ /*
39151+ * The spinlock is to prevent any other process from accessing or deleting
39152+ * the eroute while we are using and updating it.
39153+ */
39154+ spin_lock(&eroute_lock);
39155+
39156+ ixs->eroute = ipsec_findroute(&ixs->matcher);
39157+
39158+ if(ixs->iph->protocol == IPPROTO_UDP) {
39159+ struct udphdr *t = NULL;
39160+
39161+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39162+ "klips_debug:udp port check: "
39163+ "fragoff: %d len: %d>%ld \n",
39164+ ntohs(ixs->iph->frag_off) & IP_OFFSET,
39165+ (ixs->skb->len - ixs->hard_header_len),
39166+ (unsigned long int) ((ixs->iph->ihl << 2) + sizeof(struct udphdr)));
39167+
39168+ if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
39169+ ((ixs->skb->len - ixs->hard_header_len) >=
39170+ ((ixs->iph->ihl << 2) + sizeof(struct udphdr))))
39171+ {
39172+ t =((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
39173+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39174+ "klips_debug:udp port in packet: "
39175+ "port %d -> %d\n",
39176+ ntohs(t->source), ntohs(t->dest));
39177+ }
39178+
39179+ ixs->sport=0; ixs->dport=0;
39180+
39181+ if(ixs->skb->sk) {
39182+#ifdef NET_26
39183+#ifdef HAVE_INET_SK_SPORT
39184+ ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
39185+ ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
39186+#else
39187+ struct udp_sock *us;
39188+
39189+ us = (struct udp_sock *)ixs->skb->sk;
39190+
39191+ ixs->sport = ntohs(us->inet.sport);
39192+ ixs->dport = ntohs(us->inet.dport);
39193+#endif
39194+#else
39195+ ixs->sport = ntohs(ixs->skb->sk->sport);
39196+ ixs->dport = ntohs(ixs->skb->sk->dport);
39197+#endif
39198+
39199+ }
39200+
39201+ if(t != NULL) {
39202+ if(ixs->sport == 0) {
39203+ ixs->sport = ntohs(t->source);
39204+ }
39205+ if(ixs->dport == 0) {
39206+ ixs->dport = ntohs(t->dest);
39207+ }
39208+ }
39209+ }
39210+
39211+ /*
39212+ * practically identical to above, but let's be careful about
39213+ * tcp vs udp headers
39214+ */
39215+ if(ixs->iph->protocol == IPPROTO_TCP) {
39216+ struct tcphdr *t = NULL;
39217+
39218+ if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
39219+ ((ixs->skb->len - ixs->hard_header_len) >=
39220+ ((ixs->iph->ihl << 2) + sizeof(struct tcphdr)))) {
39221+ t =((struct tcphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
39222+ }
39223+
39224+ ixs->sport=0; ixs->dport=0;
39225+
39226+ if(ixs->skb->sk) {
39227+#ifdef NET_26
39228+#ifdef HAVE_INET_SK_SPORT
39229+ ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
39230+ ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
39231+#else
39232+ struct tcp_tw_bucket *tw;
39233+
39234+ tw = (struct tcp_tw_bucket *)ixs->skb->sk;
39235+
39236+ ixs->sport = ntohs(tw->tw_sport);
39237+ ixs->dport = ntohs(tw->tw_dport);
39238+#endif
39239+#else
39240+ ixs->sport = ntohs(ixs->skb->sk->sport);
39241+ ixs->dport = ntohs(ixs->skb->sk->dport);
39242+#endif
39243+ }
39244+
39245+ if(t != NULL) {
39246+ if(ixs->sport == 0) {
39247+ ixs->sport = ntohs(t->source);
39248+ }
39249+ if(ixs->dport == 0) {
39250+ ixs->dport = ntohs(t->dest);
39251+ }
39252+ }
39253+ }
39254+
39255+ /* default to a %drop eroute */
39256+ ixs->outgoing_said.proto = IPPROTO_INT;
39257+ ixs->outgoing_said.spi = htonl(SPI_DROP);
39258+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
39259+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39260+ "klips_debug:ipsec_xmit_SAlookup: "
39261+ "checking for local udp/500 IKE packet "
39262+ "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
39263+ ntohl((unsigned int)ixs->iph->saddr),
39264+ ixs->eroute,
39265+ ntohl((unsigned int)ixs->iph->daddr),
39266+ ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0,
39267+ ixs->iph->protocol,
39268+ ixs->sport,
39269+ ixs->dport);
39270+
39271+ /*
39272+ * cheat for now...are we udp/500? If so, let it through
39273+ * without interference since it is most likely an IKE packet.
39274+ */
39275+
39276+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
39277+ && (ixs->eroute==NULL
39278+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
39279+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
39280+ && (ixs->iph->protocol == IPPROTO_UDP &&
39281+ (ixs->sport == 500 || ixs->sport == 4500))) {
39282+ /* Whatever the eroute, this is an IKE message
39283+ * from us (i.e. not being forwarded).
39284+ * Furthermore, if there is a tunnel eroute,
39285+ * the destination is the peer for this eroute.
39286+ * So %pass the packet: modify the default %drop.
39287+ */
39288+
39289+ ixs->outgoing_said.spi = htonl(SPI_PASS);
39290+ if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) {
39291+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39292+ "klips_debug:ipsec_xmit_SAlookup: "
39293+ "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
39294+ }
39295+ bypass = TRUE;
39296+ }
39297+
39298+#ifdef KLIPS_EXCEPT_DNS53
39299+ /*
39300+ *
39301+ * if we are udp/53 or tcp/53, also let it through a %trap or %hold,
39302+ * since it is DNS, but *also* follow the %trap.
39303+ *
39304+ * we do not do this for tunnels, only %trap's and %hold's.
39305+ *
39306+ */
39307+
39308+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
39309+ && (ixs->eroute==NULL
39310+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
39311+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
39312+ && ((ixs->iph->protocol == IPPROTO_UDP
39313+ || ixs->iph->protocol == IPPROTO_TCP)
39314+ && ixs->dport == 53)) {
39315+
39316+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39317+ "klips_debug:ipsec_xmit_SAlookup: "
39318+ "possible DNS packet\n");
39319+
39320+ if(ixs->eroute)
39321+ {
39322+ if(ixs->eroute->er_said.spi == htonl(SPI_TRAP)
39323+ || ixs->eroute->er_said.spi == htonl(SPI_HOLD))
39324+ {
39325+ ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
39326+ bypass = TRUE;
39327+ }
39328+ }
39329+ else
39330+ {
39331+ ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
39332+ bypass = TRUE;
39333+ }
39334+
39335+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39336+ "klips_debug:ipsec_xmit_SAlookup: "
39337+ "bypass = %d\n", bypass);
39338+
39339+ if(bypass
39340+ && !(ixs->skb->sk)
39341+ && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0))
39342+ {
39343+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39344+ "klips_debug:ipsec_xmit_SAlookup: "
39345+ "local port 53 (probably DNS) passthrough:"
39346+ "base fragment, rest of fragments will "
39347+ "probably get filtered.\n");
39348+ }
39349+ }
39350+#endif
39351+
39352+ if (bypass==FALSE && ixs->eroute) {
39353+ ixs->eroute->er_count++;
39354+ ixs->eroute->er_lasttime = jiffies/HZ;
39355+ if(ixs->eroute->er_said.proto==IPPROTO_INT
39356+ && ixs->eroute->er_said.spi==htonl(SPI_HOLD))
39357+ {
39358+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39359+ "klips_debug:ipsec_xmit_SAlookup: "
39360+ "shunt SA of HOLD: skb stored in HOLD.\n");
39361+ if(ixs->eroute->er_last != NULL) {
39362+ kfree_skb(ixs->eroute->er_last);
39363+ }
39364+ ixs->eroute->er_last = ixs->skb;
39365+ ixs->skb = NULL;
39366+ ixs->stats->tx_dropped++;
39367+ spin_unlock(&eroute_lock);
39368+ return IPSEC_XMIT_STOLEN;
39369+ }
39370+ ixs->outgoing_said = ixs->eroute->er_said;
39371+ ixs->eroute_pid = ixs->eroute->er_pid;
39372+
39373+ /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
39374+ if(ixs->outgoing_said.proto==IPPROTO_INT
39375+ && (ixs->outgoing_said.spi==htonl(SPI_TRAP)
39376+ || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
39377+ int len;
39378+
39379+ ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type;
39380+ ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id;
39381+ ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len;
39382+ if (ixs->ips.ips_ident_s.len)
39383+ {
39384+ len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
39385+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39386+ "klips_debug:ipsec_xmit_SAlookup: "
39387+ "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
39388+ len);
39389+ if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
39390+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
39391+ "Failed, tried to allocate %d bytes for source ident.\n",
39392+ len);
39393+ ixs->stats->tx_dropped++;
39394+ spin_unlock(&eroute_lock);
39395+ return IPSEC_XMIT_ERRMEMALLOC;
39396+ }
39397+ memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len);
39398+ }
39399+ ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type;
39400+ ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id;
39401+ ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len;
39402+ if (ixs->ips.ips_ident_d.len)
39403+ {
39404+ len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
39405+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39406+ "klips_debug:ipsec_xmit_SAlookup: "
39407+ "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
39408+ len);
39409+ if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
39410+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
39411+ "Failed, tried to allocate %d bytes for dest ident.\n",
39412+ len);
39413+ ixs->stats->tx_dropped++;
39414+ spin_unlock(&eroute_lock);
39415+ return IPSEC_XMIT_ERRMEMALLOC;
39416+ }
39417+ memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len);
39418+ }
39419+ }
39420+ }
39421+
39422+ spin_unlock(&eroute_lock);
39423+ return IPSEC_XMIT_OK;
39424+}
39425+
39426+
39427+enum ipsec_xmit_value
39428+ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs)
39429+{
39430+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39431+ "klips_debug:ipsec_xmit_restore_hard_header: "
39432+ "After recursive xforms -- head,tailroom: %d,%d\n",
39433+ skb_headroom(ixs->skb),
39434+ skb_tailroom(ixs->skb));
39435+
39436+ if(ixs->saved_header) {
39437+ if(skb_headroom(ixs->skb) < ixs->hard_header_len) {
39438+ printk(KERN_WARNING
39439+ "klips_error:ipsec_xmit_restore_hard_header: "
39440+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
39441+ ixs->hard_header_len,
39442+ skb_headroom(ixs->skb));
39443+ ixs->stats->tx_errors++;
39444+ return IPSEC_XMIT_PUSHPULLERR;
39445+
39446+ }
39447+ skb_push(ixs->skb, ixs->hard_header_len);
39448+ {
39449+ int i;
39450+ for (i = 0; i < ixs->hard_header_len; i++) {
39451+ ixs->skb->data[i] = ixs->saved_header[i];
39452+ }
39453+ }
39454+ }
39455+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39456+ if (ixs->natt_type && ixs->natt_head) {
39457+ struct iphdr *ipp = ip_hdr(ixs->skb);
39458+ struct udphdr *udp;
39459+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39460+ "klips_debug:ipsec_tunnel_start_xmit: "
39461+ "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
39462+ ixs->natt_type, ixs->natt_head);
39463+
39464+ ixs->iphlen = ipp->ihl << 2;
39465+ ipp->tot_len =
39466+ htons(ntohs(ipp->tot_len) + ixs->natt_head);
39467+ if(skb_tailroom(ixs->skb) < ixs->natt_head) {
39468+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
39469+ "tried to skb_put %d, %d available. "
39470+ "This should never happen, please report.\n",
39471+ ixs->natt_head,
39472+ skb_tailroom(ixs->skb));
39473+ ixs->stats->tx_errors++;
39474+ return IPSEC_XMIT_ESPUDP;
39475+ }
39476+ skb_put(ixs->skb, ixs->natt_head);
39477+
39478+ udp = (struct udphdr *)((char *)ipp + ixs->iphlen);
39479+
39480+ /* move ESP hdr after UDP hdr */
39481+ memmove((void *)((char *)udp + ixs->natt_head),
39482+ (void *)(udp),
39483+ ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head);
39484+
39485+ /* clear UDP & Non-IKE Markers (if any) */
39486+ memset(udp, 0, ixs->natt_head);
39487+
39488+ /* fill UDP with usefull informations ;-) */
39489+ udp->source = htons(ixs->natt_sport);
39490+ udp->dest = htons(ixs->natt_dport);
39491+ udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen);
39492+
39493+ /* set protocol */
39494+ ipp->protocol = IPPROTO_UDP;
39495+
39496+ /* fix IP checksum */
39497+ ipp->check = 0;
39498+ ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
39499+ }
39500+#endif
39501+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39502+ "klips_debug:ipsec_xmit_restore_hard_header: "
39503+ "With hard_header, final head,tailroom: %d,%d\n",
39504+ skb_headroom(ixs->skb),
39505+ skb_tailroom(ixs->skb));
39506+
39507+ return IPSEC_XMIT_OK;
39508+}
39509+
39510+enum ipsec_xmit_value
39511+ipsec_tunnel_send(struct ipsec_xmit_state*ixs)
39512+{
39513+#ifdef NETDEV_25
39514+ struct flowi fl;
39515+#endif
39516+
39517+#ifdef NET_21 /* 2.2 and 2.4 kernels */
39518+ /* new route/dst cache code from James Morris */
39519+ ixs->skb->dev = ixs->physdev;
39520+#ifdef NETDEV_25
39521+ memset (&fl, 0x0, sizeof (struct flowi));
39522+ fl.oif = ixs->physdev->iflink;
39523+ fl.nl_u.ip4_u.daddr = ip_hdr(ixs->skb)->daddr;
39524+ fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ip_hdr(ixs->skb)->saddr;
39525+ fl.nl_u.ip4_u.tos = RT_TOS(ip_hdr(ixs->skb)->tos);
39526+ fl.proto = ip_hdr(ixs->skb)->protocol;
39527+ if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) {
39528+#else
39529+ /*skb_orphan(ixs->skb);*/
39530+ if((ixs->error = ip_route_output(&ixs->route,
39531+ ixs->skb->nh.iph->daddr,
39532+ ixs->pass ? 0 : ip_hdr(ixs->skb)->saddr,
39533+ RT_TOS(ip_hdr(ixs->skb)->tos),
39534+ /* mcr->rgb: should this be 0 instead? */
39535+ ixs->physdev->iflink))) {
39536+#endif
39537+ ixs->stats->tx_errors++;
39538+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39539+ "klips_debug:ipsec_xmit_send: "
39540+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
39541+ ixs->error,
39542+ ixs->route->u.dst.dev->name);
39543+ return IPSEC_XMIT_ROUTEERR;
39544+ }
39545+ if(ixs->dev == ixs->route->u.dst.dev) {
39546+ ip_rt_put(ixs->route);
39547+ /* This is recursion, drop it. */
39548+ ixs->stats->tx_errors++;
39549+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39550+ "klips_debug:ipsec_xmit_send: "
39551+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
39552+ ixs->dev->name);
39553+ return IPSEC_XMIT_RECURSDETECT;
39554+ }
39555+ dst_release(ixs->skb->dst);
39556+ ixs->skb->dst = &ixs->route->u.dst;
39557+ ixs->stats->tx_bytes += ixs->skb->len;
39558+ if(ixs->skb->len < skb_network_header(ixs->skb) - ixs->skb->data) {
39559+ ixs->stats->tx_errors++;
39560+ printk(KERN_WARNING
39561+ "klips_error:ipsec_xmit_send: "
39562+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
39563+ (unsigned long)(skb_network_header(ixs->skb) - ixs->skb->data),
39564+ ixs->skb->len);
39565+ return IPSEC_XMIT_PUSHPULLERR;
39566+ }
39567+ __skb_pull(ixs->skb, skb_network_header(ixs->skb) - ixs->skb->data);
39568+#ifdef SKB_RESET_NFCT
39569+ if(!ixs->pass) {
39570+ nf_conntrack_put(ixs->skb->nfct);
39571+ ixs->skb->nfct = NULL;
39572+ }
39573+#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
39574+ ixs->skb->nf_debug = 0;
39575+#endif /* CONFIG_NETFILTER_DEBUG */
39576+#endif /* SKB_RESET_NFCT */
39577+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39578+ "klips_debug:ipsec_xmit_send: "
39579+ "...done, calling ip_send() on device:%s\n",
39580+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
39581+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ip_hdr(ixs->skb));
39582+#ifdef NETDEV_23 /* 2.4 kernels */
39583+ {
39584+ int err;
39585+
39586+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
39587+ ipsec_tunnel_xmit2);
39588+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
39589+ if(net_ratelimit())
39590+ printk(KERN_ERR
39591+ "klips_error:ipsec_xmit_send: "
39592+ "ip_send() failed, err=%d\n",
39593+ -err);
39594+ ixs->stats->tx_errors++;
39595+ ixs->stats->tx_aborted_errors++;
39596+ ixs->skb = NULL;
39597+ return IPSEC_XMIT_IPSENDFAILURE;
39598+ }
39599+ }
39600+#else /* NETDEV_23 */ /* 2.2 kernels */
39601+ ip_send(ixs->skb);
39602+#endif /* NETDEV_23 */
39603+#else /* NET_21 */ /* 2.0 kernels */
39604+ ixs->skb->arp = 1;
39605+ /* ISDN/ASYNC PPP from Matjaz Godec. */
39606+ /* skb->protocol = htons(ETH_P_IP); */
39607+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39608+ "klips_debug:ipsec_xmit_send: "
39609+ "...done, calling dev_queue_xmit() or ip_fragment().\n");
39610+ IP_SEND(ixs->skb, ixs->physdev);
39611+#endif /* NET_21 */
39612+ ixs->stats->tx_packets++;
39613+
39614+ ixs->skb = NULL;
39615+
39616+ return IPSEC_XMIT_OK;
39617+}
39618+
39619+void
39620+ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs)
39621+{
39622+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
39623+ netif_wake_queue(ixs->dev);
39624+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
39625+ ixs->dev->tbusy = 0;
39626+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
39627+ if(ixs->saved_header) {
39628+ kfree(ixs->saved_header);
39629+ }
39630+ if(ixs->skb) {
39631+ dev_kfree_skb(ixs->skb, FREE_WRITE);
39632+ }
39633+ if(ixs->oskb) {
39634+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
39635+ }
39636+ if (ixs->ips.ips_ident_s.data) {
39637+ kfree(ixs->ips.ips_ident_s.data);
39638+ }
39639+ if (ixs->ips.ips_ident_d.data) {
39640+ kfree(ixs->ips.ips_ident_d.data);
39641+ }
39642+}
39643+
39644+/*
39645+ * This function assumes it is being called from dev_queue_xmit()
39646+ * and that skb is filled properly by that function.
39647+ */
39648+int
39649+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev)
39650+{
39651+ struct ipsec_xmit_state ixs_mem;
39652+ struct ipsec_xmit_state *ixs = &ixs_mem;
39653+ enum ipsec_xmit_value stat;
39654+
39655+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39656+ ixs->natt_type = 0, ixs->natt_head = 0;
39657+ ixs->natt_sport = 0, ixs->natt_dport = 0;
39658+#endif
39659+
39660+ memset((caddr_t)ixs, 0, sizeof(*ixs));
39661+ ixs->oskb = NULL;
39662+ ixs->saved_header = NULL; /* saved copy of the hard header */
39663+ ixs->route = NULL;
39664+ memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips));
39665+ ixs->dev = dev;
39666+ ixs->skb = skb;
39667+
39668+ stat = ipsec_xmit_sanity_check_dev(ixs);
39669+ if(stat != IPSEC_XMIT_OK) {
39670+ goto cleanup;
39671+ }
39672+
39673+ stat = ipsec_xmit_sanity_check_skb(ixs);
39674+ if(stat != IPSEC_XMIT_OK) {
39675+ goto cleanup;
39676+ }
39677+
39678+ stat = ipsec_tunnel_strip_hard_header(ixs);
39679+ if(stat != IPSEC_XMIT_OK) {
39680+ goto cleanup;
39681+ }
39682+
39683+ stat = ipsec_tunnel_SAlookup(ixs);
39684+ if(stat != IPSEC_XMIT_OK) {
39685+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39686+ "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n",
39687+ stat);
39688+ goto cleanup;
39689+ }
39690+
39691+ ixs->innersrc = ixs->iph->saddr;
39692+ /* start encapsulation loop here XXX */
39693+ do {
39694+ stat = ipsec_xmit_encap_bundle(ixs);
39695+ if(stat != IPSEC_XMIT_OK) {
39696+ if(stat == IPSEC_XMIT_PASS) {
39697+ goto bypass;
39698+ }
39699+
39700+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39701+ "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n",
39702+ stat);
39703+ goto cleanup;
39704+ }
39705+
39706+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
39707+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
39708+ ixs->matcher.sen_proto = ixs->iph->protocol;
39709+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
39710+
39711+ spin_lock(&eroute_lock);
39712+ ixs->eroute = ipsec_findroute(&ixs->matcher);
39713+ if(ixs->eroute) {
39714+ ixs->outgoing_said = ixs->eroute->er_said;
39715+ ixs->eroute_pid = ixs->eroute->er_pid;
39716+ ixs->eroute->er_count++;
39717+ ixs->eroute->er_lasttime = jiffies/HZ;
39718+ }
39719+ spin_unlock(&eroute_lock);
39720+
39721+ KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
39722+ /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */
39723+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
39724+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
39725+ ixs->eroute,
39726+ "klips_debug:ipsec_tunnel_start_xmit: "
39727+ "We are recursing here.\n");
39728+
39729+ } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/
39730+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
39731+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
39732+ ixs->eroute);
39733+
39734+ stat = ipsec_tunnel_restore_hard_header(ixs);
39735+ if(stat != IPSEC_XMIT_OK) {
39736+ goto cleanup;
39737+ }
39738+
39739+ bypass:
39740+ stat = ipsec_tunnel_send(ixs);
39741+
39742+ cleanup:
39743+ ipsec_tunnel_cleanup(ixs);
39744+
39745+ return 0;
39746+}
39747+
39748+DEBUG_NO_STATIC struct net_device_stats *
39749+ipsec_tunnel_get_stats(struct net_device *dev)
39750+{
39751+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
39752+}
39753+
39754+/*
39755+ * Revectored calls.
39756+ * For each of these calls, a field exists in our private structure.
39757+ */
39758+
39759+DEBUG_NO_STATIC int
39760+ipsec_tunnel_hard_header(struct sk_buff *skb, struct net_device *dev,
39761+ unsigned short type, void *daddr, void *saddr, unsigned len)
39762+{
39763+ struct ipsecpriv *prv = dev->priv;
39764+ struct net_device *tmp;
39765+ int ret;
39766+ struct net_device_stats *stats; /* This device's statistics */
39767+
39768+ if(skb == NULL) {
39769+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39770+ "klips_debug:ipsec_tunnel_hard_header: "
39771+ "no skb...\n");
39772+ return -ENODATA;
39773+ }
39774+
39775+ if(dev == NULL) {
39776+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39777+ "klips_debug:ipsec_tunnel_hard_header: "
39778+ "no device...\n");
39779+ return -ENODEV;
39780+ }
39781+
39782+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39783+ "klips_debug:ipsec_tunnel_hard_header: "
39784+ "skb->dev=%s dev=%s.\n",
39785+ skb->dev ? skb->dev->name : "NULL",
39786+ dev->name);
39787+
39788+ if(prv == NULL) {
39789+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39790+ "klips_debug:ipsec_tunnel_hard_header: "
39791+ "no private space associated with dev=%s\n",
39792+ dev->name ? dev->name : "NULL");
39793+ return -ENODEV;
39794+ }
39795+
39796+ stats = (struct net_device_stats *) &(prv->mystats);
39797+
39798+ if(prv->dev == NULL) {
39799+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39800+ "klips_debug:ipsec_tunnel_hard_header: "
39801+ "no physical device associated with dev=%s\n",
39802+ dev->name ? dev->name : "NULL");
39803+ stats->tx_dropped++;
39804+ return -ENODEV;
39805+ }
39806+
39807+ /* check if we have to send a IPv6 packet. It might be a Router
39808+ Solicitation, where the building of the packet happens in
39809+ reverse order:
39810+ 1. ll hdr,
39811+ 2. IPv6 hdr,
39812+ 3. ICMPv6 hdr
39813+ -> skb->nh.raw is still uninitialized when this function is
39814+ called!! If this is no IPv6 packet, we can print debugging
39815+ messages, otherwise we skip all debugging messages and just
39816+ build the ll header */
39817+ if(type != ETH_P_IPV6) {
39818+ /* execute this only, if we don't have to build the
39819+ header for a IPv6 packet */
39820+ if(!prv->hard_header) {
39821+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39822+ "klips_debug:ipsec_tunnel_hard_header: "
39823+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
39824+ saddr,
39825+ daddr,
39826+ len,
39827+ type,
39828+ dev->name);
39829+#ifdef NET_21
39830+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39831+ "ip=%08x->%08x\n",
39832+ (__u32)ntohl(ip_hdr(skb)->saddr),
39833+ (__u32)ntohl(ip_hdr(skb)->daddr) );
39834+#else /* NET_21 */
39835+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39836+ "ip=%08x->%08x\n",
39837+ (__u32)ntohl(skb->ip_hdr->saddr),
39838+ (__u32)ntohl(skb->ip_hdr->daddr) );
39839+#endif /* NET_21 */
39840+ stats->tx_dropped++;
39841+ return -ENODEV;
39842+ }
39843+
39844+#define da ((struct net_device *)(prv->dev))->dev_addr
39845+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39846+ "klips_debug:ipsec_tunnel_hard_header: "
39847+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
39848+ saddr,
39849+ daddr,
39850+ len,
39851+ type,
39852+ dev->name,
39853+ prv->dev->name,
39854+ da[0], da[1], da[2], da[3], da[4], da[5]);
39855+#ifdef NET_21
39856+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39857+ "ip=%08x->%08x\n",
39858+ (__u32)ntohl(ip_hdr(skb)->saddr),
39859+ (__u32)ntohl(ip_hdr(skb)->daddr) );
39860+#else /* NET_21 */
39861+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39862+ "ip=%08x->%08x\n",
39863+ (__u32)ntohl(skb->ip_hdr->saddr),
39864+ (__u32)ntohl(skb->ip_hdr->daddr) );
39865+#endif /* NET_21 */
39866+ } else {
39867+ KLIPS_PRINT(debug_tunnel,
39868+ "klips_debug:ipsec_tunnel_hard_header: "
39869+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
39870+ }
39871+ tmp = skb->dev;
39872+ skb->dev = prv->dev;
39873+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
39874+ skb->dev = tmp;
39875+ return ret;
39876+}
39877+
39878+DEBUG_NO_STATIC int
39879+#ifdef NET_21
39880+ipsec_tunnel_rebuild_header(struct sk_buff *skb)
39881+#else /* NET_21 */
39882+ipsec_tunnel_rebuild_header(void *buff, struct net_device *dev,
39883+ unsigned long raddr, struct sk_buff *skb)
39884+#endif /* NET_21 */
39885+{
39886+ struct ipsecpriv *prv = skb->dev->priv;
39887+ struct net_device *tmp;
39888+ int ret;
39889+ struct net_device_stats *stats; /* This device's statistics */
39890+
39891+ if(skb->dev == NULL) {
39892+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39893+ "klips_debug:ipsec_tunnel_rebuild_header: "
39894+ "no device...");
39895+ return -ENODEV;
39896+ }
39897+
39898+ if(prv == NULL) {
39899+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39900+ "klips_debug:ipsec_tunnel_rebuild_header: "
39901+ "no private space associated with dev=%s",
39902+ skb->dev->name ? skb->dev->name : "NULL");
39903+ return -ENODEV;
39904+ }
39905+
39906+ stats = (struct net_device_stats *) &(prv->mystats);
39907+
39908+ if(prv->dev == NULL) {
39909+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39910+ "klips_debug:ipsec_tunnel_rebuild_header: "
39911+ "no physical device associated with dev=%s",
39912+ skb->dev->name ? skb->dev->name : "NULL");
39913+ stats->tx_dropped++;
39914+ return -ENODEV;
39915+ }
39916+
39917+ if(!prv->rebuild_header) {
39918+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39919+ "klips_debug:ipsec_tunnel_rebuild_header: "
39920+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
39921+ skb->dev->name);
39922+#ifdef NET_21
39923+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39924+ "ip=%08x->%08x\n",
39925+ (__u32)ntohl(ip_hdr(skb)->saddr),
39926+ (__u32)ntohl(ip_hdr(skb)->daddr) );
39927+#else /* NET_21 */
39928+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39929+ "ip=%08x->%08x\n",
39930+ (__u32)ntohl(skb->ip_hdr->saddr),
39931+ (__u32)ntohl(skb->ip_hdr->daddr) );
39932+#endif /* NET_21 */
39933+ stats->tx_dropped++;
39934+ return -ENODEV;
39935+ }
39936+
39937+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39938+ "klips_debug:ipsec_tunnel: "
39939+ "Revectored rebuild_header dev=%s->%s ",
39940+ skb->dev->name, prv->dev->name);
39941+#ifdef NET_21
39942+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39943+ "ip=%08x->%08x\n",
39944+ (__u32)ntohl(ip_hdr(skb)->saddr),
39945+ (__u32)ntohl(ip_hdr(skb)->daddr) );
39946+#else /* NET_21 */
39947+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39948+ "ip=%08x->%08x\n",
39949+ (__u32)ntohl(skb->ip_hdr->saddr),
39950+ (__u32)ntohl(skb->ip_hdr->daddr) );
39951+#endif /* NET_21 */
39952+ tmp = skb->dev;
39953+ skb->dev = prv->dev;
39954+
39955+#ifdef NET_21
39956+ ret = prv->rebuild_header(skb);
39957+#else /* NET_21 */
39958+ ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
39959+#endif /* NET_21 */
39960+ skb->dev = tmp;
39961+ return ret;
39962+}
39963+
39964+DEBUG_NO_STATIC int
39965+ipsec_tunnel_set_mac_address(struct net_device *dev, void *addr)
39966+{
39967+ struct ipsecpriv *prv = dev->priv;
39968+
39969+ struct net_device_stats *stats; /* This device's statistics */
39970+
39971+ if(dev == NULL) {
39972+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39973+ "klips_debug:ipsec_tunnel_set_mac_address: "
39974+ "no device...");
39975+ return -ENODEV;
39976+ }
39977+
39978+ if(prv == NULL) {
39979+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39980+ "klips_debug:ipsec_tunnel_set_mac_address: "
39981+ "no private space associated with dev=%s",
39982+ dev->name ? dev->name : "NULL");
39983+ return -ENODEV;
39984+ }
39985+
39986+ stats = (struct net_device_stats *) &(prv->mystats);
39987+
39988+ if(prv->dev == NULL) {
39989+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39990+ "klips_debug:ipsec_tunnel_set_mac_address: "
39991+ "no physical device associated with dev=%s",
39992+ dev->name ? dev->name : "NULL");
39993+ stats->tx_dropped++;
39994+ return -ENODEV;
39995+ }
39996+
39997+ if(!prv->set_mac_address) {
39998+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39999+ "klips_debug:ipsec_tunnel_set_mac_address: "
40000+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
40001+ dev->name);
40002+ return -ENODEV;
40003+ }
40004+
40005+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40006+ "klips_debug:ipsec_tunnel_set_mac_address: "
40007+ "Revectored dev=%s->%s addr=0p%p\n",
40008+ dev->name, prv->dev->name, addr);
40009+ return prv->set_mac_address(prv->dev, addr);
40010+
40011+}
40012+
40013+#ifndef NET_21
40014+DEBUG_NO_STATIC void
40015+ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct net_device *dev,
40016+ unsigned short htype, __u32 daddr)
40017+{
40018+ struct ipsecpriv *prv = dev->priv;
40019+
40020+ struct net_device_stats *stats; /* This device's statistics */
40021+
40022+ if(dev == NULL) {
40023+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40024+ "klips_debug:ipsec_tunnel_cache_bind: "
40025+ "no device...");
40026+ return;
40027+ }
40028+
40029+ if(prv == NULL) {
40030+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40031+ "klips_debug:ipsec_tunnel_cache_bind: "
40032+ "no private space associated with dev=%s",
40033+ dev->name ? dev->name : "NULL");
40034+ return;
40035+ }
40036+
40037+ stats = (struct net_device_stats *) &(prv->mystats);
40038+
40039+ if(prv->dev == NULL) {
40040+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40041+ "klips_debug:ipsec_tunnel_cache_bind: "
40042+ "no physical device associated with dev=%s",
40043+ dev->name ? dev->name : "NULL");
40044+ stats->tx_dropped++;
40045+ return;
40046+ }
40047+
40048+ if(!prv->header_cache_bind) {
40049+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40050+ "klips_debug:ipsec_tunnel_cache_bind: "
40051+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
40052+ dev->name);
40053+ stats->tx_dropped++;
40054+ return;
40055+ }
40056+
40057+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40058+ "klips_debug:ipsec_tunnel_cache_bind: "
40059+ "Revectored \n");
40060+ prv->header_cache_bind(hhp, prv->dev, htype, daddr);
40061+ return;
40062+}
40063+#endif /* !NET_21 */
40064+
40065+
40066+DEBUG_NO_STATIC void
40067+ipsec_tunnel_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
40068+{
40069+ struct ipsecpriv *prv = dev->priv;
40070+
40071+ struct net_device_stats *stats; /* This device's statistics */
40072+
40073+ if(dev == NULL) {
40074+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40075+ "klips_debug:ipsec_tunnel_cache_update: "
40076+ "no device...");
40077+ return;
40078+ }
40079+
40080+ if(prv == NULL) {
40081+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40082+ "klips_debug:ipsec_tunnel_cache_update: "
40083+ "no private space associated with dev=%s",
40084+ dev->name ? dev->name : "NULL");
40085+ return;
40086+ }
40087+
40088+ stats = (struct net_device_stats *) &(prv->mystats);
40089+
40090+ if(prv->dev == NULL) {
40091+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40092+ "klips_debug:ipsec_tunnel_cache_update: "
40093+ "no physical device associated with dev=%s",
40094+ dev->name ? dev->name : "NULL");
40095+ stats->tx_dropped++;
40096+ return;
40097+ }
40098+
40099+ if(!prv->header_cache_update) {
40100+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40101+ "klips_debug:ipsec_tunnel_cache_update: "
40102+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
40103+ dev->name);
40104+ return;
40105+ }
40106+
40107+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40108+ "klips_debug:ipsec_tunnel: "
40109+ "Revectored cache_update\n");
40110+ prv->header_cache_update(hh, prv->dev, haddr);
40111+ return;
40112+}
40113+
40114+#ifdef NET_21
40115+DEBUG_NO_STATIC int
40116+ipsec_tunnel_neigh_setup(struct neighbour *n)
40117+{
40118+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40119+ "klips_debug:ipsec_tunnel_neigh_setup:\n");
40120+
40121+ if (n->nud_state == NUD_NONE) {
40122+ n->ops = &arp_broken_ops;
40123+ n->output = n->ops->output;
40124+ }
40125+ return 0;
40126+}
40127+
40128+DEBUG_NO_STATIC int
40129+ipsec_tunnel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
40130+{
40131+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40132+ "klips_debug:ipsec_tunnel_neigh_setup_dev: "
40133+ "setting up %s\n",
40134+ dev ? dev->name : "NULL");
40135+
40136+ if (p->tbl->family == AF_INET) {
40137+ p->neigh_setup = ipsec_tunnel_neigh_setup;
40138+ p->ucast_probes = 0;
40139+ p->mcast_probes = 0;
40140+ }
40141+ return 0;
40142+}
40143+#endif /* NET_21 */
40144+
40145+/*
40146+ * We call the attach routine to attach another device.
40147+ */
40148+
40149+DEBUG_NO_STATIC int
40150+ipsec_tunnel_attach(struct net_device *dev, struct net_device *physdev)
40151+{
40152+ int i;
40153+ struct ipsecpriv *prv = dev->priv;
40154+
40155+ if(dev == NULL) {
40156+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40157+ "klips_debug:ipsec_tunnel_attach: "
40158+ "no device...");
40159+ return -ENODEV;
40160+ }
40161+
40162+ if(prv == NULL) {
40163+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40164+ "klips_debug:ipsec_tunnel_attach: "
40165+ "no private space associated with dev=%s",
40166+ dev->name ? dev->name : "NULL");
40167+ return -ENODATA;
40168+ }
40169+
40170+ prv->dev = physdev;
40171+ prv->hard_start_xmit = physdev->hard_start_xmit;
40172+ prv->get_stats = physdev->get_stats;
40173+
40174+ if (physdev->hard_header) {
40175+ prv->hard_header = physdev->hard_header;
40176+ dev->hard_header = ipsec_tunnel_hard_header;
40177+ } else
40178+ dev->hard_header = NULL;
40179+
40180+ if (physdev->rebuild_header) {
40181+ prv->rebuild_header = physdev->rebuild_header;
40182+ dev->rebuild_header = ipsec_tunnel_rebuild_header;
40183+ } else
40184+ dev->rebuild_header = NULL;
40185+
40186+ if (physdev->set_mac_address) {
40187+ prv->set_mac_address = physdev->set_mac_address;
40188+ dev->set_mac_address = ipsec_tunnel_set_mac_address;
40189+ } else
40190+ dev->set_mac_address = NULL;
40191+
40192+#ifndef NET_21
40193+ if (physdev->header_cache_bind) {
40194+ prv->header_cache_bind = physdev->header_cache_bind;
40195+ dev->header_cache_bind = ipsec_tunnel_cache_bind;
40196+ } else
40197+ dev->header_cache_bind = NULL;
40198+#endif /* !NET_21 */
40199+
40200+ if (physdev->header_cache_update) {
40201+ prv->header_cache_update = physdev->header_cache_update;
40202+ dev->header_cache_update = ipsec_tunnel_cache_update;
40203+ } else
40204+ dev->header_cache_update = NULL;
40205+
40206+ dev->hard_header_len = physdev->hard_header_len;
40207+
40208+#ifdef NET_21
40209+/* prv->neigh_setup = physdev->neigh_setup; */
40210+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
40211+#endif /* NET_21 */
40212+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
40213+ prv->mtu = physdev->mtu;
40214+
40215+#ifdef PHYSDEV_TYPE
40216+ dev->type = physdev->type; /* ARPHRD_TUNNEL; */
40217+#endif /* PHYSDEV_TYPE */
40218+
40219+ dev->addr_len = physdev->addr_len;
40220+ for (i=0; i<dev->addr_len; i++) {
40221+ dev->dev_addr[i] = physdev->dev_addr[i];
40222+ }
40223+#ifdef CONFIG_KLIPS_DEBUG
40224+ if(debug_tunnel & DB_TN_INIT) {
40225+ printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
40226+ "physical device %s being attached has HW address: %2x",
40227+ physdev->name, physdev->dev_addr[0]);
40228+ for (i=1; i < physdev->addr_len; i++) {
40229+ printk(":%02x", physdev->dev_addr[i]);
40230+ }
40231+ printk("\n");
40232+ }
40233+#endif /* CONFIG_KLIPS_DEBUG */
40234+
40235+ return 0;
40236+}
40237+
40238+/*
40239+ * We call the detach routine to detach the ipsec tunnel from another device.
40240+ */
40241+
40242+DEBUG_NO_STATIC int
40243+ipsec_tunnel_detach(struct net_device *dev)
40244+{
40245+ int i;
40246+ struct ipsecpriv *prv = dev->priv;
40247+
40248+ if(dev == NULL) {
40249+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40250+ "klips_debug:ipsec_tunnel_detach: "
40251+ "no device...");
40252+ return -ENODEV;
40253+ }
40254+
40255+ if(prv == NULL) {
40256+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40257+ "klips_debug:ipsec_tunnel_detach: "
40258+ "no private space associated with dev=%s",
40259+ dev->name ? dev->name : "NULL");
40260+ return -ENODATA;
40261+ }
40262+
40263+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40264+ "klips_debug:ipsec_tunnel_detach: "
40265+ "physical device %s being detached from virtual device %s\n",
40266+ prv->dev ? prv->dev->name : "NULL",
40267+ dev->name);
40268+
40269+ ipsec_dev_put(prv->dev);
40270+ prv->dev = NULL;
40271+ prv->hard_start_xmit = NULL;
40272+ prv->get_stats = NULL;
40273+
40274+ prv->hard_header = NULL;
40275+#ifdef DETACH_AND_DOWN
40276+ dev->hard_header = NULL;
40277+#endif /* DETACH_AND_DOWN */
40278+
40279+ prv->rebuild_header = NULL;
40280+#ifdef DETACH_AND_DOWN
40281+ dev->rebuild_header = NULL;
40282+#endif /* DETACH_AND_DOWN */
40283+
40284+ prv->set_mac_address = NULL;
40285+#ifdef DETACH_AND_DOWN
40286+ dev->set_mac_address = NULL;
40287+#endif /* DETACH_AND_DOWN */
40288+
40289+#ifndef NET_21
40290+ prv->header_cache_bind = NULL;
40291+#ifdef DETACH_AND_DOWN
40292+ dev->header_cache_bind = NULL;
40293+#endif /* DETACH_AND_DOWN */
40294+#endif /* !NET_21 */
40295+
40296+ prv->header_cache_update = NULL;
40297+#ifdef DETACH_AND_DOWN
40298+ dev->header_cache_update = NULL;
40299+#endif /* DETACH_AND_DOWN */
40300+
40301+#ifdef NET_21
40302+/* prv->neigh_setup = NULL; */
40303+#ifdef DETACH_AND_DOWN
40304+ dev->neigh_setup = NULL;
40305+#endif /* DETACH_AND_DOWN */
40306+#endif /* NET_21 */
40307+ dev->hard_header_len = 0;
40308+#ifdef DETACH_AND_DOWN
40309+ dev->mtu = 0;
40310+#endif /* DETACH_AND_DOWN */
40311+ prv->mtu = 0;
40312+ for (i=0; i<MAX_ADDR_LEN; i++) {
40313+ dev->dev_addr[i] = 0;
40314+ }
40315+ dev->addr_len = 0;
40316+#ifdef PHYSDEV_TYPE
40317+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
40318+#endif /* PHYSDEV_TYPE */
40319+
40320+ return 0;
40321+}
40322+
40323+/*
40324+ * We call the clear routine to detach all ipsec tunnels from other devices.
40325+ */
40326+DEBUG_NO_STATIC int
40327+ipsec_tunnel_clear(void)
40328+{
40329+ int i;
40330+ struct net_device *ipsecdev = NULL, *prvdev;
40331+ struct ipsecpriv *prv;
40332+ int ret;
40333+
40334+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40335+ "klips_debug:ipsec_tunnel_clear: .\n");
40336+
40337+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40338+ ipsecdev = ipsecdevices[i];
40339+ if(ipsecdev != NULL) {
40340+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
40341+ prvdev = (struct net_device *)(prv->dev);
40342+ if(prvdev) {
40343+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40344+ "klips_debug:ipsec_tunnel_clear: "
40345+ "physical device for device %s is %s\n",
40346+ ipsecdev->name, prvdev->name);
40347+ if((ret = ipsec_tunnel_detach(ipsecdev))) {
40348+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40349+ "klips_debug:ipsec_tunnel_clear: "
40350+ "error %d detatching device %s from device %s.\n",
40351+ ret, ipsecdev->name, prvdev->name);
40352+ return ret;
40353+ }
40354+ }
40355+ }
40356+ }
40357+ }
40358+ return 0;
40359+}
40360+
40361+DEBUG_NO_STATIC int
40362+ipsec_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
40363+{
40364+ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
40365+ struct ipsecpriv *prv = dev->priv;
40366+ struct net_device *them; /* physical device */
40367+#ifdef CONFIG_IP_ALIAS
40368+ char *colon;
40369+ char realphysname[IFNAMSIZ];
40370+#endif /* CONFIG_IP_ALIAS */
40371+
40372+ if(dev == NULL) {
40373+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40374+ "klips_debug:ipsec_tunnel_ioctl: "
40375+ "device not supplied.\n");
40376+ return -ENODEV;
40377+ }
40378+
40379+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40380+ "klips_debug:ipsec_tunnel_ioctl: "
40381+ "tncfg service call #%d for dev=%s\n",
40382+ cmd,
40383+ dev->name ? dev->name : "NULL");
40384+ switch (cmd) {
40385+ /* attach a virtual ipsec? device to a physical device */
40386+ case IPSEC_SET_DEV:
40387+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40388+ "klips_debug:ipsec_tunnel_ioctl: "
40389+ "calling ipsec_tunnel_attatch...\n");
40390+#ifdef CONFIG_IP_ALIAS
40391+ /* If this is an IP alias interface, get its real physical name */
40392+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
40393+ realphysname[IFNAMSIZ-1] = 0;
40394+ colon = strchr(realphysname, ':');
40395+ if (colon) *colon = 0;
40396+ them = ipsec_dev_get(realphysname);
40397+#else /* CONFIG_IP_ALIAS */
40398+ them = ipsec_dev_get(cf->cf_name);
40399+#endif /* CONFIG_IP_ALIAS */
40400+
40401+ if (them == NULL) {
40402+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40403+ "klips_debug:ipsec_tunnel_ioctl: "
40404+ "physical device %s requested is null\n",
40405+ cf->cf_name);
40406+ return -ENXIO;
40407+ }
40408+
40409+#if 0
40410+ if (them->flags & IFF_UP) {
40411+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40412+ "klips_debug:ipsec_tunnel_ioctl: "
40413+ "physical device %s requested is not up.\n",
40414+ cf->cf_name);
40415+ ipsec_dev_put(them);
40416+ return -ENXIO;
40417+ }
40418+#endif
40419+
40420+ if (prv && prv->dev) {
40421+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40422+ "klips_debug:ipsec_tunnel_ioctl: "
40423+ "virtual device is already connected to %s.\n",
40424+ prv->dev->name ? prv->dev->name : "NULL");
40425+ ipsec_dev_put(them);
40426+ return -EBUSY;
40427+ }
40428+ return ipsec_tunnel_attach(dev, them);
40429+
40430+ case IPSEC_DEL_DEV:
40431+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40432+ "klips_debug:ipsec_tunnel_ioctl: "
40433+ "calling ipsec_tunnel_detatch.\n");
40434+ if (! prv->dev) {
40435+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40436+ "klips_debug:ipsec_tunnel_ioctl: "
40437+ "physical device not connected.\n");
40438+ return -ENODEV;
40439+ }
40440+ return ipsec_tunnel_detach(dev);
40441+
40442+ case IPSEC_CLR_DEV:
40443+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40444+ "klips_debug:ipsec_tunnel_ioctl: "
40445+ "calling ipsec_tunnel_clear.\n");
40446+ return ipsec_tunnel_clear();
40447+
40448+ default:
40449+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40450+ "klips_debug:ipsec_tunnel_ioctl: "
40451+ "unknown command %d.\n",
40452+ cmd);
40453+ return -EOPNOTSUPP;
40454+ }
40455+}
40456+
40457+struct net_device *ipsec_get_device(int inst)
40458+{
40459+ struct net_device *ipsec_dev;
40460+
40461+ ipsec_dev = NULL;
40462+
40463+ if(inst < IPSEC_NUM_IF) {
40464+ ipsec_dev = ipsecdevices[inst];
40465+ }
40466+
40467+ return ipsec_dev;
40468+}
40469+
40470+int
40471+ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
40472+{
40473+ struct net_device *dev = ptr;
40474+ struct net_device *ipsec_dev;
40475+ struct ipsecpriv *priv;
40476+ int i;
40477+
40478+ if (dev == NULL) {
40479+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40480+ "klips_debug:ipsec_device_event: "
40481+ "dev=NULL for event type %ld.\n",
40482+ event);
40483+ return(NOTIFY_DONE);
40484+ }
40485+
40486+ /* check for loopback devices */
40487+ if (dev && (dev->flags & IFF_LOOPBACK)) {
40488+ return(NOTIFY_DONE);
40489+ }
40490+
40491+ switch (event) {
40492+ case NETDEV_DOWN:
40493+ /* look very carefully at the scope of these compiler
40494+ directives before changing anything... -- RGB */
40495+#ifdef NET_21
40496+ case NETDEV_UNREGISTER:
40497+ switch (event) {
40498+ case NETDEV_DOWN:
40499+#endif /* NET_21 */
40500+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40501+ "klips_debug:ipsec_device_event: "
40502+ "NETDEV_DOWN dev=%s flags=%x\n",
40503+ dev->name,
40504+ dev->flags);
40505+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
40506+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
40507+ dev->name);
40508+ }
40509+#ifdef NET_21
40510+ break;
40511+ case NETDEV_UNREGISTER:
40512+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40513+ "klips_debug:ipsec_device_event: "
40514+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
40515+ dev->name,
40516+ dev->flags);
40517+ break;
40518+ }
40519+#endif /* NET_21 */
40520+
40521+ /* find the attached physical device and detach it. */
40522+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40523+ ipsec_dev = ipsecdevices[i];
40524+
40525+ if(ipsec_dev) {
40526+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
40527+ if(priv) {
40528+ ;
40529+ if(((struct net_device *)(priv->dev)) == dev) {
40530+ /* dev_close(ipsec_dev); */
40531+ /* return */ ipsec_tunnel_detach(ipsec_dev);
40532+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40533+ "klips_debug:ipsec_device_event: "
40534+ "device '%s' has been detached.\n",
40535+ ipsec_dev->name);
40536+ break;
40537+ }
40538+ } else {
40539+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40540+ "klips_debug:ipsec_device_event: "
40541+ "device '%s' has no private data space!\n",
40542+ ipsec_dev->name);
40543+ }
40544+ }
40545+ }
40546+ break;
40547+ case NETDEV_UP:
40548+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40549+ "klips_debug:ipsec_device_event: "
40550+ "NETDEV_UP dev=%s\n",
40551+ dev->name);
40552+ break;
40553+#ifdef NET_21
40554+ case NETDEV_REBOOT:
40555+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40556+ "klips_debug:ipsec_device_event: "
40557+ "NETDEV_REBOOT dev=%s\n",
40558+ dev->name);
40559+ break;
40560+ case NETDEV_CHANGE:
40561+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40562+ "klips_debug:ipsec_device_event: "
40563+ "NETDEV_CHANGE dev=%s flags=%x\n",
40564+ dev->name,
40565+ dev->flags);
40566+ break;
40567+ case NETDEV_REGISTER:
40568+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40569+ "klips_debug:ipsec_device_event: "
40570+ "NETDEV_REGISTER dev=%s\n",
40571+ dev->name);
40572+ break;
40573+ case NETDEV_CHANGEMTU:
40574+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40575+ "klips_debug:ipsec_device_event: "
40576+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
40577+ dev->name,
40578+ dev->mtu);
40579+ break;
40580+ case NETDEV_CHANGEADDR:
40581+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40582+ "klips_debug:ipsec_device_event: "
40583+ "NETDEV_CHANGEADDR dev=%s\n",
40584+ dev->name);
40585+ break;
40586+ case NETDEV_GOING_DOWN:
40587+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40588+ "klips_debug:ipsec_device_event: "
40589+ "NETDEV_GOING_DOWN dev=%s\n",
40590+ dev->name);
40591+ break;
40592+ case NETDEV_CHANGENAME:
40593+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40594+ "klips_debug:ipsec_device_event: "
40595+ "NETDEV_CHANGENAME dev=%s\n",
40596+ dev->name);
40597+ break;
40598+#endif /* NET_21 */
40599+ default:
40600+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40601+ "klips_debug:ipsec_device_event: "
40602+ "event type %ld unrecognised for dev=%s\n",
40603+ event,
40604+ dev->name);
40605+ break;
40606+ }
40607+ return NOTIFY_DONE;
40608+}
40609+
40610+/*
40611+ * Called when an ipsec tunnel device is initialized.
40612+ * The ipsec tunnel device structure is passed to us.
40613+ */
40614+
40615+int
40616+ipsec_tunnel_init(struct net_device *dev)
40617+{
40618+ int i;
40619+
40620+ KLIPS_PRINT(debug_tunnel,
40621+ "klips_debug:ipsec_tunnel_init: "
40622+ "allocating %lu bytes initialising device: %s\n",
40623+ (unsigned long) sizeof(struct ipsecpriv),
40624+ dev->name ? dev->name : "NULL");
40625+
40626+ /* Add our tunnel functions to the device */
40627+ dev->open = ipsec_tunnel_open;
40628+ dev->stop = ipsec_tunnel_close;
40629+ dev->hard_start_xmit = ipsec_tunnel_start_xmit;
40630+ dev->get_stats = ipsec_tunnel_get_stats;
40631+
40632+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
40633+ if (dev->priv == NULL)
40634+ return -ENOMEM;
40635+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
40636+
40637+ for(i = 0; i < sizeof(zeroes); i++) {
40638+ ((__u8*)(zeroes))[i] = 0;
40639+ }
40640+
40641+#ifndef NET_21
40642+ /* Initialize the tunnel device structure */
40643+ for (i = 0; i < DEV_NUMBUFFS; i++)
40644+ skb_queue_head_init(&dev->buffs[i]);
40645+#endif /* !NET_21 */
40646+
40647+ dev->set_multicast_list = NULL;
40648+ dev->do_ioctl = ipsec_tunnel_ioctl;
40649+ dev->hard_header = NULL;
40650+ dev->rebuild_header = NULL;
40651+ dev->set_mac_address = NULL;
40652+#ifndef NET_21
40653+ dev->header_cache_bind = NULL;
40654+#endif /* !NET_21 */
40655+ dev->header_cache_update= NULL;
40656+
40657+#ifdef NET_21
40658+/* prv->neigh_setup = NULL; */
40659+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
40660+#endif /* NET_21 */
40661+ dev->hard_header_len = 0;
40662+ dev->mtu = 0;
40663+ dev->addr_len = 0;
40664+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
40665+ dev->tx_queue_len = 10; /* Small queue */
40666+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
40667+
40668+ /* New-style flags. */
40669+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
40670+
40671+#if 0
40672+#ifdef NET_21
40673+ dev_init_buffers(dev);
40674+#else /* NET_21 */
40675+ dev->family = AF_INET;
40676+ dev->pa_addr = 0;
40677+ dev->pa_brdaddr = 0;
40678+ dev->pa_mask = 0;
40679+ dev->pa_alen = 4;
40680+#endif /* NET_21 */
40681+#endif
40682+
40683+ /* We're done. Have I forgotten anything? */
40684+ return 0;
40685+}
40686+
40687+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40688+/* Module specific interface (but it links with the rest of IPSEC) */
40689+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40690+
40691+int
40692+ipsec_tunnel_probe(struct net_device *dev)
40693+{
40694+ ipsec_tunnel_init(dev);
40695+ return 0;
40696+}
40697+
40698+struct net_device *ipsecdevices[IPSEC_NUM_IF];
40699+
40700+int
40701+ipsec_tunnel_init_devices(void)
40702+{
40703+ int i;
40704+ char name[IFNAMSIZ];
40705+ struct net_device *dev_ipsec;
40706+
40707+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40708+ "klips_debug:ipsec_tunnel_init_devices: "
40709+ "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
40710+ IPSEC_NUM_IF,
40711+ (unsigned long) (sizeof(struct net_device) + IFNAMSIZ),
40712+ IFNAMSIZ);
40713+
40714+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40715+ sprintf(name, IPSEC_DEV_FORMAT, i);
40716+ dev_ipsec = (struct net_device*)kmalloc(sizeof(struct net_device), GFP_KERNEL);
40717+ if (dev_ipsec == NULL) {
40718+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40719+ "klips_debug:ipsec_tunnel_init_devices: "
40720+ "failed to allocate memory for device %s, quitting device init.\n",
40721+ name);
40722+ return -ENOMEM;
40723+ }
40724+ memset((caddr_t)dev_ipsec, 0, sizeof(struct net_device));
40725+#ifdef NETDEV_23
40726+ strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
40727+#else /* NETDEV_23 */
40728+ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
40729+ if (dev_ipsec->name == NULL) {
40730+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40731+ "klips_debug:ipsec_tunnel_init_devices: "
40732+ "failed to allocate memory for device %s name, quitting device init.\n",
40733+ name);
40734+ return -ENOMEM;
40735+ }
40736+ memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ);
40737+ strncpy(dev_ipsec->name, name, IFNAMSIZ);
40738+#endif /* NETDEV_23 */
40739+#ifdef HAVE_DEV_NEXT
40740+ dev_ipsec->next = NULL;
40741+#endif
40742+ dev_ipsec->init = &ipsec_tunnel_probe;
40743+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40744+ "klips_debug:ipsec_tunnel_init_devices: "
40745+ "registering device %s\n",
40746+ dev_ipsec->name);
40747+
40748+ /* reference and hold the device reference */
40749+ dev_hold(dev_ipsec);
40750+ ipsecdevices[i]=dev_ipsec;
40751+
40752+ if (register_netdev(dev_ipsec) != 0) {
40753+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
40754+ "klips_debug:ipsec_tunnel_init_devices: "
40755+ "registering device %s failed, quitting device init.\n",
40756+ dev_ipsec->name);
40757+ return -EIO;
40758+ } else {
40759+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40760+ "klips_debug:ipsec_tunnel_init_devices: "
40761+ "registering device %s succeeded, continuing...\n",
40762+ dev_ipsec->name);
40763+ }
40764+ }
40765+ return 0;
40766+}
40767+
40768+/* void */
40769+int
40770+ipsec_tunnel_cleanup_devices(void)
40771+{
40772+ int error = 0;
40773+ int i;
40774+ struct net_device *dev_ipsec;
40775+
40776+ for(i = 0; i < IPSEC_NUM_IF; i++) {
40777+ dev_ipsec = ipsecdevices[i];
40778+ if(dev_ipsec == NULL) {
40779+ continue;
40780+ }
40781+
40782+ /* release reference */
40783+ ipsecdevices[i]=NULL;
40784+ ipsec_dev_put(dev_ipsec);
40785+
40786+ KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
40787+ dev_ipsec->name,
40788+ atomic_read(&dev_ipsec->refcnt));
40789+ unregister_netdev(dev_ipsec);
40790+ KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", dev_ipsec->name);
40791+#ifndef NETDEV_23
40792+ kfree(dev_ipsec->name);
40793+ dev_ipsec->name=NULL;
40794+#endif /* !NETDEV_23 */
40795+ kfree(dev_ipsec->priv);
40796+ dev_ipsec->priv=NULL;
40797+ }
40798+ return error;
40799+}
40800+
40801+/*
40802+ * $Log: ipsec_tunnel.c,v $
40803+ * Revision 1.232.2.7 2007-09-18 18:26:18 paul
40804+ * Fix mangled preprocessor line in HAVE_INET_SK_SPORT case.
40805+ *
40806+ * Revision 1.232.2.6 2007/09/05 02:56:10 paul
40807+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
40808+ * Fixes based on David McCullough patch.
40809+ *
40810+ * Revision 1.232.2.5 2006/10/06 21:39:26 paul
40811+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
40812+ * set. This is defined through autoconf.h which is included through the
40813+ * linux kernel build macros.
40814+ *
40815+ * Revision 1.232.2.4 2006/03/28 20:58:19 ken
40816+ * Fix for KLIPS on 2.6.16 - need to include <net/arp.h> now
40817+ *
40818+ * Revision 1.232.2.3 2006/02/15 05:14:12 paul
40819+ * 568: uninitialized struct in ipsec_tunnel.c coud break routing under 2.6 kernels
40820+ * ipsec_tunnel_send() calls the entry point function of routing subsystem
40821+ * (ip_route_output_key()) using a not fully initialized struct of type
40822+ * struct flowi.
40823+ * This will cause a failure in routing packets through an ipsec interface
40824+ * when patches for multipath routing from http://www.ssi.bg/~ja/
40825+ * are applied.
40826+ *
40827+ * Revision 1.232.2.2 2005/11/22 04:11:52 ken
40828+ * Backport fixes for 2.6.14 kernels from HEAD
40829+ *
40830+ * Revision 1.232.2.1 2005/09/21 22:57:43 paul
40831+ * pulled up compile fix for 2.6.13
40832+ *
40833+ * Revision 1.232 2005/06/04 16:06:06 mcr
40834+ * better patch for nat-t rcv-device code.
40835+ *
40836+ * Revision 1.231 2005/05/21 03:28:51 mcr
40837+ * make sure that port-500 hole is used for port-4500 as well.
40838+ *
40839+ * Revision 1.230 2005/05/11 01:42:04 mcr
40840+ * removal of debugging showed useless/wrong variables used.
40841+ *
40842+ * Revision 1.229 2005/04/29 05:10:22 mcr
40843+ * removed from extraenous includes to make unit testing easier.
40844+ *
40845+ * Revision 1.228 2005/01/26 00:50:35 mcr
40846+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
40847+ * and make sure that NAT_TRAVERSAL is set as well to match
40848+ * userspace compiles of code.
40849+ *
40850+ * Revision 1.227 2004/12/10 21:16:08 ken
40851+ * 64bit fixes from Opteron port of KLIPS 2.6
40852+ *
40853+ * Revision 1.226 2004/12/04 07:11:23 mcr
40854+ * fix for snmp SIOCPRIVATE use of snmpd.
40855+ * http://bugs.xelerance.com/view.php?id=144
40856+ *
40857+ * Revision 1.225 2004/12/03 21:25:57 mcr
40858+ * compile time fixes for running on 2.6.
40859+ * still experimental.
40860+ *
40861+ * Revision 1.224 2004/08/14 03:28:24 mcr
40862+ * fixed log comment to remove warning about embedded comment.
40863+ *
40864+ * Revision 1.223 2004/08/04 15:57:07 mcr
40865+ * moved des .h files to include/des/ *
40866+ * included 2.6 protocol specific things
40867+ * started at NAT-T support, but it will require a kernel patch.
40868+ *
40869+ * Revision 1.222 2004/08/03 18:19:08 mcr
40870+ * in 2.6, use "net_device" instead of #define device->net_device.
40871+ * this probably breaks 2.0 compiles.
40872+ *
40873+ * Revision 1.221 2004/07/10 19:11:18 mcr
40874+ * CONFIG_IPSEC -> CONFIG_KLIPS.
40875+ *
40876+ * Revision 1.220 2004/04/06 02:49:26 mcr
40877+ * pullup of algo code from alg-branch.
40878+ *
40879+ * Revision 1.219 2004/02/03 03:13:17 mcr
40880+ * minor edits for readability, and error reporting.
40881+ *
40882+ * Revision 1.218 2004/01/27 20:29:20 mcr
40883+ * fix for unregister_netdev() problem for underlying eth0.
40884+ *
40885+ * Revision 1.217 2003/12/10 01:14:27 mcr
40886+ * NAT-traversal patches to KLIPS.
40887+ *
40888+ * Revision 1.216 2003/12/04 23:01:17 mcr
40889+ * removed ipsec_netlink.h
40890+ *
40891+ * Revision 1.215 2003/12/04 16:35:16 ken
40892+ * Fix for ATM devices where physdev->hard_header_len *is* correct
40893+ *
40894+ * Revision 1.214 2003/11/25 23:52:37 mcr
40895+ * fix typo in patch - ixs-> needed.
40896+ *
40897+ * Revision 1.213 2003/11/24 18:25:49 mcr
40898+ * patch from willy@w.ods.org to fix problems with ATM interfaces.
40899+ *
40900+ * Revision 1.212 2003/10/31 02:27:55 mcr
40901+ * pulled up port-selector patches and sa_id elimination.
40902+ *
40903+ * Revision 1.211.2.2 2003/10/29 01:30:41 mcr
40904+ * elimited "struct sa_id".
40905+ *
40906+ * Revision 1.211.2.1 2003/09/21 13:59:56 mcr
40907+ * pre-liminary X.509 patch - does not yet pass tests.
40908+ *
40909+ * Revision 1.211 2003/09/10 16:46:30 mcr
40910+ * patches for 2.4 backport/2.6 existence.
40911+ *
40912+ * Revision 1.210 2003/07/31 22:47:16 mcr
40913+ * preliminary (untested by FS-team) 2.5 patches.
40914+ *
40915+ * Revision 1.209 2003/06/22 21:28:43 mcr
40916+ * inability to unload module was caused by calls to dev_get
40917+ * (ipsec_dev_get), to gather a device from a name. There is
40918+ * simply no reason to look the devices up - they should be kept
40919+ * in a nice array, ready for use.
40920+ *
40921+ * Revision 1.208 2003/06/22 21:25:07 mcr
40922+ * all staticly counted ipsecXXX device support removed.
40923+ *
40924+ * Revision 1.207 2003/04/02 20:15:37 mcr
40925+ * fix for PR#204 - do not clear connection tracking info if we
40926+ * the packet is being sent in the clear.
40927+ *
40928+ * Revision 1.206 2003/02/12 19:32:51 rgb
40929+ * Refactored file to:
40930+ * ipsec_xmit.c
40931+ * ipsec_xmit.h
40932+ * ipsec_mast.c
40933+ *
40934+ * Revision 1.205 2003/02/06 17:47:00 rgb
40935+ *
40936+ * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code.
40937+ * Refactor ipsec_tunnel_start_xmit() further into:
40938+ * ipsec_xmit_sanity_check_dev()
40939+ * ipsec_xmit_sanity_check_skb()
40940+ * ipsec_xmit_strip_hard_header()
40941+ * ipsec_xmit_restore_hard_header()
40942+ * ipsec_xmit_send()
40943+ * ipsec_xmit_cleanup()
40944+ * and start a skeletal ipsec_mast_start_xmit() .
40945+ *
40946+ * Revision 1.204 2003/02/06 06:43:46 rgb
40947+ *
40948+ * Refactor ipsec_tunnel_start_xmit, bringing out:
40949+ * ipsec_xmit_SAlookup
40950+ * ipsec_xmit_encap_once
40951+ * ipsec_xmit_encap_bundle
40952+ *
40953+ * Revision 1.203 2003/02/06 02:21:34 rgb
40954+ *
40955+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
40956+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
40957+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
40958+ *
40959+ * Revision 1.202 2003/01/03 07:38:01 rgb
40960+ *
40961+ * Start to refactor ipsec_tunnel_start_xmit() by putting local variables
40962+ * into struct ipsec_xmit_state and renaming a few variables to give more
40963+ * unique or searchable names.
40964+ *
40965+ * Revision 1.201 2003/01/03 00:31:28 rgb
40966+ *
40967+ * Clean up memset usage, including fixing 2 places where keys were not
40968+ * properly wiped.
40969+ *
40970+ * Revision 1.200 2002/12/06 02:24:02 mcr
40971+ * patches for compiling against SUSE 8.1 kernels. Requires
40972+ * an additional -DSUSE_LINUX_2_4_19_IS_STUPID.
40973+ *
40974+ * Revision 1.199 2002/10/12 23:11:53 dhr
40975+ *
40976+ * [KenB + DHR] more 64-bit cleanup
40977+ *
40978+ * Revision 1.198 2002/10/05 05:02:58 dhr
40979+ *
40980+ * C labels go on statements
40981+ *
40982+ * Revision 1.197 2002/09/20 05:01:50 rgb
40983+ * Added compiler directive to switch on IP options and fix IP options bug.
40984+ * Make ip->ihl treatment consistent using shifts rather than multiplications.
40985+ * Check for large enough packet before accessing udp header for IKE bypass.
40986+ * Added memory allocation debugging.
40987+ * Fixed potential memory allocation failure-induced oops.
40988+ *
40989+ * Revision 1.196 2002/07/24 18:44:54 rgb
40990+ * Type fiddling to tame ia64 compiler.
40991+ *
40992+ * Revision 1.195 2002/07/23 03:36:07 rgb
40993+ * Fixed 2.2 device initialisation hang.
40994+ *
40995+ * Revision 1.194 2002/05/27 21:40:34 rgb
40996+ * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2.
40997+ * Cleaned up intermediate step to dynamic device allocation.
40998+ *
40999+ * Revision 1.193 2002/05/27 19:31:36 rgb
41000+ * Convert to dynamic ipsec device allocation.
41001+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
41002+ *
41003+ * Revision 1.192 2002/05/23 07:14:28 rgb
41004+ * Added refcount code.
41005+ * Cleaned up %p variants to 0p%p for test suite cleanup.
41006+ *
41007+ * Revision 1.191 2002/05/14 02:34:37 rgb
41008+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
41009+ * ipsec_sa or ipsec_sa.
41010+ *
41011+ * Revision 1.190 2002/04/24 07:55:32 mcr
41012+ * #include patches and Makefiles for post-reorg compilation.
41013+ *
41014+ * Revision 1.189 2002/04/24 07:36:32 mcr
41015+ * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v
41016+ *
41017+ * Revision 1.188 2002/04/20 00:12:25 rgb
41018+ * Added esp IV CBC attack fix, disabled.
41019+ *
41020+ * Revision 1.187 2002/03/23 19:55:17 rgb
41021+ * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if
41022+ * iptraf or another pcap app is running.
41023+ *
41024+ * Revision 1.186 2002/03/19 03:26:22 rgb
41025+ * Applied DHR's tunnel patch to streamline IKE/specialSA processing.
41026+ *
41027+ * Revision 1.185 2002/02/20 04:13:05 rgb
41028+ * Send back ICMP_PKT_FILTERED upon %reject.
41029+ *
41030+ * Revision 1.184 2002/01/29 17:17:56 mcr
41031+ * moved include of ipsec_param.h to after include of linux/kernel.h
41032+ * otherwise, it seems that some option that is set in ipsec_param.h
41033+ * screws up something subtle in the include path to kernel.h, and
41034+ * it complains on the snprintf() prototype.
41035+ *
41036+ * Revision 1.183 2002/01/29 04:00:53 mcr
41037+ * more excise of kversions.h header.
41038+ *
41039+ * Revision 1.182 2002/01/29 02:13:18 mcr
41040+ * introduction of ipsec_kversion.h means that include of
41041+ * ipsec_param.h must preceed any decisions about what files to
41042+ * include to deal with differences in kernel source.
41043+ *
41044+ * Revision 1.181 2002/01/07 20:00:33 rgb
41045+ * Added IKE destination port debugging.
41046+ *
41047+ * Revision 1.180 2001/12/21 21:49:54 rgb
41048+ * Fixed bug as a result of moving IKE bypass above %trap/%hold code.
41049+ *
41050+ * Revision 1.179 2001/12/19 21:08:14 rgb
41051+ * Added transport protocol ports to ipsec_print_ip().
41052+ * Update eroute info for non-SA targets.
41053+ * Added obey DF code disabled.
41054+ * Fixed formatting bugs in ipsec_tunnel_hard_header().
41055+ *
41056+ * Revision 1.178 2001/12/05 09:36:10 rgb
41057+ * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid
41058+ * IKE packets being stolen by the %hold (and returned to the sending KMd
41059+ * in an ACQUIRE, ironically ;-).
41060+ *
41061+ * Revision 1.177 2001/11/26 09:23:50 rgb
41062+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
41063+ *
41064+ * Revision 1.170.2.1 2001/09/25 02:28:27 mcr
41065+ * struct tdb -> struct ipsec_sa.
41066+ * lifetime checks moved to common routines.
41067+ * cleaned up includes.
41068+ *
41069+ * Revision 1.170.2.2 2001/10/22 21:08:01 mcr
41070+ * include des.h, removed phony prototypes and fixed calling
41071+ * conventions to match real prototypes.
41072+ *
41073+ * Revision 1.176 2001/11/09 18:32:31 rgb
41074+ * Added Hans Schultz' fragmented UDP/500 IKE socket port selector.
41075+ *
41076+ * Revision 1.175 2001/11/06 20:47:00 rgb
41077+ * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling.
41078+ *
41079+ * Revision 1.174 2001/11/06 19:50:43 rgb
41080+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
41081+ * use also by pfkey_v2_parser.c
41082+ *
41083+ * Revision 1.173 2001/10/29 21:53:44 henry
41084+ * tone down the device-down message slightly, until we can make it smarter
41085+ *
41086+ * Revision 1.172 2001/10/26 04:59:37 rgb
41087+ * Added a critical level syslog message if an ipsec device goes down.
41088+ *
41089+ * Revision 1.171 2001/10/18 04:45:21 rgb
41090+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
41091+ * lib/freeswan.h version macros moved to lib/kversions.h.
41092+ * Other compiler directive cleanups.
41093+ *
41094+ * Revision 1.170 2001/09/25 00:09:50 rgb
41095+ * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a
41096+ * HOLD.
41097+ *
41098+ * Revision 1.169 2001/09/15 16:24:05 rgb
41099+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
41100+ *
41101+ * Revision 1.168 2001/09/14 16:58:37 rgb
41102+ * Added support for storing the first and last packets through a HOLD.
41103+ *
41104+ * Revision 1.167 2001/09/08 21:13:33 rgb
41105+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
41106+ *
41107+ * Revision 1.166 2001/08/27 19:47:59 rgb
41108+ * Clear tdb before usage.
41109+ * Added comment: clear IF before calling routing?
41110+ *
41111+ * Revision 1.165 2001/07/03 01:23:53 rgb
41112+ * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len >
41113+ * emtu, and don't drop.
41114+ *
41115+ * Revision 1.164 2001/06/14 19:35:10 rgb
41116+ * Update copyright date.
41117+ *
41118+ * Revision 1.163 2001/06/06 20:28:51 rgb
41119+ * Added sanity checks for NULL skbs and devices.
41120+ * Added more debugging output to various functions.
41121+ * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach().
41122+ * Renamed ipsec_tunnel_attach() virtual and physical device arguments.
41123+ * Corrected neigh_setup() device function assignment.
41124+ * Keep valid pointers to ipsec_tunnel_*() on detach.
41125+ * Set dev->type to the originally-initiallised value.
41126+ *
41127+ * Revision 1.162 2001/06/01 07:28:04 rgb
41128+ * Added sanity checks for detached devices. Don't down virtual devices
41129+ * to prevent packets going out in the clear if the detached device comes
41130+ * back up.
41131+ *
41132+ * Revision 1.161 2001/05/30 08:14:52 rgb
41133+ * Removed vestiges of esp-null transforms.
41134+ * NetDev Notifier instrumentation to track down disappearing devices.
41135+ *
41136+ * Revision 1.160 2001/05/29 05:15:12 rgb
41137+ * Added SS' PMTU patch which notifies sender if packet doesn't fit
41138+ * physical MTU (if it wasn't ICMP) and then drops it.
41139+ *
41140+ * Revision 1.159 2001/05/27 06:12:12 rgb
41141+ * Added structures for pid, packet count and last access time to eroute.
41142+ * Added packet count to beginning of /proc/net/ipsec_eroute.
41143+ *
41144+ * Revision 1.158 2001/05/24 05:39:33 rgb
41145+ * Applied source zeroing to 2.2 ip_route_output() call as well to enable
41146+ * PASS eroutes for opportunism.
41147+ *
41148+ * Revision 1.157 2001/05/23 22:35:28 rgb
41149+ * 2.4 source override simplification.
41150+ *
41151+ * Revision 1.156 2001/05/23 21:41:31 rgb
41152+ * Added error return code printing on ip_route_output().
41153+ *
41154+ * Revision 1.155 2001/05/23 05:09:13 rgb
41155+ * Fixed incorrect ip_route_output() failure message.
41156+ *
41157+ * Revision 1.154 2001/05/21 14:53:31 rgb
41158+ * Added debug statement for case when ip_route_output() fails, causing
41159+ * packet to be dropped, but log looked ok.
41160+ *
41161+ * Revision 1.153 2001/05/19 02:37:54 rgb
41162+ * Fixed missing comment termination.
41163+ *
41164+ * Revision 1.152 2001/05/19 02:35:50 rgb
41165+ * Debug code optimisation for non-debug speed.
41166+ * Kernel version compiler define comments.
41167+ * 2.2 and 2.4 kernel ip_send device and ip debug output added.
41168+ *
41169+ * Revision 1.151 2001/05/18 16:17:35 rgb
41170+ * Changed reference from "magic" to "shunt" SAs.
41171+ *
41172+ * Revision 1.150 2001/05/18 16:12:19 rgb
41173+ * Changed UDP/500 bypass test from 3 nested ifs to one anded if.
41174+ *
41175+ * Revision 1.149 2001/05/16 04:39:33 rgb
41176+ * Add default == eroute.dest to IKE bypass conditions for magic eroutes.
41177+ *
41178+ * Revision 1.148 2001/05/05 03:31:41 rgb
41179+ * IP frag debugging updates and enhancements.
41180+ *
41181+ * Revision 1.147 2001/05/03 19:41:40 rgb
41182+ * Added SS' skb_cow fix for 2.4.4.
41183+ *
41184+ * Revision 1.146 2001/04/30 19:28:16 rgb
41185+ * Update for 2.4.4. ip_select_ident() now has 3 args.
41186+ *
41187+ * Revision 1.145 2001/04/23 14:56:10 rgb
41188+ * Added spin_lock() check to prevent double-locking for multiple
41189+ * transforms and hence kernel lock-ups with SMP kernels.
41190+ *
41191+ * Revision 1.144 2001/04/21 23:04:45 rgb
41192+ * Define out skb->used for 2.4 kernels.
41193+ * Check if soft expire has already been sent before sending another to
41194+ * prevent ACQUIRE flooding.
41195+ *
41196+ * Revision 1.143 2001/03/16 07:37:21 rgb
41197+ * Added comments to all #endifs.
41198+ *
41199+ * Revision 1.142 2001/02/28 05:03:27 rgb
41200+ * Clean up and rationalise startup messages.
41201+ *
41202+ * Revision 1.141 2001/02/27 22:24:54 rgb
41203+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
41204+ * Check for satoa() return codes.
41205+ *
41206+ * Revision 1.140 2001/02/27 06:40:12 rgb
41207+ * Fixed TRAP->HOLD eroute byte order.
41208+ *
41209+ * Revision 1.139 2001/02/26 20:38:59 rgb
41210+ * Added compiler defines for 2.4.x-specific code.
41211+ *
41212+ * Revision 1.138 2001/02/26 19:57:27 rgb
41213+ * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
41214+ * of the new SPD and to support opportunistic.
41215+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
41216+ *
41217+ * Revision 1.137 2001/02/19 22:29:49 rgb
41218+ * Fixes for presence of active ipv6 segments which share ipsec physical
41219+ * device (gg).
41220+ *
41221+ * Revision 1.136 2001/01/29 22:30:38 rgb
41222+ * Fixed minor acquire debug printing bug.
41223+ *
41224+ * Revision 1.135 2001/01/29 22:19:45 rgb
41225+ * Zero source address for 2.4 bypass route lookup.
41226+ *
41227+ * Revision 1.134 2001/01/23 20:19:49 rgb
41228+ * 2.4 fix to remove removed is_clone member.
41229+ *
41230+ * Revision 1.133 2000/12/09 22:08:35 rgb
41231+ * Fix NET_23 bug, should be NETDEV_23.
41232+ *
41233+ * Revision 1.132 2000/12/01 06:54:50 rgb
41234+ * Fix for new 2.4 IP TTL default variable name.
41235+ *
41236+ * Revision 1.131 2000/11/09 20:52:15 rgb
41237+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
41238+ * include ipcomp and prevent races, renaming some tdb variables that got
41239+ * forgotten, moving some unlocks to include tdbs and adding a missing
41240+ * unlock. Thanks to Svenning for some of these.
41241+ *
41242+ * Revision 1.130 2000/11/09 20:11:22 rgb
41243+ * Minor shuffles to fix non-standard kernel config option selection.
41244+ *
41245+ * Revision 1.129 2000/11/06 04:32:49 rgb
41246+ * Clean up debug printing.
41247+ * Copy skb->protocol for all kernel versions.
41248+ * Ditched spin_lock_irqsave in favour of spin_lock.
41249+ * Disabled TTL decrement, done in ip_forward.
41250+ * Added debug printing before pfkey_acquire().
41251+ * Fixed printk-deltdbchain-spin_lock races (Svenning).
41252+ * Use defaultTTL for 2.1+ kernels.
41253+ * Add Svenning's adaptive content compression.
41254+ * Fix up debug display arguments.
41255+ *
41256+ * Revision 1.128 2000/09/28 00:58:57 rgb
41257+ * Moved the IKE passthrough check after the eroute lookup so we can pass
41258+ * IKE through intermediate tunnels.
41259+ *
41260+ * Revision 1.127 2000/09/22 17:52:11 rgb
41261+ * Fixed misleading ipcomp debug output.
41262+ *
41263+ * Revision 1.126 2000/09/22 04:22:56 rgb
41264+ * Fixed dumb spi->cpi conversion error.
41265+ *
41266+ * Revision 1.125 2000/09/21 04:34:48 rgb
41267+ * A few debug-specific things should be hidden under
41268+ * CONFIG_IPSEC_DEBUG.(MB)
41269+ * Improved ip_send() error handling.(MB)
41270+ *
41271+ * Revision 1.124 2000/09/21 03:40:58 rgb
41272+ * Added more debugging to try and track down the cpi outward copy problem.
41273+ *
41274+ * Revision 1.123 2000/09/19 07:08:49 rgb
41275+ * Added debugging to outgoing compression report.
41276+ *
41277+ * Revision 1.122 2000/09/18 19:21:26 henry
41278+ * RGB-supplied fix for RH5.2 problem
41279+ *
41280+ * Revision 1.121 2000/09/17 21:05:09 rgb
41281+ * Added tdb to skb_compress call to write in cpi.
41282+ *
41283+ * Revision 1.120 2000/09/17 16:57:16 rgb
41284+ * Added Svenning's patch to remove restriction of ipcomp to innermost
41285+ * transform.
41286+ *
41287+ * Revision 1.119 2000/09/15 11:37:01 rgb
41288+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
41289+ * IPCOMP zlib deflate code.
41290+ *
41291+ * Revision 1.118 2000/09/15 04:57:16 rgb
41292+ * Moved debug output after sanity check.
41293+ * Added tos copy sysctl.
41294+ *
41295+ * Revision 1.117 2000/09/12 03:22:51 rgb
41296+ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
41297+ * sysctl.
41298+ *
41299+ * Revision 1.116 2000/09/08 19:18:19 rgb
41300+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
41301+ * Added outgoing opportunistic hook, ifdef'ed out.
41302+ *
41303+ * Revision 1.115 2000/08/30 05:27:29 rgb
41304+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
41305+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
41306+ *
41307+ * Revision 1.114 2000/08/28 18:15:46 rgb
41308+ * Added MB's nf-debug reset patch.
41309+ *
41310+ * Revision 1.113 2000/08/27 02:26:40 rgb
41311+ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
41312+ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
41313+ *
41314+ * Revision 1.112 2000/08/20 21:37:33 rgb
41315+ * Activated pfkey_expire() calls.
41316+ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
41317+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
41318+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
41319+ *
41320+ * Revision 1.111 2000/08/01 14:51:51 rgb
41321+ * Removed _all_ remaining traces of DES.
41322+ *
41323+ * Revision 1.110 2000/07/28 14:58:31 rgb
41324+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
41325+ *
41326+ * Revision 1.109 2000/07/28 13:50:54 rgb
41327+ * Changed enet_statistics to net_device_stats and added back compatibility
41328+ * for pre-2.1.19.
41329+ *
41330+ * Revision 1.108 2000/05/16 03:03:11 rgb
41331+ * Updates for 2.3.99pre8 from MB.
41332+ *
41333+ * Revision 1.107 2000/05/10 23:08:21 rgb
41334+ * Print a debug warning about bogus packets received by the outgoing
41335+ * processing machinery only when klipsdebug is not set to none.
41336+ * Comment out the device initialisation informational messages.
41337+ *
41338+ * Revision 1.106 2000/05/10 19:17:14 rgb
41339+ * Define an IP_SEND macro, intending to have all packet passthroughs
41340+ * use fragmentation. This didn't quite work, but is a step in the
41341+ * right direction.
41342+ * Added buffer allocation debugging statements.
41343+ * Added configure option to shut off no eroute passthrough.
41344+ * Only check usetime against soft and hard limits if the tdb has been
41345+ * used.
41346+ * Cast output of ntohl so that the broken prototype doesn't make our
41347+ * compile noisy.
41348+ *
41349+ * Revision 1.105 2000/03/22 16:15:37 rgb
41350+ * Fixed renaming of dev_get (MB).
41351+ *
41352+ * Revision 1.104 2000/03/16 14:04:15 rgb
41353+ * Indented headers for readability.
41354+ * Fixed debug scope to enable compilation with debug off.
41355+ * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
41356+ *
41357+ * Revision 1.103 2000/03/16 07:11:07 rgb
41358+ * Hardcode PF_KEYv2 support.
41359+ * Fixed bug which allowed UDP/500 packet from another machine
41360+ * through in the clear.
41361+ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
41362+ *
41363+ * Revision 1.102 2000/03/14 12:26:59 rgb
41364+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
41365+ *
41366+ * Revision 1.101 2000/02/14 21:05:22 rgb
41367+ * Added MB's netif_queue fix for kernels 2.3.43+.
41368+ *
41369+ * Revision 1.100 2000/01/26 10:04:57 rgb
41370+ * Fixed noisy 2.0 printk arguments.
41371+ *
41372+ * Revision 1.99 2000/01/21 06:16:25 rgb
41373+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
41374+ * Switched to AF_ENCAP macro.
41375+ * Shortened debug output per packet and re-arranging debug_tunnel
41376+ * bitmap flags, while retaining necessary information to avoid
41377+ * trampling the kernel print ring buffer.
41378+ * Reformatted recursion switch code.
41379+ * Changed all references to tdb_proto to tdb_said.proto for clarity.
41380+ *
41381+ * Revision 1.98 2000/01/13 08:09:31 rgb
41382+ * Shuffled debug_tunnel switches to focus output.
41383+ * Fixed outgoing recursion bug, limiting to recursing only if the remote
41384+ * SG changes and if it is valid, ie. not passthrough.
41385+ * Clarified a number of debug messages.
41386+ *
41387+ * Revision 1.97 2000/01/10 16:37:16 rgb
41388+ * MB support for new ip_select_ident() upon disappearance of
41389+ * ip_id_count in 2.3.36+.
41390+ *
41391+ * Revision 1.96 1999/12/31 14:59:08 rgb
41392+ * MB fix to use new skb_copy_expand in kernel 2.3.35.
41393+ *
41394+ * Revision 1.95 1999/12/29 21:15:44 rgb
41395+ * Fix tncfg to aliased device bug.
41396+ *
41397+ * Revision 1.94 1999/12/22 04:26:06 rgb
41398+ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
41399+ * debugging by providing external labels to all functions with debugging
41400+ * turned on.
41401+ *
41402+ * Revision 1.93 1999/12/13 13:30:14 rgb
41403+ * Changed MTU reports and HW address reporting back to debug only.
41404+ *
41405+ * Revision 1.92 1999/12/07 18:57:56 rgb
41406+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
41407+ *
41408+ * Revision 1.91 1999/12/01 22:15:36 rgb
41409+ * Add checks for LARVAL and DEAD SAs.
41410+ * Change state of SA from MATURE to DYING when a soft lifetime is
41411+ * reached and print debug warning.
41412+ *
41413+ * Revision 1.90 1999/11/23 23:04:04 rgb
41414+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
41415+ * Sort out pfkey and freeswan headers, putting them in a library path.
41416+ *
41417+ * Revision 1.89 1999/11/18 18:50:59 rgb
41418+ * Changed all device registrations for static linking to
41419+ * dynamic to reduce the number and size of patches.
41420+ *
41421+ * Revision 1.88 1999/11/18 04:09:19 rgb
41422+ * Replaced all kernel version macros to shorter, readable form.
41423+ *
41424+ * Revision 1.87 1999/11/17 15:53:40 rgb
41425+ * Changed all occurrences of #include "../../../lib/freeswan.h"
41426+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
41427+ * klips/net/ipsec/Makefile.
41428+ *
41429+ * Revision 1.86 1999/10/16 18:25:37 rgb
41430+ * Moved SA lifetime expiry checks before packet processing.
41431+ * Expire SA on replay counter rollover.
41432+ *
41433+ * Revision 1.85 1999/10/16 04:24:31 rgb
41434+ * Add stats for time since last packet.
41435+ *
41436+ * Revision 1.84 1999/10/16 00:30:47 rgb
41437+ * Added SA lifetime counting.
41438+ *
41439+ * Revision 1.83 1999/10/15 22:15:57 rgb
41440+ * Clean out cruft.
41441+ * Add debugging.
41442+ *
41443+ * Revision 1.82 1999/10/08 18:26:19 rgb
41444+ * Fix 2.0.3x outgoing fragmented packet memory leak.
41445+ *
41446+ * Revision 1.81 1999/10/05 02:38:54 rgb
41447+ * Lower the default mtu of virtual devices to 16260.
41448+ *
41449+ * Revision 1.80 1999/10/03 18:56:41 rgb
41450+ * Spinlock support for 2.3.xx.
41451+ * Don't forget to undo spinlocks on error!
41452+ * Check for valid eroute before copying the structure.
41453+ *
41454+ * Revision 1.79 1999/10/01 15:44:53 rgb
41455+ * Move spinlock header include to 2.1> scope.
41456+ *
41457+ * Revision 1.78 1999/10/01 00:02:43 rgb
41458+ * Added tdb structure locking.
41459+ * Added eroute structure locking.
41460+ *
41461+ * Revision 1.77 1999/09/30 02:52:29 rgb
41462+ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
41463+ *
41464+ * Revision 1.76 1999/09/25 19:31:27 rgb
41465+ * Refine MSS hack to affect SYN, but not SYN+ACK packets.
41466+ *
41467+ * Revision 1.75 1999/09/24 22:52:38 rgb
41468+ * Fix two things broken in 2.0.38 by trying to fix network notifiers.
41469+ *
41470+ * Revision 1.74 1999/09/24 00:30:37 rgb
41471+ * Add test for changed source as well as destination to check for
41472+ * recursion.
41473+ *
41474+ * Revision 1.73 1999/09/23 20:52:24 rgb
41475+ * Add James Morris' MSS hack patch, disabled.
41476+ *
41477+ * Revision 1.72 1999/09/23 20:22:40 rgb
41478+ * Enable, tidy and fix network notifier code.
41479+ *
41480+ * Revision 1.71 1999/09/23 18:09:05 rgb
41481+ * Clean up 2.2.x fragmenting traces.
41482+ * Disable dev->type switching, forcing ARPHRD_TUNNEL.
41483+ *
41484+ * Revision 1.70 1999/09/22 14:14:24 rgb
41485+ * Add sanity checks for revectored calls to prevent calling a downed I/F.
41486+ *
41487+ * Revision 1.69 1999/09/21 15:00:57 rgb
41488+ * Add Marc Boucher's packet size check.
41489+ * Flesh out network device notifier code.
41490+ *
41491+ * Revision 1.68 1999/09/18 11:39:57 rgb
41492+ * Start to add (disabled) netdevice notifier code.
41493+ *
41494+ * Revision 1.67 1999/09/17 23:44:40 rgb
41495+ * Add a comment warning potential code hackers to stay away from mac.raw.
41496+ *
41497+ * Revision 1.66 1999/09/17 18:04:02 rgb
41498+ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
41499+ * Ditch TTL decrement in 2.2 (MB).
41500+ *
41501+ * Revision 1.65 1999/09/15 23:15:35 henry
41502+ * Marc Boucher's PPP fixes
41503+ *
41504+ * Revision 1.64 1999/09/07 13:40:53 rgb
41505+ * Ditch unreliable references to skb->mac.raw.
41506+ *
41507+ * Revision 1.63 1999/08/28 11:33:09 rgb
41508+ * Check for null skb->mac pointer.
41509+ *
41510+ * Revision 1.62 1999/08/28 02:02:30 rgb
41511+ * Add Marc Boucher's fix for properly dealing with skb->sk.
41512+ *
41513+ * Revision 1.61 1999/08/27 05:23:05 rgb
41514+ * Clean up skb->data/raw/nh/h manipulation.
41515+ * Add Marc Boucher's mods to aid tcpdump.
41516+ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
41517+ * Re-order hard_header stripping -- might be able to remove it...
41518+ *
41519+ * Revision 1.60 1999/08/26 20:01:02 rgb
41520+ * Tidy up compiler directives and macros.
41521+ * Re-enable ICMP for tunnels where inner_dst != outer_dst.
41522+ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
41523+ *
41524+ * Revision 1.59 1999/08/25 15:44:41 rgb
41525+ * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
41526+ *
41527+ * Revision 1.58 1999/08/25 15:00:54 rgb
41528+ * Add dst cache code for 2.2.xx.
41529+ * Add sanity check for skb packet header pointers.
41530+ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
41531+ * *_rebuild_header.
41532+ * Add neigh_* cache code.
41533+ * Change dev->type back to ARPHRD_TUNNEL.
41534+ *
41535+ * Revision 1.57 1999/08/17 21:50:23 rgb
41536+ * Fixed minor debug output bugs.
41537+ * Regrouped error recovery exit code.
41538+ * Added compiler directives to remove unwanted code and symbols.
41539+ * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
41540+ * Add debugging code for output function addresses.
41541+ * Fix minor bug in (possibly unused) header_cache_bind function.
41542+ * Add device neighbour caching code.
41543+ * Change dev->type from ARPHRD_TUNNEL to physdev->type.
41544+ *
41545+ * Revision 1.56 1999/08/03 17:22:56 rgb
41546+ * Debug output clarification using KERN_* macros. Other inactive changes
41547+ * added.
41548+ *
41549+ * Revision 1.55 1999/08/03 16:58:46 rgb
41550+ * Fix skb_copy_expand size bug. Was getting incorrect size.
41551+ *
41552+ * Revision 1.54 1999/07/14 19:32:38 rgb
41553+ * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
41554+ *
41555+ * Revision 1.53 1999/06/10 15:44:02 rgb
41556+ * Minor reformatting and clean-up.
41557+ *
41558+ * Revision 1.52 1999/05/09 03:25:36 rgb
41559+ * Fix bug introduced by 2.2 quick-and-dirty patch.
41560+ *
41561+ * Revision 1.51 1999/05/08 21:24:59 rgb
41562+ * Add casting to silence the 2.2.x compile.
41563+ *
41564+ * Revision 1.50 1999/05/05 22:02:32 rgb
41565+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
41566+ *
41567+ * Revision 1.49 1999/04/29 15:18:52 rgb
41568+ * Change gettdb parameter to a pointer to reduce stack loading and
41569+ * facilitate parameter sanity checking.
41570+ * Fix undetected bug that might have tried to access a null pointer.
41571+ * Eliminate unnessessary usage of tdb_xform member to further switch
41572+ * away from the transform switch to the algorithm switch.
41573+ * Add return values to init and cleanup functions.
41574+ *
41575+ * Revision 1.48 1999/04/16 15:38:00 rgb
41576+ * Minor rearrangement of freeing code to avoid memory leaks with impossible or
41577+ * rare situations.
41578+ *
41579+ * Revision 1.47 1999/04/15 15:37:25 rgb
41580+ * Forward check changes from POST1_00 branch.
41581+ *
41582+ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb
41583+ * Ditch 'things I wish I had known before...'.
41584+ *
41585+ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb
41586+ * Free skb after fragmentation.
41587+ * Use stats more effectively.
41588+ * Add I/F to mtu notch-down reporting.
41589+ *
41590+ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb
41591+ * Backcheck from HEAD, pre1.0.
41592+ *
41593+ * Revision 1.46 1999/04/11 00:29:00 henry
41594+ * GPL boilerplate
41595+ *
41596+ * Revision 1.45 1999/04/07 15:42:01 rgb
41597+ * Fix mtu/ping bug AGAIN!
41598+ *
41599+ * Revision 1.44 1999/04/06 04:54:27 rgb
41600+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
41601+ * patch shell fixes.
41602+ *
41603+ * Revision 1.43 1999/04/04 03:57:07 rgb
41604+ * ip_fragment() doesn't free the supplied skb. Freed.
41605+ *
41606+ * Revision 1.42 1999/04/01 23:27:15 rgb
41607+ * Preload size of virtual mtu.
41608+ *
41609+ * Revision 1.41 1999/04/01 09:31:23 rgb
41610+ * Invert meaning of ICMP PMTUD config option and clarify.
41611+ * Code clean-up.
41612+ *
41613+ * Revision 1.40 1999/04/01 04:37:17 rgb
41614+ * SSH stalling bug fix.
41615+ *
41616+ * Revision 1.39 1999/03/31 23:44:28 rgb
41617+ * Don't send ICMP on DF and frag_off.
41618+ *
41619+ * Revision 1.38 1999/03/31 15:20:10 rgb
41620+ * Quiet down debugging.
41621+ *
41622+ * Revision 1.37 1999/03/31 08:30:31 rgb
41623+ * Add switch to shut off ICMP PMTUD packets.
41624+ *
41625+ * Revision 1.36 1999/03/31 05:44:47 rgb
41626+ * Keep PMTU reduction private.
41627+ *
41628+ * Revision 1.35 1999/03/27 15:13:02 rgb
41629+ * PMTU/fragmentation bug fix.
41630+ *
41631+ * Revision 1.34 1999/03/17 21:19:26 rgb
41632+ * Fix kmalloc nonatomic bug.
41633+ *
41634+ * Revision 1.33 1999/03/17 15:38:42 rgb
41635+ * Code clean-up.
41636+ * ESP_NULL IV bug fix.
41637+ *
41638+ * Revision 1.32 1999/03/01 20:44:25 rgb
41639+ * Code clean-up.
41640+ * Memory leak bug fix.
41641+ *
41642+ * Revision 1.31 1999/02/27 00:02:09 rgb
41643+ * Tune to report the MTU reduction once, rather than after every recursion
41644+ * through the encapsulating code, preventing tcp stream stalling.
41645+ *
41646+ * Revision 1.30 1999/02/24 20:21:01 rgb
41647+ * Reformat debug printk's.
41648+ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
41649+ * Clean-up.
41650+ *
41651+ * Revision 1.29 1999/02/22 17:08:14 rgb
41652+ * Fix recursive encapsulation code.
41653+ *
41654+ * Revision 1.28 1999/02/19 18:27:02 rgb
41655+ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
41656+ *
41657+ * Revision 1.27 1999/02/17 16:51:37 rgb
41658+ * Clean out unused cruft.
41659+ * Temporarily tone down volume of debug output.
41660+ * Temporarily shut off fragment rejection.
41661+ * Disabled temporary failed recursive encapsulation loop.
41662+ *
41663+ * Revision 1.26 1999/02/12 21:21:26 rgb
41664+ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
41665+ *
41666+ * Revision 1.25 1999/02/11 19:38:27 rgb
41667+ * More clean-up.
41668+ * Add sanity checking for skb_copy_expand() to prevent kernel panics on
41669+ * skb_put() values out of range.
41670+ * Fix head/tailroom calculation causing skb_put() out-of-range values.
41671+ * Fix return values to prevent 'nonatomic alloc_skb' warnings.
41672+ * Allocate new skb iff needed.
41673+ * Added more debug statements.
41674+ * Make headroom depend on structure, not hard-coded values.
41675+ *
41676+ * Revision 1.24 1999/02/10 23:20:33 rgb
41677+ * Shut up annoying 'statement has no effect' compiler warnings with
41678+ * debugging compiled out.
41679+ *
41680+ * Revision 1.23 1999/02/10 22:36:30 rgb
41681+ * Clean-up obsolete, unused and messy code.
41682+ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
41683+ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
41684+ * original ipsec_tunnel_start_xmit.
41685+ * Send all packet with different inner and outer destinations directly to
41686+ * the attached physical device, rather than back through ip_forward,
41687+ * preventing disappearing routes problems.
41688+ * Do sanity checking before investing too much CPU in allocating new
41689+ * structures.
41690+ * Fail on IP header options: We cannot process them yet.
41691+ * Add some helpful comments.
41692+ * Use virtual device for parameters instead of physical device.
41693+ *
41694+ * Revision 1.22 1999/02/10 03:03:02 rgb
41695+ * Duh. Fixed the TTL bug: forgot to update the checksum.
41696+ *
41697+ * Revision 1.21 1999/02/09 23:17:53 rgb
41698+ * Add structure members to ipsec_print_ip debug function.
41699+ * Temporarily fix TTL bug preventing tunnel mode from functioning.
41700+ *
41701+ * Revision 1.20 1999/02/09 00:14:25 rgb
41702+ * Add KLIPSPRINT macro. (Not used yet, though.)
41703+ * Delete old ip_tunnel code (BADCODE).
41704+ * Decrement TTL in outgoing packet.
41705+ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
41706+ * Delete ethernet only feature and fix hard-coded hard_header_len.
41707+ *
41708+ * Revision 1.19 1999/01/29 17:56:22 rgb
41709+ * 64-bit re-fix submitted by Peter Onion.
41710+ *
41711+ * Revision 1.18 1999/01/28 22:43:24 rgb
41712+ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
41713+ *
41714+ * Revision 1.17 1999/01/26 02:08:16 rgb
41715+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
41716+ * Removed dead code.
41717+ *
41718+ * Revision 1.16 1999/01/22 06:25:26 rgb
41719+ * Cruft clean-out.
41720+ * Added algorithm switch code.
41721+ * 64-bit clean-up.
41722+ * Passthrough on IPIP protocol, spi 0x0 fix.
41723+ * Enhanced debugging.
41724+ *
41725+ * Revision 1.15 1998/12/01 13:22:04 rgb
41726+ * Added support for debug printing of version info.
41727+ *
41728+ * Revision 1.14 1998/11/30 13:22:55 rgb
41729+ * Rationalised all the klips kernel file headers. They are much shorter
41730+ * now and won't conflict under RH5.2.
41731+ *
41732+ * Revision 1.13 1998/11/17 21:13:52 rgb
41733+ * Put IKE port bypass debug output in user-switched debug statements.
41734+ *
41735+ * Revision 1.12 1998/11/13 13:20:25 rgb
41736+ * Fixed ntohs bug in udp/500 hole for IKE.
41737+ *
41738+ * Revision 1.11 1998/11/10 08:01:19 rgb
41739+ * Kill tcp/500 hole, keep udp/500 hole.
41740+ *
41741+ * Revision 1.10 1998/11/09 21:29:26 rgb
41742+ * If no eroute is found, discard packet and incr. tx_error.
41743+ *
41744+ * Revision 1.9 1998/10/31 06:50:00 rgb
41745+ * Add tcp/udp/500 bypass.
41746+ * Fixed up comments in #endif directives.
41747+ *
41748+ * Revision 1.8 1998/10/27 00:34:31 rgb
41749+ * Reformat debug output of IP headers.
41750+ * Newlines added before calls to ipsec_print_ip.
41751+ *
41752+ * Revision 1.7 1998/10/19 14:44:28 rgb
41753+ * Added inclusion of freeswan.h.
41754+ * sa_id structure implemented and used: now includes protocol.
41755+ *
41756+ * Revision 1.6 1998/10/09 04:31:35 rgb
41757+ * Added 'klips_debug' prefix to all klips printk debug statements.
41758+ *
41759+ * Revision 1.5 1998/08/28 03:09:51 rgb
41760+ * Prevent kernel log spam with default route through ipsec.
41761+ *
41762+ * Revision 1.4 1998/08/05 22:23:09 rgb
41763+ * Change setdev return code to ENXIO for a non-existant physical device.
41764+ *
41765+ * Revision 1.3 1998/07/29 20:41:11 rgb
41766+ * Add ipsec_tunnel_clear to clear all tunnel attachments.
41767+ *
41768+ * Revision 1.2 1998/06/25 20:00:33 rgb
41769+ * Clean up #endif comments.
41770+ * Rename dev_ipsec to dev_ipsec0 for consistency.
41771+ * Document ipsec device fields.
41772+ * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
41773+ * Get debugging report for *every* ipsec device initialisation.
41774+ * Comment out redundant code.
41775+ *
41776+ * Revision 1.1 1998/06/18 21:27:50 henry
41777+ * move sources from klips/src to klips/net/ipsec, to keep stupid
41778+ * kernel-build scripts happier in the presence of symlinks
41779+ *
41780+ * Revision 1.8 1998/06/14 23:49:40 rgb
41781+ * Clarify version reporting on module loading.
41782+ *
41783+ * Revision 1.7 1998/05/27 23:19:20 rgb
41784+ * Added version reporting.
41785+ *
41786+ * Revision 1.6 1998/05/18 21:56:23 rgb
41787+ * Clean up for numerical consistency of output and cleaning up debug code.
41788+ *
41789+ * Revision 1.5 1998/05/12 02:44:23 rgb
41790+ * Clarifying 'no e-route to host' message.
41791+ *
41792+ * Revision 1.4 1998/04/30 15:34:35 rgb
41793+ * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
41794+ *
41795+ * Revision 1.3 1998/04/21 21:28:54 rgb
41796+ * Rearrange debug switches to change on the fly debug output from user
41797+ * space. Only kernel changes checked in at this time. radij.c was also
41798+ * changed to temporarily remove buggy debugging code in rj_delete causing
41799+ * an OOPS and hence, netlink device open errors.
41800+ *
41801+ * Revision 1.2 1998/04/12 22:03:24 rgb
41802+ * Updated ESP-3DES-HMAC-MD5-96,
41803+ * ESP-DES-HMAC-MD5-96,
41804+ * AH-HMAC-MD5-96,
41805+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
41806+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
41807+ *
41808+ * Fixed eroute references in /proc/net/ipsec*.
41809+ *
41810+ * Started to patch module unloading memory leaks in ipsec_netlink and
41811+ * radij tree unloading.
41812+ *
41813+ * Revision 1.1 1998/04/09 03:06:12 henry
41814+ * sources moved up from linux/net/ipsec
41815+ *
41816+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
41817+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
41818+ *
41819+ * Revision 0.5 1997/06/03 04:24:48 ji
41820+ * Added transport mode.
41821+ * Changed the way routing is done.
41822+ * Lots of bug fixes.
41823+ *
41824+ * Revision 0.4 1997/01/15 01:28:15 ji
41825+ * No changes.
41826+ *
41827+ * Revision 0.3 1996/11/20 14:39:04 ji
41828+ * Minor cleanups.
41829+ * Rationalized debugging code.
41830+ *
41831+ * Revision 0.2 1996/11/02 00:18:33 ji
41832+ * First limited release.
41833+ *
41834+ * Local Variables:
41835+ * c-style: linux
41836+ * End:
41837+ */
41838--- /dev/null Tue Mar 11 13:02:56 2003
41839+++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004
41840@@ -0,0 +1,360 @@
41841+/*
41842+ * Common routines for IPSEC transformations.
41843+ * Copyright (C) 1996, 1997 John Ioannidis.
41844+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
41845+ *
41846+ * This program is free software; you can redistribute it and/or modify it
41847+ * under the terms of the GNU General Public License as published by the
41848+ * Free Software Foundation; either version 2 of the License, or (at your
41849+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
41850+ *
41851+ * This program is distributed in the hope that it will be useful, but
41852+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
41853+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41854+ * for more details.
41855+ *
41856+ * RCSID $Id: ipsec_xform.c,v 1.65.2.1 2006-10-06 21:39:26 paul Exp $
41857+ */
41858+
41859+#ifndef AUTOCONF_INCLUDED
41860+#include <linux/config.h>
41861+#endif
41862+#include <linux/version.h>
41863+#include <linux/kernel.h> /* printk() */
41864+
41865+#include "freeswan/ipsec_param.h"
41866+
41867+#ifdef MALLOC_SLAB
41868+# include <linux/slab.h> /* kmalloc() */
41869+#else /* MALLOC_SLAB */
41870+# include <linux/malloc.h> /* kmalloc() */
41871+#endif /* MALLOC_SLAB */
41872+#include <linux/errno.h> /* error codes */
41873+#include <linux/types.h> /* size_t */
41874+#include <linux/interrupt.h> /* mark_bh */
41875+
41876+#include <linux/netdevice.h> /* struct device, and other headers */
41877+#include <linux/etherdevice.h> /* eth_type_trans */
41878+#include <linux/ip.h> /* struct iphdr */
41879+#include <linux/skbuff.h>
41880+#include <linux/random.h> /* get_random_bytes() */
41881+#include <freeswan.h>
41882+#ifdef SPINLOCK
41883+# ifdef SPINLOCK_23
41884+# include <linux/spinlock.h> /* *lock* */
41885+# else /* SPINLOCK_23 */
41886+# include <asm/spinlock.h> /* *lock* */
41887+# endif /* SPINLOCK_23 */
41888+#endif /* SPINLOCK */
41889+
41890+#include <net/ip.h>
41891+
41892+#include "freeswan/radij.h"
41893+#include "freeswan/ipsec_encap.h"
41894+#include "freeswan/ipsec_radij.h"
41895+#include "freeswan/ipsec_xform.h"
41896+#include "freeswan/ipsec_ipe4.h"
41897+#include "freeswan/ipsec_ah.h"
41898+#include "freeswan/ipsec_esp.h"
41899+
41900+#include <pfkeyv2.h>
41901+#include <pfkey.h>
41902+
41903+#ifdef CONFIG_KLIPS_DEBUG
41904+int debug_xform = 0;
41905+#endif /* CONFIG_KLIPS_DEBUG */
41906+
41907+#ifdef SPINLOCK
41908+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
41909+#else /* SPINLOCK */
41910+spinlock_t tdb_lock;
41911+#endif /* SPINLOCK */
41912+
41913+/*
41914+ * $Log: ipsec_xform.c,v $
41915+ * Revision 1.65.2.1 2006-10-06 21:39:26 paul
41916+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
41917+ * set. This is defined through autoconf.h which is included through the
41918+ * linux kernel build macros.
41919+ *
41920+ * Revision 1.65 2005/04/29 05:10:22 mcr
41921+ * removed from extraenous includes to make unit testing easier.
41922+ *
41923+ * Revision 1.64 2004/07/10 19:11:18 mcr
41924+ * CONFIG_IPSEC -> CONFIG_KLIPS.
41925+ *
41926+ * Revision 1.63 2003/10/31 02:27:55 mcr
41927+ * pulled up port-selector patches and sa_id elimination.
41928+ *
41929+ * Revision 1.62.30.1 2003/10/29 01:30:41 mcr
41930+ * elimited "struct sa_id".
41931+ *
41932+ * Revision 1.62 2002/05/14 02:34:21 rgb
41933+ * Delete stale code.
41934+ *
41935+ * Revision 1.61 2002/04/24 07:55:32 mcr
41936+ * #include patches and Makefiles for post-reorg compilation.
41937+ *
41938+ * Revision 1.60 2002/04/24 07:36:33 mcr
41939+ * Moved from ./klips/net/ipsec/ipsec_xform.c,v
41940+ *
41941+ * Revision 1.59 2002/03/29 15:01:36 rgb
41942+ * Delete decommissioned code.
41943+ *
41944+ * Revision 1.58 2002/01/29 17:17:57 mcr
41945+ * moved include of ipsec_param.h to after include of linux/kernel.h
41946+ * otherwise, it seems that some option that is set in ipsec_param.h
41947+ * screws up something subtle in the include path to kernel.h, and
41948+ * it complains on the snprintf() prototype.
41949+ *
41950+ * Revision 1.57 2002/01/29 04:00:53 mcr
41951+ * more excise of kversions.h header.
41952+ *
41953+ * Revision 1.56 2001/11/27 05:17:22 mcr
41954+ * turn off the worst of the per-packet debugging.
41955+ *
41956+ * Revision 1.55 2001/11/26 09:23:50 rgb
41957+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
41958+ *
41959+ * Revision 1.54 2001/10/18 04:45:21 rgb
41960+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
41961+ * lib/freeswan.h version macros moved to lib/kversions.h.
41962+ * Other compiler directive cleanups.
41963+ *
41964+ * Revision 1.53 2001/09/08 21:13:34 rgb
41965+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
41966+ *
41967+ * Revision 1.52 2001/06/14 19:35:11 rgb
41968+ * Update copyright date.
41969+ *
41970+ * Revision 1.51 2001/05/30 08:14:03 rgb
41971+ * Removed vestiges of esp-null transforms.
41972+ *
41973+ * Revision 1.50 2001/05/03 19:43:18 rgb
41974+ * Initialise error return variable.
41975+ * Update SENDERR macro.
41976+ * Fix sign of error return code for ipsec_tdbcleanup().
41977+ * Use more appropriate return code for ipsec_tdbwipe().
41978+ *
41979+ * Revision 1.49 2001/04/19 18:56:17 rgb
41980+ * Fixed tdb table locking comments.
41981+ *
41982+ * Revision 1.48 2001/02/27 22:24:55 rgb
41983+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
41984+ * Check for satoa() return codes.
41985+ *
41986+ * Revision 1.47 2000/11/06 04:32:08 rgb
41987+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
41988+ *
41989+ * Revision 1.46 2000/09/20 16:21:57 rgb
41990+ * Cleaned up ident string alloc/free.
41991+ *
41992+ * Revision 1.45 2000/09/08 19:16:51 rgb
41993+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
41994+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
41995+ *
41996+ * Revision 1.44 2000/08/30 05:29:04 rgb
41997+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
41998+ *
41999+ * Revision 1.43 2000/08/18 21:30:41 rgb
42000+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
42001+ *
42002+ * Revision 1.42 2000/08/01 14:51:51 rgb
42003+ * Removed _all_ remaining traces of DES.
42004+ *
42005+ * Revision 1.41 2000/07/28 14:58:31 rgb
42006+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
42007+ *
42008+ * Revision 1.40 2000/06/28 05:50:11 rgb
42009+ * Actually set iv_bits.
42010+ *
42011+ * Revision 1.39 2000/05/10 23:11:09 rgb
42012+ * Added netlink debugging output.
42013+ * Added a cast to quiet down the ntohl bug.
42014+ *
42015+ * Revision 1.38 2000/05/10 19:18:42 rgb
42016+ * Cast output of ntohl so that the broken prototype doesn't make our
42017+ * compile noisy.
42018+ *
42019+ * Revision 1.37 2000/03/16 14:04:59 rgb
42020+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
42021+ *
42022+ * Revision 1.36 2000/01/26 10:11:28 rgb
42023+ * Fixed spacing in error text causing run-in words.
42024+ *
42025+ * Revision 1.35 2000/01/21 06:17:16 rgb
42026+ * Tidied up compiler directive indentation for readability.
42027+ * Added ictx,octx vars for simplification.(kravietz)
42028+ * Added macros for HMAC padding magic numbers.(kravietz)
42029+ * Fixed missing key length reporting bug.
42030+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
42031+ *
42032+ * Revision 1.34 1999/12/08 00:04:19 rgb
42033+ * Fixed SA direction overwriting bug for netlink users.
42034+ *
42035+ * Revision 1.33 1999/12/01 22:16:44 rgb
42036+ * Minor formatting changes in ESP MD5 initialisation.
42037+ *
42038+ * Revision 1.32 1999/11/25 09:06:36 rgb
42039+ * Fixed error return messages, should be returning negative numbers.
42040+ * Implemented SENDERR macro for propagating error codes.
42041+ * Added debug message and separate error code for algorithms not compiled
42042+ * in.
42043+ *
42044+ * Revision 1.31 1999/11/23 23:06:26 rgb
42045+ * Sort out pfkey and freeswan headers, putting them in a library path.
42046+ *
42047+ * Revision 1.30 1999/11/18 04:09:20 rgb
42048+ * Replaced all kernel version macros to shorter, readable form.
42049+ *
42050+ * Revision 1.29 1999/11/17 15:53:40 rgb
42051+ * Changed all occurrences of #include "../../../lib/freeswan.h"
42052+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
42053+ * klips/net/ipsec/Makefile.
42054+ *
42055+ * Revision 1.28 1999/10/18 20:04:01 rgb
42056+ * Clean-out unused cruft.
42057+ *
42058+ * Revision 1.27 1999/10/03 19:01:03 rgb
42059+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
42060+ *
42061+ * Revision 1.26 1999/10/01 16:22:24 rgb
42062+ * Switch from assignment init. to functional init. of spinlocks.
42063+ *
42064+ * Revision 1.25 1999/10/01 15:44:54 rgb
42065+ * Move spinlock header include to 2.1> scope.
42066+ *
42067+ * Revision 1.24 1999/10/01 00:03:46 rgb
42068+ * Added tdb structure locking.
42069+ * Minor formatting changes.
42070+ * Add function to initialize tdb hash table.
42071+ *
42072+ * Revision 1.23 1999/05/25 22:42:12 rgb
42073+ * Add deltdbchain() debugging.
42074+ *
42075+ * Revision 1.22 1999/05/25 21:24:31 rgb
42076+ * Add debugging statements to deltdbchain().
42077+ *
42078+ * Revision 1.21 1999/05/25 03:51:48 rgb
42079+ * Refix error return code.
42080+ *
42081+ * Revision 1.20 1999/05/25 03:34:07 rgb
42082+ * Fix error return for flush.
42083+ *
42084+ * Revision 1.19 1999/05/09 03:25:37 rgb
42085+ * Fix bug introduced by 2.2 quick-and-dirty patch.
42086+ *
42087+ * Revision 1.18 1999/05/05 22:02:32 rgb
42088+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
42089+ *
42090+ * Revision 1.17 1999/04/29 15:20:16 rgb
42091+ * Change gettdb parameter to a pointer to reduce stack loading and
42092+ * facilitate parameter sanity checking.
42093+ * Add sanity checking for null pointer arguments.
42094+ * Add debugging instrumentation.
42095+ * Add function deltdbchain() which will take care of unlinking,
42096+ * zeroing and deleting a chain of tdbs.
42097+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
42098+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
42099+ * structures.
42100+ *
42101+ * Revision 1.16 1999/04/16 15:36:29 rgb
42102+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
42103+ *
42104+ * Revision 1.15 1999/04/11 00:29:01 henry
42105+ * GPL boilerplate
42106+ *
42107+ * Revision 1.14 1999/04/06 04:54:28 rgb
42108+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
42109+ * patch shell fixes.
42110+ *
42111+ * Revision 1.13 1999/02/19 18:23:01 rgb
42112+ * Nix debug off compile warning.
42113+ *
42114+ * Revision 1.12 1999/02/17 16:52:16 rgb
42115+ * Consolidate satoa()s for space and speed efficiency.
42116+ * Convert DEBUG_IPSEC to KLIPS_PRINT
42117+ * Clean out unused cruft.
42118+ * Ditch NET_IPIP dependancy.
42119+ * Loop for 3des key setting.
42120+ *
42121+ * Revision 1.11 1999/01/26 02:09:05 rgb
42122+ * Remove ah/esp/IPIP switching on include files.
42123+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
42124+ * Removed dead code.
42125+ * Clean up debug code when switched off.
42126+ * Remove references to INET_GET_PROTOCOL.
42127+ * Added code exclusion macros to reduce code from unused algorithms.
42128+ *
42129+ * Revision 1.10 1999/01/22 06:28:55 rgb
42130+ * Cruft clean-out.
42131+ * Put random IV generation in kernel.
42132+ * Added algorithm switch code.
42133+ * Enhanced debugging.
42134+ * 64-bit clean-up.
42135+ *
42136+ * Revision 1.9 1998/11/30 13:22:55 rgb
42137+ * Rationalised all the klips kernel file headers. They are much shorter
42138+ * now and won't conflict under RH5.2.
42139+ *
42140+ * Revision 1.8 1998/11/25 04:59:06 rgb
42141+ * Add conditionals for no IPIP tunnel code.
42142+ * Delete commented out code.
42143+ *
42144+ * Revision 1.7 1998/10/31 06:50:41 rgb
42145+ * Convert xform ASCII names to no spaces.
42146+ * Fixed up comments in #endif directives.
42147+ *
42148+ * Revision 1.6 1998/10/19 14:44:28 rgb
42149+ * Added inclusion of freeswan.h.
42150+ * sa_id structure implemented and used: now includes protocol.
42151+ *
42152+ * Revision 1.5 1998/10/09 04:32:19 rgb
42153+ * Added 'klips_debug' prefix to all klips printk debug statements.
42154+ *
42155+ * Revision 1.4 1998/08/12 00:11:31 rgb
42156+ * Added new xform functions to the xform table.
42157+ * Fixed minor debug output spelling error.
42158+ *
42159+ * Revision 1.3 1998/07/09 17:45:31 rgb
42160+ * Clarify algorithm not available message.
42161+ *
42162+ * Revision 1.2 1998/06/23 03:00:51 rgb
42163+ * Check for presence of IPIP protocol if it is setup one way (we don't
42164+ * know what has been set up the other way and can only assume it will be
42165+ * symmetrical with the exception of keys).
42166+ *
42167+ * Revision 1.1 1998/06/18 21:27:51 henry
42168+ * move sources from klips/src to klips/net/ipsec, to keep stupid
42169+ * kernel-build scripts happier in the presence of symlinks
42170+ *
42171+ * Revision 1.3 1998/06/11 05:54:59 rgb
42172+ * Added transform version string pointer to xformsw initialisations.
42173+ *
42174+ * Revision 1.2 1998/04/21 21:28:57 rgb
42175+ * Rearrange debug switches to change on the fly debug output from user
42176+ * space. Only kernel changes checked in at this time. radij.c was also
42177+ * changed to temporarily remove buggy debugging code in rj_delete causing
42178+ * an OOPS and hence, netlink device open errors.
42179+ *
42180+ * Revision 1.1 1998/04/09 03:06:13 henry
42181+ * sources moved up from linux/net/ipsec
42182+ *
42183+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
42184+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
42185+ *
42186+ * Revision 0.5 1997/06/03 04:24:48 ji
42187+ * Added ESP-3DES-MD5-96
42188+ *
42189+ * Revision 0.4 1997/01/15 01:28:15 ji
42190+ * Added new transforms.
42191+ *
42192+ * Revision 0.3 1996/11/20 14:39:04 ji
42193+ * Minor cleanups.
42194+ * Rationalized debugging code.
42195+ *
42196+ * Revision 0.2 1996/11/02 00:18:33 ji
42197+ * First limited release.
42198+ *
42199+ *
42200+ */
42201--- /dev/null Tue Mar 11 13:02:56 2003
42202+++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004
42203@@ -0,0 +1,1877 @@
42204+/*
42205+ * IPSEC Transmit code.
42206+ * Copyright (C) 1996, 1997 John Ioannidis.
42207+ * Copyright (C) 1998-2003 Richard Guy Briggs.
42208+ * Copyright (C) 2004-2005 Michael Richardson <mcr@xelerance.com>
42209+ *
42210+ * This program is free software; you can redistribute it and/or modify it
42211+ * under the terms of the GNU General Public License as published by the
42212+ * Free Software Foundation; either version 2 of the License, or (at your
42213+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
42214+ *
42215+ * This program is distributed in the hope that it will be useful, but
42216+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
42217+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
42218+ * for more details.
42219+ */
42220+
42221+char ipsec_xmit_c_version[] = "RCSID $Id: ipsec_xmit.c,v 1.20.2.13 2007-10-30 21:38:56 paul Exp $";
42222+
42223+#define __NO_VERSION__
42224+#include <linux/module.h>
42225+#ifndef AUTOCONF_INCLUDED
42226+#include <linux/config.h>
42227+#endif /* for CONFIG_IP_FORWARD */
42228+#include <linux/version.h>
42229+#include <linux/kernel.h> /* printk() */
42230+
42231+#include "openswan/ipsec_param.h"
42232+
42233+#ifdef MALLOC_SLAB
42234+# include <linux/slab.h> /* kmalloc() */
42235+#else /* MALLOC_SLAB */
42236+# include <linux/malloc.h> /* kmalloc() */
42237+#endif /* MALLOC_SLAB */
42238+#include <linux/errno.h> /* error codes */
42239+#include <linux/types.h> /* size_t */
42240+#include <linux/interrupt.h> /* mark_bh */
42241+
42242+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
42243+#include <linux/etherdevice.h> /* eth_type_trans */
42244+#include <linux/ip.h> /* struct iphdr */
42245+#include <linux/tcp.h> /* struct tcphdr */
42246+#include <linux/udp.h> /* struct udphdr */
42247+#include <linux/skbuff.h>
42248+#include <asm/uaccess.h>
42249+#include <asm/checksum.h>
42250+#include <openswan.h>
42251+#ifdef NET_21
42252+# define MSS_HACK_ /* experimental */
42253+# include <linux/in6.h>
42254+# include <net/dst.h>
42255+# define proto_priv cb
42256+#endif /* NET_21 */
42257+
42258+#include <net/icmp.h> /* icmp_send() */
42259+#include <net/ip.h>
42260+#ifdef NETDEV_23
42261+# include <linux/netfilter_ipv4.h>
42262+#endif /* NETDEV_23 */
42263+
42264+#include <linux/if_arp.h>
42265+#ifdef MSS_HACK
42266+# include <net/tcp.h> /* TCP options */
42267+#endif /* MSS_HACK */
42268+
42269+#include "openswan/radij.h"
42270+#include "openswan/ipsec_life.h"
42271+#include "openswan/ipsec_xform.h"
42272+#include "openswan/ipsec_eroute.h"
42273+#include "openswan/ipsec_encap.h"
42274+#include "openswan/ipsec_radij.h"
42275+#include "openswan/ipsec_xmit.h"
42276+#include "openswan/ipsec_sa.h"
42277+#include "openswan/ipsec_tunnel.h"
42278+#include "openswan/ipsec_ipe4.h"
42279+#include "openswan/ipsec_ah.h"
42280+#include "openswan/ipsec_esp.h"
42281+
42282+#ifdef CONFIG_KLIPS_IPCOMP
42283+#include "openswan/ipcomp.h"
42284+#endif /* CONFIG_KLIPS_IPCOMP */
42285+
42286+#include <pfkeyv2.h>
42287+#include <pfkey.h>
42288+
42289+#include "openswan/ipsec_proto.h"
42290+#include "openswan/ipsec_alg.h"
42291+
42292+
42293+/*
42294+ * Stupid kernel API differences in APIs. Not only do some
42295+ * kernels not have ip_select_ident, but some have differing APIs,
42296+ * and SuSE has one with one parameter, but no way of checking to
42297+ * see what is really what.
42298+ */
42299+
42300+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
42301+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
42302+#else
42303+
42304+/* simplest case, nothing */
42305+#if !defined(IP_SELECT_IDENT)
42306+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
42307+#endif
42308+
42309+/* kernels > 2.3.37-ish */
42310+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
42311+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
42312+#endif
42313+
42314+/* kernels > 2.4.2 */
42315+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
42316+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
42317+#endif
42318+
42319+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
42320+
42321+
42322+
42323+#if defined(CONFIG_KLIPS_AH)
42324+static __u32 zeroes[64];
42325+#endif
42326+
42327+#ifdef CONFIG_KLIPS_DEBUG
42328+int sysctl_ipsec_debug_verbose = 0;
42329+#endif /* CONFIG_KLIPS_DEBUG */
42330+
42331+int ipsec_xmit_trap_count = 0;
42332+int ipsec_xmit_trap_sendcount = 0;
42333+
42334+int sysctl_ipsec_icmp = 0;
42335+int sysctl_ipsec_tos = 0;
42336+
42337+#ifdef CONFIG_KLIPS_DEBUG
42338+#define dmp(_x,_y,_z) if(debug_tunnel) ipsec_dmp_block(_x,_y,_z)
42339+#else /* CONFIG_KLIPS_DEBUG */
42340+#define dmp(_x, _y, _z)
42341+#endif /* CONFIG_KLIPS_DEBUG */
42342+
42343+
42344+#if !defined(SKB_COPY_EXPAND) || defined(KLIPS_UNIT_TESTS)
42345+/*
42346+ * This is mostly skbuff.c:skb_copy().
42347+ */
42348+struct sk_buff *
42349+skb_copy_expand(const struct sk_buff *skb, int headroom,
42350+ int tailroom, int priority)
42351+{
42352+ struct sk_buff *n;
42353+ unsigned long offset;
42354+
42355+ /*
42356+ * Do sanity checking
42357+ */
42358+ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
42359+ printk(KERN_WARNING
42360+ "klips_error:skb_copy_expand: "
42361+ "Illegal negative head,tailroom %d,%d\n",
42362+ headroom,
42363+ tailroom);
42364+ return NULL;
42365+ }
42366+ /*
42367+ * Allocate the copy buffer
42368+ */
42369+
42370+#ifndef NET_21
42371+ IS_SKB(skb);
42372+#endif /* !NET_21 */
42373+
42374+
42375+ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
42376+
42377+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42378+ "klips_debug:skb_copy_expand: "
42379+ "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
42380+ skb->end - skb->head + headroom + tailroom,
42381+ skb->head,
42382+ skb->data,
42383+ skb->tail,
42384+ skb->end,
42385+ skb->end - skb->head,
42386+ skb->tail - skb->data);
42387+
42388+ if(n==NULL)
42389+ return NULL;
42390+
42391+ /*
42392+ * Shift between the two data areas in bytes
42393+ */
42394+
42395+ /* Set the data pointer */
42396+ skb_reserve(n,skb->data-skb->head+headroom);
42397+ /* Set the tail pointer and length */
42398+ if(skb_tailroom(n) < skb->len) {
42399+ printk(KERN_WARNING "klips_error:skb_copy_expand: "
42400+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
42401+ (unsigned long int)skb->len,
42402+ skb_tailroom(n));
42403+ ipsec_kfree_skb(n);
42404+ return NULL;
42405+ }
42406+ skb_put(n,skb->len);
42407+
42408+ offset=n->head + headroom - skb->head;
42409+
42410+ /* Copy the bytes */
42411+ memcpy(n->head + headroom, skb->head,skb->end-skb->head);
42412+#ifdef NET_21
42413+ n->csum=skb->csum;
42414+ n->priority=skb->priority;
42415+ n->dst=dst_clone(skb->dst);
42416+ if(skb->nh.raw)
42417+ n->nh.raw=skb->nh.raw+offset;
42418+#ifndef NETDEV_23
42419+ n->is_clone=0;
42420+#endif /* NETDEV_23 */
42421+ atomic_set(&n->users, 1);
42422+ n->destructor = NULL;
42423+#ifdef HAVE_SOCK_SECURITY
42424+ n->security=skb->security;
42425+#endif
42426+#else /* NET_21 */
42427+ n->link3=NULL;
42428+ n->when=skb->when;
42429+ if(skb->ip_hdr)
42430+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
42431+ n->saddr=skb->saddr;
42432+ n->daddr=skb->daddr;
42433+ n->raddr=skb->raddr;
42434+ n->seq=skb->seq;
42435+ n->end_seq=skb->end_seq;
42436+ n->ack_seq=skb->ack_seq;
42437+ n->acked=skb->acked;
42438+ n->free=1;
42439+ n->arp=skb->arp;
42440+ n->tries=0;
42441+ n->lock=0;
42442+ n->users=0;
42443+#endif /* NET_21 */
42444+ n->protocol=skb->protocol;
42445+ n->list=NULL;
42446+ n->sk=NULL;
42447+ n->dev=skb->dev;
42448+ if(skb->h.raw)
42449+ n->h.raw=skb->h.raw+offset;
42450+ if(skb->mac.raw)
42451+ n->mac.raw=skb->mac.raw+offset;
42452+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
42453+#ifndef NETDEV_23
42454+ n->used=skb->used;
42455+#endif /* !NETDEV_23 */
42456+ n->pkt_type=skb->pkt_type;
42457+ n->stamp=skb->stamp;
42458+
42459+#ifndef NET_21
42460+ IS_SKB(n);
42461+#endif /* !NET_21 */
42462+ return n;
42463+}
42464+#endif /* !SKB_COPY_EXPAND */
42465+
42466+#ifdef CONFIG_KLIPS_DEBUG
42467+void
42468+ipsec_print_ip(struct iphdr *ip)
42469+{
42470+ char buf[ADDRTOA_BUF];
42471+
42472+ printk(KERN_INFO "klips_debug: IP:");
42473+ printk(" ihl:%d", ip->ihl << 2);
42474+ printk(" ver:%d", ip->version);
42475+ printk(" tos:%d", ip->tos);
42476+ printk(" tlen:%d", ntohs(ip->tot_len));
42477+ printk(" id:%d", ntohs(ip->id));
42478+ printk(" %s%s%sfrag_off:%d",
42479+ ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
42480+ ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
42481+ ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
42482+ (ntohs(ip->frag_off) & IP_OFFSET) << 3);
42483+ printk(" ttl:%d", ip->ttl);
42484+ printk(" proto:%d", ip->protocol);
42485+ if(ip->protocol == IPPROTO_UDP)
42486+ printk(" (UDP)");
42487+ if(ip->protocol == IPPROTO_TCP)
42488+ printk(" (TCP)");
42489+ if(ip->protocol == IPPROTO_ICMP)
42490+ printk(" (ICMP)");
42491+ if(ip->protocol == IPPROTO_ESP)
42492+ printk(" (ESP)");
42493+ if(ip->protocol == IPPROTO_AH)
42494+ printk(" (AH)");
42495+ if(ip->protocol == IPPROTO_COMP)
42496+ printk(" (COMP)");
42497+ printk(" chk:%d", ntohs(ip->check));
42498+ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
42499+ printk(" saddr:%s", buf);
42500+ if(ip->protocol == IPPROTO_UDP)
42501+ printk(":%d",
42502+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
42503+ if(ip->protocol == IPPROTO_TCP)
42504+ printk(":%d",
42505+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
42506+ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
42507+ printk(" daddr:%s", buf);
42508+ if(ip->protocol == IPPROTO_UDP)
42509+ printk(":%d",
42510+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
42511+ if(ip->protocol == IPPROTO_TCP)
42512+ printk(":%d",
42513+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
42514+ if(ip->protocol == IPPROTO_ICMP)
42515+ printk(" type:code=%d:%d",
42516+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
42517+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
42518+ printk("\n");
42519+
42520+ if(sysctl_ipsec_debug_verbose) {
42521+ __u8 *c;
42522+ int len = ntohs(ip->tot_len) - ip->ihl*4;
42523+
42524+ c = ((__u8*)ip) + ip->ihl*4;
42525+ ipsec_dmp_block("ip_print", c, len);
42526+ }
42527+}
42528+#endif /* CONFIG_KLIPS_DEBUG */
42529+
42530+#ifdef MSS_HACK
42531+/*
42532+ * Issues:
42533+ * 1) Fragments arriving in the tunnel should probably be rejected.
42534+ * 2) How does this affect syncookies, mss_cache, dst cache ?
42535+ * 3) Path MTU discovery handling needs to be reviewed. For example,
42536+ * if we receive an ICMP 'packet too big' message from an intermediate
42537+ * router specifying it's next hop MTU, our stack may process this and
42538+ * adjust the MSS without taking our AH/ESP overheads into account.
42539+ */
42540+
42541+
42542+/*
42543+ * Recaclulate checksum using differences between changed datum,
42544+ * borrowed from netfilter.
42545+ */
42546+DEBUG_NO_STATIC u_int16_t
42547+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
42548+{
42549+ u_int32_t diffs[] = { oldvalinv, newval };
42550+ return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
42551+ oldcheck^0xFFFF));
42552+}
42553+
42554+/*
42555+ * Determine effective MSS.
42556+ *
42557+ * Note that we assume that there is always an MSS option for our own
42558+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
42559+ * This could change, and we should probably parse TCP options instead.
42560+ *
42561+ */
42562+DEBUG_NO_STATIC u_int8_t
42563+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
42564+{
42565+ u_int16_t oldmss, newmss;
42566+ u_int32_t *mssp;
42567+ struct sock *sk = skb->sk;
42568+
42569+ newmss = tcp_sync_mss(sk, mtu);
42570+ printk(KERN_INFO "klips: setting mss to %u\n", newmss);
42571+ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
42572+ oldmss = ntohl(*mssp) & 0x0000FFFF;
42573+ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
42574+ tcph->check = ipsec_fast_csum(htons(~oldmss),
42575+ htons(newmss), tcph->check);
42576+ return 1;
42577+}
42578+#endif /* MSS_HACK */
42579+
42580+/*
42581+ * Sanity checks
42582+ */
42583+enum ipsec_xmit_value
42584+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs)
42585+{
42586+
42587+ if (ixs->dev == NULL) {
42588+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42589+ "klips_error:ipsec_xmit_sanity_check_dev: "
42590+ "No device associated with skb!\n" );
42591+ return IPSEC_XMIT_NODEV;
42592+ }
42593+
42594+ ixs->prv = ixs->dev->priv;
42595+ if (ixs->prv == NULL) {
42596+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42597+ "klips_error:ipsec_xmit_sanity_check_dev: "
42598+ "Device has no private structure!\n" );
42599+ return IPSEC_XMIT_NOPRIVDEV;
42600+ }
42601+
42602+ ixs->physdev = ixs->prv->dev;
42603+ if (ixs->physdev == NULL) {
42604+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42605+ "klips_error:ipsec_xmit_sanity_check_dev: "
42606+ "Device is not attached to physical device!\n" );
42607+ return IPSEC_XMIT_NOPHYSDEV;
42608+ }
42609+
42610+ ixs->physmtu = ixs->physdev->mtu;
42611+ ixs->cur_mtu = ixs->physdev->mtu;
42612+ ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);
42613+
42614+ return IPSEC_XMIT_OK;
42615+}
42616+
42617+enum ipsec_xmit_value
42618+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs)
42619+{
42620+ /*
42621+ * Return if there is nothing to do. (Does this ever happen?) XXX
42622+ */
42623+ if (ixs->skb == NULL) {
42624+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42625+ "klips_error:ipsec_xmit_sanity_check_skb: "
42626+ "Nothing to do!\n" );
42627+ return IPSEC_XMIT_NOSKB;
42628+ }
42629+
42630+ /* if skb was cloned (most likely due to a packet sniffer such as
42631+ tcpdump being momentarily attached to the interface), make
42632+ a copy of our own to modify */
42633+ if(skb_cloned(ixs->skb)) {
42634+ if
42635+#ifdef SKB_COW_NEW
42636+ (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0)
42637+#else /* SKB_COW_NEW */
42638+ ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL)
42639+#endif /* SKB_COW_NEW */
42640+ {
42641+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42642+ "klips_error:ipsec_xmit_sanity_check_skb: "
42643+ "skb_cow failed to allocate buffer, dropping.\n" );
42644+ ixs->stats->tx_dropped++;
42645+ return IPSEC_XMIT_ERRSKBALLOC;
42646+ }
42647+ }
42648+
42649+ ixs->iph = ip_hdr(ixs->skb);
42650+
42651+ /* sanity check for IP version as we can't handle IPv6 right now */
42652+ if (ixs->iph->version != 4) {
42653+ KLIPS_PRINT(debug_tunnel,
42654+ "klips_debug:ipsec_xmit_sanity_check_skb: "
42655+ "found IP Version %d but cannot process other IP versions than v4.\n",
42656+ ixs->iph->version); /* XXX */
42657+ ixs->stats->tx_dropped++;
42658+ return IPSEC_XMIT_NOIPV6;
42659+ }
42660+
42661+#if IPSEC_DISALLOW_IPOPTIONS
42662+ if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) {
42663+ KLIPS_PRINT(debug_tunnel,
42664+ "klips_debug:ipsec_xmit_sanity_check_skb: "
42665+ "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */
42666+ ixs->stats->tx_dropped++;
42667+ return IPSEC_XMIT_NOIPOPTIONS;
42668+ }
42669+#endif /* IPSEC_DISALLOW_IPOPTIONS */
42670+
42671+#ifndef NET_21
42672+ if (ixs->iph->ttl <= 0) {
42673+ /* Tell the sender its packet died... */
42674+ ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev);
42675+
42676+ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: "
42677+ "TTL=0, too many hops!\n");
42678+ ixs->stats->tx_dropped++;
42679+ return IPSEC_XMIT_TTLEXPIRED;
42680+ }
42681+#endif /* !NET_21 */
42682+
42683+ return IPSEC_XMIT_OK;
42684+}
42685+
42686+enum ipsec_xmit_value
42687+ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs)
42688+{
42689+#ifdef CONFIG_KLIPS_ESP
42690+ struct esphdr *espp;
42691+ unsigned char *idat, *pad;
42692+ int authlen = 0, padlen = 0, i;
42693+#endif /* !CONFIG_KLIPS_ESP */
42694+#ifdef CONFIG_KLIPS_AH
42695+ struct iphdr ipo;
42696+ struct ahhdr *ahp;
42697+#endif /* CONFIG_KLIPS_AH */
42698+#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
42699+ union {
42700+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42701+ MD5_CTX md5;
42702+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42703+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42704+ SHA1_CTX sha1;
42705+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42706+ } tctx;
42707+ __u8 hash[AH_AMAX];
42708+#endif /* defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMACn_SHA1) */
42709+ int headroom = 0, tailroom = 0, ilen = 0, len = 0;
42710+ unsigned char *dat;
42711+ int blocksize = 8; /* XXX: should be inside ixs --jjo */
42712+ struct ipsec_alg_enc *ixt_e = NULL;
42713+ struct ipsec_alg_auth *ixt_a = NULL;
42714+
42715+ ixs->iphlen = ixs->iph->ihl << 2;
42716+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
42717+ ixs->sa_len = KLIPS_SATOT(debug_tunnel, &ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF);
42718+ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
42719+ "klips_debug:ipsec_xmit_encap_once: "
42720+ "calling output for <%s%s%s>, SA:%s\n",
42721+ IPS_XFORM_NAME(ixs->ipsp),
42722+ ixs->sa_len ? ixs->sa_txt : " (error)");
42723+
42724+ switch(ixs->ipsp->ips_said.proto) {
42725+#ifdef CONFIG_KLIPS_AH
42726+ case IPPROTO_AH:
42727+ headroom += sizeof(struct ahhdr);
42728+ break;
42729+#endif /* CONFIG_KLIPS_AH */
42730+
42731+#ifdef CONFIG_KLIPS_ESP
42732+ case IPPROTO_ESP:
42733+ ixt_e=ixs->ipsp->ips_alg_enc;
42734+ if (ixt_e) {
42735+ blocksize = ixt_e->ixt_common.ixt_blocksize;
42736+ headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
42737+ } else {
42738+ ixs->stats->tx_errors++;
42739+ return IPSEC_XMIT_ESP_BADALG;
42740+ }
42741+
42742+ ixt_a=ixs->ipsp->ips_alg_auth;
42743+ if (ixt_a) {
42744+ tailroom += AHHMAC_HASHLEN;
42745+ authlen = AHHMAC_HASHLEN;
42746+ } else
42747+ switch(ixs->ipsp->ips_authalg) {
42748+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42749+ case AH_MD5:
42750+ authlen = AHHMAC_HASHLEN;
42751+ break;
42752+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42753+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42754+ case AH_SHA:
42755+ authlen = AHHMAC_HASHLEN;
42756+ break;
42757+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42758+ case AH_NONE:
42759+ break;
42760+ default:
42761+ ixs->stats->tx_errors++;
42762+ return IPSEC_XMIT_ESP_BADALG;
42763+ }
42764+ tailroom += blocksize != 1 ?
42765+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
42766+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
42767+ tailroom += authlen;
42768+ break;
42769+#endif /* CONFIG_KLIPS_ESP */
42770+
42771+#ifdef CONFIG_KLIPS_IPIP
42772+ case IPPROTO_IPIP:
42773+ headroom += sizeof(struct iphdr);
42774+ ixs->iphlen = sizeof(struct iphdr);
42775+ break;
42776+#endif /* !CONFIG_KLIPS_IPIP */
42777+
42778+#ifdef CONFIG_KLIPS_IPCOMP
42779+ case IPPROTO_COMP:
42780+ break;
42781+#endif /* CONFIG_KLIPS_IPCOMP */
42782+
42783+ default:
42784+ ixs->stats->tx_errors++;
42785+ return IPSEC_XMIT_BADPROTO;
42786+ }
42787+
42788+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42789+ "klips_debug:ipsec_xmit_encap_once: "
42790+ "pushing %d bytes, putting %d, proto %d.\n",
42791+ headroom, tailroom, ixs->ipsp->ips_said.proto);
42792+ if(skb_headroom(ixs->skb) < headroom) {
42793+ printk(KERN_WARNING
42794+ "klips_error:ipsec_xmit_encap_once: "
42795+ "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n",
42796+ headroom, skb_headroom(ixs->skb));
42797+ ixs->stats->tx_errors++;
42798+ return IPSEC_XMIT_ESP_PUSHPULLERR;
42799+ }
42800+
42801+ dat = skb_push(ixs->skb, headroom);
42802+ ilen = ixs->skb->len - tailroom;
42803+ if(skb_tailroom(ixs->skb) < tailroom) {
42804+ printk(KERN_WARNING
42805+ "klips_error:ipsec_xmit_encap_once: "
42806+ "tried to skb_put %d, %d available. This should never happen, please report.\n",
42807+ tailroom, skb_tailroom(ixs->skb));
42808+ ixs->stats->tx_errors++;
42809+ return IPSEC_XMIT_ESP_PUSHPULLERR;
42810+ }
42811+ skb_put(ixs->skb, tailroom);
42812+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42813+ "klips_debug:ipsec_xmit_encap_once: "
42814+ "head,tailroom: %d,%d before xform.\n",
42815+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
42816+ len = ixs->skb->len;
42817+ if(len > 0xfff0) {
42818+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: "
42819+ "tot_len (%d) > 65520. This should never happen, please report.\n",
42820+ len);
42821+ ixs->stats->tx_errors++;
42822+ return IPSEC_XMIT_BADLEN;
42823+ }
42824+ memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen);
42825+ ixs->iph = (struct iphdr *)dat;
42826+ ixs->iph->tot_len = htons(ixs->skb->len);
42827+
42828+ switch(ixs->ipsp->ips_said.proto) {
42829+#ifdef CONFIG_KLIPS_ESP
42830+ case IPPROTO_ESP:
42831+ espp = (struct esphdr *)(dat + ixs->iphlen);
42832+ espp->esp_spi = ixs->ipsp->ips_said.spi;
42833+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
42834+
42835+ if (!ixt_e) {
42836+ ixs->stats->tx_errors++;
42837+ return IPSEC_XMIT_ESP_BADALG;
42838+ }
42839+
42840+ idat = dat + ixs->iphlen + headroom;
42841+ ilen = len - (ixs->iphlen + headroom + authlen);
42842+
42843+ /* Self-describing padding */
42844+ pad = &dat[len - tailroom];
42845+ padlen = tailroom - 2 - authlen;
42846+ for (i = 0; i < padlen; i++) {
42847+ pad[i] = i + 1;
42848+ }
42849+ dat[len - authlen - 2] = padlen;
42850+
42851+ dat[len - authlen - 1] = ixs->iph->protocol;
42852+ ixs->iph->protocol = IPPROTO_ESP;
42853+#ifdef CONFIG_KLIPS_DEBUG
42854+ if(debug_tunnel & DB_TN_ENCAP) {
42855+ dmp("pre-encrypt", dat, len);
42856+ }
42857+#endif
42858+
42859+ /*
42860+ * Do all operations here:
42861+ * copy IV->ESP, encrypt, update ips IV
42862+ *
42863+ */
42864+ {
42865+ int ret;
42866+ memcpy(espp->esp_iv,
42867+ ixs->ipsp->ips_iv,
42868+ ixs->ipsp->ips_iv_size);
42869+ ret=ipsec_alg_esp_encrypt(ixs->ipsp,
42870+ idat, ilen, espp->esp_iv,
42871+ IPSEC_ALG_ENCRYPT);
42872+
42873+ prng_bytes(&ipsec_prng,
42874+ (char *)ixs->ipsp->ips_iv,
42875+ ixs->ipsp->ips_iv_size);
42876+ }
42877+
42878+ if (ixt_a) {
42879+ ipsec_alg_sa_esp_hash(ixs->ipsp,
42880+ (caddr_t)espp, len - ixs->iphlen - authlen,
42881+ &(dat[len - authlen]), authlen);
42882+
42883+ } else
42884+ switch(ixs->ipsp->ips_authalg) {
42885+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42886+ case AH_MD5:
42887+ dmp("espp", (char*)espp, len - ixs->iphlen - authlen);
42888+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42889+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
42890+ osMD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen);
42891+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
42892+ osMD5Final(hash, &tctx.md5);
42893+ dmp("ictx hash", (char*)&hash, sizeof(hash));
42894+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
42895+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
42896+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
42897+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
42898+ osMD5Final(hash, &tctx.md5);
42899+ dmp("octx hash", (char*)&hash, sizeof(hash));
42900+ memcpy(&(dat[len - authlen]), hash, authlen);
42901+
42902+ /* paranoid */
42903+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
42904+ memset((caddr_t)hash, 0, sizeof(*hash));
42905+ break;
42906+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42907+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42908+ case AH_SHA:
42909+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42910+ SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen);
42911+ SHA1Final(hash, &tctx.sha1);
42912+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
42913+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
42914+ SHA1Final(hash, &tctx.sha1);
42915+ memcpy(&(dat[len - authlen]), hash, authlen);
42916+
42917+ /* paranoid */
42918+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
42919+ memset((caddr_t)hash, 0, sizeof(*hash));
42920+ break;
42921+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42922+ case AH_NONE:
42923+ break;
42924+ default:
42925+ ixs->stats->tx_errors++;
42926+ return IPSEC_XMIT_AH_BADALG;
42927+ }
42928+#ifdef NET_21
42929+ /*ixs->skb->h.raw = (unsigned char*)espp;*/
42930+ skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, espp));
42931+#endif /* NET_21 */
42932+ break;
42933+#endif /* !CONFIG_KLIPS_ESP */
42934+#ifdef CONFIG_KLIPS_AH
42935+ case IPPROTO_AH:
42936+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
42937+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
42938+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
42939+ ahp->ah_rv = 0;
42940+ ahp->ah_nh = ixs->iph->protocol;
42941+ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
42942+ ixs->iph->protocol = IPPROTO_AH;
42943+ dmp("ahp", (char*)ahp, sizeof(*ahp));
42944+
42945+ ipo = *ixs->iph;
42946+ ipo.tos = 0;
42947+ ipo.frag_off = 0;
42948+ ipo.ttl = 0;
42949+ ipo.check = 0;
42950+ dmp("ipo", (char*)&ipo, sizeof(ipo));
42951+
42952+ switch(ixs->ipsp->ips_authalg) {
42953+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42954+ case AH_MD5:
42955+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42956+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
42957+ osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
42958+ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
42959+ osMD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
42960+ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
42961+ osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
42962+ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
42963+ osMD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
42964+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
42965+ osMD5Final(hash, &tctx.md5);
42966+ dmp("ictx hash", (char*)&hash, sizeof(hash));
42967+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
42968+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
42969+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
42970+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
42971+ osMD5Final(hash, &tctx.md5);
42972+ dmp("octx hash", (char*)&hash, sizeof(hash));
42973+
42974+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
42975+
42976+ /* paranoid */
42977+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
42978+ memset((caddr_t)hash, 0, sizeof(*hash));
42979+ break;
42980+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42981+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42982+ case AH_SHA:
42983+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42984+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
42985+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
42986+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
42987+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
42988+ SHA1Final(hash, &tctx.sha1);
42989+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
42990+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
42991+ SHA1Final(hash, &tctx.sha1);
42992+
42993+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
42994+
42995+ /* paranoid */
42996+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
42997+ memset((caddr_t)hash, 0, sizeof(*hash));
42998+ break;
42999+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
43000+ default:
43001+ ixs->stats->tx_errors++;
43002+ return IPSEC_XMIT_AH_BADALG;
43003+ }
43004+#ifdef NET_21
43005+ skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, ahp));
43006+#endif /* NET_21 */
43007+ break;
43008+#endif /* CONFIG_KLIPS_AH */
43009+#ifdef CONFIG_KLIPS_IPIP
43010+ case IPPROTO_IPIP:
43011+ ixs->iph->version = 4;
43012+ switch(sysctl_ipsec_tos) {
43013+ case 0:
43014+#ifdef NET_21
43015+ ixs->iph->tos = ip_hdr(ixs->skb)->tos;
43016+#else /* NET_21 */
43017+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
43018+#endif /* NET_21 */
43019+ break;
43020+ case 1:
43021+ ixs->iph->tos = 0;
43022+ break;
43023+ default:
43024+ break;
43025+ }
43026+ ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
43027+ ixs->iph->frag_off = 0;
43028+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
43029+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
43030+ ixs->iph->protocol = IPPROTO_IPIP;
43031+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
43032+
43033+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
43034+
43035+ ixs->newdst = (__u32)ixs->iph->daddr;
43036+ ixs->newsrc = (__u32)ixs->iph->saddr;
43037+
43038+#ifdef NET_21
43039+ skb_set_transport_header(ixs->skb, ipsec_skb_offset(ixs->skb, ip_hdr(ixs->skb)));
43040+#endif /* NET_21 */
43041+ break;
43042+#endif /* !CONFIG_KLIPS_IPIP */
43043+#ifdef CONFIG_KLIPS_IPCOMP
43044+ case IPPROTO_COMP:
43045+ {
43046+ unsigned int flags = 0;
43047+#ifdef CONFIG_KLIPS_DEBUG
43048+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
43049+#endif /* CONFIG_KLIPS_DEBUG */
43050+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
43051+
43052+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
43053+
43054+#ifdef NET_21
43055+ ixs->iph = ip_hdr(ixs->skb);
43056+#else /* NET_21 */
43057+ ixs->iph = ixs->skb->ip_hdr;
43058+#endif /* NET_21 */
43059+
43060+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
43061+
43062+#ifdef CONFIG_KLIPS_DEBUG
43063+ if (debug_tunnel & DB_TN_CROUT)
43064+ {
43065+ if (old_tot_len > ntohs(ixs->iph->tot_len))
43066+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43067+ "klips_debug:ipsec_xmit_encap_once: "
43068+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
43069+ old_tot_len, ntohs(ixs->iph->tot_len),
43070+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
43071+ ntohl(ixs->ipsp->ips_said.spi),
43072+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
43073+ else
43074+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43075+ "klips_debug:ipsec_xmit_encap_once: "
43076+ "packet did not compress (flags = %d).\n",
43077+ flags);
43078+ }
43079+#endif /* CONFIG_KLIPS_DEBUG */
43080+ }
43081+ break;
43082+#endif /* CONFIG_KLIPS_IPCOMP */
43083+ default:
43084+ ixs->stats->tx_errors++;
43085+ return IPSEC_XMIT_BADPROTO;
43086+ }
43087+
43088+#ifdef NET_21
43089+ skb_set_network_header(ixs->skb, ipsec_skb_offset(ixs->skb, ixs->skb->data));
43090+
43091+#else /* NET_21 */
43092+ ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data;
43093+#endif /* NET_21 */
43094+ ixs->iph->check = 0;
43095+ ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl);
43096+
43097+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43098+ "klips_debug:ipsec_xmit_encap_once: "
43099+ "after <%s%s%s>, SA:%s:\n",
43100+ IPS_XFORM_NAME(ixs->ipsp),
43101+ ixs->sa_len ? ixs->sa_txt : " (error)");
43102+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
43103+
43104+ ixs->ipsp->ips_life.ipl_bytes.ipl_count += len;
43105+ ixs->ipsp->ips_life.ipl_bytes.ipl_last = len;
43106+
43107+ if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) {
43108+ ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
43109+ }
43110+ ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
43111+ ixs->ipsp->ips_life.ipl_packets.ipl_count++;
43112+
43113+ ixs->ipsp = ixs->ipsp->ips_onext;
43114+
43115+ return IPSEC_XMIT_OK;
43116+}
43117+
43118+/*
43119+ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
43120+ * source and destination ports to those from the TCP/UDP header.
43121+ */
43122+void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
43123+{
43124+ struct udphdr *udp;
43125+
43126+ switch (iph->protocol) {
43127+ case IPPROTO_UDP:
43128+ case IPPROTO_TCP:
43129+ /*
43130+ * The ports are at the same offsets in a TCP and UDP
43131+ * header so hack it ...
43132+ */
43133+ udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
43134+ er->sen_sport = udp->source;
43135+ er->sen_dport = udp->dest;
43136+ break;
43137+ default:
43138+ er->sen_sport = 0;
43139+ er->sen_dport = 0;
43140+ break;
43141+ }
43142+}
43143+
43144+/*
43145+ * A TRAP eroute is installed and we want to replace it with a HOLD
43146+ * eroute.
43147+ */
43148+static int create_hold_eroute(struct eroute *origtrap,
43149+ struct sk_buff * skb, struct iphdr * iph,
43150+ uint32_t eroute_pid)
43151+{
43152+ struct eroute hold_eroute;
43153+ ip_said hold_said;
43154+ struct sk_buff *first, *last;
43155+ int error;
43156+
43157+ first = last = NULL;
43158+ memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
43159+ memset((caddr_t)&hold_said, 0, sizeof(hold_said));
43160+
43161+ hold_said.proto = IPPROTO_INT;
43162+ hold_said.spi = htonl(SPI_HOLD);
43163+ hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
43164+
43165+ hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
43166+ hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
43167+ hold_eroute.er_eaddr.sen_family = AF_ENCAP;
43168+ hold_eroute.er_emask.sen_family = AF_ENCAP;
43169+ hold_eroute.er_eaddr.sen_type = SENT_IP4;
43170+ hold_eroute.er_emask.sen_type = 255;
43171+
43172+ hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
43173+ hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
43174+ hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
43175+ hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
43176+ hold_eroute.er_emask.sen_sport = 0;
43177+ hold_eroute.er_emask.sen_dport = 0;
43178+ hold_eroute.er_pid = eroute_pid;
43179+ hold_eroute.er_count = 0;
43180+ hold_eroute.er_lasttime = jiffies/HZ;
43181+
43182+ /*
43183+ * if it wasn't captured by a wildcard, then don't record it as
43184+ * a wildcard.
43185+ */
43186+ if(origtrap->er_eaddr.sen_proto != 0) {
43187+ hold_eroute.er_eaddr.sen_proto = iph->protocol;
43188+
43189+ if((iph->protocol == IPPROTO_TCP ||
43190+ iph->protocol == IPPROTO_UDP) &&
43191+ (origtrap->er_eaddr.sen_sport != 0 ||
43192+ origtrap->er_eaddr.sen_dport != 0)) {
43193+
43194+ if(origtrap->er_eaddr.sen_sport != 0)
43195+ hold_eroute.er_emask.sen_sport = ~0;
43196+
43197+ if(origtrap->er_eaddr.sen_dport != 0)
43198+ hold_eroute.er_emask.sen_dport = ~0;
43199+
43200+ ipsec_extract_ports(iph, &hold_eroute.er_eaddr);
43201+ }
43202+ }
43203+
43204+#ifdef CONFIG_KLIPS_DEBUG
43205+ if (debug_pfkey) {
43206+ char buf1[64], buf2[64];
43207+ subnettoa(hold_eroute.er_eaddr.sen_ip_src,
43208+ hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
43209+ subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
43210+ hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
43211+ KLIPS_PRINT(debug_pfkey,
43212+ "klips_debug:ipsec_tunnel_start_xmit: "
43213+ "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
43214+ buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
43215+ buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
43216+ hold_eroute.er_eaddr.sen_proto);
43217+ }
43218+#endif /* CONFIG_KLIPS_DEBUG */
43219+
43220+ if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
43221+ &first, &last)) {
43222+ KLIPS_PRINT(debug_pfkey,
43223+ "klips_debug:ipsec_tunnel_start_xmit: "
43224+ "HOLD breakeroute found nothing.\n");
43225+ } else {
43226+ KLIPS_PRINT(debug_pfkey,
43227+ "klips_debug:ipsec_tunnel_start_xmit: "
43228+ "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
43229+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
43230+ ntohs(hold_eroute.er_eaddr.sen_sport),
43231+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
43232+ ntohs(hold_eroute.er_eaddr.sen_dport),
43233+ hold_eroute.er_eaddr.sen_proto);
43234+ }
43235+ if (first != NULL)
43236+ kfree_skb(first);
43237+ if (last != NULL)
43238+ kfree_skb(last);
43239+
43240+ error = ipsec_makeroute(&(hold_eroute.er_eaddr),
43241+ &(hold_eroute.er_emask),
43242+ hold_said, eroute_pid, skb, NULL, NULL);
43243+ if (error) {
43244+ KLIPS_PRINT(debug_pfkey,
43245+ "klips_debug:ipsec_tunnel_start_xmit: "
43246+ "HOLD makeroute returned %d, failed.\n", error);
43247+ } else {
43248+ KLIPS_PRINT(debug_pfkey,
43249+ "klips_debug:ipsec_tunnel_start_xmit: "
43250+ "HOLD makeroute call successful.\n");
43251+ }
43252+ return (error == 0);
43253+}
43254+
43255+/*
43256+ * upon entry to this function, ixs->skb should be setup
43257+ * as follows:
43258+ *
43259+ * data = beginning of IP packet <- differs from ipsec_rcv().
43260+ * nh.raw = beginning of IP packet.
43261+ * h.raw = data after the IP packet.
43262+ *
43263+ */
43264+enum ipsec_xmit_value
43265+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs)
43266+{
43267+#ifdef CONFIG_KLIPS_ALG
43268+ struct ipsec_alg_enc *ixt_e = NULL;
43269+ struct ipsec_alg_auth *ixt_a = NULL;
43270+ int blocksize = 8;
43271+#endif
43272+ enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK;
43273+
43274+ ixs->newdst = ixs->orgdst = ixs->iph->daddr;
43275+ ixs->newsrc = ixs->orgsrc = ixs->iph->saddr;
43276+ ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr;
43277+ ixs->iphlen = ixs->iph->ihl << 2;
43278+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
43279+ ixs->max_headroom = ixs->max_tailroom = 0;
43280+
43281+ if (ixs->outgoing_said.proto == IPPROTO_INT) {
43282+ switch (ntohl(ixs->outgoing_said.spi)) {
43283+ case SPI_DROP:
43284+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43285+ "klips_debug:ipsec_xmit_encap_bundle: "
43286+ "shunt SA of DROP or no eroute: dropping.\n");
43287+ ixs->stats->tx_dropped++;
43288+ break;
43289+
43290+ case SPI_REJECT:
43291+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43292+ "klips_debug:ipsec_xmit_encap_bundle: "
43293+ "shunt SA of REJECT: notifying and dropping.\n");
43294+ ICMP_SEND(ixs->skb,
43295+ ICMP_DEST_UNREACH,
43296+ ICMP_PKT_FILTERED,
43297+ 0,
43298+ ixs->physdev);
43299+ ixs->stats->tx_dropped++;
43300+ break;
43301+
43302+ case SPI_PASS:
43303+#ifdef NET_21
43304+ ixs->pass = 1;
43305+#endif /* NET_21 */
43306+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43307+ "klips_debug:ipsec_xmit_encap_bundle: "
43308+ "PASS: calling dev_queue_xmit\n");
43309+ return IPSEC_XMIT_PASS;
43310+ goto cleanup;
43311+
43312+ case SPI_HOLD:
43313+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43314+ "klips_debug:ipsec_xmit_encap_bundle: "
43315+ "shunt SA of HOLD: this does not make sense here, dropping.\n");
43316+ ixs->stats->tx_dropped++;
43317+ break;
43318+
43319+ case SPI_TRAP:
43320+ case SPI_TRAPSUBNET:
43321+ {
43322+ struct sockaddr_in src, dst;
43323+#ifdef CONFIG_KLIPS_DEBUG
43324+ char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
43325+#endif /* CONFIG_KLIPS_DEBUG */
43326+
43327+ /* Signal all listening KMds with a PF_KEY ACQUIRE */
43328+
43329+ memset(&src, 0, sizeof(src));
43330+ memset(&dst, 0, sizeof(dst));
43331+ src.sin_family = AF_INET;
43332+ dst.sin_family = AF_INET;
43333+ src.sin_addr.s_addr = ixs->iph->saddr;
43334+ dst.sin_addr.s_addr = ixs->iph->daddr;
43335+
43336+ ixs->ips.ips_transport_protocol = 0;
43337+ src.sin_port = 0;
43338+ dst.sin_port = 0;
43339+
43340+ if(ixs->eroute->er_eaddr.sen_proto != 0) {
43341+ ixs->ips.ips_transport_protocol = ixs->iph->protocol;
43342+
43343+ if(ixs->eroute->er_eaddr.sen_sport != 0) {
43344+ src.sin_port =
43345+ (ixs->iph->protocol == IPPROTO_UDP
43346+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source
43347+ : (ixs->iph->protocol == IPPROTO_TCP
43348+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source
43349+ : 0));
43350+ }
43351+ if(ixs->eroute->er_eaddr.sen_dport != 0) {
43352+ dst.sin_port =
43353+ (ixs->iph->protocol == IPPROTO_UDP
43354+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest
43355+ : (ixs->iph->protocol == IPPROTO_TCP
43356+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest
43357+ : 0));
43358+ }
43359+ }
43360+
43361+ ixs->ips.ips_addr_s = (struct sockaddr*)(&src);
43362+ ixs->ips.ips_addr_d = (struct sockaddr*)(&dst);
43363+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43364+ "klips_debug:ipsec_xmit_encap_bundle: "
43365+ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
43366+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
43367+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port),
43368+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
43369+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port),
43370+ ixs->ips.ips_said.proto);
43371+
43372+ /* increment count of total traps needed */
43373+ ipsec_xmit_trap_count++;
43374+
43375+ if (pfkey_acquire(&ixs->ips) == 0) {
43376+
43377+ /* note that we succeeded */
43378+ ipsec_xmit_trap_sendcount++;
43379+
43380+ if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
43381+ /*
43382+ * The spinlock is to prevent any other
43383+ * process from accessing or deleting
43384+ * the eroute while we are using and
43385+ * updating it.
43386+ */
43387+ spin_lock(&eroute_lock);
43388+ ixs->eroute = ipsec_findroute(&ixs->matcher);
43389+ if(ixs->eroute) {
43390+ ixs->eroute->er_said.spi = htonl(SPI_HOLD);
43391+ ixs->eroute->er_first = ixs->skb;
43392+ ixs->skb = NULL;
43393+ }
43394+ spin_unlock(&eroute_lock);
43395+ } else if (create_hold_eroute(ixs->eroute,
43396+ ixs->skb,
43397+ ixs->iph,
43398+ ixs->eroute_pid)) {
43399+ ixs->skb = NULL;
43400+ }
43401+ /* whether or not the above succeeded, we continue */
43402+
43403+ }
43404+ ixs->stats->tx_dropped++;
43405+ }
43406+ default:
43407+ /* XXX what do we do with an unknown shunt spi? */
43408+ break;
43409+ } /* switch (ntohl(ixs->outgoing_said.spi)) */
43410+ return IPSEC_XMIT_STOLEN;
43411+ } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */
43412+
43413+ /*
43414+ The spinlock is to prevent any other process from
43415+ accessing or deleting the ipsec_sa hash table or any of the
43416+ ipsec_sa s while we are using and updating them.
43417+
43418+ This is not optimal, but was relatively straightforward
43419+ at the time. A better way to do it has been planned for
43420+ more than a year, to lock the hash table and put reference
43421+ counts on each ipsec_sa instead. This is not likely to happen
43422+ in KLIPS1 unless a volunteer contributes it, but will be
43423+ designed into KLIPS2.
43424+ */
43425+ spin_lock(&tdb_lock);
43426+
43427+ ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said);
43428+ ixs->sa_len = KLIPS_SATOT(debug_tunnel, &ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
43429+
43430+ if (ixs->ipsp == NULL) {
43431+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43432+ "klips_debug:ipsec_xmit_encap_bundle: "
43433+ "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
43434+ ixs->sa_len ? ixs->sa_txt : " (error)");
43435+ if(ixs->stats) {
43436+ ixs->stats->tx_dropped++;
43437+ }
43438+ bundle_stat = IPSEC_XMIT_SAIDNOTFOUND;
43439+ goto cleanup;
43440+ }
43441+
43442+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43443+ "klips_debug:ipsec_xmit_encap_bundle: "
43444+ "found ipsec_sa -- SA:<%s%s%s> %s\n",
43445+ IPS_XFORM_NAME(ixs->ipsp),
43446+ ixs->sa_len ? ixs->sa_txt : " (error)");
43447+
43448+ /*
43449+ * How much headroom do we need to be able to apply
43450+ * all the grouped transforms?
43451+ */
43452+ ixs->ipsq = ixs->ipsp; /* save the head of the ipsec_sa chain */
43453+ while (ixs->ipsp) {
43454+ if (debug_tunnel & DB_TN_XMIT) {
43455+ ixs->sa_len = KLIPS_SATOT(debug_tunnel, &ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
43456+ if(ixs->sa_len == 0) {
43457+ strcpy(ixs->sa_txt, "(error)");
43458+ }
43459+ } else {
43460+ *ixs->sa_txt = 0;
43461+ ixs->sa_len = 0;
43462+ }
43463+
43464+ /* If it is in larval state, drop the packet, we cannot process yet. */
43465+ if(ixs->ipsp->ips_state == SADB_SASTATE_LARVAL) {
43466+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43467+ "klips_debug:ipsec_xmit_encap_bundle: "
43468+ "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
43469+ IPS_XFORM_NAME(ixs->ipsp),
43470+ ixs->sa_len ? ixs->sa_txt : " (error)");
43471+ if(ixs->stats) {
43472+ ixs->stats->tx_errors++;
43473+ }
43474+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
43475+ goto cleanup;
43476+ }
43477+
43478+ if(ixs->ipsp->ips_state == SADB_SASTATE_DEAD) {
43479+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43480+ "klips_debug:ipsec_xmit_encap_bundle: "
43481+ "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
43482+ IPS_XFORM_NAME(ixs->ipsp),
43483+ ixs->sa_len ? ixs->sa_txt : " (error)");
43484+ ixs->stats->tx_errors++;
43485+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
43486+ goto cleanup;
43487+ }
43488+
43489+ /* If the replay window counter == -1, expire SA, it will roll */
43490+ if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) {
43491+ pfkey_expire(ixs->ipsp, 1);
43492+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43493+ "klips_debug:ipsec_xmit_encap_bundle: "
43494+ "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
43495+ IPS_XFORM_NAME(ixs->ipsp),
43496+ ixs->sa_len ? ixs->sa_txt : " (error)");
43497+ ipsec_sa_delchain(ixs->ipsp);
43498+ ixs->stats->tx_errors++;
43499+ bundle_stat = IPSEC_XMIT_REPLAYROLLED;
43500+ goto cleanup;
43501+ }
43502+
43503+ /*
43504+ * if this is the first time we are using this SA, mark start time,
43505+ * and offset hard/soft counters by "now" for later checking.
43506+ */
43507+#if 0
43508+ if(ixs->ipsp->ips_life.ipl_usetime.count == 0) {
43509+ ixs->ipsp->ips_life.ipl_usetime.count = jiffies;
43510+ ixs->ipsp->ips_life.ipl_usetime.hard += jiffies;
43511+ ixs->ipsp->ips_life.ipl_usetime.soft += jiffies;
43512+ }
43513+#endif
43514+
43515+
43516+ if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt,
43517+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43518+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt,
43519+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43520+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt,
43521+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43522+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt,
43523+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) {
43524+
43525+ ipsec_sa_delchain(ixs->ipsp);
43526+ ixs->stats->tx_errors++;
43527+ bundle_stat = IPSEC_XMIT_LIFETIMEFAILED;
43528+ goto cleanup;
43529+ }
43530+
43531+
43532+ ixs->headroom = ixs->tailroom = 0;
43533+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43534+ "klips_debug:ipsec_xmit_encap_bundle: "
43535+ "calling room for <%s%s%s>, SA:%s\n",
43536+ IPS_XFORM_NAME(ixs->ipsp),
43537+ ixs->sa_len ? ixs->sa_txt : " (error)");
43538+ switch(ixs->ipsp->ips_said.proto) {
43539+#ifdef CONFIG_KLIPS_AH
43540+ case IPPROTO_AH:
43541+ ixs->headroom += sizeof(struct ahhdr);
43542+ break;
43543+#endif /* CONFIG_KLIPS_AH */
43544+#ifdef CONFIG_KLIPS_ESP
43545+ case IPPROTO_ESP:
43546+ ixt_e=ixs->ipsp->ips_alg_enc;
43547+ if (ixt_e) {
43548+ blocksize = ixt_e->ixt_common.ixt_blocksize;
43549+ ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
43550+ }
43551+ else {
43552+ ixs->stats->tx_errors++;
43553+ bundle_stat = IPSEC_XMIT_ESP_BADALG;
43554+ goto cleanup;
43555+ }
43556+
43557+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
43558+ ixs->tailroom += AHHMAC_HASHLEN;
43559+ } else
43560+ switch(ixs->ipsp->ips_authalg) {
43561+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
43562+ case AH_MD5:
43563+ ixs->tailroom += AHHMAC_HASHLEN;
43564+ break;
43565+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
43566+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
43567+ case AH_SHA:
43568+ ixs->tailroom += AHHMAC_HASHLEN;
43569+ break;
43570+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
43571+ case AH_NONE:
43572+ break;
43573+ default:
43574+ ixs->stats->tx_errors++;
43575+ bundle_stat = IPSEC_XMIT_AH_BADALG;
43576+ goto cleanup;
43577+ }
43578+ ixs->tailroom += blocksize != 1 ?
43579+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
43580+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
43581+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
43582+ if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) {
43583+ ixs->natt_type = ixs->ipsp->ips_natt_type;
43584+ ixs->natt_sport = ixs->ipsp->ips_natt_sport;
43585+ ixs->natt_dport = ixs->ipsp->ips_natt_dport;
43586+ switch (ixs->natt_type) {
43587+ case ESPINUDP_WITH_NON_IKE:
43588+ ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32));
43589+ break;
43590+
43591+ case ESPINUDP_WITH_NON_ESP:
43592+ ixs->natt_head = sizeof(struct udphdr);
43593+ break;
43594+
43595+ default:
43596+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT
43597+ , "klips_xmit: invalid nat-t type %d"
43598+ , ixs->natt_type);
43599+ bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;
43600+ goto cleanup;
43601+
43602+ break;
43603+ }
43604+ ixs->tailroom += ixs->natt_head;
43605+ }
43606+#endif
43607+ break;
43608+#endif /* !CONFIG_KLIPS_ESP */
43609+#ifdef CONFIG_KLIPS_IPIP
43610+ case IPPROTO_IPIP:
43611+ ixs->headroom += sizeof(struct iphdr);
43612+ break;
43613+#endif /* !CONFIG_KLIPS_IPIP */
43614+ case IPPROTO_COMP:
43615+#ifdef CONFIG_KLIPS_IPCOMP
43616+ /*
43617+ We can't predict how much the packet will
43618+ shrink without doing the actual compression.
43619+ We could do it here, if we were the first
43620+ encapsulation in the chain. That might save
43621+ us a skb_copy_expand, since we might fit
43622+ into the existing skb then. However, this
43623+ would be a bit unclean (and this hack has
43624+ bit us once), so we better not do it. After
43625+ all, the skb_copy_expand is cheap in
43626+ comparison to the actual compression.
43627+ At least we know the packet will not grow.
43628+ */
43629+ break;
43630+#endif /* CONFIG_KLIPS_IPCOMP */
43631+ default:
43632+ ixs->stats->tx_errors++;
43633+ bundle_stat = IPSEC_XMIT_BADPROTO;
43634+ goto cleanup;
43635+ }
43636+ ixs->ipsp = ixs->ipsp->ips_onext;
43637+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43638+ "klips_debug:ipsec_xmit_encap_bundle: "
43639+ "Required head,tailroom: %d,%d\n",
43640+ ixs->headroom, ixs->tailroom);
43641+ ixs->max_headroom += ixs->headroom;
43642+ ixs->max_tailroom += ixs->tailroom;
43643+ ixs->pyldsz += (ixs->headroom + ixs->tailroom);
43644+ }
43645+ ixs->ipsp = ixs->ipsq; /* restore the head of the ipsec_sa chain */
43646+
43647+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43648+ "klips_debug:ipsec_xmit_encap_bundle: "
43649+ "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
43650+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb),
43651+ ixs->max_headroom, ixs->max_tailroom);
43652+
43653+ ixs->tot_headroom += ixs->max_headroom;
43654+ ixs->tot_tailroom += ixs->max_tailroom;
43655+
43656+ ixs->mtudiff = ixs->cur_mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;
43657+
43658+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43659+ "klips_debug:ipsec_xmit_encap_bundle: "
43660+ "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
43661+ ixs->cur_mtu, ixs->physmtu,
43662+ ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));
43663+ if(ixs->cur_mtu == 0 || ixs->mtudiff > 0) {
43664+ int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);
43665+
43666+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43667+ "klips_info:ipsec_xmit_encap_bundle: "
43668+ "dev %s mtu of %d decreased by %d to %d\n",
43669+ ixs->dev ? ixs->dev->name : "ifX",
43670+ ixs->cur_mtu,
43671+ ixs->cur_mtu - newmtu,
43672+ newmtu);
43673+ ixs->cur_mtu = newmtu;
43674+
43675+ /* this would seem to adjust the MTU of the route as well */
43676+#if 0
43677+ ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */
43678+#endif /* 0 */
43679+ }
43680+
43681+ /*
43682+ If the sender is doing PMTU discovery, and the
43683+ packet doesn't fit within ixs->prv->mtu, notify him
43684+ (unless it was an ICMP packet, or it was not the
43685+ zero-offset packet) and send it anyways.
43686+
43687+ Note: buggy firewall configuration may prevent the
43688+ ICMP packet from getting back.
43689+ */
43690+ if(sysctl_ipsec_icmp
43691+ && ixs->cur_mtu < ntohs(ixs->iph->tot_len)
43692+ && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {
43693+ int notify = ixs->iph->protocol != IPPROTO_ICMP
43694+ && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
43695+
43696+#ifdef IPSEC_obey_DF
43697+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43698+ "klips_debug:ipsec_xmit_encap_bundle: "
43699+ "fragmentation needed and DF set; %sdropping packet\n",
43700+ notify ? "sending ICMP and " : "");
43701+ if (notify)
43702+ ICMP_SEND(ixs->skb,
43703+ ICMP_DEST_UNREACH,
43704+ ICMP_FRAG_NEEDED,
43705+ ixs->cur_mtu,
43706+ ixs->physdev);
43707+ ixs->stats->tx_errors++;
43708+ bundle_stat = IPSEC_XMIT_CANNOTFRAG;
43709+ goto cleanup;
43710+#else /* IPSEC_obey_DF */
43711+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43712+ "klips_debug:ipsec_xmit_encap_bundle: "
43713+ "fragmentation needed and DF set; %spassing packet\n",
43714+ notify ? "sending ICMP and " : "");
43715+ if (notify)
43716+ ICMP_SEND(ixs->skb,
43717+ ICMP_DEST_UNREACH,
43718+ ICMP_FRAG_NEEDED,
43719+ ixs->cur_mtu,
43720+ ixs->physdev);
43721+#endif /* IPSEC_obey_DF */
43722+ }
43723+
43724+#ifdef MSS_HACK
43725+ /*
43726+ * If this is a transport mode TCP packet with
43727+ * SYN set, determine an effective MSS based on
43728+ * AH/ESP overheads determined above.
43729+ */
43730+ if (ixs->iph->protocol == IPPROTO_TCP
43731+ && ixs->outgoing_said.proto != IPPROTO_IPIP) {
43732+ struct tcphdr *tcph = ixs->skb->h.th;
43733+ if (tcph->syn && !tcph->ack) {
43734+ if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->cur_mtu)) {
43735+ printk(KERN_WARNING
43736+ "klips_warning:ipsec_xmit_encap_bundle: "
43737+ "ipsec_adjust_mss() failed\n");
43738+ ixs->stats->tx_errors++;
43739+ bundle_stat = IPSEC_XMIT_MSSERR;
43740+ goto cleanup;
43741+ }
43742+ }
43743+ }
43744+#endif /* MSS_HACK */
43745+
43746+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
43747+ if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {
43748+ /**
43749+ * NAT-Traversal and Transport Mode:
43750+ * we need to correct TCP/UDP checksum
43751+ *
43752+ * If we've got NAT-OA, we can fix checksum without recalculation.
43753+ * If we don't we can zero udp checksum.
43754+ */
43755+ __u32 natt_oa = ixs->ipsp->ips_natt_oa ?
43756+ ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
43757+ unsigned int pkt_len = skb_tail_pointer(ixs->skb) - (unsigned char *)ixs->iph;
43758+ __u16 data_len = pkt_len - (ixs->iph->ihl << 2);
43759+ switch (ixs->iph->protocol) {
43760+ case IPPROTO_TCP:
43761+ if (data_len >= sizeof(struct tcphdr)) {
43762+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
43763+ if (natt_oa) {
43764+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
43765+ KLIPS_PRINT(debug_tunnel,
43766+ "klips_debug:ipsec_tunnel_start_xmit: "
43767+ "NAT-T & TRANSPORT: "
43768+ "fix TCP checksum using NAT-OA\n");
43769+ tcp->check = csum_fold(
43770+ csum_partial((unsigned char *)buff, sizeof(buff),
43771+ tcp->check^0xffff));
43772+ }
43773+ else {
43774+ KLIPS_PRINT(debug_tunnel,
43775+ "klips_debug:ipsec_tunnel_start_xmit: "
43776+ "NAT-T & TRANSPORT: do not recalc TCP checksum\n");
43777+ }
43778+ }
43779+ else {
43780+ KLIPS_PRINT(debug_tunnel,
43781+ "klips_debug:ipsec_tunnel_start_xmit: "
43782+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
43783+ }
43784+ break;
43785+ case IPPROTO_UDP:
43786+ if (data_len >= sizeof(struct udphdr)) {
43787+ struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
43788+ if (udp->check == 0) {
43789+ KLIPS_PRINT(debug_tunnel,
43790+ "klips_debug:ipsec_tunnel_start_xmit: "
43791+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
43792+ }
43793+ else if (natt_oa) {
43794+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
43795+ KLIPS_PRINT(debug_tunnel,
43796+ "klips_debug:ipsec_tunnel_start_xmit: "
43797+ "NAT-T & TRANSPORT: "
43798+ "fix UDP checksum using NAT-OA\n");
43799+ udp->check = csum_fold(
43800+ csum_partial((unsigned char *)buff, sizeof(buff),
43801+ udp->check^0xffff));
43802+ }
43803+ else {
43804+ KLIPS_PRINT(debug_tunnel,
43805+ "klips_debug:ipsec_tunnel_start_xmit: "
43806+ "NAT-T & TRANSPORT: zero UDP checksum\n");
43807+ udp->check = 0;
43808+ }
43809+ }
43810+ else {
43811+ KLIPS_PRINT(debug_tunnel,
43812+ "klips_debug:ipsec_tunnel_start_xmit: "
43813+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
43814+ }
43815+ break;
43816+ default:
43817+ KLIPS_PRINT(debug_tunnel,
43818+ "klips_debug:ipsec_tunnel_start_xmit: "
43819+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
43820+ break;
43821+ }
43822+ }
43823+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
43824+
43825+ if(!ixs->hard_header_stripped && ixs->hard_header_len>0) {
43826+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43827+ "klips_debug:ipsec_xmit_encap_bundle: "
43828+ "allocating %d bytes for hardheader.\n",
43829+ ixs->hard_header_len);
43830+ if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {
43831+ printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: "
43832+ "Failed, tried to allocate %d bytes for temp hard_header.\n",
43833+ ixs->hard_header_len);
43834+ ixs->stats->tx_errors++;
43835+ bundle_stat = IPSEC_XMIT_ERRMEMALLOC;
43836+ goto cleanup;
43837+ }
43838+ {
43839+ int i;
43840+ for (i = 0; i < ixs->hard_header_len; i++) {
43841+ ixs->saved_header[i] = ixs->skb->data[i];
43842+ }
43843+ }
43844+ if(ixs->skb->len < ixs->hard_header_len) {
43845+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: "
43846+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
43847+ ixs->hard_header_len, (int)(ixs->skb->len));
43848+ ixs->stats->tx_errors++;
43849+ bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;
43850+ goto cleanup;
43851+ }
43852+ skb_pull(ixs->skb, ixs->hard_header_len);
43853+ ixs->hard_header_stripped = 1;
43854+
43855+/* ixs->iph = (struct iphdr *) (ixs->skb->data); */
43856+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43857+ "klips_debug:ipsec_xmit_encap_bundle: "
43858+ "head,tailroom: %d,%d after hard_header stripped.\n",
43859+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
43860+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);
43861+ } else {
43862+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43863+ "klips_debug:ipsec_xmit_encap_bundle: "
43864+ "hard header already stripped.\n");
43865+ }
43866+
43867+ ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;
43868+
43869+ if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) &&
43870+ (skb_tailroom(ixs->skb) >= ixs->max_tailroom)
43871+#ifndef NET_21
43872+ && ixs->skb->free
43873+#endif /* !NET_21 */
43874+ ) {
43875+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43876+ "klips_debug:ipsec_xmit_encap_bundle: "
43877+ "data fits in existing skb\n");
43878+ } else {
43879+ struct sk_buff* tskb;
43880+
43881+ if(!ixs->oskb) {
43882+ ixs->oskb = ixs->skb;
43883+ }
43884+
43885+ tskb = skb_copy_expand(ixs->skb,
43886+ /* The need for 2 * link layer length here remains unexplained...RGB */
43887+ ixs->max_headroom + 2 * ixs->ll_headroom,
43888+ ixs->max_tailroom,
43889+ GFP_ATOMIC);
43890+
43891+ if(tskb && ixs->skb->sk) {
43892+ skb_set_owner_w(tskb, ixs->skb->sk);
43893+ }
43894+
43895+ if(ixs->skb != ixs->oskb) {
43896+ ipsec_kfree_skb(ixs->skb);
43897+ }
43898+ ixs->skb = tskb;
43899+ if (!ixs->skb) {
43900+ printk(KERN_WARNING
43901+ "klips_debug:ipsec_xmit_encap_bundle: "
43902+ "Failed, tried to allocate %d head and %d tailroom\n",
43903+ ixs->max_headroom, ixs->max_tailroom);
43904+ ixs->stats->tx_errors++;
43905+ bundle_stat = IPSEC_XMIT_ERRSKBALLOC;
43906+ goto cleanup;
43907+ }
43908+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43909+ "klips_debug:ipsec_xmit_encap_bundle: "
43910+ "head,tailroom: %d,%d after allocation\n",
43911+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
43912+ }
43913+#ifdef CONFIG_KLIPS_DEBUG
43914+ if(debug_tunnel & DB_TN_ENCAP) {
43915+ ipsec_print_ip(ixs->iph);
43916+ }
43917+#endif
43918+
43919+ /*
43920+ * Apply grouped transforms to packet
43921+ */
43922+ while (ixs->ipsp) {
43923+ enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK;
43924+
43925+ encap_stat = ipsec_xmit_encap_once(ixs);
43926+#ifdef CONFIG_KLIPS_DEBUG
43927+ if(debug_tunnel & DB_TN_ENCAP) {
43928+ ipsec_print_ip(ixs->iph);
43929+ }
43930+#endif
43931+
43932+ if(encap_stat != IPSEC_XMIT_OK) {
43933+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43934+ "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n",
43935+ encap_stat);
43936+
43937+ bundle_stat = IPSEC_XMIT_ENCAPFAIL;
43938+ goto cleanup;
43939+ }
43940+ }
43941+
43942+ /* we are done with this SA */
43943+ ipsec_sa_put(ixs->ipsp);
43944+
43945+ /* end encapsulation loop here XXX */
43946+ cleanup:
43947+ spin_unlock(&tdb_lock);
43948+ return bundle_stat;
43949+}
43950+
43951+/*
43952+ * $Log: ipsec_xmit.c,v $
43953+ * Revision 1.20.2.13 2007-10-30 21:38:56 paul
43954+ * Use skb_tail_pointer [dhr]
43955+ *
43956+ * Revision 1.20.2.12 2007-10-28 00:26:03 paul
43957+ * Start of fix for 2.6.22+ kernels and skb_tail_pointer()
43958+ *
43959+ * Revision 1.20.2.11 2007/10/22 15:40:45 paul
43960+ * Missing #ifdef CONFIG_KLIPS_ALG [davidm]
43961+ *
43962+ * Revision 1.20.2.10 2007/09/05 02:56:10 paul
43963+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
43964+ * Fixes based on David McCullough patch.
43965+ *
43966+ * Revision 1.20.2.9 2007/07/06 17:18:43 paul
43967+ * Fix for authentication field on sent packets has size equals to zero when
43968+ * using custom auth algorithms. This is bug #811. Patch by "iamscared".
43969+ *
43970+ * Revision 1.20.2.8 2006/10/06 21:39:26 paul
43971+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
43972+ * set. This is defined through autoconf.h which is included through the
43973+ * linux kernel build macros.
43974+ *
43975+ * Revision 1.20.2.7 2006/08/24 03:02:01 paul
43976+ * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
43977+ *
43978+ * Revision 1.20.2.6 2006/07/07 22:09:49 paul
43979+ * From: Bart Trojanowski <bart@xelerance.com>
43980+ * Removing a left over '#else' that split another '#if/#endif' block in two.
43981+ *
43982+ * Revision 1.20.2.5 2006/07/07 15:43:17 paul
43983+ * From: Bart Trojanowski <bart@xelerance.com>
43984+ * improved protocol detection in ipsec_print_ip() -- a debug aid.
43985+ *
43986+ * Revision 1.20.2.4 2006/04/20 16:33:07 mcr
43987+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
43988+ * Fix in-kernel module compilation. Sub-makefiles do not work.
43989+ *
43990+ * Revision 1.20.2.3 2005/11/29 21:52:57 ken
43991+ * Fix for #518 MTU issues
43992+ *
43993+ * Revision 1.20.2.2 2005/11/27 21:41:03 paul
43994+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"in for klips as module.
43995+ *
43996+ * Revision 1.20.2.1 2005/08/27 23:40:00 paul
43997+ * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
43998+ *
43999+ * Revision 1.20 2005/07/12 15:39:27 paul
44000+ * include asm/uaccess.h for VERIFY_WRITE
44001+ *
44002+ * Revision 1.19 2005/05/24 01:02:35 mcr
44003+ * some refactoring/simplification of situation where alg
44004+ * is not found.
44005+ *
44006+ * Revision 1.18 2005/05/23 23:52:33 mcr
44007+ * adjust comments, add additional debugging.
44008+ *
44009+ * Revision 1.17 2005/05/23 22:57:23 mcr
44010+ * removed explicit 3DES support.
44011+ *
44012+ * Revision 1.16 2005/05/21 03:29:15 mcr
44013+ * fixed warning about unused zeroes if AH is off.
44014+ *
44015+ * Revision 1.15 2005/05/20 16:47:59 mcr
44016+ * include asm/checksum.h to get ip_fast_csum macro.
44017+ *
44018+ * Revision 1.14 2005/05/11 01:43:03 mcr
44019+ * removed "poor-man"s OOP in favour of proper C structures.
44020+ *
44021+ * Revision 1.13 2005/04/29 05:10:22 mcr
44022+ * removed from extraenous includes to make unit testing easier.
44023+ *
44024+ * Revision 1.12 2005/04/15 01:28:34 mcr
44025+ * use ipsec_dmp_block.
44026+ *
44027+ * Revision 1.11 2005/01/26 00:50:35 mcr
44028+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
44029+ * and make sure that NAT_TRAVERSAL is set as well to match
44030+ * userspace compiles of code.
44031+ *
44032+ * Revision 1.10 2004/09/13 17:55:21 ken
44033+ * MD5* -> osMD5*
44034+ *
44035+ * Revision 1.9 2004/07/10 19:11:18 mcr
44036+ * CONFIG_IPSEC -> CONFIG_KLIPS.
44037+ *
44038+ * Revision 1.8 2004/04/06 02:49:26 mcr
44039+ * pullup of algo code from alg-branch.
44040+ *
44041+ * Revision 1.7 2004/02/03 03:13:41 mcr
44042+ * mark invalid encapsulation states.
44043+ *
44044+ * Revision 1.6.2.1 2003/12/22 15:25:52 jjo
44045+ * Merged algo-0.8.1-rc11-test1 into alg-branch
44046+ *
44047+ * Revision 1.6 2003/12/10 01:14:27 mcr
44048+ * NAT-traversal patches to KLIPS.
44049+ *
44050+ * Revision 1.5 2003/10/31 02:27:55 mcr
44051+ * pulled up port-selector patches and sa_id elimination.
44052+ *
44053+ * Revision 1.4.4.2 2003/10/29 01:37:39 mcr
44054+ * when creating %hold from %trap, only make the %hold as
44055+ * specific as the %trap was - so if the protocol and ports
44056+ * were wildcards, then the %hold will be too.
44057+ *
44058+ * Revision 1.4.4.1 2003/09/21 13:59:56 mcr
44059+ * pre-liminary X.509 patch - does not yet pass tests.
44060+ *
44061+ * Revision 1.4 2003/06/20 02:28:10 mcr
44062+ * misstype of variable name, not detected by module build.
44063+ *
44064+ * Revision 1.3 2003/06/20 01:42:21 mcr
44065+ * added counters to measure how many ACQUIREs we send to pluto,
44066+ * and how many are successfully sent.
44067+ *
44068+ * Revision 1.2 2003/04/03 17:38:35 rgb
44069+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
44070+ * Normalised coding style.
44071+ * Simplified logic and reduced duplication of code.
44072+ *
44073+ * Revision 1.1 2003/02/12 19:31:23 rgb
44074+ * Refactored from ipsec_tunnel.c
44075+ *
44076+ * Local Variables:
44077+ * c-file-style: "linux"
44078+ * End:
44079+ *
44080+ */
44081--- /dev/null Tue Mar 11 13:02:56 2003
44082+++ linux/net/ipsec/match586.S Mon Feb 9 13:51:03 2004
44083@@ -0,0 +1,357 @@
44084+/* match.s -- Pentium-optimized version of longest_match()
44085+ * Written for zlib 1.1.2
44086+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
44087+ *
44088+ * This is free software; you can redistribute it and/or modify it
44089+ * under the terms of the GNU General Public License.
44090+ */
44091+
44092+#ifndef NO_UNDERLINE
44093+#define match_init _ipcomp_match_init
44094+#define longest_match _ipcomp_longest_match
44095+#else
44096+#define match_init ipcomp_match_init
44097+#define longest_match ipcomp_longest_match
44098+#endif
44099+
44100+#define MAX_MATCH (258)
44101+#define MIN_MATCH (3)
44102+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
44103+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
44104+
44105+/* stack frame offsets */
44106+
44107+#define wmask 0 /* local copy of s->wmask */
44108+#define window 4 /* local copy of s->window */
44109+#define windowbestlen 8 /* s->window + bestlen */
44110+#define chainlenscanend 12 /* high word: current chain len */
44111+ /* low word: last bytes sought */
44112+#define scanstart 16 /* first two bytes of string */
44113+#define scanalign 20 /* dword-misalignment of string */
44114+#define nicematch 24 /* a good enough match size */
44115+#define bestlen 28 /* size of best match so far */
44116+#define scan 32 /* ptr to string wanting match */
44117+
44118+#define LocalVarsSize (36)
44119+/* saved ebx 36 */
44120+/* saved edi 40 */
44121+/* saved esi 44 */
44122+/* saved ebp 48 */
44123+/* return address 52 */
44124+#define deflatestate 56 /* the function arguments */
44125+#define curmatch 60
44126+
44127+/* Offsets for fields in the deflate_state structure. These numbers
44128+ * are calculated from the definition of deflate_state, with the
44129+ * assumption that the compiler will dword-align the fields. (Thus,
44130+ * changing the definition of deflate_state could easily cause this
44131+ * program to crash horribly, without so much as a warning at
44132+ * compile time. Sigh.)
44133+ */
44134+#define dsWSize 36
44135+#define dsWMask 44
44136+#define dsWindow 48
44137+#define dsPrev 56
44138+#define dsMatchLen 88
44139+#define dsPrevMatch 92
44140+#define dsStrStart 100
44141+#define dsMatchStart 104
44142+#define dsLookahead 108
44143+#define dsPrevLen 112
44144+#define dsMaxChainLen 116
44145+#define dsGoodMatch 132
44146+#define dsNiceMatch 136
44147+
44148+
44149+.file "match.S"
44150+
44151+.globl match_init, longest_match
44152+
44153+.text
44154+
44155+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
44156+
44157+longest_match:
44158+
44159+/* Save registers that the compiler may be using, and adjust %esp to */
44160+/* make room for our stack frame. */
44161+
44162+ pushl %ebp
44163+ pushl %edi
44164+ pushl %esi
44165+ pushl %ebx
44166+ subl $LocalVarsSize, %esp
44167+
44168+/* Retrieve the function arguments. %ecx will hold cur_match */
44169+/* throughout the entire function. %edx will hold the pointer to the */
44170+/* deflate_state structure during the function's setup (before */
44171+/* entering the main loop). */
44172+
44173+ movl deflatestate(%esp), %edx
44174+ movl curmatch(%esp), %ecx
44175+
44176+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
44177+
44178+ movl dsNiceMatch(%edx), %eax
44179+ movl dsLookahead(%edx), %ebx
44180+ cmpl %eax, %ebx
44181+ jl LookaheadLess
44182+ movl %eax, %ebx
44183+LookaheadLess: movl %ebx, nicematch(%esp)
44184+
44185+/* register Bytef *scan = s->window + s->strstart; */
44186+
44187+ movl dsWindow(%edx), %esi
44188+ movl %esi, window(%esp)
44189+ movl dsStrStart(%edx), %ebp
44190+ lea (%esi,%ebp), %edi
44191+ movl %edi, scan(%esp)
44192+
44193+/* Determine how many bytes the scan ptr is off from being */
44194+/* dword-aligned. */
44195+
44196+ movl %edi, %eax
44197+ negl %eax
44198+ andl $3, %eax
44199+ movl %eax, scanalign(%esp)
44200+
44201+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
44202+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
44203+
44204+ movl dsWSize(%edx), %eax
44205+ subl $MIN_LOOKAHEAD, %eax
44206+ subl %eax, %ebp
44207+ jg LimitPositive
44208+ xorl %ebp, %ebp
44209+LimitPositive:
44210+
44211+/* unsigned chain_length = s->max_chain_length; */
44212+/* if (s->prev_length >= s->good_match) { */
44213+/* chain_length >>= 2; */
44214+/* } */
44215+
44216+ movl dsPrevLen(%edx), %eax
44217+ movl dsGoodMatch(%edx), %ebx
44218+ cmpl %ebx, %eax
44219+ movl dsMaxChainLen(%edx), %ebx
44220+ jl LastMatchGood
44221+ shrl $2, %ebx
44222+LastMatchGood:
44223+
44224+/* chainlen is decremented once beforehand so that the function can */
44225+/* use the sign flag instead of the zero flag for the exit test. */
44226+/* It is then shifted into the high word, to make room for the scanend */
44227+/* scanend value, which it will always accompany. */
44228+
44229+ decl %ebx
44230+ shll $16, %ebx
44231+
44232+/* int best_len = s->prev_length; */
44233+
44234+ movl dsPrevLen(%edx), %eax
44235+ movl %eax, bestlen(%esp)
44236+
44237+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
44238+
44239+ addl %eax, %esi
44240+ movl %esi, windowbestlen(%esp)
44241+
44242+/* register ush scan_start = *(ushf*)scan; */
44243+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
44244+
44245+ movw (%edi), %bx
44246+ movw %bx, scanstart(%esp)
44247+ movw -1(%edi,%eax), %bx
44248+ movl %ebx, chainlenscanend(%esp)
44249+
44250+/* Posf *prev = s->prev; */
44251+/* uInt wmask = s->w_mask; */
44252+
44253+ movl dsPrev(%edx), %edi
44254+ movl dsWMask(%edx), %edx
44255+ mov %edx, wmask(%esp)
44256+
44257+/* Jump into the main loop. */
44258+
44259+ jmp LoopEntry
44260+
44261+.balign 16
44262+
44263+/* do {
44264+ * match = s->window + cur_match;
44265+ * if (*(ushf*)(match+best_len-1) != scan_end ||
44266+ * *(ushf*)match != scan_start) continue;
44267+ * [...]
44268+ * } while ((cur_match = prev[cur_match & wmask]) > limit
44269+ * && --chain_length != 0);
44270+ *
44271+ * Here is the inner loop of the function. The function will spend the
44272+ * majority of its time in this loop, and majority of that time will
44273+ * be spent in the first ten instructions.
44274+ *
44275+ * Within this loop:
44276+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
44277+ * %ecx = curmatch
44278+ * %edx = curmatch & wmask
44279+ * %esi = windowbestlen - i.e., (window + bestlen)
44280+ * %edi = prev
44281+ * %ebp = limit
44282+ *
44283+ * Two optimization notes on the choice of instructions:
44284+ *
44285+ * The first instruction uses a 16-bit address, which costs an extra,
44286+ * unpairable cycle. This is cheaper than doing a 32-bit access and
44287+ * zeroing the high word, due to the 3-cycle misalignment penalty which
44288+ * would occur half the time. This also turns out to be cheaper than
44289+ * doing two separate 8-bit accesses, as the memory is so rarely in the
44290+ * L1 cache.
44291+ *
44292+ * The window buffer, however, apparently spends a lot of time in the
44293+ * cache, and so it is faster to retrieve the word at the end of the
44294+ * match string with two 8-bit loads. The instructions that test the
44295+ * word at the beginning of the match string, however, are executed
44296+ * much less frequently, and there it was cheaper to use 16-bit
44297+ * instructions, which avoided the necessity of saving off and
44298+ * subsequently reloading one of the other registers.
44299+ */
44300+LookupLoop:
44301+ /* 1 U & V */
44302+ movw (%edi,%edx,2), %cx /* 2 U pipe */
44303+ movl wmask(%esp), %edx /* 2 V pipe */
44304+ cmpl %ebp, %ecx /* 3 U pipe */
44305+ jbe LeaveNow /* 3 V pipe */
44306+ subl $0x00010000, %ebx /* 4 U pipe */
44307+ js LeaveNow /* 4 V pipe */
44308+LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
44309+ andl %ecx, %edx /* 5 V pipe */
44310+ cmpb %bl, %al /* 6 U pipe */
44311+ jnz LookupLoop /* 6 V pipe */
44312+ movb (%esi,%ecx), %ah
44313+ cmpb %bh, %ah
44314+ jnz LookupLoop
44315+ movl window(%esp), %eax
44316+ movw (%eax,%ecx), %ax
44317+ cmpw scanstart(%esp), %ax
44318+ jnz LookupLoop
44319+
44320+/* Store the current value of chainlen. */
44321+
44322+ movl %ebx, chainlenscanend(%esp)
44323+
44324+/* Point %edi to the string under scrutiny, and %esi to the string we */
44325+/* are hoping to match it up with. In actuality, %esi and %edi are */
44326+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
44327+/* initialized to -(MAX_MATCH_8 - scanalign). */
44328+
44329+ movl window(%esp), %esi
44330+ movl scan(%esp), %edi
44331+ addl %ecx, %esi
44332+ movl scanalign(%esp), %eax
44333+ movl $(-MAX_MATCH_8), %edx
44334+ lea MAX_MATCH_8(%edi,%eax), %edi
44335+ lea MAX_MATCH_8(%esi,%eax), %esi
44336+
44337+/* Test the strings for equality, 8 bytes at a time. At the end,
44338+ * adjust %edx so that it is offset to the exact byte that mismatched.
44339+ *
44340+ * We already know at this point that the first three bytes of the
44341+ * strings match each other, and they can be safely passed over before
44342+ * starting the compare loop. So what this code does is skip over 0-3
44343+ * bytes, as much as necessary in order to dword-align the %edi
44344+ * pointer. (%esi will still be misaligned three times out of four.)
44345+ *
44346+ * It should be confessed that this loop usually does not represent
44347+ * much of the total running time. Replacing it with a more
44348+ * straightforward "rep cmpsb" would not drastically degrade
44349+ * performance.
44350+ */
44351+LoopCmps:
44352+ movl (%esi,%edx), %eax
44353+ movl (%edi,%edx), %ebx
44354+ xorl %ebx, %eax
44355+ jnz LeaveLoopCmps
44356+ movl 4(%esi,%edx), %eax
44357+ movl 4(%edi,%edx), %ebx
44358+ xorl %ebx, %eax
44359+ jnz LeaveLoopCmps4
44360+ addl $8, %edx
44361+ jnz LoopCmps
44362+ jmp LenMaximum
44363+LeaveLoopCmps4: addl $4, %edx
44364+LeaveLoopCmps: testl $0x0000FFFF, %eax
44365+ jnz LenLower
44366+ addl $2, %edx
44367+ shrl $16, %eax
44368+LenLower: subb $1, %al
44369+ adcl $0, %edx
44370+
44371+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
44372+/* then automatically accept it as the best possible match and leave. */
44373+
44374+ lea (%edi,%edx), %eax
44375+ movl scan(%esp), %edi
44376+ subl %edi, %eax
44377+ cmpl $MAX_MATCH, %eax
44378+ jge LenMaximum
44379+
44380+/* If the length of the match is not longer than the best match we */
44381+/* have so far, then forget it and return to the lookup loop. */
44382+
44383+ movl deflatestate(%esp), %edx
44384+ movl bestlen(%esp), %ebx
44385+ cmpl %ebx, %eax
44386+ jg LongerMatch
44387+ movl chainlenscanend(%esp), %ebx
44388+ movl windowbestlen(%esp), %esi
44389+ movl dsPrev(%edx), %edi
44390+ movl wmask(%esp), %edx
44391+ andl %ecx, %edx
44392+ jmp LookupLoop
44393+
44394+/* s->match_start = cur_match; */
44395+/* best_len = len; */
44396+/* if (len >= nice_match) break; */
44397+/* scan_end = *(ushf*)(scan+best_len-1); */
44398+
44399+LongerMatch: movl nicematch(%esp), %ebx
44400+ movl %eax, bestlen(%esp)
44401+ movl %ecx, dsMatchStart(%edx)
44402+ cmpl %ebx, %eax
44403+ jge LeaveNow
44404+ movl window(%esp), %esi
44405+ addl %eax, %esi
44406+ movl %esi, windowbestlen(%esp)
44407+ movl chainlenscanend(%esp), %ebx
44408+ movw -1(%edi,%eax), %bx
44409+ movl dsPrev(%edx), %edi
44410+ movl %ebx, chainlenscanend(%esp)
44411+ movl wmask(%esp), %edx
44412+ andl %ecx, %edx
44413+ jmp LookupLoop
44414+
44415+/* Accept the current string, with the maximum possible length. */
44416+
44417+LenMaximum: movl deflatestate(%esp), %edx
44418+ movl $MAX_MATCH, bestlen(%esp)
44419+ movl %ecx, dsMatchStart(%edx)
44420+
44421+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
44422+/* return s->lookahead; */
44423+
44424+LeaveNow:
44425+ movl deflatestate(%esp), %edx
44426+ movl bestlen(%esp), %ebx
44427+ movl dsLookahead(%edx), %eax
44428+ cmpl %eax, %ebx
44429+ jg LookaheadRet
44430+ movl %ebx, %eax
44431+LookaheadRet:
44432+
44433+/* Restore the stack and return from whence we came. */
44434+
44435+ addl $LocalVarsSize, %esp
44436+ popl %ebx
44437+ popl %esi
44438+ popl %edi
44439+ popl %ebp
44440+match_init: ret
44441--- /dev/null Tue Mar 11 13:02:56 2003
44442+++ linux/net/ipsec/match686.S Mon Feb 9 13:51:03 2004
44443@@ -0,0 +1,330 @@
44444+/* match.s -- Pentium-Pro-optimized version of longest_match()
44445+ * Written for zlib 1.1.2
44446+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
44447+ *
44448+ * This is free software; you can redistribute it and/or modify it
44449+ * under the terms of the GNU General Public License.
44450+ */
44451+
44452+#ifndef NO_UNDERLINE
44453+#define match_init _ipcomp_match_init
44454+#define longest_match _ipcomp_longest_match
44455+#else
44456+#define match_init ipcomp_match_init
44457+#define longest_match ipcomp_longest_match
44458+#endif
44459+
44460+#define MAX_MATCH (258)
44461+#define MIN_MATCH (3)
44462+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
44463+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
44464+
44465+/* stack frame offsets */
44466+
44467+#define chainlenwmask 0 /* high word: current chain len */
44468+ /* low word: s->wmask */
44469+#define window 4 /* local copy of s->window */
44470+#define windowbestlen 8 /* s->window + bestlen */
44471+#define scanstart 16 /* first two bytes of string */
44472+#define scanend 12 /* last two bytes of string */
44473+#define scanalign 20 /* dword-misalignment of string */
44474+#define nicematch 24 /* a good enough match size */
44475+#define bestlen 28 /* size of best match so far */
44476+#define scan 32 /* ptr to string wanting match */
44477+
44478+#define LocalVarsSize (36)
44479+/* saved ebx 36 */
44480+/* saved edi 40 */
44481+/* saved esi 44 */
44482+/* saved ebp 48 */
44483+/* return address 52 */
44484+#define deflatestate 56 /* the function arguments */
44485+#define curmatch 60
44486+
44487+/* Offsets for fields in the deflate_state structure. These numbers
44488+ * are calculated from the definition of deflate_state, with the
44489+ * assumption that the compiler will dword-align the fields. (Thus,
44490+ * changing the definition of deflate_state could easily cause this
44491+ * program to crash horribly, without so much as a warning at
44492+ * compile time. Sigh.)
44493+ */
44494+#define dsWSize 36
44495+#define dsWMask 44
44496+#define dsWindow 48
44497+#define dsPrev 56
44498+#define dsMatchLen 88
44499+#define dsPrevMatch 92
44500+#define dsStrStart 100
44501+#define dsMatchStart 104
44502+#define dsLookahead 108
44503+#define dsPrevLen 112
44504+#define dsMaxChainLen 116
44505+#define dsGoodMatch 132
44506+#define dsNiceMatch 136
44507+
44508+
44509+.file "match.S"
44510+
44511+.globl match_init, longest_match
44512+
44513+.text
44514+
44515+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
44516+
44517+longest_match:
44518+
44519+/* Save registers that the compiler may be using, and adjust %esp to */
44520+/* make room for our stack frame. */
44521+
44522+ pushl %ebp
44523+ pushl %edi
44524+ pushl %esi
44525+ pushl %ebx
44526+ subl $LocalVarsSize, %esp
44527+
44528+/* Retrieve the function arguments. %ecx will hold cur_match */
44529+/* throughout the entire function. %edx will hold the pointer to the */
44530+/* deflate_state structure during the function's setup (before */
44531+/* entering the main loop). */
44532+
44533+ movl deflatestate(%esp), %edx
44534+ movl curmatch(%esp), %ecx
44535+
44536+/* uInt wmask = s->w_mask; */
44537+/* unsigned chain_length = s->max_chain_length; */
44538+/* if (s->prev_length >= s->good_match) { */
44539+/* chain_length >>= 2; */
44540+/* } */
44541+
44542+ movl dsPrevLen(%edx), %eax
44543+ movl dsGoodMatch(%edx), %ebx
44544+ cmpl %ebx, %eax
44545+ movl dsWMask(%edx), %eax
44546+ movl dsMaxChainLen(%edx), %ebx
44547+ jl LastMatchGood
44548+ shrl $2, %ebx
44549+LastMatchGood:
44550+
44551+/* chainlen is decremented once beforehand so that the function can */
44552+/* use the sign flag instead of the zero flag for the exit test. */
44553+/* It is then shifted into the high word, to make room for the wmask */
44554+/* value, which it will always accompany. */
44555+
44556+ decl %ebx
44557+ shll $16, %ebx
44558+ orl %eax, %ebx
44559+ movl %ebx, chainlenwmask(%esp)
44560+
44561+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
44562+
44563+ movl dsNiceMatch(%edx), %eax
44564+ movl dsLookahead(%edx), %ebx
44565+ cmpl %eax, %ebx
44566+ jl LookaheadLess
44567+ movl %eax, %ebx
44568+LookaheadLess: movl %ebx, nicematch(%esp)
44569+
44570+/* register Bytef *scan = s->window + s->strstart; */
44571+
44572+ movl dsWindow(%edx), %esi
44573+ movl %esi, window(%esp)
44574+ movl dsStrStart(%edx), %ebp
44575+ lea (%esi,%ebp), %edi
44576+ movl %edi, scan(%esp)
44577+
44578+/* Determine how many bytes the scan ptr is off from being */
44579+/* dword-aligned. */
44580+
44581+ movl %edi, %eax
44582+ negl %eax
44583+ andl $3, %eax
44584+ movl %eax, scanalign(%esp)
44585+
44586+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
44587+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
44588+
44589+ movl dsWSize(%edx), %eax
44590+ subl $MIN_LOOKAHEAD, %eax
44591+ subl %eax, %ebp
44592+ jg LimitPositive
44593+ xorl %ebp, %ebp
44594+LimitPositive:
44595+
44596+/* int best_len = s->prev_length; */
44597+
44598+ movl dsPrevLen(%edx), %eax
44599+ movl %eax, bestlen(%esp)
44600+
44601+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
44602+
44603+ addl %eax, %esi
44604+ movl %esi, windowbestlen(%esp)
44605+
44606+/* register ush scan_start = *(ushf*)scan; */
44607+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
44608+/* Posf *prev = s->prev; */
44609+
44610+ movzwl (%edi), %ebx
44611+ movl %ebx, scanstart(%esp)
44612+ movzwl -1(%edi,%eax), %ebx
44613+ movl %ebx, scanend(%esp)
44614+ movl dsPrev(%edx), %edi
44615+
44616+/* Jump into the main loop. */
44617+
44618+ movl chainlenwmask(%esp), %edx
44619+ jmp LoopEntry
44620+
44621+.balign 16
44622+
44623+/* do {
44624+ * match = s->window + cur_match;
44625+ * if (*(ushf*)(match+best_len-1) != scan_end ||
44626+ * *(ushf*)match != scan_start) continue;
44627+ * [...]
44628+ * } while ((cur_match = prev[cur_match & wmask]) > limit
44629+ * && --chain_length != 0);
44630+ *
44631+ * Here is the inner loop of the function. The function will spend the
44632+ * majority of its time in this loop, and majority of that time will
44633+ * be spent in the first ten instructions.
44634+ *
44635+ * Within this loop:
44636+ * %ebx = scanend
44637+ * %ecx = curmatch
44638+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
44639+ * %esi = windowbestlen - i.e., (window + bestlen)
44640+ * %edi = prev
44641+ * %ebp = limit
44642+ */
44643+LookupLoop:
44644+ andl %edx, %ecx
44645+ movzwl (%edi,%ecx,2), %ecx
44646+ cmpl %ebp, %ecx
44647+ jbe LeaveNow
44648+ subl $0x00010000, %edx
44649+ js LeaveNow
44650+LoopEntry: movzwl -1(%esi,%ecx), %eax
44651+ cmpl %ebx, %eax
44652+ jnz LookupLoop
44653+ movl window(%esp), %eax
44654+ movzwl (%eax,%ecx), %eax
44655+ cmpl scanstart(%esp), %eax
44656+ jnz LookupLoop
44657+
44658+/* Store the current value of chainlen. */
44659+
44660+ movl %edx, chainlenwmask(%esp)
44661+
44662+/* Point %edi to the string under scrutiny, and %esi to the string we */
44663+/* are hoping to match it up with. In actuality, %esi and %edi are */
44664+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
44665+/* initialized to -(MAX_MATCH_8 - scanalign). */
44666+
44667+ movl window(%esp), %esi
44668+ movl scan(%esp), %edi
44669+ addl %ecx, %esi
44670+ movl scanalign(%esp), %eax
44671+ movl $(-MAX_MATCH_8), %edx
44672+ lea MAX_MATCH_8(%edi,%eax), %edi
44673+ lea MAX_MATCH_8(%esi,%eax), %esi
44674+
44675+/* Test the strings for equality, 8 bytes at a time. At the end,
44676+ * adjust %edx so that it is offset to the exact byte that mismatched.
44677+ *
44678+ * We already know at this point that the first three bytes of the
44679+ * strings match each other, and they can be safely passed over before
44680+ * starting the compare loop. So what this code does is skip over 0-3
44681+ * bytes, as much as necessary in order to dword-align the %edi
44682+ * pointer. (%esi will still be misaligned three times out of four.)
44683+ *
44684+ * It should be confessed that this loop usually does not represent
44685+ * much of the total running time. Replacing it with a more
44686+ * straightforward "rep cmpsb" would not drastically degrade
44687+ * performance.
44688+ */
44689+LoopCmps:
44690+ movl (%esi,%edx), %eax
44691+ xorl (%edi,%edx), %eax
44692+ jnz LeaveLoopCmps
44693+ movl 4(%esi,%edx), %eax
44694+ xorl 4(%edi,%edx), %eax
44695+ jnz LeaveLoopCmps4
44696+ addl $8, %edx
44697+ jnz LoopCmps
44698+ jmp LenMaximum
44699+LeaveLoopCmps4: addl $4, %edx
44700+LeaveLoopCmps: testl $0x0000FFFF, %eax
44701+ jnz LenLower
44702+ addl $2, %edx
44703+ shrl $16, %eax
44704+LenLower: subb $1, %al
44705+ adcl $0, %edx
44706+
44707+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
44708+/* then automatically accept it as the best possible match and leave. */
44709+
44710+ lea (%edi,%edx), %eax
44711+ movl scan(%esp), %edi
44712+ subl %edi, %eax
44713+ cmpl $MAX_MATCH, %eax
44714+ jge LenMaximum
44715+
44716+/* If the length of the match is not longer than the best match we */
44717+/* have so far, then forget it and return to the lookup loop. */
44718+
44719+ movl deflatestate(%esp), %edx
44720+ movl bestlen(%esp), %ebx
44721+ cmpl %ebx, %eax
44722+ jg LongerMatch
44723+ movl windowbestlen(%esp), %esi
44724+ movl dsPrev(%edx), %edi
44725+ movl scanend(%esp), %ebx
44726+ movl chainlenwmask(%esp), %edx
44727+ jmp LookupLoop
44728+
44729+/* s->match_start = cur_match; */
44730+/* best_len = len; */
44731+/* if (len >= nice_match) break; */
44732+/* scan_end = *(ushf*)(scan+best_len-1); */
44733+
44734+LongerMatch: movl nicematch(%esp), %ebx
44735+ movl %eax, bestlen(%esp)
44736+ movl %ecx, dsMatchStart(%edx)
44737+ cmpl %ebx, %eax
44738+ jge LeaveNow
44739+ movl window(%esp), %esi
44740+ addl %eax, %esi
44741+ movl %esi, windowbestlen(%esp)
44742+ movzwl -1(%edi,%eax), %ebx
44743+ movl dsPrev(%edx), %edi
44744+ movl %ebx, scanend(%esp)
44745+ movl chainlenwmask(%esp), %edx
44746+ jmp LookupLoop
44747+
44748+/* Accept the current string, with the maximum possible length. */
44749+
44750+LenMaximum: movl deflatestate(%esp), %edx
44751+ movl $MAX_MATCH, bestlen(%esp)
44752+ movl %ecx, dsMatchStart(%edx)
44753+
44754+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
44755+/* return s->lookahead; */
44756+
44757+LeaveNow:
44758+ movl deflatestate(%esp), %edx
44759+ movl bestlen(%esp), %ebx
44760+ movl dsLookahead(%edx), %eax
44761+ cmpl %eax, %ebx
44762+ jg LookaheadRet
44763+ movl %ebx, %eax
44764+LookaheadRet:
44765+
44766+/* Restore the stack and return from whence we came. */
44767+
44768+ addl $LocalVarsSize, %esp
44769+ popl %ebx
44770+ popl %esi
44771+ popl %edi
44772+ popl %ebp
44773+match_init: ret
44774--- /dev/null Tue Mar 11 13:02:56 2003
44775+++ linux/net/ipsec/null/ipsec_alg_null.c Mon Feb 9 13:51:03 2004
44776@@ -0,0 +1,147 @@
44777+/*
44778+ * ipsec_alg NULL cipher stubs
44779+ *
44780+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
44781+ *
44782+ * $Id: ipsec_alg_null.c,v 1.1.2.2 2008-01-11 21:07:23 paul Exp $
44783+ *
44784+ * This program is free software; you can redistribute it and/or modify it
44785+ * under the terms of the GNU General Public License as published by the
44786+ * Free Software Foundation; either version 2 of the License, or (at your
44787+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
44788+ *
44789+ * This program is distributed in the hope that it will be useful, but
44790+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
44791+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44792+ * for more details.
44793+ *
44794+ */
44795+#ifndef AUTOCONF_INCLUDED
44796+#include <linux/config.h>
44797+#endif
44798+#include <linux/version.h>
44799+
44800+/*
44801+ * special case: ipsec core modular with this static algo inside:
44802+ * must avoid MODULE magic for this file
44803+ */
44804+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_NULL)
44805+#undef MODULE
44806+#endif
44807+
44808+#include <linux/module.h>
44809+#include <linux/init.h>
44810+
44811+#include <linux/kernel.h> /* printk() */
44812+#include <linux/errno.h> /* error codes */
44813+#include <linux/types.h> /* size_t */
44814+#include <linux/string.h>
44815+
44816+/* Check if __exit is defined, if not null it */
44817+#ifndef __exit
44818+#define __exit
44819+#endif
44820+
44821+/* Low freeswan header coupling */
44822+#include "openswan/ipsec_alg.h"
44823+
44824+#define ESP_NULL 11 /* from ipsec drafts */
44825+#define ESP_NULL_BLK_LEN 1
44826+
44827+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
44828+static int debug_null=0;
44829+static int test_null=0;
44830+#ifdef module_param
44831+module_param(debug_null, int, 0600);
44832+module_param(test_null, int, 0600);
44833+#else
44834+MODULE_PARM(debug_null, "i");
44835+MODULE_PARM(test_null, "i");
44836+#endif
44837+
44838+typedef int null_context;
44839+
44840+struct null_eks{
44841+ null_context null_ctx;
44842+};
44843+static int _null_set_key(struct ipsec_alg_enc *alg,
44844+ __u8 * key_e, const __u8 * key,
44845+ size_t keysize) {
44846+ null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
44847+ if (debug_null > 0)
44848+ printk(KERN_DEBUG "klips_debug:_null_set_key:"
44849+ "key_e=%p key=%p keysize=%d\n",
44850+ key_e, key, keysize);
44851+ *ctx = 1;
44852+ return 0;
44853+}
44854+static int _null_cbc_encrypt(struct ipsec_alg_enc *alg,
44855+ __u8 * key_e, __u8 * in, int ilen, const __u8 * iv,
44856+ int encrypt) {
44857+ null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
44858+ if (debug_null > 0)
44859+ printk(KERN_DEBUG "klips_debug:_null_cbc_encrypt:"
44860+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
44861+ key_e, in, ilen, iv, encrypt);
44862+ (*ctx)++;
44863+ return ilen;
44864+}
44865+static struct ipsec_alg_enc ipsec_alg_NULL = {
44866+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
44867+ ixt_refcnt: ATOMIC_INIT(0),
44868+ ixt_name: "null",
44869+ ixt_blocksize: ESP_NULL_BLK_LEN,
44870+ ixt_support: {
44871+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
44872+ ias_id: ESP_NULL,
44873+ ias_ivlen: 0,
44874+ ias_keyminbits: 0,
44875+ ias_keymaxbits: 0,
44876+ },
44877+ },
44878+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44879+ ixt_module: THIS_MODULE,
44880+#endif
44881+ ixt_e_keylen: 0,
44882+ ixt_e_ctx_size: sizeof(null_context),
44883+ ixt_e_set_key: _null_set_key,
44884+ ixt_e_cbc_encrypt:_null_cbc_encrypt,
44885+};
44886+
44887+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44888+IPSEC_ALG_MODULE_INIT_MOD( ipsec_null_init )
44889+#else
44890+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_null_init )
44891+#endif
44892+{
44893+ int ret, test_ret;
44894+ ret=register_ipsec_alg_enc(&ipsec_alg_NULL);
44895+ printk("ipsec_null_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
44896+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44897+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44898+ ipsec_alg_NULL.ixt_common.ixt_name,
44899+ ret);
44900+ if (ret==0 && test_null) {
44901+ test_ret=ipsec_alg_test(
44902+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44903+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44904+ test_null);
44905+ printk("ipsec_null_init(alg_type=%d alg_id=%d): test_ret=%d\n",
44906+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44907+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44908+ test_ret);
44909+ }
44910+ return ret;
44911+}
44912+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44913+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_null_fini )
44914+#else
44915+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_null_fini )
44916+#endif
44917+{
44918+ unregister_ipsec_alg_enc(&ipsec_alg_NULL);
44919+ return;
44920+}
44921+#ifdef MODULE_LICENSE
44922+MODULE_LICENSE("GPL");
44923+#endif
44924--- /dev/null Tue Mar 11 13:02:56 2003
44925+++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004
44926@@ -0,0 +1,2043 @@
44927+/*
44928+ * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
44929+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
44930+ *
44931+ * This program is free software; you can redistribute it and/or modify it
44932+ * under the terms of the GNU General Public License as published by the
44933+ * Free Software Foundation; either version 2 of the License, or (at your
44934+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
44935+ *
44936+ * This program is distributed in the hope that it will be useful, but
44937+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
44938+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44939+ * for more details.
44940+ *
44941+ * RCSID $Id: pfkey_v2.c,v 1.97.2.16 2007-10-31 19:57:41 paul Exp $
44942+ */
44943+
44944+/*
44945+ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
44946+ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
44947+ */
44948+
44949+#define __NO_VERSION__
44950+#include <linux/module.h>
44951+#include <linux/version.h>
44952+#ifndef AUTOCONF_INCLUDED
44953+#include <linux/config.h>
44954+#endif
44955+#include <linux/kernel.h>
44956+
44957+#include "openswan/ipsec_param.h"
44958+
44959+#include <linux/major.h>
44960+#include <linux/signal.h>
44961+#include <linux/sched.h>
44962+#include <linux/errno.h>
44963+#include <linux/string.h>
44964+#include <linux/stat.h>
44965+#include <linux/socket.h>
44966+#include <linux/un.h>
44967+#include <linux/fcntl.h>
44968+#include <linux/termios.h>
44969+#include <linux/socket.h>
44970+#include <linux/sockios.h>
44971+#include <linux/net.h> /* struct socket */
44972+#include <linux/in.h>
44973+#include <linux/fs.h>
44974+#ifdef MALLOC_SLAB
44975+# include <linux/slab.h> /* kmalloc() */
44976+#else /* MALLOC_SLAB */
44977+# include <linux/malloc.h> /* kmalloc() */
44978+#endif /* MALLOC_SLAB */
44979+#include <asm/segment.h>
44980+#include <linux/skbuff.h>
44981+#include <linux/netdevice.h>
44982+#include <net/sock.h> /* struct sock */
44983+#include <net/protocol.h>
44984+/* #include <net/tcp.h> */
44985+#include <net/af_unix.h>
44986+#ifdef CONFIG_PROC_FS
44987+# include <linux/proc_fs.h>
44988+#endif /* CONFIG_PROC_FS */
44989+
44990+#include <linux/types.h>
44991+
44992+#include <openswan.h>
44993+
44994+#include "openswan/radij.h"
44995+#include "openswan/ipsec_encap.h"
44996+#include "openswan/ipsec_sa.h"
44997+
44998+#include <pfkeyv2.h>
44999+#include <pfkey.h>
45000+
45001+#include "openswan/ipsec_proto.h"
45002+#include "openswan/ipsec_kern24.h"
45003+
45004+#ifdef CONFIG_KLIPS_DEBUG
45005+int debug_pfkey = 0;
45006+extern int sysctl_ipsec_debug_verbose;
45007+#endif /* CONFIG_KLIPS_DEBUG */
45008+
45009+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
45010+
45011+#ifndef SOCKOPS_WRAPPED
45012+#define SOCKOPS_WRAPPED(name) name
45013+#endif /* SOCKOPS_WRAPPED */
45014+
45015+#ifdef NET_26
45016+static rwlock_t pfkey_sock_lock = RW_LOCK_UNLOCKED;
45017+HLIST_HEAD(pfkey_sock_list);
45018+static DECLARE_WAIT_QUEUE_HEAD(pfkey_sock_wait);
45019+static atomic_t pfkey_sock_users = ATOMIC_INIT(0);
45020+#else
45021+struct sock *pfkey_sock_list = NULL;
45022+#endif
45023+
45024+struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
45025+
45026+struct socket_list *pfkey_open_sockets = NULL;
45027+struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
45028+
45029+int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
45030+
45031+DEBUG_NO_STATIC int pfkey_create(struct socket *sock, int protocol);
45032+DEBUG_NO_STATIC int pfkey_shutdown(struct socket *sock, int mode);
45033+DEBUG_NO_STATIC int pfkey_release(struct socket *sock);
45034+
45035+#ifdef NET_26
45036+DEBUG_NO_STATIC int pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len);
45037+DEBUG_NO_STATIC int pfkey_recvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg
45038+ , size_t size, int flags);
45039+#else
45040+DEBUG_NO_STATIC int pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm);
45041+DEBUG_NO_STATIC int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm);
45042+#endif
45043+
45044+struct net_proto_family pfkey_family_ops = {
45045+#ifdef NETDEV_23
45046+ .family = PF_KEY,
45047+ .create = pfkey_create,
45048+#ifdef NET_26
45049+ .owner = THIS_MODULE,
45050+#endif
45051+#else
45052+ PF_KEY,
45053+ pfkey_create
45054+#endif
45055+};
45056+
45057+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
45058+#ifdef NETDEV_23
45059+ family: PF_KEY,
45060+#ifdef NET_26
45061+ owner: THIS_MODULE,
45062+#endif
45063+ release: pfkey_release,
45064+ bind: sock_no_bind,
45065+ connect: sock_no_connect,
45066+ socketpair: sock_no_socketpair,
45067+ accept: sock_no_accept,
45068+ getname: sock_no_getname,
45069+ poll: datagram_poll,
45070+ ioctl: sock_no_ioctl,
45071+ listen: sock_no_listen,
45072+ shutdown: pfkey_shutdown,
45073+ setsockopt: sock_no_setsockopt,
45074+ getsockopt: sock_no_getsockopt,
45075+ sendmsg: pfkey_sendmsg,
45076+ recvmsg: pfkey_recvmsg,
45077+ mmap: sock_no_mmap,
45078+#else /* NETDEV_23 */
45079+ PF_KEY,
45080+ sock_no_dup,
45081+ pfkey_release,
45082+ sock_no_bind,
45083+ sock_no_connect,
45084+ sock_no_socketpair,
45085+ sock_no_accept,
45086+ sock_no_getname,
45087+ datagram_poll,
45088+ sock_no_ioctl,
45089+ sock_no_listen,
45090+ pfkey_shutdown,
45091+ sock_no_setsockopt,
45092+ sock_no_getsockopt,
45093+ sock_no_fcntl,
45094+ pfkey_sendmsg,
45095+ pfkey_recvmsg
45096+#endif /* NETDEV_23 */
45097+};
45098+
45099+#ifdef NETDEV_23
45100+#include <linux/smp_lock.h>
45101+SOCKOPS_WRAP(pfkey, PF_KEY);
45102+#endif /* NETDEV_23 */
45103+
45104+#ifdef NET_26
45105+static void pfkey_sock_list_grab(void)
45106+{
45107+ write_lock_bh(&pfkey_sock_lock);
45108+
45109+ if (atomic_read(&pfkey_sock_users)) {
45110+ DECLARE_WAITQUEUE(wait, current);
45111+
45112+ add_wait_queue_exclusive(&pfkey_sock_wait, &wait);
45113+ for(;;) {
45114+ set_current_state(TASK_UNINTERRUPTIBLE);
45115+ if (atomic_read(&pfkey_sock_users) == 0)
45116+ break;
45117+ write_unlock_bh(&pfkey_sock_lock);
45118+ schedule();
45119+ write_lock_bh(&pfkey_sock_lock);
45120+ }
45121+
45122+ __set_current_state(TASK_RUNNING);
45123+ remove_wait_queue(&pfkey_sock_wait, &wait);
45124+ }
45125+}
45126+
45127+static __inline__ void pfkey_sock_list_ungrab(void)
45128+{
45129+ write_unlock_bh(&pfkey_sock_lock);
45130+ wake_up(&pfkey_sock_wait);
45131+}
45132+
45133+static __inline__ void pfkey_lock_sock_list(void)
45134+{
45135+ /* read_lock() synchronizes us to pfkey_table_grab */
45136+
45137+ read_lock(&pfkey_sock_lock);
45138+ atomic_inc(&pfkey_sock_users);
45139+ read_unlock(&pfkey_sock_lock);
45140+}
45141+
45142+static __inline__ void pfkey_unlock_sock_list(void)
45143+{
45144+ if (atomic_dec_and_test(&pfkey_sock_users))
45145+ wake_up(&pfkey_sock_wait);
45146+}
45147+#endif
45148+
45149+int
45150+pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
45151+{
45152+ struct socket_list *socket_listp,*prev;
45153+
45154+ if(!socketp) {
45155+ KLIPS_PRINT(debug_pfkey,
45156+ "klips_debug:pfkey_list_remove_socket: "
45157+ "NULL socketp handed in, failed.\n");
45158+ return -EINVAL;
45159+ }
45160+
45161+ if(!sockets) {
45162+ KLIPS_PRINT(debug_pfkey,
45163+ "klips_debug:pfkey_list_remove_socket: "
45164+ "NULL sockets list handed in, failed.\n");
45165+ return -EINVAL;
45166+ }
45167+
45168+ socket_listp = *sockets;
45169+ prev = NULL;
45170+
45171+ KLIPS_PRINT(debug_pfkey,
45172+ "klips_debug:pfkey_list_remove_socket: "
45173+ "removing sock=0p%p\n",
45174+ socketp);
45175+
45176+ while(socket_listp != NULL) {
45177+ if(socket_listp->socketp == socketp) {
45178+ if(prev != NULL) {
45179+ prev->next = socket_listp->next;
45180+ } else {
45181+ *sockets = socket_listp->next;
45182+ }
45183+
45184+ kfree((void*)socket_listp);
45185+
45186+ break;
45187+ }
45188+ prev = socket_listp;
45189+ socket_listp = socket_listp->next;
45190+ }
45191+
45192+ return 0;
45193+}
45194+
45195+int
45196+pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
45197+{
45198+ struct socket_list *socket_listp;
45199+
45200+ if(!socketp) {
45201+ KLIPS_PRINT(debug_pfkey,
45202+ "klips_debug:pfkey_list_insert_socket: "
45203+ "NULL socketp handed in, failed.\n");
45204+ return -EINVAL;
45205+ }
45206+
45207+ if(!sockets) {
45208+ KLIPS_PRINT(debug_pfkey,
45209+ "klips_debug:pfkey_list_insert_socket: "
45210+ "NULL sockets list handed in, failed.\n");
45211+ return -EINVAL;
45212+ }
45213+
45214+ KLIPS_PRINT(debug_pfkey,
45215+ "klips_debug:pfkey_list_insert_socket: "
45216+ "allocating %lu bytes for socketp=0p%p\n",
45217+ (unsigned long) sizeof(struct socket_list),
45218+ socketp);
45219+
45220+ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
45221+ KLIPS_PRINT(debug_pfkey,
45222+ "klips_debug:pfkey_list_insert_socket: "
45223+ "memory allocation error.\n");
45224+ return -ENOMEM;
45225+ }
45226+
45227+ socket_listp->socketp = socketp;
45228+ socket_listp->next = *sockets;
45229+ *sockets = socket_listp;
45230+
45231+ return 0;
45232+}
45233+
45234+int
45235+pfkey_list_remove_supported(struct ipsec_alg_supported *supported, struct supported_list **supported_list)
45236+{
45237+ struct supported_list *supported_listp = *supported_list, *prev = NULL;
45238+
45239+ if(!supported) {
45240+ KLIPS_PRINT(debug_pfkey,
45241+ "klips_debug:pfkey_list_remove_supported: "
45242+ "NULL supported handed in, failed.\n");
45243+ return -EINVAL;
45244+ }
45245+
45246+ if(!supported_list) {
45247+ KLIPS_PRINT(debug_pfkey,
45248+ "klips_debug:pfkey_list_remove_supported: "
45249+ "NULL supported_list handed in, failed.\n");
45250+ return -EINVAL;
45251+ }
45252+
45253+ KLIPS_PRINT(debug_pfkey,
45254+ "klips_debug:pfkey_list_remove_supported: "
45255+ "removing supported=0p%p\n",
45256+ supported);
45257+
45258+ while(supported_listp != NULL) {
45259+ if(supported_listp->supportedp == supported) {
45260+ if(prev != NULL) {
45261+ prev->next = supported_listp->next;
45262+ } else {
45263+ *supported_list = supported_listp->next;
45264+ }
45265+
45266+ kfree((void*)supported_listp);
45267+
45268+ break;
45269+ }
45270+ prev = supported_listp;
45271+ supported_listp = supported_listp->next;
45272+ }
45273+
45274+ return 0;
45275+}
45276+
45277+int
45278+pfkey_list_insert_supported(struct ipsec_alg_supported *supported
45279+ , struct supported_list **supported_list)
45280+{
45281+ struct supported_list *supported_listp;
45282+
45283+ if(!supported) {
45284+ KLIPS_PRINT(debug_pfkey,
45285+ "klips_debug:pfkey_list_insert_supported: "
45286+ "NULL supported handed in, failed.\n");
45287+ return -EINVAL;
45288+ }
45289+
45290+ if(!supported_list) {
45291+ KLIPS_PRINT(debug_pfkey,
45292+ "klips_debug:pfkey_list_insert_supported: "
45293+ "NULL supported_list handed in, failed.\n");
45294+ return -EINVAL;
45295+ }
45296+
45297+ KLIPS_PRINT(debug_pfkey,
45298+ "klips_debug:pfkey_list_insert_supported: "
45299+ "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
45300+ (unsigned long) sizeof(struct supported_list),
45301+ supported,
45302+ supported_list);
45303+
45304+ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
45305+
45306+ if(supported_listp == NULL)
45307+ {
45308+ KLIPS_PRINT(debug_pfkey,
45309+ "klips_debug:pfkey_list_insert_supported: "
45310+ "memory allocation error.\n");
45311+ return -ENOMEM;
45312+ }
45313+
45314+ supported_listp->supportedp = supported;
45315+ supported_listp->next = *supported_list;
45316+ *supported_list = supported_listp;
45317+ KLIPS_PRINT(debug_pfkey,
45318+ "klips_debug:pfkey_list_insert_supported: "
45319+ "outgoing, supported=0p%p, supported_list=0p%p\n",
45320+ supported,
45321+ supported_list);
45322+
45323+ return 0;
45324+}
45325+
45326+#ifdef NET_26
45327+DEBUG_NO_STATIC void
45328+pfkey_insert_socket(struct sock *sk)
45329+{
45330+ KLIPS_PRINT(debug_pfkey,
45331+ "klips_debug:pfkey_insert_socket: "
45332+ "sk=0p%p\n",
45333+ sk);
45334+ pfkey_sock_list_grab();
45335+ sk_add_node(sk, &pfkey_sock_list);
45336+ pfkey_sock_list_ungrab();
45337+}
45338+
45339+DEBUG_NO_STATIC void
45340+pfkey_remove_socket(struct sock *sk)
45341+{
45342+ KLIPS_PRINT(debug_pfkey,
45343+ "klips_debug:pfkey_remove_socket: 0p%p\n", sk);
45344+ pfkey_sock_list_grab();
45345+ sk_del_node_init(sk);
45346+ pfkey_sock_list_ungrab();
45347+ return;
45348+}
45349+#else
45350+
45351+DEBUG_NO_STATIC void
45352+pfkey_insert_socket(struct sock *sk)
45353+{
45354+ KLIPS_PRINT(debug_pfkey,
45355+ "klips_debug:pfkey_insert_socket: "
45356+ "sk=0p%p\n",
45357+ sk);
45358+ cli();
45359+ sk->next=pfkey_sock_list;
45360+ pfkey_sock_list=sk;
45361+ sti();
45362+}
45363+DEBUG_NO_STATIC void
45364+pfkey_remove_socket(struct sock *sk)
45365+{
45366+ struct sock **s;
45367+
45368+ s = NULL;
45369+ KLIPS_PRINT(debug_pfkey,
45370+ "klips_debug:pfkey_remove_socket: .\n");
45371+
45372+ cli();
45373+ s=&pfkey_sock_list;
45374+
45375+ while(*s!=NULL) {
45376+ if(*s==sk) {
45377+ *s=sk->next;
45378+ sk->next=NULL;
45379+ sti();
45380+ KLIPS_PRINT(debug_pfkey,
45381+ "klips_debug:pfkey_remove_socket: "
45382+ "succeeded.\n");
45383+ return;
45384+ }
45385+ s=&((*s)->next);
45386+ }
45387+ sti();
45388+
45389+ KLIPS_PRINT(debug_pfkey,
45390+ "klips_debug:pfkey_remove_socket: "
45391+ "not found.\n");
45392+ return;
45393+}
45394+#endif
45395+
45396+DEBUG_NO_STATIC void
45397+pfkey_destroy_socket(struct sock *sk)
45398+{
45399+ struct sk_buff *skb;
45400+
45401+ KLIPS_PRINT(debug_pfkey,
45402+ "klips_debug:pfkey_destroy_socket: 0p%p\n",sk);
45403+ pfkey_remove_socket(sk);
45404+
45405+ KLIPS_PRINT(debug_pfkey,
45406+ "klips_debug:pfkey_destroy_socket: "
45407+ "pfkey_remove_socket called, sk=0p%p\n",sk);
45408+
45409+ KLIPS_PRINT(debug_pfkey,
45410+ "klips_debug:pfkey_destroy_socket: "
45411+ "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
45412+ sk,
45413+ &(sk->sk_receive_queue),
45414+ sk->sk_receive_queue.next,
45415+ sk->sk_receive_queue.prev);
45416+
45417+ while(sk && ((skb=skb_dequeue(&(sk->sk_receive_queue)))!=NULL)) {
45418+#ifdef CONFIG_KLIPS_DEBUG
45419+ if(debug_pfkey && sysctl_ipsec_debug_verbose) {
45420+ KLIPS_PRINT(debug_pfkey,
45421+ "klips_debug:pfkey_destroy_socket: "
45422+ "skb=0p%p dequeued.\n", skb);
45423+ printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
45424+ "pfkey_skb contents:");
45425+ printk(" next:0p%p", skb->next);
45426+ printk(" prev:0p%p", skb->prev);
45427+ printk(" sk:0p%p", skb->sk);
45428+ printk(" dev:0p%p", skb->dev);
45429+ if(skb->dev) {
45430+ if(skb->dev->name) {
45431+ printk(" dev->name:%s", skb->dev->name);
45432+ } else {
45433+ printk(" dev->name:NULL?");
45434+ }
45435+ } else {
45436+ printk(" dev:NULL");
45437+ }
45438+ printk(" h:0p%p", skb_transport_header(skb));
45439+ printk(" nh:0p%p", skb_network_header(skb));
45440+ printk(" mac:0p%p", skb_mac_header(skb));
45441+ printk(" dst:0p%p", skb->dst);
45442+ if(sysctl_ipsec_debug_verbose) {
45443+ int i;
45444+
45445+ printk(" cb");
45446+ for(i=0; i<48; i++) {
45447+ printk(":%2x", skb->cb[i]);
45448+ }
45449+ }
45450+ printk(" len:%d", skb->len);
45451+ printk(" csum:%d", skb->csum);
45452+#ifndef NETDEV_23
45453+ printk(" used:%d", skb->used);
45454+ printk(" is_clone:%d", skb->is_clone);
45455+#endif /* NETDEV_23 */
45456+ printk(" cloned:%d", skb->cloned);
45457+ printk(" pkt_type:%d", skb->pkt_type);
45458+ printk(" ip_summed:%d", skb->ip_summed);
45459+ printk(" priority:%d", skb->priority);
45460+ printk(" protocol:%d", skb->protocol);
45461+#ifdef HAVE_SOCK_SECURITY
45462+ printk(" security:%d", skb->security);
45463+#endif
45464+ printk(" truesize:%d", skb->truesize);
45465+ printk(" head:0p%p", skb->head);
45466+ printk(" data:0p%p", skb->data);
45467+ printk(" tail:0p%p", skb_tail_pointer(skb));
45468+ printk(" end:0p%p", skb_end_pointer(skb));
45469+ if(sysctl_ipsec_debug_verbose) {
45470+ unsigned char* i;
45471+ printk(" data");
45472+ for(i = skb->head; i < skb_end_pointer(skb); i++) {
45473+ printk(":%2x", (unsigned char)(*(i)));
45474+ }
45475+ }
45476+ printk(" destructor:0p%p", skb->destructor);
45477+ printk("\n");
45478+ }
45479+#endif /* CONFIG_KLIPS_DEBUG */
45480+ KLIPS_PRINT(debug_pfkey,
45481+ "klips_debug:pfkey_destroy_socket: "
45482+ "skb=0p%p freed.\n",
45483+ skb);
45484+ ipsec_kfree_skb(skb);
45485+ }
45486+
45487+#ifdef NET_26
45488+ sock_set_flag(sk, SOCK_DEAD);
45489+#else
45490+ sk->dead = 1;
45491+#endif
45492+ sk_free(sk);
45493+
45494+ KLIPS_PRINT(debug_pfkey,
45495+ "klips_debug:pfkey_destroy_socket: destroyed.\n");
45496+}
45497+
45498+int
45499+pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
45500+{
45501+ int error = 0;
45502+ struct sk_buff * skb = NULL;
45503+ struct sock *sk;
45504+
45505+ if(sock == NULL) {
45506+ KLIPS_PRINT(debug_pfkey,
45507+ "klips_debug:pfkey_upmsg: "
45508+ "NULL socket passed in.\n");
45509+ return -EINVAL;
45510+ }
45511+
45512+ if(pfkey_msg == NULL) {
45513+ KLIPS_PRINT(debug_pfkey,
45514+ "klips_debug:pfkey_upmsg: "
45515+ "NULL pfkey_msg passed in.\n");
45516+ return -EINVAL;
45517+ }
45518+
45519+ sk = sock->sk;
45520+
45521+ if(sk == NULL) {
45522+ KLIPS_PRINT(debug_pfkey,
45523+ "klips_debug:pfkey_upmsg: "
45524+ "NULL sock passed in.\n");
45525+ return -EINVAL;
45526+ }
45527+
45528+ KLIPS_PRINT(debug_pfkey,
45529+ "klips_debug:pfkey_upmsg: "
45530+ "allocating %d bytes...\n",
45531+ (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
45532+ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
45533+ KLIPS_PRINT(debug_pfkey,
45534+ "klips_debug:pfkey_upmsg: "
45535+ "no buffers left to send up a message.\n");
45536+ return -ENOBUFS;
45537+ }
45538+ KLIPS_PRINT(debug_pfkey,
45539+ "klips_debug:pfkey_upmsg: "
45540+ "...allocated at 0p%p.\n",
45541+ skb);
45542+
45543+ skb->dev = NULL;
45544+
45545+ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
45546+ printk(KERN_WARNING "klips_error:pfkey_upmsg: "
45547+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
45548+ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
45549+ skb_tailroom(skb));
45550+ ipsec_kfree_skb(skb);
45551+ return -ENOBUFS;
45552+ }
45553+ skb_set_transport_header(skb, ipsec_skb_offset(skb, skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)));
45554+ memcpy(skb_transport_header(skb), pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
45555+
45556+ if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
45557+ skb->sk=NULL;
45558+ KLIPS_PRINT(debug_pfkey,
45559+ "klips_debug:pfkey_upmsg: "
45560+ "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
45561+ error,
45562+ skb);
45563+ ipsec_kfree_skb(skb);
45564+ return error;
45565+ }
45566+ return error;
45567+}
45568+
45569+#ifdef NET_26_12_SKALLOC
45570+static struct proto key_proto = {
45571+ .name = "KEY",
45572+ .owner = THIS_MODULE,
45573+ .obj_size = sizeof(struct sock),
45574+
45575+};
45576+#endif
45577+
45578+DEBUG_NO_STATIC int
45579+pfkey_create(struct socket *sock, int protocol)
45580+{
45581+ struct sock *sk;
45582+
45583+ if(sock == NULL) {
45584+ KLIPS_PRINT(debug_pfkey,
45585+ "klips_debug:pfkey_create: "
45586+ "socket NULL.\n");
45587+ return -EINVAL;
45588+ }
45589+
45590+ KLIPS_PRINT(debug_pfkey,
45591+ "klips_debug:pfkey_create: "
45592+ "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
45593+ sock,
45594+ sock->type,
45595+ (unsigned int)(sock->state),
45596+ sock->flags, protocol);
45597+
45598+ if(sock->type != SOCK_RAW) {
45599+ KLIPS_PRINT(debug_pfkey,
45600+ "klips_debug:pfkey_create: "
45601+ "only SOCK_RAW supported.\n");
45602+ return -ESOCKTNOSUPPORT;
45603+ }
45604+
45605+ if(protocol != PF_KEY_V2) {
45606+ KLIPS_PRINT(debug_pfkey,
45607+ "klips_debug:pfkey_create: "
45608+ "protocol not PF_KEY_V2.\n");
45609+ return -EPROTONOSUPPORT;
45610+ }
45611+
45612+ if((current->uid != 0)) {
45613+ KLIPS_PRINT(debug_pfkey,
45614+ "klips_debug:pfkey_create: "
45615+ "must be root to open pfkey sockets.\n");
45616+ return -EACCES;
45617+ }
45618+
45619+ sock->state = SS_UNCONNECTED;
45620+
45621+ KLIPS_INC_USE;
45622+
45623+#ifdef NET_26
45624+#ifdef NET_26_12_SKALLOC
45625+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
45626+#else
45627+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);
45628+#endif
45629+#else
45630+ /* 2.4 interface */
45631+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1);
45632+#endif
45633+
45634+ if(sk == NULL)
45635+ {
45636+ KLIPS_PRINT(debug_pfkey,
45637+ "klips_debug:pfkey_create: "
45638+ "Out of memory trying to allocate.\n");
45639+ KLIPS_DEC_USE;
45640+ return -ENOMEM;
45641+ }
45642+
45643+ sock_init_data(sock, sk);
45644+
45645+ sk->sk_destruct = NULL;
45646+ sk->sk_reuse = 1;
45647+ sock->ops = &pfkey_ops;
45648+
45649+ sk->sk_family = PF_KEY;
45650+/* sk->num = protocol; */
45651+ sk->sk_protocol = protocol;
45652+ key_pid(sk) = current->pid;
45653+ KLIPS_PRINT(debug_pfkey,
45654+ "klips_debug:pfkey_create: "
45655+ "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
45656+ sock->fasync_list,
45657+ sk->sk_sleep);
45658+
45659+ pfkey_insert_socket(sk);
45660+ pfkey_list_insert_socket(sock, &pfkey_open_sockets);
45661+
45662+ KLIPS_PRINT(debug_pfkey,
45663+ "klips_debug:pfkey_create: "
45664+ "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
45665+ return 0;
45666+}
45667+
45668+DEBUG_NO_STATIC int
45669+#ifdef NETDEV_23
45670+pfkey_release(struct socket *sock)
45671+#else /* NETDEV_23 */
45672+pfkey_release(struct socket *sock, struct socket *peersock)
45673+#endif /* NETDEV_23 */
45674+{
45675+ struct sock *sk;
45676+ int i;
45677+
45678+ if(sock==NULL) {
45679+ KLIPS_PRINT(debug_pfkey,
45680+ "klips_debug:pfkey_release: "
45681+ "No socket attached.\n");
45682+ return 0; /* -EINVAL; */
45683+ }
45684+
45685+ sk=sock->sk;
45686+
45687+ /* May not have data attached */
45688+ if(sk==NULL) {
45689+ KLIPS_PRINT(debug_pfkey,
45690+ "klips_debug:pfkey_release: "
45691+ "No sk attached to sock=0p%p.\n", sock);
45692+ return 0; /* -EINVAL; */
45693+ }
45694+
45695+ KLIPS_PRINT(debug_pfkey,
45696+ "klips_debug:pfkey_release: "
45697+ "sock=0p%p sk=0p%p\n", sock, sk);
45698+
45699+ if(sock_flag(sk, SOCK_DEAD))
45700+ if(sk->sk_state_change) {
45701+ sk->sk_state_change(sk);
45702+ }
45703+
45704+ sock->sk = NULL;
45705+
45706+ /* Try to flush out this socket. Throw out buffers at least */
45707+ pfkey_destroy_socket(sk);
45708+ pfkey_list_remove_socket(sock, &pfkey_open_sockets);
45709+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
45710+ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
45711+ }
45712+
45713+ KLIPS_DEC_USE;
45714+ KLIPS_PRINT(debug_pfkey,
45715+ "klips_debug:pfkey_release: "
45716+ "succeeded.\n");
45717+
45718+ return 0;
45719+}
45720+
45721+DEBUG_NO_STATIC int
45722+pfkey_shutdown(struct socket *sock, int mode)
45723+{
45724+ struct sock *sk;
45725+
45726+ if(sock == NULL) {
45727+ KLIPS_PRINT(debug_pfkey,
45728+ "klips_debug:pfkey_shutdown: "
45729+ "NULL socket passed in.\n");
45730+ return -EINVAL;
45731+ }
45732+
45733+ sk=sock->sk;
45734+
45735+ if(sk == NULL) {
45736+ KLIPS_PRINT(debug_pfkey,
45737+ "klips_debug:pfkey_shutdown: "
45738+ "No sock attached to socket.\n");
45739+ return -EINVAL;
45740+ }
45741+
45742+ KLIPS_PRINT(debug_pfkey,
45743+ "klips_debug:pfkey_shutdown: "
45744+ "mode=%x.\n", mode);
45745+ mode++;
45746+
45747+ if(mode&SEND_SHUTDOWN) {
45748+ sk->sk_shutdown|=SEND_SHUTDOWN;
45749+ sk->sk_state_change(sk);
45750+ }
45751+
45752+ if(mode&RCV_SHUTDOWN) {
45753+ sk->sk_shutdown|=RCV_SHUTDOWN;
45754+ sk->sk_state_change(sk);
45755+ }
45756+ return 0;
45757+}
45758+
45759+/*
45760+ * Send PF_KEY data down.
45761+ */
45762+
45763+DEBUG_NO_STATIC int
45764+#ifdef NET_26
45765+pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
45766+#else
45767+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
45768+#endif
45769+{
45770+ struct sock *sk;
45771+ int error = 0;
45772+ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
45773+
45774+ if(sock == NULL) {
45775+ KLIPS_PRINT(debug_pfkey,
45776+ "klips_debug:pfkey_sendmsg: "
45777+ "Null socket passed in.\n");
45778+ SENDERR(EINVAL);
45779+ }
45780+
45781+ sk = sock->sk;
45782+
45783+ if(sk == NULL) {
45784+ KLIPS_PRINT(debug_pfkey,
45785+ "klips_debug:pfkey_sendmsg: "
45786+ "Null sock passed in.\n");
45787+ SENDERR(EINVAL);
45788+ }
45789+
45790+ if(msg == NULL) {
45791+ KLIPS_PRINT(debug_pfkey,
45792+ "klips_debug:pfkey_sendmsg: "
45793+ "Null msghdr passed in.\n");
45794+ SENDERR(EINVAL);
45795+ }
45796+
45797+ KLIPS_PRINT(debug_pfkey,
45798+ "klips_debug:pfkey_sendmsg: .\n");
45799+ if(sk->sk_err) {
45800+ error = sock_error(sk);
45801+ KLIPS_PRINT(debug_pfkey,
45802+ "klips_debug:pfkey_sendmsg: "
45803+ "sk->err is non-zero, returns %d.\n",
45804+ error);
45805+ SENDERR(-error);
45806+ }
45807+
45808+ if((current->uid != 0)) {
45809+ KLIPS_PRINT(debug_pfkey,
45810+ "klips_debug:pfkey_sendmsg: "
45811+ "must be root to send messages to pfkey sockets.\n");
45812+ SENDERR(EACCES);
45813+ }
45814+
45815+ if(msg->msg_control)
45816+ {
45817+ KLIPS_PRINT(debug_pfkey,
45818+ "klips_debug:pfkey_sendmsg: "
45819+ "can't set flags or set msg_control.\n");
45820+ SENDERR(EINVAL);
45821+ }
45822+
45823+ if(sk->sk_shutdown & SEND_SHUTDOWN) {
45824+ KLIPS_PRINT(debug_pfkey,
45825+ "klips_debug:pfkey_sendmsg: "
45826+ "shutdown.\n");
45827+ send_sig(SIGPIPE, current, 0);
45828+ SENDERR(EPIPE);
45829+ }
45830+
45831+ if(len < sizeof(struct sadb_msg)) {
45832+ KLIPS_PRINT(debug_pfkey,
45833+ "klips_debug:pfkey_sendmsg: "
45834+ "bogus msg len of %d, too small.\n", (int)len);
45835+ SENDERR(EMSGSIZE);
45836+ }
45837+
45838+ KLIPS_PRINT(debug_pfkey,
45839+ "klips_debug:pfkey_sendmsg: "
45840+ "allocating %d bytes for downward message.\n",
45841+ (int)len);
45842+ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
45843+ KLIPS_PRINT(debug_pfkey,
45844+ "klips_debug:pfkey_sendmsg: "
45845+ "memory allocation error.\n");
45846+ SENDERR(ENOBUFS);
45847+ }
45848+
45849+ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
45850+
45851+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
45852+ KLIPS_PRINT(1 || debug_pfkey,
45853+ "klips_debug:pfkey_sendmsg: "
45854+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
45855+ pfkey_msg->sadb_msg_version,
45856+ PF_KEY_V2);
45857+ kfree((void*)pfkey_msg);
45858+ return -EINVAL;
45859+ }
45860+
45861+ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
45862+ KLIPS_PRINT(debug_pfkey,
45863+ "klips_debug:pfkey_sendmsg: "
45864+ "bogus msg len of %d, not %d byte aligned.\n",
45865+ (int)len, (int)IPSEC_PFKEYv2_ALIGN);
45866+ SENDERR(EMSGSIZE);
45867+ }
45868+
45869+#if 0
45870+ /* This check is questionable, since a downward message could be
45871+ the result of an ACQUIRE either from kernel (PID==0) or
45872+ userspace (some other PID). */
45873+ /* check PID */
45874+ if(pfkey_msg->sadb_msg_pid != current->pid) {
45875+ KLIPS_PRINT(debug_pfkey,
45876+ "klips_debug:pfkey_sendmsg: "
45877+ "pid (%d) does not equal sending process pid (%d).\n",
45878+ pfkey_msg->sadb_msg_pid, current->pid);
45879+ SENDERR(EINVAL);
45880+ }
45881+#endif
45882+
45883+ if(pfkey_msg->sadb_msg_reserved) {
45884+ KLIPS_PRINT(debug_pfkey,
45885+ "klips_debug:pfkey_sendmsg: "
45886+ "reserved field must be zero, set to %d.\n",
45887+ pfkey_msg->sadb_msg_reserved);
45888+ SENDERR(EINVAL);
45889+ }
45890+
45891+ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
45892+ KLIPS_PRINT(debug_pfkey,
45893+ "klips_debug:pfkey_sendmsg: "
45894+ "msg type too large or small:%d.\n",
45895+ pfkey_msg->sadb_msg_type);
45896+ SENDERR(EINVAL);
45897+ }
45898+
45899+ KLIPS_PRINT(debug_pfkey,
45900+ "klips_debug:pfkey_sendmsg: "
45901+ "msg sent for parsing.\n");
45902+
45903+ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
45904+ struct socket_list *pfkey_socketsp;
45905+
45906+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45907+ "pfkey_msg_parse returns %d.\n",
45908+ error);
45909+
45910+ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
45911+ KLIPS_PRINT(debug_pfkey,
45912+ "klips_debug:pfkey_sendmsg: "
45913+ "memory allocation error.\n");
45914+ SENDERR(ENOBUFS);
45915+ }
45916+ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
45917+ pfkey_reply->sadb_msg_errno = -error;
45918+ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
45919+
45920+ for(pfkey_socketsp = pfkey_open_sockets;
45921+ pfkey_socketsp;
45922+ pfkey_socketsp = pfkey_socketsp->next) {
45923+ int error_upmsg = 0;
45924+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45925+ "sending up error=%d message=0p%p to socket=0p%p.\n",
45926+ error,
45927+ pfkey_reply,
45928+ pfkey_socketsp->socketp);
45929+ if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
45930+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45931+ "sending up error message to socket=0p%p failed with error=%d.\n",
45932+ pfkey_socketsp->socketp,
45933+ error_upmsg);
45934+ /* pfkey_msg_free(&pfkey_reply); */
45935+ /* SENDERR(-error); */
45936+ }
45937+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45938+ "sending up error message to socket=0p%p succeeded.\n",
45939+ pfkey_socketsp->socketp);
45940+ }
45941+
45942+ pfkey_msg_free(&pfkey_reply);
45943+
45944+ SENDERR(-error);
45945+ }
45946+
45947+ errlab:
45948+ if (pfkey_msg) {
45949+ kfree((void*)pfkey_msg);
45950+ }
45951+
45952+ if(error) {
45953+ return error;
45954+ } else {
45955+ return len;
45956+ }
45957+}
45958+
45959+/*
45960+ * Receive PF_KEY data up.
45961+ */
45962+
45963+DEBUG_NO_STATIC int
45964+#ifdef NET_26
45965+pfkey_recvmsg(struct kiocb *kiocb
45966+ , struct socket *sock
45967+ , struct msghdr *msg
45968+ , size_t size
45969+ , int flags)
45970+#else
45971+pfkey_recvmsg(struct socket *sock
45972+ , struct msghdr *msg
45973+ , int size, int flags
45974+ , struct scm_cookie *scm)
45975+#endif
45976+{
45977+ struct sock *sk;
45978+ int noblock = flags & MSG_DONTWAIT;
45979+ struct sk_buff *skb;
45980+ int error;
45981+
45982+ if(sock == NULL) {
45983+ KLIPS_PRINT(debug_pfkey,
45984+ "klips_debug:pfkey_recvmsg: "
45985+ "Null socket passed in.\n");
45986+ return -EINVAL;
45987+ }
45988+
45989+ sk = sock->sk;
45990+
45991+ if(sk == NULL) {
45992+ KLIPS_PRINT(debug_pfkey,
45993+ "klips_debug:pfkey_recvmsg: "
45994+ "Null sock passed in for sock=0p%p.\n", sock);
45995+ return -EINVAL;
45996+ }
45997+
45998+ if(msg == NULL) {
45999+ KLIPS_PRINT(debug_pfkey,
46000+ "klips_debug:pfkey_recvmsg: "
46001+ "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
46002+ sock, sk);
46003+ return -EINVAL;
46004+ }
46005+
46006+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
46007+ "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
46008+ sock, sk, msg, (int)size);
46009+ if(flags & ~MSG_PEEK) {
46010+ KLIPS_PRINT(debug_pfkey,
46011+ "klips_debug:pfkey_sendmsg: "
46012+ "flags (%d) other than MSG_PEEK not supported.\n",
46013+ flags);
46014+ return -EOPNOTSUPP;
46015+ }
46016+
46017+ msg->msg_namelen = 0; /* sizeof(*ska); */
46018+
46019+ if(sk->sk_err) {
46020+ KLIPS_PRINT(debug_pfkey,
46021+ "klips_debug:pfkey_sendmsg: "
46022+ "sk->sk_err=%d.\n", sk->sk_err);
46023+ return sock_error(sk);
46024+ }
46025+
46026+ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
46027+ return error;
46028+ }
46029+
46030+ if(size > skb->len) {
46031+ size = skb->len;
46032+ }
46033+ else if(size <skb->len) {
46034+ msg->msg_flags |= MSG_TRUNC;
46035+ }
46036+
46037+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
46038+#ifdef HAVE_KERNEL_TSTAMP
46039+ sk->sk_stamp = skb->tstamp;
46040+#elif defined(HAVE_TSTAMP)
46041+ sk->sk_stamp.tv_sec = skb->tstamp.off_sec;
46042+ sk->sk_stamp.tv_usec = skb->tstamp.off_usec;
46043+#else
46044+ sk->sk_stamp=skb->stamp;
46045+#endif
46046+
46047+ skb_free_datagram(sk, skb);
46048+ return size;
46049+}
46050+
46051+#ifdef CONFIG_PROC_FS
46052+#ifndef PROC_FS_2325
46053+DEBUG_NO_STATIC
46054+#endif /* PROC_FS_2325 */
46055+int
46056+pfkey_get_info(char *buffer, char **start, off_t offset, int length
46057+#ifndef PROC_NO_DUMMY
46058+, int dummy
46059+#endif /* !PROC_NO_DUMMY */
46060+)
46061+{
46062+ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
46063+#ifdef NET_26
46064+ struct hlist_node *node;
46065+#endif
46066+ off_t begin=0;
46067+ int len=0;
46068+ struct sock *sk;
46069+
46070+#ifdef CONFIG_KLIPS_DEBUG
46071+ if(!sysctl_ipsec_debug_verbose) {
46072+#endif /* CONFIG_KLIPS_DEBUG */
46073+ len += ipsec_snprintf(buffer, length,
46074+ " sock pid socket next prev e n p sndbf Flags Type St\n");
46075+#ifdef CONFIG_KLIPS_DEBUG
46076+ } else {
46077+ len += ipsec_snprintf(buffer, length,
46078+ " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
46079+ }
46080+#endif /* CONFIG_KLIPS_DEBUG */
46081+
46082+ sk_for_each(sk, node, &pfkey_sock_list) {
46083+
46084+#ifdef CONFIG_KLIPS_DEBUG
46085+ if(!sysctl_ipsec_debug_verbose) {
46086+#endif /* CONFIG_KLIPS_DEBUG */
46087+ len += ipsec_snprintf(buffer+len, length-len,
46088+ "%8p %5d %8p %d %d %5d %08lX %8X %2X\n",
46089+ sk,
46090+ key_pid(sk),
46091+ sk->sk_socket,
46092+ sk->sk_err,
46093+ sk->sk_protocol,
46094+ sk->sk_sndbuf,
46095+ sk->sk_socket->flags,
46096+ sk->sk_socket->type,
46097+ sk->sk_socket->state);
46098+#ifdef CONFIG_KLIPS_DEBUG
46099+ } else {
46100+ struct timeval t;
46101+ grab_socket_timeval(t, *sk);
46102+ len += ipsec_snprintf(buffer+len, length-len,
46103+ "%8p %5d %d %8p %8p %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
46104+ sk,
46105+ key_pid(sk),
46106+ sock_flag(sk, SOCK_DEAD),
46107+ sk->sk_sleep,
46108+ sk->sk_socket,
46109+ sk->sk_err,
46110+ sk->sk_reuse,
46111+#ifdef HAVE_SOCK_ZAPPED
46112+ sock_flag(sk, SOCK_ZAPPED),
46113+#else
46114+ sk->sk_zapped,
46115+#endif
46116+ sk->sk_protocol,
46117+ sk->sk_sndbuf,
46118+ (unsigned int)t.tv_sec,
46119+ (unsigned int)t.tv_usec,
46120+ sk->sk_socket->flags,
46121+ sk->sk_socket->type,
46122+ sk->sk_socket->state);
46123+ }
46124+#endif /* CONFIG_KLIPS_DEBUG */
46125+
46126+ if (len >= max_content) {
46127+ /* we've done all that can fit -- stop loop */
46128+ len = max_content; /* truncate crap */
46129+ break;
46130+ } else {
46131+ const off_t pos = begin + len; /* file position of end of what we've generated */
46132+
46133+ if (pos <= offset) {
46134+ /* all is before first interesting character:
46135+ * discard, but note where we are.
46136+ */
46137+ len = 0;
46138+ begin = pos;
46139+ }
46140+ }
46141+ }
46142+
46143+ *start = buffer + (offset - begin); /* Start of wanted data */
46144+ return len - (offset - begin);
46145+}
46146+
46147+#ifndef PROC_FS_2325
46148+DEBUG_NO_STATIC
46149+#endif /* PROC_FS_2325 */
46150+int
46151+pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
46152+#ifndef PROC_NO_DUMMY
46153+, int dummy
46154+#endif /* !PROC_NO_DUMMY */
46155+)
46156+{
46157+ /* limit of useful snprintf output */
46158+ const int max_content = length > 0? length-1 : 0;
46159+ off_t begin=0;
46160+ int len=0;
46161+ int satype;
46162+ struct supported_list *ps;
46163+
46164+ len += ipsec_snprintf(buffer, length,
46165+ "satype exttype alg_id ivlen minbits maxbits name\n");
46166+
46167+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
46168+ ps = pfkey_supported_list[satype];
46169+ while(ps) {
46170+ struct ipsec_alg_supported *alg = ps->supportedp;
46171+ unsigned char *n = alg->ias_name;
46172+ if(n == NULL) n = "unknown";
46173+
46174+ len += ipsec_snprintf(buffer+len, length-len,
46175+ " %2d %2d %2d %3d %3d %3d %20s\n",
46176+ satype,
46177+ alg->ias_exttype,
46178+ alg->ias_id,
46179+ alg->ias_ivlen,
46180+ alg->ias_keyminbits,
46181+ alg->ias_keymaxbits,
46182+ n);
46183+
46184+ if (len >= max_content) {
46185+ /* we've done all that can fit -- stop loop */
46186+ len = max_content; /* truncate crap */
46187+ break;
46188+ } else {
46189+ const off_t pos = begin + len; /* file position of end of what we've generated */
46190+
46191+ if (pos <= offset) {
46192+ /* all is before first interesting character:
46193+ * discard, but note where we are.
46194+ */
46195+ len = 0;
46196+ begin = pos;
46197+ }
46198+ }
46199+
46200+ ps = ps->next;
46201+ }
46202+ }
46203+ *start = buffer + (offset - begin); /* Start of wanted data */
46204+ return len - (offset - begin);
46205+}
46206+
46207+#ifndef PROC_FS_2325
46208+DEBUG_NO_STATIC
46209+#endif /* PROC_FS_2325 */
46210+int
46211+pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
46212+#ifndef PROC_NO_DUMMY
46213+, int dummy
46214+#endif /* !PROC_NO_DUMMY */
46215+)
46216+{
46217+ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
46218+ off_t begin=0;
46219+ int len=0;
46220+ int satype;
46221+ struct socket_list *pfkey_sockets;
46222+
46223+ len += ipsec_snprintf(buffer, length,
46224+ "satype socket pid sk\n");
46225+
46226+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
46227+ pfkey_sockets = pfkey_registered_sockets[satype];
46228+ while(pfkey_sockets) {
46229+ len += ipsec_snprintf(buffer+len, length-len,
46230+ " %2d %8p %5d %8p\n",
46231+ satype,
46232+ pfkey_sockets->socketp,
46233+ key_pid(pfkey_sockets->socketp->sk),
46234+ pfkey_sockets->socketp->sk);
46235+
46236+ if (len >= max_content) {
46237+ /* we've done all that can fit -- stop loop (could stop two) */
46238+ len = max_content; /* truncate crap */
46239+ break;
46240+ } else {
46241+ const off_t pos = begin + len; /* file position of end of what we've generated */
46242+
46243+ if (pos <= offset) {
46244+ /* all is before first interesting character:
46245+ * discard, but note where we are.
46246+ */
46247+ len = 0;
46248+ begin = pos;
46249+ }
46250+ }
46251+
46252+ pfkey_sockets = pfkey_sockets->next;
46253+ }
46254+ }
46255+ *start = buffer + (offset - begin); /* Start of wanted data */
46256+ return len - (offset - begin);
46257+}
46258+
46259+#ifndef PROC_FS_2325
46260+struct proc_dir_entry proc_net_pfkey =
46261+{
46262+ 0,
46263+ 6, "pf_key",
46264+ S_IFREG | S_IRUGO, 1, 0, 0,
46265+ 0, &proc_net_inode_operations,
46266+ pfkey_get_info
46267+};
46268+struct proc_dir_entry proc_net_pfkey_supported =
46269+{
46270+ 0,
46271+ 16, "pf_key_supported",
46272+ S_IFREG | S_IRUGO, 1, 0, 0,
46273+ 0, &proc_net_inode_operations,
46274+ pfkey_supported_get_info
46275+};
46276+struct proc_dir_entry proc_net_pfkey_registered =
46277+{
46278+ 0,
46279+ 17, "pf_key_registered",
46280+ S_IFREG | S_IRUGO, 1, 0, 0,
46281+ 0, &proc_net_inode_operations,
46282+ pfkey_registered_get_info
46283+};
46284+#endif /* !PROC_FS_2325 */
46285+#endif /* CONFIG_PROC_FS */
46286+
46287+DEBUG_NO_STATIC int
46288+supported_add_all(int satype, struct ipsec_alg_supported supported[], int size)
46289+{
46290+ int i;
46291+ int error = 0;
46292+
46293+ KLIPS_PRINT(debug_pfkey,
46294+ "klips_debug:init_pfkey: "
46295+ "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct ipsec_alg_supported)[%d]=%d.\n",
46296+ satype,
46297+ size,
46298+ (int)sizeof(struct ipsec_alg_supported),
46299+ (int)(size/sizeof(struct ipsec_alg_supported)));
46300+
46301+ for(i = 0; i < size / sizeof(struct ipsec_alg_supported); i++) {
46302+
46303+ unsigned char *n = supported[i].ias_name;
46304+ if(n == NULL) n="unknown";
46305+
46306+ KLIPS_PRINT(debug_pfkey,
46307+ "klips_debug:init_pfkey: "
46308+ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
46309+ i,
46310+ satype,
46311+ supported[i].ias_exttype,
46312+ supported[i].ias_id,
46313+ supported[i].ias_ivlen,
46314+ supported[i].ias_keyminbits,
46315+ supported[i].ias_keymaxbits,
46316+ n);
46317+
46318+ error |= pfkey_list_insert_supported(&(supported[i]),
46319+ &(pfkey_supported_list[satype]));
46320+ }
46321+ return error;
46322+}
46323+
46324+DEBUG_NO_STATIC int
46325+supported_remove_all(int satype)
46326+{
46327+ int error = 0;
46328+ struct ipsec_alg_supported*supportedp;
46329+
46330+ while(pfkey_supported_list[satype]) {
46331+ unsigned char *n;
46332+ supportedp = pfkey_supported_list[satype]->supportedp;
46333+
46334+ n = supportedp->ias_name;
46335+ if(n == NULL) n="unknown";
46336+
46337+ KLIPS_PRINT(debug_pfkey,
46338+ "klips_debug:init_pfkey: "
46339+ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
46340+ satype,
46341+ supportedp->ias_exttype,
46342+ supportedp->ias_id,
46343+ supportedp->ias_ivlen,
46344+ supportedp->ias_keyminbits,
46345+ supportedp->ias_keymaxbits, n);
46346+
46347+ error |= pfkey_list_remove_supported(supportedp,
46348+ &(pfkey_supported_list[satype]));
46349+ }
46350+ return error;
46351+}
46352+
46353+int
46354+pfkey_init(void)
46355+{
46356+ int error = 0;
46357+ int i;
46358+
46359+ static struct ipsec_alg_supported supported_init_ah[] = {
46360+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
46361+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
46362+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
46363+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
46364+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
46365+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
46366+ };
46367+ static struct ipsec_alg_supported supported_init_esp[] = {
46368+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
46369+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
46370+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
46371+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
46372+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
46373+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
46374+#ifdef CONFIG_KLIPS_ENC_3DES
46375+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168},
46376+#endif /* CONFIG_KLIPS_ENC_3DES */
46377+ };
46378+ static struct ipsec_alg_supported supported_init_ipip[] = {
46379+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
46380+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
46381+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
46382+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
46383+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
46384+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
46385+ };
46386+#ifdef CONFIG_KLIPS_IPCOMP
46387+ static struct ipsec_alg_supported supported_init_ipcomp[] = {
46388+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
46389+ };
46390+#endif /* CONFIG_KLIPS_IPCOMP */
46391+
46392+#if 0
46393+ printk(KERN_INFO
46394+ "klips_info:pfkey_init: "
46395+ "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
46396+#endif
46397+
46398+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
46399+ pfkey_registered_sockets[i] = NULL;
46400+ pfkey_supported_list[i] = NULL;
46401+ }
46402+
46403+ error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
46404+ error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
46405+#ifdef CONFIG_KLIPS_IPCOMP
46406+ error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
46407+#endif /* CONFIG_KLIPS_IPCOMP */
46408+ error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
46409+
46410+ error |= sock_register(&pfkey_family_ops);
46411+
46412+#ifdef CONFIG_PROC_FS
46413+# ifndef PROC_FS_2325
46414+# ifdef PROC_FS_21
46415+ error |= proc_register(proc_net, &proc_net_pfkey);
46416+ error |= proc_register(proc_net, &proc_net_pfkey_supported);
46417+ error |= proc_register(proc_net, &proc_net_pfkey_registered);
46418+# else /* PROC_FS_21 */
46419+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
46420+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
46421+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
46422+# endif /* PROC_FS_21 */
46423+# else /* !PROC_FS_2325 */
46424+ proc_net_create ("pf_key", 0, pfkey_get_info);
46425+ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
46426+ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
46427+# endif /* !PROC_FS_2325 */
46428+#endif /* CONFIG_PROC_FS */
46429+
46430+ return error;
46431+}
46432+
46433+int
46434+pfkey_cleanup(void)
46435+{
46436+ int error = 0;
46437+
46438+ printk(KERN_INFO "klips_info:pfkey_cleanup: "
46439+ "shutting down PF_KEY domain sockets.\n");
46440+#ifdef VOID_SOCK_UNREGISTER
46441+ sock_unregister(PF_KEY);
46442+#else
46443+ sock_unregister(PF_KEY);
46444+#endif
46445+
46446+ error |= supported_remove_all(SADB_SATYPE_AH);
46447+ error |= supported_remove_all(SADB_SATYPE_ESP);
46448+#ifdef CONFIG_KLIPS_IPCOMP
46449+ error |= supported_remove_all(SADB_X_SATYPE_COMP);
46450+#endif /* CONFIG_KLIPS_IPCOMP */
46451+ error |= supported_remove_all(SADB_X_SATYPE_IPIP);
46452+
46453+#ifdef CONFIG_PROC_FS
46454+# ifndef PROC_FS_2325
46455+ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
46456+ printk("klips_debug:pfkey_cleanup: "
46457+ "cannot unregister /proc/net/pf_key\n");
46458+ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
46459+ printk("klips_debug:pfkey_cleanup: "
46460+ "cannot unregister /proc/net/pf_key_supported\n");
46461+ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
46462+ printk("klips_debug:pfkey_cleanup: "
46463+ "cannot unregister /proc/net/pf_key_registered\n");
46464+# else /* !PROC_FS_2325 */
46465+ proc_net_remove ("pf_key");
46466+ proc_net_remove ("pf_key_supported");
46467+ proc_net_remove ("pf_key_registered");
46468+# endif /* !PROC_FS_2325 */
46469+#endif /* CONFIG_PROC_FS */
46470+
46471+ /* other module unloading cleanup happens here */
46472+ return error;
46473+}
46474+
46475+#ifdef MODULE
46476+#if 0
46477+int
46478+init_module(void)
46479+{
46480+ pfkey_init();
46481+ return 0;
46482+}
46483+
46484+void
46485+cleanup_module(void)
46486+{
46487+ pfkey_cleanup();
46488+}
46489+#endif /* 0 */
46490+#else /* MODULE */
46491+struct net_protocol;
46492+void pfkey_proto_init(struct net_protocol *pro)
46493+{
46494+ pfkey_init();
46495+}
46496+#endif /* MODULE */
46497+
46498+/*
46499+ * $Log: pfkey_v2.c,v $
46500+ * Revision 1.97.2.16 2007-10-31 19:57:41 paul
46501+ * type of sock.sk_stamp changed from timeval to ktime [dhr]
46502+ *
46503+ * Revision 1.97.2.15 2007-10-30 21:39:30 paul
46504+ * Use skb_tail_pointer/skb_end_pointer [dhr]
46505+ *
46506+ * Revision 1.97.2.14 2007/09/05 02:56:10 paul
46507+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
46508+ * Fixes based on David McCullough patch.
46509+ *
46510+ * Revision 1.97.2.13 2007/08/10 01:40:49 paul
46511+ * Fix for sock_unregister for 2.6.19 by Sergeil
46512+ *
46513+ * Revision 1.97.2.12 2006/11/24 05:43:29 paul
46514+ * kernels after 2.6.18 do not return a code from unregister_socket()
46515+ * backport from git 41e54a2684dc809d7952e816860ea646a3194a72
46516+ *
46517+ * Revision 1.97.2.11 2006/11/15 16:05:57 paul
46518+ * fix for compiling on 2.4. kernels by Matthias Haas.
46519+ *
46520+ * Revision 1.97.2.10 2006/10/10 20:43:28 paul
46521+ * Add family/create/owner for pfkey_family_ops. This fixes bug #671
46522+ *
46523+ * Revision 1.97.2.9 2006/10/06 21:39:26 paul
46524+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
46525+ * set. This is defined through autoconf.h which is included through the
46526+ * linux kernel build macros.
46527+ *
46528+ * Revision 1.97.2.8 2006/07/10 15:56:11 paul
46529+ * Fix for bug #642 by Bart.
46530+ *
46531+ * Revision 1.97.2.7 2006/04/04 11:34:19 ken
46532+ * Backport SMP fixes + #ifdef cleanup from #public
46533+ *
46534+ * Revision 1.97.2.6 2006/02/15 05:00:20 paul
46535+ * Fix for crasher on 2.6.12+ with klips (mostly seen on redhat kernels)
46536+ *
46537+ * Revision 1.97.2.5 2005/11/22 04:11:52 ken
46538+ * Backport fixes for 2.6.14 kernels from HEAD
46539+ *
46540+ * Revision 1.97.2.4 2005/09/14 16:40:45 mcr
46541+ * pull up of compilation on 2.4
46542+ *
46543+ * Revision 1.97.2.3 2005/09/06 02:10:03 mcr
46544+ * pulled up possible SMP-related compilation fix
46545+ *
46546+ * Revision 1.97.2.2 2005/08/28 01:21:12 paul
46547+ * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on
46548+ * SMP kernels.
46549+ *
46550+ * Revision 1.97.2.1 2005/08/27 23:40:00 paul
46551+ * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
46552+ *
46553+ * Revision 1.102 2005/09/14 16:37:23 mcr
46554+ * fix to compile on 2.4.
46555+ *
46556+ * Revision 1.101 2005/09/06 01:42:25 mcr
46557+ * removed additional SOCKOPS_WRAPPED code
46558+ *
46559+ * Revision 1.100 2005/08/30 18:10:15 mcr
46560+ * remove SOCKOPS_WRAPPED() code, add proper locking to the
46561+ * pfkey code. (cross fingers)
46562+ *
46563+ * Revision 1.99 2005/08/28 01:53:37 paul
46564+ * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on SMP kernels.
46565+ *
46566+ * Revision 1.98 2005/08/27 23:07:21 paul
46567+ * Somewhere between 2.6.12 and 2.6.13rc7 the unused security memnber in sk_buff
46568+ * has been removed. This patch should fix compilation for both cases.
46569+ *
46570+ * Revision 1.97 2005/07/20 00:33:36 mcr
46571+ * fixed typo in #ifdef for SKALLOC.
46572+ *
46573+ * Revision 1.96 2005/07/19 20:02:15 mcr
46574+ * sk_alloc() interface change.
46575+ *
46576+ * Revision 1.95 2005/07/09 00:40:06 ken
46577+ * Fix for GCC4 - it doesn't like the potential for duplicate declaration
46578+ *
46579+ * Revision 1.94 2005/07/09 00:14:04 ken
46580+ * Casts for 64bit cleanliness
46581+ *
46582+ * Revision 1.93 2005/07/08 16:20:05 mcr
46583+ * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
46584+ *
46585+ * Revision 1.92 2005/05/21 03:29:39 mcr
46586+ * fixed missing prototype definition.
46587+ *
46588+ * Revision 1.91 2005/05/11 01:43:45 mcr
46589+ * removed "poor-man"s OOP in favour of proper C structures.
46590+ *
46591+ * Revision 1.90 2005/05/02 18:42:47 mcr
46592+ * fix for cut&paste error with pfkey_v2.c "supported_name"
46593+ *
46594+ * Revision 1.89 2005/05/01 03:12:31 mcr
46595+ * print name if it is available.
46596+ *
46597+ * Revision 1.88 2005/04/29 05:10:22 mcr
46598+ * removed from extraenous includes to make unit testing easier.
46599+ *
46600+ * Revision 1.87 2005/04/15 19:57:10 mcr
46601+ * make sure that address has 0p so that it will
46602+ * sanitized.
46603+ *
46604+ * Revision 1.86 2005/04/08 18:28:36 mcr
46605+ * some minor #ifdef simplification in pursuit of a possible bug.
46606+ *
46607+ * Revision 1.85 2004/12/03 21:25:57 mcr
46608+ * compile time fixes for running on 2.6.
46609+ * still experimental.
46610+ *
46611+ * Revision 1.84 2004/08/17 03:27:23 mcr
46612+ * klips 2.6 edits.
46613+ *
46614+ * Revision 1.83 2004/08/04 15:57:07 mcr
46615+ * moved des .h files to include/des/ *
46616+ * included 2.6 protocol specific things
46617+ * started at NAT-T support, but it will require a kernel patch.
46618+ *
46619+ * Revision 1.82 2004/07/10 19:11:18 mcr
46620+ * CONFIG_IPSEC -> CONFIG_KLIPS.
46621+ *
46622+ * Revision 1.81 2004/04/25 21:23:11 ken
46623+ * Pull in dhr's changes from FreeS/WAN 2.06
46624+ *
46625+ * Revision 1.80 2004/04/06 02:49:26 mcr
46626+ * pullup of algo code from alg-branch.
46627+ *
46628+ * Revision 1.79.4.1 2003/12/22 15:25:52 jjo
46629+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
46630+ *
46631+ * Revision 1.79 2003/10/31 02:27:55 mcr
46632+ * pulled up port-selector patches and sa_id elimination.
46633+ *
46634+ * Revision 1.78.4.1 2003/10/29 01:30:41 mcr
46635+ * elimited "struct sa_id".
46636+ *
46637+ * Revision 1.78 2003/04/03 17:38:09 rgb
46638+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
46639+ *
46640+ * Revision 1.77 2002/10/17 16:49:36 mcr
46641+ * sock->ops should reference the unwrapped options so that
46642+ * we get hacked in locking on SMP systems.
46643+ *
46644+ * Revision 1.76 2002/10/12 23:11:53 dhr
46645+ *
46646+ * [KenB + DHR] more 64-bit cleanup
46647+ *
46648+ * Revision 1.75 2002/09/20 05:01:57 rgb
46649+ * Added memory allocation debugging.
46650+ *
46651+ * Revision 1.74 2002/09/19 02:42:50 mcr
46652+ * do not define the pfkey_ops function for now.
46653+ *
46654+ * Revision 1.73 2002/09/17 17:29:23 mcr
46655+ * #if 0 out some dead code - pfkey_ops is never used as written.
46656+ *
46657+ * Revision 1.72 2002/07/24 18:44:54 rgb
46658+ * Type fiddling to tame ia64 compiler.
46659+ *
46660+ * Revision 1.71 2002/05/23 07:14:11 rgb
46661+ * Cleaned up %p variants to 0p%p for test suite cleanup.
46662+ *
46663+ * Revision 1.70 2002/04/24 07:55:32 mcr
46664+ * #include patches and Makefiles for post-reorg compilation.
46665+ *
46666+ * Revision 1.69 2002/04/24 07:36:33 mcr
46667+ * Moved from ./klips/net/ipsec/pfkey_v2.c,v
46668+ *
46669+ * Revision 1.68 2002/03/08 01:15:17 mcr
46670+ * put some internal structure only debug messages behind
46671+ * && sysctl_ipsec_debug_verbose.
46672+ *
46673+ * Revision 1.67 2002/01/29 17:17:57 mcr
46674+ * moved include of ipsec_param.h to after include of linux/kernel.h
46675+ * otherwise, it seems that some option that is set in ipsec_param.h
46676+ * screws up something subtle in the include path to kernel.h, and
46677+ * it complains on the snprintf() prototype.
46678+ *
46679+ * Revision 1.66 2002/01/29 04:00:54 mcr
46680+ * more excise of kversions.h header.
46681+ *
46682+ * Revision 1.65 2002/01/29 02:13:18 mcr
46683+ * introduction of ipsec_kversion.h means that include of
46684+ * ipsec_param.h must preceed any decisions about what files to
46685+ * include to deal with differences in kernel source.
46686+ *
46687+ * Revision 1.64 2001/11/26 09:23:51 rgb
46688+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
46689+ *
46690+ * Revision 1.61.2.1 2001/09/25 02:28:44 mcr
46691+ * cleaned up includes.
46692+ *
46693+ * Revision 1.63 2001/11/12 19:38:00 rgb
46694+ * Continue trying other sockets even if one fails and return only original
46695+ * error.
46696+ *
46697+ * Revision 1.62 2001/10/18 04:45:22 rgb
46698+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
46699+ * lib/freeswan.h version macros moved to lib/kversions.h.
46700+ * Other compiler directive cleanups.
46701+ *
46702+ * Revision 1.61 2001/09/20 15:32:59 rgb
46703+ * Min/max cleanup.
46704+ *
46705+ * Revision 1.60 2001/06/14 19:35:12 rgb
46706+ * Update copyright date.
46707+ *
46708+ * Revision 1.59 2001/06/13 15:35:48 rgb
46709+ * Fixed #endif comments.
46710+ *
46711+ * Revision 1.58 2001/05/04 16:37:24 rgb
46712+ * Remove erroneous checking of return codes for proc_net_* in 2.4.
46713+ *
46714+ * Revision 1.57 2001/05/03 19:43:36 rgb
46715+ * Initialise error return variable.
46716+ * Check error return codes in startup and shutdown.
46717+ * Standardise on SENDERR() macro.
46718+ *
46719+ * Revision 1.56 2001/04/21 23:05:07 rgb
46720+ * Define out skb->used for 2.4 kernels.
46721+ *
46722+ * Revision 1.55 2001/02/28 05:03:28 rgb
46723+ * Clean up and rationalise startup messages.
46724+ *
46725+ * Revision 1.54 2001/02/27 22:24:55 rgb
46726+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
46727+ * Check for satoa() return codes.
46728+ *
46729+ * Revision 1.53 2001/02/27 06:48:18 rgb
46730+ * Fixed pfkey socket unregister log message to reflect type and function.
46731+ *
46732+ * Revision 1.52 2001/02/26 22:34:38 rgb
46733+ * Fix error return code that was getting overwritten by the error return
46734+ * code of an upmsg.
46735+ *
46736+ * Revision 1.51 2001/01/30 23:42:47 rgb
46737+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
46738+ * and subsequent ADD or UDATE.
46739+ *
46740+ * Revision 1.50 2001/01/23 20:22:59 rgb
46741+ * 2.4 fix to remove removed is_clone member.
46742+ *
46743+ * Revision 1.49 2000/11/06 04:33:47 rgb
46744+ * Changed non-exported functions to DEBUG_NO_STATIC.
46745+ *
46746+ * Revision 1.48 2000/09/29 19:47:41 rgb
46747+ * Update copyright.
46748+ *
46749+ * Revision 1.47 2000/09/22 04:23:04 rgb
46750+ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
46751+ *
46752+ * Revision 1.46 2000/09/21 04:20:44 rgb
46753+ * Fixed array size off-by-one error. (Thanks Svenning!)
46754+ *
46755+ * Revision 1.45 2000/09/20 04:01:26 rgb
46756+ * Changed static functions to DEBUG_NO_STATIC for revealing function names
46757+ * in oopsen.
46758+ *
46759+ * Revision 1.44 2000/09/19 00:33:17 rgb
46760+ * 2.0 fixes.
46761+ *
46762+ * Revision 1.43 2000/09/16 01:28:13 rgb
46763+ * Fixed use of 0 in p format warning.
46764+ *
46765+ * Revision 1.42 2000/09/16 01:09:41 rgb
46766+ * Fixed debug format warning for pointers that was expecting ints.
46767+ *
46768+ * Revision 1.41 2000/09/13 15:54:00 rgb
46769+ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
46770+ * Moved supported algos add and remove to functions.
46771+ *
46772+ * Revision 1.40 2000/09/12 18:49:28 rgb
46773+ * Added IPIP tunnel and IPCOMP register support.
46774+ *
46775+ * Revision 1.39 2000/09/12 03:23:49 rgb
46776+ * Converted #if0 debugs to sysctl.
46777+ * Removed debug_pfkey initialisations that prevented no_debug loading or
46778+ * linking.
46779+ *
46780+ * Revision 1.38 2000/09/09 06:38:02 rgb
46781+ * Return positive errno in pfkey_reply error message.
46782+ *
46783+ * Revision 1.37 2000/09/08 19:19:09 rgb
46784+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
46785+ * Clean-up of long-unused crud...
46786+ * Create pfkey error message on on failure.
46787+ * Give pfkey_list_{insert,remove}_{socket,supported}() some error
46788+ * checking.
46789+ *
46790+ * Revision 1.36 2000/09/01 18:49:38 rgb
46791+ * Reap experimental NET_21_ bits.
46792+ * Turned registered sockets list into an array of one list per satype.
46793+ * Remove references to deprecated sklist_{insert,remove}_socket.
46794+ * Removed leaking socket debugging code.
46795+ * Removed duplicate pfkey_insert_socket in pfkey_create.
46796+ * Removed all references to pfkey msg->msg_name, since it is not used for
46797+ * pfkey.
46798+ * Added a supported algorithms array lists, one per satype and registered
46799+ * existing algorithms.
46800+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
46801+ * list.
46802+ * Only send pfkey_expire() messages to sockets registered for that satype.
46803+ *
46804+ * Revision 1.35 2000/08/24 17:03:00 rgb
46805+ * Corrected message size error return code for PF_KEYv2.
46806+ * Removed downward error prohibition.
46807+ *
46808+ * Revision 1.34 2000/08/21 16:32:26 rgb
46809+ * Re-formatted for cosmetic consistency and readability.
46810+ *
46811+ * Revision 1.33 2000/08/20 21:38:24 rgb
46812+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
46813+ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
46814+ *
46815+ * Revision 1.32 2000/07/28 14:58:31 rgb
46816+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
46817+ *
46818+ * Revision 1.31 2000/05/16 03:04:00 rgb
46819+ * Updates for 2.3.99pre8 from MB.
46820+ *
46821+ * Revision 1.30 2000/05/10 19:22:21 rgb
46822+ * Use sklist private functions for 2.3.xx compatibility.
46823+ *
46824+ * Revision 1.29 2000/03/22 16:17:03 rgb
46825+ * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
46826+ *
46827+ * Revision 1.28 2000/02/21 19:30:45 rgb
46828+ * Removed references to pkt_bridged for 2.3.47 compatibility.
46829+ *
46830+ * Revision 1.27 2000/02/14 21:07:00 rgb
46831+ * Fixed /proc/net/pf-key legend spacing.
46832+ *
46833+ * Revision 1.26 2000/01/22 03:46:59 rgb
46834+ * Fixed pfkey error return mechanism so that we are able to free the
46835+ * local copy of the pfkey_msg, plugging a memory leak and silencing
46836+ * the bad object free complaints.
46837+ *
46838+ * Revision 1.25 2000/01/21 06:19:44 rgb
46839+ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
46840+ * Added debugging to pfkey_upmsg.
46841+ *
46842+ * Revision 1.24 2000/01/10 16:38:23 rgb
46843+ * MB fixups for 2.3.x.
46844+ *
46845+ * Revision 1.23 1999/12/09 23:22:16 rgb
46846+ * Added more instrumentation for debugging 2.0 socket
46847+ * selection/reading.
46848+ * Removed erroneous 2.0 wait==NULL check bug in select.
46849+ *
46850+ * Revision 1.22 1999/12/08 20:32:16 rgb
46851+ * Tidied up 2.0.xx support, after major pfkey work, eliminating
46852+ * msg->msg_name twiddling in the process, since it is not defined
46853+ * for PF_KEYv2.
46854+ *
46855+ * Revision 1.21 1999/12/01 22:17:19 rgb
46856+ * Set skb->dev to zero on new skb in case it is a reused skb.
46857+ * Added check for skb_put overflow and freeing to avoid upmsg on error.
46858+ * Added check for wrong pfkey version and freeing to avoid upmsg on
46859+ * error.
46860+ * Shut off content dumping in pfkey_destroy.
46861+ * Added debugging message for size of buffer allocated for upmsg.
46862+ *
46863+ * Revision 1.20 1999/11/27 12:11:00 rgb
46864+ * Minor clean-up, enabling quiet operation of pfkey if desired.
46865+ *
46866+ * Revision 1.19 1999/11/25 19:04:21 rgb
46867+ * Update proc_fs code for pfkey to use dynamic registration.
46868+ *
46869+ * Revision 1.18 1999/11/25 09:07:17 rgb
46870+ * Implemented SENDERR macro for propagating error codes.
46871+ * Fixed error return code bug.
46872+ *
46873+ * Revision 1.17 1999/11/23 23:07:20 rgb
46874+ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
46875+ * parses. (PJO)
46876+ * Sort out pfkey and freeswan headers, putting them in a library path.
46877+ *
46878+ * Revision 1.16 1999/11/20 22:00:22 rgb
46879+ * Moved socketlist type declarations and prototypes for shared use.
46880+ * Renamed reformatted and generically extended for use by other socket
46881+ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
46882+ *
46883+ * Revision 1.15 1999/11/18 04:15:09 rgb
46884+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
46885+ * Clean up pfkey_destroy_socket() debugging statements.
46886+ * Add Peter Onion's code to send messages up to all listening sockets.
46887+ * Changed all occurrences of #include "../../../lib/freeswan.h"
46888+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
46889+ * klips/net/ipsec/Makefile.
46890+ * Replaced all kernel version macros to shorter, readable form.
46891+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
46892+ *
46893+ * Revision 1.14 1999/11/17 16:01:00 rgb
46894+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
46895+ * Clean up pfkey_destroy_socket() debugging statements.
46896+ * Add Peter Onion's code to send messages up to all listening sockets.
46897+ * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
46898+ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
46899+ *
46900+ * Revision 1.13 1999/10/27 19:59:51 rgb
46901+ * Removed af_unix comments that are no longer relevant.
46902+ * Added debug prink statements.
46903+ * Added to the /proc output in pfkey_get_info.
46904+ * Made most functions non-static to enable oops tracing.
46905+ * Re-enable skb dequeueing and freeing.
46906+ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
46907+ *
46908+ * Revision 1.12 1999/10/26 17:05:42 rgb
46909+ * Complete re-ordering based on proto_ops structure order.
46910+ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
46911+ * Simplification to use built-in socket ops where possible for 2.2.x.
46912+ * Add shorter macros for compiler directives to visually clean-up.
46913+ * Add lots of sk skb dequeueing debugging statements.
46914+ * Added to the /proc output in pfkey_get_info.
46915+ *
46916+ * Revision 1.11 1999/09/30 02:55:10 rgb
46917+ * Bogus skb detection.
46918+ * Fix incorrect /proc/net/ipsec-eroute printk message.
46919+ *
46920+ * Revision 1.10 1999/09/21 15:22:13 rgb
46921+ * Temporary fix while I figure out the right way to destroy sockets.
46922+ *
46923+ * Revision 1.9 1999/07/08 19:19:44 rgb
46924+ * Fix pointer format warning.
46925+ * Fix missing member error under 2.0.xx kernels.
46926+ *
46927+ * Revision 1.8 1999/06/13 07:24:04 rgb
46928+ * Add more debugging.
46929+ *
46930+ * Revision 1.7 1999/06/10 05:24:17 rgb
46931+ * Clarified compiler directives.
46932+ * Renamed variables to reduce confusion.
46933+ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
46934+ * Added lots of sanity checking.
46935+ *
46936+ * Revision 1.6 1999/06/03 18:59:50 rgb
46937+ * More updates to 2.2.x socket support. Almost works, oops at end of call.
46938+ *
46939+ * Revision 1.5 1999/05/25 22:44:05 rgb
46940+ * Start fixing 2.2 sockets.
46941+ *
46942+ * Revision 1.4 1999/04/29 15:21:34 rgb
46943+ * Move log to the end of the file.
46944+ * Eliminate min/max redefinition in #include <net/tcp.h>.
46945+ * Correct path for pfkey #includes
46946+ * Standardise an error return method.
46947+ * Add debugging instrumentation.
46948+ * Move message type checking to pfkey_msg_parse().
46949+ * Add check for errno incorrectly set.
46950+ * Add check for valid PID.
46951+ * Add check for reserved illegally set.
46952+ * Add check for message out of bounds.
46953+ *
46954+ * Revision 1.3 1999/04/15 17:58:07 rgb
46955+ * Add RCSID labels.
46956+ *
46957+ * Revision 1.2 1999/04/15 15:37:26 rgb
46958+ * Forward check changes from POST1_00 branch.
46959+ *
46960+ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
46961+ * Header Title correction.
46962+ *
46963+ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
46964+ * Add pfkeyv2 support to KLIPS.
46965+ *
46966+ *
46967+ * RFC 2367
46968+ * PF_KEY_v2 Key Management API
46969+ */
46970--- /dev/null Tue Mar 11 13:02:56 2003
46971+++ linux/net/ipsec/pfkey_v2_build.c Mon Feb 9 13:51:03 2004
46972@@ -0,0 +1,1581 @@
46973+/*
46974+ * RFC2367 PF_KEYv2 Key management API message parser
46975+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
46976+ *
46977+ * This program is free software; you can redistribute it and/or modify it
46978+ * under the terms of the GNU General Public License as published by the
46979+ * Free Software Foundation; either version 2 of the License, or (at your
46980+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
46981+ *
46982+ * This program is distributed in the hope that it will be useful, but
46983+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
46984+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
46985+ * for more details.
46986+ *
46987+ * RCSID $Id: pfkey_v2_build.c,v 1.51.8.1 2006-05-01 14:36:39 mcr Exp $
46988+ */
46989+
46990+/*
46991+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
46992+ */
46993+
46994+char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.51.8.1 2006-05-01 14:36:39 mcr Exp $";
46995+
46996+/*
46997+ * Some ugly stuff to allow consistent debugging code for use in the
46998+ * kernel and in user space
46999+*/
47000+
47001+#ifdef __KERNEL__
47002+
47003+# include <linux/kernel.h> /* for printk */
47004+
47005+# include "openswan/ipsec_kversion.h" /* for malloc switch */
47006+# ifdef MALLOC_SLAB
47007+# include <linux/slab.h> /* kmalloc() */
47008+# else /* MALLOC_SLAB */
47009+# include <linux/malloc.h> /* kmalloc() */
47010+# endif /* MALLOC_SLAB */
47011+# include <linux/errno.h> /* error codes */
47012+# include <linux/types.h> /* size_t */
47013+# include <linux/interrupt.h> /* mark_bh */
47014+
47015+# include <linux/netdevice.h> /* struct device, and other headers */
47016+# include <linux/etherdevice.h> /* eth_type_trans */
47017+# include <linux/ip.h> /* struct iphdr */
47018+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
47019+# include <linux/ipv6.h> /* struct ipv6hdr */
47020+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
47021+
47022+# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
47023+# define FREE(obj) kfree(obj)
47024+# include <openswan.h>
47025+#else /* __KERNEL__ */
47026+
47027+# include <sys/types.h>
47028+# include <linux/types.h>
47029+# include <linux/errno.h>
47030+# include <malloc.h>
47031+# include <string.h> /* memset */
47032+
47033+# include <openswan.h>
47034+
47035+#endif /* __KERNEL__ */
47036+
47037+#include <pfkeyv2.h>
47038+#include <pfkey.h>
47039+
47040+#ifdef __KERNEL__
47041+#include "openswan/radij.h" /* rd_nodes */
47042+#include "openswan/ipsec_encap.h" /* sockaddr_encap */
47043+#endif /* __KERNEL__ */
47044+
47045+
47046+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
47047+#include "openswan/pfkey_debug.h"
47048+
47049+
47050+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
47051+
47052+void
47053+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
47054+{
47055+ int i;
47056+
47057+ for (i = 0; i != SADB_EXT_MAX + 1; i++) {
47058+ extensions[i] = NULL;
47059+ }
47060+}
47061+
47062+void
47063+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
47064+{
47065+ int i;
47066+
47067+ if(!extensions) {
47068+ return;
47069+ }
47070+
47071+ if(extensions[0]) {
47072+ memset(extensions[0], 0, sizeof(struct sadb_msg));
47073+ FREE(extensions[0]);
47074+ extensions[0] = NULL;
47075+ }
47076+
47077+ for (i = 1; i != SADB_EXT_MAX + 1; i++) {
47078+ if(extensions[i]) {
47079+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
47080+ FREE(extensions[i]);
47081+ extensions[i] = NULL;
47082+ }
47083+ }
47084+}
47085+
47086+void
47087+pfkey_msg_free(struct sadb_msg **pfkey_msg)
47088+{
47089+ if(*pfkey_msg) {
47090+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
47091+ FREE(*pfkey_msg);
47092+ *pfkey_msg = NULL;
47093+ }
47094+}
47095+
47096+/* Default extension builders taken from the KLIPS code */
47097+
47098+int
47099+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
47100+ uint8_t msg_type,
47101+ uint8_t satype,
47102+ uint8_t msg_errno,
47103+ uint32_t seq,
47104+ uint32_t pid)
47105+{
47106+ int error = 0;
47107+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
47108+
47109+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47110+ "pfkey_msg_hdr_build:\n");
47111+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47112+ "pfkey_msg_hdr_build: "
47113+ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
47114+ &pfkey_ext,
47115+ pfkey_ext,
47116+ *pfkey_ext);
47117+ /* sanity checks... */
47118+ if(pfkey_msg) {
47119+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47120+ "pfkey_msg_hdr_build: "
47121+ "why is pfkey_msg already pointing to something?\n");
47122+ SENDERR(EINVAL);
47123+ }
47124+
47125+ if(!msg_type) {
47126+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47127+ "pfkey_msg_hdr_build: "
47128+ "msg type not set, must be non-zero..\n");
47129+ SENDERR(EINVAL);
47130+ }
47131+
47132+ if(msg_type > SADB_MAX) {
47133+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47134+ "pfkey_msg_hdr_build: "
47135+ "msg type too large:%d.\n",
47136+ msg_type);
47137+ SENDERR(EINVAL);
47138+ }
47139+
47140+ if(satype > SADB_SATYPE_MAX) {
47141+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47142+ "pfkey_msg_hdr_build: "
47143+ "satype %d > max %d\n",
47144+ satype, SADB_SATYPE_MAX);
47145+ SENDERR(EINVAL);
47146+ }
47147+
47148+ pfkey_msg = (struct sadb_msg*)MALLOC(sizeof(struct sadb_msg));
47149+ *pfkey_ext = (struct sadb_ext*)pfkey_msg;
47150+
47151+ if(pfkey_msg == NULL) {
47152+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47153+ "pfkey_msg_hdr_build: "
47154+ "memory allocation failed\n");
47155+ SENDERR(ENOMEM);
47156+ }
47157+ memset(pfkey_msg, 0, sizeof(struct sadb_msg));
47158+
47159+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
47160+
47161+ pfkey_msg->sadb_msg_type = msg_type;
47162+ pfkey_msg->sadb_msg_satype = satype;
47163+
47164+ pfkey_msg->sadb_msg_version = PF_KEY_V2;
47165+ pfkey_msg->sadb_msg_errno = msg_errno;
47166+ pfkey_msg->sadb_msg_reserved = 0;
47167+ pfkey_msg->sadb_msg_seq = seq;
47168+ pfkey_msg->sadb_msg_pid = pid;
47169+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47170+ "pfkey_msg_hdr_build: "
47171+ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
47172+ &pfkey_ext,
47173+ pfkey_ext,
47174+ *pfkey_ext);
47175+errlab:
47176+ return error;
47177+}
47178+
47179+int
47180+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
47181+ uint16_t exttype,
47182+ uint32_t spi,
47183+ uint8_t replay_window,
47184+ uint8_t sa_state,
47185+ uint8_t auth,
47186+ uint8_t encrypt,
47187+ uint32_t flags,
47188+ uint32_t/*IPsecSAref_t*/ ref)
47189+{
47190+ int error = 0;
47191+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
47192+
47193+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47194+ "pfkey_sa_build: "
47195+ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
47196+ ntohl(spi), /* in network order */
47197+ replay_window,
47198+ sa_state,
47199+ auth,
47200+ encrypt,
47201+ flags);
47202+ /* sanity checks... */
47203+ if(pfkey_sa) {
47204+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47205+ "pfkey_sa_build: "
47206+ "why is pfkey_sa already pointing to something?\n");
47207+ SENDERR(EINVAL);
47208+ }
47209+
47210+ if(exttype != SADB_EXT_SA &&
47211+ exttype != SADB_X_EXT_SA2) {
47212+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47213+ "pfkey_sa_build: "
47214+ "invalid exttype=%d.\n",
47215+ exttype);
47216+ SENDERR(EINVAL);
47217+ }
47218+
47219+ if(replay_window > 64) {
47220+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47221+ "pfkey_sa_build: "
47222+ "replay window size: %d -- must be 0 <= size <= 64\n",
47223+ replay_window);
47224+ SENDERR(EINVAL);
47225+ }
47226+
47227+ if(auth > SADB_AALG_MAX) {
47228+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47229+ "pfkey_sa_build: "
47230+ "auth=%d > SADB_AALG_MAX=%d.\n",
47231+ auth,
47232+ SADB_AALG_MAX);
47233+ SENDERR(EINVAL);
47234+ }
47235+
47236+#if SADB_EALG_MAX < 255
47237+ if(encrypt > SADB_EALG_MAX) {
47238+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47239+ "pfkey_sa_build: "
47240+ "encrypt=%d > SADB_EALG_MAX=%d.\n",
47241+ encrypt,
47242+ SADB_EALG_MAX);
47243+ SENDERR(EINVAL);
47244+ }
47245+#endif
47246+
47247+ if(sa_state > SADB_SASTATE_MAX) {
47248+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47249+ "pfkey_sa_build: "
47250+ "sa_state=%d exceeds MAX=%d.\n",
47251+ sa_state,
47252+ SADB_SASTATE_MAX);
47253+ SENDERR(EINVAL);
47254+ }
47255+
47256+ if(sa_state == SADB_SASTATE_DEAD) {
47257+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47258+ "pfkey_sa_build: "
47259+ "sa_state=%d is DEAD=%d is not allowed.\n",
47260+ sa_state,
47261+ SADB_SASTATE_DEAD);
47262+ SENDERR(EINVAL);
47263+ }
47264+
47265+ if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
47266+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47267+ "pfkey_sa_build: "
47268+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
47269+ ref,
47270+ IPSEC_SAREF_NULL,
47271+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
47272+ SENDERR(EINVAL);
47273+ }
47274+
47275+ pfkey_sa = (struct sadb_sa*)MALLOC(sizeof(struct sadb_sa));
47276+ *pfkey_ext = (struct sadb_ext*)pfkey_sa;
47277+
47278+ if(pfkey_sa == NULL) {
47279+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47280+ "pfkey_sa_build: "
47281+ "memory allocation failed\n");
47282+ SENDERR(ENOMEM);
47283+ }
47284+ memset(pfkey_sa, 0, sizeof(struct sadb_sa));
47285+
47286+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
47287+ pfkey_sa->sadb_sa_exttype = exttype;
47288+ pfkey_sa->sadb_sa_spi = spi;
47289+ pfkey_sa->sadb_sa_replay = replay_window;
47290+ pfkey_sa->sadb_sa_state = sa_state;
47291+ pfkey_sa->sadb_sa_auth = auth;
47292+ pfkey_sa->sadb_sa_encrypt = encrypt;
47293+ pfkey_sa->sadb_sa_flags = flags;
47294+ pfkey_sa->sadb_x_sa_ref = ref;
47295+
47296+errlab:
47297+ return error;
47298+}
47299+
47300+int
47301+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
47302+ uint16_t exttype,
47303+ uint32_t spi,
47304+ uint8_t replay_window,
47305+ uint8_t sa_state,
47306+ uint8_t auth,
47307+ uint8_t encrypt,
47308+ uint32_t flags)
47309+{
47310+ return pfkey_sa_ref_build(pfkey_ext,
47311+ exttype,
47312+ spi,
47313+ replay_window,
47314+ sa_state,
47315+ auth,
47316+ encrypt,
47317+ flags,
47318+ IPSEC_SAREF_NULL);
47319+}
47320+
47321+int
47322+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
47323+ uint16_t exttype,
47324+ uint32_t allocations,
47325+ uint64_t bytes,
47326+ uint64_t addtime,
47327+ uint64_t usetime,
47328+ uint32_t packets)
47329+{
47330+ int error = 0;
47331+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
47332+
47333+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47334+ "pfkey_lifetime_build:\n");
47335+ /* sanity checks... */
47336+ if(pfkey_lifetime) {
47337+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47338+ "pfkey_lifetime_build: "
47339+ "why is pfkey_lifetime already pointing to something?\n");
47340+ SENDERR(EINVAL);
47341+ }
47342+
47343+ if(exttype != SADB_EXT_LIFETIME_CURRENT &&
47344+ exttype != SADB_EXT_LIFETIME_HARD &&
47345+ exttype != SADB_EXT_LIFETIME_SOFT) {
47346+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47347+ "pfkey_lifetime_build: "
47348+ "invalid exttype=%d.\n",
47349+ exttype);
47350+ SENDERR(EINVAL);
47351+ }
47352+
47353+ pfkey_lifetime = (struct sadb_lifetime*)MALLOC(sizeof(struct sadb_lifetime));
47354+ *pfkey_ext = (struct sadb_ext*) pfkey_lifetime;
47355+
47356+ if(pfkey_lifetime == NULL) {
47357+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47358+ "pfkey_lifetime_build: "
47359+ "memory allocation failed\n");
47360+ SENDERR(ENOMEM);
47361+ }
47362+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
47363+
47364+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
47365+ pfkey_lifetime->sadb_lifetime_exttype = exttype;
47366+ pfkey_lifetime->sadb_lifetime_allocations = allocations;
47367+ pfkey_lifetime->sadb_lifetime_bytes = bytes;
47368+ pfkey_lifetime->sadb_lifetime_addtime = addtime;
47369+ pfkey_lifetime->sadb_lifetime_usetime = usetime;
47370+ pfkey_lifetime->sadb_x_lifetime_packets = packets;
47371+
47372+errlab:
47373+ return error;
47374+}
47375+
47376+int
47377+pfkey_address_build(struct sadb_ext** pfkey_ext,
47378+ uint16_t exttype,
47379+ uint8_t proto,
47380+ uint8_t prefixlen,
47381+ struct sockaddr* address)
47382+{
47383+ int error = 0;
47384+ int saddr_len = 0;
47385+ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
47386+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
47387+
47388+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47389+ "pfkey_address_build: "
47390+ "exttype=%d proto=%d prefixlen=%d\n",
47391+ exttype,
47392+ proto,
47393+ prefixlen);
47394+ /* sanity checks... */
47395+ if(pfkey_address) {
47396+ ERROR("pfkey_address_build: "
47397+ "why is pfkey_address already pointing to something?\n");
47398+ SENDERR(EINVAL);
47399+ }
47400+
47401+ if (!address) {
47402+ ERROR("pfkey_address_build: " "address is NULL\n");
47403+ SENDERR(EINVAL);
47404+ }
47405+
47406+ switch(exttype) {
47407+ case SADB_EXT_ADDRESS_SRC:
47408+ case SADB_EXT_ADDRESS_DST:
47409+ case SADB_EXT_ADDRESS_PROXY:
47410+ case SADB_X_EXT_ADDRESS_DST2:
47411+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
47412+ case SADB_X_EXT_ADDRESS_DST_FLOW:
47413+ case SADB_X_EXT_ADDRESS_SRC_MASK:
47414+ case SADB_X_EXT_ADDRESS_DST_MASK:
47415+#ifdef NAT_TRAVERSAL
47416+ case SADB_X_EXT_NAT_T_OA:
47417+#endif
47418+ break;
47419+ default:
47420+ ERROR("pfkey_address_build: "
47421+ "unrecognised ext_type=%d.\n",
47422+ exttype);
47423+ SENDERR(EINVAL);
47424+ }
47425+
47426+ switch(address->sa_family) {
47427+ case AF_INET:
47428+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47429+ "pfkey_address_build: "
47430+ "found address family AF_INET.\n");
47431+ saddr_len = sizeof(struct sockaddr_in);
47432+ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
47433+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
47434+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
47435+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
47436+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
47437+ , ntohs(((struct sockaddr_in*)address)->sin_port));
47438+ break;
47439+ case AF_INET6:
47440+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47441+ "pfkey_address_build: "
47442+ "found address family AF_INET6.\n");
47443+ saddr_len = sizeof(struct sockaddr_in6);
47444+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
47445+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
47446+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
47447+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
47448+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
47449+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
47450+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
47451+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
47452+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
47453+ , ntohs(((struct sockaddr_in6*)address)->sin6_port));
47454+ break;
47455+ default:
47456+ ERROR("pfkey_address_build: "
47457+ "address->sa_family=%d not supported.\n",
47458+ address->sa_family);
47459+ SENDERR(EPFNOSUPPORT);
47460+ }
47461+
47462+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47463+ "pfkey_address_build: "
47464+ "found address=%s.\n",
47465+ ipaddr_txt);
47466+ if(prefixlen != 0) {
47467+ ERROR("pfkey_address_build: "
47468+ "address prefixes not supported yet.\n");
47469+ SENDERR(EAFNOSUPPORT); /* not supported yet */
47470+ }
47471+
47472+ /* allocate some memory for the extension */
47473+ pfkey_address = (struct sadb_address*)
47474+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
47475+ *pfkey_ext = (struct sadb_ext*)pfkey_address;
47476+
47477+ if(pfkey_address == NULL ) {
47478+ ERROR("pfkey_lifetime_build: "
47479+ "memory allocation failed\n");
47480+ SENDERR(ENOMEM);
47481+ }
47482+ memset(pfkey_address,
47483+ 0,
47484+ ALIGN_N(sizeof(struct sadb_address) + saddr_len,
47485+ IPSEC_PFKEYv2_ALIGN));
47486+
47487+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
47488+ IPSEC_PFKEYv2_ALIGN);
47489+
47490+ pfkey_address->sadb_address_exttype = exttype;
47491+ pfkey_address->sadb_address_proto = proto;
47492+ pfkey_address->sadb_address_prefixlen = prefixlen;
47493+ pfkey_address->sadb_address_reserved = 0;
47494+
47495+ memcpy((char*)pfkey_address + sizeof(struct sadb_address),
47496+ address,
47497+ saddr_len);
47498+
47499+#if 0
47500+ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
47501+ pfkey_address_s_ska.sin_zero[i] = 0;
47502+ }
47503+#endif
47504+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47505+ "pfkey_address_build: "
47506+ "successful created len: %d.\n", pfkey_address->sadb_address_len);
47507+
47508+ errlab:
47509+ return error;
47510+}
47511+
47512+int
47513+pfkey_key_build(struct sadb_ext** pfkey_ext,
47514+ uint16_t exttype,
47515+ uint16_t key_bits,
47516+ char* key)
47517+{
47518+ int error = 0;
47519+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
47520+
47521+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47522+ "pfkey_key_build:\n");
47523+ /* sanity checks... */
47524+ if(pfkey_key) {
47525+ ERROR("pfkey_key_build: "
47526+ "why is pfkey_key already pointing to something?\n");
47527+ SENDERR(EINVAL);
47528+ }
47529+
47530+ if(!key_bits) {
47531+ ERROR("pfkey_key_build: "
47532+ "key_bits is zero, it must be non-zero.\n");
47533+ SENDERR(EINVAL);
47534+ }
47535+
47536+ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
47537+ ERROR("pfkey_key_build: "
47538+ "unsupported extension type=%d.\n",
47539+ exttype);
47540+ SENDERR(EINVAL);
47541+ }
47542+
47543+ pfkey_key = (struct sadb_key*)
47544+ MALLOC(sizeof(struct sadb_key) +
47545+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
47546+
47547+ *pfkey_ext = (struct sadb_ext*)pfkey_key;
47548+
47549+ if(pfkey_key == NULL) {
47550+ ERROR("pfkey_key_build: "
47551+ "memory allocation failed\n");
47552+ SENDERR(ENOMEM);
47553+ }
47554+ memset(pfkey_key,
47555+ 0,
47556+ sizeof(struct sadb_key) +
47557+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
47558+
47559+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
47560+ 64);
47561+ pfkey_key->sadb_key_exttype = exttype;
47562+ pfkey_key->sadb_key_bits = key_bits;
47563+ pfkey_key->sadb_key_reserved = 0;
47564+ memcpy((char*)pfkey_key + sizeof(struct sadb_key),
47565+ key,
47566+ DIVUP(key_bits, 8));
47567+
47568+errlab:
47569+ return error;
47570+}
47571+
47572+int
47573+pfkey_ident_build(struct sadb_ext** pfkey_ext,
47574+ uint16_t exttype,
47575+ uint16_t ident_type,
47576+ uint64_t ident_id,
47577+ uint8_t ident_len,
47578+ char* ident_string)
47579+{
47580+ int error = 0;
47581+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
47582+ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
47583+
47584+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47585+ "pfkey_ident_build:\n");
47586+ /* sanity checks... */
47587+ if(pfkey_ident) {
47588+ ERROR("pfkey_ident_build: "
47589+ "why is pfkey_ident already pointing to something?\n");
47590+ SENDERR(EINVAL);
47591+ }
47592+
47593+ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
47594+ (exttype == SADB_EXT_IDENTITY_DST))) {
47595+ ERROR("pfkey_ident_build: "
47596+ "unsupported extension type=%d.\n",
47597+ exttype);
47598+ SENDERR(EINVAL);
47599+ }
47600+
47601+ if((ident_type == SADB_IDENTTYPE_RESERVED)) {
47602+ ERROR("pfkey_ident_build: "
47603+ "ident_type must be non-zero.\n");
47604+ SENDERR(EINVAL);
47605+ }
47606+
47607+ if(ident_type > SADB_IDENTTYPE_MAX) {
47608+ ERROR("pfkey_ident_build: "
47609+ "identtype=%d out of range.\n",
47610+ ident_type);
47611+ SENDERR(EINVAL);
47612+ }
47613+
47614+ if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
47615+ (ident_type == SADB_IDENTTYPE_FQDN)) &&
47616+ !ident_string) {
47617+ ERROR("pfkey_ident_build: "
47618+ "string required to allocate size of extension.\n");
47619+ SENDERR(EINVAL);
47620+ }
47621+
47622+#if 0
47623+ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
47624+ }
47625+#endif
47626+
47627+ pfkey_ident = (struct sadb_ident*)
47628+ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
47629+
47630+ *pfkey_ext = (struct sadb_ext*)pfkey_ident;
47631+
47632+ if(pfkey_ident == NULL) {
47633+ ERROR("pfkey_ident_build: "
47634+ "memory allocation failed\n");
47635+ SENDERR(ENOMEM);
47636+ }
47637+ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
47638+
47639+ pfkey_ident->sadb_ident_len = ident_len;
47640+ pfkey_ident->sadb_ident_exttype = exttype;
47641+ pfkey_ident->sadb_ident_type = ident_type;
47642+ pfkey_ident->sadb_ident_reserved = 0;
47643+ pfkey_ident->sadb_ident_id = ident_id;
47644+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
47645+ ident_string,
47646+ data_len);
47647+
47648+errlab:
47649+ return error;
47650+}
47651+
47652+int
47653+pfkey_sens_build(struct sadb_ext** pfkey_ext,
47654+ uint32_t dpd,
47655+ uint8_t sens_level,
47656+ uint8_t sens_len,
47657+ uint64_t* sens_bitmap,
47658+ uint8_t integ_level,
47659+ uint8_t integ_len,
47660+ uint64_t* integ_bitmap)
47661+{
47662+ int error = 0;
47663+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
47664+ int i;
47665+ uint64_t* bitmap;
47666+
47667+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47668+ "pfkey_sens_build:\n");
47669+ /* sanity checks... */
47670+ if(pfkey_sens) {
47671+ ERROR("pfkey_sens_build: "
47672+ "why is pfkey_sens already pointing to something?\n");
47673+ SENDERR(EINVAL);
47674+ }
47675+
47676+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47677+ "pfkey_sens_build: "
47678+ "Sorry, I can't build exttype=%d yet.\n",
47679+ (*pfkey_ext)->sadb_ext_type);
47680+ SENDERR(EINVAL); /* don't process these yet */
47681+
47682+ pfkey_sens = (struct sadb_sens*)
47683+ MALLOC(sizeof(struct sadb_sens) +
47684+ (sens_len + integ_len) * sizeof(uint64_t));
47685+
47686+ *pfkey_ext = (struct sadb_ext*)pfkey_sens;
47687+
47688+ if(pfkey_sens == NULL) {
47689+ ERROR("pfkey_sens_build: "
47690+ "memory allocation failed\n");
47691+ SENDERR(ENOMEM);
47692+ }
47693+ memset(pfkey_sens,
47694+ 0,
47695+ sizeof(struct sadb_sens) +
47696+ (sens_len + integ_len) * sizeof(uint64_t));
47697+
47698+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
47699+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
47700+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
47701+ pfkey_sens->sadb_sens_dpd = dpd;
47702+ pfkey_sens->sadb_sens_sens_level = sens_level;
47703+ pfkey_sens->sadb_sens_sens_len = sens_len;
47704+ pfkey_sens->sadb_sens_integ_level = integ_level;
47705+ pfkey_sens->sadb_sens_integ_len = integ_len;
47706+ pfkey_sens->sadb_sens_reserved = 0;
47707+
47708+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
47709+ for(i = 0; i < sens_len; i++) {
47710+ *bitmap = sens_bitmap[i];
47711+ bitmap++;
47712+ }
47713+ for(i = 0; i < integ_len; i++) {
47714+ *bitmap = integ_bitmap[i];
47715+ bitmap++;
47716+ }
47717+
47718+errlab:
47719+ return error;
47720+}
47721+
47722+int
47723+pfkey_prop_build(struct sadb_ext** pfkey_ext,
47724+ uint8_t replay,
47725+ unsigned int comb_num,
47726+ struct sadb_comb* comb)
47727+{
47728+ int error = 0;
47729+ int i;
47730+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
47731+ struct sadb_comb *combp;
47732+
47733+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47734+ "pfkey_prop_build:\n");
47735+ /* sanity checks... */
47736+ if(pfkey_prop) {
47737+ ERROR("pfkey_prop_build: "
47738+ "why is pfkey_prop already pointing to something?\n");
47739+ SENDERR(EINVAL);
47740+ }
47741+
47742+ pfkey_prop = (struct sadb_prop*)
47743+ MALLOC(sizeof(struct sadb_prop) +
47744+ comb_num * sizeof(struct sadb_comb));
47745+
47746+ *pfkey_ext = (struct sadb_ext*)pfkey_prop;
47747+
47748+ if(pfkey_prop == NULL) {
47749+ ERROR("pfkey_prop_build: "
47750+ "memory allocation failed\n");
47751+ SENDERR(ENOMEM);
47752+ }
47753+ memset(pfkey_prop,
47754+ 0,
47755+ sizeof(struct sadb_prop) +
47756+ comb_num * sizeof(struct sadb_comb));
47757+
47758+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
47759+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
47760+
47761+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
47762+ pfkey_prop->sadb_prop_replay = replay;
47763+
47764+ for(i=0; i<3; i++) {
47765+ pfkey_prop->sadb_prop_reserved[i] = 0;
47766+ }
47767+
47768+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
47769+ for(i = 0; i < comb_num; i++) {
47770+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
47771+ combp++;
47772+ }
47773+
47774+#if 0
47775+ uint8_t sadb_comb_auth;
47776+ uint8_t sadb_comb_encrypt;
47777+ uint16_t sadb_comb_flags;
47778+ uint16_t sadb_comb_auth_minbits;
47779+ uint16_t sadb_comb_auth_maxbits;
47780+ uint16_t sadb_comb_encrypt_minbits;
47781+ uint16_t sadb_comb_encrypt_maxbits;
47782+ uint32_t sadb_comb_reserved;
47783+ uint32_t sadb_comb_soft_allocations;
47784+ uint32_t sadb_comb_hard_allocations;
47785+ uint64_t sadb_comb_soft_bytes;
47786+ uint64_t sadb_comb_hard_bytes;
47787+ uint64_t sadb_comb_soft_addtime;
47788+ uint64_t sadb_comb_hard_addtime;
47789+ uint64_t sadb_comb_soft_usetime;
47790+ uint64_t sadb_comb_hard_usetime;
47791+ uint32_t sadb_comb_soft_packets;
47792+ uint32_t sadb_comb_hard_packets;
47793+#endif
47794+errlab:
47795+ return error;
47796+}
47797+
47798+int
47799+pfkey_supported_build(struct sadb_ext** pfkey_ext,
47800+ uint16_t exttype,
47801+ unsigned int alg_num,
47802+ struct sadb_alg* alg)
47803+{
47804+ int error = 0;
47805+ unsigned int i;
47806+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
47807+ struct sadb_alg *pfkey_alg;
47808+
47809+ /* sanity checks... */
47810+ if(pfkey_supported) {
47811+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47812+ "pfkey_supported_build: "
47813+ "why is pfkey_supported already pointing to something?\n");
47814+ SENDERR(EINVAL);
47815+ }
47816+
47817+ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
47818+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47819+ "pfkey_supported_build: "
47820+ "unsupported extension type=%d.\n",
47821+ exttype);
47822+ SENDERR(EINVAL);
47823+ }
47824+
47825+ pfkey_supported = (struct sadb_supported*)
47826+ MALLOC(sizeof(struct sadb_supported) +
47827+ alg_num *
47828+ sizeof(struct sadb_alg));
47829+
47830+ *pfkey_ext = (struct sadb_ext*)pfkey_supported;
47831+
47832+ if(pfkey_supported == NULL) {
47833+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47834+ "pfkey_supported_build: "
47835+ "memory allocation failed\n");
47836+ SENDERR(ENOMEM);
47837+ }
47838+ memset(pfkey_supported,
47839+ 0,
47840+ sizeof(struct sadb_supported) +
47841+ alg_num *
47842+ sizeof(struct sadb_alg));
47843+
47844+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
47845+ alg_num *
47846+ sizeof(struct sadb_alg)) /
47847+ IPSEC_PFKEYv2_ALIGN;
47848+ pfkey_supported->sadb_supported_exttype = exttype;
47849+ pfkey_supported->sadb_supported_reserved = 0;
47850+
47851+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
47852+ for(i = 0; i < alg_num; i++) {
47853+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
47854+ pfkey_alg->sadb_alg_reserved = 0;
47855+ pfkey_alg++;
47856+ }
47857+
47858+#if 0
47859+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47860+ "pfkey_supported_build: "
47861+ "Sorry, I can't build exttype=%d yet.\n",
47862+ (*pfkey_ext)->sadb_ext_type);
47863+ SENDERR(EINVAL); /* don't process these yet */
47864+
47865+ uint8_t sadb_alg_id;
47866+ uint8_t sadb_alg_ivlen;
47867+ uint16_t sadb_alg_minbits;
47868+ uint16_t sadb_alg_maxbits;
47869+ uint16_t sadb_alg_reserved;
47870+#endif
47871+errlab:
47872+ return error;
47873+}
47874+
47875+int
47876+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
47877+ uint16_t exttype,
47878+ uint32_t min, /* in network order */
47879+ uint32_t max) /* in network order */
47880+{
47881+ int error = 0;
47882+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
47883+
47884+ /* sanity checks... */
47885+ if(pfkey_spirange) {
47886+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47887+ "pfkey_spirange_build: "
47888+ "why is pfkey_spirange already pointing to something?\n");
47889+ SENDERR(EINVAL);
47890+ }
47891+
47892+ if(ntohl(max) < ntohl(min)) {
47893+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47894+ "pfkey_spirange_build: "
47895+ "minspi=%08x must be < maxspi=%08x.\n",
47896+ ntohl(min),
47897+ ntohl(max));
47898+ SENDERR(EINVAL);
47899+ }
47900+
47901+ if(ntohl(min) <= 255) {
47902+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47903+ "pfkey_spirange_build: "
47904+ "minspi=%08x must be > 255.\n",
47905+ ntohl(min));
47906+ SENDERR(EEXIST);
47907+ }
47908+
47909+ pfkey_spirange = (struct sadb_spirange*)
47910+ MALLOC(sizeof(struct sadb_spirange));
47911+
47912+ *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
47913+
47914+ if(pfkey_spirange == NULL) {
47915+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47916+ "pfkey_spirange_build: "
47917+ "memory allocation failed\n");
47918+ SENDERR(ENOMEM);
47919+ }
47920+ memset(pfkey_spirange,
47921+ 0,
47922+ sizeof(struct sadb_spirange));
47923+
47924+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
47925+
47926+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
47927+ pfkey_spirange->sadb_spirange_min = min;
47928+ pfkey_spirange->sadb_spirange_max = max;
47929+ pfkey_spirange->sadb_spirange_reserved = 0;
47930+ errlab:
47931+ return error;
47932+}
47933+
47934+int
47935+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
47936+{
47937+ int error = 0;
47938+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
47939+
47940+ /* sanity checks... */
47941+ if(pfkey_x_kmprivate) {
47942+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47943+ "pfkey_x_kmprivate_build: "
47944+ "why is pfkey_x_kmprivate already pointing to something?\n");
47945+ SENDERR(EINVAL);
47946+ }
47947+
47948+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
47949+
47950+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47951+ "pfkey_x_kmprivate_build: "
47952+ "Sorry, I can't build exttype=%d yet.\n",
47953+ (*pfkey_ext)->sadb_ext_type);
47954+ SENDERR(EINVAL); /* don't process these yet */
47955+
47956+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
47957+ MALLOC(sizeof(struct sadb_x_kmprivate));
47958+
47959+ *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
47960+
47961+ if(pfkey_x_kmprivate == NULL) {
47962+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47963+ "pfkey_x_kmprivate_build: "
47964+ "memory allocation failed\n");
47965+ SENDERR(ENOMEM);
47966+ }
47967+ memset(pfkey_x_kmprivate,
47968+ 0,
47969+ sizeof(struct sadb_x_kmprivate));
47970+
47971+ pfkey_x_kmprivate->sadb_x_kmprivate_len =
47972+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
47973+
47974+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
47975+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
47976+errlab:
47977+ return error;
47978+}
47979+
47980+int
47981+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
47982+ uint8_t satype)
47983+{
47984+ int error = 0;
47985+ int i;
47986+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
47987+
47988+ DEBUGGING(PF_KEY_DEBUG_BUILD,
47989+ "pfkey_x_satype_build:\n");
47990+ /* sanity checks... */
47991+ if(pfkey_x_satype) {
47992+ ERROR("pfkey_x_satype_build: "
47993+ "why is pfkey_x_satype already pointing to something?\n");
47994+ SENDERR(EINVAL);
47995+ }
47996+
47997+ if(!satype) {
47998+ ERROR("pfkey_x_satype_build: "
47999+ "SA type not set, must be non-zero.\n");
48000+ SENDERR(EINVAL);
48001+ }
48002+
48003+ if(satype > SADB_SATYPE_MAX) {
48004+ ERROR("pfkey_x_satype_build: "
48005+ "satype %d > max %d\n",
48006+ satype, SADB_SATYPE_MAX);
48007+ SENDERR(EINVAL);
48008+ }
48009+
48010+ pfkey_x_satype = (struct sadb_x_satype*)
48011+ MALLOC(sizeof(struct sadb_x_satype));
48012+
48013+ *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
48014+ if(pfkey_x_satype == NULL) {
48015+ ERROR("pfkey_x_satype_build: "
48016+ "memory allocation failed\n");
48017+ SENDERR(ENOMEM);
48018+ }
48019+ memset(pfkey_x_satype,
48020+ 0,
48021+ sizeof(struct sadb_x_satype));
48022+
48023+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
48024+
48025+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
48026+ pfkey_x_satype->sadb_x_satype_satype = satype;
48027+ for(i=0; i<3; i++) {
48028+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
48029+ }
48030+
48031+errlab:
48032+ return error;
48033+}
48034+
48035+int
48036+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
48037+ uint32_t tunnel,
48038+ uint32_t netlink,
48039+ uint32_t xform,
48040+ uint32_t eroute,
48041+ uint32_t spi,
48042+ uint32_t radij,
48043+ uint32_t esp,
48044+ uint32_t ah,
48045+ uint32_t rcv,
48046+ uint32_t pfkey,
48047+ uint32_t ipcomp,
48048+ uint32_t verbose)
48049+{
48050+ int error = 0;
48051+ int i;
48052+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
48053+
48054+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48055+ "pfkey_x_debug_build:\n");
48056+ /* sanity checks... */
48057+ if(pfkey_x_debug) {
48058+ ERROR("pfkey_x_debug_build: "
48059+ "why is pfkey_x_debug already pointing to something?\n");
48060+ SENDERR(EINVAL);
48061+ }
48062+
48063+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48064+ "pfkey_x_debug_build: "
48065+ "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",
48066+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
48067+
48068+ pfkey_x_debug = (struct sadb_x_debug*)
48069+ MALLOC(sizeof(struct sadb_x_debug));
48070+
48071+ *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
48072+
48073+ if(pfkey_x_debug == NULL) {
48074+ ERROR("pfkey_x_debug_build: "
48075+ "memory allocation failed\n");
48076+ SENDERR(ENOMEM);
48077+ }
48078+#if 0
48079+ memset(pfkey_x_debug,
48080+ 0,
48081+ sizeof(struct sadb_x_debug));
48082+#endif
48083+
48084+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
48085+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
48086+
48087+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
48088+ pfkey_x_debug->sadb_x_debug_netlink = netlink;
48089+ pfkey_x_debug->sadb_x_debug_xform = xform;
48090+ pfkey_x_debug->sadb_x_debug_eroute = eroute;
48091+ pfkey_x_debug->sadb_x_debug_spi = spi;
48092+ pfkey_x_debug->sadb_x_debug_radij = radij;
48093+ pfkey_x_debug->sadb_x_debug_esp = esp;
48094+ pfkey_x_debug->sadb_x_debug_ah = ah;
48095+ pfkey_x_debug->sadb_x_debug_rcv = rcv;
48096+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
48097+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
48098+ pfkey_x_debug->sadb_x_debug_verbose = verbose;
48099+
48100+ for(i=0; i<4; i++) {
48101+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
48102+ }
48103+
48104+errlab:
48105+ return error;
48106+}
48107+
48108+int
48109+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
48110+ uint8_t type)
48111+{
48112+ int error = 0;
48113+ int i;
48114+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
48115+
48116+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48117+ "pfkey_x_nat_t_type_build:\n");
48118+ /* sanity checks... */
48119+ if(pfkey_x_nat_t_type) {
48120+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48121+ "pfkey_x_nat_t_type_build: "
48122+ "why is pfkey_x_nat_t_type already pointing to something?\n");
48123+ SENDERR(EINVAL);
48124+ }
48125+
48126+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48127+ "pfkey_x_nat_t_type_build: "
48128+ "type=%d\n", type);
48129+
48130+ pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
48131+ MALLOC(sizeof(struct sadb_x_nat_t_type));
48132+
48133+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
48134+
48135+ if(pfkey_x_nat_t_type == NULL) {
48136+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48137+ "pfkey_x_nat_t_type_build: "
48138+ "memory allocation failed\n");
48139+ SENDERR(ENOMEM);
48140+ }
48141+
48142+ pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
48143+ pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
48144+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
48145+ for(i=0; i<3; i++) {
48146+ pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
48147+ }
48148+
48149+errlab:
48150+ return error;
48151+}
48152+int
48153+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
48154+ uint16_t exttype,
48155+ uint16_t port)
48156+{
48157+ int error = 0;
48158+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
48159+
48160+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48161+ "pfkey_x_nat_t_port_build:\n");
48162+ /* sanity checks... */
48163+ if(pfkey_x_nat_t_port) {
48164+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48165+ "pfkey_x_nat_t_port_build: "
48166+ "why is pfkey_x_nat_t_port already pointing to something?\n");
48167+ SENDERR(EINVAL);
48168+ }
48169+
48170+ switch(exttype) {
48171+ case SADB_X_EXT_NAT_T_SPORT:
48172+ case SADB_X_EXT_NAT_T_DPORT:
48173+ break;
48174+ default:
48175+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48176+ "pfkey_nat_t_port_build: "
48177+ "unrecognised ext_type=%d.\n",
48178+ exttype);
48179+ SENDERR(EINVAL);
48180+ }
48181+
48182+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48183+ "pfkey_x_nat_t_port_build: "
48184+ "ext=%d, port=%d\n", exttype, port);
48185+
48186+ pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
48187+ MALLOC(sizeof(struct sadb_x_nat_t_port));
48188+
48189+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
48190+
48191+ if(pfkey_x_nat_t_port == NULL) {
48192+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48193+ "pfkey_x_nat_t_port_build: "
48194+ "memory allocation failed\n");
48195+ SENDERR(ENOMEM);
48196+ }
48197+
48198+ pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
48199+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
48200+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
48201+ pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
48202+
48203+errlab:
48204+ return error;
48205+}
48206+
48207+int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
48208+ uint8_t protocol)
48209+{
48210+ int error = 0;
48211+ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
48212+ DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol);
48213+ /* sanity checks... */
48214+ if (p != 0) {
48215+ ERROR("pfkey_x_protocol_build: bogus protocol pointer\n");
48216+ SENDERR(EINVAL);
48217+ }
48218+ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
48219+ ERROR("pfkey_build: memory allocation failed\n");
48220+ SENDERR(ENOMEM);
48221+ }
48222+ *pfkey_ext = (struct sadb_ext *)p;
48223+ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
48224+ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
48225+ p->sadb_protocol_proto = protocol;
48226+ p->sadb_protocol_flags = 0;
48227+ p->sadb_protocol_reserved2 = 0;
48228+ errlab:
48229+ return error;
48230+}
48231+
48232+int
48233+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
48234+{
48235+ int error = 0;
48236+ unsigned ext;
48237+ unsigned total_size;
48238+ struct sadb_ext *pfkey_ext;
48239+ int extensions_seen = 0;
48240+#ifndef __KERNEL__
48241+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
48242+#endif
48243+
48244+ if(!extensions[0]) {
48245+ ERROR("pfkey_msg_build: "
48246+ "extensions[0] must be specified (struct sadb_msg).\n");
48247+ SENDERR(EINVAL);
48248+ }
48249+
48250+ /* figure out the total size for all the requested extensions */
48251+ total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
48252+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
48253+ if(extensions[ext]) {
48254+ total_size += (extensions[ext])->sadb_ext_len;
48255+ }
48256+ }
48257+
48258+ /* allocate that much space */
48259+ *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN);
48260+ if(*pfkey_msg == NULL) {
48261+ ERROR("pfkey_msg_build: "
48262+ "memory allocation failed\n");
48263+ SENDERR(ENOMEM);
48264+ }
48265+
48266+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48267+ "pfkey_msg_build: "
48268+ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
48269+ *pfkey_msg,
48270+ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
48271+ &(extensions[0]));
48272+
48273+ memcpy(*pfkey_msg,
48274+ extensions[0],
48275+ sizeof(struct sadb_msg));
48276+ (*pfkey_msg)->sadb_msg_len = total_size;
48277+ (*pfkey_msg)->sadb_msg_reserved = 0;
48278+ extensions_seen = 1 ;
48279+
48280+ /*
48281+ * point pfkey_ext to immediately after the space for the header,
48282+ * i.e. at the first extension location.
48283+ */
48284+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
48285+
48286+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
48287+ /* copy from extension[ext] to buffer */
48288+ if(extensions[ext]) {
48289+ /* Is this type of extension permitted for this type of message? */
48290+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
48291+ 1<<ext)) {
48292+ ERROR("pfkey_msg_build: "
48293+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
48294+ ext,
48295+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
48296+ 1<<ext);
48297+ SENDERR(EINVAL);
48298+ }
48299+
48300+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48301+ "pfkey_msg_build: "
48302+ "copying %lu bytes from extensions[%u] (type=%d)\n",
48303+ (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
48304+ ext,
48305+ extensions[ext]->sadb_ext_type);
48306+
48307+ memcpy(pfkey_ext,
48308+ extensions[ext],
48309+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
48310+ {
48311+ char *pfkey_ext_c = (char *)pfkey_ext;
48312+
48313+ pfkey_ext_c += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
48314+ pfkey_ext = (struct sadb_ext *)pfkey_ext_c;
48315+ }
48316+
48317+ /* Mark that we have seen this extension and remember the header location */
48318+ extensions_seen |= ( 1 << ext );
48319+ }
48320+ }
48321+
48322+ /* check required extensions */
48323+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48324+ "pfkey_msg_build: "
48325+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
48326+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
48327+ extensions_seen,
48328+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
48329+
48330+ if((extensions_seen &
48331+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
48332+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
48333+ DEBUGGING(PF_KEY_DEBUG_BUILD,
48334+ "pfkey_msg_build: "
48335+ "required extensions missing:%08x.\n",
48336+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
48337+ (extensions_seen &
48338+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
48339+ SENDERR(EINVAL);
48340+ }
48341+
48342+#ifndef __KERNEL__
48343+/*
48344+ * this is silly, there is no need to reparse the message that we just built.
48345+ *
48346+ */
48347+ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
48348+ ERROR(
48349+ "pfkey_msg_build: "
48350+ "Trouble parsing newly built pfkey message, error=%d.\n",
48351+ error);
48352+ SENDERR(-error);
48353+ }
48354+#endif
48355+
48356+errlab:
48357+
48358+ return error;
48359+}
48360+
48361+/*
48362+ * $Log: pfkey_v2_build.c,v $
48363+ * Revision 1.51.8.1 2006-05-01 14:36:39 mcr
48364+ * get rid of dead code.
48365+ *
48366+ * Revision 1.51 2004/10/03 01:26:36 mcr
48367+ * fixes for gcc 3.4 compilation.
48368+ *
48369+ * Revision 1.50 2004/07/10 07:48:35 mcr
48370+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
48371+ *
48372+ * Revision 1.49 2004/04/12 02:59:06 mcr
48373+ * erroneously moved pfkey_v2_build.c
48374+ *
48375+ * Revision 1.48 2004/04/09 18:00:40 mcr
48376+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
48377+ *
48378+ * Revision 1.47 2004/03/08 01:59:08 ken
48379+ * freeswan.h -> openswan.h
48380+ *
48381+ * Revision 1.46 2003/12/10 01:20:19 mcr
48382+ * NAT-traversal patches to KLIPS.
48383+ *
48384+ * Revision 1.45 2003/12/04 23:01:12 mcr
48385+ * removed ipsec_netlink.h
48386+ *
48387+ * Revision 1.44 2003/10/31 02:27:12 mcr
48388+ * pulled up port-selector patches and sa_id elimination.
48389+ *
48390+ * Revision 1.43.4.2 2003/10/29 01:11:32 mcr
48391+ * added debugging for pfkey library.
48392+ *
48393+ * Revision 1.43.4.1 2003/09/21 13:59:44 mcr
48394+ * pre-liminary X.509 patch - does not yet pass tests.
48395+ *
48396+ * Revision 1.43 2003/05/07 17:29:17 mcr
48397+ * new function pfkey_debug_func added for us in debugging from
48398+ * pfkey library.
48399+ *
48400+ * Revision 1.42 2003/01/30 02:32:09 rgb
48401+ *
48402+ * Rename SAref table macro names for clarity.
48403+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
48404+ *
48405+ * Revision 1.41 2002/12/13 18:16:02 mcr
48406+ * restored sa_ref code
48407+ *
48408+ * Revision 1.40 2002/12/13 18:06:52 mcr
48409+ * temporarily removed sadb_x_sa_ref reference for 2.xx
48410+ *
48411+ * Revision 1.39 2002/12/13 17:43:28 mcr
48412+ * commented out access to sadb_x_sa_ref for 2.xx branch
48413+ *
48414+ * Revision 1.38 2002/10/09 03:12:05 dhr
48415+ *
48416+ * [kenb+dhr] 64-bit fixes
48417+ *
48418+ * Revision 1.37 2002/09/20 15:40:39 rgb
48419+ * Added new function pfkey_sa_ref_build() to accomodate saref parameter.
48420+ *
48421+ * Revision 1.36 2002/09/20 05:01:22 rgb
48422+ * Generalise for platform independance: fix (ia64) using unsigned for sizes.
48423+ *
48424+ * Revision 1.35 2002/07/24 18:44:54 rgb
48425+ * Type fiddling to tame ia64 compiler.
48426+ *
48427+ * Revision 1.34 2002/05/23 07:14:11 rgb
48428+ * Cleaned up %p variants to 0p%p for test suite cleanup.
48429+ *
48430+ * Revision 1.33 2002/04/24 07:55:32 mcr
48431+ * #include patches and Makefiles for post-reorg compilation.
48432+ *
48433+ * Revision 1.32 2002/04/24 07:36:40 mcr
48434+ * Moved from ./lib/pfkey_v2_build.c,v
48435+ *
48436+ * Revision 1.31 2002/01/29 22:25:35 rgb
48437+ * Re-add ipsec_kversion.h to keep MALLOC happy.
48438+ *
48439+ * Revision 1.30 2002/01/29 01:59:09 mcr
48440+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
48441+ * updating of IPv6 structures to match latest in6.h version.
48442+ * removed dead code from openswan.h that also duplicated kversions.h
48443+ * code.
48444+ *
48445+ * Revision 1.29 2001/12/19 21:06:09 rgb
48446+ * Added port numbers to pfkey_address_build() debugging.
48447+ *
48448+ * Revision 1.28 2001/11/06 19:47:47 rgb
48449+ * Added packet parameter to lifetime and comb structures.
48450+ *
48451+ * Revision 1.27 2001/10/18 04:45:24 rgb
48452+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
48453+ * lib/openswan.h version macros moved to lib/kversions.h.
48454+ * Other compiler directive cleanups.
48455+ *
48456+ * Revision 1.26 2001/09/08 21:13:34 rgb
48457+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
48458+ *
48459+ * Revision 1.25 2001/06/14 19:35:16 rgb
48460+ * Update copyright date.
48461+ *
48462+ * Revision 1.24 2001/03/20 03:49:45 rgb
48463+ * Ditch superfluous debug_pfkey declaration.
48464+ * Move misplaced openswan.h inclusion for kernel case.
48465+ *
48466+ * Revision 1.23 2001/03/16 07:41:50 rgb
48467+ * Put openswan.h include before pluto includes.
48468+ *
48469+ * Revision 1.22 2001/02/27 22:24:56 rgb
48470+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
48471+ * Check for satoa() return codes.
48472+ *
48473+ * Revision 1.21 2000/11/17 18:10:30 rgb
48474+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
48475+ * network byte order since this is the way PF_KEYv2 stored spis.
48476+ *
48477+ * Revision 1.20 2000/10/12 00:02:39 rgb
48478+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
48479+ *
48480+ * Revision 1.19 2000/10/10 20:10:20 rgb
48481+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
48482+ *
48483+ * Revision 1.18 2000/09/12 18:59:54 rgb
48484+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
48485+ *
48486+ * Revision 1.17 2000/09/12 03:27:00 rgb
48487+ * Moved DEBUGGING definition to compile kernel with debug off.
48488+ *
48489+ * Revision 1.16 2000/09/08 19:22:12 rgb
48490+ * Fixed pfkey_prop_build() parameter to be only single indirection.
48491+ * Fixed struct alg copy.
48492+ *
48493+ * Revision 1.15 2000/08/20 21:40:01 rgb
48494+ * Added an address parameter sanity check to pfkey_address_build().
48495+ *
48496+ * Revision 1.14 2000/08/15 17:29:23 rgb
48497+ * Fixes from SZI to untested pfkey_prop_build().
48498+ *
48499+ * Revision 1.13 2000/06/02 22:54:14 rgb
48500+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
48501+ *
48502+ * Revision 1.12 2000/05/10 19:24:01 rgb
48503+ * Fleshed out sensitivity, proposal and supported extensions.
48504+ *
48505+ * Revision 1.11 2000/03/16 14:07:23 rgb
48506+ * Renamed ALIGN macro to avoid fighting with others in kernel.
48507+ *
48508+ * Revision 1.10 2000/01/24 21:14:35 rgb
48509+ * Added disabled pluto pfkey lib debug flag.
48510+ *
48511+ * Revision 1.9 2000/01/21 06:27:32 rgb
48512+ * Added address cases for eroute flows.
48513+ * Removed unused code.
48514+ * Dropped unused argument to pfkey_x_satype_build().
48515+ * Indented compiler directives for readability.
48516+ * Added klipsdebug switching capability.
48517+ * Fixed SADB_EXT_MAX bug not permitting last extension access.
48518+ *
48519+ * Revision 1.8 1999/12/29 21:17:41 rgb
48520+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
48521+ * parameter for cleaner manipulation of extensions[] and to guard
48522+ * against potential memory leaks.
48523+ * Changed the I/F to pfkey_msg_free() for the same reason.
48524+ *
48525+ * Revision 1.7 1999/12/09 23:12:20 rgb
48526+ * Removed unused cruft.
48527+ * Added argument to pfkey_sa_build() to do eroutes.
48528+ * Fixed exttype check in as yet unused pfkey_lifetime_build().
48529+ *
48530+ * Revision 1.6 1999/12/07 19:54:29 rgb
48531+ * Removed static pluto debug flag.
48532+ * Added functions for pfkey message and extensions initialisation
48533+ * and cleanup.
48534+ *
48535+ * Revision 1.5 1999/12/01 22:20:06 rgb
48536+ * Changed pfkey_sa_build to accept an SPI in network byte order.
48537+ * Added <string.h> to quiet userspace compiler.
48538+ * Moved pfkey_lib_debug variable into the library.
48539+ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
48540+ * Added extension assembly debugging.
48541+ * Isolated assignment with brackets to be sure of scope.
48542+ *
48543+ * Revision 1.4 1999/11/27 11:57:35 rgb
48544+ * Added ipv6 headers.
48545+ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
48546+ * Debugging error messages added.
48547+ * Fixed missing auth and encrypt assignment bug.
48548+ * Add argument to pfkey_msg_parse() for direction.
48549+ * Move parse-after-build check inside pfkey_msg_build().
48550+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
48551+ * Add CVS log entry to bottom of file.
48552+ *
48553+ */
48554--- /dev/null Tue Mar 11 13:02:56 2003
48555+++ linux/net/ipsec/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004
48556@@ -0,0 +1,181 @@
48557+/*
48558+ * @(#) pfkey version 2 debugging messages
48559+ *
48560+ * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org>
48561+ * and Michael Richardson <mcr@openswan.org>
48562+ *
48563+ * This program is free software; you can redistribute it and/or modify it
48564+ * under the terms of the GNU General Public License as published by the
48565+ * Free Software Foundation; either version 2 of the License, or (at your
48566+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
48567+ *
48568+ * This program is distributed in the hope that it will be useful, but
48569+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48570+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48571+ * for more details.
48572+ *
48573+ * RCSID $Id: pfkey_v2_debug.c,v 1.11 2005-04-06 17:45:16 mcr Exp $
48574+ *
48575+ */
48576+
48577+#ifdef __KERNEL__
48578+
48579+# include <linux/kernel.h> /* for printk */
48580+
48581+# include "openswan/ipsec_kversion.h" /* for malloc switch */
48582+# ifdef MALLOC_SLAB
48583+# include <linux/slab.h> /* kmalloc() */
48584+# else /* MALLOC_SLAB */
48585+# include <linux/malloc.h> /* kmalloc() */
48586+# endif /* MALLOC_SLAB */
48587+# include <linux/errno.h> /* error codes */
48588+# include <linux/types.h> /* size_t */
48589+# include <linux/interrupt.h> /* mark_bh */
48590+
48591+# include <linux/netdevice.h> /* struct device, and other headers */
48592+# include <linux/etherdevice.h> /* eth_type_trans */
48593+extern int debug_pfkey;
48594+
48595+#else /* __KERNEL__ */
48596+
48597+# include <sys/types.h>
48598+# include <linux/types.h>
48599+# include <linux/errno.h>
48600+
48601+#endif /* __KERNEL__ */
48602+
48603+#include "openswan.h"
48604+#include "pfkeyv2.h"
48605+#include "pfkey.h"
48606+
48607+/*
48608+ * This file provides ASCII translations of PF_KEY magic numbers.
48609+ *
48610+ */
48611+
48612+static char *pfkey_sadb_ext_strings[]={
48613+ "reserved", /* SADB_EXT_RESERVED 0 */
48614+ "security-association", /* SADB_EXT_SA 1 */
48615+ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */
48616+ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */
48617+ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */
48618+ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */
48619+ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */
48620+ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */
48621+ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */
48622+ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */
48623+ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */
48624+ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */
48625+ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */
48626+ "proposal", /* SADB_EXT_PROPOSAL 13 */
48627+ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */
48628+ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */
48629+ "spi-range", /* SADB_EXT_SPIRANGE 16 */
48630+ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */
48631+ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */
48632+ "X-security-association", /* SADB_X_EXT_SA2 19 */
48633+ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */
48634+ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
48635+ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */
48636+ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */
48637+ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */
48638+ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */
48639+ /* NAT_TRAVERSAL */
48640+ "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */
48641+ "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */
48642+ "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */
48643+ "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */
48644+};
48645+
48646+const char *
48647+pfkey_v2_sadb_ext_string(int ext)
48648+{
48649+ if(ext <= SADB_EXT_MAX) {
48650+ return pfkey_sadb_ext_strings[ext];
48651+ } else {
48652+ return "unknown-ext";
48653+ }
48654+}
48655+
48656+
48657+static char *pfkey_sadb_type_strings[]={
48658+ "reserved", /* SADB_RESERVED */
48659+ "getspi", /* SADB_GETSPI */
48660+ "update", /* SADB_UPDATE */
48661+ "add", /* SADB_ADD */
48662+ "delete", /* SADB_DELETE */
48663+ "get", /* SADB_GET */
48664+ "acquire", /* SADB_ACQUIRE */
48665+ "register", /* SADB_REGISTER */
48666+ "expire", /* SADB_EXPIRE */
48667+ "flush", /* SADB_FLUSH */
48668+ "dump", /* SADB_DUMP */
48669+ "x-promisc", /* SADB_X_PROMISC */
48670+ "x-pchange", /* SADB_X_PCHANGE */
48671+ "x-groupsa", /* SADB_X_GRPSA */
48672+ "x-addflow(eroute)", /* SADB_X_ADDFLOW */
48673+ "x-delflow(eroute)", /* SADB_X_DELFLOW */
48674+ "x-debug", /* SADB_X_DEBUG */
48675+};
48676+
48677+const char *
48678+pfkey_v2_sadb_type_string(int sadb_type)
48679+{
48680+ if(sadb_type <= SADB_MAX) {
48681+ return pfkey_sadb_type_strings[sadb_type];
48682+ } else {
48683+ return "unknown-sadb-type";
48684+ }
48685+}
48686+
48687+
48688+
48689+
48690+/*
48691+ * $Log: pfkey_v2_debug.c,v $
48692+ * Revision 1.11 2005-04-06 17:45:16 mcr
48693+ * always include NAT-T names.
48694+ *
48695+ * Revision 1.10 2004/07/10 07:48:35 mcr
48696+ * Moved from linux/lib/libfreeswan/pfkey_v2_debug.c,v
48697+ *
48698+ * Revision 1.9 2004/03/08 01:59:08 ken
48699+ * freeswan.h -> openswan.h
48700+ *
48701+ * Revision 1.8 2003/12/10 01:20:19 mcr
48702+ * NAT-traversal patches to KLIPS.
48703+ *
48704+ * Revision 1.7 2002/09/20 05:01:26 rgb
48705+ * Fixed limit inclusion error in both type and ext string conversion.
48706+ *
48707+ * Revision 1.6 2002/04/24 07:55:32 mcr
48708+ * #include patches and Makefiles for post-reorg compilation.
48709+ *
48710+ * Revision 1.5 2002/04/24 07:36:40 mcr
48711+ * Moved from ./lib/pfkey_v2_debug.c,v
48712+ *
48713+ * Revision 1.4 2002/01/29 22:25:36 rgb
48714+ * Re-add ipsec_kversion.h to keep MALLOC happy.
48715+ *
48716+ * Revision 1.3 2002/01/29 01:59:09 mcr
48717+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
48718+ * updating of IPv6 structures to match latest in6.h version.
48719+ * removed dead code from openswan.h that also duplicated kversions.h
48720+ * code.
48721+ *
48722+ * Revision 1.2 2002/01/20 20:34:50 mcr
48723+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
48724+ *
48725+ * Revision 1.1 2001/11/27 05:30:06 mcr
48726+ * initial set of debug strings for pfkey debugging.
48727+ * this will eventually only be included for debug builds.
48728+ *
48729+ * Revision 1.1 2001/09/21 04:12:03 mcr
48730+ * first compilable version.
48731+ *
48732+ *
48733+ * Local variables:
48734+ * c-file-style: "linux"
48735+ * End:
48736+ *
48737+ */
48738--- /dev/null Tue Mar 11 13:02:56 2003
48739+++ linux/net/ipsec/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004
48740@@ -0,0 +1,814 @@
48741+/*
48742+ * RFC2367 PF_KEYv2 Key management API message parser
48743+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
48744+ *
48745+ * This program is free software; you can redistribute it and/or modify it
48746+ * under the terms of the GNU General Public License as published by the
48747+ * Free Software Foundation; either version 2 of the License, or (at your
48748+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
48749+ *
48750+ * This program is distributed in the hope that it will be useful, but
48751+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48752+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48753+ * for more details.
48754+ *
48755+ * RCSID $Id: pfkey_v2_ext_bits.c,v 1.22 2005-05-11 01:45:31 mcr Exp $
48756+ */
48757+
48758+/*
48759+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
48760+ */
48761+
48762+char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.22 2005-05-11 01:45:31 mcr Exp $";
48763+
48764+/*
48765+ * Some ugly stuff to allow consistent debugging code for use in the
48766+ * kernel and in user space
48767+*/
48768+
48769+#ifdef __KERNEL__
48770+
48771+# include <linux/kernel.h> /* for printk */
48772+
48773+# include "openswan/ipsec_kversion.h" /* for malloc switch */
48774+# ifdef MALLOC_SLAB
48775+# include <linux/slab.h> /* kmalloc() */
48776+# else /* MALLOC_SLAB */
48777+# include <linux/malloc.h> /* kmalloc() */
48778+# endif /* MALLOC_SLAB */
48779+# include <linux/errno.h> /* error codes */
48780+# include <linux/types.h> /* size_t */
48781+# include <linux/interrupt.h> /* mark_bh */
48782+
48783+# include <linux/netdevice.h> /* struct device, and other headers */
48784+# include <linux/etherdevice.h> /* eth_type_trans */
48785+# include <linux/ip.h> /* struct iphdr */
48786+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
48787+# include <linux/ipv6.h>
48788+# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
48789+
48790+#else /* __KERNEL__ */
48791+
48792+# include <sys/types.h>
48793+# include <linux/types.h>
48794+# include <linux/errno.h>
48795+#endif
48796+
48797+#include <openswan.h>
48798+#include <pfkeyv2.h>
48799+#include <pfkey.h>
48800+
48801+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX] = {
48802+
48803+/* INBOUND EXTENSIONS */
48804+{
48805+
48806+/* PERMITTED IN */
48807+{
48808+/* SADB_RESERVED */
48809+0
48810+,
48811+/* SADB_GETSPI */
48812+1<<SADB_EXT_RESERVED
48813+| 1<<SADB_EXT_ADDRESS_SRC
48814+| 1<<SADB_EXT_ADDRESS_DST
48815+| 1<<SADB_EXT_ADDRESS_PROXY
48816+| 1<<SADB_EXT_SPIRANGE
48817+,
48818+/* SADB_UPDATE */
48819+1<<SADB_EXT_RESERVED
48820+| 1<<SADB_EXT_SA
48821+| 1<<SADB_EXT_LIFETIME_CURRENT
48822+| 1<<SADB_EXT_LIFETIME_HARD
48823+| 1<<SADB_EXT_LIFETIME_SOFT
48824+| 1<<SADB_EXT_ADDRESS_SRC
48825+| 1<<SADB_EXT_ADDRESS_DST
48826+| 1<<SADB_EXT_ADDRESS_PROXY
48827+| 1<<SADB_EXT_KEY_AUTH
48828+| 1<<SADB_EXT_KEY_ENCRYPT
48829+| 1<<SADB_EXT_IDENTITY_SRC
48830+| 1<<SADB_EXT_IDENTITY_DST
48831+| 1<<SADB_EXT_SENSITIVITY
48832+| 1<<SADB_X_EXT_NAT_T_SPORT
48833+| 1<<SADB_X_EXT_NAT_T_DPORT
48834+,
48835+/* SADB_ADD */
48836+1<<SADB_EXT_RESERVED
48837+| 1<<SADB_EXT_SA
48838+| 1<<SADB_EXT_LIFETIME_HARD
48839+| 1<<SADB_EXT_LIFETIME_SOFT
48840+| 1<<SADB_EXT_ADDRESS_SRC
48841+| 1<<SADB_EXT_ADDRESS_DST
48842+| 1<<SADB_EXT_ADDRESS_PROXY
48843+| 1<<SADB_EXT_KEY_AUTH
48844+| 1<<SADB_EXT_KEY_ENCRYPT
48845+| 1<<SADB_EXT_IDENTITY_SRC
48846+| 1<<SADB_EXT_IDENTITY_DST
48847+| 1<<SADB_EXT_SENSITIVITY
48848+| 1<<SADB_X_EXT_NAT_T_TYPE
48849+| 1<<SADB_X_EXT_NAT_T_SPORT
48850+| 1<<SADB_X_EXT_NAT_T_DPORT
48851+| 1<<SADB_X_EXT_NAT_T_OA
48852+,
48853+/* SADB_DELETE */
48854+1<<SADB_EXT_RESERVED
48855+| 1<<SADB_EXT_SA
48856+| 1<<SADB_EXT_ADDRESS_SRC
48857+| 1<<SADB_EXT_ADDRESS_DST
48858+,
48859+/* SADB_GET */
48860+1<<SADB_EXT_RESERVED
48861+| 1<<SADB_EXT_SA
48862+| 1<<SADB_EXT_ADDRESS_SRC
48863+| 1<<SADB_EXT_ADDRESS_DST
48864+,
48865+/* SADB_ACQUIRE */
48866+1<<SADB_EXT_RESERVED
48867+| 1<<SADB_EXT_ADDRESS_SRC
48868+| 1<<SADB_EXT_ADDRESS_DST
48869+| 1<<SADB_EXT_ADDRESS_PROXY
48870+| 1<<SADB_EXT_IDENTITY_SRC
48871+| 1<<SADB_EXT_IDENTITY_DST
48872+| 1<<SADB_EXT_SENSITIVITY
48873+| 1<<SADB_EXT_PROPOSAL
48874+,
48875+/* SADB_REGISTER */
48876+1<<SADB_EXT_RESERVED
48877+,
48878+/* SADB_EXPIRE */
48879+0
48880+,
48881+/* SADB_FLUSH */
48882+1<<SADB_EXT_RESERVED
48883+,
48884+/* SADB_DUMP */
48885+1<<SADB_EXT_RESERVED
48886+,
48887+/* SADB_X_PROMISC */
48888+1<<SADB_EXT_RESERVED
48889+| 1<<SADB_EXT_SA
48890+| 1<<SADB_EXT_LIFETIME_CURRENT
48891+| 1<<SADB_EXT_LIFETIME_HARD
48892+| 1<<SADB_EXT_LIFETIME_SOFT
48893+| 1<<SADB_EXT_ADDRESS_SRC
48894+| 1<<SADB_EXT_ADDRESS_DST
48895+| 1<<SADB_EXT_ADDRESS_PROXY
48896+| 1<<SADB_EXT_KEY_AUTH
48897+| 1<<SADB_EXT_KEY_ENCRYPT
48898+| 1<<SADB_EXT_IDENTITY_SRC
48899+| 1<<SADB_EXT_IDENTITY_DST
48900+| 1<<SADB_EXT_SENSITIVITY
48901+| 1<<SADB_EXT_PROPOSAL
48902+| 1<<SADB_EXT_SUPPORTED_AUTH
48903+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48904+| 1<<SADB_EXT_SPIRANGE
48905+| 1<<SADB_X_EXT_KMPRIVATE
48906+| 1<<SADB_X_EXT_SATYPE2
48907+| 1<<SADB_X_EXT_SA2
48908+| 1<<SADB_X_EXT_ADDRESS_DST2
48909+,
48910+/* SADB_X_PCHANGE */
48911+1<<SADB_EXT_RESERVED
48912+| 1<<SADB_EXT_SA
48913+| 1<<SADB_EXT_LIFETIME_CURRENT
48914+| 1<<SADB_EXT_LIFETIME_HARD
48915+| 1<<SADB_EXT_LIFETIME_SOFT
48916+| 1<<SADB_EXT_ADDRESS_SRC
48917+| 1<<SADB_EXT_ADDRESS_DST
48918+| 1<<SADB_EXT_ADDRESS_PROXY
48919+| 1<<SADB_EXT_KEY_AUTH
48920+| 1<<SADB_EXT_KEY_ENCRYPT
48921+| 1<<SADB_EXT_IDENTITY_SRC
48922+| 1<<SADB_EXT_IDENTITY_DST
48923+| 1<<SADB_EXT_SENSITIVITY
48924+| 1<<SADB_EXT_PROPOSAL
48925+| 1<<SADB_EXT_SUPPORTED_AUTH
48926+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48927+| 1<<SADB_EXT_SPIRANGE
48928+| 1<<SADB_X_EXT_KMPRIVATE
48929+| 1<<SADB_X_EXT_SATYPE2
48930+| 1<<SADB_X_EXT_SA2
48931+| 1<<SADB_X_EXT_ADDRESS_DST2
48932+,
48933+/* SADB_X_GRPSA */
48934+1<<SADB_EXT_RESERVED
48935+| 1<<SADB_EXT_SA
48936+| 1<<SADB_EXT_ADDRESS_DST
48937+| 1<<SADB_X_EXT_SATYPE2
48938+| 1<<SADB_X_EXT_SA2
48939+| 1<<SADB_X_EXT_ADDRESS_DST2
48940+,
48941+/* SADB_X_ADDFLOW */
48942+1<<SADB_EXT_RESERVED
48943+| 1<<SADB_EXT_SA
48944+| 1<<SADB_EXT_ADDRESS_SRC
48945+| 1<<SADB_EXT_ADDRESS_DST
48946+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48947+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48948+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48949+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48950+| 1<<SADB_EXT_IDENTITY_SRC
48951+| 1<<SADB_EXT_IDENTITY_DST
48952+| 1<<SADB_X_EXT_PROTOCOL
48953+,
48954+/* SADB_X_DELFLOW */
48955+1<<SADB_EXT_RESERVED
48956+| 1<<SADB_EXT_SA
48957+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48958+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48959+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48960+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48961+| 1<<SADB_EXT_IDENTITY_SRC
48962+| 1<<SADB_EXT_IDENTITY_DST
48963+| 1<<SADB_X_EXT_PROTOCOL
48964+,
48965+/* SADB_X_DEBUG */
48966+1<<SADB_EXT_RESERVED
48967+| 1<<SADB_X_EXT_DEBUG
48968+,
48969+/* SADB_X_NAT_T_NEW_MAPPING */
48970+1<<SADB_EXT_RESERVED
48971+| 1<<SADB_EXT_SA
48972+| 1<<SADB_EXT_ADDRESS_SRC
48973+| 1<<SADB_EXT_ADDRESS_DST
48974+| 1<<SADB_X_EXT_NAT_T_SPORT
48975+| 1<<SADB_X_EXT_NAT_T_DPORT
48976+},
48977+
48978+/* REQUIRED IN */
48979+{
48980+/* SADB_RESERVED */
48981+0
48982+,
48983+/* SADB_GETSPI */
48984+1<<SADB_EXT_RESERVED
48985+| 1<<SADB_EXT_ADDRESS_SRC
48986+| 1<<SADB_EXT_ADDRESS_DST
48987+| 1<<SADB_EXT_SPIRANGE
48988+,
48989+/* SADB_UPDATE */
48990+1<<SADB_EXT_RESERVED
48991+| 1<<SADB_EXT_SA
48992+| 1<<SADB_EXT_ADDRESS_SRC
48993+| 1<<SADB_EXT_ADDRESS_DST
48994+/*| 1<<SADB_EXT_KEY_AUTH*/
48995+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
48996+,
48997+/* SADB_ADD */
48998+1<<SADB_EXT_RESERVED
48999+| 1<<SADB_EXT_SA
49000+| 1<<SADB_EXT_ADDRESS_SRC
49001+| 1<<SADB_EXT_ADDRESS_DST
49002+/*| 1<<SADB_EXT_KEY_AUTH*/
49003+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
49004+,
49005+/* SADB_DELETE */
49006+1<<SADB_EXT_RESERVED
49007+| 1<<SADB_EXT_SA
49008+| 1<<SADB_EXT_ADDRESS_SRC
49009+| 1<<SADB_EXT_ADDRESS_DST
49010+,
49011+/* SADB_GET */
49012+1<<SADB_EXT_RESERVED
49013+| 1<<SADB_EXT_SA
49014+| 1<<SADB_EXT_ADDRESS_SRC
49015+| 1<<SADB_EXT_ADDRESS_DST
49016+,
49017+/* SADB_ACQUIRE */
49018+1<<SADB_EXT_RESERVED
49019+| 1<<SADB_EXT_ADDRESS_SRC
49020+| 1<<SADB_EXT_ADDRESS_DST
49021+| 1<<SADB_EXT_PROPOSAL
49022+,
49023+/* SADB_REGISTER */
49024+1<<SADB_EXT_RESERVED
49025+,
49026+/* SADB_EXPIRE */
49027+0
49028+,
49029+/* SADB_FLUSH */
49030+1<<SADB_EXT_RESERVED
49031+,
49032+/* SADB_DUMP */
49033+1<<SADB_EXT_RESERVED
49034+,
49035+/* SADB_X_PROMISC */
49036+1<<SADB_EXT_RESERVED
49037+| 1<<SADB_EXT_SA
49038+| 1<<SADB_EXT_LIFETIME_CURRENT
49039+| 1<<SADB_EXT_LIFETIME_HARD
49040+| 1<<SADB_EXT_LIFETIME_SOFT
49041+| 1<<SADB_EXT_ADDRESS_SRC
49042+| 1<<SADB_EXT_ADDRESS_DST
49043+| 1<<SADB_EXT_ADDRESS_PROXY
49044+| 1<<SADB_EXT_KEY_AUTH
49045+| 1<<SADB_EXT_KEY_ENCRYPT
49046+| 1<<SADB_EXT_IDENTITY_SRC
49047+| 1<<SADB_EXT_IDENTITY_DST
49048+| 1<<SADB_EXT_SENSITIVITY
49049+| 1<<SADB_EXT_PROPOSAL
49050+| 1<<SADB_EXT_SUPPORTED_AUTH
49051+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49052+| 1<<SADB_EXT_SPIRANGE
49053+| 1<<SADB_X_EXT_KMPRIVATE
49054+| 1<<SADB_X_EXT_SATYPE2
49055+| 1<<SADB_X_EXT_SA2
49056+| 1<<SADB_X_EXT_ADDRESS_DST2
49057+,
49058+/* SADB_X_PCHANGE */
49059+1<<SADB_EXT_RESERVED
49060+| 1<<SADB_EXT_SA
49061+| 1<<SADB_EXT_LIFETIME_CURRENT
49062+| 1<<SADB_EXT_LIFETIME_HARD
49063+| 1<<SADB_EXT_LIFETIME_SOFT
49064+| 1<<SADB_EXT_ADDRESS_SRC
49065+| 1<<SADB_EXT_ADDRESS_DST
49066+| 1<<SADB_EXT_ADDRESS_PROXY
49067+| 1<<SADB_EXT_KEY_AUTH
49068+| 1<<SADB_EXT_KEY_ENCRYPT
49069+| 1<<SADB_EXT_IDENTITY_SRC
49070+| 1<<SADB_EXT_IDENTITY_DST
49071+| 1<<SADB_EXT_SENSITIVITY
49072+| 1<<SADB_EXT_PROPOSAL
49073+| 1<<SADB_EXT_SUPPORTED_AUTH
49074+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49075+| 1<<SADB_EXT_SPIRANGE
49076+| 1<<SADB_X_EXT_KMPRIVATE
49077+| 1<<SADB_X_EXT_SATYPE2
49078+| 1<<SADB_X_EXT_SA2
49079+| 1<<SADB_X_EXT_ADDRESS_DST2
49080+,
49081+/* SADB_X_GRPSA */
49082+1<<SADB_EXT_RESERVED
49083+| 1<<SADB_EXT_SA
49084+| 1<<SADB_EXT_ADDRESS_DST
49085+/*| 1<<SADB_X_EXT_SATYPE2*/
49086+/*| 1<<SADB_X_EXT_SA2*/
49087+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
49088+,
49089+/* SADB_X_ADDFLOW */
49090+1<<SADB_EXT_RESERVED
49091+| 1<<SADB_EXT_SA
49092+| 1<<SADB_EXT_ADDRESS_DST
49093+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49094+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49095+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49096+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49097+,
49098+/* SADB_X_DELFLOW */
49099+1<<SADB_EXT_RESERVED
49100+/*| 1<<SADB_EXT_SA*/
49101+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
49102+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49103+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49104+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49105+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49106+#endif
49107+,
49108+/* SADB_X_DEBUG */
49109+1<<SADB_EXT_RESERVED
49110+| 1<<SADB_X_EXT_DEBUG
49111+,
49112+/* SADB_X_NAT_T_NEW_MAPPING */
49113+1<<SADB_EXT_RESERVED
49114+| 1<<SADB_EXT_SA
49115+| 1<<SADB_EXT_ADDRESS_SRC
49116+| 1<<SADB_EXT_ADDRESS_DST
49117+| 1<<SADB_X_EXT_NAT_T_SPORT
49118+| 1<<SADB_X_EXT_NAT_T_DPORT
49119+}
49120+
49121+},
49122+
49123+/* OUTBOUND EXTENSIONS */
49124+{
49125+
49126+/* PERMITTED OUT */
49127+{
49128+/* SADB_RESERVED */
49129+0
49130+,
49131+/* SADB_GETSPI */
49132+1<<SADB_EXT_RESERVED
49133+| 1<<SADB_EXT_SA
49134+| 1<<SADB_EXT_ADDRESS_SRC
49135+| 1<<SADB_EXT_ADDRESS_DST
49136+,
49137+/* SADB_UPDATE */
49138+1<<SADB_EXT_RESERVED
49139+| 1<<SADB_EXT_SA
49140+| 1<<SADB_EXT_LIFETIME_CURRENT
49141+| 1<<SADB_EXT_LIFETIME_HARD
49142+| 1<<SADB_EXT_LIFETIME_SOFT
49143+| 1<<SADB_EXT_ADDRESS_SRC
49144+| 1<<SADB_EXT_ADDRESS_DST
49145+| 1<<SADB_EXT_ADDRESS_PROXY
49146+| 1<<SADB_EXT_IDENTITY_SRC
49147+| 1<<SADB_EXT_IDENTITY_DST
49148+| 1<<SADB_EXT_SENSITIVITY
49149+| 1<<SADB_X_EXT_NAT_T_SPORT
49150+| 1<<SADB_X_EXT_NAT_T_DPORT
49151+,
49152+/* SADB_ADD */
49153+1<<SADB_EXT_RESERVED
49154+| 1<<SADB_EXT_SA
49155+| 1<<SADB_EXT_LIFETIME_HARD
49156+| 1<<SADB_EXT_LIFETIME_SOFT
49157+| 1<<SADB_EXT_ADDRESS_SRC
49158+| 1<<SADB_EXT_ADDRESS_DST
49159+| 1<<SADB_EXT_IDENTITY_SRC
49160+| 1<<SADB_EXT_IDENTITY_DST
49161+| 1<<SADB_EXT_SENSITIVITY
49162+| 1<<SADB_X_EXT_NAT_T_TYPE
49163+| 1<<SADB_X_EXT_NAT_T_SPORT
49164+| 1<<SADB_X_EXT_NAT_T_DPORT
49165+| 1<<SADB_X_EXT_NAT_T_OA
49166+,
49167+/* SADB_DELETE */
49168+1<<SADB_EXT_RESERVED
49169+| 1<<SADB_EXT_SA
49170+| 1<<SADB_EXT_ADDRESS_SRC
49171+| 1<<SADB_EXT_ADDRESS_DST
49172+,
49173+/* SADB_GET */
49174+1<<SADB_EXT_RESERVED
49175+| 1<<SADB_EXT_SA
49176+| 1<<SADB_EXT_LIFETIME_CURRENT
49177+| 1<<SADB_EXT_LIFETIME_HARD
49178+| 1<<SADB_EXT_LIFETIME_SOFT
49179+| 1<<SADB_EXT_ADDRESS_SRC
49180+| 1<<SADB_EXT_ADDRESS_DST
49181+| 1<<SADB_EXT_ADDRESS_PROXY
49182+| 1<<SADB_EXT_KEY_AUTH
49183+| 1<<SADB_EXT_KEY_ENCRYPT
49184+| 1<<SADB_EXT_IDENTITY_SRC
49185+| 1<<SADB_EXT_IDENTITY_DST
49186+| 1<<SADB_EXT_SENSITIVITY
49187+| 1<<SADB_X_EXT_NAT_T_TYPE
49188+| 1<<SADB_X_EXT_NAT_T_SPORT
49189+| 1<<SADB_X_EXT_NAT_T_DPORT
49190+| 1<<SADB_X_EXT_NAT_T_OA
49191+,
49192+/* SADB_ACQUIRE */
49193+1<<SADB_EXT_RESERVED
49194+| 1<<SADB_EXT_ADDRESS_SRC
49195+| 1<<SADB_EXT_ADDRESS_DST
49196+| 1<<SADB_EXT_ADDRESS_PROXY
49197+| 1<<SADB_EXT_IDENTITY_SRC
49198+| 1<<SADB_EXT_IDENTITY_DST
49199+| 1<<SADB_EXT_SENSITIVITY
49200+| 1<<SADB_EXT_PROPOSAL
49201+,
49202+/* SADB_REGISTER */
49203+1<<SADB_EXT_RESERVED
49204+| 1<<SADB_EXT_SUPPORTED_AUTH
49205+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49206+,
49207+/* SADB_EXPIRE */
49208+1<<SADB_EXT_RESERVED
49209+| 1<<SADB_EXT_SA
49210+| 1<<SADB_EXT_LIFETIME_CURRENT
49211+| 1<<SADB_EXT_LIFETIME_HARD
49212+| 1<<SADB_EXT_LIFETIME_SOFT
49213+| 1<<SADB_EXT_ADDRESS_SRC
49214+| 1<<SADB_EXT_ADDRESS_DST
49215+,
49216+/* SADB_FLUSH */
49217+1<<SADB_EXT_RESERVED
49218+,
49219+/* SADB_DUMP */
49220+1<<SADB_EXT_RESERVED
49221+| 1<<SADB_EXT_SA
49222+| 1<<SADB_EXT_LIFETIME_CURRENT
49223+| 1<<SADB_EXT_LIFETIME_HARD
49224+| 1<<SADB_EXT_LIFETIME_SOFT
49225+| 1<<SADB_EXT_ADDRESS_SRC
49226+| 1<<SADB_EXT_ADDRESS_DST
49227+| 1<<SADB_EXT_ADDRESS_PROXY
49228+| 1<<SADB_EXT_KEY_AUTH
49229+| 1<<SADB_EXT_KEY_ENCRYPT
49230+| 1<<SADB_EXT_IDENTITY_SRC
49231+| 1<<SADB_EXT_IDENTITY_DST
49232+| 1<<SADB_EXT_SENSITIVITY
49233+| 1<<SADB_X_EXT_NAT_T_TYPE
49234+| 1<<SADB_X_EXT_NAT_T_SPORT
49235+| 1<<SADB_X_EXT_NAT_T_DPORT
49236+| 1<<SADB_X_EXT_NAT_T_OA
49237+,
49238+/* SADB_X_PROMISC */
49239+1<<SADB_EXT_RESERVED
49240+| 1<<SADB_EXT_SA
49241+| 1<<SADB_EXT_LIFETIME_CURRENT
49242+| 1<<SADB_EXT_LIFETIME_HARD
49243+| 1<<SADB_EXT_LIFETIME_SOFT
49244+| 1<<SADB_EXT_ADDRESS_SRC
49245+| 1<<SADB_EXT_ADDRESS_DST
49246+| 1<<SADB_EXT_ADDRESS_PROXY
49247+| 1<<SADB_EXT_KEY_AUTH
49248+| 1<<SADB_EXT_KEY_ENCRYPT
49249+| 1<<SADB_EXT_IDENTITY_SRC
49250+| 1<<SADB_EXT_IDENTITY_DST
49251+| 1<<SADB_EXT_SENSITIVITY
49252+| 1<<SADB_EXT_PROPOSAL
49253+| 1<<SADB_EXT_SUPPORTED_AUTH
49254+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49255+| 1<<SADB_EXT_SPIRANGE
49256+| 1<<SADB_X_EXT_KMPRIVATE
49257+| 1<<SADB_X_EXT_SATYPE2
49258+| 1<<SADB_X_EXT_SA2
49259+| 1<<SADB_X_EXT_ADDRESS_DST2
49260+,
49261+/* SADB_X_PCHANGE */
49262+1<<SADB_EXT_RESERVED
49263+| 1<<SADB_EXT_SA
49264+| 1<<SADB_EXT_LIFETIME_CURRENT
49265+| 1<<SADB_EXT_LIFETIME_HARD
49266+| 1<<SADB_EXT_LIFETIME_SOFT
49267+| 1<<SADB_EXT_ADDRESS_SRC
49268+| 1<<SADB_EXT_ADDRESS_DST
49269+| 1<<SADB_EXT_ADDRESS_PROXY
49270+| 1<<SADB_EXT_KEY_AUTH
49271+| 1<<SADB_EXT_KEY_ENCRYPT
49272+| 1<<SADB_EXT_IDENTITY_SRC
49273+| 1<<SADB_EXT_IDENTITY_DST
49274+| 1<<SADB_EXT_SENSITIVITY
49275+| 1<<SADB_EXT_PROPOSAL
49276+| 1<<SADB_EXT_SUPPORTED_AUTH
49277+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49278+| 1<<SADB_EXT_SPIRANGE
49279+| 1<<SADB_X_EXT_KMPRIVATE
49280+| 1<<SADB_X_EXT_SATYPE2
49281+| 1<<SADB_X_EXT_SA2
49282+| 1<<SADB_X_EXT_ADDRESS_DST2
49283+,
49284+/* SADB_X_GRPSA */
49285+1<<SADB_EXT_RESERVED
49286+| 1<<SADB_EXT_SA
49287+| 1<<SADB_EXT_ADDRESS_DST
49288+| 1<<SADB_X_EXT_SATYPE2
49289+| 1<<SADB_X_EXT_SA2
49290+| 1<<SADB_X_EXT_ADDRESS_DST2
49291+,
49292+/* SADB_X_ADDFLOW */
49293+1<<SADB_EXT_RESERVED
49294+| 1<<SADB_EXT_SA
49295+| 1<<SADB_EXT_ADDRESS_SRC
49296+| 1<<SADB_EXT_ADDRESS_DST
49297+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49298+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49299+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49300+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49301+| 1<<SADB_X_EXT_PROTOCOL
49302+,
49303+/* SADB_X_DELFLOW */
49304+1<<SADB_EXT_RESERVED
49305+| 1<<SADB_EXT_SA
49306+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49307+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49308+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49309+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49310+| 1<<SADB_X_EXT_PROTOCOL
49311+,
49312+/* SADB_X_DEBUG */
49313+1<<SADB_EXT_RESERVED
49314+| 1<<SADB_X_EXT_DEBUG
49315+,
49316+/* SADB_X_NAT_T_NEW_MAPPING */
49317+1<<SADB_EXT_RESERVED
49318+| 1<<SADB_EXT_SA
49319+| 1<<SADB_EXT_ADDRESS_SRC
49320+| 1<<SADB_EXT_ADDRESS_DST
49321+| 1<<SADB_X_EXT_NAT_T_SPORT
49322+| 1<<SADB_X_EXT_NAT_T_DPORT
49323+},
49324+
49325+/* REQUIRED OUT */
49326+{
49327+/* SADB_RESERVED */
49328+0
49329+,
49330+/* SADB_GETSPI */
49331+1<<SADB_EXT_RESERVED
49332+| 1<<SADB_EXT_SA
49333+| 1<<SADB_EXT_ADDRESS_SRC
49334+| 1<<SADB_EXT_ADDRESS_DST
49335+,
49336+/* SADB_UPDATE */
49337+1<<SADB_EXT_RESERVED
49338+| 1<<SADB_EXT_SA
49339+| 1<<SADB_EXT_ADDRESS_SRC
49340+| 1<<SADB_EXT_ADDRESS_DST
49341+,
49342+/* SADB_ADD */
49343+1<<SADB_EXT_RESERVED
49344+| 1<<SADB_EXT_SA
49345+| 1<<SADB_EXT_ADDRESS_SRC
49346+| 1<<SADB_EXT_ADDRESS_DST
49347+,
49348+/* SADB_DELETE */
49349+1<<SADB_EXT_RESERVED
49350+| 1<<SADB_EXT_SA
49351+| 1<<SADB_EXT_ADDRESS_SRC
49352+| 1<<SADB_EXT_ADDRESS_DST
49353+,
49354+/* SADB_GET */
49355+1<<SADB_EXT_RESERVED
49356+| 1<<SADB_EXT_SA
49357+| 1<<SADB_EXT_ADDRESS_SRC
49358+| 1<<SADB_EXT_ADDRESS_DST
49359+/* | 1<<SADB_EXT_KEY_AUTH */
49360+/* | 1<<SADB_EXT_KEY_ENCRYPT */
49361+,
49362+/* SADB_ACQUIRE */
49363+1<<SADB_EXT_RESERVED
49364+| 1<<SADB_EXT_ADDRESS_SRC
49365+| 1<<SADB_EXT_ADDRESS_DST
49366+| 1<<SADB_EXT_PROPOSAL
49367+,
49368+/* SADB_REGISTER */
49369+1<<SADB_EXT_RESERVED
49370+/* | 1<<SADB_EXT_SUPPORTED_AUTH
49371+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
49372+,
49373+/* SADB_EXPIRE */
49374+1<<SADB_EXT_RESERVED
49375+| 1<<SADB_EXT_SA
49376+| 1<<SADB_EXT_LIFETIME_CURRENT
49377+/* | 1<<SADB_EXT_LIFETIME_HARD
49378+ | 1<<SADB_EXT_LIFETIME_SOFT */
49379+| 1<<SADB_EXT_ADDRESS_SRC
49380+| 1<<SADB_EXT_ADDRESS_DST
49381+,
49382+/* SADB_FLUSH */
49383+1<<SADB_EXT_RESERVED
49384+,
49385+/* SADB_DUMP */
49386+1<<SADB_EXT_RESERVED
49387+| 1<<SADB_EXT_SA
49388+| 1<<SADB_EXT_ADDRESS_SRC
49389+| 1<<SADB_EXT_ADDRESS_DST
49390+| 1<<SADB_EXT_KEY_AUTH
49391+| 1<<SADB_EXT_KEY_ENCRYPT
49392+,
49393+/* SADB_X_PROMISC */
49394+1<<SADB_EXT_RESERVED
49395+| 1<<SADB_EXT_SA
49396+| 1<<SADB_EXT_LIFETIME_CURRENT
49397+| 1<<SADB_EXT_LIFETIME_HARD
49398+| 1<<SADB_EXT_LIFETIME_SOFT
49399+| 1<<SADB_EXT_ADDRESS_SRC
49400+| 1<<SADB_EXT_ADDRESS_DST
49401+| 1<<SADB_EXT_ADDRESS_PROXY
49402+| 1<<SADB_EXT_KEY_AUTH
49403+| 1<<SADB_EXT_KEY_ENCRYPT
49404+| 1<<SADB_EXT_IDENTITY_SRC
49405+| 1<<SADB_EXT_IDENTITY_DST
49406+| 1<<SADB_EXT_SENSITIVITY
49407+| 1<<SADB_EXT_PROPOSAL
49408+| 1<<SADB_EXT_SUPPORTED_AUTH
49409+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49410+| 1<<SADB_EXT_SPIRANGE
49411+| 1<<SADB_X_EXT_KMPRIVATE
49412+| 1<<SADB_X_EXT_SATYPE2
49413+| 1<<SADB_X_EXT_SA2
49414+| 1<<SADB_X_EXT_ADDRESS_DST2
49415+,
49416+/* SADB_X_PCHANGE */
49417+1<<SADB_EXT_RESERVED
49418+| 1<<SADB_EXT_SA
49419+| 1<<SADB_EXT_LIFETIME_CURRENT
49420+| 1<<SADB_EXT_LIFETIME_HARD
49421+| 1<<SADB_EXT_LIFETIME_SOFT
49422+| 1<<SADB_EXT_ADDRESS_SRC
49423+| 1<<SADB_EXT_ADDRESS_DST
49424+| 1<<SADB_EXT_ADDRESS_PROXY
49425+| 1<<SADB_EXT_KEY_AUTH
49426+| 1<<SADB_EXT_KEY_ENCRYPT
49427+| 1<<SADB_EXT_IDENTITY_SRC
49428+| 1<<SADB_EXT_IDENTITY_DST
49429+| 1<<SADB_EXT_SENSITIVITY
49430+| 1<<SADB_EXT_PROPOSAL
49431+| 1<<SADB_EXT_SUPPORTED_AUTH
49432+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49433+| 1<<SADB_EXT_SPIRANGE
49434+| 1<<SADB_X_EXT_KMPRIVATE
49435+| 1<<SADB_X_EXT_SATYPE2
49436+| 1<<SADB_X_EXT_SA2
49437+| 1<<SADB_X_EXT_ADDRESS_DST2
49438+,
49439+/* SADB_X_GRPSA */
49440+1<<SADB_EXT_RESERVED
49441+| 1<<SADB_EXT_SA
49442+| 1<<SADB_EXT_ADDRESS_DST
49443+,
49444+/* SADB_X_ADDFLOW */
49445+1<<SADB_EXT_RESERVED
49446+| 1<<SADB_EXT_SA
49447+| 1<<SADB_EXT_ADDRESS_DST
49448+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49449+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49450+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49451+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49452+,
49453+/* SADB_X_DELFLOW */
49454+1<<SADB_EXT_RESERVED
49455+/*| 1<<SADB_EXT_SA*/
49456+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49457+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49458+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49459+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49460+,
49461+/* SADB_X_DEBUG */
49462+1<<SADB_EXT_RESERVED
49463+| 1<<SADB_X_EXT_DEBUG
49464+,
49465+/* SADB_X_NAT_T_NEW_MAPPING */
49466+1<<SADB_EXT_RESERVED
49467+| 1<<SADB_EXT_SA
49468+| 1<<SADB_EXT_ADDRESS_SRC
49469+| 1<<SADB_EXT_ADDRESS_DST
49470+| 1<<SADB_X_EXT_NAT_T_SPORT
49471+| 1<<SADB_X_EXT_NAT_T_DPORT
49472+}
49473+}
49474+};
49475+
49476+/*
49477+ * $Log: pfkey_v2_ext_bits.c,v $
49478+ * Revision 1.22 2005-05-11 01:45:31 mcr
49479+ * make pfkey.h standalone.
49480+ *
49481+ * Revision 1.21 2004/07/10 07:48:36 mcr
49482+ * Moved from linux/lib/libfreeswan/pfkey_v2_ext_bits.c,v
49483+ *
49484+ * Revision 1.20 2004/03/08 01:59:08 ken
49485+ * freeswan.h -> openswan.h
49486+ *
49487+ * Revision 1.19 2003/12/22 21:38:13 mcr
49488+ * removed extraenous #endif.
49489+ *
49490+ * Revision 1.18 2003/12/22 19:34:41 mcr
49491+ * added 0.6c NAT-T patch.
49492+ *
49493+ * Revision 1.17 2003/12/10 01:20:19 mcr
49494+ * NAT-traversal patches to KLIPS.
49495+ *
49496+ * Revision 1.16 2003/10/31 02:27:12 mcr
49497+ * pulled up port-selector patches and sa_id elimination.
49498+ *
49499+ * Revision 1.15.30.1 2003/09/21 13:59:44 mcr
49500+ * pre-liminary X.509 patch - does not yet pass tests.
49501+ *
49502+ * Revision 1.15 2002/04/24 07:55:32 mcr
49503+ * #include patches and Makefiles for post-reorg compilation.
49504+ *
49505+ * Revision 1.14 2002/04/24 07:36:40 mcr
49506+ * Moved from ./lib/pfkey_v2_ext_bits.c,v
49507+ *
49508+ * Revision 1.13 2002/01/29 22:25:36 rgb
49509+ * Re-add ipsec_kversion.h to keep MALLOC happy.
49510+ *
49511+ * Revision 1.12 2002/01/29 01:59:10 mcr
49512+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
49513+ * updating of IPv6 structures to match latest in6.h version.
49514+ * removed dead code from openswan.h that also duplicated kversions.h
49515+ * code.
49516+ *
49517+ * Revision 1.11 2001/10/18 04:45:24 rgb
49518+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
49519+ * lib/openswan.h version macros moved to lib/kversions.h.
49520+ * Other compiler directive cleanups.
49521+ *
49522+ * Revision 1.10 2001/09/08 21:13:35 rgb
49523+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
49524+ *
49525+ * Revision 1.9 2001/06/14 19:35:16 rgb
49526+ * Update copyright date.
49527+ *
49528+ * Revision 1.8 2001/03/26 23:07:36 rgb
49529+ * Remove requirement for auth and enc key from UPDATE.
49530+ *
49531+ * Revision 1.7 2000/09/12 22:35:37 rgb
49532+ * Restructured to remove unused extensions from CLEARFLOW messages.
49533+ *
49534+ * Revision 1.6 2000/09/09 06:39:01 rgb
49535+ * Added comments for clarity.
49536+ *
49537+ * Revision 1.5 2000/06/02 22:54:14 rgb
49538+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
49539+ *
49540+ * Revision 1.4 2000/01/21 06:27:56 rgb
49541+ * Added address cases for eroute flows.
49542+ * Added comments for each message type.
49543+ * Added klipsdebug switching capability.
49544+ * Fixed GRPSA bitfields.
49545+ *
49546+ * Revision 1.3 1999/12/01 22:20:27 rgb
49547+ * Remove requirement for a proxy address in an incoming getspi message.
49548+ *
49549+ * Revision 1.2 1999/11/27 11:57:06 rgb
49550+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
49551+ * Add CVS log entry to bottom of file.
49552+ * Cleaned out unused bits.
49553+ *
49554+ */
49555--- /dev/null Tue Mar 11 13:02:56 2003
49556+++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004
49557@@ -0,0 +1,971 @@
49558+/*
49559+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
49560+ * Copyright (C) 1998-2003 Richard Guy Briggs.
49561+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
49562+ *
49563+ * This program is free software; you can redistribute it and/or modify it
49564+ * under the terms of the GNU General Public License as published by the
49565+ * Free Software Foundation; either version 2 of the License, or (at your
49566+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
49567+ *
49568+ * This program is distributed in the hope that it will be useful, but
49569+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
49570+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49571+ * for more details.
49572+ *
49573+ * RCSID $Id: pfkey_v2_ext_process.c,v 1.20.2.4 2007-11-16 03:42:22 paul Exp $
49574+ */
49575+
49576+/*
49577+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
49578+ */
49579+
49580+char pfkey_v2_ext_process_c_version[] = "$Id: pfkey_v2_ext_process.c,v 1.20.2.4 2007-11-16 03:42:22 paul Exp $";
49581+
49582+#ifndef AUTOCONF_INCLUDED
49583+#include <linux/config.h>
49584+#endif
49585+#include <linux/version.h>
49586+#include <linux/kernel.h> /* printk() */
49587+
49588+#include "openswan/ipsec_param.h"
49589+
49590+#ifdef MALLOC_SLAB
49591+# include <linux/slab.h> /* kmalloc() */
49592+#else /* MALLOC_SLAB */
49593+# include <linux/malloc.h> /* kmalloc() */
49594+#endif /* MALLOC_SLAB */
49595+#include <linux/errno.h> /* error codes */
49596+#include <linux/types.h> /* size_t */
49597+#include <linux/interrupt.h> /* mark_bh */
49598+
49599+#include <linux/netdevice.h> /* struct device, and other headers */
49600+#include <linux/etherdevice.h> /* eth_type_trans */
49601+#include <linux/ip.h> /* struct iphdr */
49602+#include <linux/skbuff.h>
49603+
49604+#include <openswan.h>
49605+
49606+#include <crypto/des.h>
49607+
49608+#ifdef SPINLOCK
49609+# ifdef SPINLOCK_23
49610+# include <linux/spinlock.h> /* *lock* */
49611+# else /* SPINLOCK_23 */
49612+# include <asm/spinlock.h> /* *lock* */
49613+# endif /* SPINLOCK_23 */
49614+#endif /* SPINLOCK */
49615+#ifdef NET_21
49616+# include <linux/in6.h>
49617+# define ip_chk_addr inet_addr_type
49618+# define IS_MYADDR RTN_LOCAL
49619+#endif
49620+
49621+#include <net/ip.h>
49622+#ifdef NETLINK_SOCK
49623+# include <linux/netlink.h>
49624+#else
49625+# include <net/netlink.h>
49626+#endif
49627+
49628+#include <linux/random.h> /* get_random_bytes() */
49629+
49630+#include "openswan/radij.h"
49631+#include "openswan/ipsec_encap.h"
49632+#include "openswan/ipsec_sa.h"
49633+
49634+#include "openswan/ipsec_radij.h"
49635+#include "openswan/ipsec_xform.h"
49636+#include "openswan/ipsec_ah.h"
49637+#include "openswan/ipsec_esp.h"
49638+#include "openswan/ipsec_tunnel.h"
49639+#include "openswan/ipsec_rcv.h"
49640+#include "openswan/ipcomp.h"
49641+
49642+#include <pfkeyv2.h>
49643+#include <pfkey.h>
49644+
49645+#include "openswan/ipsec_proto.h"
49646+#include "openswan/ipsec_alg.h"
49647+
49648+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
49649+
49650+int
49651+pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49652+{
49653+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
49654+ int error = 0;
49655+ struct ipsec_sa* ipsp;
49656+
49657+ KLIPS_PRINT(debug_pfkey,
49658+ "klips_debug:pfkey_sa_process: .\n");
49659+
49660+ if(!extr || !extr->ips) {
49661+ KLIPS_PRINT(debug_pfkey,
49662+ "klips_debug:pfkey_sa_process: "
49663+ "extr or extr->ips is NULL, fatal\n");
49664+ SENDERR(EINVAL);
49665+ }
49666+
49667+ switch(pfkey_ext->sadb_ext_type) {
49668+ case SADB_EXT_SA:
49669+ ipsp = extr->ips;
49670+ break;
49671+ case SADB_X_EXT_SA2:
49672+ if(extr->ips2 == NULL) {
49673+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49674+ }
49675+ if(extr->ips2 == NULL) {
49676+ SENDERR(-error);
49677+ }
49678+ ipsp = extr->ips2;
49679+ break;
49680+ default:
49681+ KLIPS_PRINT(debug_pfkey,
49682+ "klips_debug:pfkey_sa_process: "
49683+ "invalid exttype=%d.\n",
49684+ pfkey_ext->sadb_ext_type);
49685+ SENDERR(EINVAL);
49686+ }
49687+
49688+ ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
49689+ ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
49690+ ipsp->ips_state = pfkey_sa->sadb_sa_state;
49691+ ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
49692+ ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
49693+ ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref;
49694+
49695+ switch(ipsp->ips_said.proto) {
49696+ case IPPROTO_AH:
49697+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
49698+ ipsp->ips_encalg = SADB_EALG_NONE;
49699+ break;
49700+ case IPPROTO_ESP:
49701+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
49702+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
49703+#ifdef CONFIG_KLIPS_ALG
49704+ ipsec_alg_sa_init(ipsp);
49705+#endif
49706+ break;
49707+ case IPPROTO_IPIP:
49708+ ipsp->ips_authalg = AH_NONE;
49709+ ipsp->ips_encalg = ESP_NONE;
49710+ break;
49711+#ifdef CONFIG_KLIPS_IPCOMP
49712+ case IPPROTO_COMP:
49713+ ipsp->ips_authalg = AH_NONE;
49714+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
49715+ break;
49716+#endif /* CONFIG_KLIPS_IPCOMP */
49717+ case IPPROTO_INT:
49718+ ipsp->ips_authalg = AH_NONE;
49719+ ipsp->ips_encalg = ESP_NONE;
49720+ break;
49721+ case 0:
49722+ break;
49723+ default:
49724+ KLIPS_PRINT(debug_pfkey,
49725+ "klips_debug:pfkey_sa_process: "
49726+ "unknown proto=%d.\n",
49727+ ipsp->ips_said.proto);
49728+ SENDERR(EINVAL);
49729+ }
49730+
49731+errlab:
49732+ return error;
49733+}
49734+
49735+int
49736+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49737+{
49738+ int error = 0;
49739+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
49740+
49741+ KLIPS_PRINT(debug_pfkey,
49742+ "klips_debug:pfkey_lifetime_process: .\n");
49743+
49744+ if(!extr || !extr->ips) {
49745+ KLIPS_PRINT(debug_pfkey,
49746+ "klips_debug:pfkey_lifetime_process: "
49747+ "extr or extr->ips is NULL, fatal\n");
49748+ SENDERR(EINVAL);
49749+ }
49750+
49751+ switch(pfkey_lifetime->sadb_lifetime_exttype) {
49752+ case SADB_EXT_LIFETIME_CURRENT:
49753+ KLIPS_PRINT(debug_pfkey,
49754+ "klips_debug:pfkey_lifetime_process: "
49755+ "lifetime_current not supported yet.\n");
49756+ SENDERR(EINVAL);
49757+ break;
49758+ case SADB_EXT_LIFETIME_HARD:
49759+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
49760+ pfkey_lifetime->sadb_lifetime_allocations);
49761+
49762+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
49763+ pfkey_lifetime->sadb_lifetime_bytes);
49764+
49765+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
49766+ pfkey_lifetime->sadb_lifetime_addtime);
49767+
49768+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
49769+ pfkey_lifetime->sadb_lifetime_usetime);
49770+
49771+ break;
49772+
49773+ case SADB_EXT_LIFETIME_SOFT:
49774+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
49775+ pfkey_lifetime->sadb_lifetime_allocations);
49776+
49777+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
49778+ pfkey_lifetime->sadb_lifetime_bytes);
49779+
49780+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
49781+ pfkey_lifetime->sadb_lifetime_addtime);
49782+
49783+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
49784+ pfkey_lifetime->sadb_lifetime_usetime);
49785+
49786+ break;
49787+ default:
49788+ KLIPS_PRINT(debug_pfkey,
49789+ "klips_debug:pfkey_lifetime_process: "
49790+ "invalid exttype=%d.\n",
49791+ pfkey_ext->sadb_ext_type);
49792+ SENDERR(EINVAL);
49793+ }
49794+
49795+errlab:
49796+ return error;
49797+}
49798+
49799+int
49800+pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49801+{
49802+ int error = 0;
49803+ int saddr_len = 0;
49804+ char ipaddr_txt[ADDRTOA_BUF];
49805+ unsigned char **sap;
49806+ unsigned short * portp = 0;
49807+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
49808+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
49809+ struct ipsec_sa* ipsp;
49810+
49811+ KLIPS_PRINT(debug_pfkey,
49812+ "klips_debug:pfkey_address_process:\n");
49813+
49814+ if(!extr || !extr->ips) {
49815+ KLIPS_PRINT(debug_pfkey,
49816+ "klips_debug:pfkey_address_process: "
49817+ "extr or extr->ips is NULL, fatal\n");
49818+ SENDERR(EINVAL);
49819+ }
49820+
49821+ switch(s->sa_family) {
49822+ case AF_INET:
49823+ saddr_len = sizeof(struct sockaddr_in);
49824+ if (debug_pfkey)
49825+ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
49826+ KLIPS_PRINT(debug_pfkey,
49827+ "klips_debug:pfkey_address_process: "
49828+ "found address family=%d, AF_INET, %s.\n",
49829+ s->sa_family,
49830+ ipaddr_txt);
49831+ break;
49832+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
49833+ case AF_INET6:
49834+ saddr_len = sizeof(struct sockaddr_in6);
49835+ break;
49836+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
49837+ default:
49838+ KLIPS_PRINT(debug_pfkey,
49839+ "klips_debug:pfkey_address_process: "
49840+ "s->sa_family=%d not supported.\n",
49841+ s->sa_family);
49842+ SENDERR(EPFNOSUPPORT);
49843+ }
49844+
49845+ switch(pfkey_address->sadb_address_exttype) {
49846+ case SADB_EXT_ADDRESS_SRC:
49847+ KLIPS_PRINT(debug_pfkey,
49848+ "klips_debug:pfkey_address_process: "
49849+ "found src address.\n");
49850+ sap = (unsigned char **)&(extr->ips->ips_addr_s);
49851+ extr->ips->ips_addr_s_size = saddr_len;
49852+ break;
49853+ case SADB_EXT_ADDRESS_DST:
49854+ KLIPS_PRINT(debug_pfkey,
49855+ "klips_debug:pfkey_address_process: "
49856+ "found dst address.\n");
49857+ sap = (unsigned char **)&(extr->ips->ips_addr_d);
49858+ extr->ips->ips_addr_d_size = saddr_len;
49859+ break;
49860+ case SADB_EXT_ADDRESS_PROXY:
49861+ KLIPS_PRINT(debug_pfkey,
49862+ "klips_debug:pfkey_address_process: "
49863+ "found proxy address.\n");
49864+ sap = (unsigned char **)&(extr->ips->ips_addr_p);
49865+ extr->ips->ips_addr_p_size = saddr_len;
49866+ break;
49867+ case SADB_X_EXT_ADDRESS_DST2:
49868+ KLIPS_PRINT(debug_pfkey,
49869+ "klips_debug:pfkey_address_process: "
49870+ "found 2nd dst address.\n");
49871+ if(extr->ips2 == NULL) {
49872+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49873+ }
49874+ if(extr->ips2 == NULL) {
49875+ SENDERR(-error);
49876+ }
49877+ sap = (unsigned char **)&(extr->ips2->ips_addr_d);
49878+ extr->ips2->ips_addr_d_size = saddr_len;
49879+ break;
49880+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
49881+ KLIPS_PRINT(debug_pfkey,
49882+ "klips_debug:pfkey_address_process: "
49883+ "found src flow address.\n");
49884+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49885+ SENDERR(ENOMEM);
49886+ }
49887+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
49888+ portp = &(extr->eroute->er_eaddr.sen_sport);
49889+ break;
49890+ case SADB_X_EXT_ADDRESS_DST_FLOW:
49891+ KLIPS_PRINT(debug_pfkey,
49892+ "klips_debug:pfkey_address_process: "
49893+ "found dst flow address.\n");
49894+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49895+ SENDERR(ENOMEM);
49896+ }
49897+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
49898+ portp = &(extr->eroute->er_eaddr.sen_dport);
49899+ break;
49900+ case SADB_X_EXT_ADDRESS_SRC_MASK:
49901+ KLIPS_PRINT(debug_pfkey,
49902+ "klips_debug:pfkey_address_process: "
49903+ "found src mask address.\n");
49904+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49905+ SENDERR(ENOMEM);
49906+ }
49907+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
49908+ portp = &(extr->eroute->er_emask.sen_sport);
49909+ break;
49910+ case SADB_X_EXT_ADDRESS_DST_MASK:
49911+ KLIPS_PRINT(debug_pfkey,
49912+ "klips_debug:pfkey_address_process: "
49913+ "found dst mask address.\n");
49914+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49915+ SENDERR(ENOMEM);
49916+ }
49917+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
49918+ portp = &(extr->eroute->er_emask.sen_dport);
49919+ break;
49920+#ifdef NAT_TRAVERSAL
49921+ case SADB_X_EXT_NAT_T_OA:
49922+ KLIPS_PRINT(debug_pfkey,
49923+ "klips_debug:pfkey_address_process: "
49924+ "found NAT-OA address.\n");
49925+ sap = (unsigned char **)&(extr->ips->ips_natt_oa);
49926+ extr->ips->ips_natt_oa_size = saddr_len;
49927+ break;
49928+#endif
49929+ default:
49930+ KLIPS_PRINT(debug_pfkey,
49931+ "klips_debug:pfkey_address_process: "
49932+ "unrecognised ext_type=%d.\n",
49933+ pfkey_address->sadb_address_exttype);
49934+ SENDERR(EINVAL);
49935+ }
49936+
49937+ switch(pfkey_address->sadb_address_exttype) {
49938+ case SADB_EXT_ADDRESS_SRC:
49939+ case SADB_EXT_ADDRESS_DST:
49940+ case SADB_EXT_ADDRESS_PROXY:
49941+ case SADB_X_EXT_ADDRESS_DST2:
49942+#ifdef NAT_TRAVERSAL
49943+ case SADB_X_EXT_NAT_T_OA:
49944+#endif
49945+ KLIPS_PRINT(debug_pfkey,
49946+ "klips_debug:pfkey_address_process: "
49947+ "allocating %d bytes for saddr.\n",
49948+ saddr_len);
49949+ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
49950+ SENDERR(ENOMEM);
49951+ }
49952+ memcpy(*sap, s, saddr_len);
49953+ break;
49954+ default:
49955+ if(s->sa_family != AF_INET) {
49956+ KLIPS_PRINT(debug_pfkey,
49957+ "klips_debug:pfkey_address_process: "
49958+ "s->sa_family=%d not supported.\n",
49959+ s->sa_family);
49960+ SENDERR(EPFNOSUPPORT);
49961+ }
49962+ {
49963+ *(struct in_addr *)sap = ((struct sockaddr_in *)s)->sin_addr;
49964+ }
49965+
49966+ if (portp != 0)
49967+ *portp = ((struct sockaddr_in*)s)->sin_port;
49968+#ifdef CONFIG_KLIPS_DEBUG
49969+ if(extr->eroute) {
49970+ char buf1[64], buf2[64];
49971+ if (debug_pfkey) {
49972+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
49973+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
49974+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
49975+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
49976+ KLIPS_PRINT(debug_pfkey,
49977+ "klips_debug:pfkey_address_parse: "
49978+ "extr->eroute set to %s:%d->%s:%d\n",
49979+ buf1,
49980+ ntohs(extr->eroute->er_eaddr.sen_sport),
49981+ buf2,
49982+ ntohs(extr->eroute->er_eaddr.sen_dport));
49983+ }
49984+ }
49985+#endif /* CONFIG_KLIPS_DEBUG */
49986+ }
49987+
49988+ ipsp = extr->ips;
49989+ switch(pfkey_address->sadb_address_exttype) {
49990+ case SADB_X_EXT_ADDRESS_DST2:
49991+ ipsp = extr->ips2;
49992+ case SADB_EXT_ADDRESS_DST:
49993+ if(s->sa_family == AF_INET) {
49994+ ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
49995+ ipsp->ips_said.dst.u.v4.sin_family = AF_INET;
49996+ if (debug_pfkey)
49997+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
49998+ 0,
49999+ ipaddr_txt,
50000+ sizeof(ipaddr_txt));
50001+ KLIPS_PRINT(debug_pfkey,
50002+ "klips_debug:pfkey_address_process: "
50003+ "ips_said.dst set to %s.\n",
50004+ ipaddr_txt);
50005+ } else {
50006+ KLIPS_PRINT(debug_pfkey,
50007+ "klips_debug:pfkey_address_process: "
50008+ "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
50009+ s->sa_family);
50010+ }
50011+ default:
50012+ break;
50013+ }
50014+
50015+ /* XXX check if port!=0 */
50016+
50017+ KLIPS_PRINT(debug_pfkey,
50018+ "klips_debug:pfkey_address_process: successful.\n");
50019+ errlab:
50020+ return error;
50021+}
50022+
50023+int
50024+pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50025+{
50026+ int error = 0;
50027+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
50028+
50029+ KLIPS_PRINT(debug_pfkey,
50030+ "klips_debug:pfkey_key_process: .\n");
50031+
50032+ if(!extr || !extr->ips) {
50033+ KLIPS_PRINT(debug_pfkey,
50034+ "klips_debug:pfkey_key_process: "
50035+ "extr or extr->ips is NULL, fatal\n");
50036+ SENDERR(EINVAL);
50037+ }
50038+
50039+ switch(pfkey_key->sadb_key_exttype) {
50040+ case SADB_EXT_KEY_AUTH:
50041+ KLIPS_PRINT(debug_pfkey,
50042+ "klips_debug:pfkey_key_process: "
50043+ "allocating %d bytes for authkey.\n",
50044+ DIVUP(pfkey_key->sadb_key_bits, 8));
50045+ if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
50046+ KLIPS_PRINT(debug_pfkey,
50047+ "klips_debug:pfkey_key_process: "
50048+ "memory allocation error.\n");
50049+ SENDERR(ENOMEM);
50050+ }
50051+ extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
50052+ extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
50053+ memcpy(extr->ips->ips_key_a,
50054+ (char*)pfkey_key + sizeof(struct sadb_key),
50055+ extr->ips->ips_key_a_size);
50056+ break;
50057+ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
50058+ KLIPS_PRINT(debug_pfkey,
50059+ "klips_debug:pfkey_key_process: "
50060+ "allocating %d bytes for enckey.\n",
50061+ DIVUP(pfkey_key->sadb_key_bits, 8));
50062+ if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
50063+ KLIPS_PRINT(debug_pfkey,
50064+ "klips_debug:pfkey_key_process: "
50065+ "memory allocation error.\n");
50066+ SENDERR(ENOMEM);
50067+ }
50068+ extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
50069+ extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
50070+ memcpy(extr->ips->ips_key_e,
50071+ (char*)pfkey_key + sizeof(struct sadb_key),
50072+ extr->ips->ips_key_e_size);
50073+ break;
50074+ default:
50075+ SENDERR(EINVAL);
50076+ }
50077+
50078+ KLIPS_PRINT(debug_pfkey,
50079+ "klips_debug:pfkey_key_process: "
50080+ "success.\n");
50081+errlab:
50082+ return error;
50083+}
50084+
50085+int
50086+pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50087+{
50088+ int error = 0;
50089+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
50090+ int data_len;
50091+
50092+ KLIPS_PRINT(debug_pfkey,
50093+ "klips_debug:pfkey_ident_process: .\n");
50094+
50095+ if(!extr || !extr->ips) {
50096+ KLIPS_PRINT(debug_pfkey,
50097+ "klips_debug:pfkey_ident_process: "
50098+ "extr or extr->ips is NULL, fatal\n");
50099+ SENDERR(EINVAL);
50100+ }
50101+
50102+ switch(pfkey_ident->sadb_ident_exttype) {
50103+ case SADB_EXT_IDENTITY_SRC:
50104+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
50105+
50106+ extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
50107+ extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
50108+ extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
50109+ if(data_len) {
50110+ KLIPS_PRINT(debug_pfkey,
50111+ "klips_debug:pfkey_ident_process: "
50112+ "allocating %d bytes for ident_s.\n",
50113+ data_len);
50114+ if(!(extr->ips->ips_ident_s.data
50115+ = kmalloc(data_len, GFP_KERNEL))) {
50116+ SENDERR(ENOMEM);
50117+ }
50118+ memcpy(extr->ips->ips_ident_s.data,
50119+ (char*)pfkey_ident + sizeof(struct sadb_ident),
50120+ data_len);
50121+ } else {
50122+ extr->ips->ips_ident_s.data = NULL;
50123+ }
50124+ break;
50125+ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
50126+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
50127+
50128+ extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
50129+ extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
50130+ extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
50131+ if(data_len) {
50132+ KLIPS_PRINT(debug_pfkey,
50133+ "klips_debug:pfkey_ident_process: "
50134+ "allocating %d bytes for ident_d.\n",
50135+ data_len);
50136+ if(!(extr->ips->ips_ident_d.data
50137+ = kmalloc(data_len, GFP_KERNEL))) {
50138+ SENDERR(ENOMEM);
50139+ }
50140+ memcpy(extr->ips->ips_ident_d.data,
50141+ (char*)pfkey_ident + sizeof(struct sadb_ident),
50142+ data_len);
50143+ } else {
50144+ extr->ips->ips_ident_d.data = NULL;
50145+ }
50146+ break;
50147+ default:
50148+ SENDERR(EINVAL);
50149+ }
50150+errlab:
50151+ return error;
50152+}
50153+
50154+int
50155+pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50156+{
50157+ int error = 0;
50158+
50159+ KLIPS_PRINT(debug_pfkey,
50160+ "klips_debug:pfkey_sens_process: "
50161+ "Sorry, I can't process exttype=%d yet.\n",
50162+ pfkey_ext->sadb_ext_type);
50163+ SENDERR(EINVAL); /* don't process these yet */
50164+ errlab:
50165+ return error;
50166+}
50167+
50168+int
50169+pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50170+{
50171+ int error = 0;
50172+
50173+ KLIPS_PRINT(debug_pfkey,
50174+ "klips_debug:pfkey_prop_process: "
50175+ "Sorry, I can't process exttype=%d yet.\n",
50176+ pfkey_ext->sadb_ext_type);
50177+ SENDERR(EINVAL); /* don't process these yet */
50178+
50179+ errlab:
50180+ return error;
50181+}
50182+
50183+int
50184+pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50185+{
50186+ int error = 0;
50187+
50188+ KLIPS_PRINT(debug_pfkey,
50189+ "klips_debug:pfkey_supported_process: "
50190+ "Sorry, I can't process exttype=%d yet.\n",
50191+ pfkey_ext->sadb_ext_type);
50192+ SENDERR(EINVAL); /* don't process these yet */
50193+
50194+errlab:
50195+ return error;
50196+}
50197+
50198+int
50199+pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50200+{
50201+ int error = 0;
50202+
50203+ KLIPS_PRINT(debug_pfkey,
50204+ "klips_debug:pfkey_spirange_process: .\n");
50205+/* errlab: */
50206+ return error;
50207+}
50208+
50209+int
50210+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50211+{
50212+ int error = 0;
50213+
50214+ KLIPS_PRINT(debug_pfkey,
50215+ "klips_debug:pfkey_x_kmprivate_process: "
50216+ "Sorry, I can't process exttype=%d yet.\n",
50217+ pfkey_ext->sadb_ext_type);
50218+ SENDERR(EINVAL); /* don't process these yet */
50219+
50220+errlab:
50221+ return error;
50222+}
50223+
50224+int
50225+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50226+{
50227+ int error = 0;
50228+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
50229+
50230+ KLIPS_PRINT(debug_pfkey,
50231+ "klips_debug:pfkey_x_satype_process: .\n");
50232+
50233+ if(!extr || !extr->ips) {
50234+ KLIPS_PRINT(debug_pfkey,
50235+ "klips_debug:pfkey_x_satype_process: "
50236+ "extr or extr->ips is NULL, fatal\n");
50237+ SENDERR(EINVAL);
50238+ }
50239+
50240+ if(extr->ips2 == NULL) {
50241+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
50242+ }
50243+ if(extr->ips2 == NULL) {
50244+ SENDERR(-error);
50245+ }
50246+ if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
50247+ KLIPS_PRINT(debug_pfkey,
50248+ "klips_debug:pfkey_x_satype_process: "
50249+ "proto lookup from satype=%d failed.\n",
50250+ pfkey_x_satype->sadb_x_satype_satype);
50251+ SENDERR(EINVAL);
50252+ }
50253+ KLIPS_PRINT(debug_pfkey,
50254+ "klips_debug:pfkey_x_satype_process: "
50255+ "protocol==%d decoded from satype==%d(%s).\n",
50256+ extr->ips2->ips_said.proto,
50257+ pfkey_x_satype->sadb_x_satype_satype,
50258+ satype2name(pfkey_x_satype->sadb_x_satype_satype));
50259+
50260+errlab:
50261+ return error;
50262+}
50263+
50264+
50265+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
50266+int
50267+pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50268+{
50269+ int error = 0;
50270+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
50271+
50272+ if(!pfkey_x_nat_t_type) {
50273+ printk("klips_debug:pfkey_x_nat_t_type_process: "
50274+ "null pointer passed in\n");
50275+ SENDERR(EINVAL);
50276+ }
50277+
50278+ KLIPS_PRINT(debug_pfkey,
50279+ "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
50280+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
50281+
50282+ if(!extr || !extr->ips) {
50283+ KLIPS_PRINT(debug_pfkey,
50284+ "klips_debug:pfkey_nat_t_type_process: "
50285+ "extr or extr->ips is NULL, fatal\n");
50286+ SENDERR(EINVAL);
50287+ }
50288+
50289+ switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
50290+ case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */
50291+ case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
50292+
50293+ extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
50294+ break;
50295+ default:
50296+ KLIPS_PRINT(debug_pfkey,
50297+ "klips_debug:pfkey_x_nat_t_type_process: "
50298+ "unknown type %d.\n",
50299+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
50300+ SENDERR(EINVAL);
50301+ break;
50302+ }
50303+
50304+errlab:
50305+ return error;
50306+}
50307+
50308+int
50309+pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50310+{
50311+ int error = 0;
50312+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
50313+
50314+ if(!pfkey_x_nat_t_port) {
50315+ printk("klips_debug:pfkey_x_nat_t_port_process: "
50316+ "null pointer passed in\n");
50317+ SENDERR(EINVAL);
50318+ }
50319+
50320+ KLIPS_PRINT(debug_pfkey,
50321+ "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
50322+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
50323+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
50324+
50325+ if(!extr || !extr->ips) {
50326+ KLIPS_PRINT(debug_pfkey,
50327+ "klips_debug:pfkey_nat_t_type_process: "
50328+ "extr or extr->ips is NULL, fatal\n");
50329+ SENDERR(EINVAL);
50330+ }
50331+
50332+ switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
50333+ case SADB_X_EXT_NAT_T_SPORT:
50334+ extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
50335+ break;
50336+ case SADB_X_EXT_NAT_T_DPORT:
50337+ extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
50338+ break;
50339+ default:
50340+ KLIPS_PRINT(debug_pfkey,
50341+ "klips_debug:pfkey_x_nat_t_port_process: "
50342+ "unknown exttype %d.\n",
50343+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
50344+ SENDERR(EINVAL);
50345+ break;
50346+ }
50347+
50348+errlab:
50349+ return error;
50350+}
50351+#endif
50352+
50353+int
50354+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50355+{
50356+ int error = 0;
50357+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
50358+
50359+ if(!pfkey_x_debug) {
50360+ printk("klips_debug:pfkey_x_debug_process: "
50361+ "null pointer passed in\n");
50362+ SENDERR(EINVAL);
50363+ }
50364+
50365+ KLIPS_PRINT(debug_pfkey,
50366+ "klips_debug:pfkey_x_debug_process: .\n");
50367+
50368+#ifdef CONFIG_KLIPS_DEBUG
50369+ if(pfkey_x_debug->sadb_x_debug_netlink >>
50370+ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
50371+ pfkey_x_debug->sadb_x_debug_netlink &=
50372+ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
50373+ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
50374+ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
50375+ debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
50376+ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
50377+ debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
50378+ debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
50379+ debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
50380+ debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
50381+ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
50382+ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
50383+#ifdef CONFIG_KLIPS_IPCOMP
50384+ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
50385+#endif /* CONFIG_KLIPS_IPCOMP */
50386+ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
50387+ KLIPS_PRINT(debug_pfkey,
50388+ "klips_debug:pfkey_x_debug_process: "
50389+ "set\n");
50390+ } else {
50391+ KLIPS_PRINT(debug_pfkey,
50392+ "klips_debug:pfkey_x_debug_process: "
50393+ "unset\n");
50394+ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
50395+ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
50396+ debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
50397+ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
50398+ debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
50399+ debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
50400+ debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
50401+ debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
50402+ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
50403+ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
50404+#ifdef CONFIG_KLIPS_IPCOMP
50405+ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
50406+#endif /* CONFIG_KLIPS_IPCOMP */
50407+ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
50408+ }
50409+#else /* CONFIG_KLIPS_DEBUG */
50410+ printk("klips_debug:pfkey_x_debug_process: "
50411+ "debugging not enabled\n");
50412+ SENDERR(EINVAL);
50413+#endif /* CONFIG_KLIPS_DEBUG */
50414+
50415+errlab:
50416+ return error;
50417+}
50418+
50419+/*
50420+ * $Log: pfkey_v2_ext_process.c,v $
50421+ * Revision 1.20.2.4 2007-11-16 03:42:22 paul
50422+ * Fix for 64bit big endian machines where a cast for struct in_addr was
50423+ * wrong. This resulted in KLIPS dropping all NAT-T packets with the
50424+ * error:
50425+ *
50426+ * klips_debug:ipsec_xmit_SAlookup: checking for local udp/500 IKE packet
50427+ * saddr=a010c92, er=0p0000000000000000, daddr=a010f17, er_dst=0, proto=1
50428+ * sport=0 dport=0
50429+ * klips_debug:ipsec_xmit_encap_bundle: shunt SA of DROP or no eroute:
50430+ * dropping.
50431+ *
50432+ * Patch by [dhr]
50433+ *
50434+ * Revision 1.20.2.3 2007/09/05 02:56:10 paul
50435+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
50436+ * Fixes based on David McCullough patch.
50437+ *
50438+ * Revision 1.20.2.2 2006/10/06 21:39:26 paul
50439+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
50440+ * set. This is defined through autoconf.h which is included through the
50441+ * linux kernel build macros.
50442+ *
50443+ * Revision 1.20.2.1 2006/04/20 16:33:07 mcr
50444+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
50445+ * Fix in-kernel module compilation. Sub-makefiles do not work.
50446+ *
50447+ * Revision 1.20 2005/04/29 05:10:22 mcr
50448+ * removed from extraenous includes to make unit testing easier.
50449+ *
50450+ * Revision 1.19 2004/12/04 07:14:18 mcr
50451+ * resolution to gcc3-ism was wrong. fixed to assign correct
50452+ * variable.
50453+ *
50454+ * Revision 1.18 2004/12/03 21:25:57 mcr
50455+ * compile time fixes for running on 2.6.
50456+ * still experimental.
50457+ *
50458+ * Revision 1.17 2004/08/21 00:45:04 mcr
50459+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
50460+ *
50461+ * Revision 1.16 2004/07/10 19:11:18 mcr
50462+ * CONFIG_IPSEC -> CONFIG_KLIPS.
50463+ *
50464+ * Revision 1.15 2004/04/06 02:49:26 mcr
50465+ * pullup of algo code from alg-branch.
50466+ *
50467+ * Revision 1.14 2004/02/03 03:13:59 mcr
50468+ * no longer #ifdef out NON_ESP mode. That was a mistake.
50469+ *
50470+ * Revision 1.13 2003/12/15 18:13:12 mcr
50471+ * when compiling with NAT traversal, don't assume that the
50472+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
50473+ * is set.
50474+ *
50475+ * Revision 1.12.2.1 2003/12/22 15:25:52 jjo
50476+ * Merged algo-0.8.1-rc11-test1 into alg-branch
50477+ *
50478+ * Revision 1.12 2003/12/10 01:14:27 mcr
50479+ * NAT-traversal patches to KLIPS.
50480+ *
50481+ * Revision 1.11 2003/10/31 02:27:55 mcr
50482+ * pulled up port-selector patches and sa_id elimination.
50483+ *
50484+ * Revision 1.10.4.2 2003/10/29 01:30:41 mcr
50485+ * elimited "struct sa_id".
50486+ *
50487+ * Revision 1.10.4.1 2003/09/21 13:59:56 mcr
50488+ * pre-liminary X.509 patch - does not yet pass tests.
50489+ *
50490+ * Revision 1.10 2003/02/06 01:51:41 rgb
50491+ * Removed no longer relevant comment
50492+ *
50493+ * Revision 1.9 2003/01/30 02:32:44 rgb
50494+ *
50495+ * Transmit error code through to caller from callee for better diagnosis of problems.
50496+ *
50497+ * Revision 1.8 2002/12/13 22:42:22 mcr
50498+ * restored sa_ref code
50499+ *
50500+ * Revision 1.7 2002/12/13 22:40:48 mcr
50501+ * temporarily removed sadb_x_sa_ref reference for 2.xx
50502+ *
50503+ * Revision 1.6 2002/10/05 05:02:58 dhr
50504+ *
50505+ * C labels go on statements
50506+ *
50507+ * Revision 1.5 2002/09/20 15:41:08 rgb
50508+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
50509+ * Added sadb_x_sa_ref to struct sadb_sa.
50510+ *
50511+ * Revision 1.4 2002/09/20 05:02:02 rgb
50512+ * Added memory allocation debugging.
50513+ *
50514+ * Revision 1.3 2002/07/24 18:44:54 rgb
50515+ * Type fiddling to tame ia64 compiler.
50516+ *
50517+ * Revision 1.2 2002/05/27 18:55:03 rgb
50518+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
50519+ *
50520+ * Revision 1.1 2002/05/14 02:33:51 rgb
50521+ * Moved all the extension processing functions to pfkey_v2_ext_process.c.
50522+ *
50523+ *
50524+ * Local variables:
50525+ * c-file-style: "linux"
50526+ * End:
50527+ *
50528+ */
50529--- /dev/null Tue Mar 11 13:02:56 2003
50530+++ linux/net/ipsec/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004
50531@@ -0,0 +1,1846 @@
50532+/*
50533+ * RFC2367 PF_KEYv2 Key management API message parser
50534+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
50535+ *
50536+ * This program is free software; you can redistribute it and/or modify it
50537+ * under the terms of the GNU General Public License as published by the
50538+ * Free Software Foundation; either version 2 of the License, or (at your
50539+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
50540+ *
50541+ * This program is distributed in the hope that it will be useful, but
50542+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
50543+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50544+ * for more details.
50545+ *
50546+ * RCSID $Id: pfkey_v2_parse.c,v 1.65 2005-04-06 17:46:05 mcr Exp $
50547+ */
50548+
50549+/*
50550+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
50551+ */
50552+
50553+char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.65 2005-04-06 17:46:05 mcr Exp $";
50554+
50555+/*
50556+ * Some ugly stuff to allow consistent debugging code for use in the
50557+ * kernel and in user space
50558+*/
50559+
50560+#ifdef __KERNEL__
50561+
50562+# include <linux/kernel.h> /* for printk */
50563+
50564+#include "openswan/ipsec_kversion.h" /* for malloc switch */
50565+
50566+# ifdef MALLOC_SLAB
50567+# include <linux/slab.h> /* kmalloc() */
50568+# else /* MALLOC_SLAB */
50569+# include <linux/malloc.h> /* kmalloc() */
50570+# endif /* MALLOC_SLAB */
50571+# include <linux/errno.h> /* error codes */
50572+# include <linux/types.h> /* size_t */
50573+# include <linux/interrupt.h> /* mark_bh */
50574+
50575+# include <linux/netdevice.h> /* struct device, and other headers */
50576+# include <linux/etherdevice.h> /* eth_type_trans */
50577+# include <linux/ip.h> /* struct iphdr */
50578+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
50579+# include <linux/ipv6.h> /* struct ipv6hdr */
50580+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
50581+extern int debug_pfkey;
50582+
50583+# include <openswan.h>
50584+
50585+#include "openswan/ipsec_encap.h"
50586+
50587+#else /* __KERNEL__ */
50588+
50589+# include <sys/types.h>
50590+# include <linux/types.h>
50591+# include <linux/errno.h>
50592+
50593+# include <openswan.h>
50594+# include "constants.h"
50595+# include "programs/pluto/defs.h" /* for PRINTF_LIKE */
50596+
50597+#endif /* __KERNEL__ */
50598+
50599+
50600+#include <pfkeyv2.h>
50601+#include <pfkey.h>
50602+
50603+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
50604+
50605+/*
50606+ * how to handle debugging for pfkey.
50607+ */
50608+#include <openswan/pfkey_debug.h>
50609+
50610+unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;
50611+void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
50612+void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
50613+
50614+
50615+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
50616+
50617+struct satype_tbl {
50618+ uint8_t proto;
50619+ uint8_t satype;
50620+ char* name;
50621+} static satype_tbl[] = {
50622+#ifdef __KERNEL__
50623+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
50624+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
50625+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
50626+#ifdef CONFIG_KLIPS_IPCOMP
50627+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
50628+#endif /* CONFIG_KLIPS_IPCOMP */
50629+ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
50630+#else /* __KERNEL__ */
50631+ { SA_ESP, SADB_SATYPE_ESP, "ESP" },
50632+ { SA_AH, SADB_SATYPE_AH, "AH" },
50633+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
50634+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
50635+ { SA_INT, SADB_X_SATYPE_INT, "INT" },
50636+#endif /* __KERNEL__ */
50637+ { 0, 0, "UNKNOWN" }
50638+};
50639+
50640+uint8_t
50641+satype2proto(uint8_t satype)
50642+{
50643+ int i =0;
50644+
50645+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
50646+ i++;
50647+ }
50648+ return satype_tbl[i].proto;
50649+}
50650+
50651+uint8_t
50652+proto2satype(uint8_t proto)
50653+{
50654+ int i = 0;
50655+
50656+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
50657+ i++;
50658+ }
50659+ return satype_tbl[i].satype;
50660+}
50661+
50662+char*
50663+satype2name(uint8_t satype)
50664+{
50665+ int i = 0;
50666+
50667+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
50668+ i++;
50669+ }
50670+ return satype_tbl[i].name;
50671+}
50672+
50673+char*
50674+proto2name(uint8_t proto)
50675+{
50676+ int i = 0;
50677+
50678+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
50679+ i++;
50680+ }
50681+ return satype_tbl[i].name;
50682+}
50683+
50684+/* Default extension parsers taken from the KLIPS code */
50685+
50686+DEBUG_NO_STATIC int
50687+pfkey_sa_parse(struct sadb_ext *pfkey_ext)
50688+{
50689+ int error = 0;
50690+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
50691+#if 0
50692+ struct sadb_sa sav2;
50693+#endif
50694+
50695+ /* sanity checks... */
50696+ if(!pfkey_sa) {
50697+ ERROR("pfkey_sa_parse: "
50698+ "NULL pointer passed in.\n");
50699+ SENDERR(EINVAL);
50700+ }
50701+
50702+#if 0
50703+ /* check if this structure is short, and if so, fix it up.
50704+ * XXX this is NOT the way to do things.
50705+ */
50706+ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
50707+
50708+ /* yes, so clear out a temporary structure, and copy first */
50709+ memset(&sav2, 0, sizeof(sav2));
50710+ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
50711+ sav2.sadb_x_sa_ref=-1;
50712+ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
50713+
50714+ pfkey_sa = &sav2;
50715+ }
50716+#endif
50717+
50718+
50719+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
50720+ ERROR(
50721+ "pfkey_sa_parse: "
50722+ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
50723+ pfkey_sa->sadb_sa_len,
50724+ (int)sizeof(struct sadb_sa));
50725+ SENDERR(EINVAL);
50726+ }
50727+
50728+#if SADB_EALG_MAX < 255
50729+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
50730+ ERROR(
50731+ "pfkey_sa_parse: "
50732+ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
50733+ pfkey_sa->sadb_sa_encrypt,
50734+ SADB_EALG_MAX);
50735+ SENDERR(EINVAL);
50736+ }
50737+#endif
50738+
50739+#if SADB_AALG_MAX < 255
50740+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
50741+ ERROR(
50742+ "pfkey_sa_parse: "
50743+ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
50744+ pfkey_sa->sadb_sa_auth,
50745+ SADB_AALG_MAX);
50746+ SENDERR(EINVAL);
50747+ }
50748+#endif
50749+
50750+#if SADB_SASTATE_MAX < 255
50751+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
50752+ ERROR(
50753+ "pfkey_sa_parse: "
50754+ "state=%d exceeds MAX=%d.\n",
50755+ pfkey_sa->sadb_sa_state,
50756+ SADB_SASTATE_MAX);
50757+ SENDERR(EINVAL);
50758+ }
50759+#endif
50760+
50761+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
50762+ ERROR(
50763+ "pfkey_sa_parse: "
50764+ "state=%d is DEAD=%d.\n",
50765+ pfkey_sa->sadb_sa_state,
50766+ SADB_SASTATE_DEAD);
50767+ SENDERR(EINVAL);
50768+ }
50769+
50770+ if(pfkey_sa->sadb_sa_replay > 64) {
50771+ ERROR(
50772+ "pfkey_sa_parse: "
50773+ "replay window size: %d -- must be 0 <= size <= 64\n",
50774+ pfkey_sa->sadb_sa_replay);
50775+ SENDERR(EINVAL);
50776+ }
50777+
50778+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
50779+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
50780+ {
50781+ ERROR(
50782+ "pfkey_sa_parse: "
50783+ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
50784+ pfkey_sa->sadb_sa_exttype,
50785+ SADB_EXT_SA,
50786+ SADB_X_EXT_SA2);
50787+ SENDERR(EINVAL);
50788+ }
50789+
50790+ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
50791+ ERROR(
50792+ "pfkey_sa_parse: "
50793+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
50794+ pfkey_sa->sadb_x_sa_ref,
50795+ IPSEC_SAREF_NULL,
50796+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
50797+ SENDERR(EINVAL);
50798+ }
50799+
50800+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50801+ "pfkey_sa_parse: "
50802+ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
50803+ pfkey_sa->sadb_sa_len,
50804+ pfkey_sa->sadb_sa_exttype,
50805+ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
50806+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
50807+ pfkey_sa->sadb_sa_replay,
50808+ pfkey_sa->sadb_sa_state,
50809+ pfkey_sa->sadb_sa_auth,
50810+ pfkey_sa->sadb_sa_encrypt,
50811+ pfkey_sa->sadb_sa_flags,
50812+ pfkey_sa->sadb_x_sa_ref);
50813+
50814+ errlab:
50815+ return error;
50816+}
50817+
50818+DEBUG_NO_STATIC int
50819+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
50820+{
50821+ int error = 0;
50822+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
50823+
50824+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50825+ "pfkey_lifetime_parse:enter\n");
50826+ /* sanity checks... */
50827+ if(!pfkey_lifetime) {
50828+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50829+ "pfkey_lifetime_parse: "
50830+ "NULL pointer passed in.\n");
50831+ SENDERR(EINVAL);
50832+ }
50833+
50834+ if(pfkey_lifetime->sadb_lifetime_len !=
50835+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
50836+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50837+ "pfkey_lifetime_parse: "
50838+ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
50839+ pfkey_lifetime->sadb_lifetime_len,
50840+ (int)sizeof(struct sadb_lifetime));
50841+ SENDERR(EINVAL);
50842+ }
50843+
50844+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
50845+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
50846+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
50847+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50848+ "pfkey_lifetime_parse: "
50849+ "unexpected ext_type=%d.\n",
50850+ pfkey_lifetime->sadb_lifetime_exttype);
50851+ SENDERR(EINVAL);
50852+ }
50853+
50854+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50855+ "pfkey_lifetime_parse: "
50856+ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n",
50857+ pfkey_lifetime->sadb_lifetime_exttype,
50858+ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
50859+ pfkey_lifetime->sadb_lifetime_allocations,
50860+ (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
50861+ (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
50862+ (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
50863+ pfkey_lifetime->sadb_x_lifetime_packets);
50864+errlab:
50865+ return error;
50866+}
50867+
50868+DEBUG_NO_STATIC int
50869+pfkey_address_parse(struct sadb_ext *pfkey_ext)
50870+{
50871+ int error = 0;
50872+ int saddr_len = 0;
50873+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
50874+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
50875+ char ipaddr_txt[ADDRTOT_BUF];
50876+
50877+ /* sanity checks... */
50878+ if(!pfkey_address) {
50879+ ERROR(
50880+ "pfkey_address_parse: "
50881+ "NULL pointer passed in.\n");
50882+ SENDERR(EINVAL);
50883+ }
50884+
50885+ if(pfkey_address->sadb_address_len <
50886+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
50887+ IPSEC_PFKEYv2_ALIGN) {
50888+ ERROR("pfkey_address_parse: "
50889+ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
50890+ pfkey_address->sadb_address_len,
50891+ (int)sizeof(struct sadb_address),
50892+ (int)sizeof(struct sockaddr));
50893+ SENDERR(EINVAL);
50894+ }
50895+
50896+ if(pfkey_address->sadb_address_reserved) {
50897+ ERROR("pfkey_address_parse: "
50898+ "res=%d, must be zero.\n",
50899+ pfkey_address->sadb_address_reserved);
50900+ SENDERR(EINVAL);
50901+ }
50902+
50903+ switch(pfkey_address->sadb_address_exttype) {
50904+ case SADB_EXT_ADDRESS_SRC:
50905+ case SADB_EXT_ADDRESS_DST:
50906+ case SADB_EXT_ADDRESS_PROXY:
50907+ case SADB_X_EXT_ADDRESS_DST2:
50908+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
50909+ case SADB_X_EXT_ADDRESS_DST_FLOW:
50910+ case SADB_X_EXT_ADDRESS_SRC_MASK:
50911+ case SADB_X_EXT_ADDRESS_DST_MASK:
50912+#ifdef NAT_TRAVERSAL
50913+ case SADB_X_EXT_NAT_T_OA:
50914+#endif
50915+ break;
50916+ default:
50917+ ERROR(
50918+ "pfkey_address_parse: "
50919+ "unexpected ext_type=%d.\n",
50920+ pfkey_address->sadb_address_exttype);
50921+ SENDERR(ENOPKG);
50922+ }
50923+
50924+ switch(s->sa_family) {
50925+ case AF_INET:
50926+ saddr_len = sizeof(struct sockaddr_in);
50927+ sprintf(ipaddr_txt, "%d.%d.%d.%d"
50928+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
50929+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
50930+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
50931+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
50932+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50933+ "pfkey_address_parse: "
50934+ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
50935+ pfkey_address->sadb_address_exttype,
50936+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
50937+ s->sa_family,
50938+ ipaddr_txt,
50939+ pfkey_address->sadb_address_proto,
50940+ ntohs(((struct sockaddr_in*)s)->sin_port));
50941+ break;
50942+ case AF_INET6:
50943+ saddr_len = sizeof(struct sockaddr_in6);
50944+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
50945+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
50946+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
50947+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
50948+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
50949+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
50950+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
50951+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
50952+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
50953+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50954+ "pfkey_address_parse: "
50955+ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
50956+ pfkey_address->sadb_address_exttype,
50957+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
50958+ s->sa_family,
50959+ ipaddr_txt,
50960+ pfkey_address->sadb_address_proto,
50961+ ((struct sockaddr_in6*)s)->sin6_port);
50962+ break;
50963+ default:
50964+ ERROR(
50965+ "pfkey_address_parse: "
50966+ "s->sa_family=%d not supported.\n",
50967+ s->sa_family);
50968+ SENDERR(EPFNOSUPPORT);
50969+ }
50970+
50971+ if(pfkey_address->sadb_address_len !=
50972+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
50973+ ERROR(
50974+ "pfkey_address_parse: "
50975+ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
50976+ pfkey_address->sadb_address_len,
50977+ (int)sizeof(struct sadb_address),
50978+ saddr_len);
50979+ SENDERR(EINVAL);
50980+ }
50981+
50982+ if(pfkey_address->sadb_address_prefixlen != 0) {
50983+ ERROR(
50984+ "pfkey_address_parse: "
50985+ "address prefixes not supported yet.\n");
50986+ SENDERR(EAFNOSUPPORT); /* not supported yet */
50987+ }
50988+
50989+ /* XXX check if port!=0 */
50990+
50991+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50992+ "pfkey_address_parse: successful.\n");
50993+ errlab:
50994+ return error;
50995+}
50996+
50997+DEBUG_NO_STATIC int
50998+pfkey_key_parse(struct sadb_ext *pfkey_ext)
50999+{
51000+ int error = 0;
51001+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
51002+
51003+ /* sanity checks... */
51004+
51005+ if(!pfkey_key) {
51006+ ERROR(
51007+ "pfkey_key_parse: "
51008+ "NULL pointer passed in.\n");
51009+ SENDERR(EINVAL);
51010+ }
51011+
51012+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
51013+ ERROR(
51014+ "pfkey_key_parse: "
51015+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51016+ pfkey_key->sadb_key_len,
51017+ (int)sizeof(struct sadb_key));
51018+ SENDERR(EINVAL);
51019+ }
51020+
51021+ if(!pfkey_key->sadb_key_bits) {
51022+ ERROR(
51023+ "pfkey_key_parse: "
51024+ "key length set to zero, must be non-zero.\n");
51025+ SENDERR(EINVAL);
51026+ }
51027+
51028+ if(pfkey_key->sadb_key_len !=
51029+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
51030+ PFKEYBITS)) {
51031+ ERROR(
51032+ "pfkey_key_parse: "
51033+ "key length=%d does not agree with extension length=%d.\n",
51034+ pfkey_key->sadb_key_bits,
51035+ pfkey_key->sadb_key_len);
51036+ SENDERR(EINVAL);
51037+ }
51038+
51039+ if(pfkey_key->sadb_key_reserved) {
51040+ ERROR(
51041+ "pfkey_key_parse: "
51042+ "res=%d, must be zero.\n",
51043+ pfkey_key->sadb_key_reserved);
51044+ SENDERR(EINVAL);
51045+ }
51046+
51047+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
51048+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
51049+ ERROR(
51050+ "pfkey_key_parse: "
51051+ "expecting extension type AUTH or ENCRYPT, got %d.\n",
51052+ pfkey_key->sadb_key_exttype);
51053+ SENDERR(EINVAL);
51054+ }
51055+
51056+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51057+ "pfkey_key_parse: "
51058+ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
51059+ pfkey_key->sadb_key_len,
51060+ pfkey_key->sadb_key_exttype,
51061+ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
51062+ pfkey_key->sadb_key_bits,
51063+ pfkey_key->sadb_key_reserved);
51064+
51065+errlab:
51066+ return error;
51067+}
51068+
51069+DEBUG_NO_STATIC int
51070+pfkey_ident_parse(struct sadb_ext *pfkey_ext)
51071+{
51072+ int error = 0;
51073+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
51074+
51075+ /* sanity checks... */
51076+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
51077+ ERROR(
51078+ "pfkey_ident_parse: "
51079+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51080+ pfkey_ident->sadb_ident_len,
51081+ (int)sizeof(struct sadb_ident));
51082+ SENDERR(EINVAL);
51083+ }
51084+
51085+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
51086+ ERROR(
51087+ "pfkey_ident_parse: "
51088+ "ident_type=%d out of range, must be less than %d.\n",
51089+ pfkey_ident->sadb_ident_type,
51090+ SADB_IDENTTYPE_MAX);
51091+ SENDERR(EINVAL);
51092+ }
51093+
51094+ if(pfkey_ident->sadb_ident_reserved) {
51095+ ERROR(
51096+ "pfkey_ident_parse: "
51097+ "res=%d, must be zero.\n",
51098+ pfkey_ident->sadb_ident_reserved);
51099+ SENDERR(EINVAL);
51100+ }
51101+
51102+ /* string terminator/padding must be zero */
51103+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
51104+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
51105+ ERROR(
51106+ "pfkey_ident_parse: "
51107+ "string padding must be zero, last is 0x%02x.\n",
51108+ *((char*)pfkey_ident +
51109+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
51110+ SENDERR(EINVAL);
51111+ }
51112+ }
51113+
51114+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
51115+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
51116+ ERROR(
51117+ "pfkey_key_parse: "
51118+ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
51119+ pfkey_ident->sadb_ident_exttype);
51120+ SENDERR(EINVAL);
51121+ }
51122+
51123+errlab:
51124+ return error;
51125+}
51126+
51127+DEBUG_NO_STATIC int
51128+pfkey_sens_parse(struct sadb_ext *pfkey_ext)
51129+{
51130+ int error = 0;
51131+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
51132+
51133+ /* sanity checks... */
51134+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
51135+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51136+ "pfkey_sens_parse: "
51137+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51138+ pfkey_sens->sadb_sens_len,
51139+ (int)sizeof(struct sadb_sens));
51140+ SENDERR(EINVAL);
51141+ }
51142+
51143+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51144+ "pfkey_sens_parse: "
51145+ "Sorry, I can't parse exttype=%d yet.\n",
51146+ pfkey_ext->sadb_ext_type);
51147+#if 0
51148+ SENDERR(EINVAL); /* don't process these yet */
51149+#endif
51150+
51151+errlab:
51152+ return error;
51153+}
51154+
51155+DEBUG_NO_STATIC int
51156+pfkey_prop_parse(struct sadb_ext *pfkey_ext)
51157+{
51158+ int error = 0;
51159+ int i, num_comb;
51160+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
51161+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
51162+
51163+ /* sanity checks... */
51164+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
51165+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
51166+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51167+ "pfkey_prop_parse: "
51168+ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
51169+ pfkey_prop->sadb_prop_len,
51170+ (int)sizeof(struct sadb_prop),
51171+ (int)sizeof(struct sadb_comb));
51172+ SENDERR(EINVAL);
51173+ }
51174+
51175+ if(pfkey_prop->sadb_prop_replay > 64) {
51176+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51177+ "pfkey_prop_parse: "
51178+ "replay window size: %d -- must be 0 <= size <= 64\n",
51179+ pfkey_prop->sadb_prop_replay);
51180+ SENDERR(EINVAL);
51181+ }
51182+
51183+ for(i=0; i<3; i++) {
51184+ if(pfkey_prop->sadb_prop_reserved[i]) {
51185+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51186+ "pfkey_prop_parse: "
51187+ "res[%d]=%d, must be zero.\n",
51188+ i, pfkey_prop->sadb_prop_reserved[i]);
51189+ SENDERR(EINVAL);
51190+ }
51191+ }
51192+
51193+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
51194+
51195+ for(i = 0; i < num_comb; i++) {
51196+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
51197+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51198+ "pfkey_prop_parse: "
51199+ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
51200+ i,
51201+ pfkey_comb->sadb_comb_auth,
51202+ SADB_AALG_MAX);
51203+ SENDERR(EINVAL);
51204+ }
51205+
51206+ if(pfkey_comb->sadb_comb_auth) {
51207+ if(!pfkey_comb->sadb_comb_auth_minbits) {
51208+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51209+ "pfkey_prop_parse: "
51210+ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
51211+ i);
51212+ SENDERR(EINVAL);
51213+ }
51214+ if(!pfkey_comb->sadb_comb_auth_maxbits) {
51215+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51216+ "pfkey_prop_parse: "
51217+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
51218+ i);
51219+ SENDERR(EINVAL);
51220+ }
51221+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
51222+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51223+ "pfkey_prop_parse: "
51224+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
51225+ i,
51226+ pfkey_comb->sadb_comb_auth_minbits,
51227+ pfkey_comb->sadb_comb_auth_maxbits);
51228+ SENDERR(EINVAL);
51229+ }
51230+ } else {
51231+ if(pfkey_comb->sadb_comb_auth_minbits) {
51232+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51233+ "pfkey_prop_parse: "
51234+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
51235+ i,
51236+ pfkey_comb->sadb_comb_auth_minbits);
51237+ SENDERR(EINVAL);
51238+ }
51239+ if(pfkey_comb->sadb_comb_auth_maxbits) {
51240+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51241+ "pfkey_prop_parse: "
51242+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
51243+ i,
51244+ pfkey_comb->sadb_comb_auth_maxbits);
51245+ SENDERR(EINVAL);
51246+ }
51247+ }
51248+
51249+#if SADB_EALG_MAX < 255
51250+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
51251+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51252+ "pfkey_comb_parse: "
51253+ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
51254+ i,
51255+ pfkey_comb->sadb_comb_encrypt,
51256+ SADB_EALG_MAX);
51257+ SENDERR(EINVAL);
51258+ }
51259+#endif
51260+
51261+ if(pfkey_comb->sadb_comb_encrypt) {
51262+ if(!pfkey_comb->sadb_comb_encrypt_minbits) {
51263+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51264+ "pfkey_prop_parse: "
51265+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
51266+ i);
51267+ SENDERR(EINVAL);
51268+ }
51269+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
51270+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51271+ "pfkey_prop_parse: "
51272+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
51273+ i);
51274+ SENDERR(EINVAL);
51275+ }
51276+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
51277+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51278+ "pfkey_prop_parse: "
51279+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
51280+ i,
51281+ pfkey_comb->sadb_comb_encrypt_minbits,
51282+ pfkey_comb->sadb_comb_encrypt_maxbits);
51283+ SENDERR(EINVAL);
51284+ }
51285+ } else {
51286+ if(pfkey_comb->sadb_comb_encrypt_minbits) {
51287+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51288+ "pfkey_prop_parse: "
51289+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
51290+ i,
51291+ pfkey_comb->sadb_comb_encrypt_minbits);
51292+ SENDERR(EINVAL);
51293+ }
51294+ if(pfkey_comb->sadb_comb_encrypt_maxbits) {
51295+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51296+ "pfkey_prop_parse: "
51297+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
51298+ i,
51299+ pfkey_comb->sadb_comb_encrypt_maxbits);
51300+ SENDERR(EINVAL);
51301+ }
51302+ }
51303+
51304+ /* XXX do sanity check on flags */
51305+
51306+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
51307+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51308+ "pfkey_prop_parse: "
51309+ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
51310+ i,
51311+ pfkey_comb->sadb_comb_soft_allocations,
51312+ pfkey_comb->sadb_comb_hard_allocations);
51313+ SENDERR(EINVAL);
51314+ }
51315+
51316+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
51317+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51318+ "pfkey_prop_parse: "
51319+ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
51320+ i,
51321+ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
51322+ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
51323+ SENDERR(EINVAL);
51324+ }
51325+
51326+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
51327+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51328+ "pfkey_prop_parse: "
51329+ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
51330+ i,
51331+ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
51332+ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
51333+ SENDERR(EINVAL);
51334+ }
51335+
51336+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
51337+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51338+ "pfkey_prop_parse: "
51339+ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
51340+ i,
51341+ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
51342+ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
51343+ SENDERR(EINVAL);
51344+ }
51345+
51346+ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
51347+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51348+ "pfkey_prop_parse: "
51349+ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
51350+ i,
51351+ pfkey_comb->sadb_x_comb_soft_packets,
51352+ pfkey_comb->sadb_x_comb_hard_packets);
51353+ SENDERR(EINVAL);
51354+ }
51355+
51356+ if(pfkey_comb->sadb_comb_reserved) {
51357+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51358+ "pfkey_prop_parse: "
51359+ "comb[%d].res=%d, must be zero.\n",
51360+ i,
51361+ pfkey_comb->sadb_comb_reserved);
51362+ SENDERR(EINVAL);
51363+ }
51364+ pfkey_comb++;
51365+ }
51366+
51367+errlab:
51368+ return error;
51369+}
51370+
51371+DEBUG_NO_STATIC int
51372+pfkey_supported_parse(struct sadb_ext *pfkey_ext)
51373+{
51374+ int error = 0;
51375+ unsigned int i, num_alg;
51376+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
51377+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
51378+
51379+ /* sanity checks... */
51380+ if((pfkey_supported->sadb_supported_len <
51381+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
51382+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
51383+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
51384+
51385+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51386+ "pfkey_supported_parse: "
51387+ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
51388+ pfkey_supported->sadb_supported_len,
51389+ (int)sizeof(struct sadb_supported),
51390+ (int)sizeof(struct sadb_alg));
51391+ SENDERR(EINVAL);
51392+ }
51393+
51394+ if(pfkey_supported->sadb_supported_reserved) {
51395+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51396+ "pfkey_supported_parse: "
51397+ "res=%d, must be zero.\n",
51398+ pfkey_supported->sadb_supported_reserved);
51399+ SENDERR(EINVAL);
51400+ }
51401+
51402+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
51403+
51404+ for(i = 0; i < num_alg; i++) {
51405+ /* process algo description */
51406+ if(pfkey_alg->sadb_alg_reserved) {
51407+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51408+ "pfkey_supported_parse: "
51409+ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
51410+ i,
51411+ pfkey_alg->sadb_alg_id,
51412+ pfkey_alg->sadb_alg_ivlen,
51413+ pfkey_alg->sadb_alg_minbits,
51414+ pfkey_alg->sadb_alg_maxbits,
51415+ pfkey_alg->sadb_alg_reserved);
51416+ SENDERR(EINVAL);
51417+ }
51418+
51419+ /* XXX can alg_id auth/enc be determined from info given?
51420+ Yes, but OpenBSD's method does not iteroperate with rfc2367.
51421+ rgb, 2000-04-06 */
51422+
51423+ switch(pfkey_supported->sadb_supported_exttype) {
51424+ case SADB_EXT_SUPPORTED_AUTH:
51425+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
51426+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51427+ "pfkey_supported_parse: "
51428+ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
51429+ i,
51430+ pfkey_alg->sadb_alg_id,
51431+ SADB_AALG_MAX);
51432+ SENDERR(EINVAL);
51433+ }
51434+ break;
51435+ case SADB_EXT_SUPPORTED_ENCRYPT:
51436+#if SADB_EALG_MAX < 255
51437+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
51438+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51439+ "pfkey_supported_parse: "
51440+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
51441+ i,
51442+ pfkey_alg->sadb_alg_id,
51443+ SADB_EALG_MAX);
51444+ SENDERR(EINVAL);
51445+ }
51446+#endif
51447+ break;
51448+ default:
51449+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51450+ "pfkey_supported_parse: "
51451+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
51452+ i,
51453+ pfkey_alg->sadb_alg_id,
51454+ SADB_EALG_MAX);
51455+ SENDERR(EINVAL);
51456+ }
51457+ pfkey_alg++;
51458+ }
51459+
51460+ errlab:
51461+ return error;
51462+}
51463+
51464+DEBUG_NO_STATIC int
51465+pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
51466+{
51467+ int error = 0;
51468+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
51469+
51470+ /* sanity checks... */
51471+ if(pfkey_spirange->sadb_spirange_len !=
51472+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
51473+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51474+ "pfkey_spirange_parse: "
51475+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51476+ pfkey_spirange->sadb_spirange_len,
51477+ (int)sizeof(struct sadb_spirange));
51478+ SENDERR(EINVAL);
51479+ }
51480+
51481+ if(pfkey_spirange->sadb_spirange_reserved) {
51482+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51483+ "pfkey_spirange_parse: "
51484+ "reserved=%d must be set to zero.\n",
51485+ pfkey_spirange->sadb_spirange_reserved);
51486+ SENDERR(EINVAL);
51487+ }
51488+
51489+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
51490+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51491+ "pfkey_spirange_parse: "
51492+ "minspi=%08x must be < maxspi=%08x.\n",
51493+ ntohl(pfkey_spirange->sadb_spirange_min),
51494+ ntohl(pfkey_spirange->sadb_spirange_max));
51495+ SENDERR(EINVAL);
51496+ }
51497+
51498+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
51499+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51500+ "pfkey_spirange_parse: "
51501+ "minspi=%08x must be > 255.\n",
51502+ ntohl(pfkey_spirange->sadb_spirange_min));
51503+ SENDERR(EEXIST);
51504+ }
51505+
51506+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51507+ "pfkey_spirange_parse: "
51508+ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
51509+ pfkey_spirange->sadb_spirange_len,
51510+ pfkey_spirange->sadb_spirange_exttype,
51511+ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
51512+ pfkey_spirange->sadb_spirange_min,
51513+ pfkey_spirange->sadb_spirange_max,
51514+ pfkey_spirange->sadb_spirange_reserved);
51515+ errlab:
51516+ return error;
51517+}
51518+
51519+DEBUG_NO_STATIC int
51520+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
51521+{
51522+ int error = 0;
51523+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
51524+
51525+ /* sanity checks... */
51526+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
51527+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
51528+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51529+ "pfkey_x_kmprivate_parse: "
51530+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51531+ pfkey_x_kmprivate->sadb_x_kmprivate_len,
51532+ (int)sizeof(struct sadb_x_kmprivate));
51533+ SENDERR(EINVAL);
51534+ }
51535+
51536+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
51537+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51538+ "pfkey_x_kmprivate_parse: "
51539+ "reserved=%d must be set to zero.\n",
51540+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
51541+ SENDERR(EINVAL);
51542+ }
51543+
51544+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51545+ "pfkey_x_kmprivate_parse: "
51546+ "Sorry, I can't parse exttype=%d yet.\n",
51547+ pfkey_ext->sadb_ext_type);
51548+ SENDERR(EINVAL); /* don't process these yet */
51549+
51550+errlab:
51551+ return error;
51552+}
51553+
51554+DEBUG_NO_STATIC int
51555+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
51556+{
51557+ int error = 0;
51558+ int i;
51559+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
51560+
51561+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51562+ "pfkey_x_satype_parse: enter\n");
51563+ /* sanity checks... */
51564+ if(pfkey_x_satype->sadb_x_satype_len !=
51565+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
51566+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51567+ "pfkey_x_satype_parse: "
51568+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51569+ pfkey_x_satype->sadb_x_satype_len,
51570+ (int)sizeof(struct sadb_x_satype));
51571+ SENDERR(EINVAL);
51572+ }
51573+
51574+ if(!pfkey_x_satype->sadb_x_satype_satype) {
51575+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51576+ "pfkey_x_satype_parse: "
51577+ "satype is zero, must be non-zero.\n");
51578+ SENDERR(EINVAL);
51579+ }
51580+
51581+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
51582+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51583+ "pfkey_x_satype_parse: "
51584+ "satype %d > max %d, invalid.\n",
51585+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
51586+ SENDERR(EINVAL);
51587+ }
51588+
51589+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
51590+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51591+ "pfkey_x_satype_parse: "
51592+ "proto lookup from satype=%d failed.\n",
51593+ pfkey_x_satype->sadb_x_satype_satype);
51594+ SENDERR(EINVAL);
51595+ }
51596+
51597+ for(i = 0; i < 3; i++) {
51598+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
51599+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51600+ "pfkey_x_satype_parse: "
51601+ "reserved[%d]=%d must be set to zero.\n",
51602+ i, pfkey_x_satype->sadb_x_satype_reserved[i]);
51603+ SENDERR(EINVAL);
51604+ }
51605+ }
51606+
51607+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51608+ "pfkey_x_satype_parse: "
51609+ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
51610+ pfkey_x_satype->sadb_x_satype_len,
51611+ pfkey_x_satype->sadb_x_satype_exttype,
51612+ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
51613+ pfkey_x_satype->sadb_x_satype_satype,
51614+ satype2name(pfkey_x_satype->sadb_x_satype_satype),
51615+ pfkey_x_satype->sadb_x_satype_reserved[0],
51616+ pfkey_x_satype->sadb_x_satype_reserved[1],
51617+ pfkey_x_satype->sadb_x_satype_reserved[2]);
51618+errlab:
51619+ return error;
51620+}
51621+
51622+DEBUG_NO_STATIC int
51623+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
51624+{
51625+ int error = 0;
51626+ int i;
51627+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
51628+
51629+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51630+ "pfkey_x_debug_parse: enter\n");
51631+ /* sanity checks... */
51632+ if(pfkey_x_debug->sadb_x_debug_len !=
51633+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
51634+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51635+ "pfkey_x_debug_parse: "
51636+ "size wrong ext_len=%d, key_ext_len=%d.\n",
51637+ pfkey_x_debug->sadb_x_debug_len,
51638+ (int)sizeof(struct sadb_x_debug));
51639+ SENDERR(EINVAL);
51640+ }
51641+
51642+ for(i = 0; i < 4; i++) {
51643+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
51644+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51645+ "pfkey_x_debug_parse: "
51646+ "reserved[%d]=%d must be set to zero.\n",
51647+ i, pfkey_x_debug->sadb_x_debug_reserved[i]);
51648+ SENDERR(EINVAL);
51649+ }
51650+ }
51651+
51652+errlab:
51653+ return error;
51654+}
51655+
51656+DEBUG_NO_STATIC int
51657+pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
51658+{
51659+ int error = 0;
51660+ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
51661+
51662+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
51663+ /* sanity checks... */
51664+
51665+ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
51666+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51667+ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
51668+ p->sadb_protocol_len, (int)sizeof(*p));
51669+ SENDERR(EINVAL);
51670+ }
51671+
51672+ if (p->sadb_protocol_reserved2 != 0) {
51673+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51674+ "pfkey_protocol_parse: res=%d, must be zero.\n",
51675+ p->sadb_protocol_reserved2);
51676+ SENDERR(EINVAL);
51677+ }
51678+
51679+ errlab:
51680+ return error;
51681+}
51682+
51683+#ifdef NAT_TRAVERSAL
51684+DEBUG_NO_STATIC int
51685+pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
51686+{
51687+ return 0;
51688+}
51689+DEBUG_NO_STATIC int
51690+pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
51691+{
51692+ return 0;
51693+}
51694+#endif
51695+
51696+#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
51697+
51698+DEFINEPARSER(pfkey_sa_parse);
51699+DEFINEPARSER(pfkey_lifetime_parse);
51700+DEFINEPARSER(pfkey_address_parse);
51701+DEFINEPARSER(pfkey_key_parse);
51702+DEFINEPARSER(pfkey_ident_parse);
51703+DEFINEPARSER(pfkey_sens_parse);
51704+DEFINEPARSER(pfkey_prop_parse);
51705+DEFINEPARSER(pfkey_supported_parse);
51706+DEFINEPARSER(pfkey_spirange_parse);
51707+DEFINEPARSER(pfkey_x_kmprivate_parse);
51708+DEFINEPARSER(pfkey_x_satype_parse);
51709+DEFINEPARSER(pfkey_x_ext_debug_parse);
51710+DEFINEPARSER(pfkey_x_ext_protocol_parse);
51711+#ifdef NAT_TRAVERSAL
51712+DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
51713+DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
51714+#endif
51715+
51716+struct pf_key_ext_parsers_def *ext_default_parsers[]=
51717+{
51718+ NULL, /* pfkey_msg_parse, */
51719+ &pfkey_sa_parse_def,
51720+ &pfkey_lifetime_parse_def,
51721+ &pfkey_lifetime_parse_def,
51722+ &pfkey_lifetime_parse_def,
51723+ &pfkey_address_parse_def,
51724+ &pfkey_address_parse_def,
51725+ &pfkey_address_parse_def,
51726+ &pfkey_key_parse_def,
51727+ &pfkey_key_parse_def,
51728+ &pfkey_ident_parse_def,
51729+ &pfkey_ident_parse_def,
51730+ &pfkey_sens_parse_def,
51731+ &pfkey_prop_parse_def,
51732+ &pfkey_supported_parse_def,
51733+ &pfkey_supported_parse_def,
51734+ &pfkey_spirange_parse_def,
51735+ &pfkey_x_kmprivate_parse_def,
51736+ &pfkey_x_satype_parse_def,
51737+ &pfkey_sa_parse_def,
51738+ &pfkey_address_parse_def,
51739+ &pfkey_address_parse_def,
51740+ &pfkey_address_parse_def,
51741+ &pfkey_address_parse_def,
51742+ &pfkey_address_parse_def,
51743+ &pfkey_x_ext_debug_parse_def,
51744+ &pfkey_x_ext_protocol_parse_def
51745+#ifdef NAT_TRAVERSAL
51746+ ,
51747+ &pfkey_x_ext_nat_t_type_parse_def,
51748+ &pfkey_x_ext_nat_t_port_parse_def,
51749+ &pfkey_x_ext_nat_t_port_parse_def,
51750+ &pfkey_address_parse_def
51751+#endif
51752+};
51753+
51754+int
51755+pfkey_msg_parse(struct sadb_msg *pfkey_msg,
51756+ struct pf_key_ext_parsers_def *ext_parsers[],
51757+ struct sadb_ext *extensions[],
51758+ int dir)
51759+{
51760+ int error = 0;
51761+ int remain;
51762+ struct sadb_ext *pfkey_ext;
51763+ int extensions_seen = 0;
51764+
51765+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51766+ "pfkey_msg_parse: "
51767+ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
51768+ pfkey_msg->sadb_msg_version,
51769+ pfkey_msg->sadb_msg_type,
51770+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
51771+ pfkey_msg->sadb_msg_errno,
51772+ pfkey_msg->sadb_msg_satype,
51773+ satype2name(pfkey_msg->sadb_msg_satype),
51774+ pfkey_msg->sadb_msg_len,
51775+ pfkey_msg->sadb_msg_reserved,
51776+ pfkey_msg->sadb_msg_seq,
51777+ pfkey_msg->sadb_msg_pid);
51778+
51779+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
51780+
51781+ pfkey_extensions_init(extensions);
51782+
51783+ remain = pfkey_msg->sadb_msg_len;
51784+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
51785+
51786+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
51787+ sizeof(struct sadb_msg));
51788+
51789+ extensions[0] = (struct sadb_ext *) pfkey_msg;
51790+
51791+
51792+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
51793+ ERROR("pfkey_msg_parse: "
51794+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
51795+ pfkey_msg->sadb_msg_version,
51796+ PF_KEY_V2);
51797+ SENDERR(EINVAL);
51798+ }
51799+
51800+ if(!pfkey_msg->sadb_msg_type) {
51801+ ERROR("pfkey_msg_parse: "
51802+ "msg type not set, must be non-zero..\n");
51803+ SENDERR(EINVAL);
51804+ }
51805+
51806+ if(pfkey_msg->sadb_msg_type > SADB_MAX) {
51807+ ERROR("pfkey_msg_parse: "
51808+ "msg type=%d > max=%d.\n",
51809+ pfkey_msg->sadb_msg_type,
51810+ SADB_MAX);
51811+ SENDERR(EINVAL);
51812+ }
51813+
51814+ switch(pfkey_msg->sadb_msg_type) {
51815+ case SADB_GETSPI:
51816+ case SADB_UPDATE:
51817+ case SADB_ADD:
51818+ case SADB_DELETE:
51819+ case SADB_GET:
51820+ case SADB_X_GRPSA:
51821+ case SADB_X_ADDFLOW:
51822+ if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
51823+ ERROR("pfkey_msg_parse: "
51824+ "satype %d conversion to proto failed for msg_type %d (%s).\n",
51825+ pfkey_msg->sadb_msg_satype,
51826+ pfkey_msg->sadb_msg_type,
51827+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51828+ SENDERR(EINVAL);
51829+ } else {
51830+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51831+ "pfkey_msg_parse: "
51832+ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
51833+ pfkey_msg->sadb_msg_satype,
51834+ satype2name(pfkey_msg->sadb_msg_satype),
51835+ satype2proto(pfkey_msg->sadb_msg_satype),
51836+ pfkey_msg->sadb_msg_type,
51837+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51838+ }
51839+ case SADB_ACQUIRE:
51840+ case SADB_REGISTER:
51841+ case SADB_EXPIRE:
51842+ if(!pfkey_msg->sadb_msg_satype) {
51843+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51844+ "pfkey_msg_parse: "
51845+ "satype is zero, must be non-zero for msg_type %d(%s).\n",
51846+ pfkey_msg->sadb_msg_type,
51847+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51848+ SENDERR(EINVAL);
51849+ }
51850+ default:
51851+ break;
51852+ }
51853+
51854+ /* errno must not be set in downward messages */
51855+ /* this is not entirely true... a response to an ACQUIRE could return an error */
51856+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
51857+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51858+ "pfkey_msg_parse: "
51859+ "errno set to %d.\n",
51860+ pfkey_msg->sadb_msg_errno);
51861+ SENDERR(EINVAL);
51862+ }
51863+
51864+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51865+ "pfkey_msg_parse: "
51866+ "remain=%d\n",
51867+ remain
51868+ );
51869+
51870+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51871+ "pfkey_msg_parse: "
51872+ "extensions permitted=%08x, required=%08x.\n",
51873+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51874+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
51875+
51876+ extensions_seen = 1;
51877+
51878+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
51879+ /* Is there enough message left to support another extension header? */
51880+ if(remain < pfkey_ext->sadb_ext_len) {
51881+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51882+ "pfkey_msg_parse: "
51883+ "remain %d less than ext len %d.\n",
51884+ remain, pfkey_ext->sadb_ext_len);
51885+ SENDERR(EINVAL);
51886+ }
51887+
51888+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51889+ "pfkey_msg_parse: "
51890+ "parsing ext type=%d(%s) remain=%d.\n",
51891+ pfkey_ext->sadb_ext_type,
51892+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51893+ remain);
51894+
51895+ /* Is the extension header type valid? */
51896+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
51897+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51898+ "pfkey_msg_parse: "
51899+ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
51900+ pfkey_ext->sadb_ext_type,
51901+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51902+ SADB_EXT_MAX);
51903+ SENDERR(EINVAL);
51904+ }
51905+
51906+ /* Have we already seen this type of extension? */
51907+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
51908+ {
51909+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51910+ "pfkey_msg_parse: "
51911+ "ext type %d(%s) already seen.\n",
51912+ pfkey_ext->sadb_ext_type,
51913+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51914+ SENDERR(EINVAL);
51915+ }
51916+
51917+ /* Do I even know about this type of extension? */
51918+ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
51919+ ERROR("pfkey_msg_parse: "
51920+ "ext type %d(%s) unknown, ignoring.\n",
51921+ pfkey_ext->sadb_ext_type,
51922+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51923+ goto next_ext;
51924+ }
51925+
51926+ /* Is this type of extension permitted for this type of message? */
51927+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
51928+ 1<<pfkey_ext->sadb_ext_type)) {
51929+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51930+ "pfkey_msg_parse: "
51931+ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
51932+ pfkey_ext->sadb_ext_type,
51933+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51934+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51935+ 1<<pfkey_ext->sadb_ext_type);
51936+ SENDERR(EINVAL);
51937+ }
51938+
51939+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51940+ "pfkey_msg_parse: "
51941+ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
51942+ remain,
51943+ pfkey_ext->sadb_ext_type,
51944+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51945+ pfkey_ext->sadb_ext_len,
51946+ pfkey_ext,
51947+ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
51948+
51949+ /* Parse the extension */
51950+ if((error =
51951+ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
51952+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51953+ "pfkey_msg_parse: "
51954+ "extension parsing for type %d(%s) failed with error %d.\n",
51955+ pfkey_ext->sadb_ext_type,
51956+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51957+ error);
51958+ SENDERR(-error);
51959+ }
51960+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51961+ "pfkey_msg_parse: "
51962+ "Extension %d(%s) parsed.\n",
51963+ pfkey_ext->sadb_ext_type,
51964+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51965+
51966+ /* Mark that we have seen this extension and remember the header location */
51967+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
51968+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
51969+
51970+ next_ext:
51971+ /* Calculate how much message remains */
51972+ remain -= pfkey_ext->sadb_ext_len;
51973+
51974+ if(!remain) {
51975+ break;
51976+ }
51977+ /* Find the next extension header */
51978+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
51979+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
51980+ }
51981+
51982+ if(remain) {
51983+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51984+ "pfkey_msg_parse: "
51985+ "unexpected remainder of %d.\n",
51986+ remain);
51987+ /* why is there still something remaining? */
51988+ SENDERR(EINVAL);
51989+ }
51990+
51991+ /* check required extensions */
51992+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51993+ "pfkey_msg_parse: "
51994+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
51995+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51996+ extensions_seen,
51997+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
51998+
51999+ /* don't check further if it is an error return message since it
52000+ may not have a body */
52001+ if(pfkey_msg->sadb_msg_errno) {
52002+ SENDERR(-error);
52003+ }
52004+
52005+ if((extensions_seen &
52006+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
52007+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
52008+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52009+ "pfkey_msg_parse: "
52010+ "required extensions missing:%08x.\n",
52011+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
52012+ (extensions_seen &
52013+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
52014+ SENDERR(EINVAL);
52015+ }
52016+
52017+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
52018+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
52019+ != SADB_X_EXT_ADDRESS_DELFLOW)
52020+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
52021+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
52022+ & SADB_X_SAFLAGS_CLEARFLOW)
52023+ != SADB_X_SAFLAGS_CLEARFLOW))) {
52024+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52025+ "pfkey_msg_parse: "
52026+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
52027+ SADB_X_EXT_ADDRESS_DELFLOW
52028+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
52029+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
52030+ SENDERR(EINVAL);
52031+ }
52032+
52033+ switch(pfkey_msg->sadb_msg_type) {
52034+ case SADB_ADD:
52035+ case SADB_UPDATE:
52036+ /* check maturity */
52037+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
52038+ SADB_SASTATE_MATURE) {
52039+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52040+ "pfkey_msg_parse: "
52041+ "state=%d for add or update should be MATURE=%d.\n",
52042+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
52043+ SADB_SASTATE_MATURE);
52044+ SENDERR(EINVAL);
52045+ }
52046+
52047+ /* check AH and ESP */
52048+ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
52049+ case SADB_SATYPE_AH:
52050+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
52051+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
52052+ SADB_AALG_NONE)) {
52053+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52054+ "pfkey_msg_parse: "
52055+ "auth alg is zero, must be non-zero for AH SAs.\n");
52056+ SENDERR(EINVAL);
52057+ }
52058+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
52059+ SADB_EALG_NONE) {
52060+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52061+ "pfkey_msg_parse: "
52062+ "AH handed encalg=%d, must be zero.\n",
52063+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
52064+ SENDERR(EINVAL);
52065+ }
52066+ break;
52067+ case SADB_SATYPE_ESP:
52068+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
52069+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
52070+ SADB_EALG_NONE)) {
52071+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52072+ "pfkey_msg_parse: "
52073+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
52074+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
52075+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
52076+ SENDERR(EINVAL);
52077+ }
52078+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
52079+ SADB_EALG_NULL) &&
52080+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
52081+ SADB_AALG_NONE) ) {
52082+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52083+ "pfkey_msg_parse: "
52084+ "ESP handed encNULL+authNONE, illegal combination.\n");
52085+ SENDERR(EINVAL);
52086+ }
52087+ break;
52088+ case SADB_X_SATYPE_COMP:
52089+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
52090+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
52091+ SADB_EALG_NONE)) {
52092+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52093+ "pfkey_msg_parse: "
52094+ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
52095+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
52096+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
52097+ SENDERR(EINVAL);
52098+ }
52099+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
52100+ SADB_AALG_NONE) {
52101+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52102+ "pfkey_msg_parse: "
52103+ "COMP handed auth=%d, must be zero.\n",
52104+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
52105+ SENDERR(EINVAL);
52106+ }
52107+ break;
52108+ default:
52109+ break;
52110+ }
52111+ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
52112+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
52113+ "pfkey_msg_parse: "
52114+ "spi=%08x must be > 255.\n",
52115+ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
52116+ SENDERR(EINVAL);
52117+ }
52118+ default:
52119+ break;
52120+ }
52121+errlab:
52122+
52123+ return error;
52124+}
52125+
52126+/*
52127+ * $Log: pfkey_v2_parse.c,v $
52128+ * Revision 1.65 2005-04-06 17:46:05 mcr
52129+ * failure to recognize an extension is considered an error.
52130+ * This could be a problem in the future, but we need some kind
52131+ * of logging. This should be rate limited, probably.
52132+ *
52133+ * Revision 1.64 2005/01/26 00:50:35 mcr
52134+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
52135+ * and make sure that NAT_TRAVERSAL is set as well to match
52136+ * userspace compiles of code.
52137+ *
52138+ * Revision 1.63 2004/10/28 22:54:10 mcr
52139+ * results from valgrind, thanks to: Harald Hoyer <harald@redhat.com>
52140+ *
52141+ * Revision 1.62 2004/10/03 01:26:36 mcr
52142+ * fixes for gcc 3.4 compilation.
52143+ *
52144+ * Revision 1.61 2004/07/10 19:11:18 mcr
52145+ * CONFIG_IPSEC -> CONFIG_KLIPS.
52146+ *
52147+ * Revision 1.59 2004/04/18 03:03:49 mcr
52148+ * renamed common include files from pluto directory.
52149+ *
52150+ * Revision 1.58 2004/03/08 01:59:08 ken
52151+ * freeswan.h -> openswan.h
52152+ *
52153+ * Revision 1.57 2003/12/10 01:20:19 mcr
52154+ * NAT-traversal patches to KLIPS.
52155+ *
52156+ * Revision 1.56 2003/12/04 23:01:12 mcr
52157+ * removed ipsec_netlink.h
52158+ *
52159+ * Revision 1.55 2003/11/07 01:30:37 ken
52160+ * Cast sizeof() to int to keep things 64bit clean
52161+ *
52162+ * Revision 1.54 2003/10/31 02:27:12 mcr
52163+ * pulled up port-selector patches and sa_id elimination.
52164+ *
52165+ * Revision 1.53.20.2 2003/10/29 01:11:32 mcr
52166+ * added debugging for pfkey library.
52167+ *
52168+ * Revision 1.53.20.1 2003/09/21 13:59:44 mcr
52169+ * pre-liminary X.509 patch - does not yet pass tests.
52170+ *
52171+ * Revision 1.53 2003/01/30 02:32:09 rgb
52172+ *
52173+ * Rename SAref table macro names for clarity.
52174+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
52175+ *
52176+ * Revision 1.52 2002/12/30 06:53:07 mcr
52177+ * deal with short SA structures... #if 0 out for now. Probably
52178+ * not quite the right way.
52179+ *
52180+ * Revision 1.51 2002/12/13 18:16:02 mcr
52181+ * restored sa_ref code
52182+ *
52183+ * Revision 1.50 2002/12/13 18:06:52 mcr
52184+ * temporarily removed sadb_x_sa_ref reference for 2.xx
52185+ *
52186+ * Revision 1.49 2002/10/05 05:02:58 dhr
52187+ *
52188+ * C labels go on statements
52189+ *
52190+ * Revision 1.48 2002/09/20 15:40:45 rgb
52191+ * Added sadb_x_sa_ref to struct sadb_sa.
52192+ *
52193+ * Revision 1.47 2002/09/20 05:01:31 rgb
52194+ * Fixed usage of pfkey_lib_debug.
52195+ * Format for function declaration style consistency.
52196+ * Added text labels to elucidate numeric values presented.
52197+ * Re-organised debug output to reduce noise in output.
52198+ *
52199+ * Revision 1.46 2002/07/24 18:44:54 rgb
52200+ * Type fiddling to tame ia64 compiler.
52201+ *
52202+ * Revision 1.45 2002/05/23 07:14:11 rgb
52203+ * Cleaned up %p variants to 0p%p for test suite cleanup.
52204+ *
52205+ * Revision 1.44 2002/04/24 07:55:32 mcr
52206+ * #include patches and Makefiles for post-reorg compilation.
52207+ *
52208+ * Revision 1.43 2002/04/24 07:36:40 mcr
52209+ * Moved from ./lib/pfkey_v2_parse.c,v
52210+ *
52211+ * Revision 1.42 2002/01/29 22:25:36 rgb
52212+ * Re-add ipsec_kversion.h to keep MALLOC happy.
52213+ *
52214+ * Revision 1.41 2002/01/29 01:59:10 mcr
52215+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
52216+ * updating of IPv6 structures to match latest in6.h version.
52217+ * removed dead code from openswan.h that also duplicated kversions.h
52218+ * code.
52219+ *
52220+ * Revision 1.40 2002/01/20 20:34:50 mcr
52221+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
52222+ *
52223+ * Revision 1.39 2001/11/27 05:29:22 mcr
52224+ * pfkey parses are now maintained by a structure
52225+ * that includes their name for debug purposes.
52226+ * DEBUGGING() macro changed so that it takes a debug
52227+ * level so that pf_key() can use this to decode the
52228+ * structures without innundanting humans.
52229+ * Also uses pfkey_v2_sadb_ext_string() in messages.
52230+ *
52231+ * Revision 1.38 2001/11/06 19:47:47 rgb
52232+ * Added packet parameter to lifetime and comb structures.
52233+ *
52234+ * Revision 1.37 2001/10/18 04:45:24 rgb
52235+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
52236+ * lib/openswan.h version macros moved to lib/kversions.h.
52237+ * Other compiler directive cleanups.
52238+ *
52239+ * Revision 1.36 2001/06/14 19:35:16 rgb
52240+ * Update copyright date.
52241+ *
52242+ * Revision 1.35 2001/05/03 19:44:51 rgb
52243+ * Standardise on SENDERR() macro.
52244+ *
52245+ * Revision 1.34 2001/03/16 07:41:51 rgb
52246+ * Put openswan.h include before pluto includes.
52247+ *
52248+ * Revision 1.33 2001/02/27 07:13:51 rgb
52249+ * Added satype2name() function.
52250+ * Added text to default satype_tbl entry.
52251+ * Added satype2name() conversions for most satype debug output.
52252+ *
52253+ * Revision 1.32 2001/02/26 20:01:09 rgb
52254+ * Added internal IP protocol 61 for magic SAs.
52255+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
52256+ * Re-formatted debug output (split lines, consistent spacing).
52257+ * Removed acquire, register and expire requirements for a known satype.
52258+ * Changed message type checking to a switch structure.
52259+ * Verify expected NULL auth for IPCOMP.
52260+ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for
52261+ * appropriate message types.
52262+ *
52263+ * Revision 1.31 2000/12/01 07:09:00 rgb
52264+ * Added ipcomp sanity check to require encalgo is set.
52265+ *
52266+ * Revision 1.30 2000/11/17 18:10:30 rgb
52267+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
52268+ * network byte order since this is the way PF_KEYv2 stored spis.
52269+ *
52270+ * Revision 1.29 2000/10/12 00:02:39 rgb
52271+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
52272+ *
52273+ * Revision 1.28 2000/09/20 16:23:04 rgb
52274+ * Remove over-paranoid extension check in the presence of sadb_msg_errno.
52275+ *
52276+ * Revision 1.27 2000/09/20 04:04:21 rgb
52277+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
52278+ * oopsen.
52279+ *
52280+ * Revision 1.26 2000/09/15 11:37:02 rgb
52281+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
52282+ * IPCOMP zlib deflate code.
52283+ *
52284+ * Revision 1.25 2000/09/12 22:35:37 rgb
52285+ * Restructured to remove unused extensions from CLEARFLOW messages.
52286+ *
52287+ * Revision 1.24 2000/09/12 18:59:54 rgb
52288+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
52289+ *
52290+ * Revision 1.23 2000/09/12 03:27:00 rgb
52291+ * Moved DEBUGGING definition to compile kernel with debug off.
52292+ *
52293+ * Revision 1.22 2000/09/09 06:39:27 rgb
52294+ * Restrict pfkey errno check to downward messages only.
52295+ *
52296+ * Revision 1.21 2000/09/08 19:22:34 rgb
52297+ * Enabled pfkey_sens_parse().
52298+ * Added check for errno on downward acquire messages only.
52299+ *
52300+ * Revision 1.20 2000/09/01 18:48:23 rgb
52301+ * Fixed reserved check bug and added debug output in
52302+ * pfkey_supported_parse().
52303+ * Fixed debug output label bug in pfkey_ident_parse().
52304+ *
52305+ * Revision 1.19 2000/08/27 01:55:26 rgb
52306+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
52307+ *
52308+ * Revision 1.18 2000/08/24 17:00:36 rgb
52309+ * Ignore unknown extensions instead of failing.
52310+ *
52311+ * Revision 1.17 2000/06/02 22:54:14 rgb
52312+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
52313+ *
52314+ * Revision 1.16 2000/05/10 19:25:11 rgb
52315+ * Fleshed out proposal and supported extensions.
52316+ *
52317+ * Revision 1.15 2000/01/24 21:15:31 rgb
52318+ * Added disabled pluto pfkey lib debug flag.
52319+ * Added algo debugging reporting.
52320+ *
52321+ * Revision 1.14 2000/01/22 23:24:29 rgb
52322+ * Added new functions proto2satype() and satype2proto() and lookup
52323+ * table satype_tbl. Also added proto2name() since it was easy.
52324+ *
52325+ * Revision 1.13 2000/01/21 09:43:59 rgb
52326+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
52327+ *
52328+ * Revision 1.12 2000/01/21 06:28:19 rgb
52329+ * Added address cases for eroute flows.
52330+ * Indented compiler directives for readability.
52331+ * Added klipsdebug switching capability.
52332+ *
52333+ * Revision 1.11 1999/12/29 21:14:59 rgb
52334+ * Fixed debug text cut and paste typo.
52335+ *
52336+ * Revision 1.10 1999/12/10 17:45:24 rgb
52337+ * Added address debugging.
52338+ *
52339+ * Revision 1.9 1999/12/09 23:11:42 rgb
52340+ * Ditched <string.h> include since we no longer use memset().
52341+ * Use new pfkey_extensions_init() instead of memset().
52342+ * Added check for SATYPE in pfkey_msg_build().
52343+ * Tidy up comments and debugging comments.
52344+ *
52345+ * Revision 1.8 1999/12/07 19:55:26 rgb
52346+ * Removed unused first argument from extension parsers.
52347+ * Removed static pluto debug flag.
52348+ * Moved message type and state checking to pfkey_msg_parse().
52349+ * Changed print[fk] type from lx to x to quiet compiler.
52350+ * Removed redundant remain check.
52351+ * Changed __u* types to uint* to avoid use of asm/types.h and
52352+ * sys/types.h in userspace code.
52353+ *
52354+ * Revision 1.7 1999/12/01 22:20:51 rgb
52355+ * Moved pfkey_lib_debug variable into the library.
52356+ * Added pfkey version check into header parsing.
52357+ * Added check for SATYPE only for those extensions that require a
52358+ * non-zero value.
52359+ *
52360+ * Revision 1.6 1999/11/27 11:58:05 rgb
52361+ * Added ipv6 headers.
52362+ * Moved sadb_satype2proto protocol lookup table from
52363+ * klips/net/ipsec/pfkey_v2_parser.c.
52364+ * Enable lifetime_current checking.
52365+ * Debugging error messages added.
52366+ * Add argument to pfkey_msg_parse() for direction.
52367+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
52368+ * Add CVS log entry to bottom of file.
52369+ * Moved auth and enc alg check to pfkey_msg_parse().
52370+ * Enable accidentally disabled spirange parsing.
52371+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
52372+ *
52373+ * Local variables:
52374+ * c-file-style: "linux"
52375+ * End:
52376+ *
52377+ */
52378--- /dev/null Tue Mar 11 13:02:56 2003
52379+++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004
52380@@ -0,0 +1,3529 @@
52381+/*
52382+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
52383+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
52384+ *
52385+ * This program is free software; you can redistribute it and/or modify it
52386+ * under the terms of the GNU General Public License as published by the
52387+ * Free Software Foundation; either version 2 of the License, or (at your
52388+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
52389+ *
52390+ * This program is distributed in the hope that it will be useful, but
52391+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
52392+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
52393+ * for more details.
52394+ *
52395+ * RCSID $Id: pfkey_v2_parser.c,v 1.134.2.4 2007-10-30 21:40:36 paul Exp $
52396+ */
52397+
52398+/*
52399+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
52400+ */
52401+
52402+char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.134.2.4 2007-10-30 21:40:36 paul Exp $";
52403+
52404+#ifndef AUTOCONF_INCLUDED
52405+#include <linux/config.h>
52406+#endif
52407+#include <linux/version.h>
52408+#include <linux/kernel.h> /* printk() */
52409+
52410+#include "openswan/ipsec_param.h"
52411+
52412+#ifdef MALLOC_SLAB
52413+# include <linux/slab.h> /* kmalloc() */
52414+#else /* MALLOC_SLAB */
52415+# include <linux/malloc.h> /* kmalloc() */
52416+#endif /* MALLOC_SLAB */
52417+#include <linux/errno.h> /* error codes */
52418+#include <linux/types.h> /* size_t */
52419+#include <linux/interrupt.h> /* mark_bh */
52420+
52421+#include <linux/netdevice.h> /* struct device, and other headers */
52422+#include <linux/etherdevice.h> /* eth_type_trans */
52423+#include <linux/ip.h> /* struct iphdr */
52424+#include <linux/skbuff.h>
52425+
52426+#include <openswan.h>
52427+
52428+#include <crypto/des.h>
52429+
52430+#ifdef SPINLOCK
52431+# ifdef SPINLOCK_23
52432+# include <linux/spinlock.h> /* *lock* */
52433+# else /* SPINLOCK_23 */
52434+# include <asm/spinlock.h> /* *lock* */
52435+# endif /* SPINLOCK_23 */
52436+#endif /* SPINLOCK */
52437+
52438+#include <linux/in6.h>
52439+#include <net/route.h>
52440+
52441+#include <net/ip.h>
52442+#ifdef NETLINK_SOCK
52443+# include <linux/netlink.h>
52444+#else
52445+# include <net/netlink.h>
52446+#endif
52447+
52448+#include <linux/random.h> /* get_random_bytes() */
52449+
52450+#include "openswan/radij.h"
52451+#include "openswan/ipsec_encap.h"
52452+#include "openswan/ipsec_sa.h"
52453+
52454+#include "openswan/ipsec_radij.h"
52455+#include "openswan/ipsec_xform.h"
52456+#include "openswan/ipsec_ah.h"
52457+#include "openswan/ipsec_esp.h"
52458+#include "openswan/ipsec_tunnel.h"
52459+#include "openswan/ipsec_rcv.h"
52460+#include "openswan/ipcomp.h"
52461+
52462+#include <pfkeyv2.h>
52463+#include <pfkey.h>
52464+
52465+#include "openswan/ipsec_proto.h"
52466+#include "openswan/ipsec_alg.h"
52467+
52468+#include "openswan/ipsec_kern24.h"
52469+
52470+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
52471+
52472+struct sklist_t {
52473+ struct socket *sk;
52474+ struct sklist_t* next;
52475+} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
52476+
52477+__u32 pfkey_msg_seq = 0;
52478+
52479+
52480+#if 0
52481+#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)
52482+#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)
52483+static void dump_said(ip_said *s, int line)
52484+{
52485+ char msa[SATOT_BUF];
52486+ size_t msa_len;
52487+
52488+ msa_len = satot(s, 0, msa, sizeof(msa));
52489+
52490+ printk("line: %d msa: %s\n", line, msa);
52491+}
52492+#endif
52493+
52494+
52495+int
52496+pfkey_alloc_eroute(struct eroute** eroute)
52497+{
52498+ int error = 0;
52499+ if(*eroute) {
52500+ KLIPS_PRINT(debug_pfkey,
52501+ "klips_debug:pfkey_alloc_eroute: "
52502+ "eroute struct already allocated\n");
52503+ SENDERR(EEXIST);
52504+ }
52505+
52506+ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
52507+ KLIPS_PRINT(debug_pfkey,
52508+ "klips_debug:pfkey_alloc_eroute: "
52509+ "memory allocation error\n");
52510+ SENDERR(ENOMEM);
52511+ }
52512+
52513+ KLIPS_PRINT(debug_pfkey,
52514+ "klips_debug:pfkey_alloc_eroute: "
52515+ "allocating %lu bytes for an eroute at 0p%p\n",
52516+ (unsigned long) sizeof(**eroute), *eroute);
52517+
52518+ memset((caddr_t)*eroute, 0, sizeof(**eroute));
52519+ (*eroute)->er_eaddr.sen_len =
52520+ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
52521+ (*eroute)->er_eaddr.sen_family =
52522+ (*eroute)->er_emask.sen_family = AF_ENCAP;
52523+ (*eroute)->er_eaddr.sen_type = SENT_IP4;
52524+ (*eroute)->er_emask.sen_type = 255;
52525+ (*eroute)->er_pid = 0;
52526+ (*eroute)->er_count = 0;
52527+ (*eroute)->er_lasttime = jiffies/HZ;
52528+
52529+ errlab:
52530+ return(error);
52531+}
52532+
52533+DEBUG_NO_STATIC int
52534+pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
52535+ struct pfkey_extracted_data *extr)
52536+{
52537+ int error = 0;
52538+ struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
52539+
52540+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
52541+
52542+ if (extr == 0) {
52543+ KLIPS_PRINT(debug_pfkey,
52544+ "klips_debug:pfkey_x_protocol_process:"
52545+ "extr is NULL, fatal\n");
52546+ SENDERR(EINVAL);
52547+ }
52548+ if (extr->eroute == 0) {
52549+ KLIPS_PRINT(debug_pfkey,
52550+ "klips_debug:pfkey_x_protocol_process:"
52551+ "extr->eroute is NULL, fatal\n");
52552+ SENDERR(EINVAL);
52553+ }
52554+
52555+ extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
52556+ extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
52557+ KLIPS_PRINT(debug_pfkey,
52558+ "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
52559+ p->sadb_protocol_proto);
52560+ errlab:
52561+ return error;
52562+}
52563+
52564+DEBUG_NO_STATIC int
52565+pfkey_ipsec_sa_init(struct ipsec_sa *ipsp)
52566+{
52567+
52568+ return ipsec_sa_init(ipsp);
52569+}
52570+
52571+int
52572+pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
52573+{
52574+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
52575+ "error=%d\n",
52576+ error);
52577+ if (!error) {
52578+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
52579+ "success.\n");
52580+ return 1;
52581+ } else {
52582+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
52583+ "caught error %d\n",
52584+ error);
52585+ pfkey_extensions_free(extensions);
52586+ return 0;
52587+ }
52588+}
52589+
52590+
52591+DEBUG_NO_STATIC int
52592+pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52593+{
52594+ int error = 0;
52595+ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
52596+ int found_avail = 0;
52597+ struct ipsec_sa *ipsq;
52598+ char sa[SATOT_BUF];
52599+ size_t sa_len;
52600+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52601+ struct sadb_msg *pfkey_reply = NULL;
52602+ struct socket_list *pfkey_socketsp;
52603+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52604+
52605+ KLIPS_PRINT(debug_pfkey,
52606+ "klips_debug:pfkey_getspi_parse: .\n");
52607+
52608+ pfkey_extensions_init(extensions_reply);
52609+
52610+ if(extr == NULL || extr->ips == NULL) {
52611+ KLIPS_PRINT(debug_pfkey,
52612+ "klips_debug:pfkey_getspi_parse: "
52613+ "error, extr or extr->ipsec_sa pointer NULL\n");
52614+ SENDERR(EINVAL);
52615+ }
52616+
52617+ if(extensions[SADB_EXT_SPIRANGE]) {
52618+ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
52619+ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
52620+ }
52621+
52622+ if(maxspi == minspi) {
52623+ extr->ips->ips_said.spi = maxspi;
52624+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52625+ if(ipsq != NULL) {
52626+ sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
52627+ ipsec_sa_put(ipsq);
52628+ KLIPS_PRINT(debug_pfkey,
52629+ "klips_debug:pfkey_getspi_parse: "
52630+ "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
52631+ sa_len ? sa : " (error)");
52632+ SENDERR(EEXIST);
52633+ } else {
52634+ found_avail = 1;
52635+ }
52636+ } else {
52637+ int i = 0;
52638+ __u32 rand_val;
52639+ __u32 spi_diff;
52640+ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
52641+ prng_bytes(&ipsec_prng, (char *) &(rand_val),
52642+ ( (spi_diff < (2^8)) ? 1 :
52643+ ( (spi_diff < (2^16)) ? 2 :
52644+ ( (spi_diff < (2^24)) ? 3 :
52645+ 4 ) ) ) );
52646+ extr->ips->ips_said.spi = htonl(ntohl(minspi) +
52647+ (rand_val %
52648+ (spi_diff + 1)));
52649+ i++;
52650+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52651+ if(ipsq == NULL) {
52652+ found_avail = 1;
52653+ } else {
52654+ ipsec_sa_put(ipsq);
52655+ }
52656+ }
52657+ }
52658+
52659+ sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
52660+
52661+ if (!found_avail) {
52662+ KLIPS_PRINT(debug_pfkey,
52663+ "klips_debug:pfkey_getspi_parse: "
52664+ "found an old ipsec_sa for SA: %s, delete it first.\n",
52665+ sa_len ? sa : " (error)");
52666+ SENDERR(EEXIST);
52667+ }
52668+
52669+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52670+ extr->ips->ips_flags |= EMT_INBOUND;
52671+ }
52672+
52673+ KLIPS_PRINT(debug_pfkey,
52674+ "klips_debug:pfkey_getspi_parse: "
52675+ "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
52676+ sa_len ? sa : " (error)",
52677+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52678+
52679+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52680+ extr->ips->ips_rcvif = NULL;
52681+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
52682+
52683+ extr->ips->ips_state = SADB_SASTATE_LARVAL;
52684+
52685+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
52686+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
52687+ }
52688+
52689+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52690+ SADB_GETSPI,
52691+ satype,
52692+ 0,
52693+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52694+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52695+ extensions_reply)
52696+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52697+ SADB_EXT_SA,
52698+ extr->ips->ips_said.spi,
52699+ 0,
52700+ SADB_SASTATE_LARVAL,
52701+ 0,
52702+ 0,
52703+ 0,
52704+ extr->ips->ips_ref),
52705+ extensions_reply)
52706+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52707+ SADB_EXT_ADDRESS_SRC,
52708+ 0, /*extr->ips->ips_said.proto,*/
52709+ 0,
52710+ extr->ips->ips_addr_s),
52711+ extensions_reply)
52712+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52713+ SADB_EXT_ADDRESS_DST,
52714+ 0, /*extr->ips->ips_said.proto,*/
52715+ 0,
52716+ extr->ips->ips_addr_d),
52717+ extensions_reply) )) {
52718+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52719+ "failed to build the getspi reply message extensions\n");
52720+ goto errlab;
52721+ }
52722+
52723+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52724+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52725+ "failed to build the getspi reply message\n");
52726+ SENDERR(-error);
52727+ }
52728+ for(pfkey_socketsp = pfkey_open_sockets;
52729+ pfkey_socketsp;
52730+ pfkey_socketsp = pfkey_socketsp->next) {
52731+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52732+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52733+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52734+ satype,
52735+ satype2name(satype),
52736+ pfkey_socketsp->socketp,
52737+ error);
52738+ SENDERR(-error);
52739+ }
52740+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52741+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52742+ satype,
52743+ satype2name(satype),
52744+ pfkey_socketsp->socketp);
52745+ }
52746+
52747+ if((error = ipsec_sa_add(extr->ips))) {
52748+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52749+ "failed to add the larval SA=%s with error=%d.\n",
52750+ sa_len ? sa : " (error)",
52751+ error);
52752+ SENDERR(-error);
52753+ }
52754+ extr->ips = NULL;
52755+
52756+ KLIPS_PRINT(debug_pfkey,
52757+ "klips_debug:pfkey_getspi_parse: "
52758+ "successful for SA: %s\n",
52759+ sa_len ? sa : " (error)");
52760+
52761+ errlab:
52762+ if (pfkey_reply) {
52763+ pfkey_msg_free(&pfkey_reply);
52764+ }
52765+ pfkey_extensions_free(extensions_reply);
52766+ return error;
52767+}
52768+
52769+DEBUG_NO_STATIC int
52770+pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52771+{
52772+ int error = 0;
52773+ struct ipsec_sa* ipsq;
52774+ char sa[SATOT_BUF];
52775+ size_t sa_len;
52776+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52777+ struct sadb_msg *pfkey_reply = NULL;
52778+ struct socket_list *pfkey_socketsp;
52779+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52780+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52781+ struct ipsec_sa *nat_t_ips_saved = NULL;
52782+#endif
52783+ KLIPS_PRINT(debug_pfkey,
52784+ "klips_debug:pfkey_update_parse: .\n");
52785+
52786+ pfkey_extensions_init(extensions_reply);
52787+
52788+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
52789+ KLIPS_PRINT(debug_pfkey,
52790+ "klips_debug:pfkey_update_parse: "
52791+ "error, sa_state=%d must be MATURE=%d\n",
52792+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
52793+ SADB_SASTATE_MATURE);
52794+ SENDERR(EINVAL);
52795+ }
52796+
52797+ if(extr == NULL || extr->ips == NULL) {
52798+ KLIPS_PRINT(debug_pfkey,
52799+ "klips_debug:pfkey_update_parse: "
52800+ "error, extr or extr->ips pointer NULL\n");
52801+ SENDERR(EINVAL);
52802+ }
52803+
52804+ sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
52805+
52806+ spin_lock_bh(&tdb_lock);
52807+
52808+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52809+ if (ipsq == NULL) {
52810+ spin_unlock_bh(&tdb_lock);
52811+ KLIPS_PRINT(debug_pfkey,
52812+ "klips_debug:pfkey_update_parse: "
52813+ "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n",
52814+ sa_len ? sa : " (error)");
52815+ SENDERR(ENOENT);
52816+ }
52817+
52818+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52819+ extr->ips->ips_flags |= EMT_INBOUND;
52820+ }
52821+
52822+ KLIPS_PRINT(debug_pfkey,
52823+ "klips_debug:pfkey_update_parse: "
52824+ "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
52825+ sa_len ? sa : " (error)",
52826+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52827+
52828+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52829+ if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) {
52830+ KLIPS_PRINT(debug_pfkey,
52831+ "klips_debug:pfkey_update_parse: only updating NAT-T ports "
52832+ "(%u:%u -> %u:%u)\n",
52833+ ipsq->ips_natt_sport, ipsq->ips_natt_dport,
52834+ extr->ips->ips_natt_sport, extr->ips->ips_natt_dport);
52835+
52836+ if (extr->ips->ips_natt_sport) {
52837+ ipsq->ips_natt_sport = extr->ips->ips_natt_sport;
52838+ if (ipsq->ips_addr_s->sa_family == AF_INET) {
52839+ ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport);
52840+ }
52841+ }
52842+
52843+ if (extr->ips->ips_natt_dport) {
52844+ ipsq->ips_natt_dport = extr->ips->ips_natt_dport;
52845+ if (ipsq->ips_addr_d->sa_family == AF_INET) {
52846+ ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport);
52847+ }
52848+ }
52849+
52850+ nat_t_ips_saved = extr->ips;
52851+ extr->ips = ipsq;
52852+ }
52853+ else {
52854+#endif
52855+
52856+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52857+ extr->ips->ips_rcvif = NULL;
52858+ if ((error = pfkey_ipsec_sa_init(extr->ips))) {
52859+ ipsec_sa_put(ipsq);
52860+ spin_unlock_bh(&tdb_lock);
52861+ KLIPS_PRINT(debug_pfkey,
52862+ "klips_debug:pfkey_update_parse: "
52863+ "not successful for SA: %s, deleting.\n",
52864+ sa_len ? sa : " (error)");
52865+ SENDERR(-error);
52866+ }
52867+
52868+ extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
52869+ ipsec_sa_put(ipsq);
52870+ if((error = ipsec_sa_delchain(ipsq))) {
52871+ spin_unlock_bh(&tdb_lock);
52872+ KLIPS_PRINT(debug_pfkey,
52873+ "klips_debug:pfkey_update_parse: "
52874+ "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n",
52875+ error,
52876+ sa_len ? sa : " (error)");
52877+ SENDERR(-error);
52878+ }
52879+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52880+ }
52881+#endif
52882+
52883+ spin_unlock_bh(&tdb_lock);
52884+
52885+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52886+ SADB_UPDATE,
52887+ satype,
52888+ 0,
52889+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52890+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52891+ extensions_reply)
52892+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52893+ SADB_EXT_SA,
52894+ extr->ips->ips_said.spi,
52895+ extr->ips->ips_replaywin,
52896+ extr->ips->ips_state,
52897+ extr->ips->ips_authalg,
52898+ extr->ips->ips_encalg,
52899+ extr->ips->ips_flags,
52900+ extr->ips->ips_ref),
52901+ extensions_reply)
52902+ /* The 3 lifetime extentions should only be sent if non-zero. */
52903+ && (extensions[SADB_EXT_LIFETIME_HARD]
52904+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
52905+ SADB_EXT_LIFETIME_HARD,
52906+ extr->ips->ips_life.ipl_allocations.ipl_hard,
52907+ extr->ips->ips_life.ipl_bytes.ipl_hard,
52908+ extr->ips->ips_life.ipl_addtime.ipl_hard,
52909+ extr->ips->ips_life.ipl_usetime.ipl_hard,
52910+ extr->ips->ips_life.ipl_packets.ipl_hard),
52911+ extensions_reply) : 1)
52912+ && (extensions[SADB_EXT_LIFETIME_SOFT]
52913+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
52914+ SADB_EXT_LIFETIME_SOFT,
52915+ extr->ips->ips_life.ipl_allocations.ipl_count,
52916+ extr->ips->ips_life.ipl_bytes.ipl_count,
52917+ extr->ips->ips_life.ipl_addtime.ipl_count,
52918+ extr->ips->ips_life.ipl_usetime.ipl_count,
52919+ extr->ips->ips_life.ipl_packets.ipl_count),
52920+ extensions_reply) : 1)
52921+ && (extr->ips->ips_life.ipl_allocations.ipl_count
52922+ || extr->ips->ips_life.ipl_bytes.ipl_count
52923+ || extr->ips->ips_life.ipl_addtime.ipl_count
52924+ || extr->ips->ips_life.ipl_usetime.ipl_count
52925+ || extr->ips->ips_life.ipl_packets.ipl_count
52926+
52927+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
52928+ SADB_EXT_LIFETIME_CURRENT,
52929+ extr->ips->ips_life.ipl_allocations.ipl_count,
52930+ extr->ips->ips_life.ipl_bytes.ipl_count,
52931+ extr->ips->ips_life.ipl_addtime.ipl_count,
52932+ extr->ips->ips_life.ipl_usetime.ipl_count,
52933+ extr->ips->ips_life.ipl_packets.ipl_count),
52934+ extensions_reply) : 1)
52935+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52936+ SADB_EXT_ADDRESS_SRC,
52937+ 0, /*extr->ips->ips_said.proto,*/
52938+ 0,
52939+ extr->ips->ips_addr_s),
52940+ extensions_reply)
52941+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52942+ SADB_EXT_ADDRESS_DST,
52943+ 0, /*extr->ips->ips_said.proto,*/
52944+ 0,
52945+ extr->ips->ips_addr_d),
52946+ extensions_reply)
52947+ && (extr->ips->ips_ident_s.data
52948+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
52949+ SADB_EXT_IDENTITY_SRC,
52950+ extr->ips->ips_ident_s.type,
52951+ extr->ips->ips_ident_s.id,
52952+ extr->ips->ips_ident_s.len,
52953+ extr->ips->ips_ident_s.data),
52954+ extensions_reply) : 1)
52955+ && (extr->ips->ips_ident_d.data
52956+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
52957+ SADB_EXT_IDENTITY_DST,
52958+ extr->ips->ips_ident_d.type,
52959+ extr->ips->ips_ident_d.id,
52960+ extr->ips->ips_ident_d.len,
52961+ extr->ips->ips_ident_d.data),
52962+ extensions_reply) : 1)
52963+#if 0
52964+ /* FIXME: This won't work yet because I have not finished
52965+ it. */
52966+ && (extr->ips->ips_sens_
52967+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
52968+ extr->ips->ips_sens_dpd,
52969+ extr->ips->ips_sens_sens_level,
52970+ extr->ips->ips_sens_sens_len,
52971+ extr->ips->ips_sens_sens_bitmap,
52972+ extr->ips->ips_sens_integ_level,
52973+ extr->ips->ips_sens_integ_len,
52974+ extr->ips->ips_sens_integ_bitmap),
52975+ extensions_reply) : 1)
52976+#endif
52977+ )) {
52978+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52979+ "failed to build the update reply message extensions\n");
52980+ SENDERR(-error);
52981+ }
52982+
52983+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52984+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52985+ "failed to build the update reply message\n");
52986+ SENDERR(-error);
52987+ }
52988+ for(pfkey_socketsp = pfkey_open_sockets;
52989+ pfkey_socketsp;
52990+ pfkey_socketsp = pfkey_socketsp->next) {
52991+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52992+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52993+ "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52994+ satype,
52995+ satype2name(satype),
52996+ pfkey_socketsp->socketp,
52997+ error);
52998+ SENDERR(-error);
52999+ }
53000+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
53001+ "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53002+ satype,
53003+ satype2name(satype),
53004+ pfkey_socketsp->socketp);
53005+ }
53006+
53007+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
53008+ if (nat_t_ips_saved) {
53009+ /**
53010+ * As we _really_ update existing SA, we keep tdbq and need to delete
53011+ * parsed ips (nat_t_ips_saved, was extr->ips).
53012+ *
53013+ * goto errlab with extr->ips = nat_t_ips_saved will free it.
53014+ */
53015+
53016+ extr->ips = nat_t_ips_saved;
53017+
53018+ error = 0;
53019+ KLIPS_PRINT(debug_pfkey,
53020+ "klips_debug:pfkey_update_parse (NAT-T ports): "
53021+ "successful for SA: %s\n",
53022+ sa_len ? sa : " (error)");
53023+
53024+ goto errlab;
53025+ }
53026+#endif
53027+
53028+ if((error = ipsec_sa_add(extr->ips))) {
53029+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
53030+ "failed to update the mature SA=%s with error=%d.\n",
53031+ sa_len ? sa : " (error)",
53032+ error);
53033+ SENDERR(-error);
53034+ }
53035+ extr->ips = NULL;
53036+
53037+ KLIPS_PRINT(debug_pfkey,
53038+ "klips_debug:pfkey_update_parse: "
53039+ "successful for SA: %s\n",
53040+ sa_len ? sa : " (error)");
53041+
53042+ errlab:
53043+ if (pfkey_reply) {
53044+ pfkey_msg_free(&pfkey_reply);
53045+ }
53046+ pfkey_extensions_free(extensions_reply);
53047+ return error;
53048+}
53049+
53050+DEBUG_NO_STATIC int
53051+pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53052+{
53053+ int error = 0;
53054+ struct ipsec_sa* ipsq;
53055+ char sa[SATOT_BUF];
53056+ size_t sa_len;
53057+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53058+ struct sadb_msg *pfkey_reply = NULL;
53059+ struct socket_list *pfkey_socketsp;
53060+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53061+
53062+ KLIPS_PRINT(debug_pfkey,
53063+ "klips_debug:pfkey_add_parse: .\n");
53064+
53065+ pfkey_extensions_init(extensions_reply);
53066+
53067+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
53068+ KLIPS_PRINT(debug_pfkey,
53069+ "klips_debug:pfkey_add_parse: "
53070+ "error, sa_state=%d must be MATURE=%d\n",
53071+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
53072+ SADB_SASTATE_MATURE);
53073+ SENDERR(EINVAL);
53074+ }
53075+
53076+ if(!extr || !extr->ips) {
53077+ KLIPS_PRINT(debug_pfkey,
53078+ "klips_debug:pfkey_add_parse: "
53079+ "extr or extr->ips pointer NULL\n");
53080+ SENDERR(EINVAL);
53081+ }
53082+
53083+ sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
53084+
53085+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
53086+ if(ipsq != NULL) {
53087+ ipsec_sa_put(ipsq);
53088+ KLIPS_PRINT(debug_pfkey,
53089+ "klips_debug:pfkey_add_parse: "
53090+ "found an old ipsec_sa for SA%s, delete it first.\n",
53091+ sa_len ? sa : " (error)");
53092+ SENDERR(EEXIST);
53093+ }
53094+
53095+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
53096+ extr->ips->ips_flags |= EMT_INBOUND;
53097+ }
53098+
53099+ KLIPS_PRINT(debug_pfkey,
53100+ "klips_debug:pfkey_add_parse: "
53101+ "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
53102+ sa_len ? sa : " (error)",
53103+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
53104+
53105+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
53106+ extr->ips->ips_rcvif = NULL;
53107+
53108+ if ((error = pfkey_ipsec_sa_init(extr->ips))) {
53109+ KLIPS_PRINT(debug_pfkey,
53110+ "klips_debug:pfkey_add_parse: "
53111+ "not successful for SA: %s, deleting.\n",
53112+ sa_len ? sa : " (error)");
53113+ SENDERR(-error);
53114+ }
53115+
53116+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
53117+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
53118+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
53119+ }
53120+
53121+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53122+ SADB_ADD,
53123+ satype,
53124+ 0,
53125+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53126+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53127+ extensions_reply)
53128+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53129+ SADB_EXT_SA,
53130+ extr->ips->ips_said.spi,
53131+ extr->ips->ips_replaywin,
53132+ extr->ips->ips_state,
53133+ extr->ips->ips_authalg,
53134+ extr->ips->ips_encalg,
53135+ extr->ips->ips_flags,
53136+ extr->ips->ips_ref),
53137+ extensions_reply)
53138+ /* The 3 lifetime extentions should only be sent if non-zero. */
53139+ && (extensions[SADB_EXT_LIFETIME_HARD]
53140+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
53141+ SADB_EXT_LIFETIME_HARD,
53142+ extr->ips->ips_life.ipl_allocations.ipl_hard,
53143+ extr->ips->ips_life.ipl_bytes.ipl_hard,
53144+ extr->ips->ips_life.ipl_addtime.ipl_hard,
53145+ extr->ips->ips_life.ipl_usetime.ipl_hard,
53146+ extr->ips->ips_life.ipl_packets.ipl_hard),
53147+ extensions_reply) : 1)
53148+ && (extensions[SADB_EXT_LIFETIME_SOFT]
53149+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
53150+ SADB_EXT_LIFETIME_SOFT,
53151+ extr->ips->ips_life.ipl_allocations.ipl_soft,
53152+ extr->ips->ips_life.ipl_bytes.ipl_soft,
53153+ extr->ips->ips_life.ipl_addtime.ipl_soft,
53154+ extr->ips->ips_life.ipl_usetime.ipl_soft,
53155+ extr->ips->ips_life.ipl_packets.ipl_soft),
53156+ extensions_reply) : 1)
53157+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
53158+ SADB_EXT_ADDRESS_SRC,
53159+ 0, /*extr->ips->ips_said.proto,*/
53160+ 0,
53161+ extr->ips->ips_addr_s),
53162+ extensions_reply)
53163+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53164+ SADB_EXT_ADDRESS_DST,
53165+ 0, /*extr->ips->ips_said.proto,*/
53166+ 0,
53167+ extr->ips->ips_addr_d),
53168+ extensions_reply)
53169+ && (extr->ips->ips_ident_s.data
53170+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
53171+ SADB_EXT_IDENTITY_SRC,
53172+ extr->ips->ips_ident_s.type,
53173+ extr->ips->ips_ident_s.id,
53174+ extr->ips->ips_ident_s.len,
53175+ extr->ips->ips_ident_s.data),
53176+ extensions_reply) : 1)
53177+ && (extr->ips->ips_ident_d.data
53178+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
53179+ SADB_EXT_IDENTITY_DST,
53180+ extr->ips->ips_ident_d.type,
53181+ extr->ips->ips_ident_d.id,
53182+ extr->ips->ips_ident_d.len,
53183+ extr->ips->ips_ident_d.data),
53184+ extensions_reply) : 1)
53185+#if 0
53186+ /* FIXME: This won't work yet because I have not finished
53187+ it. */
53188+ && (extr->ips->ips_sens_
53189+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
53190+ extr->ips->ips_sens_dpd,
53191+ extr->ips->ips_sens_sens_level,
53192+ extr->ips->ips_sens_sens_len,
53193+ extr->ips->ips_sens_sens_bitmap,
53194+ extr->ips->ips_sens_integ_level,
53195+ extr->ips->ips_sens_integ_len,
53196+ extr->ips->ips_sens_integ_bitmap),
53197+ extensions_reply) : 1)
53198+#endif
53199+ )) {
53200+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
53201+ "failed to build the add reply message extensions\n");
53202+ SENDERR(-error);
53203+ }
53204+
53205+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53206+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
53207+ "failed to build the add reply message\n");
53208+ SENDERR(-error);
53209+ }
53210+ for(pfkey_socketsp = pfkey_open_sockets;
53211+ pfkey_socketsp;
53212+ pfkey_socketsp = pfkey_socketsp->next) {
53213+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53214+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
53215+ "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53216+ satype,
53217+ satype2name(satype),
53218+ pfkey_socketsp->socketp,
53219+ error);
53220+ SENDERR(-error);
53221+ }
53222+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
53223+ "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53224+ satype,
53225+ satype2name(satype),
53226+ pfkey_socketsp->socketp);
53227+ }
53228+
53229+ if((error = ipsec_sa_add(extr->ips))) {
53230+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
53231+ "failed to add the mature SA=%s with error=%d.\n",
53232+ sa_len ? sa : " (error)",
53233+ error);
53234+ SENDERR(-error);
53235+ }
53236+ extr->ips = NULL;
53237+
53238+ KLIPS_PRINT(debug_pfkey,
53239+ "klips_debug:pfkey_add_parse: "
53240+ "successful for SA: %s\n",
53241+ sa_len ? sa : " (error)");
53242+
53243+ errlab:
53244+ if (pfkey_reply) {
53245+ pfkey_msg_free(&pfkey_reply);
53246+ }
53247+ pfkey_extensions_free(extensions_reply);
53248+ return error;
53249+}
53250+
53251+DEBUG_NO_STATIC int
53252+pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53253+{
53254+ struct ipsec_sa *ipsp;
53255+ char sa[SATOT_BUF];
53256+ size_t sa_len;
53257+ int error = 0;
53258+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53259+ struct sadb_msg *pfkey_reply = NULL;
53260+ struct socket_list *pfkey_socketsp;
53261+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53262+
53263+ KLIPS_PRINT(debug_pfkey,
53264+ "klips_debug:pfkey_delete_parse: .\n");
53265+
53266+ pfkey_extensions_init(extensions_reply);
53267+
53268+ if(!extr || !extr->ips) {
53269+ KLIPS_PRINT(debug_pfkey,
53270+ "klips_debug:pfkey_delete_parse: "
53271+ "extr or extr->ips pointer NULL, fatal\n");
53272+ SENDERR(EINVAL);
53273+ }
53274+
53275+ sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
53276+
53277+ spin_lock_bh(&tdb_lock);
53278+
53279+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
53280+ if (ipsp == NULL) {
53281+ spin_unlock_bh(&tdb_lock);
53282+ KLIPS_PRINT(debug_pfkey,
53283+ "klips_debug:pfkey_delete_parse: "
53284+ "ipsec_sa not found for SA:%s, could not delete.\n",
53285+ sa_len ? sa : " (error)");
53286+ SENDERR(ESRCH);
53287+ }
53288+
53289+ ipsec_sa_put(ipsp);
53290+ if((error = ipsec_sa_delchain(ipsp))) {
53291+ spin_unlock_bh(&tdb_lock);
53292+ KLIPS_PRINT(debug_pfkey,
53293+ "klips_debug:pfkey_delete_parse: "
53294+ "error=%d returned trying to delete ipsec_sa for SA:%s.\n",
53295+ error,
53296+ sa_len ? sa : " (error)");
53297+ SENDERR(-error);
53298+ }
53299+ spin_unlock_bh(&tdb_lock);
53300+
53301+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53302+ SADB_DELETE,
53303+ satype,
53304+ 0,
53305+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53306+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53307+ extensions_reply)
53308+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53309+ SADB_EXT_SA,
53310+ extr->ips->ips_said.spi,
53311+ 0,
53312+ 0,
53313+ 0,
53314+ 0,
53315+ 0,
53316+ extr->ips->ips_ref),
53317+ extensions_reply)
53318+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
53319+ SADB_EXT_ADDRESS_SRC,
53320+ 0, /*extr->ips->ips_said.proto,*/
53321+ 0,
53322+ extr->ips->ips_addr_s),
53323+ extensions_reply)
53324+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53325+ SADB_EXT_ADDRESS_DST,
53326+ 0, /*extr->ips->ips_said.proto,*/
53327+ 0,
53328+ extr->ips->ips_addr_d),
53329+ extensions_reply)
53330+ )) {
53331+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53332+ "failed to build the delete reply message extensions\n");
53333+ SENDERR(-error);
53334+ }
53335+
53336+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53337+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53338+ "failed to build the delete reply message\n");
53339+ SENDERR(-error);
53340+ }
53341+ for(pfkey_socketsp = pfkey_open_sockets;
53342+ pfkey_socketsp;
53343+ pfkey_socketsp = pfkey_socketsp->next) {
53344+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53345+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53346+ "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53347+ satype,
53348+ satype2name(satype),
53349+ pfkey_socketsp->socketp,
53350+ error);
53351+ SENDERR(-error);
53352+ }
53353+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53354+ "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53355+ satype,
53356+ satype2name(satype),
53357+ pfkey_socketsp->socketp);
53358+ }
53359+
53360+ errlab:
53361+ if (pfkey_reply) {
53362+ pfkey_msg_free(&pfkey_reply);
53363+ }
53364+ pfkey_extensions_free(extensions_reply);
53365+ return error;
53366+}
53367+
53368+DEBUG_NO_STATIC int
53369+pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53370+{
53371+ int error = 0;
53372+ struct ipsec_sa *ipsp;
53373+ char sa[SATOT_BUF];
53374+ size_t sa_len;
53375+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53376+ struct sadb_msg *pfkey_reply = NULL;
53377+
53378+ KLIPS_PRINT(debug_pfkey,
53379+ "klips_debug:pfkey_get_parse: .\n");
53380+
53381+ pfkey_extensions_init(extensions_reply);
53382+
53383+ if(!extr || !extr->ips) {
53384+ KLIPS_PRINT(debug_pfkey,
53385+ "klips_debug:pfkey_get_parse: "
53386+ "extr or extr->ips pointer NULL, fatal\n");
53387+ SENDERR(EINVAL);
53388+ }
53389+
53390+ sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
53391+
53392+ spin_lock_bh(&tdb_lock);
53393+
53394+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
53395+ if (ipsp == NULL) {
53396+ spin_unlock_bh(&tdb_lock);
53397+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53398+ "ipsec_sa not found for SA=%s, could not get.\n",
53399+ sa_len ? sa : " (error)");
53400+ SENDERR(ESRCH);
53401+ }
53402+
53403+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53404+ SADB_GET,
53405+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
53406+ 0,
53407+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53408+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53409+ extensions_reply)
53410+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53411+ SADB_EXT_SA,
53412+ extr->ips->ips_said.spi,
53413+ extr->ips->ips_replaywin,
53414+ extr->ips->ips_state,
53415+ extr->ips->ips_authalg,
53416+ extr->ips->ips_encalg,
53417+ extr->ips->ips_flags,
53418+ extr->ips->ips_ref),
53419+ extensions_reply)
53420+ /* The 3 lifetime extentions should only be sent if non-zero. */
53421+ && (ipsp->ips_life.ipl_allocations.ipl_count
53422+ || ipsp->ips_life.ipl_bytes.ipl_count
53423+ || ipsp->ips_life.ipl_addtime.ipl_count
53424+ || ipsp->ips_life.ipl_usetime.ipl_count
53425+ || ipsp->ips_life.ipl_packets.ipl_count
53426+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
53427+ SADB_EXT_LIFETIME_CURRENT,
53428+ ipsp->ips_life.ipl_allocations.ipl_count,
53429+ ipsp->ips_life.ipl_bytes.ipl_count,
53430+ ipsp->ips_life.ipl_addtime.ipl_count,
53431+ ipsp->ips_life.ipl_usetime.ipl_count,
53432+ ipsp->ips_life.ipl_packets.ipl_count),
53433+ extensions_reply) : 1)
53434+ && (ipsp->ips_life.ipl_allocations.ipl_hard
53435+ || ipsp->ips_life.ipl_bytes.ipl_hard
53436+ || ipsp->ips_life.ipl_addtime.ipl_hard
53437+ || ipsp->ips_life.ipl_usetime.ipl_hard
53438+ || ipsp->ips_life.ipl_packets.ipl_hard
53439+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
53440+ SADB_EXT_LIFETIME_HARD,
53441+ ipsp->ips_life.ipl_allocations.ipl_hard,
53442+ ipsp->ips_life.ipl_bytes.ipl_hard,
53443+ ipsp->ips_life.ipl_addtime.ipl_hard,
53444+ ipsp->ips_life.ipl_usetime.ipl_hard,
53445+ ipsp->ips_life.ipl_packets.ipl_hard),
53446+ extensions_reply) : 1)
53447+ && (ipsp->ips_life.ipl_allocations.ipl_soft
53448+ || ipsp->ips_life.ipl_bytes.ipl_soft
53449+ || ipsp->ips_life.ipl_addtime.ipl_soft
53450+ || ipsp->ips_life.ipl_usetime.ipl_soft
53451+ || ipsp->ips_life.ipl_packets.ipl_soft
53452+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
53453+ SADB_EXT_LIFETIME_SOFT,
53454+ ipsp->ips_life.ipl_allocations.ipl_soft,
53455+ ipsp->ips_life.ipl_bytes.ipl_soft,
53456+ ipsp->ips_life.ipl_addtime.ipl_soft,
53457+ ipsp->ips_life.ipl_usetime.ipl_soft,
53458+ ipsp->ips_life.ipl_packets.ipl_soft),
53459+ extensions_reply) : 1)
53460+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
53461+ SADB_EXT_ADDRESS_SRC,
53462+ 0, /*extr->ips->ips_said.proto,*/
53463+ 0,
53464+ extr->ips->ips_addr_s),
53465+ extensions_reply)
53466+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53467+ SADB_EXT_ADDRESS_DST,
53468+ 0, /*extr->ips->ips_said.proto,*/
53469+ 0,
53470+ extr->ips->ips_addr_d),
53471+ extensions_reply)
53472+ && (extr->ips->ips_addr_p
53473+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
53474+ SADB_EXT_ADDRESS_PROXY,
53475+ 0, /*extr->ips->ips_said.proto,*/
53476+ 0,
53477+ extr->ips->ips_addr_p),
53478+ extensions_reply) : 1)
53479+#if 0
53480+ /* FIXME: This won't work yet because the keys are not
53481+ stored directly in the ipsec_sa. They are stored as
53482+ contexts. */
53483+ && (extr->ips->ips_key_a_size
53484+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
53485+ SADB_EXT_KEY_AUTH,
53486+ extr->ips->ips_key_a_size * 8,
53487+ extr->ips->ips_key_a),
53488+ extensions_reply) : 1)
53489+ /* FIXME: This won't work yet because the keys are not
53490+ stored directly in the ipsec_sa. They are stored as
53491+ key schedules. */
53492+ && (extr->ips->ips_key_e_size
53493+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
53494+ SADB_EXT_KEY_ENCRYPT,
53495+ extr->ips->ips_key_e_size * 8,
53496+ extr->ips->ips_key_e),
53497+ extensions_reply) : 1)
53498+#endif
53499+ && (extr->ips->ips_ident_s.data
53500+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
53501+ SADB_EXT_IDENTITY_SRC,
53502+ extr->ips->ips_ident_s.type,
53503+ extr->ips->ips_ident_s.id,
53504+ extr->ips->ips_ident_s.len,
53505+ extr->ips->ips_ident_s.data),
53506+ extensions_reply) : 1)
53507+ && (extr->ips->ips_ident_d.data
53508+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
53509+ SADB_EXT_IDENTITY_DST,
53510+ extr->ips->ips_ident_d.type,
53511+ extr->ips->ips_ident_d.id,
53512+ extr->ips->ips_ident_d.len,
53513+ extr->ips->ips_ident_d.data),
53514+ extensions_reply) : 1)
53515+#if 0
53516+ /* FIXME: This won't work yet because I have not finished
53517+ it. */
53518+ && (extr->ips->ips_sens_
53519+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
53520+ extr->ips->ips_sens_dpd,
53521+ extr->ips->ips_sens_sens_level,
53522+ extr->ips->ips_sens_sens_len,
53523+ extr->ips->ips_sens_sens_bitmap,
53524+ extr->ips->ips_sens_integ_level,
53525+ extr->ips->ips_sens_integ_len,
53526+ extr->ips->ips_sens_integ_bitmap),
53527+ extensions_reply) : 1)
53528+#endif
53529+ )) {
53530+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53531+ "failed to build the get reply message extensions\n");
53532+ ipsec_sa_put(ipsp);
53533+ spin_unlock_bh(&tdb_lock);
53534+ SENDERR(-error);
53535+ }
53536+
53537+ ipsec_sa_put(ipsp);
53538+ spin_unlock_bh(&tdb_lock);
53539+
53540+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53541+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53542+ "failed to build the get reply message\n");
53543+ SENDERR(-error);
53544+ }
53545+
53546+ if((error = pfkey_upmsg(sk->sk_socket, pfkey_reply))) {
53547+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53548+ "failed to send the get reply message\n");
53549+ SENDERR(-error);
53550+ }
53551+
53552+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53553+ "succeeded in sending get reply message.\n");
53554+
53555+ errlab:
53556+ if (pfkey_reply) {
53557+ pfkey_msg_free(&pfkey_reply);
53558+ }
53559+ pfkey_extensions_free(extensions_reply);
53560+ return error;
53561+}
53562+
53563+DEBUG_NO_STATIC int
53564+pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53565+{
53566+ int error = 0;
53567+ struct socket_list *pfkey_socketsp;
53568+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53569+
53570+ KLIPS_PRINT(debug_pfkey,
53571+ "klips_debug:pfkey_acquire_parse: .\n");
53572+
53573+ /* XXX I don't know if we want an upper bound, since userspace may
53574+ want to register itself for an satype > SADB_SATYPE_MAX. */
53575+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53576+ KLIPS_PRINT(debug_pfkey,
53577+ "klips_debug:pfkey_acquire_parse: "
53578+ "SATYPE=%d invalid.\n",
53579+ satype);
53580+ SENDERR(EINVAL);
53581+ }
53582+
53583+ if(!(pfkey_registered_sockets[satype])) {
53584+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53585+ "no sockets registered for SAtype=%d(%s).\n",
53586+ satype,
53587+ satype2name(satype));
53588+ SENDERR(EPROTONOSUPPORT);
53589+ }
53590+
53591+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
53592+ pfkey_socketsp;
53593+ pfkey_socketsp = pfkey_socketsp->next) {
53594+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53595+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53596+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53597+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53598+ satype,
53599+ satype2name(satype),
53600+ pfkey_socketsp->socketp,
53601+ error);
53602+ SENDERR(-error);
53603+ }
53604+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53605+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53606+ satype,
53607+ satype2name(satype),
53608+ pfkey_socketsp->socketp);
53609+ }
53610+
53611+ errlab:
53612+ return error;
53613+}
53614+
53615+DEBUG_NO_STATIC int
53616+pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53617+{
53618+ int error = 0;
53619+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53620+
53621+ KLIPS_PRINT(debug_pfkey,
53622+ "klips_debug:pfkey_register_parse: .\n");
53623+
53624+ /* XXX I don't know if we want an upper bound, since userspace may
53625+ want to register itself for an satype > SADB_SATYPE_MAX. */
53626+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53627+ KLIPS_PRINT(debug_pfkey,
53628+ "klips_debug:pfkey_register_parse: "
53629+ "SATYPE=%d invalid.\n",
53630+ satype);
53631+ SENDERR(EINVAL);
53632+ }
53633+
53634+ if(!pfkey_list_insert_socket(sk->sk_socket,
53635+ &(pfkey_registered_sockets[satype]))) {
53636+ KLIPS_PRINT(debug_pfkey,
53637+ "klips_debug:pfkey_register_parse: "
53638+ "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
53639+ satype,
53640+ satype2name(satype),
53641+ key_pid(sk));
53642+ };
53643+
53644+ /* send up register msg with supported SATYPE algos */
53645+
53646+ error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]);
53647+ errlab:
53648+ return error;
53649+}
53650+
53651+int
53652+pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
53653+{
53654+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53655+ struct sadb_msg *pfkey_reply = NULL;
53656+ struct socket_list *pfkey_socketsp;
53657+ struct supported_list *pfkey_supported_listp;
53658+ unsigned int alg_num_a = 0, alg_num_e = 0;
53659+ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
53660+ int error = 0;
53661+
53662+ pfkey_extensions_init(extensions_reply);
53663+
53664+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53665+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53666+ "SAtype=%d unspecified or unknown.\n",
53667+ satype);
53668+ SENDERR(EINVAL);
53669+ }
53670+ if(!(pfkey_registered_sockets[satype])) {
53671+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53672+ "no sockets registered for SAtype=%d(%s).\n",
53673+ satype,
53674+ satype2name(satype));
53675+ SENDERR(EPROTONOSUPPORT);
53676+ }
53677+ /* send up register msg with supported SATYPE algos */
53678+ pfkey_supported_listp = pfkey_supported_list[satype];
53679+ KLIPS_PRINT(debug_pfkey,
53680+ "klips_debug:pfkey_register_reply: "
53681+ "pfkey_supported_list[%d]=0p%p\n",
53682+ satype,
53683+ pfkey_supported_list[satype]);
53684+ while(pfkey_supported_listp) {
53685+ KLIPS_PRINT(debug_pfkey,
53686+ "klips_debug:pfkey_register_reply: "
53687+ "checking supported=0p%p\n",
53688+ pfkey_supported_listp);
53689+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
53690+ KLIPS_PRINT(debug_pfkey,
53691+ "klips_debug:pfkey_register_reply: "
53692+ "adding auth alg.\n");
53693+ alg_num_a++;
53694+ }
53695+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
53696+ KLIPS_PRINT(debug_pfkey,
53697+ "klips_debug:pfkey_register_reply: "
53698+ "adding encrypt alg.\n");
53699+ alg_num_e++;
53700+ }
53701+ pfkey_supported_listp = pfkey_supported_listp->next;
53702+ }
53703+
53704+ if(alg_num_a) {
53705+ KLIPS_PRINT(debug_pfkey,
53706+ "klips_debug:pfkey_register_reply: "
53707+ "allocating %lu bytes for auth algs.\n",
53708+ (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
53709+ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
53710+ KLIPS_PRINT(debug_pfkey,
53711+ "klips_debug:pfkey_register_reply: "
53712+ "auth alg memory allocation error\n");
53713+ SENDERR(ENOMEM);
53714+ }
53715+ alg_ap = alg_a;
53716+ }
53717+
53718+ if(alg_num_e) {
53719+ KLIPS_PRINT(debug_pfkey,
53720+ "klips_debug:pfkey_register_reply: "
53721+ "allocating %lu bytes for enc algs.\n",
53722+ (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
53723+ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
53724+ KLIPS_PRINT(debug_pfkey,
53725+ "klips_debug:pfkey_register_reply: "
53726+ "enc alg memory allocation error\n");
53727+ SENDERR(ENOMEM);
53728+ }
53729+ alg_ep = alg_e;
53730+ }
53731+
53732+ pfkey_supported_listp = pfkey_supported_list[satype];
53733+ while(pfkey_supported_listp) {
53734+ if(alg_num_a) {
53735+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
53736+ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
53737+ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
53738+ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
53739+ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
53740+ alg_ap->sadb_alg_reserved = 0;
53741+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
53742+ "klips_debug:pfkey_register_reply: "
53743+ "adding auth=0p%p\n",
53744+ alg_ap);
53745+ alg_ap++;
53746+ }
53747+ }
53748+ if(alg_num_e) {
53749+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
53750+ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
53751+ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
53752+ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
53753+ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
53754+ alg_ep->sadb_alg_reserved = 0;
53755+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
53756+ "klips_debug:pfkey_register_reply: "
53757+ "adding encrypt=0p%p\n",
53758+ alg_ep);
53759+ alg_ep++;
53760+ }
53761+ }
53762+ KLIPS_PRINT(debug_pfkey,
53763+ "klips_debug:pfkey_register_reply: "
53764+ "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
53765+ satype,
53766+ satype2name(satype),
53767+ pfkey_supported_listp->supportedp->ias_exttype,
53768+ pfkey_supported_listp->supportedp->ias_id,
53769+ pfkey_supported_listp->supportedp->ias_ivlen,
53770+ pfkey_supported_listp->supportedp->ias_keyminbits,
53771+ pfkey_supported_listp->supportedp->ias_keymaxbits);
53772+ pfkey_supported_listp = pfkey_supported_listp->next;
53773+ }
53774+
53775+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53776+ SADB_REGISTER,
53777+ satype,
53778+ 0,
53779+ sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
53780+ sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
53781+ extensions_reply) &&
53782+ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
53783+ SADB_EXT_SUPPORTED_AUTH,
53784+ alg_num_a,
53785+ alg_a),
53786+ extensions_reply) : 1) &&
53787+ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
53788+ SADB_EXT_SUPPORTED_ENCRYPT,
53789+ alg_num_e,
53790+ alg_e),
53791+ extensions_reply) : 1))) {
53792+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53793+ "failed to build the register message extensions_reply\n");
53794+ SENDERR(-error);
53795+ }
53796+
53797+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53798+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53799+ "failed to build the register message\n");
53800+ SENDERR(-error);
53801+ }
53802+ /* this should go to all registered sockets for that satype only */
53803+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
53804+ pfkey_socketsp;
53805+ pfkey_socketsp = pfkey_socketsp->next) {
53806+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53807+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53808+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53809+ satype,
53810+ satype2name(satype),
53811+ pfkey_socketsp->socketp,
53812+ error);
53813+ SENDERR(-error);
53814+ }
53815+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53816+ "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n",
53817+ satype,
53818+ satype2name(satype),
53819+ pfkey_socketsp->socketp);
53820+ }
53821+
53822+ errlab:
53823+ if(alg_a) {
53824+ kfree(alg_a);
53825+ }
53826+ if(alg_e) {
53827+ kfree(alg_e);
53828+ }
53829+
53830+ if (pfkey_reply) {
53831+ pfkey_msg_free(&pfkey_reply);
53832+ }
53833+ pfkey_extensions_free(extensions_reply);
53834+ return error;
53835+}
53836+
53837+DEBUG_NO_STATIC int
53838+pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53839+{
53840+ int error = 0;
53841+ struct socket_list *pfkey_socketsp;
53842+#ifdef CONFIG_KLIPS_DEBUG
53843+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53844+#endif /* CONFIG_KLIPS_DEBUG */
53845+
53846+ KLIPS_PRINT(debug_pfkey,
53847+ "klips_debug:pfkey_expire_parse: .\n");
53848+
53849+ if(pfkey_open_sockets) {
53850+ for(pfkey_socketsp = pfkey_open_sockets;
53851+ pfkey_socketsp;
53852+ pfkey_socketsp = pfkey_socketsp->next) {
53853+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53854+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53855+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
53856+ "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53857+ satype,
53858+ satype2name(satype),
53859+ pfkey_socketsp->socketp,
53860+ error);
53861+ SENDERR(-error);
53862+ }
53863+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
53864+ "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53865+ satype,
53866+ satype2name(satype),
53867+ pfkey_socketsp->socketp);
53868+ }
53869+ }
53870+
53871+ errlab:
53872+ return error;
53873+}
53874+
53875+DEBUG_NO_STATIC int
53876+pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53877+{
53878+ int error = 0;
53879+ struct socket_list *pfkey_socketsp;
53880+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53881+ uint8_t proto = 0;
53882+
53883+ KLIPS_PRINT(debug_pfkey,
53884+ "klips_debug:pfkey_flush_parse: "
53885+ "flushing type %d SAs\n",
53886+ satype);
53887+
53888+ if(satype && !(proto = satype2proto(satype))) {
53889+ KLIPS_PRINT(debug_pfkey,
53890+ "klips_debug:pfkey_flush_parse: "
53891+ "satype %d lookup failed.\n",
53892+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
53893+ SENDERR(EINVAL);
53894+ }
53895+
53896+ if ((error = ipsec_sadb_cleanup(proto))) {
53897+ SENDERR(-error);
53898+ }
53899+
53900+ if(pfkey_open_sockets) {
53901+ for(pfkey_socketsp = pfkey_open_sockets;
53902+ pfkey_socketsp;
53903+ pfkey_socketsp = pfkey_socketsp->next) {
53904+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53905+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53906+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
53907+ "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
53908+ satype,
53909+ satype2name(satype),
53910+ proto,
53911+ pfkey_socketsp->socketp,
53912+ error);
53913+ SENDERR(-error);
53914+ }
53915+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
53916+ "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53917+ satype,
53918+ satype2name(satype),
53919+ pfkey_socketsp->socketp);
53920+ }
53921+ }
53922+
53923+ errlab:
53924+ return error;
53925+}
53926+
53927+DEBUG_NO_STATIC int
53928+pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53929+{
53930+ int error = 0;
53931+
53932+ KLIPS_PRINT(debug_pfkey,
53933+ "klips_debug:pfkey_dump_parse: .\n");
53934+
53935+ SENDERR(ENOSYS);
53936+ errlab:
53937+ return error;
53938+}
53939+
53940+DEBUG_NO_STATIC int
53941+pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53942+{
53943+ int error = 0;
53944+
53945+ KLIPS_PRINT(debug_pfkey,
53946+ "klips_debug:pfkey_promisc_parse: .\n");
53947+
53948+ SENDERR(ENOSYS);
53949+ errlab:
53950+ return error;
53951+}
53952+
53953+DEBUG_NO_STATIC int
53954+pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53955+{
53956+ int error = 0;
53957+
53958+ KLIPS_PRINT(debug_pfkey,
53959+ "klips_debug:pfkey_x_pchange_parse: .\n");
53960+
53961+ SENDERR(ENOSYS);
53962+ errlab:
53963+ return error;
53964+}
53965+
53966+DEBUG_NO_STATIC int
53967+pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53968+{
53969+ struct ipsec_sa *ips1p, *ips2p, *ipsp;
53970+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53971+ struct sadb_msg *pfkey_reply = NULL;
53972+ struct socket_list *pfkey_socketsp;
53973+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53974+ char sa1[SATOT_BUF], sa2[SATOT_BUF];
53975+ size_t sa_len1, sa_len2 = 0;
53976+ int error = 0;
53977+
53978+ KLIPS_PRINT(debug_pfkey,
53979+ "klips_debug:pfkey_x_grpsa_parse: .\n");
53980+
53981+ pfkey_extensions_init(extensions_reply);
53982+
53983+ if(extr == NULL || extr->ips == NULL) {
53984+ KLIPS_PRINT(debug_pfkey,
53985+ "klips_debug:pfkey_x_grpsa_parse: "
53986+ "extr or extr->ips is NULL, fatal.\n");
53987+ SENDERR(EINVAL);
53988+ }
53989+
53990+ sa_len1 = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa1, sizeof(sa1));
53991+ if(extr->ips2 != NULL) {
53992+ sa_len2 = KLIPS_SATOT(debug_pfkey, &extr->ips2->ips_said, 0, sa2, sizeof(sa2));
53993+ }
53994+
53995+ spin_lock_bh(&tdb_lock);
53996+
53997+ ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
53998+ if(ips1p == NULL) {
53999+ spin_unlock_bh(&tdb_lock);
54000+ KLIPS_PRINT(debug_pfkey,
54001+ "klips_debug:pfkey_x_grpsa_parse: "
54002+ "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n",
54003+ sa_len1 ? sa1 : " (error)");
54004+ SENDERR(ENOENT);
54005+ }
54006+ if(extr->ips2) { /* GRPSA */
54007+ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
54008+ if(ips2p == NULL) {
54009+ ipsec_sa_put(ips1p);
54010+ spin_unlock_bh(&tdb_lock);
54011+ KLIPS_PRINT(debug_pfkey,
54012+ "klips_debug:pfkey_x_grpsa_parse: "
54013+ "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n",
54014+ sa_len2 ? sa2 : " (error)");
54015+ SENDERR(ENOENT);
54016+ }
54017+
54018+ /* Is either one already linked? */
54019+ if(ips1p->ips_onext) {
54020+ ipsec_sa_put(ips1p);
54021+ ipsec_sa_put(ips2p);
54022+ spin_unlock_bh(&tdb_lock);
54023+ KLIPS_PRINT(debug_pfkey,
54024+ "klips_debug:pfkey_x_grpsa_parse: "
54025+ "ipsec_sa for SA: %s is already linked.\n",
54026+ sa_len1 ? sa1 : " (error)");
54027+ SENDERR(EEXIST);
54028+ }
54029+ if(ips2p->ips_inext) {
54030+ ipsec_sa_put(ips1p);
54031+ ipsec_sa_put(ips2p);
54032+ spin_unlock_bh(&tdb_lock);
54033+ KLIPS_PRINT(debug_pfkey,
54034+ "klips_debug:pfkey_x_grpsa_parse: "
54035+ "ipsec_sa for SA: %s is already linked.\n",
54036+ sa_len2 ? sa2 : " (error)");
54037+ SENDERR(EEXIST);
54038+ }
54039+
54040+ /* Is extr->ips already linked to extr->ips2? */
54041+ ipsp = ips2p;
54042+ while(ipsp) {
54043+ if(ipsp == ips1p) {
54044+ ipsec_sa_put(ips1p);
54045+ ipsec_sa_put(ips2p);
54046+ spin_unlock_bh(&tdb_lock);
54047+ KLIPS_PRINT(debug_pfkey,
54048+ "klips_debug:pfkey_x_grpsa_parse: "
54049+ "ipsec_sa for SA: %s is already linked to %s.\n",
54050+ sa_len1 ? sa1 : " (error)",
54051+ sa_len2 ? sa2 : " (error)");
54052+ SENDERR(EEXIST);
54053+ }
54054+ ipsp = ipsp->ips_onext;
54055+ }
54056+
54057+ /* link 'em */
54058+ KLIPS_PRINT(debug_pfkey,
54059+ "klips_debug:pfkey_x_grpsa_parse: "
54060+ "linking ipsec_sa SA: %s with %s.\n",
54061+ sa_len1 ? sa1 : " (error)",
54062+ sa_len2 ? sa2 : " (error)");
54063+ ips1p->ips_onext = ips2p;
54064+ ips2p->ips_inext = ips1p;
54065+ } else { /* UNGRPSA */
54066+ ipsec_sa_put(ips1p);
54067+ KLIPS_PRINT(debug_pfkey,
54068+ "klips_debug:pfkey_x_grpsa_parse: "
54069+ "unlinking ipsec_sa SA: %s.\n",
54070+ sa_len1 ? sa1 : " (error)");
54071+ while(ips1p->ips_onext) {
54072+ ips1p = ips1p->ips_onext;
54073+ }
54074+ while(ips1p->ips_inext) {
54075+ ipsp = ips1p;
54076+ ips1p = ips1p->ips_inext;
54077+ ipsec_sa_put(ips1p);
54078+ ipsp->ips_inext = NULL;
54079+ ipsec_sa_put(ipsp);
54080+ ips1p->ips_onext = NULL;
54081+ }
54082+ }
54083+
54084+ spin_unlock_bh(&tdb_lock);
54085+
54086+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
54087+ SADB_X_GRPSA,
54088+ satype,
54089+ 0,
54090+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
54091+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
54092+ extensions_reply)
54093+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
54094+ SADB_EXT_SA,
54095+ extr->ips->ips_said.spi,
54096+ extr->ips->ips_replaywin,
54097+ extr->ips->ips_state,
54098+ extr->ips->ips_authalg,
54099+ extr->ips->ips_encalg,
54100+ extr->ips->ips_flags,
54101+ extr->ips->ips_ref),
54102+ extensions_reply)
54103+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
54104+ SADB_EXT_ADDRESS_DST,
54105+ 0, /*extr->ips->ips_said.proto,*/
54106+ 0,
54107+ extr->ips->ips_addr_d),
54108+ extensions_reply)
54109+ && (extr->ips2
54110+ ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
54111+ ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
54112+ /* proto2satype(extr->ips2->ips_said.proto) */),
54113+ extensions_reply)
54114+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2],
54115+ SADB_X_EXT_SA2,
54116+ extr->ips2->ips_said.spi,
54117+ extr->ips2->ips_replaywin,
54118+ extr->ips2->ips_state,
54119+ extr->ips2->ips_authalg,
54120+ extr->ips2->ips_encalg,
54121+ extr->ips2->ips_flags,
54122+ extr->ips2->ips_ref),
54123+ extensions_reply)
54124+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
54125+ SADB_X_EXT_ADDRESS_DST2,
54126+ 0, /*extr->ips->ips_said.proto,*/
54127+ 0,
54128+ extr->ips2->ips_addr_d),
54129+ extensions_reply) ) : 1 )
54130+ )) {
54131+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
54132+ "failed to build the x_grpsa reply message extensions\n");
54133+ SENDERR(-error);
54134+ }
54135+
54136+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
54137+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
54138+ "failed to build the x_grpsa reply message\n");
54139+ SENDERR(-error);
54140+ }
54141+
54142+ for(pfkey_socketsp = pfkey_open_sockets;
54143+ pfkey_socketsp;
54144+ pfkey_socketsp = pfkey_socketsp->next) {
54145+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
54146+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
54147+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54148+ satype,
54149+ satype2name(satype),
54150+ pfkey_socketsp->socketp,
54151+ error);
54152+ SENDERR(-error);
54153+ }
54154+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
54155+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
54156+ satype,
54157+ satype2name(satype),
54158+ pfkey_socketsp->socketp);
54159+ }
54160+
54161+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
54162+ "succeeded in sending x_grpsa reply message.\n");
54163+
54164+ errlab:
54165+ if (pfkey_reply) {
54166+ pfkey_msg_free(&pfkey_reply);
54167+ }
54168+ pfkey_extensions_free(extensions_reply);
54169+ return error;
54170+}
54171+
54172+DEBUG_NO_STATIC int
54173+pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54174+{
54175+ int error = 0;
54176+#ifdef CONFIG_KLIPS_DEBUG
54177+ char buf1[64], buf2[64];
54178+#endif /* CONFIG_KLIPS_DEBUG */
54179+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
54180+ struct sadb_msg *pfkey_reply = NULL;
54181+ struct socket_list *pfkey_socketsp;
54182+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
54183+ ip_address srcflow, dstflow, srcmask, dstmask;
54184+
54185+ KLIPS_PRINT(debug_pfkey,
54186+ "klips_debug:pfkey_x_addflow_parse: .\n");
54187+
54188+ pfkey_extensions_init(extensions_reply);
54189+
54190+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
54191+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
54192+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
54193+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
54194+
54195+ if(!extr || !(extr->ips) || !(extr->eroute)) {
54196+ KLIPS_PRINT(debug_pfkey,
54197+ "klips_debug:pfkey_x_addflow_parse: "
54198+ "missing extr, ipsec_sa or eroute data.\n");
54199+ SENDERR(EINVAL);
54200+ }
54201+
54202+ srcflow.u.v4.sin_family = AF_INET;
54203+ dstflow.u.v4.sin_family = AF_INET;
54204+ srcmask.u.v4.sin_family = AF_INET;
54205+ dstmask.u.v4.sin_family = AF_INET;
54206+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
54207+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
54208+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
54209+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
54210+
54211+#ifdef CONFIG_KLIPS_DEBUG
54212+ if (debug_pfkey) {
54213+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
54214+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
54215+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
54216+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
54217+ KLIPS_PRINT(debug_pfkey,
54218+ "klips_debug:pfkey_x_addflow_parse: "
54219+ "calling breakeroute and/or makeroute for %s->%s\n",
54220+ buf1, buf2);
54221+ }
54222+#endif /* CONFIG_KLIPS_DEBUG */
54223+
54224+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
54225+ struct ipsec_sa *ipsp, *ipsq;
54226+ char sa[SATOT_BUF];
54227+ size_t sa_len;
54228+
54229+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
54230+ if(ipsq == NULL) {
54231+ KLIPS_PRINT(debug_pfkey,
54232+ "klips_debug:pfkey_x_addflow_parse: "
54233+ "ipsec_sa not found, cannot set incoming policy.\n");
54234+ SENDERR(ENOENT);
54235+ }
54236+
54237+ ipsp = ipsq;
54238+ while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
54239+ ipsp = ipsp->ips_inext;
54240+ }
54241+
54242+ if(ipsp == NULL) {
54243+ ipsec_sa_put(ipsq);
54244+ KLIPS_PRINT(debug_pfkey,
54245+ "klips_debug:pfkey_x_addflow_parse: "
54246+ "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
54247+ SENDERR(ENOENT);
54248+ }
54249+
54250+ sa_len = KLIPS_SATOT(debug_pfkey, &extr->ips->ips_said, 0, sa, sizeof(sa));
54251+
54252+ ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
54253+ ipsp->ips_flow_s = srcflow;
54254+ ipsp->ips_flow_d = dstflow;
54255+ ipsp->ips_mask_s = srcmask;
54256+ ipsp->ips_mask_d = dstmask;
54257+
54258+ ipsec_sa_put(ipsq);
54259+
54260+ KLIPS_PRINT(debug_pfkey,
54261+ "klips_debug:pfkey_x_addflow_parse: "
54262+ "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
54263+ sa_len ? sa : " (error)");
54264+ } else {
54265+ struct sk_buff *first = NULL, *last = NULL;
54266+
54267+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
54268+ KLIPS_PRINT(debug_pfkey,
54269+ "klips_debug:pfkey_x_addflow_parse: "
54270+ "REPLACEFLOW flag set, calling breakeroute.\n");
54271+ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
54272+ &(extr->eroute->er_emask),
54273+ &first, &last))) {
54274+ KLIPS_PRINT(debug_pfkey,
54275+ "klips_debug:pfkey_x_addflow_parse: "
54276+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
54277+ error,
54278+ first,
54279+ last);
54280+ if(first != NULL) {
54281+ ipsec_kfree_skb(first);
54282+ }
54283+ if(last != NULL) {
54284+ ipsec_kfree_skb(last);
54285+ }
54286+ SENDERR(-error);
54287+ }
54288+ }
54289+
54290+ KLIPS_PRINT(debug_pfkey,
54291+ "klips_debug:pfkey_x_addflow_parse: "
54292+ "calling makeroute.\n");
54293+
54294+ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
54295+ &(extr->eroute->er_emask),
54296+ extr->ips->ips_said,
54297+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
54298+ NULL,
54299+ &(extr->ips->ips_ident_s),
54300+ &(extr->ips->ips_ident_d)))) {
54301+ KLIPS_PRINT(debug_pfkey,
54302+ "klips_debug:pfkey_x_addflow_parse: "
54303+ "makeroute returned %d.\n", error);
54304+ SENDERR(-error);
54305+ }
54306+ if(first != NULL) {
54307+ KLIPS_PRINT(debug_eroute,
54308+ "klips_debug:pfkey_x_addflow_parse: "
54309+ "first=0p%p HOLD packet re-injected.\n",
54310+ first);
54311+ DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL);
54312+ }
54313+ if(last != NULL) {
54314+ KLIPS_PRINT(debug_eroute,
54315+ "klips_debug:pfkey_x_addflow_parse: "
54316+ "last=0p%p HOLD packet re-injected.\n",
54317+ last);
54318+ DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL);
54319+ }
54320+ }
54321+
54322+ KLIPS_PRINT(debug_pfkey,
54323+ "klips_debug:pfkey_x_addflow_parse: "
54324+ "makeroute call successful.\n");
54325+
54326+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
54327+ SADB_X_ADDFLOW,
54328+ satype,
54329+ 0,
54330+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
54331+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
54332+ extensions_reply)
54333+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
54334+ SADB_EXT_SA,
54335+ extr->ips->ips_said.spi,
54336+ extr->ips->ips_replaywin,
54337+ extr->ips->ips_state,
54338+ extr->ips->ips_authalg,
54339+ extr->ips->ips_encalg,
54340+ extr->ips->ips_flags,
54341+ extr->ips->ips_ref),
54342+ extensions_reply)
54343+ && (extensions[SADB_EXT_ADDRESS_SRC]
54344+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
54345+ SADB_EXT_ADDRESS_SRC,
54346+ 0, /*extr->ips->ips_said.proto,*/
54347+ 0,
54348+ extr->ips->ips_addr_s),
54349+ extensions_reply) : 1)
54350+ && (extensions[SADB_EXT_ADDRESS_DST]
54351+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
54352+ SADB_EXT_ADDRESS_DST,
54353+ 0, /*extr->ips->ips_said.proto,*/
54354+ 0,
54355+ extr->ips->ips_addr_d),
54356+ extensions_reply) : 1)
54357+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
54358+ SADB_X_EXT_ADDRESS_SRC_FLOW,
54359+ 0, /*extr->ips->ips_said.proto,*/
54360+ 0,
54361+ (struct sockaddr*)&srcflow),
54362+ extensions_reply)
54363+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
54364+ SADB_X_EXT_ADDRESS_DST_FLOW,
54365+ 0, /*extr->ips->ips_said.proto,*/
54366+ 0,
54367+ (struct sockaddr*)&dstflow),
54368+ extensions_reply)
54369+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
54370+ SADB_X_EXT_ADDRESS_SRC_MASK,
54371+ 0, /*extr->ips->ips_said.proto,*/
54372+ 0,
54373+ (struct sockaddr*)&srcmask),
54374+ extensions_reply)
54375+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
54376+ SADB_X_EXT_ADDRESS_DST_MASK,
54377+ 0, /*extr->ips->ips_said.proto,*/
54378+ 0,
54379+ (struct sockaddr*)&dstmask),
54380+ extensions_reply)
54381+ )) {
54382+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54383+ "failed to build the x_addflow reply message extensions\n");
54384+ SENDERR(-error);
54385+ }
54386+
54387+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
54388+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54389+ "failed to build the x_addflow reply message\n");
54390+ SENDERR(-error);
54391+ }
54392+
54393+ for(pfkey_socketsp = pfkey_open_sockets;
54394+ pfkey_socketsp;
54395+ pfkey_socketsp = pfkey_socketsp->next) {
54396+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
54397+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54398+ "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54399+ satype,
54400+ satype2name(satype),
54401+ pfkey_socketsp->socketp,
54402+ error);
54403+ SENDERR(-error);
54404+ }
54405+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54406+ "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
54407+ satype,
54408+ satype2name(satype),
54409+ extr->ips->ips_said.proto,
54410+ pfkey_socketsp->socketp);
54411+ }
54412+
54413+ KLIPS_PRINT(debug_pfkey,
54414+ "klips_debug:pfkey_x_addflow_parse: "
54415+ "extr->ips cleaned up and freed.\n");
54416+
54417+ errlab:
54418+ if (pfkey_reply) {
54419+ pfkey_msg_free(&pfkey_reply);
54420+ }
54421+ pfkey_extensions_free(extensions_reply);
54422+ return error;
54423+}
54424+
54425+DEBUG_NO_STATIC int
54426+pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54427+{
54428+ int error = 0;
54429+#ifdef CONFIG_KLIPS_DEBUG
54430+ char buf1[64], buf2[64];
54431+#endif /* CONFIG_KLIPS_DEBUG */
54432+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
54433+ struct sadb_msg *pfkey_reply = NULL;
54434+ struct socket_list *pfkey_socketsp;
54435+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
54436+ ip_address srcflow, dstflow, srcmask, dstmask;
54437+
54438+ KLIPS_PRINT(debug_pfkey,
54439+ "klips_debug:pfkey_x_delflow_parse: .\n");
54440+
54441+ pfkey_extensions_init(extensions_reply);
54442+
54443+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
54444+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
54445+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
54446+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
54447+
54448+ if(!extr || !(extr->ips)) {
54449+ KLIPS_PRINT(debug_pfkey,
54450+ "klips_debug:pfkey_x_delflow_parse: "
54451+ "extr, or extr->ips is NULL, fatal\n");
54452+ SENDERR(EINVAL);
54453+ }
54454+
54455+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
54456+ KLIPS_PRINT(debug_pfkey,
54457+ "klips_debug:pfkey_x_delflow_parse: "
54458+ "CLEARFLOW flag set, calling cleareroutes.\n");
54459+ if ((error = ipsec_cleareroutes()))
54460+ KLIPS_PRINT(debug_pfkey,
54461+ "klips_debug:pfkey_x_delflow_parse: "
54462+ "cleareroutes returned %d.\n", error);
54463+ SENDERR(-error);
54464+ } else {
54465+ struct sk_buff *first = NULL, *last = NULL;
54466+
54467+ if(!(extr->eroute)) {
54468+ KLIPS_PRINT(debug_pfkey,
54469+ "klips_debug:pfkey_x_delflow_parse: "
54470+ "extr->eroute is NULL, fatal.\n");
54471+ SENDERR(EINVAL);
54472+ }
54473+
54474+ srcflow.u.v4.sin_family = AF_INET;
54475+ dstflow.u.v4.sin_family = AF_INET;
54476+ srcmask.u.v4.sin_family = AF_INET;
54477+ dstmask.u.v4.sin_family = AF_INET;
54478+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
54479+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
54480+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
54481+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
54482+
54483+#ifdef CONFIG_KLIPS_DEBUG
54484+ if (debug_pfkey) {
54485+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
54486+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
54487+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
54488+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
54489+ KLIPS_PRINT(debug_pfkey,
54490+ "klips_debug:pfkey_x_delflow_parse: "
54491+ "calling breakeroute for %s->%s\n",
54492+ buf1, buf2);
54493+ }
54494+#endif /* CONFIG_KLIPS_DEBUG */
54495+ error = ipsec_breakroute(&(extr->eroute->er_eaddr),
54496+ &(extr->eroute->er_emask),
54497+ &first, &last);
54498+ if(error) {
54499+ KLIPS_PRINT(debug_pfkey,
54500+ "klips_debug:pfkey_x_delflow_parse: "
54501+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
54502+ error,
54503+ first,
54504+ last);
54505+ }
54506+ if(first != NULL) {
54507+ ipsec_kfree_skb(first);
54508+ }
54509+ if(last != NULL) {
54510+ ipsec_kfree_skb(last);
54511+ }
54512+ if(error) {
54513+ SENDERR(-error);
54514+ }
54515+ }
54516+
54517+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
54518+ SADB_X_DELFLOW,
54519+ satype,
54520+ 0,
54521+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
54522+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
54523+ extensions_reply)
54524+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
54525+ SADB_EXT_SA,
54526+ extr->ips->ips_said.spi,
54527+ extr->ips->ips_replaywin,
54528+ extr->ips->ips_state,
54529+ extr->ips->ips_authalg,
54530+ extr->ips->ips_encalg,
54531+ extr->ips->ips_flags,
54532+ extr->ips->ips_ref),
54533+ extensions_reply)
54534+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
54535+ SADB_X_EXT_ADDRESS_SRC_FLOW,
54536+ 0, /*extr->ips->ips_said.proto,*/
54537+ 0,
54538+ (struct sockaddr*)&srcflow),
54539+ extensions_reply)
54540+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
54541+ SADB_X_EXT_ADDRESS_DST_FLOW,
54542+ 0, /*extr->ips->ips_said.proto,*/
54543+ 0,
54544+ (struct sockaddr*)&dstflow),
54545+ extensions_reply)
54546+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
54547+ SADB_X_EXT_ADDRESS_SRC_MASK,
54548+ 0, /*extr->ips->ips_said.proto,*/
54549+ 0,
54550+ (struct sockaddr*)&srcmask),
54551+ extensions_reply)
54552+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
54553+ SADB_X_EXT_ADDRESS_DST_MASK,
54554+ 0, /*extr->ips->ips_said.proto,*/
54555+ 0,
54556+ (struct sockaddr*)&dstmask),
54557+ extensions_reply)
54558+ )) {
54559+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54560+ "failed to build the x_delflow reply message extensions\n");
54561+ SENDERR(-error);
54562+ }
54563+
54564+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
54565+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54566+ "failed to build the x_delflow reply message\n");
54567+ SENDERR(-error);
54568+ }
54569+
54570+ for(pfkey_socketsp = pfkey_open_sockets;
54571+ pfkey_socketsp;
54572+ pfkey_socketsp = pfkey_socketsp->next) {
54573+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
54574+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54575+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54576+ satype,
54577+ satype2name(satype),
54578+ pfkey_socketsp->socketp,
54579+ error);
54580+ SENDERR(-error);
54581+ }
54582+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54583+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
54584+ satype,
54585+ satype2name(satype),
54586+ pfkey_socketsp->socketp);
54587+ }
54588+
54589+ KLIPS_PRINT(debug_pfkey,
54590+ "klips_debug:pfkey_x_delflow_parse: "
54591+ "extr->ips cleaned up and freed.\n");
54592+
54593+ errlab:
54594+ if (pfkey_reply) {
54595+ pfkey_msg_free(&pfkey_reply);
54596+ }
54597+ pfkey_extensions_free(extensions_reply);
54598+ return error;
54599+}
54600+
54601+DEBUG_NO_STATIC int
54602+pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54603+{
54604+ int error = 0;
54605+
54606+ KLIPS_PRINT(debug_pfkey,
54607+ "klips_debug:pfkey_x_msg_debug_parse: .\n");
54608+
54609+/* errlab:*/
54610+ return error;
54611+}
54612+
54613+/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
54614+int
54615+pfkey_expire(struct ipsec_sa *ipsp, int hard)
54616+{
54617+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54618+ struct sadb_msg *pfkey_msg = NULL;
54619+ struct socket_list *pfkey_socketsp;
54620+ int error = 0;
54621+ uint8_t satype;
54622+
54623+ pfkey_extensions_init(extensions);
54624+
54625+ if(!(satype = proto2satype(ipsp->ips_said.proto))) {
54626+ KLIPS_PRINT(debug_pfkey,
54627+ "klips_debug:pfkey_expire: "
54628+ "satype lookup for protocol %d lookup failed.\n",
54629+ ipsp->ips_said.proto);
54630+ SENDERR(EINVAL);
54631+ }
54632+
54633+ if(!pfkey_open_sockets) {
54634+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54635+ "no sockets listening.\n");
54636+ SENDERR(EPROTONOSUPPORT);
54637+ }
54638+
54639+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
54640+ SADB_EXPIRE,
54641+ satype,
54642+ 0,
54643+ ++pfkey_msg_seq,
54644+ 0),
54645+ extensions)
54646+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
54647+ SADB_EXT_SA,
54648+ ipsp->ips_said.spi,
54649+ ipsp->ips_replaywin,
54650+ ipsp->ips_state,
54651+ ipsp->ips_authalg,
54652+ ipsp->ips_encalg,
54653+ ipsp->ips_flags,
54654+ ipsp->ips_ref),
54655+ extensions)
54656+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
54657+ SADB_EXT_LIFETIME_CURRENT,
54658+ ipsp->ips_life.ipl_allocations.ipl_count,
54659+ ipsp->ips_life.ipl_bytes.ipl_count,
54660+ ipsp->ips_life.ipl_addtime.ipl_count,
54661+ ipsp->ips_life.ipl_usetime.ipl_count,
54662+ ipsp->ips_life.ipl_packets.ipl_count),
54663+ extensions)
54664+ && (hard ?
54665+ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
54666+ SADB_EXT_LIFETIME_HARD,
54667+ ipsp->ips_life.ipl_allocations.ipl_hard,
54668+ ipsp->ips_life.ipl_bytes.ipl_hard,
54669+ ipsp->ips_life.ipl_addtime.ipl_hard,
54670+ ipsp->ips_life.ipl_usetime.ipl_hard,
54671+ ipsp->ips_life.ipl_packets.ipl_hard),
54672+ extensions)
54673+ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
54674+ SADB_EXT_LIFETIME_SOFT,
54675+ ipsp->ips_life.ipl_allocations.ipl_soft,
54676+ ipsp->ips_life.ipl_bytes.ipl_soft,
54677+ ipsp->ips_life.ipl_addtime.ipl_soft,
54678+ ipsp->ips_life.ipl_usetime.ipl_soft,
54679+ ipsp->ips_life.ipl_packets.ipl_soft),
54680+ extensions))
54681+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54682+ SADB_EXT_ADDRESS_SRC,
54683+ 0, /* ipsp->ips_said.proto, */
54684+ 0,
54685+ ipsp->ips_addr_s),
54686+ extensions)
54687+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54688+ SADB_EXT_ADDRESS_DST,
54689+ 0, /* ipsp->ips_said.proto, */
54690+ 0,
54691+ ipsp->ips_addr_d),
54692+ extensions))) {
54693+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54694+ "failed to build the expire message extensions\n");
54695+ spin_unlock(&tdb_lock);
54696+ goto errlab;
54697+ }
54698+
54699+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54700+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54701+ "failed to build the expire message\n");
54702+ SENDERR(-error);
54703+ }
54704+
54705+ for(pfkey_socketsp = pfkey_open_sockets;
54706+ pfkey_socketsp;
54707+ pfkey_socketsp = pfkey_socketsp->next) {
54708+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54709+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54710+ "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54711+ satype,
54712+ satype2name(satype),
54713+ pfkey_socketsp->socketp,
54714+ error);
54715+ SENDERR(-error);
54716+ }
54717+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54718+ "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
54719+ satype,
54720+ satype2name(satype),
54721+ ipsp->ips_said.proto,
54722+ pfkey_socketsp->socketp);
54723+ }
54724+
54725+ errlab:
54726+ if (pfkey_msg) {
54727+ pfkey_msg_free(&pfkey_msg);
54728+ }
54729+ pfkey_extensions_free(extensions);
54730+ return error;
54731+}
54732+
54733+int
54734+pfkey_acquire(struct ipsec_sa *ipsp)
54735+{
54736+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54737+ struct sadb_msg *pfkey_msg = NULL;
54738+ struct socket_list *pfkey_socketsp;
54739+ int error = 0;
54740+ struct sadb_comb comb[] = {
54741+ /* auth; encrypt; flags; */
54742+ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
54743+ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
54744+ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
54745+ /* soft_packets; hard_packets; */
54746+ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
54747+ 128, 128, 168, 168,
54748+ 0, 0, 0, 0, 0,
54749+ 57600, 86400, 57600, 86400,
54750+ 0, 0 },
54751+ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
54752+ 160, 160, 168, 168,
54753+ 0, 0, 0, 0, 0,
54754+ 57600, 86400, 57600, 86400,
54755+ 0, 0 }
54756+ };
54757+
54758+ /* XXX This should not be hard-coded. It should be taken from the spdb */
54759+ uint8_t satype = SADB_SATYPE_ESP;
54760+
54761+ pfkey_extensions_init(extensions);
54762+
54763+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
54764+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
54765+ "SAtype=%d unspecified or unknown.\n",
54766+ satype);
54767+ SENDERR(EINVAL);
54768+ }
54769+
54770+ if(!(pfkey_registered_sockets[satype])) {
54771+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54772+ "no sockets registered for SAtype=%d(%s).\n",
54773+ satype,
54774+ satype2name(satype));
54775+ SENDERR(EPROTONOSUPPORT);
54776+ }
54777+
54778+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
54779+ SADB_ACQUIRE,
54780+ satype,
54781+ 0,
54782+ ++pfkey_msg_seq,
54783+ 0),
54784+ extensions)
54785+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54786+ SADB_EXT_ADDRESS_SRC,
54787+ ipsp->ips_transport_protocol,
54788+ 0,
54789+ ipsp->ips_addr_s),
54790+ extensions)
54791+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54792+ SADB_EXT_ADDRESS_DST,
54793+ ipsp->ips_transport_protocol,
54794+ 0,
54795+ ipsp->ips_addr_d),
54796+ extensions)
54797+#if 0
54798+ && (ipsp->ips_addr_p
54799+ ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
54800+ SADB_EXT_ADDRESS_PROXY,
54801+ ipsp->ips_transport_protocol,
54802+ 0,
54803+ ipsp->ips_addr_p),
54804+ extensions) : 1)
54805+#endif
54806+ && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
54807+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
54808+ SADB_EXT_IDENTITY_SRC,
54809+ ipsp->ips_ident_s.type,
54810+ ipsp->ips_ident_s.id,
54811+ ipsp->ips_ident_s.len,
54812+ ipsp->ips_ident_s.data),
54813+ extensions) : 1)
54814+
54815+ && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
54816+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
54817+ SADB_EXT_IDENTITY_DST,
54818+ ipsp->ips_ident_d.type,
54819+ ipsp->ips_ident_d.id,
54820+ ipsp->ips_ident_d.len,
54821+ ipsp->ips_ident_d.data),
54822+ extensions) : 1)
54823+#if 0
54824+ /* FIXME: This won't work yet because I have not finished
54825+ it. */
54826+ && (ipsp->ips_sens_
54827+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
54828+ ipsp->ips_sens_dpd,
54829+ ipsp->ips_sens_sens_level,
54830+ ipsp->ips_sens_sens_len,
54831+ ipsp->ips_sens_sens_bitmap,
54832+ ipsp->ips_sens_integ_level,
54833+ ipsp->ips_sens_integ_len,
54834+ ipsp->ips_sens_integ_bitmap),
54835+ extensions) : 1)
54836+#endif
54837+ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
54838+ 64, /* replay */
54839+ sizeof(comb)/sizeof(struct sadb_comb),
54840+ &(comb[0])),
54841+ extensions)
54842+ )) {
54843+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54844+ "failed to build the acquire message extensions\n");
54845+ SENDERR(-error);
54846+ }
54847+
54848+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54849+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54850+ "failed to build the acquire message\n");
54851+ SENDERR(-error);
54852+ }
54853+
54854+#ifdef KLIPS_PFKEY_ACQUIRE_LOSSAGE
54855+# if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
54856+ if(sysctl_ipsec_regress_pfkey_lossage) {
54857+ return(0);
54858+ }
54859+# endif
54860+#endif
54861+
54862+ /* this should go to all registered sockets for that satype only */
54863+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
54864+ pfkey_socketsp;
54865+ pfkey_socketsp = pfkey_socketsp->next) {
54866+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54867+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54868+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54869+ satype,
54870+ satype2name(satype),
54871+ pfkey_socketsp->socketp,
54872+ error);
54873+ SENDERR(-error);
54874+ }
54875+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
54876+ "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
54877+ satype,
54878+ satype2name(satype),
54879+ pfkey_socketsp->socketp);
54880+ }
54881+
54882+ errlab:
54883+ if (pfkey_msg) {
54884+ pfkey_msg_free(&pfkey_msg);
54885+ }
54886+ pfkey_extensions_free(extensions);
54887+ return error;
54888+}
54889+
54890+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54891+int
54892+pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr,
54893+ __u16 sport)
54894+{
54895+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
54896+ struct sadb_msg *pfkey_msg = NULL;
54897+ struct socket_list *pfkey_socketsp;
54898+ int error = 0;
54899+ uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0;
54900+
54901+ /* Construct SADB_X_NAT_T_NEW_MAPPING message */
54902+
54903+ pfkey_extensions_init(extensions);
54904+
54905+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
54906+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54907+ "SAtype=%d unspecified or unknown.\n",
54908+ satype);
54909+ SENDERR(EINVAL);
54910+ }
54911+
54912+ if(!(pfkey_registered_sockets[satype])) {
54913+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54914+ "no sockets registered for SAtype=%d(%s).\n",
54915+ satype,
54916+ satype2name(satype));
54917+ SENDERR(EPROTONOSUPPORT);
54918+ }
54919+
54920+ if (!(pfkey_safe_build
54921+ (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING,
54922+ satype, 0, ++pfkey_msg_seq, 0), extensions)
54923+ /* SA */
54924+ && pfkey_safe_build
54925+ (error = pfkey_sa_build(&extensions[SADB_EXT_SA],
54926+ SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions)
54927+ /* ADDRESS_SRC = old addr */
54928+ && pfkey_safe_build
54929+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54930+ SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s),
54931+ extensions)
54932+ /* NAT_T_SPORT = old port */
54933+ && pfkey_safe_build
54934+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT],
54935+ SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions)
54936+ /* ADDRESS_DST = new addr */
54937+ && pfkey_safe_build
54938+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54939+ SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions)
54940+ /* NAT_T_DPORT = new port */
54941+ && pfkey_safe_build
54942+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT],
54943+ SADB_X_EXT_NAT_T_DPORT, sport), extensions)
54944+ )) {
54945+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54946+ "failed to build the nat_t_new_mapping message extensions\n");
54947+ SENDERR(-error);
54948+ }
54949+
54950+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54951+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54952+ "failed to build the nat_t_new_mapping message\n");
54953+ SENDERR(-error);
54954+ }
54955+
54956+ /* this should go to all registered sockets for that satype only */
54957+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
54958+ pfkey_socketsp;
54959+ pfkey_socketsp = pfkey_socketsp->next) {
54960+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54961+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54962+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
54963+ satype,
54964+ satype2name(satype),
54965+ pfkey_socketsp->socketp,
54966+ error);
54967+ SENDERR(-error);
54968+ }
54969+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54970+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
54971+ satype,
54972+ satype2name(satype),
54973+ pfkey_socketsp->socketp);
54974+ }
54975+
54976+ errlab:
54977+ if (pfkey_msg) {
54978+ pfkey_msg_free(&pfkey_msg);
54979+ }
54980+ pfkey_extensions_free(extensions);
54981+ return error;
54982+}
54983+
54984+DEBUG_NO_STATIC int
54985+pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54986+{
54987+ /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */
54988+ return -EINVAL;
54989+}
54990+#endif
54991+
54992+DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
54993+{
54994+ NULL, /* pfkey_msg_process, */
54995+ pfkey_sa_process,
54996+ pfkey_lifetime_process,
54997+ pfkey_lifetime_process,
54998+ pfkey_lifetime_process,
54999+ pfkey_address_process,
55000+ pfkey_address_process,
55001+ pfkey_address_process,
55002+ pfkey_key_process,
55003+ pfkey_key_process,
55004+ pfkey_ident_process,
55005+ pfkey_ident_process,
55006+ pfkey_sens_process,
55007+ pfkey_prop_process,
55008+ pfkey_supported_process,
55009+ pfkey_supported_process,
55010+ pfkey_spirange_process,
55011+ pfkey_x_kmprivate_process,
55012+ pfkey_x_satype_process,
55013+ pfkey_sa_process,
55014+ pfkey_address_process,
55015+ pfkey_address_process,
55016+ pfkey_address_process,
55017+ pfkey_address_process,
55018+ pfkey_address_process,
55019+ pfkey_x_debug_process,
55020+ pfkey_x_protocol_process
55021+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
55022+ ,
55023+ pfkey_x_nat_t_type_process,
55024+ pfkey_x_nat_t_port_process,
55025+ pfkey_x_nat_t_port_process,
55026+ pfkey_address_process
55027+#endif
55028+};
55029+
55030+
55031+DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
55032+ =
55033+{
55034+ NULL, /* RESERVED */
55035+ pfkey_getspi_parse,
55036+ pfkey_update_parse,
55037+ pfkey_add_parse,
55038+ pfkey_delete_parse,
55039+ pfkey_get_parse,
55040+ pfkey_acquire_parse,
55041+ pfkey_register_parse,
55042+ pfkey_expire_parse,
55043+ pfkey_flush_parse,
55044+ pfkey_dump_parse,
55045+ pfkey_x_promisc_parse,
55046+ pfkey_x_pchange_parse,
55047+ pfkey_x_grpsa_parse,
55048+ pfkey_x_addflow_parse,
55049+ pfkey_x_delflow_parse,
55050+ pfkey_x_msg_debug_parse
55051+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
55052+ , pfkey_x_nat_t_new_mapping_parse
55053+#endif
55054+};
55055+
55056+int
55057+pfkey_build_reply(struct sadb_msg *pfkey_msg,
55058+ struct pfkey_extracted_data *extr,
55059+ struct sadb_msg **pfkey_reply)
55060+{
55061+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
55062+ int error = 0;
55063+ int msg_type = pfkey_msg->sadb_msg_type;
55064+ int seq = pfkey_msg->sadb_msg_seq;
55065+
55066+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
55067+ "building reply with type: %d\n",
55068+ msg_type);
55069+ pfkey_extensions_init(extensions);
55070+ if (!extr || !extr->ips) {
55071+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
55072+ "bad ipsec_sa passed\n");
55073+ return EINVAL;
55074+ }
55075+ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
55076+ msg_type,
55077+ proto2satype(extr->ips->ips_said.proto),
55078+ 0,
55079+ seq,
55080+ pfkey_msg->sadb_msg_pid),
55081+ extensions) &&
55082+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
55083+ 1 << SADB_EXT_SA)
55084+ || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
55085+ SADB_EXT_SA,
55086+ extr->ips->ips_said.spi,
55087+ extr->ips->ips_replaywin,
55088+ extr->ips->ips_state,
55089+ extr->ips->ips_authalg,
55090+ extr->ips->ips_encalg,
55091+ extr->ips->ips_flags,
55092+ extr->ips->ips_ref),
55093+ extensions)) &&
55094+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
55095+ 1 << SADB_EXT_LIFETIME_CURRENT)
55096+ || pfkey_safe_build(pfkey_lifetime_build(&extensions
55097+ [SADB_EXT_LIFETIME_CURRENT],
55098+ SADB_EXT_LIFETIME_CURRENT,
55099+ extr->ips->ips_life.ipl_allocations.ipl_count,
55100+ extr->ips->ips_life.ipl_bytes.ipl_count,
55101+ extr->ips->ips_life.ipl_addtime.ipl_count,
55102+ extr->ips->ips_life.ipl_usetime.ipl_count,
55103+ extr->ips->ips_life.ipl_packets.ipl_count),
55104+ extensions)) &&
55105+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
55106+ 1 << SADB_EXT_ADDRESS_SRC)
55107+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
55108+ SADB_EXT_ADDRESS_SRC,
55109+ extr->ips->ips_said.proto,
55110+ 0,
55111+ extr->ips->ips_addr_s),
55112+ extensions)) &&
55113+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
55114+ 1 << SADB_EXT_ADDRESS_DST)
55115+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
55116+ SADB_EXT_ADDRESS_DST,
55117+ extr->ips->ips_said.proto,
55118+ 0,
55119+ extr->ips->ips_addr_d),
55120+ extensions));
55121+
55122+ if (error == 0) {
55123+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
55124+ "building extensions failed\n");
55125+ return EINVAL;
55126+ }
55127+
55128+ KLIPS_PRINT(debug_pfkey,
55129+ "klips_debug:pfkey_build_reply: "
55130+ "built extensions, proceed to build the message\n");
55131+ KLIPS_PRINT(debug_pfkey,
55132+ "klips_debug:pfkey_build_reply: "
55133+ "extensions[1]=0p%p\n",
55134+ extensions[1]);
55135+ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
55136+ pfkey_extensions_free(extensions);
55137+
55138+ return error;
55139+}
55140+
55141+int
55142+pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
55143+ struct sadb_msg **pfkey_reply)
55144+{
55145+ int error = 0;
55146+ int i;
55147+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
55148+ struct pfkey_extracted_data extr = {NULL, NULL, NULL};
55149+
55150+ pfkey_extensions_init(extensions);
55151+ KLIPS_PRINT(debug_pfkey,
55152+ "klips_debug:pfkey_msg_interp: "
55153+ "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
55154+ pfkey_msg->sadb_msg_version,
55155+ pfkey_msg->sadb_msg_type,
55156+ pfkey_msg->sadb_msg_errno,
55157+ pfkey_msg->sadb_msg_satype,
55158+ satype2name(pfkey_msg->sadb_msg_satype),
55159+ pfkey_msg->sadb_msg_len,
55160+ pfkey_msg->sadb_msg_reserved,
55161+ pfkey_msg->sadb_msg_seq,
55162+ pfkey_msg->sadb_msg_pid);
55163+
55164+ extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
55165+ if(extr.ips == NULL) {
55166+ KLIPS_PRINT(debug_pfkey,
55167+ "klips_debug:pfkey_msg_interp: "
55168+ "memory allocation error.\n");
55169+ SENDERR(-error);
55170+ }
55171+
55172+ KLIPS_PRINT(debug_pfkey,
55173+ "klips_debug:pfkey_msg_interp: "
55174+ "allocated extr->ips=0p%p.\n",
55175+ extr.ips);
55176+
55177+ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
55178+ KLIPS_PRINT(debug_pfkey,
55179+ "klips_debug:pfkey_msg_interp: "
55180+ "satype %d > max %d\n",
55181+ pfkey_msg->sadb_msg_satype,
55182+ SADB_SATYPE_MAX);
55183+ SENDERR(EINVAL);
55184+ }
55185+
55186+ switch(pfkey_msg->sadb_msg_type) {
55187+ case SADB_GETSPI:
55188+ case SADB_UPDATE:
55189+ case SADB_ADD:
55190+ case SADB_DELETE:
55191+ case SADB_X_GRPSA:
55192+ case SADB_X_ADDFLOW:
55193+ if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
55194+ KLIPS_PRINT(debug_pfkey,
55195+ "klips_debug:pfkey_msg_interp: "
55196+ "satype %d lookup failed.\n",
55197+ pfkey_msg->sadb_msg_satype);
55198+ SENDERR(EINVAL);
55199+ } else {
55200+ KLIPS_PRINT(debug_pfkey,
55201+ "klips_debug:pfkey_msg_interp: "
55202+ "satype %d lookups to proto=%d.\n",
55203+ pfkey_msg->sadb_msg_satype,
55204+ extr.ips->ips_said.proto);
55205+ }
55206+ break;
55207+ default:
55208+ break;
55209+ }
55210+
55211+ /* The NULL below causes the default extension parsers to be used */
55212+ /* Parse the extensions */
55213+ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
55214+ {
55215+ KLIPS_PRINT(debug_pfkey,
55216+ "klips_debug:pfkey_msg_interp: "
55217+ "message parsing failed with error %d.\n",
55218+ error);
55219+ SENDERR(-error);
55220+ }
55221+
55222+ /* Process the extensions */
55223+ for(i=1; i <= SADB_EXT_MAX;i++) {
55224+ if(extensions[i] != NULL) {
55225+ KLIPS_PRINT(debug_pfkey,
55226+ "klips_debug:pfkey_msg_interp: "
55227+ "processing ext %d 0p%p with processor 0p%p.\n",
55228+ i, extensions[i], ext_processors[i]);
55229+ if((error = ext_processors[i](extensions[i], &extr))) {
55230+ KLIPS_PRINT(debug_pfkey,
55231+ "klips_debug:pfkey_msg_interp: "
55232+ "extension processing for type %d failed with error %d.\n",
55233+ i,
55234+ error);
55235+ SENDERR(-error);
55236+ }
55237+
55238+ }
55239+
55240+ }
55241+
55242+ /* Parse the message types */
55243+ KLIPS_PRINT(debug_pfkey,
55244+ "klips_debug:pfkey_msg_interp: "
55245+ "parsing message type %d(%s) with msg_parser 0p%p.\n",
55246+ pfkey_msg->sadb_msg_type,
55247+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
55248+ msg_parsers[pfkey_msg->sadb_msg_type]);
55249+ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
55250+ KLIPS_PRINT(debug_pfkey,
55251+ "klips_debug:pfkey_msg_interp: "
55252+ "message parsing failed with error %d.\n",
55253+ error);
55254+ SENDERR(-error);
55255+ }
55256+
55257+#if 0
55258+ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
55259+ if (error) {
55260+ *pfkey_reply = NULL;
55261+ }
55262+#endif
55263+ errlab:
55264+ if(extr.ips != NULL) {
55265+ ipsec_sa_wipe(extr.ips);
55266+ }
55267+ if(extr.ips2 != NULL) {
55268+ ipsec_sa_wipe(extr.ips2);
55269+ }
55270+ if (extr.eroute != NULL) {
55271+ kfree(extr.eroute);
55272+ }
55273+ return(error);
55274+}
55275+
55276+/*
55277+ * $Log: pfkey_v2_parser.c,v $
55278+ * Revision 1.134.2.4 2007-10-30 21:40:36 paul
55279+ * Fix for KLIPS_PFKEY_ACQUIRE_LOSSAGE [dhr]
55280+ *
55281+ * Revision 1.134.2.3 2007/09/05 02:56:10 paul
55282+ * Use the new ipsec_kversion macros by David to deal with 2.6.22 kernels.
55283+ * Fixes based on David McCullough patch.
55284+ *
55285+ * Revision 1.134.2.2 2006/10/06 21:39:26 paul
55286+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
55287+ * set. This is defined through autoconf.h which is included through the
55288+ * linux kernel build macros.
55289+ *
55290+ * Revision 1.134.2.1 2006/05/01 14:37:25 mcr
55291+ * ip_chk_addr -> inet_addr_type for more direct 2.4/2.6 support.
55292+ *
55293+ * Revision 1.134 2005/05/11 01:48:20 mcr
55294+ * removed "poor-man"s OOP in favour of proper C structures.
55295+ *
55296+ * Revision 1.133 2005/04/29 05:10:22 mcr
55297+ * removed from extraenous includes to make unit testing easier.
55298+ *
55299+ * Revision 1.132 2005/04/14 20:56:24 mcr
55300+ * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
55301+ *
55302+ * Revision 1.131 2005/01/26 00:50:35 mcr
55303+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
55304+ * and make sure that NAT_TRAVERSAL is set as well to match
55305+ * userspace compiles of code.
55306+ *
55307+ * Revision 1.130 2004/09/08 17:21:36 ken
55308+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
55309+ *
55310+ * Revision 1.129 2004/09/06 18:36:30 mcr
55311+ * if a protocol can not be found, then log it. This is not
55312+ * debugging.
55313+ *
55314+ * Revision 1.128 2004/08/21 00:45:19 mcr
55315+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
55316+ *
55317+ * Revision 1.127 2004/08/20 21:45:45 mcr
55318+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
55319+ * be 26sec compatible. But, some defines where changed.
55320+ *
55321+ * Revision 1.126 2004/08/17 03:27:23 mcr
55322+ * klips 2.6 edits.
55323+ *
55324+ * Revision 1.125 2004/08/04 15:57:07 mcr
55325+ * moved des .h files to include/des/ *
55326+ * included 2.6 protocol specific things
55327+ * started at NAT-T support, but it will require a kernel patch.
55328+ *
55329+ * Revision 1.124 2004/07/10 19:11:18 mcr
55330+ * CONFIG_IPSEC -> CONFIG_KLIPS.
55331+ *
55332+ * Revision 1.123 2004/04/06 02:49:26 mcr
55333+ * pullup of algo code from alg-branch.
55334+ *
55335+ * Revision 1.122.2.2 2004/04/05 04:30:46 mcr
55336+ * patches for alg-branch to compile/work with 2.x openswan
55337+ *
55338+ * Revision 1.122.2.1 2003/12/22 15:25:52 jjo
55339+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
55340+ *
55341+ * Revision 1.122 2003/12/10 01:14:27 mcr
55342+ * NAT-traversal patches to KLIPS.
55343+ *
55344+ * Revision 1.121 2003/10/31 02:27:55 mcr
55345+ * pulled up port-selector patches and sa_id elimination.
55346+ *
55347+ * Revision 1.120.4.2 2003/10/29 01:30:41 mcr
55348+ * elimited "struct sa_id".
55349+ *
55350+ * Revision 1.120.4.1 2003/09/21 13:59:56 mcr
55351+ * pre-liminary X.509 patch - does not yet pass tests.
55352+ *
55353+ * Revision 1.120 2003/04/03 17:38:09 rgb
55354+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
55355+ *
55356+ * Revision 1.119 2003/02/06 01:52:37 rgb
55357+ * Removed no longer relevant comment
55358+ *
55359+ * Revision 1.118 2003/01/30 02:32:44 rgb
55360+ *
55361+ * Transmit error code through to caller from callee for better diagnosis of problems.
55362+ *
55363+ * Revision 1.117 2003/01/16 18:48:13 rgb
55364+ *
55365+ * Fixed sign bug in error return from an sa allocation call in
55366+ * pfkey_msg_interp.
55367+ *
55368+ * Revision 1.116 2002/10/17 16:38:01 rgb
55369+ * Change pfkey_alloc_eroute() to never static since its consumers
55370+ * have been moved outside the file.
55371+ *
55372+ * Revision 1.115 2002/10/12 23:11:53 dhr
55373+ *
55374+ * [KenB + DHR] more 64-bit cleanup
55375+ *
55376+ * Revision 1.114 2002/10/05 05:02:58 dhr
55377+ *
55378+ * C labels go on statements
55379+ *
55380+ * Revision 1.113 2002/09/30 19:11:22 rgb
55381+ * Turn on debugging for upgoing acquire messages to test for reliability.
55382+ *
55383+ * Revision 1.112 2002/09/20 15:41:16 rgb
55384+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
55385+ * Added sadb_x_sa_ref to struct sadb_sa.
55386+ * Added ref parameter to pfkey_sa_build().
55387+ *
55388+ * Revision 1.111 2002/09/20 05:02:08 rgb
55389+ * Added memory allocation debugging.
55390+ * Convert to switch to divulge hmac keys for debugging.
55391+ * Added text labels to elucidate numeric values presented.
55392+ *
55393+ * Revision 1.110 2002/08/03 18:03:05 mcr
55394+ * loop that checks for SPI's to have been already linked
55395+ * fails to actually step to next pointer, but continuously
55396+ * resets to head of list. Wrong pointer used.
55397+ * test east-icmp-02 revealed this.
55398+ *
55399+ * Revision 1.109 2002/07/26 08:48:31 rgb
55400+ * Added SA ref table code.
55401+ *
55402+ * Revision 1.108 2002/05/27 18:55:03 rgb
55403+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
55404+ *
55405+ * Revision 1.107 2002/05/23 07:16:08 rgb
55406+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
55407+ * Pointer clean-up.
55408+ * Added refcount code.
55409+ *
55410+ * Revision 1.106 2002/05/14 02:34:13 rgb
55411+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
55412+ * with "put" usage in the kernel.
55413+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
55414+ * ipsec_sa or ipsec_sa.
55415+ * Moved all the extension parsing functions to pfkey_v2_ext_process.c.
55416+ *
55417+ * Revision 1.105 2002/04/24 07:55:32 mcr
55418+ * #include patches and Makefiles for post-reorg compilation.
55419+ *
55420+ * Revision 1.104 2002/04/24 07:36:34 mcr
55421+ * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v
55422+ *
55423+ * Revision 1.103 2002/04/20 00:12:25 rgb
55424+ * Added esp IV CBC attack fix, disabled.
55425+ *
55426+ * Revision 1.102 2002/03/08 01:15:17 mcr
55427+ * put some internal structure only debug messages behind
55428+ * && sysctl_ipsec_debug_verbose.
55429+ *
55430+ * Revision 1.101 2002/01/29 17:17:57 mcr
55431+ * moved include of ipsec_param.h to after include of linux/kernel.h
55432+ * otherwise, it seems that some option that is set in ipsec_param.h
55433+ * screws up something subtle in the include path to kernel.h, and
55434+ * it complains on the snprintf() prototype.
55435+ *
55436+ * Revision 1.100 2002/01/29 04:00:54 mcr
55437+ * more excise of kversions.h header.
55438+ *
55439+ * Revision 1.99 2002/01/29 02:13:19 mcr
55440+ * introduction of ipsec_kversion.h means that include of
55441+ * ipsec_param.h must preceed any decisions about what files to
55442+ * include to deal with differences in kernel source.
55443+ *
55444+ * Revision 1.98 2002/01/12 02:57:57 mcr
55445+ * first regression test causes acquire messages to be lost
55446+ * 100% of the time. This is to help testing of pluto.
55447+ *
55448+ * Revision 1.97 2001/11/26 09:23:52 rgb
55449+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
55450+ *
55451+ * Revision 1.93.2.4 2001/10/23 04:20:27 mcr
55452+ * parity was forced on wrong structure! prototypes help here.
55453+ *
55454+ * Revision 1.93.2.3 2001/10/22 21:14:59 mcr
55455+ * include des.h, removed phony prototypes and fixed calling
55456+ * conventions to match real prototypes.
55457+ *
55458+ * Revision 1.93.2.2 2001/10/15 05:39:03 mcr
55459+ * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
55460+ *
55461+ * Revision 1.93.2.1 2001/09/25 02:30:14 mcr
55462+ * struct tdb -> struct ipsec_sa.
55463+ * use new lifetime structure. common format routines for debug.
55464+ *
55465+ * Revision 1.96 2001/11/06 20:47:54 rgb
55466+ * Fixed user context call to ipsec_dev_start_xmit() bug. Call
55467+ * dev_queue_xmit() instead.
55468+ *
55469+ * Revision 1.95 2001/11/06 19:47:46 rgb
55470+ * Added packet parameter to lifetime and comb structures.
55471+ *
55472+ * Revision 1.94 2001/10/18 04:45:23 rgb
55473+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
55474+ * lib/freeswan.h version macros moved to lib/kversions.h.
55475+ * Other compiler directive cleanups.
55476+ *
55477+ * Revision 1.93 2001/09/20 15:32:59 rgb
55478+ * Min/max cleanup.
55479+ *
55480+ * Revision 1.92 2001/09/19 16:35:48 rgb
55481+ * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
55482+ *
55483+ * Revision 1.91 2001/09/15 16:24:06 rgb
55484+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
55485+ *
55486+ * Revision 1.90 2001/09/14 16:58:38 rgb
55487+ * Added support for storing the first and last packets through a HOLD.
55488+ *
55489+ * Revision 1.89 2001/09/08 21:14:07 rgb
55490+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
55491+ * Better state coherency (error management) between pf_key and IKE daemon.
55492+ * (NetCelo)
55493+ *
55494+ * Revision 1.88 2001/08/27 19:42:44 rgb
55495+ * Fix memory leak of encrypt and auth structs in pfkey register.
55496+ *
55497+ * Revision 1.87 2001/07/06 19:50:46 rgb
55498+ * Removed unused debugging code.
55499+ * Added inbound policy checking code for IPIP SAs.
55500+ *
55501+ * Revision 1.86 2001/06/20 06:26:04 rgb
55502+ * Changed missing SA errors from EEXIST to ENOENT and added debug output
55503+ * for already linked SAs.
55504+ *
55505+ * Revision 1.85 2001/06/15 04:57:02 rgb
55506+ * Remove single error return condition check and check for all errors in
55507+ * the case of a replace eroute delete operation. This means that
55508+ * applications must expect to be deleting something before replacing it
55509+ * and if nothing is found, complain.
55510+ *
55511+ * Revision 1.84 2001/06/14 19:35:12 rgb
55512+ * Update copyright date.
55513+ *
55514+ * Revision 1.83 2001/06/12 00:03:19 rgb
55515+ * Silence debug set/unset under normal conditions.
55516+ *
55517+ * Revision 1.82 2001/05/30 08:14:04 rgb
55518+ * Removed vestiges of esp-null transforms.
55519+ *
55520+ * Revision 1.81 2001/05/27 06:12:12 rgb
55521+ * Added structures for pid, packet count and last access time to eroute.
55522+ * Added packet count to beginning of /proc/net/ipsec_eroute.
55523+ *
55524+ * Revision 1.80 2001/05/03 19:43:59 rgb
55525+ * Check error return codes for all build function calls.
55526+ * Standardise on SENDERR() macro.
55527+ *
55528+ * Revision 1.79 2001/04/20 21:09:16 rgb
55529+ * Cleaned up fixed tdbwipes.
55530+ * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
55531+ * delflow (Per Cederqvist) plugging memleaks.
55532+ *
55533+ * Revision 1.78 2001/04/19 19:02:39 rgb
55534+ * Fixed extr.tdb freeing, stealing it for getspi, update and add.
55535+ * Refined a couple of spinlocks, fixed the one in update.
55536+ *
55537+ * Revision 1.77 2001/04/18 20:26:16 rgb
55538+ * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
55539+ * instead of inside each message type parser. This fixes two memleaks.
55540+ *
55541+ * Revision 1.76 2001/04/17 23:51:18 rgb
55542+ * Quiet down pfkey_x_debug_process().
55543+ *
55544+ * Revision 1.75 2001/03/29 01:55:05 rgb
55545+ * Fixed pfkey key init memleak.
55546+ * Fixed pfkey encryption key debug output.
55547+ *
55548+ * Revision 1.74 2001/03/27 05:29:14 rgb
55549+ * Debug output cleanup/silencing.
55550+ *
55551+ * Revision 1.73 2001/02/28 05:03:28 rgb
55552+ * Clean up and rationalise startup messages.
55553+ *
55554+ * Revision 1.72 2001/02/27 22:24:56 rgb
55555+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
55556+ * Check for satoa() return codes.
55557+ *
55558+ * Revision 1.71 2001/02/27 06:59:30 rgb
55559+ * Added satype2name() conversions most places satype is debug printed.
55560+ *
55561+ * Revision 1.70 2001/02/26 22:37:08 rgb
55562+ * Fixed 'unknown proto' INT bug in new code.
55563+ * Added satype to protocol debugging instrumentation.
55564+ *
55565+ * Revision 1.69 2001/02/26 19:57:51 rgb
55566+ * Re-formatted debug output (split lines, consistent spacing).
55567+ * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
55568+ * with an satype instead of proto.
55569+ * Checked for satype consistency and fixed minor bugs.
55570+ * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
55571+ * Check for satype sanity in pfkey_expire().
55572+ * Added satype sanity check to addflow.
55573+ *
55574+ * Revision 1.68 2001/02/12 23:14:40 rgb
55575+ * Remove double spin lock in pfkey_expire().
55576+ *
55577+ * Revision 1.67 2001/01/31 19:23:40 rgb
55578+ * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
55579+ *
55580+ * Revision 1.66 2001/01/29 22:20:04 rgb
55581+ * Fix minor add upmsg lifetime bug.
55582+ *
55583+ * Revision 1.65 2001/01/24 06:12:33 rgb
55584+ * Fixed address extension compile bugs just introduced.
55585+ *
55586+ * Revision 1.64 2001/01/24 00:31:15 rgb
55587+ * Added upmsg for addflow/delflow.
55588+ *
55589+ * Revision 1.63 2001/01/23 22:02:55 rgb
55590+ * Added upmsg to x_grpsa.
55591+ * Fixed lifetimes extentions to add/update/get upmsg.
55592+ *
55593+ * Revision 1.62 2000/11/30 21:47:51 rgb
55594+ * Fix error return bug after returning from pfkey_tdb_init().
55595+ *
55596+ * Revision 1.61 2000/11/17 18:10:29 rgb
55597+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
55598+ * network byte order since this is the way PF_KEYv2 stored spis.
55599+ *
55600+ * Revision 1.60 2000/11/06 04:34:53 rgb
55601+ * Changed non-exported functions to DEBUG_NO_STATIC.
55602+ * Add Svenning's adaptive content compression.
55603+ * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
55604+ * Fixed double unlock bug (Svenning).
55605+ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
55606+ * Fixed incorrect extension type (prop) in pfkey)acquire().
55607+ *
55608+ * Revision 1.59 2000/10/11 15:25:12 rgb
55609+ * Fixed IPCOMP disabled compile bug.
55610+ *
55611+ * Revision 1.58 2000/10/11 14:54:03 rgb
55612+ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
55613+ * protocol violations of setting pfkey_address_build() protocol parameter
55614+ * to non-zero except in the case of pfkey_acquire().
55615+ *
55616+ * Revision 1.57 2000/10/10 20:10:18 rgb
55617+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
55618+ *
55619+ * Revision 1.56 2000/10/06 20:24:36 rgb
55620+ * Fixes to pfkey_acquire to initialize extensions[] and use correct
55621+ * ipproto.
55622+ *
55623+ * Revision 1.55 2000/10/03 03:20:57 rgb
55624+ * Added brackets to get a?b:c scope right for pfkey_register reply.
55625+ *
55626+ * Revision 1.54 2000/09/29 19:49:30 rgb
55627+ * As-yet-unused-bits cleanup.
55628+ *
55629+ * Revision 1.53 2000/09/28 00:35:45 rgb
55630+ * Padded SATYPE printout in pfkey_register for vertical alignment.
55631+ *
55632+ * Revision 1.52 2000/09/20 16:21:58 rgb
55633+ * Cleaned up ident string alloc/free.
55634+ *
55635+ * Revision 1.51 2000/09/20 04:04:20 rgb
55636+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
55637+ * oopsen.
55638+ *
55639+ * Revision 1.50 2000/09/16 01:10:53 rgb
55640+ * Fixed unused var warning with debug off.
55641+ *
55642+ * Revision 1.49 2000/09/15 11:37:02 rgb
55643+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
55644+ * IPCOMP zlib deflate code.
55645+ *
55646+ * Revision 1.48 2000/09/15 04:57:57 rgb
55647+ * Cleaned up existing IPCOMP code before svenning addition.
55648+ * Initialize pfkey_reply and extensions_reply in case of early error in
55649+ * message parsing functions (thanks Kai!).
55650+ *
55651+ * Revision 1.47 2000/09/13 08:02:56 rgb
55652+ * Added KMd registration notification.
55653+ *
55654+ * Revision 1.46 2000/09/12 22:35:36 rgb
55655+ * Restructured to remove unused extensions from CLEARFLOW messages.
55656+ *
55657+ * Revision 1.45 2000/09/12 03:24:23 rgb
55658+ * Converted #if0 debugs to sysctl.
55659+ *
55660+ * Revision 1.44 2000/09/09 06:38:39 rgb
55661+ * Correct SADB message type for update, add and delete.
55662+ *
55663+ * Revision 1.43 2000/09/08 19:19:56 rgb
55664+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
55665+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
55666+ * Put in sanity checks in most msg type parsers to catch invalid satypes
55667+ * and empty socket lists.
55668+ * Moved spin-locks in pfkey_get_parse() to simplify.
55669+ * Added pfkey_acquire().
55670+ * Added upwards messages to update, add, delete, acquire_parse,
55671+ * expire_parse and flush.
55672+ * Fix pfkey_prop_build() parameter to be only single indirection.
55673+ * Changed all replies to use pfkey_reply.
55674+ * Check return code on puttdb() and deltdbchain() in getspi, update,
55675+ * add, delete.
55676+ * Fixed up all pfkey replies to open and registered sockets.
55677+ *
55678+ * Revision 1.42 2000/09/01 18:50:26 rgb
55679+ * Added a supported algorithms array lists, one per satype and registered
55680+ * existing algorithms.
55681+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
55682+ * list.
55683+ * Only send pfkey_expire() messages to sockets registered for that satype.
55684+ * Added reply to pfkey_getspi_parse().
55685+ * Added reply to pfkey_get_parse().
55686+ * Fixed debug output label bug in pfkey_lifetime_process().
55687+ * Cleaned up pfkey_sa_process a little.
55688+ * Moved pfkey_safe_build() above message type parsers to make it available
55689+ * for creating replies.
55690+ * Added comments for future work in pfkey_acquire_parse().
55691+ * Fleshed out guts of pfkey_register_parse().
55692+ *
55693+ * Revision 1.41 2000/08/24 16:58:11 rgb
55694+ * Fixed key debugging variables.
55695+ * Fixed error return code for a failed search.
55696+ * Changed order of pfkey_get operations.
55697+ *
55698+ * Revision 1.40 2000/08/21 16:32:27 rgb
55699+ * Re-formatted for cosmetic consistency and readability.
55700+ *
55701+ * Revision 1.39 2000/08/20 21:38:57 rgb
55702+ * Bugfixes to as-yet-unused pfkey_update_parse() and
55703+ * pfkey_register_parse(). (Momchil)
55704+ * Added functions pfkey_safe_build(), pfkey_expire() and
55705+ * pfkey_build_reply(). (Momchil)
55706+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
55707+ *
55708+ * Revision 1.38 2000/08/18 21:30:41 rgb
55709+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
55710+ *
55711+ * Revision 1.37 2000/08/18 18:18:02 rgb
55712+ * Cosmetic and descriptive changes made to debug test.
55713+ * getspi and update fixes from Momchil.
55714+ *
55715+ * Revision 1.36 2000/08/15 15:41:55 rgb
55716+ * Fixed the (as yet unused and untested) pfkey_getspi() routine.
55717+ *
55718+ * Revision 1.35 2000/08/01 14:51:52 rgb
55719+ * Removed _all_ remaining traces of DES.
55720+ *
55721+ * Revision 1.34 2000/07/28 14:58:32 rgb
55722+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
55723+ *
55724+ * Revision 1.33 2000/06/28 05:50:11 rgb
55725+ * Actually set iv_bits.
55726+ *
55727+ * Revision 1.32 2000/05/30 18:36:56 rgb
55728+ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY
55729+ * FreeS/WAN, but fixes interop with other implementations.
55730+ *
55731+ * Revision 1.31 2000/03/16 14:05:48 rgb
55732+ * Fixed brace scope preventing non-debug compile.
55733+ * Added null parameter check for pfkey_x_debug().
55734+ *
55735+ * Revision 1.30 2000/01/22 23:21:13 rgb
55736+ * Use new function satype2proto().
55737+ *
55738+ * Revision 1.29 2000/01/22 08:40:21 rgb
55739+ * Invert condition to known value to avoid AF_INET6 in 2.0.36.
55740+ *
55741+ * Revision 1.28 2000/01/22 07:58:57 rgb
55742+ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
55743+ *
55744+ * Revision 1.27 2000/01/22 03:48:01 rgb
55745+ * Added extr pointer component debugging.
55746+ *
55747+ * Revision 1.26 2000/01/21 09:41:25 rgb
55748+ * Changed a (void*) to (char*) cast to do proper pointer math.
55749+ * Don't call tdbwipe if tdb2 is NULL.
55750+ *
55751+ * Revision 1.25 2000/01/21 06:21:01 rgb
55752+ * Added address cases for eroute flows.
55753+ * Tidied up compiler directive indentation for readability.
55754+ * Added ictx,octx vars for simplification.
55755+ * Added macros for HMAC padding magic numbers.
55756+ * Converted from double tdb arguments to one structure (extr)
55757+ * containing pointers to all temporary information structures
55758+ * and checking for valid arguments to all ext processors and
55759+ * msg type parsers.
55760+ * Added spiungrp'ing.
55761+ * Added klipsdebug switching capability.
55762+ * Removed sa_process() check for zero protocol.
55763+ * Added address case for DST2 for grouping.
55764+ * Added/changed minor debugging instrumentation.
55765+ * Fixed spigrp for single said, ungrouping case.
55766+ * Added code to parse addflow and delflow messages.
55767+ * Removed redundant statements duplicating tdbwipe() functionality
55768+ * and causing double kfrees.
55769+ * Permit addflow to have a protocol of 0.
55770+ *
55771+ * Revision 1.24 1999/12/09 23:23:00 rgb
55772+ * Added check to pfkey_sa_process() to do eroutes.
55773+ * Converted to DIVUP() macro.
55774+ * Converted if() to switch() in pfkey_register_parse().
55775+ * Use new pfkey_extensions_init() instead of memset().
55776+ *
55777+ * Revision 1.23 1999/12/01 22:18:13 rgb
55778+ * Preset minspi and maxspi values in case and spirange extension is not
55779+ * included and check for the presence of an spirange extension before
55780+ * using it. Initialise tdb_sastate to LARVAL.
55781+ * Fixed debugging output typo.
55782+ * Fixed authentication context initialisation bugs (4 places).
55783+ *
55784+ * Revision 1.22 1999/11/27 11:53:08 rgb
55785+ * Moved pfkey_msg_parse prototype to pfkey.h
55786+ * Moved exts_permitted/required prototype to pfkey.h.
55787+ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
55788+ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
55789+ * be called.
55790+ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
55791+ * Debugging error messages added.
55792+ * Enable lifetime_current checking.
55793+ * Remove illegal requirement for SA extension to be present in an
55794+ * originating GETSPI call.
55795+ * Re-instate requirement for UPDATE or ADD message to be MATURE.
55796+ * Add argument to pfkey_msg_parse() for direction.
55797+ * Fixed IPIP dst address bug and purged redundant, leaky code.
55798+ *
55799+ * Revision 1.21 1999/11/24 05:24:20 rgb
55800+ * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
55801+ * Fixed indention.
55802+ * Ditched redundant replay check.
55803+ * Fixed debug message text from 'parse' to 'process'.
55804+ * Added more debug output.
55805+ * Forgot to zero extensions array causing bug, fixed.
55806+ *
55807+ * Revision 1.20 1999/11/23 23:08:13 rgb
55808+ * Move all common parsing code to lib/pfkey_v2_parse.c and rename
55809+ * remaining bits to *_process. (PJO)
55810+ * Add macros for dealing with alignment and rounding up more opaquely.
55811+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
55812+ * Sort out pfkey and freeswan headers, putting them in a library path.
55813+ * Corrected a couple of bugs in as-yet-inactive code.
55814+ *
55815+ * Revision 1.19 1999/11/20 22:01:10 rgb
55816+ * Add more descriptive error messages for non-zero reserved fields.
55817+ * Add more descriptive error message for spirange parsing.
55818+ * Start on supported extension parsing.
55819+ * Start on register and get message parsing.
55820+ *
55821+ * Revision 1.18 1999/11/18 04:09:20 rgb
55822+ * Replaced all kernel version macros to shorter, readable form.
55823+ *
55824+ * Revision 1.17 1999/11/17 15:53:41 rgb
55825+ * Changed all occurrences of #include "../../../lib/freeswan.h"
55826+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
55827+ * klips/net/ipsec/Makefile.
55828+ *
55829+ * Revision 1.16 1999/10/26 16:57:43 rgb
55830+ * Add shorter macros for compiler directives to visually clean-up.
55831+ * Give ipv6 code meaningful compiler directive.
55832+ * Add comments to other #if 0 debug code.
55833+ * Remove unused *_bh_atomic() calls.
55834+ * Fix mis-placed spinlock.
55835+ *
55836+ * Revision 1.15 1999/10/16 18:27:10 rgb
55837+ * Clean-up unused cruft.
55838+ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
55839+ *
55840+ * Revision 1.14 1999/10/08 18:37:34 rgb
55841+ * Fix end-of-line spacing to sate whining PHMs.
55842+ *
55843+ * Revision 1.13 1999/10/03 18:49:12 rgb
55844+ * Spinlock fixes for 2.0.xx and 2.3.xx.
55845+ *
55846+ * Revision 1.12 1999/10/01 15:44:54 rgb
55847+ * Move spinlock header include to 2.1> scope.
55848+ *
55849+ * Revision 1.11 1999/10/01 00:05:45 rgb
55850+ * Added tdb structure locking.
55851+ * Use 'jiffies' instead of do_get_timeofday().
55852+ * Fix lifetime assignments.
55853+ *
55854+ * Revision 1.10 1999/09/21 15:24:45 rgb
55855+ * Rework spirange code to save entropy and prevent endless loops.
55856+ *
55857+ * Revision 1.9 1999/09/16 12:10:21 rgb
55858+ * Minor fixes to random spi selection for correctness and entropy conservation.
55859+ *
55860+ * Revision 1.8 1999/05/25 22:54:46 rgb
55861+ * Fix comparison that should be an assignment in an if.
55862+ *
55863+ * Revision 1.7 1999/05/09 03:25:37 rgb
55864+ * Fix bug introduced by 2.2 quick-and-dirty patch.
55865+ *
55866+ * Revision 1.6 1999/05/08 21:32:30 rgb
55867+ * Fix error return reporting.
55868+ *
55869+ * Revision 1.5 1999/05/05 22:02:33 rgb
55870+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
55871+ *
55872+ * Revision 1.4 1999/04/29 15:22:40 rgb
55873+ * Standardise an error return method.
55874+ * Add debugging instrumentation.
55875+ * Add check for existence of macros min/max.
55876+ * Add extensions permitted/required in/out filters.
55877+ * Add satype-to-protocol table.
55878+ * Add a second tdb pointer to each parser to accomodate GRPSA.
55879+ * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
55880+ * Add OOO window check.
55881+ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
55882+ * Add timestamp to lifetime parse.
55883+ * Fix address structure length checking bug.
55884+ * Fix address structure allocation bug (forgot to kmalloc!).
55885+ * Add checks for extension lengths.
55886+ * Add checks for extension reserved illegal values.
55887+ * Add check for spirange legal values.
55888+ * Add an extension type for parsing a second satype, SA and
55889+ * DST_ADDRESS.
55890+ * Make changes to tdb_init() template to get pfkey_tdb_init(),
55891+ * eliminating any mention of xformsw.
55892+ * Implement getspi, update and grpsa (not tested).
55893+ * Add stubs for as yet unimplemented message types.
55894+ * Add table of message parsers to substitute for msg_parse switch.
55895+ *
55896+ * Revision 1.3 1999/04/15 17:58:07 rgb
55897+ * Add RCSID labels.
55898+ *
55899+ * Revision 1.2 1999/04/15 15:37:26 rgb
55900+ * Forward check changes from POST1_00 branch.
55901+ *
55902+ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb
55903+ * Add pfkeyv2 support to KLIPS.
55904+ *
55905+ * Local variables:
55906+ * c-file-style: "linux"
55907+ * End:
55908+ *
55909+ */
55910--- /dev/null Tue Mar 11 13:02:56 2003
55911+++ linux/net/ipsec/prng.c Mon Feb 9 13:51:03 2004
55912@@ -0,0 +1,201 @@
55913+/*
55914+ * crypto-class pseudorandom number generator
55915+ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
55916+ * Copyright (C) 2002 Henry Spencer.
55917+ *
55918+ * This library is free software; you can redistribute it and/or modify it
55919+ * under the terms of the GNU Library General Public License as published by
55920+ * the Free Software Foundation; either version 2 of the License, or (at your
55921+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
55922+ *
55923+ * This library is distributed in the hope that it will be useful, but
55924+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
55925+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
55926+ * License for more details.
55927+ *
55928+ * RCSID $Id: prng.c,v 1.7 2004-07-10 07:48:36 mcr Exp $
55929+ */
55930+#include "openswan.h"
55931+
55932+/*
55933+ - prng_init - initialize PRNG from a key
55934+ */
55935+void
55936+prng_init(prng, key, keylen)
55937+struct prng *prng;
55938+const unsigned char *key;
55939+size_t keylen;
55940+{
55941+ unsigned char k[256];
55942+ int i, j;
55943+ unsigned const char *p;
55944+ unsigned const char *keyend = key + keylen;
55945+ unsigned char t;
55946+
55947+ for (i = 0; i <= 255; i++)
55948+ prng->sbox[i] = i;
55949+ p = key;
55950+ for (i = 0; i <= 255; i++) {
55951+ k[i] = *p++;
55952+ if (p >= keyend)
55953+ p = key;
55954+ }
55955+ j = 0;
55956+ for (i = 0; i <= 255; i++) {
55957+ j = (j + prng->sbox[i] + k[i]) & 0xff;
55958+ t = prng->sbox[i];
55959+ prng->sbox[i] = prng->sbox[j];
55960+ prng->sbox[j] = t;
55961+ k[i] = 0; /* clear out key memory */
55962+ }
55963+ prng->i = 0;
55964+ prng->j = 0;
55965+ prng->count = 0;
55966+}
55967+
55968+/*
55969+ - prng_bytes - get some pseudorandom bytes from PRNG
55970+ */
55971+void
55972+prng_bytes(prng, dst, dstlen)
55973+struct prng *prng;
55974+unsigned char *dst;
55975+size_t dstlen;
55976+{
55977+ int i, j, t;
55978+ unsigned char *p = dst;
55979+ size_t remain = dstlen;
55980+# define MAX 4000000000ul
55981+
55982+ while (remain > 0) {
55983+ i = (prng->i + 1) & 0xff;
55984+ prng->i = i;
55985+ j = (prng->j + prng->sbox[i]) & 0xff;
55986+ prng->j = j;
55987+ t = prng->sbox[i];
55988+ prng->sbox[i] = prng->sbox[j];
55989+ prng->sbox[j] = t;
55990+ t = (t + prng->sbox[i]) & 0xff;
55991+ *p++ = prng->sbox[t];
55992+ remain--;
55993+ }
55994+ if (prng->count < MAX - dstlen)
55995+ prng->count += dstlen;
55996+ else
55997+ prng->count = MAX;
55998+}
55999+
56000+/*
56001+ - prnt_count - how many bytes have been extracted from PRNG so far?
56002+ */
56003+unsigned long
56004+prng_count(prng)
56005+struct prng *prng;
56006+{
56007+ return prng->count;
56008+}
56009+
56010+/*
56011+ - prng_final - clear out PRNG to ensure nothing left in memory
56012+ */
56013+void
56014+prng_final(prng)
56015+struct prng *prng;
56016+{
56017+ int i;
56018+
56019+ for (i = 0; i <= 255; i++)
56020+ prng->sbox[i] = 0;
56021+ prng->i = 0;
56022+ prng->j = 0;
56023+ prng->count = 0; /* just for good measure */
56024+}
56025+
56026+
56027+
56028+#ifdef PRNG_MAIN
56029+
56030+#include <stdio.h>
56031+
56032+void regress();
56033+
56034+int
56035+main(argc, argv)
56036+int argc;
56037+char *argv[];
56038+{
56039+ struct prng pr;
56040+ unsigned char buf[100];
56041+ unsigned char *p;
56042+ size_t n;
56043+
56044+ if (argc < 2) {
56045+ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
56046+ exit(2);
56047+ }
56048+
56049+ if (strcmp(argv[1], "-r") == 0) {
56050+ regress();
56051+ fprintf(stderr, "regress() returned?!?\n");
56052+ exit(1);
56053+ }
56054+
56055+ prng_init(&pr, argv[1], strlen(argv[1]));
56056+ prng_bytes(&pr, buf, 32);
56057+ printf("0x");
56058+ for (p = buf, n = 32; n > 0; p++, n--)
56059+ printf("%02x", *p);
56060+ printf("\n%lu bytes\n", prng_count(&pr));
56061+ prng_final(&pr);
56062+ exit(0);
56063+}
56064+
56065+void
56066+regress()
56067+{
56068+ struct prng pr;
56069+ unsigned char buf[100];
56070+ unsigned char *p;
56071+ size_t n;
56072+ /* somewhat non-random sample key */
56073+ unsigned char key[] = "here we go gathering nuts in May";
56074+ /* first thirty bytes of output from that key */
56075+ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
56076+ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
56077+ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
56078+ int nzero, none;
56079+ int show = 0;
56080+
56081+ prng_init(&pr, key, strlen(key));
56082+ prng_bytes(&pr, buf, sizeof(buf));
56083+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
56084+ if (*p == 0)
56085+ nzero++;
56086+ if (*p == 255)
56087+ none++;
56088+ }
56089+ if (nzero > 3 || none > 3) {
56090+ fprintf(stderr, "suspiciously non-random output!\n");
56091+ show = 1;
56092+ }
56093+ if (memcmp(buf, good, strlen(good)) != 0) {
56094+ fprintf(stderr, "incorrect output!\n");
56095+ show = 1;
56096+ }
56097+ if (show) {
56098+ fprintf(stderr, "0x");
56099+ for (p = buf, n = sizeof(buf); n > 0; p++, n--)
56100+ fprintf(stderr, "%02x", *p);
56101+ fprintf(stderr, "\n");
56102+ exit(1);
56103+ }
56104+ if (prng_count(&pr) != sizeof(buf)) {
56105+ fprintf(stderr, "got %u bytes, but count is %lu\n",
56106+ sizeof(buf), prng_count(&pr));
56107+ exit(1);
56108+ }
56109+ prng_final(&pr);
56110+ exit(0);
56111+}
56112+
56113+#endif /* PRNG_MAIN */
56114--- /dev/null Tue Mar 11 13:02:56 2003
56115+++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004
56116@@ -0,0 +1,1237 @@
56117+char radij_c_version[] = "RCSID $Id: radij.c,v 1.48.2.1 2006-10-06 21:39:27 paul Exp $";
56118+
56119+/*
56120+ * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
56121+ *
56122+ * Variable and procedure names have been modified so that they don't
56123+ * conflict with the original BSD code, as a small number of modifications
56124+ * have been introduced and we may want to reuse this code in BSD.
56125+ *
56126+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
56127+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
56128+ * spanish j as in Juan. It is not as far back in the throat like
56129+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
56130+ * It has nothing to do with the Dutch ij sound.
56131+ *
56132+ * Here is the appropriate copyright notice:
56133+ */
56134+
56135+/*
56136+ * Copyright (c) 1988, 1989, 1993
56137+ * The Regents of the University of California. All rights reserved.
56138+ *
56139+ * Redistribution and use in source and binary forms, with or without
56140+ * modification, are permitted provided that the following conditions
56141+ * are met:
56142+ * 1. Redistributions of source code must retain the above copyright
56143+ * notice, this list of conditions and the following disclaimer.
56144+ * 2. Redistributions in binary form must reproduce the above copyright
56145+ * notice, this list of conditions and the following disclaimer in the
56146+ * documentation and/or other materials provided with the distribution.
56147+ * 3. All advertising materials mentioning features or use of this software
56148+ * must display the following acknowledgement:
56149+ * This product includes software developed by the University of
56150+ * California, Berkeley and its contributors.
56151+ * 4. Neither the name of the University nor the names of its contributors
56152+ * may be used to endorse or promote products derived from this software
56153+ * without specific prior written permission.
56154+ *
56155+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56156+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56157+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56158+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56159+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56160+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56161+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56162+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56163+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56164+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56165+ * SUCH DAMAGE.
56166+ *
56167+ * @(#)radix.c 8.2 (Berkeley) 1/4/94
56168+ */
56169+
56170+/*
56171+ * Routines to build and maintain radix trees for routing lookups.
56172+ */
56173+
56174+#ifndef AUTOCONF_INCLUDED
56175+#include <linux/config.h>
56176+#endif
56177+#include <linux/version.h>
56178+#include <linux/kernel.h> /* printk() */
56179+
56180+#include "openswan/ipsec_param.h"
56181+
56182+#ifdef MALLOC_SLAB
56183+# include <linux/slab.h> /* kmalloc() */
56184+#else /* MALLOC_SLAB */
56185+# include <linux/malloc.h> /* kmalloc() */
56186+#endif /* MALLOC_SLAB */
56187+#include <linux/errno.h> /* error codes */
56188+#include <linux/types.h> /* size_t */
56189+#include <linux/interrupt.h> /* mark_bh */
56190+
56191+#include <linux/netdevice.h> /* struct device, and other headers */
56192+#include <linux/etherdevice.h> /* eth_type_trans */
56193+#include <linux/ip.h> /* struct iphdr */
56194+#include <linux/skbuff.h>
56195+#ifdef NET_21
56196+# include <linux/in6.h>
56197+#endif /* NET_21 */
56198+
56199+#include <net/ip.h>
56200+
56201+#include <openswan.h>
56202+
56203+#include "openswan/radij.h"
56204+#include "openswan/ipsec_encap.h"
56205+#include "openswan/ipsec_radij.h"
56206+
56207+int maj_keylen;
56208+struct radij_mask *rj_mkfreelist;
56209+struct radij_node_head *mask_rjhead;
56210+static int gotOddMasks;
56211+static char *maskedKey;
56212+static char *rj_zeroes, *rj_ones;
56213+
56214+#define rj_masktop (mask_rjhead->rnh_treetop)
56215+#ifdef Bcmp
56216+# undef Bcmp
56217+#endif /* Bcmp */
56218+#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
56219+/*
56220+ * The data structure for the keys is a radix tree with one way
56221+ * branching removed. The index rj_b at an internal node n represents a bit
56222+ * position to be tested. The tree is arranged so that all descendants
56223+ * of a node n have keys whose bits all agree up to position rj_b - 1.
56224+ * (We say the index of n is rj_b.)
56225+ *
56226+ * There is at least one descendant which has a one bit at position rj_b,
56227+ * and at least one with a zero there.
56228+ *
56229+ * A route is determined by a pair of key and mask. We require that the
56230+ * bit-wise logical and of the key and mask to be the key.
56231+ * We define the index of a route to associated with the mask to be
56232+ * the first bit number in the mask where 0 occurs (with bit number 0
56233+ * representing the highest order bit).
56234+ *
56235+ * We say a mask is normal if every bit is 0, past the index of the mask.
56236+ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
56237+ * and m is a normal mask, then the route applies to every descendant of n.
56238+ * If the index(m) < rj_b, this implies the trailing last few bits of k
56239+ * before bit b are all 0, (and hence consequently true of every descendant
56240+ * of n), so the route applies to all descendants of the node as well.
56241+ *
56242+ * The present version of the code makes no use of normal routes,
56243+ * but similar logic shows that a non-normal mask m such that
56244+ * index(m) <= index(n) could potentially apply to many children of n.
56245+ * Thus, for each non-host route, we attach its mask to a list at an internal
56246+ * node as high in the tree as we can go.
56247+ */
56248+
56249+struct radij_node *
56250+rj_search(v_arg, head)
56251+ void *v_arg;
56252+ struct radij_node *head;
56253+{
56254+ register struct radij_node *x;
56255+ register caddr_t v;
56256+
56257+ for (x = head, v = v_arg; x->rj_b >= 0;) {
56258+ if (x->rj_bmask & v[x->rj_off])
56259+ x = x->rj_r;
56260+ else
56261+ x = x->rj_l;
56262+ }
56263+ return (x);
56264+};
56265+
56266+struct radij_node *
56267+rj_search_m(v_arg, head, m_arg)
56268+ struct radij_node *head;
56269+ void *v_arg, *m_arg;
56270+{
56271+ register struct radij_node *x;
56272+ register caddr_t v = v_arg, m = m_arg;
56273+
56274+ for (x = head; x->rj_b >= 0;) {
56275+ if ((x->rj_bmask & m[x->rj_off]) &&
56276+ (x->rj_bmask & v[x->rj_off]))
56277+ x = x->rj_r;
56278+ else
56279+ x = x->rj_l;
56280+ }
56281+ return x;
56282+};
56283+
56284+int
56285+rj_refines(m_arg, n_arg)
56286+ void *m_arg, *n_arg;
56287+{
56288+ register caddr_t m = m_arg, n = n_arg;
56289+ register caddr_t lim, lim2 = lim = n + *(u_char *)n;
56290+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
56291+ int masks_are_equal = 1;
56292+
56293+ if (longer > 0)
56294+ lim -= longer;
56295+ while (n < lim) {
56296+ if (*n & ~(*m))
56297+ return 0;
56298+ if (*n++ != *m++)
56299+ masks_are_equal = 0;
56300+
56301+ }
56302+ while (n < lim2)
56303+ if (*n++)
56304+ return 0;
56305+ if (masks_are_equal && (longer < 0))
56306+ for (lim2 = m - longer; m < lim2; )
56307+ if (*m++)
56308+ return 1;
56309+ return (!masks_are_equal);
56310+}
56311+
56312+
56313+struct radij_node *
56314+rj_match(v_arg, head)
56315+ void *v_arg;
56316+ struct radij_node_head *head;
56317+{
56318+ caddr_t v = v_arg;
56319+ register struct radij_node *t = head->rnh_treetop, *x;
56320+ register caddr_t cp = v, cp2, cp3;
56321+ caddr_t cplim, mstart;
56322+ struct radij_node *saved_t, *top = t;
56323+ int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
56324+
56325+ /*
56326+ * Open code rj_search(v, top) to avoid overhead of extra
56327+ * subroutine call.
56328+ */
56329+ for (; t->rj_b >= 0; ) {
56330+ if (t->rj_bmask & cp[t->rj_off])
56331+ t = t->rj_r;
56332+ else
56333+ t = t->rj_l;
56334+ }
56335+ /*
56336+ * See if we match exactly as a host destination
56337+ */
56338+ KLIPS_PRINT(debug_radij,
56339+ "klips_debug:rj_match: "
56340+ "* See if we match exactly as a host destination\n");
56341+
56342+ cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
56343+ for (; cp < cplim; cp++, cp2++)
56344+ if (*cp != *cp2)
56345+ goto on1;
56346+ /*
56347+ * This extra grot is in case we are explicitly asked
56348+ * to look up the default. Ugh!
56349+ */
56350+ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
56351+ t = t->rj_dupedkey;
56352+ return t;
56353+on1:
56354+ matched_off = cp - v;
56355+ saved_t = t;
56356+ KLIPS_PRINT(debug_radij,
56357+ "klips_debug:rj_match: "
56358+ "** try to match a leaf, t=0p%p\n", t);
56359+ do {
56360+ if (t->rj_mask) {
56361+ /*
56362+ * Even if we don't match exactly as a hosts;
56363+ * we may match if the leaf we wound up at is
56364+ * a route to a net.
56365+ */
56366+ cp3 = matched_off + t->rj_mask;
56367+ cp2 = matched_off + t->rj_key;
56368+ for (; cp < cplim; cp++)
56369+ if ((*cp2++ ^ *cp) & *cp3++)
56370+ break;
56371+ if (cp == cplim)
56372+ return t;
56373+ cp = matched_off + v;
56374+ }
56375+ } while ((t = t->rj_dupedkey));
56376+ t = saved_t;
56377+ /* start searching up the tree */
56378+ KLIPS_PRINT(debug_radij,
56379+ "klips_debug:rj_match: "
56380+ "*** start searching up the tree, t=0p%p\n",
56381+ t);
56382+ do {
56383+ register struct radij_mask *m;
56384+
56385+ t = t->rj_p;
56386+ KLIPS_PRINT(debug_radij,
56387+ "klips_debug:rj_match: "
56388+ "**** t=0p%p\n",
56389+ t);
56390+ if ((m = t->rj_mklist)) {
56391+ /*
56392+ * After doing measurements here, it may
56393+ * turn out to be faster to open code
56394+ * rj_search_m here instead of always
56395+ * copying and masking.
56396+ */
56397+ /* off = min(t->rj_off, matched_off); */
56398+ off = t->rj_off;
56399+ if (matched_off < off)
56400+ off = matched_off;
56401+ mstart = maskedKey + off;
56402+ do {
56403+ cp2 = mstart;
56404+ cp3 = m->rm_mask + off;
56405+ KLIPS_PRINT(debug_radij,
56406+ "klips_debug:rj_match: "
56407+ "***** cp2=0p%p cp3=0p%p\n",
56408+ cp2, cp3);
56409+ for (cp = v + off; cp < cplim;)
56410+ *cp2++ = *cp++ & *cp3++;
56411+ x = rj_search(maskedKey, t);
56412+ while (x && x->rj_mask != m->rm_mask)
56413+ x = x->rj_dupedkey;
56414+ if (x &&
56415+ (Bcmp(mstart, x->rj_key + off,
56416+ vlen - off) == 0))
56417+ return x;
56418+ } while ((m = m->rm_mklist));
56419+ }
56420+ } while (t != top);
56421+ KLIPS_PRINT(debug_radij,
56422+ "klips_debug:rj_match: "
56423+ "***** not found.\n");
56424+ return 0;
56425+};
56426+
56427+#ifdef RJ_DEBUG
56428+int rj_nodenum;
56429+struct radij_node *rj_clist;
56430+int rj_saveinfo;
56431+DEBUG_NO_STATIC void traverse(struct radij_node *);
56432+#ifdef RJ_DEBUG2
56433+int rj_debug = 1;
56434+#else
56435+int rj_debug = 0;
56436+#endif /* RJ_DEBUG2 */
56437+#endif /* RJ_DEBUG */
56438+
56439+struct radij_node *
56440+rj_newpair(v, b, nodes)
56441+ void *v;
56442+ int b;
56443+ struct radij_node nodes[2];
56444+{
56445+ register struct radij_node *tt = nodes, *t = tt + 1;
56446+ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
56447+ t->rj_l = tt; t->rj_off = b >> 3;
56448+ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
56449+ tt->rj_flags = t->rj_flags = RJF_ACTIVE;
56450+#ifdef RJ_DEBUG
56451+ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
56452+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
56453+#endif /* RJ_DEBUG */
56454+ return t;
56455+}
56456+
56457+struct radij_node *
56458+rj_insert(v_arg, head, dupentry, nodes)
56459+ void *v_arg;
56460+ struct radij_node_head *head;
56461+ int *dupentry;
56462+ struct radij_node nodes[2];
56463+{
56464+ caddr_t v = v_arg;
56465+ struct radij_node *top = head->rnh_treetop;
56466+ int head_off = top->rj_off, vlen = (int)*((u_char *)v);
56467+ register struct radij_node *t = rj_search(v_arg, top);
56468+ register caddr_t cp = v + head_off;
56469+ register int b;
56470+ struct radij_node *tt;
56471+ /*
56472+ *find first bit at which v and t->rj_key differ
56473+ */
56474+ {
56475+ register caddr_t cp2 = t->rj_key + head_off;
56476+ register int cmp_res;
56477+ caddr_t cplim = v + vlen;
56478+
56479+ while (cp < cplim)
56480+ if (*cp2++ != *cp++)
56481+ goto on1;
56482+ *dupentry = 1;
56483+ return t;
56484+on1:
56485+ *dupentry = 0;
56486+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
56487+ for (b = (cp - v) << 3; cmp_res; b--)
56488+ cmp_res >>= 1;
56489+ }
56490+ {
56491+ register struct radij_node *p, *x = top;
56492+ cp = v;
56493+ do {
56494+ p = x;
56495+ if (cp[x->rj_off] & x->rj_bmask)
56496+ x = x->rj_r;
56497+ else x = x->rj_l;
56498+ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
56499+#ifdef RJ_DEBUG
56500+ if (rj_debug)
56501+ printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
56502+#endif /* RJ_DEBUG */
56503+ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
56504+ if ((cp[p->rj_off] & p->rj_bmask) == 0)
56505+ p->rj_l = t;
56506+ else
56507+ p->rj_r = t;
56508+ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
56509+ if ((cp[t->rj_off] & t->rj_bmask) == 0) {
56510+ t->rj_r = x;
56511+ } else {
56512+ t->rj_r = tt; t->rj_l = x;
56513+ }
56514+#ifdef RJ_DEBUG
56515+ if (rj_debug)
56516+ printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
56517+#endif /* RJ_DEBUG */
56518+ }
56519+ return (tt);
56520+}
56521+
56522+struct radij_node *
56523+rj_addmask(n_arg, search, skip)
56524+ int search, skip;
56525+ void *n_arg;
56526+{
56527+ caddr_t netmask = (caddr_t)n_arg;
56528+ register struct radij_node *x;
56529+ register caddr_t cp, cplim;
56530+ register int b, mlen, j;
56531+ int maskduplicated;
56532+
56533+ mlen = *(u_char *)netmask;
56534+ if (search) {
56535+ x = rj_search(netmask, rj_masktop);
56536+ mlen = *(u_char *)netmask;
56537+ if (Bcmp(netmask, x->rj_key, mlen) == 0)
56538+ return (x);
56539+ }
56540+ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
56541+ if (x == 0)
56542+ return (0);
56543+ Bzero(x, maj_keylen + 2 * sizeof (*x));
56544+ cp = (caddr_t)(x + 2);
56545+ Bcopy(netmask, cp, mlen);
56546+ netmask = cp;
56547+ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
56548+ /*
56549+ * Calculate index of mask.
56550+ */
56551+ cplim = netmask + mlen;
56552+ for (cp = netmask + skip; cp < cplim; cp++)
56553+ if (*(u_char *)cp != 0xff)
56554+ break;
56555+ b = (cp - netmask) << 3;
56556+ if (cp != cplim) {
56557+ if (*cp != 0) {
56558+ gotOddMasks = 1;
56559+ for (j = 0x80; j; b++, j >>= 1)
56560+ if ((j & *cp) == 0)
56561+ break;
56562+ }
56563+ }
56564+ x->rj_b = -1 - b;
56565+ return (x);
56566+}
56567+
56568+#if 0
56569+struct radij_node *
56570+#endif
56571+int
56572+rj_addroute(v_arg, n_arg, head, treenodes)
56573+ void *v_arg, *n_arg;
56574+ struct radij_node_head *head;
56575+ struct radij_node treenodes[2];
56576+{
56577+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
56578+ register struct radij_node *t, *x=NULL, *tt;
56579+ struct radij_node *saved_tt, *top = head->rnh_treetop;
56580+ short b = 0, b_leaf;
56581+ int mlen, keyduplicated;
56582+ caddr_t cplim;
56583+ struct radij_mask *m, **mp;
56584+
56585+ /*
56586+ * In dealing with non-contiguous masks, there may be
56587+ * many different routes which have the same mask.
56588+ * We will find it useful to have a unique pointer to
56589+ * the mask to speed avoiding duplicate references at
56590+ * nodes and possibly save time in calculating indices.
56591+ */
56592+ if (netmask) {
56593+ x = rj_search(netmask, rj_masktop);
56594+ mlen = *(u_char *)netmask;
56595+ if (Bcmp(netmask, x->rj_key, mlen) != 0) {
56596+ x = rj_addmask(netmask, 0, top->rj_off);
56597+ if (x == 0)
56598+ return -ENOMEM; /* (0) rgb */
56599+ }
56600+ netmask = x->rj_key;
56601+ b = -1 - x->rj_b;
56602+ }
56603+ /*
56604+ * Deal with duplicated keys: attach node to previous instance
56605+ */
56606+ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
56607+#ifdef RJ_DEBUG
56608+ printk("addkey: duplicated: %d\n", keyduplicated);
56609+#endif
56610+ if (keyduplicated) {
56611+ do {
56612+ if (tt->rj_mask == netmask)
56613+ return -EEXIST; /* -ENXIO; (0) rgb */
56614+ t = tt;
56615+ if (netmask == 0 ||
56616+ (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
56617+ break;
56618+ } while ((tt = tt->rj_dupedkey));
56619+ /*
56620+ * If the mask is not duplicated, we wouldn't
56621+ * find it among possible duplicate key entries
56622+ * anyway, so the above test doesn't hurt.
56623+ *
56624+ * We sort the masks for a duplicated key the same way as
56625+ * in a masklist -- most specific to least specific.
56626+ * This may require the unfortunate nuisance of relocating
56627+ * the head of the list.
56628+ */
56629+ if (tt && t == saved_tt) {
56630+ struct radij_node *xx = x;
56631+ /* link in at head of list */
56632+ (tt = treenodes)->rj_dupedkey = t;
56633+ tt->rj_flags = t->rj_flags;
56634+ tt->rj_p = x = t->rj_p;
56635+ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
56636+ saved_tt = tt; x = xx;
56637+ } else {
56638+ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
56639+ t->rj_dupedkey = tt;
56640+ }
56641+#ifdef RJ_DEBUG
56642+ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
56643+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
56644+#endif /* RJ_DEBUG */
56645+ t = saved_tt;
56646+ tt->rj_key = (caddr_t) v;
56647+ tt->rj_b = -1;
56648+ tt->rj_flags = t->rj_flags & ~RJF_ROOT;
56649+ }
56650+ /*
56651+ * Put mask in tree.
56652+ */
56653+ if (netmask) {
56654+ tt->rj_mask = netmask;
56655+ tt->rj_b = x->rj_b;
56656+ }
56657+ t = saved_tt->rj_p;
56658+ b_leaf = -1 - t->rj_b;
56659+ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
56660+ /* Promote general routes from below */
56661+ if (x->rj_b < 0) {
56662+ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
56663+ MKGet(m);
56664+ if (m) {
56665+ Bzero(m, sizeof *m);
56666+ m->rm_b = x->rj_b;
56667+ m->rm_mask = x->rj_mask;
56668+ x->rj_mklist = t->rj_mklist = m;
56669+ }
56670+ }
56671+ } else if (x->rj_mklist) {
56672+ /*
56673+ * Skip over masks whose index is > that of new node
56674+ */
56675+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
56676+ if (m->rm_b >= b_leaf)
56677+ break;
56678+ t->rj_mklist = m; *mp = 0;
56679+ }
56680+ /* Add new route to highest possible ancestor's list */
56681+ if ((netmask == 0) || (b > t->rj_b )) {
56682+#ifdef RJ_DEBUG
56683+ printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b);
56684+#endif
56685+ return 0; /* tt rgb */ /* can't lift at all */
56686+ }
56687+ b_leaf = tt->rj_b;
56688+ do {
56689+ x = t;
56690+ t = t->rj_p;
56691+ } while (b <= t->rj_b && x != top);
56692+ /*
56693+ * Search through routes associated with node to
56694+ * insert new route according to index.
56695+ * For nodes of equal index, place more specific
56696+ * masks first.
56697+ */
56698+ cplim = netmask + mlen;
56699+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
56700+ if (m->rm_b < b_leaf)
56701+ continue;
56702+ if (m->rm_b > b_leaf)
56703+ break;
56704+ if (m->rm_mask == netmask) {
56705+ m->rm_refs++;
56706+ tt->rj_mklist = m;
56707+#ifdef RJ_DEBUG
56708+ printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask);
56709+#endif
56710+ return 0; /* tt rgb */
56711+ }
56712+ if (rj_refines(netmask, m->rm_mask))
56713+ break;
56714+ }
56715+ MKGet(m);
56716+ if (m == 0) {
56717+ printk("klips_debug:rj_addroute: "
56718+ "Mask for route not entered\n");
56719+ return 0; /* (tt) rgb */
56720+ }
56721+ Bzero(m, sizeof *m);
56722+ m->rm_b = b_leaf;
56723+ m->rm_mask = netmask;
56724+ m->rm_mklist = *mp;
56725+ *mp = m;
56726+ tt->rj_mklist = m;
56727+#ifdef RJ_DEBUG
56728+ printk("klips:radij.c: addroute done\n");
56729+#endif
56730+ return 0; /* tt rgb */
56731+}
56732+
56733+int
56734+rj_delete(v_arg, netmask_arg, head, node)
56735+ void *v_arg, *netmask_arg;
56736+ struct radij_node_head *head;
56737+ struct radij_node **node;
56738+{
56739+ register struct radij_node *t, *p, *x, *tt;
56740+ struct radij_mask *m, *saved_m, **mp;
56741+ struct radij_node *dupedkey, *saved_tt, *top;
56742+ caddr_t v, netmask;
56743+ int b, head_off, vlen;
56744+
56745+ v = v_arg;
56746+ netmask = netmask_arg;
56747+ x = head->rnh_treetop;
56748+ tt = rj_search(v, x);
56749+ head_off = x->rj_off;
56750+ vlen = *(u_char *)v;
56751+ saved_tt = tt;
56752+ top = x;
56753+ if (tt == 0 ||
56754+ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
56755+ return -EFAULT; /* (0) rgb */
56756+ /*
56757+ * Delete our route from mask lists.
56758+ */
56759+ if ((dupedkey = tt->rj_dupedkey)) {
56760+ if (netmask)
56761+ netmask = rj_search(netmask, rj_masktop)->rj_key;
56762+ while (tt->rj_mask != netmask)
56763+ if ((tt = tt->rj_dupedkey) == 0)
56764+ return -ENOENT; /* -ENXIO; (0) rgb */
56765+ }
56766+ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
56767+ goto on1;
56768+ if (m->rm_mask != tt->rj_mask) {
56769+ printk("klips_debug:rj_delete: "
56770+ "inconsistent annotation\n");
56771+ goto on1;
56772+ }
56773+ if (--m->rm_refs >= 0)
56774+ goto on1;
56775+ b = -1 - tt->rj_b;
56776+ t = saved_tt->rj_p;
56777+ if (b > t->rj_b)
56778+ goto on1; /* Wasn't lifted at all */
56779+ do {
56780+ x = t;
56781+ t = t->rj_p;
56782+ } while (b <= t->rj_b && x != top);
56783+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
56784+ if (m == saved_m) {
56785+ *mp = m->rm_mklist;
56786+ MKFree(m);
56787+ break;
56788+ }
56789+ if (m == 0)
56790+ printk("klips_debug:rj_delete: "
56791+ "couldn't find our annotation\n");
56792+on1:
56793+ /*
56794+ * Eliminate us from tree
56795+ */
56796+ if (tt->rj_flags & RJF_ROOT)
56797+ return -EFAULT; /* (0) rgb */
56798+#ifdef RJ_DEBUG
56799+ /* Get us out of the creation list */
56800+ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
56801+ if (t) t->rj_ybro = tt->rj_ybro;
56802+#endif /* RJ_DEBUG */
56803+ t = tt->rj_p;
56804+ if (dupedkey) {
56805+ if (tt == saved_tt) {
56806+ x = dupedkey; x->rj_p = t;
56807+ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
56808+ } else {
56809+ for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
56810+ p = p->rj_dupedkey;
56811+ if (p) p->rj_dupedkey = tt->rj_dupedkey;
56812+ else printk("klips_debug:rj_delete: "
56813+ "couldn't find node that we started with\n");
56814+ }
56815+ t = tt + 1;
56816+ if (t->rj_flags & RJF_ACTIVE) {
56817+#ifndef RJ_DEBUG
56818+ *++x = *t; p = t->rj_p;
56819+#else
56820+ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
56821+#endif /* RJ_DEBUG */
56822+ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
56823+ x->rj_l->rj_p = x; x->rj_r->rj_p = x;
56824+ }
56825+ goto out;
56826+ }
56827+ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
56828+ p = t->rj_p;
56829+ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
56830+ x->rj_p = p;
56831+ /*
56832+ * Demote routes attached to us.
56833+ */
56834+ if (t->rj_mklist) {
56835+ if (x->rj_b >= 0) {
56836+ for (mp = &x->rj_mklist; (m = *mp);)
56837+ mp = &m->rm_mklist;
56838+ *mp = t->rj_mklist;
56839+ } else {
56840+ for (m = t->rj_mklist; m;) {
56841+ struct radij_mask *mm = m->rm_mklist;
56842+ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
56843+ x->rj_mklist = 0;
56844+ MKFree(m);
56845+ } else
56846+ printk("klips_debug:rj_delete: "
56847+ "Orphaned Mask 0p%p at 0p%p\n", m, x);
56848+ m = mm;
56849+ }
56850+ }
56851+ }
56852+ /*
56853+ * We may be holding an active internal node in the tree.
56854+ */
56855+ x = tt + 1;
56856+ if (t != x) {
56857+#ifndef RJ_DEBUG
56858+ *t = *x;
56859+#else
56860+ b = t->rj_info; *t = *x; t->rj_info = b;
56861+#endif /* RJ_DEBUG */
56862+ t->rj_l->rj_p = t; t->rj_r->rj_p = t;
56863+ p = x->rj_p;
56864+ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
56865+ }
56866+out:
56867+ tt->rj_flags &= ~RJF_ACTIVE;
56868+ tt[1].rj_flags &= ~RJF_ACTIVE;
56869+ *node = tt;
56870+ return 0; /* (tt) rgb */
56871+}
56872+
56873+int
56874+rj_walktree(h, f, w)
56875+ struct radij_node_head *h;
56876+ register int (*f)(struct radij_node *,void *);
56877+ void *w;
56878+{
56879+ int error;
56880+ struct radij_node *base, *next;
56881+ register struct radij_node *rn;
56882+
56883+ if(!h || !f /* || !w */) {
56884+ return -ENODATA;
56885+ }
56886+
56887+ rn = h->rnh_treetop;
56888+ /*
56889+ * This gets complicated because we may delete the node
56890+ * while applying the function f to it, so we need to calculate
56891+ * the successor node in advance.
56892+ */
56893+ /* First time through node, go left */
56894+ while (rn->rj_b >= 0)
56895+ rn = rn->rj_l;
56896+ for (;;) {
56897+#ifdef CONFIG_KLIPS_DEBUG
56898+ if(debug_radij) {
56899+ printk("klips_debug:rj_walktree: "
56900+ "for: rn=0p%p rj_b=%d rj_flags=%x",
56901+ rn,
56902+ rn->rj_b,
56903+ rn->rj_flags);
56904+ rn->rj_b >= 0 ?
56905+ printk(" node off=%x\n",
56906+ rn->rj_off) :
56907+ printk(" leaf key = %08x->%08x\n",
56908+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56909+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56910+ ;
56911+ }
56912+#endif /* CONFIG_KLIPS_DEBUG */
56913+ base = rn;
56914+ /* If at right child go back up, otherwise, go right */
56915+ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
56916+ rn = rn->rj_p;
56917+ /* Find the next *leaf* since next node might vanish, too */
56918+ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
56919+ rn = rn->rj_l;
56920+ next = rn;
56921+#ifdef CONFIG_KLIPS_DEBUG
56922+ if(debug_radij) {
56923+ printk("klips_debug:rj_walktree: "
56924+ "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
56925+ rn,
56926+ rn->rj_b,
56927+ rn->rj_flags);
56928+ rn->rj_b >= 0 ?
56929+ printk(" node off=%x\n",
56930+ rn->rj_off) :
56931+ printk(" leaf key = %08x->%08x\n",
56932+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56933+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56934+ ;
56935+ }
56936+#endif /* CONFIG_KLIPS_DEBUG */
56937+ /* Process leaves */
56938+ while ((rn = base)) {
56939+ base = rn->rj_dupedkey;
56940+#ifdef CONFIG_KLIPS_DEBUG
56941+ if(debug_radij) {
56942+ printk("klips_debug:rj_walktree: "
56943+ "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
56944+ base,
56945+ rn,
56946+ rn->rj_b,
56947+ rn->rj_flags);
56948+ rn->rj_b >= 0 ?
56949+ printk(" node off=%x\n",
56950+ rn->rj_off) :
56951+ printk(" leaf key = %08x->%08x\n",
56952+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56953+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56954+ ;
56955+ }
56956+#endif /* CONFIG_KLIPS_DEBUG */
56957+ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
56958+ return (-error);
56959+ }
56960+ rn = next;
56961+ if (rn->rj_flags & RJF_ROOT)
56962+ return (0);
56963+ }
56964+ /* NOTREACHED */
56965+}
56966+
56967+int
56968+rj_inithead(head, off)
56969+ void **head;
56970+ int off;
56971+{
56972+ register struct radij_node_head *rnh;
56973+ register struct radij_node *t, *tt, *ttt;
56974+ if (*head)
56975+ return (1);
56976+ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
56977+ if (rnh == NULL)
56978+ return (0);
56979+ Bzero(rnh, sizeof (*rnh));
56980+ *head = rnh;
56981+ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
56982+ ttt = rnh->rnh_nodes + 2;
56983+ t->rj_r = ttt;
56984+ t->rj_p = t;
56985+ tt = t->rj_l;
56986+ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
56987+ tt->rj_b = -1 - off;
56988+ *ttt = *tt;
56989+ ttt->rj_key = rj_ones;
56990+ rnh->rnh_addaddr = rj_addroute;
56991+ rnh->rnh_deladdr = rj_delete;
56992+ rnh->rnh_matchaddr = rj_match;
56993+ rnh->rnh_walktree = rj_walktree;
56994+ rnh->rnh_treetop = t;
56995+ return (1);
56996+}
56997+
56998+void
56999+rj_init()
57000+{
57001+ char *cp, *cplim;
57002+
57003+ if (maj_keylen == 0) {
57004+ printk("klips_debug:rj_init: "
57005+ "radij functions require maj_keylen be set\n");
57006+ return;
57007+ }
57008+ R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
57009+ if (rj_zeroes == NULL)
57010+ panic("rj_init");
57011+ Bzero(rj_zeroes, 3 * maj_keylen);
57012+ rj_ones = cp = rj_zeroes + maj_keylen;
57013+ maskedKey = cplim = rj_ones + maj_keylen;
57014+ while (cp < cplim)
57015+ *cp++ = -1;
57016+ if (rj_inithead((void **)&mask_rjhead, 0) == 0)
57017+ panic("rj_init 2");
57018+}
57019+
57020+void
57021+rj_preorder(struct radij_node *rn, int l)
57022+{
57023+ int i;
57024+
57025+ if (rn == NULL){
57026+ printk("klips_debug:rj_preorder: "
57027+ "NULL pointer\n");
57028+ return;
57029+ }
57030+
57031+ if (rn->rj_b >= 0){
57032+ rj_preorder(rn->rj_l, l+1);
57033+ rj_preorder(rn->rj_r, l+1);
57034+ printk("klips_debug:");
57035+ for (i=0; i<l; i++)
57036+ printk("*");
57037+ printk(" off = %d\n",
57038+ rn->rj_off);
57039+ } else {
57040+ printk("klips_debug:");
57041+ for (i=0; i<l; i++)
57042+ printk("@");
57043+ printk(" flags = %x",
57044+ (u_int)rn->rj_flags);
57045+ if (rn->rj_flags & RJF_ACTIVE) {
57046+ printk(" @key=0p%p",
57047+ rn->rj_key);
57048+ printk(" key = %08x->%08x",
57049+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
57050+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
57051+ printk(" @mask=0p%p",
57052+ rn->rj_mask);
57053+ if (rn->rj_mask)
57054+ printk(" mask = %08x->%08x",
57055+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
57056+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
57057+ if (rn->rj_dupedkey)
57058+ printk(" dupedkey = 0p%p",
57059+ rn->rj_dupedkey);
57060+ }
57061+ printk("\n");
57062+ }
57063+}
57064+
57065+#ifdef RJ_DEBUG
57066+DEBUG_NO_STATIC void traverse(struct radij_node *p)
57067+{
57068+ rj_preorder(p, 0);
57069+}
57070+#endif /* RJ_DEBUG */
57071+
57072+void
57073+rj_dumptrees(void)
57074+{
57075+ rj_preorder(rnh->rnh_treetop, 0);
57076+}
57077+
57078+void
57079+rj_free_mkfreelist(void)
57080+{
57081+ struct radij_mask *mknp, *mknp2;
57082+
57083+ mknp = rj_mkfreelist;
57084+ while(mknp)
57085+ {
57086+ mknp2 = mknp;
57087+ mknp = mknp->rm_mklist;
57088+ kfree(mknp2);
57089+ }
57090+}
57091+
57092+int
57093+radijcleartree(void)
57094+{
57095+ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
57096+}
57097+
57098+int
57099+radijcleanup(void)
57100+{
57101+ int error = 0;
57102+
57103+ error = radijcleartree();
57104+
57105+ rj_free_mkfreelist();
57106+
57107+/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
57108+ if(mask_rjhead) {
57109+ kfree(mask_rjhead);
57110+ }
57111+
57112+ if(rj_zeroes) {
57113+ kfree(rj_zeroes);
57114+ }
57115+
57116+ if(rnh) {
57117+ kfree(rnh);
57118+ }
57119+
57120+ return error;
57121+}
57122+
57123+/*
57124+ * $Log: radij.c,v $
57125+ * Revision 1.48.2.1 2006-10-06 21:39:27 paul
57126+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
57127+ * set. This is defined through autoconf.h which is included through the
57128+ * linux kernel build macros.
57129+ *
57130+ * Revision 1.48 2005/04/29 05:10:22 mcr
57131+ * removed from extraenous includes to make unit testing easier.
57132+ *
57133+ * Revision 1.47 2004/07/10 19:11:18 mcr
57134+ * CONFIG_IPSEC -> CONFIG_KLIPS.
57135+ *
57136+ * Revision 1.46 2004/04/06 02:49:26 mcr
57137+ * pullup of algo code from alg-branch.
57138+ *
57139+ * Revision 1.45 2003/10/31 02:27:55 mcr
57140+ * pulled up port-selector patches and sa_id elimination.
57141+ *
57142+ * Revision 1.44.30.1 2003/10/29 01:30:41 mcr
57143+ * elimited "struct sa_id".
57144+ *
57145+ * Revision 1.44 2002/07/24 18:44:54 rgb
57146+ * Type fiddling to tame ia64 compiler.
57147+ *
57148+ * Revision 1.43 2002/05/23 07:14:11 rgb
57149+ * Cleaned up %p variants to 0p%p for test suite cleanup.
57150+ *
57151+ * Revision 1.42 2002/04/24 07:55:32 mcr
57152+ * #include patches and Makefiles for post-reorg compilation.
57153+ *
57154+ * Revision 1.41 2002/04/24 07:36:35 mcr
57155+ * Moved from ./klips/net/ipsec/radij.c,v
57156+ *
57157+ * Revision 1.40 2002/01/29 17:17:58 mcr
57158+ * moved include of ipsec_param.h to after include of linux/kernel.h
57159+ * otherwise, it seems that some option that is set in ipsec_param.h
57160+ * screws up something subtle in the include path to kernel.h, and
57161+ * it complains on the snprintf() prototype.
57162+ *
57163+ * Revision 1.39 2002/01/29 04:00:55 mcr
57164+ * more excise of kversions.h header.
57165+ *
57166+ * Revision 1.38 2002/01/29 02:13:19 mcr
57167+ * introduction of ipsec_kversion.h means that include of
57168+ * ipsec_param.h must preceed any decisions about what files to
57169+ * include to deal with differences in kernel source.
57170+ *
57171+ * Revision 1.37 2001/10/18 04:45:23 rgb
57172+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
57173+ * lib/freeswan.h version macros moved to lib/kversions.h.
57174+ * Other compiler directive cleanups.
57175+ *
57176+ * Revision 1.36 2001/08/22 13:43:51 henry
57177+ * eliminate the single use of min() to avoid problems with Linus changing it
57178+ *
57179+ * Revision 1.35 2001/06/15 04:57:29 rgb
57180+ * Clarified error return codes.
57181+ * Changed mask add already exists to EEXIST.
57182+ * Changed mask delete did not exist to ENOENT.
57183+ *
57184+ * Revision 1.34 2001/05/03 19:44:26 rgb
57185+ * Fix sign of error return codes for rj_addroute().
57186+ *
57187+ * Revision 1.33 2001/02/27 22:24:56 rgb
57188+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
57189+ * Check for satoa() return codes.
57190+ *
57191+ * Revision 1.32 2001/02/27 06:23:15 rgb
57192+ * Debug line splitting.
57193+ *
57194+ * Revision 1.31 2000/11/06 04:35:21 rgb
57195+ * Clear table *before* releasing other items in radijcleanup.
57196+ *
57197+ * Revision 1.30 2000/09/20 04:07:40 rgb
57198+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
57199+ * oopsen.
57200+ *
57201+ * Revision 1.29 2000/09/12 03:25:02 rgb
57202+ * Moved radij_c_version printing to ipsec_version_get_info().
57203+ *
57204+ * Revision 1.28 2000/09/08 19:12:56 rgb
57205+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
57206+ *
57207+ * Revision 1.27 2000/07/28 14:58:32 rgb
57208+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
57209+ *
57210+ * Revision 1.26 2000/05/10 23:11:37 rgb
57211+ * Comment out most of the startup version information.
57212+ *
57213+ * Revision 1.25 2000/01/21 06:21:47 rgb
57214+ * Change return codes to negative on error.
57215+ *
57216+ * Revision 1.24 1999/11/18 04:09:20 rgb
57217+ * Replaced all kernel version macros to shorter, readable form.
57218+ *
57219+ * Revision 1.23 1999/11/17 15:53:41 rgb
57220+ * Changed all occurrences of #include "../../../lib/freeswan.h"
57221+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
57222+ * klips/net/ipsec/Makefile.
57223+ *
57224+ * Revision 1.22 1999/10/15 22:17:28 rgb
57225+ * Modify radijcleanup() to call radijcleartree().
57226+ *
57227+ * Revision 1.21 1999/10/08 18:37:34 rgb
57228+ * Fix end-of-line spacing to sate whining PHMs.
57229+ *
57230+ * Revision 1.20 1999/10/01 15:44:54 rgb
57231+ * Move spinlock header include to 2.1> scope.
57232+ *
57233+ * Revision 1.19 1999/10/01 08:35:52 rgb
57234+ * Add spinlock include to shut up compiler for 2.0.38.
57235+ *
57236+ * Revision 1.18 1999/09/23 18:02:52 rgb
57237+ * De-alarm the search failure message so it doesn't sound so grave.
57238+ *
57239+ * Revision 1.17 1999/05/25 21:26:01 rgb
57240+ * Fix rj_walktree() sanity checking bug.
57241+ *
57242+ * Revision 1.16 1999/05/09 03:25:38 rgb
57243+ * Fix bug introduced by 2.2 quick-and-dirty patch.
57244+ *
57245+ * Revision 1.15 1999/05/05 22:02:33 rgb
57246+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
57247+ *
57248+ * Revision 1.14 1999/04/29 15:24:15 rgb
57249+ * Add sanity checking for null pointer arguments.
57250+ * Standardise an error return method.
57251+ *
57252+ * Revision 1.13 1999/04/11 00:29:02 henry
57253+ * GPL boilerplate
57254+ *
57255+ * Revision 1.12 1999/04/06 04:54:28 rgb
57256+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
57257+ * patch shell fixes.
57258+ *
57259+ * Revision 1.11 1999/02/17 16:52:53 rgb
57260+ * Convert DEBUG_IPSEC to KLIPS_PRINT
57261+ * Clean out unused cruft.
57262+ *
57263+ * Revision 1.10 1999/01/22 06:30:05 rgb
57264+ * Cruft clean-out.
57265+ * 64-bit clean-up.
57266+ *
57267+ * Revision 1.9 1998/12/01 13:22:04 rgb
57268+ * Added support for debug printing of version info.
57269+ *
57270+ * Revision 1.8 1998/11/30 13:22:55 rgb
57271+ * Rationalised all the klips kernel file headers. They are much shorter
57272+ * now and won't conflict under RH5.2.
57273+ *
57274+ * Revision 1.7 1998/10/25 02:43:26 rgb
57275+ * Change return type on rj_addroute and rj_delete and add and argument
57276+ * to the latter to be able to transmit more infomation about errors.
57277+ *
57278+ * Revision 1.6 1998/10/19 14:30:06 rgb
57279+ * Added inclusion of freeswan.h.
57280+ *
57281+ * Revision 1.5 1998/10/09 04:33:27 rgb
57282+ * Added 'klips_debug' prefix to all klips printk debug statements.
57283+ * Fixed output formatting slightly.
57284+ *
57285+ * Revision 1.4 1998/07/28 00:06:59 rgb
57286+ * Add debug detail to tree traversing.
57287+ *
57288+ * Revision 1.3 1998/07/14 18:07:58 rgb
57289+ * Add a routine to clear the eroute tree.
57290+ *
57291+ * Revision 1.2 1998/06/25 20:03:22 rgb
57292+ * Cleanup #endif comments. Debug output for rj_init.
57293+ *
57294+ * Revision 1.1 1998/06/18 21:30:22 henry
57295+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
57296+ * build scripts happier about symlinks
57297+ *
57298+ * Revision 1.8 1998/05/25 20:34:15 rgb
57299+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
57300+ *
57301+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
57302+ * add ipsec_rj_walker_delete.
57303+ *
57304+ * Recover memory for eroute table on unload of module.
57305+ *
57306+ * Revision 1.7 1998/05/21 12:58:58 rgb
57307+ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
57308+ *
57309+ * Revision 1.6 1998/04/23 20:57:29 rgb
57310+ * Cleaned up compiler warnings for unused debugging functions.
57311+ *
57312+ * Revision 1.5 1998/04/22 16:51:38 rgb
57313+ * Tidy up radij debug code from recent rash of modifications to debug code.
57314+ *
57315+ * Revision 1.4 1998/04/21 21:28:56 rgb
57316+ * Rearrange debug switches to change on the fly debug output from user
57317+ * space. Only kernel changes checked in at this time. radij.c was also
57318+ * changed to temporarily remove buggy debugging code in rj_delete causing
57319+ * an OOPS and hence, netlink device open errors.
57320+ *
57321+ * Revision 1.3 1998/04/14 17:30:37 rgb
57322+ * Fix up compiling errors for radij tree memory reclamation.
57323+ *
57324+ * Revision 1.2 1998/04/12 22:03:25 rgb
57325+ * Updated ESP-3DES-HMAC-MD5-96,
57326+ * ESP-DES-HMAC-MD5-96,
57327+ * AH-HMAC-MD5-96,
57328+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
57329+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
57330+ *
57331+ * Fixed eroute references in /proc/net/ipsec*.
57332+ *
57333+ * Started to patch module unloading memory leaks in ipsec_netlink and
57334+ * radij tree unloading.
57335+ *
57336+ * Revision 1.1 1998/04/09 03:06:15 henry
57337+ * sources moved up from linux/net/ipsec
57338+ *
57339+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
57340+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
57341+ *
57342+ * Revision 0.4 1997/01/15 01:28:15 ji
57343+ * No changes.
57344+ *
57345+ * Revision 0.3 1996/11/20 14:39:04 ji
57346+ * Minor cleanups.
57347+ * Rationalized debugging code.
57348+ *
57349+ * Revision 0.2 1996/11/02 00:18:33 ji
57350+ * First limited release.
57351+ *
57352+ *
57353+ */
57354--- /dev/null Tue Mar 11 13:02:56 2003
57355+++ linux/net/ipsec/rangetoa.c Mon Feb 9 13:51:03 2004
57356@@ -0,0 +1,60 @@
57357+/*
57358+ * convert binary form of address range to ASCII
57359+ * Copyright (C) 1998, 1999 Henry Spencer.
57360+ *
57361+ * This library is free software; you can redistribute it and/or modify it
57362+ * under the terms of the GNU Library General Public License as published by
57363+ * the Free Software Foundation; either version 2 of the License, or (at your
57364+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57365+ *
57366+ * This library is distributed in the hope that it will be useful, but
57367+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57368+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57369+ * License for more details.
57370+ *
57371+ * RCSID $Id: rangetoa.c,v 1.9 2004-07-10 07:48:37 mcr Exp $
57372+ */
57373+#include "openswan.h"
57374+
57375+/*
57376+ - rangetoa - convert address range to ASCII
57377+ */
57378+size_t /* space needed for full conversion */
57379+rangetoa(addrs, format, dst, dstlen)
57380+struct in_addr addrs[2];
57381+int format; /* character */
57382+char *dst; /* need not be valid if dstlen is 0 */
57383+size_t dstlen;
57384+{
57385+ size_t len;
57386+ size_t rest;
57387+ int n;
57388+ char *p;
57389+
57390+ switch (format) {
57391+ case 0:
57392+ break;
57393+ default:
57394+ return 0;
57395+ break;
57396+ }
57397+
57398+ len = addrtoa(addrs[0], 0, dst, dstlen);
57399+ if (len < dstlen)
57400+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
57401+ p++, len++, n--)
57402+ *p = '.';
57403+ else
57404+ p = NULL;
57405+ if (len < dstlen)
57406+ rest = dstlen - len;
57407+ else {
57408+ if (dstlen > 0)
57409+ *(dst + dstlen - 1) = '\0';
57410+ rest = 0;
57411+ }
57412+
57413+ len += addrtoa(addrs[1], 0, p, rest);
57414+
57415+ return len;
57416+}
57417--- /dev/null Tue Mar 11 13:02:56 2003
57418+++ linux/net/ipsec/satot.c Mon Feb 9 13:51:03 2004
57419@@ -0,0 +1,133 @@
57420+/*
57421+ * convert from binary form of SA ID to text
57422+ * Copyright (C) 2000, 2001 Henry Spencer.
57423+ *
57424+ * This library is free software; you can redistribute it and/or modify it
57425+ * under the terms of the GNU Library General Public License as published by
57426+ * the Free Software Foundation; either version 2 of the License, or (at your
57427+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57428+ *
57429+ * This library is distributed in the hope that it will be useful, but
57430+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57431+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57432+ * License for more details.
57433+ *
57434+ * RCSID $Id: satot.c,v 1.13 2004-07-10 07:48:37 mcr Exp $
57435+ */
57436+#include "openswan.h"
57437+
57438+static struct typename {
57439+ char type;
57440+ char *name;
57441+} typenames[] = {
57442+ { SA_AH, "ah" },
57443+ { SA_ESP, "esp" },
57444+ { SA_IPIP, "tun" },
57445+ { SA_COMP, "comp" },
57446+ { SA_INT, "int" },
57447+ { 0, NULL }
57448+};
57449+
57450+/*
57451+ - satot - convert SA to text "ah507@1.2.3.4"
57452+ */
57453+size_t /* space needed for full conversion */
57454+satot(sa, format, dst, dstlen)
57455+const ip_said *sa;
57456+int format; /* character */
57457+char *dst; /* need not be valid if dstlen is 0 */
57458+size_t dstlen;
57459+{
57460+ size_t len = 0; /* 0 means "not recognized yet" */
57461+ int base;
57462+ int showversion; /* use delimiter to show IP version? */
57463+ struct typename *tn;
57464+ char *p;
57465+ char *pre;
57466+ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
57467+ char unk[10];
57468+
57469+ switch (format) {
57470+ case 0:
57471+ base = 16;
57472+ showversion = 1;
57473+ break;
57474+ case 'f':
57475+ base = 17;
57476+ showversion = 1;
57477+ break;
57478+ case 'x':
57479+ base = 'x';
57480+ showversion = 0;
57481+ break;
57482+ case 'd':
57483+ base = 10;
57484+ showversion = 0;
57485+ break;
57486+ default:
57487+ return 0;
57488+ break;
57489+ }
57490+
57491+ memset(buf, 0, sizeof(buf));
57492+
57493+ pre = NULL;
57494+ for (tn = typenames; tn->name != NULL; tn++)
57495+ if (sa->proto == tn->type) {
57496+ pre = tn->name;
57497+ break; /* NOTE BREAK OUT */
57498+ }
57499+ if (pre == NULL) { /* unknown protocol */
57500+ strcpy(unk, "unk");
57501+ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
57502+ sizeof(unk)-strlen(unk));
57503+ pre = unk;
57504+ }
57505+
57506+ if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
57507+ sa->spi == PASSTHROUGHSPI &&
57508+ isunspecaddr(&sa->dst)) {
57509+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
57510+ PASSTHROUGH4NAME :
57511+ PASSTHROUGH6NAME);
57512+ len = strlen(buf);
57513+ }
57514+
57515+ if (sa->proto == SA_INT) {
57516+ switch (ntohl(sa->spi)) {
57517+ case SPI_PASS: p = "%pass"; break;
57518+ case SPI_DROP: p = "%drop"; break;
57519+ case SPI_REJECT: p = "%reject"; break;
57520+ case SPI_HOLD: p = "%hold"; break;
57521+ case SPI_TRAP: p = "%trap"; break;
57522+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
57523+ default: p = NULL; break;
57524+ }
57525+ if (p != NULL) {
57526+ strcpy(buf, p);
57527+ len = strlen(buf);
57528+ }
57529+ }
57530+
57531+ if (len == 0) { /* general case needed */
57532+ strcpy(buf, pre);
57533+ len = strlen(buf);
57534+ if (showversion) {
57535+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
57536+ ':';
57537+ len++;
57538+ *(buf+len) = '\0';
57539+ }
57540+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
57541+ *(buf+len-1) = '@';
57542+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
57543+ *(buf+len) = '\0';
57544+ }
57545+
57546+ if (dst != NULL) {
57547+ if (len > dstlen)
57548+ *(buf+dstlen-1) = '\0';
57549+ strcpy(dst, buf);
57550+ }
57551+ return len;
57552+}
57553--- /dev/null Tue Mar 11 13:02:56 2003
57554+++ linux/net/ipsec/subnetof.c Mon Feb 9 13:51:03 2004
57555@@ -0,0 +1,59 @@
57556+/*
57557+ * minor network-address manipulation utilities
57558+ * Copyright (C) 1998, 1999 Henry Spencer.
57559+ *
57560+ * This library is free software; you can redistribute it and/or modify it
57561+ * under the terms of the GNU Library General Public License as published by
57562+ * the Free Software Foundation; either version 2 of the License, or (at your
57563+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57564+ *
57565+ * This library is distributed in the hope that it will be useful, but
57566+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57567+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57568+ * License for more details.
57569+ *
57570+ * RCSID $Id: subnetof.c,v 1.8 2004-07-10 07:48:37 mcr Exp $
57571+ */
57572+#include "openswan.h"
57573+
57574+/*
57575+ - subnetof - given address and mask, return subnet part
57576+ */
57577+struct in_addr
57578+subnetof(addr, mask)
57579+struct in_addr addr;
57580+struct in_addr mask;
57581+{
57582+ struct in_addr result;
57583+
57584+ result.s_addr = addr.s_addr & mask.s_addr;
57585+ return result;
57586+}
57587+
57588+/*
57589+ - hostof - given address and mask, return host part
57590+ */
57591+struct in_addr
57592+hostof(addr, mask)
57593+struct in_addr addr;
57594+struct in_addr mask;
57595+{
57596+ struct in_addr result;
57597+
57598+ result.s_addr = addr.s_addr & ~mask.s_addr;
57599+ return result;
57600+}
57601+
57602+/*
57603+ - broadcastof - given (network) address and mask, return broadcast address
57604+ */
57605+struct in_addr
57606+broadcastof(addr, mask)
57607+struct in_addr addr;
57608+struct in_addr mask;
57609+{
57610+ struct in_addr result;
57611+
57612+ result.s_addr = addr.s_addr | ~mask.s_addr;
57613+ return result;
57614+}
57615--- /dev/null Tue Mar 11 13:02:56 2003
57616+++ linux/net/ipsec/subnettoa.c Mon Feb 9 13:51:03 2004
57617@@ -0,0 +1,61 @@
57618+/*
57619+ * convert binary form of subnet description to ASCII
57620+ * Copyright (C) 1998, 1999 Henry Spencer.
57621+ *
57622+ * This library is free software; you can redistribute it and/or modify it
57623+ * under the terms of the GNU Library General Public License as published by
57624+ * the Free Software Foundation; either version 2 of the License, or (at your
57625+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57626+ *
57627+ * This library is distributed in the hope that it will be useful, but
57628+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57629+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57630+ * License for more details.
57631+ *
57632+ * RCSID $Id: subnettoa.c,v 1.11 2004-07-10 07:48:37 mcr Exp $
57633+ */
57634+#include "openswan.h"
57635+
57636+/*
57637+ - subnettoa - convert address and mask to ASCII "addr/mask"
57638+ * Output expresses the mask as a bit count if possible, else dotted decimal.
57639+ */
57640+size_t /* space needed for full conversion */
57641+subnettoa(addr, mask, format, dst, dstlen)
57642+struct in_addr addr;
57643+struct in_addr mask;
57644+int format; /* character */
57645+char *dst; /* need not be valid if dstlen is 0 */
57646+size_t dstlen;
57647+{
57648+ size_t len;
57649+ size_t rest;
57650+ int n;
57651+ char *p;
57652+
57653+ switch (format) {
57654+ case 0:
57655+ break;
57656+ default:
57657+ return 0;
57658+ break;
57659+ }
57660+
57661+ len = addrtoa(addr, 0, dst, dstlen);
57662+ if (len < dstlen) {
57663+ dst[len - 1] = '/';
57664+ p = dst + len;
57665+ rest = dstlen - len;
57666+ } else {
57667+ p = NULL;
57668+ rest = 0;
57669+ }
57670+
57671+ n = masktobits(mask);
57672+ if (n >= 0)
57673+ len += ultoa((unsigned long)n, 10, p, rest);
57674+ else
57675+ len += addrtoa(mask, 0, p, rest);
57676+
57677+ return len;
57678+}
57679--- /dev/null Tue Mar 11 13:02:56 2003
57680+++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004
57681@@ -0,0 +1,217 @@
57682+/*
57683+ * sysctl interface to net IPSEC subsystem.
57684+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
57685+ *
57686+ * This program is free software; you can redistribute it and/or modify it
57687+ * under the terms of the GNU General Public License as published by the
57688+ * Free Software Foundation; either version 2 of the License, or (at your
57689+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
57690+ *
57691+ * This program is distributed in the hope that it will be useful, but
57692+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57693+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57694+ * for more details.
57695+ *
57696+ * RCSID $Id: sysctl_net_ipsec.c,v 1.17.10.2 2007-10-30 21:42:25 paul Exp $
57697+ */
57698+
57699+/* -*- linux-c -*-
57700+ *
57701+ * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
57702+ */
57703+
57704+#include <linux/version.h>
57705+#include <linux/mm.h>
57706+#include <linux/sysctl.h>
57707+
57708+#include "openswan/ipsec_param.h"
57709+
57710+#ifdef CONFIG_SYSCTL
57711+
57712+#define NET_IPSEC 2112 /* Random number */
57713+#ifdef CONFIG_KLIPS_DEBUG
57714+extern int debug_ah;
57715+extern int debug_esp;
57716+extern int debug_tunnel;
57717+extern int debug_eroute;
57718+extern int debug_spi;
57719+extern int debug_radij;
57720+extern int debug_netlink;
57721+extern int debug_xform;
57722+extern int debug_rcv;
57723+extern int debug_pfkey;
57724+extern int sysctl_ipsec_debug_verbose;
57725+#ifdef CONFIG_KLIPS_IPCOMP
57726+extern int sysctl_ipsec_debug_ipcomp;
57727+#endif /* CONFIG_KLIPS_IPCOMP */
57728+#endif /* CONFIG_KLIPS_DEBUG */
57729+
57730+extern int sysctl_ipsec_icmp;
57731+extern int sysctl_ipsec_inbound_policy_check;
57732+extern int sysctl_ipsec_tos;
57733+int sysctl_ipsec_regress_pfkey_lossage;
57734+
57735+enum {
57736+#ifdef CONFIG_KLIPS_DEBUG
57737+ NET_IPSEC_DEBUG_AH=1,
57738+ NET_IPSEC_DEBUG_ESP=2,
57739+ NET_IPSEC_DEBUG_TUNNEL=3,
57740+ NET_IPSEC_DEBUG_EROUTE=4,
57741+ NET_IPSEC_DEBUG_SPI=5,
57742+ NET_IPSEC_DEBUG_RADIJ=6,
57743+ NET_IPSEC_DEBUG_NETLINK=7,
57744+ NET_IPSEC_DEBUG_XFORM=8,
57745+ NET_IPSEC_DEBUG_RCV=9,
57746+ NET_IPSEC_DEBUG_PFKEY=10,
57747+ NET_IPSEC_DEBUG_VERBOSE=11,
57748+ NET_IPSEC_DEBUG_IPCOMP=12,
57749+#endif /* CONFIG_KLIPS_DEBUG */
57750+ NET_IPSEC_ICMP=13,
57751+ NET_IPSEC_INBOUND_POLICY_CHECK=14,
57752+ NET_IPSEC_TOS=15,
57753+ NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
57754+};
57755+
57756+static ctl_table ipsec_table[] = {
57757+#ifdef CONFIG_KLIPS_DEBUG
57758+ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
57759+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57760+ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
57761+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57762+ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
57763+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57764+ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
57765+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57766+ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
57767+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57768+ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
57769+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57770+ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
57771+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57772+ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
57773+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57774+ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
57775+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57776+ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
57777+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57778+ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
57779+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57780+#ifdef CONFIG_KLIPS_IPCOMP
57781+ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
57782+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57783+#endif /* CONFIG_KLIPS_IPCOMP */
57784+
57785+#ifdef CONFIG_KLIPS_REGRESS
57786+ { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
57787+ &sysctl_ipsec_regress_pfkey_lossage,
57788+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57789+#endif /* CONFIG_KLIPS_REGRESS */
57790+
57791+#endif /* CONFIG_KLIPS_DEBUG */
57792+ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
57793+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57794+ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
57795+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57796+ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
57797+ sizeof(int), 0644, NULL, .proc_handler = &proc_dointvec},
57798+ {0}
57799+};
57800+
57801+static ctl_table ipsec_net_table[] = {
57802+ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
57803+ { 0 }
57804+};
57805+
57806+static ctl_table ipsec_root_table[] = {
57807+ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
57808+ { 0 }
57809+};
57810+
57811+static struct ctl_table_header *ipsec_table_header;
57812+
57813+int ipsec_sysctl_register(void)
57814+{
57815+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
57816+ ipsec_table_header = register_sysctl_table(ipsec_root_table);
57817+#else
57818+ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
57819+#endif
57820+ if (!ipsec_table_header) {
57821+ return -ENOMEM;
57822+ }
57823+ return 0;
57824+}
57825+
57826+void ipsec_sysctl_unregister(void)
57827+{
57828+ unregister_sysctl_table(ipsec_table_header);
57829+}
57830+
57831+#endif /* CONFIG_SYSCTL */
57832+
57833+/*
57834+ * $Log: sysctl_net_ipsec.c,v $
57835+ * Revision 1.17.10.2 2007-10-30 21:42:25 paul
57836+ * The kernel has changed the layout of ctl_table (defined in
57837+ * linux/sysctl.h). Unfortunately, a new field has been inserted before
57838+ * the last one we wish to initialize in ipsec_table.
57839+ *
57840+ * The easiest fix that works with old and new kernels is to use an
57841+ * initializer that explicitly says which field is being initialized.
57842+ *
57843+ * Patch by dhr
57844+ *
57845+ * Revision 1.17.10.1 2007/09/05 02:54:13 paul
57846+ * register_sysctl_table() takes one argument for 2.6.21+ [david]
57847+ *
57848+ * Revision 1.17 2004/07/10 19:11:18 mcr
57849+ * CONFIG_IPSEC -> CONFIG_KLIPS.
57850+ *
57851+ * Revision 1.16 2004/04/06 02:49:26 mcr
57852+ * pullup of algo code from alg-branch.
57853+ *
57854+ * Revision 1.15 2002/04/24 07:55:32 mcr
57855+ * #include patches and Makefiles for post-reorg compilation.
57856+ *
57857+ * Revision 1.14 2002/04/24 07:36:35 mcr
57858+ * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
57859+ *
57860+ * Revision 1.13 2002/01/12 02:58:32 mcr
57861+ * first regression test causes acquire messages to be lost
57862+ * 100% of the time. This is to help testing of pluto.
57863+ *
57864+ * Revision 1.12 2001/06/14 19:35:13 rgb
57865+ * Update copyright date.
57866+ *
57867+ * Revision 1.11 2001/02/26 19:58:13 rgb
57868+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
57869+ *
57870+ * Revision 1.10 2000/09/16 01:50:15 rgb
57871+ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
57872+ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
57873+ *
57874+ * Revision 1.9 2000/09/15 23:17:51 rgb
57875+ * Moved stuff around to compile with debug off.
57876+ *
57877+ * Revision 1.8 2000/09/15 11:37:02 rgb
57878+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
57879+ * IPCOMP zlib deflate code.
57880+ *
57881+ * Revision 1.7 2000/09/15 07:37:15 rgb
57882+ * Munged silly log comment that was causing a warning.
57883+ *
57884+ * Revision 1.6 2000/09/15 04:58:23 rgb
57885+ * Added tos runtime switch.
57886+ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
57887+ *
57888+ * Revision 1.5 2000/09/12 03:25:28 rgb
57889+ * Filled in and implemented sysctl.
57890+ *
57891+ * Revision 1.4 1999/04/11 00:29:03 henry
57892+ * GPL boilerplate
57893+ *
57894+ * Revision 1.3 1999/04/06 04:54:29 rgb
57895+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
57896+ * patch shell fixes.
57897+ *
57898+ */
57899--- /dev/null Tue Mar 11 13:02:56 2003
57900+++ linux/net/ipsec/trees.c Mon Feb 9 13:51:03 2004
57901@@ -0,0 +1,1214 @@
57902+/* trees.c -- output deflated data using Huffman coding
57903+ * Copyright (C) 1995-2002 Jean-loup Gailly
57904+ * For conditions of distribution and use, see copyright notice in zlib.h
57905+ */
57906+
57907+/*
57908+ * ALGORITHM
57909+ *
57910+ * The "deflation" process uses several Huffman trees. The more
57911+ * common source values are represented by shorter bit sequences.
57912+ *
57913+ * Each code tree is stored in a compressed form which is itself
57914+ * a Huffman encoding of the lengths of all the code strings (in
57915+ * ascending order by source values). The actual code strings are
57916+ * reconstructed from the lengths in the inflate process, as described
57917+ * in the deflate specification.
57918+ *
57919+ * REFERENCES
57920+ *
57921+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
57922+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
57923+ *
57924+ * Storer, James A.
57925+ * Data Compression: Methods and Theory, pp. 49-50.
57926+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
57927+ *
57928+ * Sedgewick, R.
57929+ * Algorithms, p290.
57930+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
57931+ */
57932+
57933+/* @(#) $Id: trees.c,v 1.4 2004-07-10 07:48:39 mcr Exp $ */
57934+
57935+/* #define GEN_TREES_H */
57936+
57937+#include "deflate.h"
57938+
57939+#ifdef DEBUG
57940+# include <ctype.h>
57941+#endif
57942+
57943+/* ===========================================================================
57944+ * Constants
57945+ */
57946+
57947+#define MAX_BL_BITS 7
57948+/* Bit length codes must not exceed MAX_BL_BITS bits */
57949+
57950+#define END_BLOCK 256
57951+/* end of block literal code */
57952+
57953+#define REP_3_6 16
57954+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
57955+
57956+#define REPZ_3_10 17
57957+/* repeat a zero length 3-10 times (3 bits of repeat count) */
57958+
57959+#define REPZ_11_138 18
57960+/* repeat a zero length 11-138 times (7 bits of repeat count) */
57961+
57962+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
57963+ = {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};
57964+
57965+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
57966+ = {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};
57967+
57968+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
57969+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
57970+
57971+local const uch bl_order[BL_CODES]
57972+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
57973+/* The lengths of the bit length codes are sent in order of decreasing
57974+ * probability, to avoid transmitting the lengths for unused bit length codes.
57975+ */
57976+
57977+#define Buf_size (8 * 2*sizeof(char))
57978+/* Number of bits used within bi_buf. (bi_buf might be implemented on
57979+ * more than 16 bits on some systems.)
57980+ */
57981+
57982+/* ===========================================================================
57983+ * Local data. These are initialized only once.
57984+ */
57985+
57986+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
57987+
57988+#if defined(GEN_TREES_H) || !defined(STDC)
57989+/* non ANSI compilers may not accept trees.h */
57990+
57991+local ct_data static_ltree[L_CODES+2];
57992+/* The static literal tree. Since the bit lengths are imposed, there is no
57993+ * need for the L_CODES extra codes used during heap construction. However
57994+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
57995+ * below).
57996+ */
57997+
57998+local ct_data static_dtree[D_CODES];
57999+/* The static distance tree. (Actually a trivial tree since all codes use
58000+ * 5 bits.)
58001+ */
58002+
58003+uch _dist_code[DIST_CODE_LEN];
58004+/* Distance codes. The first 256 values correspond to the distances
58005+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
58006+ * the 15 bit distances.
58007+ */
58008+
58009+uch _length_code[MAX_MATCH-MIN_MATCH+1];
58010+/* length code for each normalized match length (0 == MIN_MATCH) */
58011+
58012+local int base_length[LENGTH_CODES];
58013+/* First normalized length for each code (0 = MIN_MATCH) */
58014+
58015+local int base_dist[D_CODES];
58016+/* First normalized distance for each code (0 = distance of 1) */
58017+
58018+#else
58019+# include "trees.h"
58020+#endif /* GEN_TREES_H */
58021+
58022+struct static_tree_desc_s {
58023+ const ct_data *static_tree; /* static tree or NULL */
58024+ const intf *extra_bits; /* extra bits for each code or NULL */
58025+ int extra_base; /* base index for extra_bits */
58026+ int elems; /* max number of elements in the tree */
58027+ int max_length; /* max bit length for the codes */
58028+};
58029+
58030+local static_tree_desc static_l_desc =
58031+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
58032+
58033+local static_tree_desc static_d_desc =
58034+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
58035+
58036+local static_tree_desc static_bl_desc =
58037+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
58038+
58039+/* ===========================================================================
58040+ * Local (static) routines in this file.
58041+ */
58042+
58043+local void tr_static_init OF((void));
58044+local void init_block OF((deflate_state *s));
58045+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
58046+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
58047+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
58048+local void build_tree OF((deflate_state *s, tree_desc *desc));
58049+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
58050+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
58051+local int build_bl_tree OF((deflate_state *s));
58052+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
58053+ int blcodes));
58054+local void compress_block OF((deflate_state *s, const ct_data *ltree,
58055+ const ct_data *dtree));
58056+local void set_data_type OF((deflate_state *s));
58057+local unsigned bi_reverse OF((unsigned value, int length));
58058+local void bi_windup OF((deflate_state *s));
58059+local void bi_flush OF((deflate_state *s));
58060+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
58061+ int header));
58062+
58063+#ifdef GEN_TREES_H
58064+local void gen_trees_header OF((void));
58065+#endif
58066+
58067+#ifndef DEBUG
58068+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
58069+ /* Send a code of the given tree. c and tree must not have side effects */
58070+
58071+#else /* DEBUG */
58072+# define send_code(s, c, tree) \
58073+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
58074+ send_bits(s, tree[c].Code, tree[c].Len); }
58075+#endif
58076+
58077+/* ===========================================================================
58078+ * Output a short LSB first on the stream.
58079+ * IN assertion: there is enough room in pendingBuf.
58080+ */
58081+#define put_short(s, w) { \
58082+ put_byte(s, (uch)((w) & 0xff)); \
58083+ put_byte(s, (uch)((ush)(w) >> 8)); \
58084+}
58085+
58086+/* ===========================================================================
58087+ * Send a value on a given number of bits.
58088+ * IN assertion: length <= 16 and value fits in length bits.
58089+ */
58090+#ifdef DEBUG
58091+local void send_bits OF((deflate_state *s, int value, int length));
58092+
58093+local void send_bits(s, value, length)
58094+ deflate_state *s;
58095+ int value; /* value to send */
58096+ int length; /* number of bits */
58097+{
58098+ Tracevv((stderr," l %2d v %4x ", length, value));
58099+ Assert(length > 0 && length <= 15, "invalid length");
58100+ s->bits_sent += (ulg)length;
58101+
58102+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
58103+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
58104+ * unused bits in value.
58105+ */
58106+ if (s->bi_valid > (int)Buf_size - length) {
58107+ s->bi_buf |= (value << s->bi_valid);
58108+ put_short(s, s->bi_buf);
58109+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
58110+ s->bi_valid += length - Buf_size;
58111+ } else {
58112+ s->bi_buf |= value << s->bi_valid;
58113+ s->bi_valid += length;
58114+ }
58115+}
58116+#else /* !DEBUG */
58117+
58118+#define send_bits(s, value, length) \
58119+{ int len = length;\
58120+ if (s->bi_valid > (int)Buf_size - len) {\
58121+ int val = value;\
58122+ s->bi_buf |= (val << s->bi_valid);\
58123+ put_short(s, s->bi_buf);\
58124+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
58125+ s->bi_valid += len - Buf_size;\
58126+ } else {\
58127+ s->bi_buf |= (value) << s->bi_valid;\
58128+ s->bi_valid += len;\
58129+ }\
58130+}
58131+#endif /* DEBUG */
58132+
58133+
58134+#define MAX(a,b) (a >= b ? a : b)
58135+/* the arguments must not have side effects */
58136+
58137+/* ===========================================================================
58138+ * Initialize the various 'constant' tables.
58139+ */
58140+local void tr_static_init()
58141+{
58142+#if defined(GEN_TREES_H) || !defined(STDC)
58143+ static int static_init_done = 0;
58144+ int n; /* iterates over tree elements */
58145+ int bits; /* bit counter */
58146+ int length; /* length value */
58147+ int code; /* code value */
58148+ int dist; /* distance index */
58149+ ush bl_count[MAX_BITS+1];
58150+ /* number of codes at each bit length for an optimal tree */
58151+
58152+ if (static_init_done) return;
58153+
58154+ /* For some embedded targets, global variables are not initialized: */
58155+ static_l_desc.static_tree = static_ltree;
58156+ static_l_desc.extra_bits = extra_lbits;
58157+ static_d_desc.static_tree = static_dtree;
58158+ static_d_desc.extra_bits = extra_dbits;
58159+ static_bl_desc.extra_bits = extra_blbits;
58160+
58161+ /* Initialize the mapping length (0..255) -> length code (0..28) */
58162+ length = 0;
58163+ for (code = 0; code < LENGTH_CODES-1; code++) {
58164+ base_length[code] = length;
58165+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
58166+ _length_code[length++] = (uch)code;
58167+ }
58168+ }
58169+ Assert (length == 256, "tr_static_init: length != 256");
58170+ /* Note that the length 255 (match length 258) can be represented
58171+ * in two different ways: code 284 + 5 bits or code 285, so we
58172+ * overwrite length_code[255] to use the best encoding:
58173+ */
58174+ _length_code[length-1] = (uch)code;
58175+
58176+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
58177+ dist = 0;
58178+ for (code = 0 ; code < 16; code++) {
58179+ base_dist[code] = dist;
58180+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
58181+ _dist_code[dist++] = (uch)code;
58182+ }
58183+ }
58184+ Assert (dist == 256, "tr_static_init: dist != 256");
58185+ dist >>= 7; /* from now on, all distances are divided by 128 */
58186+ for ( ; code < D_CODES; code++) {
58187+ base_dist[code] = dist << 7;
58188+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
58189+ _dist_code[256 + dist++] = (uch)code;
58190+ }
58191+ }
58192+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
58193+
58194+ /* Construct the codes of the static literal tree */
58195+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
58196+ n = 0;
58197+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
58198+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
58199+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
58200+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
58201+ /* Codes 286 and 287 do not exist, but we must include them in the
58202+ * tree construction to get a canonical Huffman tree (longest code
58203+ * all ones)
58204+ */
58205+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
58206+
58207+ /* The static distance tree is trivial: */
58208+ for (n = 0; n < D_CODES; n++) {
58209+ static_dtree[n].Len = 5;
58210+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
58211+ }
58212+ static_init_done = 1;
58213+
58214+# ifdef GEN_TREES_H
58215+ gen_trees_header();
58216+# endif
58217+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
58218+}
58219+
58220+/* ===========================================================================
58221+ * Genererate the file trees.h describing the static trees.
58222+ */
58223+#ifdef GEN_TREES_H
58224+# ifndef DEBUG
58225+# include <stdio.h>
58226+# endif
58227+
58228+# define SEPARATOR(i, last, width) \
58229+ ((i) == (last)? "\n};\n\n" : \
58230+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
58231+
58232+void gen_trees_header()
58233+{
58234+ FILE *header = fopen("trees.h", "w");
58235+ int i;
58236+
58237+ Assert (header != NULL, "Can't open trees.h");
58238+ fprintf(header,
58239+ "/* header created automatically with -DGEN_TREES_H */\n\n");
58240+
58241+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
58242+ for (i = 0; i < L_CODES+2; i++) {
58243+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
58244+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
58245+ }
58246+
58247+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
58248+ for (i = 0; i < D_CODES; i++) {
58249+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
58250+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
58251+ }
58252+
58253+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
58254+ for (i = 0; i < DIST_CODE_LEN; i++) {
58255+ fprintf(header, "%2u%s", _dist_code[i],
58256+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
58257+ }
58258+
58259+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
58260+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
58261+ fprintf(header, "%2u%s", _length_code[i],
58262+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
58263+ }
58264+
58265+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
58266+ for (i = 0; i < LENGTH_CODES; i++) {
58267+ fprintf(header, "%1u%s", base_length[i],
58268+ SEPARATOR(i, LENGTH_CODES-1, 20));
58269+ }
58270+
58271+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
58272+ for (i = 0; i < D_CODES; i++) {
58273+ fprintf(header, "%5u%s", base_dist[i],
58274+ SEPARATOR(i, D_CODES-1, 10));
58275+ }
58276+
58277+ fclose(header);
58278+}
58279+#endif /* GEN_TREES_H */
58280+
58281+/* ===========================================================================
58282+ * Initialize the tree data structures for a new zlib stream.
58283+ */
58284+void _tr_init(s)
58285+ deflate_state *s;
58286+{
58287+ tr_static_init();
58288+
58289+ s->l_desc.dyn_tree = s->dyn_ltree;
58290+ s->l_desc.stat_desc = &static_l_desc;
58291+
58292+ s->d_desc.dyn_tree = s->dyn_dtree;
58293+ s->d_desc.stat_desc = &static_d_desc;
58294+
58295+ s->bl_desc.dyn_tree = s->bl_tree;
58296+ s->bl_desc.stat_desc = &static_bl_desc;
58297+
58298+ s->bi_buf = 0;
58299+ s->bi_valid = 0;
58300+ s->last_eob_len = 8; /* enough lookahead for inflate */
58301+#ifdef DEBUG
58302+ s->compressed_len = 0L;
58303+ s->bits_sent = 0L;
58304+#endif
58305+
58306+ /* Initialize the first block of the first file: */
58307+ init_block(s);
58308+}
58309+
58310+/* ===========================================================================
58311+ * Initialize a new block.
58312+ */
58313+local void init_block(s)
58314+ deflate_state *s;
58315+{
58316+ int n; /* iterates over tree elements */
58317+
58318+ /* Initialize the trees. */
58319+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
58320+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
58321+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
58322+
58323+ s->dyn_ltree[END_BLOCK].Freq = 1;
58324+ s->opt_len = s->static_len = 0L;
58325+ s->last_lit = s->matches = 0;
58326+}
58327+
58328+#define SMALLEST 1
58329+/* Index within the heap array of least frequent node in the Huffman tree */
58330+
58331+
58332+/* ===========================================================================
58333+ * Remove the smallest element from the heap and recreate the heap with
58334+ * one less element. Updates heap and heap_len.
58335+ */
58336+#define pqremove(s, tree, top) \
58337+{\
58338+ top = s->heap[SMALLEST]; \
58339+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
58340+ pqdownheap(s, tree, SMALLEST); \
58341+}
58342+
58343+/* ===========================================================================
58344+ * Compares to subtrees, using the tree depth as tie breaker when
58345+ * the subtrees have equal frequency. This minimizes the worst case length.
58346+ */
58347+#define smaller(tree, n, m, depth) \
58348+ (tree[n].Freq < tree[m].Freq || \
58349+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
58350+
58351+/* ===========================================================================
58352+ * Restore the heap property by moving down the tree starting at node k,
58353+ * exchanging a node with the smallest of its two sons if necessary, stopping
58354+ * when the heap property is re-established (each father smaller than its
58355+ * two sons).
58356+ */
58357+local void pqdownheap(s, tree, k)
58358+ deflate_state *s;
58359+ ct_data *tree; /* the tree to restore */
58360+ int k; /* node to move down */
58361+{
58362+ int v = s->heap[k];
58363+ int j = k << 1; /* left son of k */
58364+ while (j <= s->heap_len) {
58365+ /* Set j to the smallest of the two sons: */
58366+ if (j < s->heap_len &&
58367+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
58368+ j++;
58369+ }
58370+ /* Exit if v is smaller than both sons */
58371+ if (smaller(tree, v, s->heap[j], s->depth)) break;
58372+
58373+ /* Exchange v with the smallest son */
58374+ s->heap[k] = s->heap[j]; k = j;
58375+
58376+ /* And continue down the tree, setting j to the left son of k */
58377+ j <<= 1;
58378+ }
58379+ s->heap[k] = v;
58380+}
58381+
58382+/* ===========================================================================
58383+ * Compute the optimal bit lengths for a tree and update the total bit length
58384+ * for the current block.
58385+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
58386+ * above are the tree nodes sorted by increasing frequency.
58387+ * OUT assertions: the field len is set to the optimal bit length, the
58388+ * array bl_count contains the frequencies for each bit length.
58389+ * The length opt_len is updated; static_len is also updated if stree is
58390+ * not null.
58391+ */
58392+local void gen_bitlen(s, desc)
58393+ deflate_state *s;
58394+ tree_desc *desc; /* the tree descriptor */
58395+{
58396+ ct_data *tree = desc->dyn_tree;
58397+ int max_code = desc->max_code;
58398+ const ct_data *stree = desc->stat_desc->static_tree;
58399+ const intf *extra = desc->stat_desc->extra_bits;
58400+ int base = desc->stat_desc->extra_base;
58401+ int max_length = desc->stat_desc->max_length;
58402+ int h; /* heap index */
58403+ int n, m; /* iterate over the tree elements */
58404+ int bits; /* bit length */
58405+ int xbits; /* extra bits */
58406+ ush f; /* frequency */
58407+ int overflow = 0; /* number of elements with bit length too large */
58408+
58409+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
58410+
58411+ /* In a first pass, compute the optimal bit lengths (which may
58412+ * overflow in the case of the bit length tree).
58413+ */
58414+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
58415+
58416+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
58417+ n = s->heap[h];
58418+ bits = tree[tree[n].Dad].Len + 1;
58419+ if (bits > max_length) bits = max_length, overflow++;
58420+ tree[n].Len = (ush)bits;
58421+ /* We overwrite tree[n].Dad which is no longer needed */
58422+
58423+ if (n > max_code) continue; /* not a leaf node */
58424+
58425+ s->bl_count[bits]++;
58426+ xbits = 0;
58427+ if (n >= base) xbits = extra[n-base];
58428+ f = tree[n].Freq;
58429+ s->opt_len += (ulg)f * (bits + xbits);
58430+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
58431+ }
58432+ if (overflow == 0) return;
58433+
58434+ Trace((stderr,"\nbit length overflow\n"));
58435+ /* This happens for example on obj2 and pic of the Calgary corpus */
58436+
58437+ /* Find the first bit length which could increase: */
58438+ do {
58439+ bits = max_length-1;
58440+ while (s->bl_count[bits] == 0) bits--;
58441+ s->bl_count[bits]--; /* move one leaf down the tree */
58442+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
58443+ s->bl_count[max_length]--;
58444+ /* The brother of the overflow item also moves one step up,
58445+ * but this does not affect bl_count[max_length]
58446+ */
58447+ overflow -= 2;
58448+ } while (overflow > 0);
58449+
58450+ /* Now recompute all bit lengths, scanning in increasing frequency.
58451+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
58452+ * lengths instead of fixing only the wrong ones. This idea is taken
58453+ * from 'ar' written by Haruhiko Okumura.)
58454+ */
58455+ for (bits = max_length; bits != 0; bits--) {
58456+ n = s->bl_count[bits];
58457+ while (n != 0) {
58458+ m = s->heap[--h];
58459+ if (m > max_code) continue;
58460+ if (tree[m].Len != (unsigned) bits) {
58461+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
58462+ s->opt_len += ((long)bits - (long)tree[m].Len)
58463+ *(long)tree[m].Freq;
58464+ tree[m].Len = (ush)bits;
58465+ }
58466+ n--;
58467+ }
58468+ }
58469+}
58470+
58471+/* ===========================================================================
58472+ * Generate the codes for a given tree and bit counts (which need not be
58473+ * optimal).
58474+ * IN assertion: the array bl_count contains the bit length statistics for
58475+ * the given tree and the field len is set for all tree elements.
58476+ * OUT assertion: the field code is set for all tree elements of non
58477+ * zero code length.
58478+ */
58479+local void gen_codes (tree, max_code, bl_count)
58480+ ct_data *tree; /* the tree to decorate */
58481+ int max_code; /* largest code with non zero frequency */
58482+ ushf *bl_count; /* number of codes at each bit length */
58483+{
58484+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
58485+ ush code = 0; /* running code value */
58486+ int bits; /* bit index */
58487+ int n; /* code index */
58488+
58489+ /* The distribution counts are first used to generate the code values
58490+ * without bit reversal.
58491+ */
58492+ for (bits = 1; bits <= MAX_BITS; bits++) {
58493+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
58494+ }
58495+ /* Check that the bit counts in bl_count are consistent. The last code
58496+ * must be all ones.
58497+ */
58498+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
58499+ "inconsistent bit counts");
58500+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
58501+
58502+ for (n = 0; n <= max_code; n++) {
58503+ int len = tree[n].Len;
58504+ if (len == 0) continue;
58505+ /* Now reverse the bits */
58506+ tree[n].Code = bi_reverse(next_code[len]++, len);
58507+
58508+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
58509+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
58510+ }
58511+}
58512+
58513+/* ===========================================================================
58514+ * Construct one Huffman tree and assigns the code bit strings and lengths.
58515+ * Update the total bit length for the current block.
58516+ * IN assertion: the field freq is set for all tree elements.
58517+ * OUT assertions: the fields len and code are set to the optimal bit length
58518+ * and corresponding code. The length opt_len is updated; static_len is
58519+ * also updated if stree is not null. The field max_code is set.
58520+ */
58521+local void build_tree(s, desc)
58522+ deflate_state *s;
58523+ tree_desc *desc; /* the tree descriptor */
58524+{
58525+ ct_data *tree = desc->dyn_tree;
58526+ const ct_data *stree = desc->stat_desc->static_tree;
58527+ int elems = desc->stat_desc->elems;
58528+ int n, m; /* iterate over heap elements */
58529+ int max_code = -1; /* largest code with non zero frequency */
58530+ int node; /* new node being created */
58531+
58532+ /* Construct the initial heap, with least frequent element in
58533+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
58534+ * heap[0] is not used.
58535+ */
58536+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
58537+
58538+ for (n = 0; n < elems; n++) {
58539+ if (tree[n].Freq != 0) {
58540+ s->heap[++(s->heap_len)] = max_code = n;
58541+ s->depth[n] = 0;
58542+ } else {
58543+ tree[n].Len = 0;
58544+ }
58545+ }
58546+
58547+ /* The pkzip format requires that at least one distance code exists,
58548+ * and that at least one bit should be sent even if there is only one
58549+ * possible code. So to avoid special checks later on we force at least
58550+ * two codes of non zero frequency.
58551+ */
58552+ while (s->heap_len < 2) {
58553+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
58554+ tree[node].Freq = 1;
58555+ s->depth[node] = 0;
58556+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
58557+ /* node is 0 or 1 so it does not have extra bits */
58558+ }
58559+ desc->max_code = max_code;
58560+
58561+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
58562+ * establish sub-heaps of increasing lengths:
58563+ */
58564+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
58565+
58566+ /* Construct the Huffman tree by repeatedly combining the least two
58567+ * frequent nodes.
58568+ */
58569+ node = elems; /* next internal node of the tree */
58570+ do {
58571+ pqremove(s, tree, n); /* n = node of least frequency */
58572+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
58573+
58574+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
58575+ s->heap[--(s->heap_max)] = m;
58576+
58577+ /* Create a new node father of n and m */
58578+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
58579+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
58580+ tree[n].Dad = tree[m].Dad = (ush)node;
58581+#ifdef DUMP_BL_TREE
58582+ if (tree == s->bl_tree) {
58583+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
58584+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
58585+ }
58586+#endif
58587+ /* and insert the new node in the heap */
58588+ s->heap[SMALLEST] = node++;
58589+ pqdownheap(s, tree, SMALLEST);
58590+
58591+ } while (s->heap_len >= 2);
58592+
58593+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
58594+
58595+ /* At this point, the fields freq and dad are set. We can now
58596+ * generate the bit lengths.
58597+ */
58598+ gen_bitlen(s, (tree_desc *)desc);
58599+
58600+ /* The field len is now set, we can generate the bit codes */
58601+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
58602+}
58603+
58604+/* ===========================================================================
58605+ * Scan a literal or distance tree to determine the frequencies of the codes
58606+ * in the bit length tree.
58607+ */
58608+local void scan_tree (s, tree, max_code)
58609+ deflate_state *s;
58610+ ct_data *tree; /* the tree to be scanned */
58611+ int max_code; /* and its largest code of non zero frequency */
58612+{
58613+ int n; /* iterates over all tree elements */
58614+ int prevlen = -1; /* last emitted length */
58615+ int curlen; /* length of current code */
58616+ int nextlen = tree[0].Len; /* length of next code */
58617+ int count = 0; /* repeat count of the current code */
58618+ int max_count = 7; /* max repeat count */
58619+ int min_count = 4; /* min repeat count */
58620+
58621+ if (nextlen == 0) max_count = 138, min_count = 3;
58622+ tree[max_code+1].Len = (ush)0xffff; /* guard */
58623+
58624+ for (n = 0; n <= max_code; n++) {
58625+ curlen = nextlen; nextlen = tree[n+1].Len;
58626+ if (++count < max_count && curlen == nextlen) {
58627+ continue;
58628+ } else if (count < min_count) {
58629+ s->bl_tree[curlen].Freq += count;
58630+ } else if (curlen != 0) {
58631+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
58632+ s->bl_tree[REP_3_6].Freq++;
58633+ } else if (count <= 10) {
58634+ s->bl_tree[REPZ_3_10].Freq++;
58635+ } else {
58636+ s->bl_tree[REPZ_11_138].Freq++;
58637+ }
58638+ count = 0; prevlen = curlen;
58639+ if (nextlen == 0) {
58640+ max_count = 138, min_count = 3;
58641+ } else if (curlen == nextlen) {
58642+ max_count = 6, min_count = 3;
58643+ } else {
58644+ max_count = 7, min_count = 4;
58645+ }
58646+ }
58647+}
58648+
58649+/* ===========================================================================
58650+ * Send a literal or distance tree in compressed form, using the codes in
58651+ * bl_tree.
58652+ */
58653+local void send_tree (s, tree, max_code)
58654+ deflate_state *s;
58655+ ct_data *tree; /* the tree to be scanned */
58656+ int max_code; /* and its largest code of non zero frequency */
58657+{
58658+ int n; /* iterates over all tree elements */
58659+ int prevlen = -1; /* last emitted length */
58660+ int curlen; /* length of current code */
58661+ int nextlen = tree[0].Len; /* length of next code */
58662+ int count = 0; /* repeat count of the current code */
58663+ int max_count = 7; /* max repeat count */
58664+ int min_count = 4; /* min repeat count */
58665+
58666+ /* tree[max_code+1].Len = -1; */ /* guard already set */
58667+ if (nextlen == 0) max_count = 138, min_count = 3;
58668+
58669+ for (n = 0; n <= max_code; n++) {
58670+ curlen = nextlen; nextlen = tree[n+1].Len;
58671+ if (++count < max_count && curlen == nextlen) {
58672+ continue;
58673+ } else if (count < min_count) {
58674+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
58675+
58676+ } else if (curlen != 0) {
58677+ if (curlen != prevlen) {
58678+ send_code(s, curlen, s->bl_tree); count--;
58679+ }
58680+ Assert(count >= 3 && count <= 6, " 3_6?");
58681+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
58682+
58683+ } else if (count <= 10) {
58684+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
58685+
58686+ } else {
58687+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
58688+ }
58689+ count = 0; prevlen = curlen;
58690+ if (nextlen == 0) {
58691+ max_count = 138, min_count = 3;
58692+ } else if (curlen == nextlen) {
58693+ max_count = 6, min_count = 3;
58694+ } else {
58695+ max_count = 7, min_count = 4;
58696+ }
58697+ }
58698+}
58699+
58700+/* ===========================================================================
58701+ * Construct the Huffman tree for the bit lengths and return the index in
58702+ * bl_order of the last bit length code to send.
58703+ */
58704+local int build_bl_tree(s)
58705+ deflate_state *s;
58706+{
58707+ int max_blindex; /* index of last bit length code of non zero freq */
58708+
58709+ /* Determine the bit length frequencies for literal and distance trees */
58710+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
58711+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
58712+
58713+ /* Build the bit length tree: */
58714+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
58715+ /* opt_len now includes the length of the tree representations, except
58716+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
58717+ */
58718+
58719+ /* Determine the number of bit length codes to send. The pkzip format
58720+ * requires that at least 4 bit length codes be sent. (appnote.txt says
58721+ * 3 but the actual value used is 4.)
58722+ */
58723+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
58724+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
58725+ }
58726+ /* Update opt_len to include the bit length tree and counts */
58727+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
58728+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
58729+ s->opt_len, s->static_len));
58730+
58731+ return max_blindex;
58732+}
58733+
58734+/* ===========================================================================
58735+ * Send the header for a block using dynamic Huffman trees: the counts, the
58736+ * lengths of the bit length codes, the literal tree and the distance tree.
58737+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
58738+ */
58739+local void send_all_trees(s, lcodes, dcodes, blcodes)
58740+ deflate_state *s;
58741+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
58742+{
58743+ int rank; /* index in bl_order */
58744+
58745+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
58746+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
58747+ "too many codes");
58748+ Tracev((stderr, "\nbl counts: "));
58749+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
58750+ send_bits(s, dcodes-1, 5);
58751+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
58752+ for (rank = 0; rank < blcodes; rank++) {
58753+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
58754+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
58755+ }
58756+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
58757+
58758+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
58759+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
58760+
58761+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
58762+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
58763+}
58764+
58765+/* ===========================================================================
58766+ * Send a stored block
58767+ */
58768+void _tr_stored_block(s, buf, stored_len, eof)
58769+ deflate_state *s;
58770+ charf *buf; /* input block */
58771+ ulg stored_len; /* length of input block */
58772+ int eof; /* true if this is the last block for a file */
58773+{
58774+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
58775+#ifdef DEBUG
58776+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
58777+ s->compressed_len += (stored_len + 4) << 3;
58778+#endif
58779+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
58780+}
58781+
58782+/* ===========================================================================
58783+ * Send one empty static block to give enough lookahead for inflate.
58784+ * This takes 10 bits, of which 7 may remain in the bit buffer.
58785+ * The current inflate code requires 9 bits of lookahead. If the
58786+ * last two codes for the previous block (real code plus EOB) were coded
58787+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
58788+ * the last real code. In this case we send two empty static blocks instead
58789+ * of one. (There are no problems if the previous block is stored or fixed.)
58790+ * To simplify the code, we assume the worst case of last real code encoded
58791+ * on one bit only.
58792+ */
58793+void _tr_align(s)
58794+ deflate_state *s;
58795+{
58796+ send_bits(s, STATIC_TREES<<1, 3);
58797+ send_code(s, END_BLOCK, static_ltree);
58798+#ifdef DEBUG
58799+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
58800+#endif
58801+ bi_flush(s);
58802+ /* Of the 10 bits for the empty block, we have already sent
58803+ * (10 - bi_valid) bits. The lookahead for the last real code (before
58804+ * the EOB of the previous block) was thus at least one plus the length
58805+ * of the EOB plus what we have just sent of the empty static block.
58806+ */
58807+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
58808+ send_bits(s, STATIC_TREES<<1, 3);
58809+ send_code(s, END_BLOCK, static_ltree);
58810+#ifdef DEBUG
58811+ s->compressed_len += 10L;
58812+#endif
58813+ bi_flush(s);
58814+ }
58815+ s->last_eob_len = 7;
58816+}
58817+
58818+/* ===========================================================================
58819+ * Determine the best encoding for the current block: dynamic trees, static
58820+ * trees or store, and output the encoded block to the zip file.
58821+ */
58822+void _tr_flush_block(s, buf, stored_len, eof)
58823+ deflate_state *s;
58824+ charf *buf; /* input block, or NULL if too old */
58825+ ulg stored_len; /* length of input block */
58826+ int eof; /* true if this is the last block for a file */
58827+{
58828+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
58829+ int max_blindex = 0; /* index of last bit length code of non zero freq */
58830+
58831+ /* Build the Huffman trees unless a stored block is forced */
58832+ if (s->level > 0) {
58833+
58834+ /* Check if the file is ascii or binary */
58835+ if (s->data_type == Z_UNKNOWN) set_data_type(s);
58836+
58837+ /* Construct the literal and distance trees */
58838+ build_tree(s, (tree_desc *)(&(s->l_desc)));
58839+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
58840+ s->static_len));
58841+
58842+ build_tree(s, (tree_desc *)(&(s->d_desc)));
58843+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
58844+ s->static_len));
58845+ /* At this point, opt_len and static_len are the total bit lengths of
58846+ * the compressed block data, excluding the tree representations.
58847+ */
58848+
58849+ /* Build the bit length tree for the above two trees, and get the index
58850+ * in bl_order of the last bit length code to send.
58851+ */
58852+ max_blindex = build_bl_tree(s);
58853+
58854+ /* Determine the best encoding. Compute first the block length in bytes*/
58855+ opt_lenb = (s->opt_len+3+7)>>3;
58856+ static_lenb = (s->static_len+3+7)>>3;
58857+
58858+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
58859+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
58860+ s->last_lit));
58861+
58862+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
58863+
58864+ } else {
58865+ Assert(buf != (char*)0, "lost buf");
58866+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
58867+ }
58868+
58869+#ifdef FORCE_STORED
58870+ if (buf != (char*)0) { /* force stored block */
58871+#else
58872+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
58873+ /* 4: two words for the lengths */
58874+#endif
58875+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
58876+ * Otherwise we can't have processed more than WSIZE input bytes since
58877+ * the last block flush, because compression would have been
58878+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
58879+ * transform a block into a stored block.
58880+ */
58881+ _tr_stored_block(s, buf, stored_len, eof);
58882+
58883+#ifdef FORCE_STATIC
58884+ } else if (static_lenb >= 0) { /* force static trees */
58885+#else
58886+ } else if (static_lenb == opt_lenb) {
58887+#endif
58888+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
58889+ compress_block(s, static_ltree, static_dtree);
58890+#ifdef DEBUG
58891+ s->compressed_len += 3 + s->static_len;
58892+#endif
58893+ } else {
58894+ send_bits(s, (DYN_TREES<<1)+eof, 3);
58895+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
58896+ max_blindex+1);
58897+ compress_block(s, s->dyn_ltree, s->dyn_dtree);
58898+#ifdef DEBUG
58899+ s->compressed_len += 3 + s->opt_len;
58900+#endif
58901+ }
58902+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
58903+ /* The above check is made mod 2^32, for files larger than 512 MB
58904+ * and uLong implemented on 32 bits.
58905+ */
58906+ init_block(s);
58907+
58908+ if (eof) {
58909+ bi_windup(s);
58910+#ifdef DEBUG
58911+ s->compressed_len += 7; /* align on byte boundary */
58912+#endif
58913+ }
58914+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
58915+ s->compressed_len-7*eof));
58916+}
58917+
58918+/* ===========================================================================
58919+ * Save the match info and tally the frequency counts. Return true if
58920+ * the current block must be flushed.
58921+ */
58922+int _tr_tally (s, dist, lc)
58923+ deflate_state *s;
58924+ unsigned dist; /* distance of matched string */
58925+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
58926+{
58927+ s->d_buf[s->last_lit] = (ush)dist;
58928+ s->l_buf[s->last_lit++] = (uch)lc;
58929+ if (dist == 0) {
58930+ /* lc is the unmatched char */
58931+ s->dyn_ltree[lc].Freq++;
58932+ } else {
58933+ s->matches++;
58934+ /* Here, lc is the match length - MIN_MATCH */
58935+ dist--; /* dist = match distance - 1 */
58936+ Assert((ush)dist < (ush)MAX_DIST(s) &&
58937+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
58938+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
58939+
58940+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
58941+ s->dyn_dtree[d_code(dist)].Freq++;
58942+ }
58943+
58944+#ifdef TRUNCATE_BLOCK
58945+ /* Try to guess if it is profitable to stop the current block here */
58946+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
58947+ /* Compute an upper bound for the compressed length */
58948+ ulg out_length = (ulg)s->last_lit*8L;
58949+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
58950+ int dcode;
58951+ for (dcode = 0; dcode < D_CODES; dcode++) {
58952+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
58953+ (5L+extra_dbits[dcode]);
58954+ }
58955+ out_length >>= 3;
58956+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
58957+ s->last_lit, in_length, out_length,
58958+ 100L - out_length*100L/in_length));
58959+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
58960+ }
58961+#endif
58962+ return (s->last_lit == s->lit_bufsize-1);
58963+ /* We avoid equality with lit_bufsize because of wraparound at 64K
58964+ * on 16 bit machines and because stored blocks are restricted to
58965+ * 64K-1 bytes.
58966+ */
58967+}
58968+
58969+/* ===========================================================================
58970+ * Send the block data compressed using the given Huffman trees
58971+ */
58972+local void compress_block(s, ltree, dtree)
58973+ deflate_state *s;
58974+ const ct_data *ltree; /* literal tree */
58975+ const ct_data *dtree; /* distance tree */
58976+{
58977+ unsigned dist; /* distance of matched string */
58978+ int lc; /* match length or unmatched char (if dist == 0) */
58979+ unsigned lx = 0; /* running index in l_buf */
58980+ unsigned code; /* the code to send */
58981+ int extra; /* number of extra bits to send */
58982+
58983+ if (s->last_lit != 0) do {
58984+ dist = s->d_buf[lx];
58985+ lc = s->l_buf[lx++];
58986+ if (dist == 0) {
58987+ send_code(s, lc, ltree); /* send a literal byte */
58988+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
58989+ } else {
58990+ /* Here, lc is the match length - MIN_MATCH */
58991+ code = _length_code[lc];
58992+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
58993+ extra = extra_lbits[code];
58994+ if (extra != 0) {
58995+ lc -= base_length[code];
58996+ send_bits(s, lc, extra); /* send the extra length bits */
58997+ }
58998+ dist--; /* dist is now the match distance - 1 */
58999+ code = d_code(dist);
59000+ Assert (code < D_CODES, "bad d_code");
59001+
59002+ send_code(s, code, dtree); /* send the distance code */
59003+ extra = extra_dbits[code];
59004+ if (extra != 0) {
59005+ dist -= base_dist[code];
59006+ send_bits(s, dist, extra); /* send the extra distance bits */
59007+ }
59008+ } /* literal or match pair ? */
59009+
59010+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
59011+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
59012+
59013+ } while (lx < s->last_lit);
59014+
59015+ send_code(s, END_BLOCK, ltree);
59016+ s->last_eob_len = ltree[END_BLOCK].Len;
59017+}
59018+
59019+/* ===========================================================================
59020+ * Set the data type to ASCII or BINARY, using a crude approximation:
59021+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
59022+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
59023+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
59024+ */
59025+local void set_data_type(s)
59026+ deflate_state *s;
59027+{
59028+ int n = 0;
59029+ unsigned ascii_freq = 0;
59030+ unsigned bin_freq = 0;
59031+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
59032+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
59033+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
59034+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
59035+}
59036+
59037+/* ===========================================================================
59038+ * Reverse the first len bits of a code, using straightforward code (a faster
59039+ * method would use a table)
59040+ * IN assertion: 1 <= len <= 15
59041+ */
59042+local unsigned bi_reverse(code, len)
59043+ unsigned code; /* the value to invert */
59044+ int len; /* its bit length */
59045+{
59046+ register unsigned res = 0;
59047+ do {
59048+ res |= code & 1;
59049+ code >>= 1, res <<= 1;
59050+ } while (--len > 0);
59051+ return res >> 1;
59052+}
59053+
59054+/* ===========================================================================
59055+ * Flush the bit buffer, keeping at most 7 bits in it.
59056+ */
59057+local void bi_flush(s)
59058+ deflate_state *s;
59059+{
59060+ if (s->bi_valid == 16) {
59061+ put_short(s, s->bi_buf);
59062+ s->bi_buf = 0;
59063+ s->bi_valid = 0;
59064+ } else if (s->bi_valid >= 8) {
59065+ put_byte(s, (Byte)s->bi_buf);
59066+ s->bi_buf >>= 8;
59067+ s->bi_valid -= 8;
59068+ }
59069+}
59070+
59071+/* ===========================================================================
59072+ * Flush the bit buffer and align the output on a byte boundary
59073+ */
59074+local void bi_windup(s)
59075+ deflate_state *s;
59076+{
59077+ if (s->bi_valid > 8) {
59078+ put_short(s, s->bi_buf);
59079+ } else if (s->bi_valid > 0) {
59080+ put_byte(s, (Byte)s->bi_buf);
59081+ }
59082+ s->bi_buf = 0;
59083+ s->bi_valid = 0;
59084+#ifdef DEBUG
59085+ s->bits_sent = (s->bits_sent+7) & ~7;
59086+#endif
59087+}
59088+
59089+/* ===========================================================================
59090+ * Copy a stored block, storing first the length and its
59091+ * one's complement if requested.
59092+ */
59093+local void copy_block(s, buf, len, header)
59094+ deflate_state *s;
59095+ charf *buf; /* the input data */
59096+ unsigned len; /* its length */
59097+ int header; /* true if block header must be written */
59098+{
59099+ bi_windup(s); /* align on byte boundary */
59100+ s->last_eob_len = 8; /* enough lookahead for inflate */
59101+
59102+ if (header) {
59103+ put_short(s, (ush)len);
59104+ put_short(s, (ush)~len);
59105+#ifdef DEBUG
59106+ s->bits_sent += 2*16;
59107+#endif
59108+ }
59109+#ifdef DEBUG
59110+ s->bits_sent += (ulg)len<<3;
59111+#endif
59112+ while (len--) {
59113+ put_byte(s, *buf++);
59114+ }
59115+}
59116--- /dev/null Tue Mar 11 13:02:56 2003
59117+++ linux/net/ipsec/trees.h Mon Feb 9 13:51:03 2004
59118@@ -0,0 +1,128 @@
59119+/* header created automatically with -DGEN_TREES_H */
59120+
59121+local const ct_data static_ltree[L_CODES+2] = {
59122+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
59123+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
59124+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
59125+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
59126+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
59127+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
59128+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
59129+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
59130+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
59131+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
59132+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
59133+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
59134+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
59135+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
59136+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
59137+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
59138+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
59139+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
59140+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
59141+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
59142+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
59143+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
59144+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
59145+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
59146+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
59147+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
59148+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
59149+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
59150+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
59151+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
59152+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
59153+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
59154+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
59155+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
59156+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
59157+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
59158+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
59159+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
59160+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
59161+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
59162+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
59163+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
59164+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
59165+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
59166+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
59167+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
59168+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
59169+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
59170+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
59171+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
59172+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
59173+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
59174+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
59175+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
59176+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
59177+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
59178+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
59179+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
59180+};
59181+
59182+local const ct_data static_dtree[D_CODES] = {
59183+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
59184+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
59185+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
59186+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
59187+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
59188+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
59189+};
59190+
59191+const uch _dist_code[DIST_CODE_LEN] = {
59192+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
59193+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
59194+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
59195+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
59196+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
59197+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
59198+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
59199+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
59200+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
59201+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
59202+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
59203+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
59204+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
59205+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
59206+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
59207+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
59208+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
59209+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
59210+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
59211+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
59212+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
59213+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
59214+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
59215+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
59216+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
59217+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
59218+};
59219+
59220+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
59221+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
59222+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
59223+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
59224+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
59225+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
59226+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
59227+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
59228+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
59229+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
59230+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
59231+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
59232+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
59233+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
59234+};
59235+
59236+local const int base_length[LENGTH_CODES] = {
59237+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
59238+64, 80, 96, 112, 128, 160, 192, 224, 0
59239+};
59240+
59241+local const int base_dist[D_CODES] = {
59242+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
59243+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
59244+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
59245+};
59246+
59247--- /dev/null Tue Mar 11 13:02:56 2003
59248+++ linux/net/ipsec/ultoa.c Mon Feb 9 13:51:03 2004
59249@@ -0,0 +1,66 @@
59250+/*
59251+ * convert unsigned long to ASCII
59252+ * Copyright (C) 1998, 1999 Henry Spencer.
59253+ *
59254+ * This library is free software; you can redistribute it and/or modify it
59255+ * under the terms of the GNU Library General Public License as published by
59256+ * the Free Software Foundation; either version 2 of the License, or (at your
59257+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
59258+ *
59259+ * This library is distributed in the hope that it will be useful, but
59260+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
59261+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
59262+ * License for more details.
59263+ *
59264+ * RCSID $Id: ultoa.c,v 1.10 2004-07-10 07:48:37 mcr Exp $
59265+ */
59266+#include "openswan.h"
59267+
59268+/*
59269+ - ultoa - convert unsigned long to decimal ASCII
59270+ */
59271+size_t /* length required for full conversion */
59272+ultoa(n, base, dst, dstlen)
59273+unsigned long n;
59274+int base;
59275+char *dst; /* need not be valid if dstlen is 0 */
59276+size_t dstlen;
59277+{
59278+ char buf[3*sizeof(unsigned long) + 1];
59279+ char *bufend = buf + sizeof(buf);
59280+ size_t len;
59281+ char *p;
59282+ static char hex[] = "0123456789abcdef";
59283+
59284+ p = bufend;
59285+ *--p = '\0';
59286+ if (base == 10) {
59287+ do {
59288+ *--p = n%10 + '0';
59289+ n /= 10;
59290+ } while (n != 0);
59291+ } else if (base == 16) {
59292+ do {
59293+ *--p = hex[n&0xf];
59294+ n >>= 4;
59295+ } while (n != 0);
59296+ *--p = 'x';
59297+ *--p = '0';
59298+ } else if (base == 8) {
59299+ do {
59300+ *--p = (n&07) + '0';
59301+ n >>= 3;
59302+ } while (n != 0);
59303+ *--p = '0';
59304+ } else
59305+ *--p = '?';
59306+
59307+ len = bufend - p;
59308+
59309+ if (dstlen > 0) {
59310+ if (len > dstlen)
59311+ *(p + dstlen - 1) = '\0';
59312+ strcpy(dst, p);
59313+ }
59314+ return len;
59315+}
59316--- /dev/null Tue Mar 11 13:02:56 2003
59317+++ linux/net/ipsec/ultot.c Mon Feb 9 13:51:03 2004
59318@@ -0,0 +1,82 @@
59319+/*
59320+ * convert unsigned long to text
59321+ * Copyright (C) 2000 Henry Spencer.
59322+ *
59323+ * This library is free software; you can redistribute it and/or modify it
59324+ * under the terms of the GNU Library General Public License as published by
59325+ * the Free Software Foundation; either version 2 of the License, or (at your
59326+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
59327+ *
59328+ * This library is distributed in the hope that it will be useful, but
59329+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
59330+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
59331+ * License for more details.
59332+ *
59333+ * RCSID $Id: ultot.c,v 1.5 2004-07-10 07:48:37 mcr Exp $
59334+ */
59335+#include "openswan.h"
59336+
59337+/*
59338+ - ultot - convert unsigned long to text
59339+ */
59340+size_t /* length required for full conversion */
59341+ultot(n, base, dst, dstlen)
59342+unsigned long n;
59343+int base;
59344+char *dst; /* need not be valid if dstlen is 0 */
59345+size_t dstlen;
59346+{
59347+ char buf[3*sizeof(unsigned long) + 1];
59348+ char *bufend = buf + sizeof(buf);
59349+ size_t len;
59350+ char *p;
59351+ static char hex[] = "0123456789abcdef";
59352+# define HEX32 (32/4)
59353+
59354+ p = bufend;
59355+ *--p = '\0';
59356+ switch (base) {
59357+ case 10:
59358+ case 'd':
59359+ do {
59360+ *--p = n%10 + '0';
59361+ n /= 10;
59362+ } while (n != 0);
59363+ break;
59364+ case 16:
59365+ case 17:
59366+ case 'x':
59367+ do {
59368+ *--p = hex[n&0xf];
59369+ n >>= 4;
59370+ } while (n != 0);
59371+ if (base == 17)
59372+ while (bufend - p < HEX32 + 1)
59373+ *--p = '0';
59374+ if (base == 'x') {
59375+ *--p = 'x';
59376+ *--p = '0';
59377+ }
59378+ break;
59379+ case 8:
59380+ case 'o':
59381+ do {
59382+ *--p = (n&07) + '0';
59383+ n >>= 3;
59384+ } while (n != 0);
59385+ if (base == 'o')
59386+ *--p = '0';
59387+ break;
59388+ default:
59389+ return 0;
59390+ break;
59391+ }
59392+
59393+ len = bufend - p;
59394+ if (dstlen > 0) {
59395+ if (len > dstlen)
59396+ *(p + dstlen - 1) = '\0';
59397+ strcpy(dst, p);
59398+ }
59399+ return len;
59400+}
59401--- /dev/null Fri May 10 13:59:54 2002
59402+++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002
59403@@ -0,0 +1 @@
59404+IPSECVERSION=2.4.12