]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/openswan-2.4.12.kernel-2.6-klips.patch
Imported the beginning of the rowie-spezial and possible 2.2 release.
[people/pmueller/ipfire-2.x.git] / src / patches / openswan-2.4.12.kernel-2.6-klips.patch
1 packaging/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