2be151db5d
Thanks to Markus for noticing.
59388 lines
1.8 MiB
59388 lines
1.8 MiB
packaging/utils/kernelpatch 2.6
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/README.openswan-2 Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,112 @@
|
|
+*
|
|
+* RCSID $Id: README.openswan-2,v 1.1 2003/12/10 01:07:49 mcr Exp $
|
|
+*
|
|
+
|
|
+ ****************************************
|
|
+ * IPSEC for Linux, Release 2.xx series *
|
|
+ ****************************************
|
|
+
|
|
+
|
|
+
|
|
+1. Files
|
|
+
|
|
+The contents of linux/net/ipsec/ (see below) join the linux kernel source tree.
|
|
+as provided for higher up.
|
|
+
|
|
+The programs/ directory contains the user-level utilities which you need
|
|
+to run IPSEC. See the top-level top/INSTALL to compile and install them.
|
|
+
|
|
+The testing/ directory contains test scripts.
|
|
+
|
|
+The doc/ directory contains -- what else -- documentation.
|
|
+
|
|
+1.1. Kernel files
|
|
+
|
|
+The following are found in net/ipsec/:
|
|
+
|
|
+Makefile The Makefile
|
|
+Config.in The configuration script for make menuconfig
|
|
+defconfig Configuration defaults for first time.
|
|
+
|
|
+radij.c General-purpose radix-tree operations
|
|
+
|
|
+ipsec_ipcomp.c IPCOMP encapsulate/decapsulate code.
|
|
+ipsec_ah.c Authentication Header (AH) encapsulate/decapsulate code.
|
|
+ipsec_esp.c Encapsulated Security Payload (ESP) encap/decap code.
|
|
+
|
|
+pfkey_v2.c PF_KEYv2 socket interface code.
|
|
+pfkey_v2_parser.c PF_KEYv2 message parsing and processing code.
|
|
+
|
|
+ipsec_init.c Initialization code, /proc interface.
|
|
+ipsec_radij.c Interface with the radix tree code.
|
|
+ipsec_netlink.c Interface with the netlink code.
|
|
+ipsec_xform.c Routines and structures common to transforms.
|
|
+ipsec_tunnel.c The outgoing packet processing code.
|
|
+ipsec_rcv.c The incoming packet processing code.
|
|
+ipsec_md5c.c Somewhat modified RSADSI MD5 C code.
|
|
+ipsec_sha1.c Somewhat modified Steve Reid SHA-1 C code.
|
|
+
|
|
+sysctl_net_ipsec.c /proc/sys/net/ipsec/* variable definitions.
|
|
+
|
|
+version.c symbolic link to project version.
|
|
+
|
|
+radij.h Headers for radij.c
|
|
+
|
|
+ipcomp.h Headers used by IPCOMP code.
|
|
+
|
|
+ipsec_radij.h Interface with the radix tree code.
|
|
+ipsec_netlink.h Headers used by the netlink interface.
|
|
+ipsec_encap.h Headers defining encapsulation structures.
|
|
+ipsec_xform.h Transform headers.
|
|
+ipsec_tunnel.h Headers used by tunneling code.
|
|
+ipsec_ipe4.h Headers for the IP-in-IP code.
|
|
+ipsec_ah.h Headers common to AH transforms.
|
|
+ipsec_md5h.h RSADSI MD5 headers.
|
|
+ipsec_sha1.h SHA-1 headers.
|
|
+ipsec_esp.h Headers common to ESP transfroms.
|
|
+ipsec_rcv.h Headers for incoming packet processing code.
|
|
+
|
|
+1.2. User-level files.
|
|
+
|
|
+The following are found in utils/:
|
|
+
|
|
+eroute.c Create an "extended route" source code
|
|
+spi.c Set up Security Associations source code
|
|
+spigrp.c Link SPIs together source code.
|
|
+tncfg.c Configure the tunneling features of the virtual interface
|
|
+ source code
|
|
+klipsdebug.c Set/reset klips debugging features source code.
|
|
+version.c symbolic link to project version.
|
|
+
|
|
+eroute.8 Create an "extended route" manual page
|
|
+spi.8 Set up Security Associations manual page
|
|
+spigrp.8 Link SPIs together manual page
|
|
+tncfg.8 Configure the tunneling features of the virtual interface
|
|
+ manual page
|
|
+klipsdebug.8 Set/reset klips debugging features manual page
|
|
+
|
|
+eroute.5 /proc/net/ipsec_eroute format manual page
|
|
+spi.5 /proc/net/ipsec_spi format manual page
|
|
+spigrp.5 /proc/net/ipsec_spigrp format manual page
|
|
+tncfg.5 /proc/net/ipsec_tncfg format manual page
|
|
+klipsdebug.5 /proc/net/ipsec_klipsdebug format manual page
|
|
+version.5 /proc/net/ipsec_version format manual page
|
|
+pf_key.5 /proc/net/pf_key format manual page
|
|
+
|
|
+Makefile Utilities makefile.
|
|
+
|
|
+*.8 Manpages for the respective utils.
|
|
+
|
|
+
|
|
+1.3. Test files
|
|
+
|
|
+The test scripts are locate in testing/ and and documentation is found
|
|
+at doc/src/umltesting.html. Automated testing via "make check" is available
|
|
+provided that the User-Mode-Linux patches are available.
|
|
+
|
|
+*
|
|
+* $Log: README.openswan-2,v $
|
|
+* Revision 1.1 2003/12/10 01:07:49 mcr
|
|
+* documentation for additions.
|
|
+*
|
|
+*
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/crypto/ciphers/aes/test_main.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,41 @@
|
|
+#include <stdio.h>
|
|
+#include <string.h>
|
|
+#include <sys/types.h>
|
|
+#include "aes_cbc.h"
|
|
+#define AES_BLOCK_SIZE 16
|
|
+#define KEY_SIZE 128 /* bits */
|
|
+#define KEY "1234567890123456"
|
|
+#define STR "hola guaso como estaisss ... 012"
|
|
+#define STRSZ (sizeof(STR)-1)
|
|
+
|
|
+#define EMT_AESCBC_BLKLEN AES_BLOCK_SIZE
|
|
+#define AES_CONTEXT_T aes_context
|
|
+#define EMT_ESPAES_KEY_SZ 16
|
|
+int pretty_print(const unsigned char *buf, int count) {
|
|
+ int i=0;
|
|
+ for (;i<count;i++) {
|
|
+ if (i%8==0) putchar(' ');
|
|
+ if (i%16==0) putchar('\n');
|
|
+ printf ("%02hhx ", buf[i]);
|
|
+ }
|
|
+ putchar('\n');
|
|
+ return i;
|
|
+}
|
|
+//#define SIZE STRSZ/2
|
|
+#define SIZE STRSZ
|
|
+int main() {
|
|
+ int ret;
|
|
+ char buf0[SIZE+1], buf1[SIZE+1];
|
|
+ char IV[AES_BLOCK_SIZE]="\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0";
|
|
+ aes_context ac;
|
|
+ AES_set_key(&ac, KEY, KEY_SIZE);
|
|
+ //pretty_print((char *)&ac.aes_e_key, sizeof(ac.aes_e_key));
|
|
+ memset(buf0, 0, sizeof (buf0));
|
|
+ memset(buf1, 0, sizeof (buf1));
|
|
+ ret=AES_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1);
|
|
+ pretty_print(buf0, SIZE);
|
|
+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0);
|
|
+ ret=AES_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0);
|
|
+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1);
|
|
+ return 0;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/crypto/ciphers/aes/test_main_mac.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,30 @@
|
|
+#include <stdio.h>
|
|
+#include <sys/types.h>
|
|
+#include <string.h>
|
|
+#include "aes.h"
|
|
+#include "aes_xcbc_mac.h"
|
|
+#define STR "Hola guasssso c|mo estais ...012"
|
|
+void print_hash(const __u8 *hash) {
|
|
+ printf("%08x %08x %08x %08x\n",
|
|
+ *(__u32*)(&hash[0]),
|
|
+ *(__u32*)(&hash[4]),
|
|
+ *(__u32*)(&hash[8]),
|
|
+ *(__u32*)(&hash[12]));
|
|
+}
|
|
+int main(int argc, char *argv[]) {
|
|
+ aes_block key= { 0xdeadbeef, 0xceedcaca, 0xcafebabe, 0xff010204 };
|
|
+ __u8 hash[16];
|
|
+ char *str = argv[1];
|
|
+ aes_context_mac ctx;
|
|
+ if (str==NULL) {
|
|
+ fprintf(stderr, "pasame el str\n");
|
|
+ return 255;
|
|
+ }
|
|
+ AES_xcbc_mac_set_key(&ctx, (__u8 *)&key, sizeof(key));
|
|
+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
|
|
+ print_hash(hash);
|
|
+ str[2]='x';
|
|
+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
|
|
+ print_hash(hash);
|
|
+ return 0;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/crypto/aes.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,97 @@
|
|
+// I retain copyright in this code but I encourage its free use provided
|
|
+// that I don't carry any responsibility for the results. I am especially
|
|
+// happy to see it used in free and open source software. If you do use
|
|
+// it I would appreciate an acknowledgement of its origin in the code or
|
|
+// the product that results and I would also appreciate knowing a little
|
|
+// about the use to which it is being put. I am grateful to Frank Yellin
|
|
+// for some ideas that are used in this implementation.
|
|
+//
|
|
+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
|
|
+//
|
|
+// This is an implementation of the AES encryption algorithm (Rijndael)
|
|
+// designed by Joan Daemen and Vincent Rijmen. This version is designed
|
|
+// to provide both fixed and dynamic block and key lengths and can also
|
|
+// run with either big or little endian internal byte order (see aes.h).
|
|
+// It inputs block and key lengths in bytes with the legal values being
|
|
+// 16, 24 and 32.
|
|
+
|
|
+/*
|
|
+ * Modified by Jari Ruusu, May 1 2001
|
|
+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
|
|
+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
|
|
+ * - Major name space cleanup: Names visible to outside now begin
|
|
+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
|
|
+ * - Removed C++ and DLL support as part of name space cleanup.
|
|
+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
|
|
+ * - Merged precomputed constant tables to aes.c file.
|
|
+ * - Removed data alignment restrictions for portability reasons.
|
|
+ * - Made block and key lengths accept bit count (128/192/256)
|
|
+ * as well byte count (16/24/32).
|
|
+ * - Removed all error checks. This change also eliminated the need
|
|
+ * to preinitialize the context struct to zero.
|
|
+ * - Removed some totally unused constants.
|
|
+ */
|
|
+
|
|
+#ifndef _AES_H
|
|
+#define _AES_H
|
|
+
|
|
+#if defined(__linux__) && defined(__KERNEL__)
|
|
+# include <linux/types.h>
|
|
+#else
|
|
+# include <sys/types.h>
|
|
+#endif
|
|
+
|
|
+// CONFIGURATION OPTIONS (see also aes.c)
|
|
+//
|
|
+// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
|
|
+// leave this undefined for dynamically variable block size (this will
|
|
+// result in much slower code).
|
|
+// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
|
|
+// left undefined a slower version providing variable block length is compiled
|
|
+
|
|
+#define AES_BLOCK_SIZE 16
|
|
+
|
|
+// The number of key schedule words for different block and key lengths
|
|
+// allowing for method of computation which requires the length to be a
|
|
+// multiple of the key length
|
|
+//
|
|
+// Nk = 4 6 8
|
|
+// -------------
|
|
+// Nb = 4 | 60 60 64
|
|
+// 6 | 96 90 96
|
|
+// 8 | 120 120 120
|
|
+
|
|
+#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
|
|
+#define AES_KS_LENGTH 120
|
|
+#define AES_RC_LENGTH 29
|
|
+#else
|
|
+#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
|
|
+#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
|
|
+#endif
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ u_int32_t aes_Nkey; // the number of words in the key input block
|
|
+ u_int32_t aes_Nrnd; // the number of cipher rounds
|
|
+ u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
|
|
+ u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
|
|
+#if !defined(AES_BLOCK_SIZE)
|
|
+ u_int32_t aes_Ncol; // the number of columns in the cipher state
|
|
+#endif
|
|
+} aes_context;
|
|
+
|
|
+// THE CIPHER INTERFACE
|
|
+
|
|
+#if !defined(AES_BLOCK_SIZE)
|
|
+extern void aes_set_blk(aes_context *, const int);
|
|
+#endif
|
|
+extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
|
|
+extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
|
|
+extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
|
|
+
|
|
+// The block length inputs to aes_set_block and aes_set_key are in numbers
|
|
+// of bytes or bits. The calls to subroutines must be made in the above
|
|
+// order but multiple calls can be made without repeating earlier calls
|
|
+// if their parameters have not changed.
|
|
+
|
|
+#endif // _AES_H
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/crypto/aes_cbc.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,4 @@
|
|
+/* Glue header */
|
|
+#include "aes.h"
|
|
+int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
|
|
+int AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/crypto/aes_xcbc_mac.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,12 @@
|
|
+#ifndef _AES_XCBC_MAC_H
|
|
+#define _AES_XCBC_MAC_H
|
|
+
|
|
+typedef u_int32_t aes_block[4];
|
|
+typedef struct {
|
|
+ aes_context ctx_k1;
|
|
+ aes_block k2;
|
|
+ aes_block k3;
|
|
+} aes_context_mac;
|
|
+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen);
|
|
+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]);
|
|
+#endif /* _AES_XCBC_MAC_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/crypto/cbc_generic.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,110 @@
|
|
+#ifndef _CBC_GENERIC_H
|
|
+#define _CBC_GENERIC_H
|
|
+/*
|
|
+ * CBC macro helpers
|
|
+ *
|
|
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Heavily inspired in loop_AES
|
|
+ */
|
|
+#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \
|
|
+int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
|
|
+ int ret=ilen, pos; \
|
|
+ const u_int32_t *iv_i; \
|
|
+ if ((ilen) % 16) return 0; \
|
|
+ if (encrypt) { \
|
|
+ pos=0; \
|
|
+ while(pos<ilen) { \
|
|
+ if (pos==0) \
|
|
+ iv_i=(const u_int32_t*) iv; \
|
|
+ else \
|
|
+ iv_i=(const u_int32_t*) (out-16); \
|
|
+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
|
|
+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
|
|
+ *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \
|
|
+ *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \
|
|
+ enc_func(ctx, (addr_type) out, (addr_type) out); \
|
|
+ in+=16; \
|
|
+ out+=16; \
|
|
+ pos+=16; \
|
|
+ } \
|
|
+ } else { \
|
|
+ pos=ilen-16; \
|
|
+ in+=pos; \
|
|
+ out+=pos; \
|
|
+ while(pos>=0) { \
|
|
+ dec_func(ctx, (const addr_type) in, (addr_type) out); \
|
|
+ if (pos==0) \
|
|
+ iv_i=(const u_int32_t*) (iv); \
|
|
+ else \
|
|
+ iv_i=(const u_int32_t*) (in-16); \
|
|
+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
|
|
+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
|
|
+ *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \
|
|
+ *((u_int32_t *)(&out[12])) ^= iv_i[3]; \
|
|
+ in-=16; \
|
|
+ out-=16; \
|
|
+ pos-=16; \
|
|
+ } \
|
|
+ } \
|
|
+ return ret; \
|
|
+}
|
|
+#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \
|
|
+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
|
|
+ int ret=ilen, pos; \
|
|
+ const u_int32_t *iv_i; \
|
|
+ if ((ilen) % 8) return 0; \
|
|
+ if (encrypt) { \
|
|
+ pos=0; \
|
|
+ while(pos<ilen) { \
|
|
+ if (pos==0) \
|
|
+ iv_i=(const u_int32_t*) iv; \
|
|
+ else \
|
|
+ iv_i=(const u_int32_t*) (out-8); \
|
|
+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
|
|
+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
|
|
+ enc_func(ctx, (addr_type)out, (addr_type)out); \
|
|
+ in+=8; \
|
|
+ out+=8; \
|
|
+ pos+=8; \
|
|
+ } \
|
|
+ } else { \
|
|
+ pos=ilen-8; \
|
|
+ in+=pos; \
|
|
+ out+=pos; \
|
|
+ while(pos>=0) { \
|
|
+ dec_func(ctx, (const addr_type)in, (addr_type)out); \
|
|
+ if (pos==0) \
|
|
+ iv_i=(const u_int32_t*) (iv); \
|
|
+ else \
|
|
+ iv_i=(const u_int32_t*) (in-8); \
|
|
+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
|
|
+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
|
|
+ in-=8; \
|
|
+ out-=8; \
|
|
+ pos-=8; \
|
|
+ } \
|
|
+ } \
|
|
+ return ret; \
|
|
+}
|
|
+#define CBC_DECL(name, ctx_type) \
|
|
+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt)
|
|
+/*
|
|
+Eg.:
|
|
+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
|
|
+CBC_DECL(AES_cbc_encrypt, aes_context);
|
|
+*/
|
|
+#endif /* _CBC_GENERIC_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/crypto/des.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,298 @@
|
|
+/* crypto/des/des.org */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
|
+ *
|
|
+ * Always modify des.org since des.h is automatically generated from
|
|
+ * it during SSLeay configuration.
|
|
+ *
|
|
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
|
+ */
|
|
+
|
|
+#ifndef HEADER_DES_H
|
|
+#define HEADER_DES_H
|
|
+
|
|
+#ifdef __cplusplus
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+
|
|
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
|
|
+ * %20 speed up (longs are 8 bytes, int's are 4). */
|
|
+/* Must be unsigned int on ia64/Itanium or DES breaks badly */
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+#include <linux/types.h>
|
|
+#else
|
|
+#include <sys/types.h>
|
|
+#endif
|
|
+
|
|
+#ifndef DES_LONG
|
|
+#define DES_LONG u_int32_t
|
|
+#endif
|
|
+
|
|
+typedef unsigned char des_cblock[8];
|
|
+typedef struct { des_cblock ks; } des_key_schedule[16];
|
|
+
|
|
+#define DES_KEY_SZ (sizeof(des_cblock))
|
|
+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
|
|
+
|
|
+#define DES_ENCRYPT 1
|
|
+#define DES_DECRYPT 0
|
|
+
|
|
+#define DES_CBC_MODE 0
|
|
+#define DES_PCBC_MODE 1
|
|
+
|
|
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
|
|
+ des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
|
|
+
|
|
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
|
|
+ des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
|
|
+
|
|
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
|
|
+ des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
|
|
+
|
|
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
|
|
+ des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
|
|
+
|
|
+#define C_Block des_cblock
|
|
+#define Key_schedule des_key_schedule
|
|
+#ifdef KERBEROS
|
|
+#define ENCRYPT DES_ENCRYPT
|
|
+#define DECRYPT DES_DECRYPT
|
|
+#endif
|
|
+#define KEY_SZ DES_KEY_SZ
|
|
+#define string_to_key des_string_to_key
|
|
+#define read_pw_string des_read_pw_string
|
|
+#define random_key des_random_key
|
|
+#define pcbc_encrypt des_pcbc_encrypt
|
|
+#define set_key des_set_key
|
|
+#define key_sched des_key_sched
|
|
+#define ecb_encrypt des_ecb_encrypt
|
|
+#define cbc_encrypt des_cbc_encrypt
|
|
+#define ncbc_encrypt des_ncbc_encrypt
|
|
+#define xcbc_encrypt des_xcbc_encrypt
|
|
+#define cbc_cksum des_cbc_cksum
|
|
+#define quad_cksum des_quad_cksum
|
|
+
|
|
+/* For compatibility with the MIT lib - eay 20/05/92 */
|
|
+typedef des_key_schedule bit_64;
|
|
+#define des_fixup_key_parity des_set_odd_parity
|
|
+#define des_check_key_parity check_parity
|
|
+
|
|
+extern int des_check_key; /* defaults to false */
|
|
+extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
|
|
+
|
|
+/* The next line is used to disable full ANSI prototypes, if your
|
|
+ * compiler has problems with the prototypes, make sure this line always
|
|
+ * evaluates to true :-) */
|
|
+#if defined(MSDOS) || defined(__STDC__)
|
|
+#undef NOPROTO
|
|
+#endif
|
|
+#ifndef NOPROTO
|
|
+char *des_options(void);
|
|
+void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
|
|
+ des_key_schedule ks1,des_key_schedule ks2,
|
|
+ des_key_schedule ks3, int enc);
|
|
+DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
|
|
+ long length,des_key_schedule schedule,des_cblock *ivec);
|
|
+void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
|
|
+ des_key_schedule schedule,des_cblock *ivec,int enc);
|
|
+void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
|
|
+ des_key_schedule schedule,des_cblock *ivec,int enc);
|
|
+void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
|
|
+ des_key_schedule schedule,des_cblock *ivec,
|
|
+ des_cblock *inw,des_cblock *outw,int enc);
|
|
+void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
|
|
+ long length,des_key_schedule schedule,des_cblock *ivec,int enc);
|
|
+void des_ecb_encrypt(des_cblock *input,des_cblock *output,
|
|
+ des_key_schedule ks,int enc);
|
|
+void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
|
|
+void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
|
|
+void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
|
|
+ des_key_schedule ks2, des_key_schedule ks3);
|
|
+void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
|
|
+ des_key_schedule ks2, des_key_schedule ks3);
|
|
+void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
|
|
+ long length, des_key_schedule ks1, des_key_schedule ks2,
|
|
+ des_key_schedule ks3, des_cblock *ivec, int enc);
|
|
+void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
|
|
+ long length, des_key_schedule ks1, des_key_schedule ks2,
|
|
+ des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
|
|
+void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
|
|
+ long length, des_key_schedule ks1, des_key_schedule ks2,
|
|
+ des_key_schedule ks3, des_cblock *ivec, int *num);
|
|
+
|
|
+void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
|
|
+ des_cblock (*out_white));
|
|
+
|
|
+int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
|
|
+ des_cblock *iv);
|
|
+int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
|
|
+ des_cblock *iv);
|
|
+char *des_fcrypt(const char *buf,const char *salt, char *ret);
|
|
+#ifdef PERL5
|
|
+char *des_crypt(const char *buf,const char *salt);
|
|
+#else
|
|
+/* some stupid compilers complain because I have declared char instead
|
|
+ * of const char */
|
|
+#ifndef __KERNEL__
|
|
+#ifdef HEADER_DES_LOCL_H
|
|
+char *crypt(const char *buf,const char *salt);
|
|
+#else /* HEADER_DES_LOCL_H */
|
|
+char *crypt(void);
|
|
+#endif /* HEADER_DES_LOCL_H */
|
|
+#endif /* __KERNEL__ */
|
|
+#endif /* PERL5 */
|
|
+void des_ofb_encrypt(unsigned char *in,unsigned char *out,
|
|
+ int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
|
|
+void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
|
|
+ des_key_schedule schedule,des_cblock *ivec,int enc);
|
|
+DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
|
|
+ long length,int out_count,des_cblock *seed);
|
|
+void des_random_seed(des_cblock key);
|
|
+void des_random_key(des_cblock ret);
|
|
+int des_read_password(des_cblock *key,char *prompt,int verify);
|
|
+int des_read_2passwords(des_cblock *key1,des_cblock *key2,
|
|
+ char *prompt,int verify);
|
|
+int des_read_pw_string(char *buf,int length,char *prompt,int verify);
|
|
+void des_set_odd_parity(des_cblock *key);
|
|
+int des_is_weak_key(des_cblock *key);
|
|
+int des_set_key(des_cblock *key,des_key_schedule schedule);
|
|
+int des_key_sched(des_cblock *key,des_key_schedule schedule);
|
|
+void des_string_to_key(char *str,des_cblock *key);
|
|
+void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
|
|
+void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
|
|
+ des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
|
|
+void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
|
|
+ des_key_schedule schedule, des_cblock *ivec, int *num);
|
|
+int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
|
|
+
|
|
+/* Extra functions from Mark Murray <mark@grondar.za> */
|
|
+/* The following functions are not in the normal unix build or the
|
|
+ * SSLeay build. When using the SSLeay build, use RAND_seed()
|
|
+ * and RAND_bytes() instead. */
|
|
+int des_new_random_key(des_cblock *key);
|
|
+void des_init_random_number_generator(des_cblock *key);
|
|
+void des_set_random_generator_seed(des_cblock *key);
|
|
+void des_set_sequence_number(des_cblock new_sequence_number);
|
|
+void des_generate_random_block(des_cblock *block);
|
|
+
|
|
+#else
|
|
+
|
|
+char *des_options();
|
|
+void des_ecb3_encrypt();
|
|
+DES_LONG des_cbc_cksum();
|
|
+void des_cbc_encrypt();
|
|
+void des_ncbc_encrypt();
|
|
+void des_xcbc_encrypt();
|
|
+void des_cfb_encrypt();
|
|
+void des_ede3_cfb64_encrypt();
|
|
+void des_ede3_ofb64_encrypt();
|
|
+void des_ecb_encrypt();
|
|
+void des_encrypt();
|
|
+void des_encrypt2();
|
|
+void des_encrypt3();
|
|
+void des_decrypt3();
|
|
+void des_ede3_cbc_encrypt();
|
|
+int des_enc_read();
|
|
+int des_enc_write();
|
|
+char *des_fcrypt();
|
|
+#ifdef PERL5
|
|
+char *des_crypt();
|
|
+#else
|
|
+char *crypt();
|
|
+#endif
|
|
+void des_ofb_encrypt();
|
|
+void des_pcbc_encrypt();
|
|
+DES_LONG des_quad_cksum();
|
|
+void des_random_seed();
|
|
+void des_random_key();
|
|
+int des_read_password();
|
|
+int des_read_2passwords();
|
|
+int des_read_pw_string();
|
|
+void des_set_odd_parity();
|
|
+int des_is_weak_key();
|
|
+int des_set_key();
|
|
+int des_key_sched();
|
|
+void des_string_to_key();
|
|
+void des_string_to_2keys();
|
|
+void des_cfb64_encrypt();
|
|
+void des_ofb64_encrypt();
|
|
+int des_read_pw();
|
|
+void des_xwhite_in2out();
|
|
+
|
|
+/* Extra functions from Mark Murray <mark@grondar.za> */
|
|
+/* The following functions are not in the normal unix build or the
|
|
+ * SSLeay build. When using the SSLeay build, use RAND_seed()
|
|
+ * and RAND_bytes() instead. */
|
|
+#ifdef FreeBSD
|
|
+int des_new_random_key();
|
|
+void des_init_random_number_generator();
|
|
+void des_set_random_generator_seed();
|
|
+void des_set_sequence_number();
|
|
+void des_generate_random_block();
|
|
+#endif
|
|
+
|
|
+#endif
|
|
+
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+
|
|
+#endif
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/des/des_locl.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,515 @@
|
|
+/* crypto/des/des_locl.org */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
|
+ *
|
|
+ * Always modify des_locl.org since des_locl.h is automatically generated from
|
|
+ * it during SSLeay configuration.
|
|
+ *
|
|
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
|
+ */
|
|
+
|
|
+#ifndef HEADER_DES_LOCL_H
|
|
+#define HEADER_DES_LOCL_H
|
|
+
|
|
+#if defined(WIN32) || defined(WIN16)
|
|
+#ifndef MSDOS
|
|
+#define MSDOS
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#include "crypto/des.h"
|
|
+
|
|
+#ifndef DES_DEFAULT_OPTIONS
|
|
+/* the following is tweaked from a config script, that is why it is a
|
|
+ * protected undef/define */
|
|
+#ifndef DES_PTR
|
|
+#define DES_PTR
|
|
+#endif
|
|
+
|
|
+/* This helps C compiler generate the correct code for multiple functional
|
|
+ * units. It reduces register dependancies at the expense of 2 more
|
|
+ * registers */
|
|
+#ifndef DES_RISC1
|
|
+#define DES_RISC1
|
|
+#endif
|
|
+
|
|
+#ifndef DES_RISC2
|
|
+#undef DES_RISC2
|
|
+#endif
|
|
+
|
|
+#if defined(DES_RISC1) && defined(DES_RISC2)
|
|
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
|
|
+#endif
|
|
+
|
|
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
|
|
+ * Very mucy CPU dependant */
|
|
+#ifndef DES_UNROLL
|
|
+#define DES_UNROLL
|
|
+#endif
|
|
+
|
|
+/* These default values were supplied by
|
|
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
|
|
+ * They are only used if nothing else has been defined */
|
|
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
|
|
+/* Special defines which change the way the code is built depending on the
|
|
+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
|
|
+ even newer MIPS CPU's, but at the moment one size fits all for
|
|
+ optimization options. Older Sparc's work better with only UNROLL, but
|
|
+ there's no way to tell at compile time what it is you're running on */
|
|
+
|
|
+#if defined( sun ) /* Newer Sparc's */
|
|
+ #define DES_PTR
|
|
+ #define DES_RISC1
|
|
+ #define DES_UNROLL
|
|
+#elif defined( __ultrix ) /* Older MIPS */
|
|
+ #define DES_PTR
|
|
+ #define DES_RISC2
|
|
+ #define DES_UNROLL
|
|
+#elif defined( __osf1__ ) /* Alpha */
|
|
+ #define DES_PTR
|
|
+ #define DES_RISC2
|
|
+#elif defined ( _AIX ) /* RS6000 */
|
|
+ /* Unknown */
|
|
+#elif defined( __hpux ) /* HP-PA */
|
|
+ /* Unknown */
|
|
+#elif defined( __aux ) /* 68K */
|
|
+ /* Unknown */
|
|
+#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
|
|
+ #define DES_UNROLL
|
|
+#elif defined( __sgi ) /* Newer MIPS */
|
|
+ #define DES_PTR
|
|
+ #define DES_RISC2
|
|
+ #define DES_UNROLL
|
|
+#elif defined( i386 ) /* x86 boxes, should be gcc */
|
|
+ #define DES_PTR
|
|
+ #define DES_RISC1
|
|
+ #define DES_UNROLL
|
|
+#endif /* Systems-specific speed defines */
|
|
+#endif
|
|
+
|
|
+#endif /* DES_DEFAULT_OPTIONS */
|
|
+
|
|
+#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
|
|
+#include <stdlib.h>
|
|
+#include <errno.h>
|
|
+#include <time.h>
|
|
+#include <io.h>
|
|
+#ifndef RAND
|
|
+#define RAND
|
|
+#endif
|
|
+#undef NOPROTO
|
|
+#endif
|
|
+
|
|
+#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
|
|
+#ifndef __KERNEL__
|
|
+#include <string.h>
|
|
+#else
|
|
+#include <linux/string.h>
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#ifndef RAND
|
|
+#define RAND
|
|
+#endif
|
|
+
|
|
+#ifdef linux
|
|
+#undef RAND
|
|
+#endif
|
|
+
|
|
+#ifdef MSDOS
|
|
+#define getpid() 2
|
|
+#define RAND
|
|
+#undef NOPROTO
|
|
+#endif
|
|
+
|
|
+#if defined(NOCONST)
|
|
+#define const
|
|
+#endif
|
|
+
|
|
+#ifdef __STDC__
|
|
+#undef NOPROTO
|
|
+#endif
|
|
+
|
|
+#ifdef RAND
|
|
+#define srandom(s) srand(s)
|
|
+#define random rand
|
|
+#endif
|
|
+
|
|
+#define ITERATIONS 16
|
|
+#define HALF_ITERATIONS 8
|
|
+
|
|
+/* used in des_read and des_write */
|
|
+#define MAXWRITE (1024*16)
|
|
+#define BSIZE (MAXWRITE+4)
|
|
+
|
|
+#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
|
|
+ l|=((DES_LONG)(*((c)++)))<< 8L, \
|
|
+ l|=((DES_LONG)(*((c)++)))<<16L, \
|
|
+ l|=((DES_LONG)(*((c)++)))<<24L)
|
|
+
|
|
+/* NOTE - c is not incremented as per c2l */
|
|
+#define c2ln(c,l1,l2,n) { \
|
|
+ c+=n; \
|
|
+ l1=l2=0; \
|
|
+ switch (n) { \
|
|
+ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
|
|
+ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
|
|
+ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
|
|
+ case 5: l2|=((DES_LONG)(*(--(c)))); \
|
|
+ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
|
|
+ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
|
|
+ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
|
|
+ case 1: l1|=((DES_LONG)(*(--(c)))); \
|
|
+ } \
|
|
+ }
|
|
+
|
|
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>>24L)&0xff))
|
|
+
|
|
+/* replacements for htonl and ntohl since I have no idea what to do
|
|
+ * when faced with machines with 8 byte longs. */
|
|
+#define HDRSIZE 4
|
|
+
|
|
+#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
|
|
+ l|=((DES_LONG)(*((c)++)))<<16L, \
|
|
+ l|=((DES_LONG)(*((c)++)))<< 8L, \
|
|
+ l|=((DES_LONG)(*((c)++))))
|
|
+
|
|
+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
|
|
+ *((c)++)=(unsigned char)(((l) )&0xff))
|
|
+
|
|
+/* NOTE - c is not incremented as per l2c */
|
|
+#define l2cn(l1,l2,c,n) { \
|
|
+ c+=n; \
|
|
+ switch (n) { \
|
|
+ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
|
|
+ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
|
|
+ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
|
|
+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
|
|
+ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
|
|
+ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
|
|
+ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
|
|
+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
|
|
+ } \
|
|
+ }
|
|
+
|
|
+#if defined(WIN32)
|
|
+#define ROTATE(a,n) (_lrotr(a,n))
|
|
+#else
|
|
+#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
|
|
+#endif
|
|
+
|
|
+/* Don't worry about the LOAD_DATA() stuff, that is used by
|
|
+ * fcrypt() to add it's little bit to the front */
|
|
+
|
|
+#ifdef DES_FCRYPT
|
|
+
|
|
+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
|
|
+ { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
|
|
+
|
|
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
|
|
+ t=R^(R>>16L); \
|
|
+ u=t&E0; t&=E1; \
|
|
+ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
|
|
+ tmp=(t<<16); t^=R^s[S+1]; t^=tmp
|
|
+#else
|
|
+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
|
|
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
|
|
+ u=R^s[S ]; \
|
|
+ t=R^s[S+1]
|
|
+#endif
|
|
+
|
|
+/* The changes to this macro may help or hinder, depending on the
|
|
+ * compiler and the achitecture. gcc2 always seems to do well :-).
|
|
+ * Inspired by Dana How <how@isl.stanford.edu>
|
|
+ * DO NOT use the alternative version on machines with 8 byte longs.
|
|
+ * It does not seem to work on the Alpha, even when DES_LONG is 4
|
|
+ * bytes, probably an issue of accessing non-word aligned objects :-( */
|
|
+#ifdef DES_PTR
|
|
+
|
|
+/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
|
|
+ * is no reason to not xor all the sub items together. This potentially
|
|
+ * saves a register since things can be xored directly into L */
|
|
+
|
|
+#if defined(DES_RISC1) || defined(DES_RISC2)
|
|
+#ifdef DES_RISC1
|
|
+#define D_ENCRYPT(LL,R,S) { \
|
|
+ unsigned int u1,u2,u3; \
|
|
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
|
|
+ u2=(int)u>>8L; \
|
|
+ u1=(int)u&0xfc; \
|
|
+ u2&=0xfc; \
|
|
+ t=ROTATE(t,4); \
|
|
+ u>>=16L; \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
|
|
+ u3=(int)(u>>8L); \
|
|
+ u1=(int)u&0xfc; \
|
|
+ u3&=0xfc; \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
|
|
+ u2=(int)t>>8L; \
|
|
+ u1=(int)t&0xfc; \
|
|
+ u2&=0xfc; \
|
|
+ t>>=16L; \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
|
|
+ u3=(int)t>>8L; \
|
|
+ u1=(int)t&0xfc; \
|
|
+ u3&=0xfc; \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
|
|
+#endif
|
|
+#ifdef DES_RISC2
|
|
+#define D_ENCRYPT(LL,R,S) { \
|
|
+ unsigned int u1,u2,s1,s2; \
|
|
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
|
|
+ u2=(int)u>>8L; \
|
|
+ u1=(int)u&0xfc; \
|
|
+ u2&=0xfc; \
|
|
+ t=ROTATE(t,4); \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
|
|
+ s1=(int)(u>>16L); \
|
|
+ s2=(int)(u>>24L); \
|
|
+ s1&=0xfc; \
|
|
+ s2&=0xfc; \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
|
|
+ u2=(int)t>>8L; \
|
|
+ u1=(int)t&0xfc; \
|
|
+ u2&=0xfc; \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
|
|
+ s1=(int)(t>>16L); \
|
|
+ s2=(int)(t>>24L); \
|
|
+ s1&=0xfc; \
|
|
+ s2&=0xfc; \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
|
|
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
|
|
+#endif
|
|
+#else
|
|
+#define D_ENCRYPT(LL,R,S) { \
|
|
+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
|
|
+ t=ROTATE(t,4); \
|
|
+ LL^= \
|
|
+ *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
|
|
+ *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
|
|
+ *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
|
|
+ *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
|
|
+ *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
|
|
+ *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
|
|
+ *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
|
|
+ *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
|
|
+#endif
|
|
+
|
|
+#else /* original version */
|
|
+
|
|
+#if defined(DES_RISC1) || defined(DES_RISC2)
|
|
+#ifdef DES_RISC1
|
|
+#define D_ENCRYPT(LL,R,S) {\
|
|
+ unsigned int u1,u2,u3; \
|
|
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
|
|
+ u>>=2L; \
|
|
+ t=ROTATE(t,6); \
|
|
+ u2=(int)u>>8L; \
|
|
+ u1=(int)u&0x3f; \
|
|
+ u2&=0x3f; \
|
|
+ u>>=16L; \
|
|
+ LL^=des_SPtrans[0][u1]; \
|
|
+ LL^=des_SPtrans[2][u2]; \
|
|
+ u3=(int)u>>8L; \
|
|
+ u1=(int)u&0x3f; \
|
|
+ u3&=0x3f; \
|
|
+ LL^=des_SPtrans[4][u1]; \
|
|
+ LL^=des_SPtrans[6][u3]; \
|
|
+ u2=(int)t>>8L; \
|
|
+ u1=(int)t&0x3f; \
|
|
+ u2&=0x3f; \
|
|
+ t>>=16L; \
|
|
+ LL^=des_SPtrans[1][u1]; \
|
|
+ LL^=des_SPtrans[3][u2]; \
|
|
+ u3=(int)t>>8L; \
|
|
+ u1=(int)t&0x3f; \
|
|
+ u3&=0x3f; \
|
|
+ LL^=des_SPtrans[5][u1]; \
|
|
+ LL^=des_SPtrans[7][u3]; }
|
|
+#endif
|
|
+#ifdef DES_RISC2
|
|
+#define D_ENCRYPT(LL,R,S) {\
|
|
+ unsigned int u1,u2,s1,s2; \
|
|
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
|
|
+ u>>=2L; \
|
|
+ t=ROTATE(t,6); \
|
|
+ u2=(int)u>>8L; \
|
|
+ u1=(int)u&0x3f; \
|
|
+ u2&=0x3f; \
|
|
+ LL^=des_SPtrans[0][u1]; \
|
|
+ LL^=des_SPtrans[2][u2]; \
|
|
+ s1=(int)u>>16L; \
|
|
+ s2=(int)u>>24L; \
|
|
+ s1&=0x3f; \
|
|
+ s2&=0x3f; \
|
|
+ LL^=des_SPtrans[4][s1]; \
|
|
+ LL^=des_SPtrans[6][s2]; \
|
|
+ u2=(int)t>>8L; \
|
|
+ u1=(int)t&0x3f; \
|
|
+ u2&=0x3f; \
|
|
+ LL^=des_SPtrans[1][u1]; \
|
|
+ LL^=des_SPtrans[3][u2]; \
|
|
+ s1=(int)t>>16; \
|
|
+ s2=(int)t>>24L; \
|
|
+ s1&=0x3f; \
|
|
+ s2&=0x3f; \
|
|
+ LL^=des_SPtrans[5][s1]; \
|
|
+ LL^=des_SPtrans[7][s2]; }
|
|
+#endif
|
|
+
|
|
+#else
|
|
+
|
|
+#define D_ENCRYPT(LL,R,S) {\
|
|
+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
|
|
+ t=ROTATE(t,4); \
|
|
+ LL^=\
|
|
+ des_SPtrans[0][(u>> 2L)&0x3f]^ \
|
|
+ des_SPtrans[2][(u>>10L)&0x3f]^ \
|
|
+ des_SPtrans[4][(u>>18L)&0x3f]^ \
|
|
+ des_SPtrans[6][(u>>26L)&0x3f]^ \
|
|
+ des_SPtrans[1][(t>> 2L)&0x3f]^ \
|
|
+ des_SPtrans[3][(t>>10L)&0x3f]^ \
|
|
+ des_SPtrans[5][(t>>18L)&0x3f]^ \
|
|
+ des_SPtrans[7][(t>>26L)&0x3f]; }
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+ /* IP and FP
|
|
+ * The problem is more of a geometric problem that random bit fiddling.
|
|
+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
|
|
+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
|
|
+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
|
|
+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
|
|
+
|
|
+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
|
|
+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
|
|
+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
|
|
+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
|
|
+
|
|
+ The output has been subject to swaps of the form
|
|
+ 0 1 -> 3 1 but the odd and even bits have been put into
|
|
+ 2 3 2 0
|
|
+ different words. The main trick is to remember that
|
|
+ t=((l>>size)^r)&(mask);
|
|
+ r^=t;
|
|
+ l^=(t<<size);
|
|
+ can be used to swap and move bits between words.
|
|
+
|
|
+ So l = 0 1 2 3 r = 16 17 18 19
|
|
+ 4 5 6 7 20 21 22 23
|
|
+ 8 9 10 11 24 25 26 27
|
|
+ 12 13 14 15 28 29 30 31
|
|
+ becomes (for size == 2 and mask == 0x3333)
|
|
+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
|
|
+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
|
|
+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
|
|
+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
|
|
+
|
|
+ Thanks for hints from Richard Outerbridge - he told me IP&FP
|
|
+ could be done in 15 xor, 10 shifts and 5 ands.
|
|
+ When I finally started to think of the problem in 2D
|
|
+ I first got ~42 operations without xors. When I remembered
|
|
+ how to use xors :-) I got it to its final state.
|
|
+ */
|
|
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
|
|
+ (b)^=(t),\
|
|
+ (a)^=((t)<<(n)))
|
|
+
|
|
+#define IP(l,r) \
|
|
+ { \
|
|
+ register DES_LONG tt; \
|
|
+ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
|
|
+ PERM_OP(l,r,tt,16,0x0000ffffL); \
|
|
+ PERM_OP(r,l,tt, 2,0x33333333L); \
|
|
+ PERM_OP(l,r,tt, 8,0x00ff00ffL); \
|
|
+ PERM_OP(r,l,tt, 1,0x55555555L); \
|
|
+ }
|
|
+
|
|
+#define FP(l,r) \
|
|
+ { \
|
|
+ register DES_LONG tt; \
|
|
+ PERM_OP(l,r,tt, 1,0x55555555L); \
|
|
+ PERM_OP(r,l,tt, 8,0x00ff00ffL); \
|
|
+ PERM_OP(l,r,tt, 2,0x33333333L); \
|
|
+ PERM_OP(r,l,tt,16,0x0000ffffL); \
|
|
+ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
|
|
+ }
|
|
+
|
|
+extern const DES_LONG des_SPtrans[8][64];
|
|
+
|
|
+#ifndef NOPROTO
|
|
+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
|
|
+ DES_LONG Eswap0, DES_LONG Eswap1);
|
|
+#else
|
|
+void fcrypt_body();
|
|
+#endif
|
|
+
|
|
+#endif
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/des/des_ver.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,60 @@
|
|
+/* crypto/des/des_ver.h */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+extern char *DES_version; /* SSLeay version string */
|
|
+extern char *libdes_version; /* old libdes version string */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/des/podd.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,75 @@
|
|
+/* crypto/des/podd.h */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+static const unsigned char odd_parity[256]={
|
|
+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
|
|
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
|
|
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
|
|
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
|
|
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
|
|
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
|
|
+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
|
|
+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
|
|
+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
|
|
+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
|
|
+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
|
|
+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
|
|
+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
|
|
+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
|
|
+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
|
|
+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/des/sk.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,204 @@
|
|
+/* crypto/des/sk.h */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+static const DES_LONG des_skb[8][64]={
|
|
+{
|
|
+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
|
+0x00000000L,0x00000010L,0x20000000L,0x20000010L,
|
|
+0x00010000L,0x00010010L,0x20010000L,0x20010010L,
|
|
+0x00000800L,0x00000810L,0x20000800L,0x20000810L,
|
|
+0x00010800L,0x00010810L,0x20010800L,0x20010810L,
|
|
+0x00000020L,0x00000030L,0x20000020L,0x20000030L,
|
|
+0x00010020L,0x00010030L,0x20010020L,0x20010030L,
|
|
+0x00000820L,0x00000830L,0x20000820L,0x20000830L,
|
|
+0x00010820L,0x00010830L,0x20010820L,0x20010830L,
|
|
+0x00080000L,0x00080010L,0x20080000L,0x20080010L,
|
|
+0x00090000L,0x00090010L,0x20090000L,0x20090010L,
|
|
+0x00080800L,0x00080810L,0x20080800L,0x20080810L,
|
|
+0x00090800L,0x00090810L,0x20090800L,0x20090810L,
|
|
+0x00080020L,0x00080030L,0x20080020L,0x20080030L,
|
|
+0x00090020L,0x00090030L,0x20090020L,0x20090030L,
|
|
+0x00080820L,0x00080830L,0x20080820L,0x20080830L,
|
|
+0x00090820L,0x00090830L,0x20090820L,0x20090830L,
|
|
+},{
|
|
+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
|
|
+0x00000000L,0x02000000L,0x00002000L,0x02002000L,
|
|
+0x00200000L,0x02200000L,0x00202000L,0x02202000L,
|
|
+0x00000004L,0x02000004L,0x00002004L,0x02002004L,
|
|
+0x00200004L,0x02200004L,0x00202004L,0x02202004L,
|
|
+0x00000400L,0x02000400L,0x00002400L,0x02002400L,
|
|
+0x00200400L,0x02200400L,0x00202400L,0x02202400L,
|
|
+0x00000404L,0x02000404L,0x00002404L,0x02002404L,
|
|
+0x00200404L,0x02200404L,0x00202404L,0x02202404L,
|
|
+0x10000000L,0x12000000L,0x10002000L,0x12002000L,
|
|
+0x10200000L,0x12200000L,0x10202000L,0x12202000L,
|
|
+0x10000004L,0x12000004L,0x10002004L,0x12002004L,
|
|
+0x10200004L,0x12200004L,0x10202004L,0x12202004L,
|
|
+0x10000400L,0x12000400L,0x10002400L,0x12002400L,
|
|
+0x10200400L,0x12200400L,0x10202400L,0x12202400L,
|
|
+0x10000404L,0x12000404L,0x10002404L,0x12002404L,
|
|
+0x10200404L,0x12200404L,0x10202404L,0x12202404L,
|
|
+},{
|
|
+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
|
|
+0x00000000L,0x00000001L,0x00040000L,0x00040001L,
|
|
+0x01000000L,0x01000001L,0x01040000L,0x01040001L,
|
|
+0x00000002L,0x00000003L,0x00040002L,0x00040003L,
|
|
+0x01000002L,0x01000003L,0x01040002L,0x01040003L,
|
|
+0x00000200L,0x00000201L,0x00040200L,0x00040201L,
|
|
+0x01000200L,0x01000201L,0x01040200L,0x01040201L,
|
|
+0x00000202L,0x00000203L,0x00040202L,0x00040203L,
|
|
+0x01000202L,0x01000203L,0x01040202L,0x01040203L,
|
|
+0x08000000L,0x08000001L,0x08040000L,0x08040001L,
|
|
+0x09000000L,0x09000001L,0x09040000L,0x09040001L,
|
|
+0x08000002L,0x08000003L,0x08040002L,0x08040003L,
|
|
+0x09000002L,0x09000003L,0x09040002L,0x09040003L,
|
|
+0x08000200L,0x08000201L,0x08040200L,0x08040201L,
|
|
+0x09000200L,0x09000201L,0x09040200L,0x09040201L,
|
|
+0x08000202L,0x08000203L,0x08040202L,0x08040203L,
|
|
+0x09000202L,0x09000203L,0x09040202L,0x09040203L,
|
|
+},{
|
|
+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
|
|
+0x00000000L,0x00100000L,0x00000100L,0x00100100L,
|
|
+0x00000008L,0x00100008L,0x00000108L,0x00100108L,
|
|
+0x00001000L,0x00101000L,0x00001100L,0x00101100L,
|
|
+0x00001008L,0x00101008L,0x00001108L,0x00101108L,
|
|
+0x04000000L,0x04100000L,0x04000100L,0x04100100L,
|
|
+0x04000008L,0x04100008L,0x04000108L,0x04100108L,
|
|
+0x04001000L,0x04101000L,0x04001100L,0x04101100L,
|
|
+0x04001008L,0x04101008L,0x04001108L,0x04101108L,
|
|
+0x00020000L,0x00120000L,0x00020100L,0x00120100L,
|
|
+0x00020008L,0x00120008L,0x00020108L,0x00120108L,
|
|
+0x00021000L,0x00121000L,0x00021100L,0x00121100L,
|
|
+0x00021008L,0x00121008L,0x00021108L,0x00121108L,
|
|
+0x04020000L,0x04120000L,0x04020100L,0x04120100L,
|
|
+0x04020008L,0x04120008L,0x04020108L,0x04120108L,
|
|
+0x04021000L,0x04121000L,0x04021100L,0x04121100L,
|
|
+0x04021008L,0x04121008L,0x04021108L,0x04121108L,
|
|
+},{
|
|
+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
|
|
+0x00000000L,0x10000000L,0x00010000L,0x10010000L,
|
|
+0x00000004L,0x10000004L,0x00010004L,0x10010004L,
|
|
+0x20000000L,0x30000000L,0x20010000L,0x30010000L,
|
|
+0x20000004L,0x30000004L,0x20010004L,0x30010004L,
|
|
+0x00100000L,0x10100000L,0x00110000L,0x10110000L,
|
|
+0x00100004L,0x10100004L,0x00110004L,0x10110004L,
|
|
+0x20100000L,0x30100000L,0x20110000L,0x30110000L,
|
|
+0x20100004L,0x30100004L,0x20110004L,0x30110004L,
|
|
+0x00001000L,0x10001000L,0x00011000L,0x10011000L,
|
|
+0x00001004L,0x10001004L,0x00011004L,0x10011004L,
|
|
+0x20001000L,0x30001000L,0x20011000L,0x30011000L,
|
|
+0x20001004L,0x30001004L,0x20011004L,0x30011004L,
|
|
+0x00101000L,0x10101000L,0x00111000L,0x10111000L,
|
|
+0x00101004L,0x10101004L,0x00111004L,0x10111004L,
|
|
+0x20101000L,0x30101000L,0x20111000L,0x30111000L,
|
|
+0x20101004L,0x30101004L,0x20111004L,0x30111004L,
|
|
+},{
|
|
+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
|
|
+0x00000000L,0x08000000L,0x00000008L,0x08000008L,
|
|
+0x00000400L,0x08000400L,0x00000408L,0x08000408L,
|
|
+0x00020000L,0x08020000L,0x00020008L,0x08020008L,
|
|
+0x00020400L,0x08020400L,0x00020408L,0x08020408L,
|
|
+0x00000001L,0x08000001L,0x00000009L,0x08000009L,
|
|
+0x00000401L,0x08000401L,0x00000409L,0x08000409L,
|
|
+0x00020001L,0x08020001L,0x00020009L,0x08020009L,
|
|
+0x00020401L,0x08020401L,0x00020409L,0x08020409L,
|
|
+0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
|
|
+0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
|
|
+0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
|
|
+0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
|
|
+0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
|
|
+0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
|
|
+0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
|
|
+0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
|
|
+},{
|
|
+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
|
|
+0x00000000L,0x00000100L,0x00080000L,0x00080100L,
|
|
+0x01000000L,0x01000100L,0x01080000L,0x01080100L,
|
|
+0x00000010L,0x00000110L,0x00080010L,0x00080110L,
|
|
+0x01000010L,0x01000110L,0x01080010L,0x01080110L,
|
|
+0x00200000L,0x00200100L,0x00280000L,0x00280100L,
|
|
+0x01200000L,0x01200100L,0x01280000L,0x01280100L,
|
|
+0x00200010L,0x00200110L,0x00280010L,0x00280110L,
|
|
+0x01200010L,0x01200110L,0x01280010L,0x01280110L,
|
|
+0x00000200L,0x00000300L,0x00080200L,0x00080300L,
|
|
+0x01000200L,0x01000300L,0x01080200L,0x01080300L,
|
|
+0x00000210L,0x00000310L,0x00080210L,0x00080310L,
|
|
+0x01000210L,0x01000310L,0x01080210L,0x01080310L,
|
|
+0x00200200L,0x00200300L,0x00280200L,0x00280300L,
|
|
+0x01200200L,0x01200300L,0x01280200L,0x01280300L,
|
|
+0x00200210L,0x00200310L,0x00280210L,0x00280310L,
|
|
+0x01200210L,0x01200310L,0x01280210L,0x01280310L,
|
|
+},{
|
|
+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
|
|
+0x00000000L,0x04000000L,0x00040000L,0x04040000L,
|
|
+0x00000002L,0x04000002L,0x00040002L,0x04040002L,
|
|
+0x00002000L,0x04002000L,0x00042000L,0x04042000L,
|
|
+0x00002002L,0x04002002L,0x00042002L,0x04042002L,
|
|
+0x00000020L,0x04000020L,0x00040020L,0x04040020L,
|
|
+0x00000022L,0x04000022L,0x00040022L,0x04040022L,
|
|
+0x00002020L,0x04002020L,0x00042020L,0x04042020L,
|
|
+0x00002022L,0x04002022L,0x00042022L,0x04042022L,
|
|
+0x00000800L,0x04000800L,0x00040800L,0x04040800L,
|
|
+0x00000802L,0x04000802L,0x00040802L,0x04040802L,
|
|
+0x00002800L,0x04002800L,0x00042800L,0x04042800L,
|
|
+0x00002802L,0x04002802L,0x00042802L,0x04042802L,
|
|
+0x00000820L,0x04000820L,0x00040820L,0x04040820L,
|
|
+0x00000822L,0x04000822L,0x00040822L,0x04040822L,
|
|
+0x00002820L,0x04002820L,0x00042820L,0x04042820L,
|
|
+0x00002822L,0x04002822L,0x00042822L,0x04042822L,
|
|
+}};
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/des/spr.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,204 @@
|
|
+/* crypto/des/spr.h */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+const DES_LONG des_SPtrans[8][64]={
|
|
+{
|
|
+/* nibble 0 */
|
|
+0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
|
|
+0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
|
|
+0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
|
|
+0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
|
|
+0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
|
|
+0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
|
|
+0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
|
|
+0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
|
|
+0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
|
|
+0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
|
|
+0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
|
|
+0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
|
|
+0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
|
|
+0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
|
|
+0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
|
|
+0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
|
|
+},{
|
|
+/* nibble 1 */
|
|
+0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
|
|
+0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
|
|
+0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
|
|
+0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
|
|
+0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
|
|
+0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
|
|
+0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
|
|
+0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
|
|
+0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
|
|
+0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
|
|
+0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
|
|
+0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
|
|
+0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
|
|
+0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
|
|
+0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
|
|
+0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
|
|
+},{
|
|
+/* nibble 2 */
|
|
+0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
|
|
+0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
|
|
+0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
|
|
+0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
|
|
+0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
|
|
+0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
|
|
+0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
|
|
+0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
|
|
+0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
|
|
+0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
|
|
+0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
|
|
+0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
|
|
+0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
|
|
+0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
|
|
+0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
|
|
+0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
|
|
+},{
|
|
+/* nibble 3 */
|
|
+0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
|
|
+0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
|
|
+0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
|
|
+0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
|
|
+0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
|
|
+0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
|
|
+0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
|
|
+0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
|
|
+0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
|
|
+0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
|
|
+0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
|
|
+0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
|
|
+0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
|
|
+0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
|
|
+0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
|
|
+0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
|
|
+},{
|
|
+/* nibble 4 */
|
|
+0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
|
|
+0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
|
|
+0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
|
|
+0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
|
|
+0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
|
|
+0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
|
|
+0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
|
|
+0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
|
|
+0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
|
|
+0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
|
|
+0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
|
|
+0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
|
|
+0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
|
|
+0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
|
|
+0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
|
|
+0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
|
|
+},{
|
|
+/* nibble 5 */
|
|
+0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
|
|
+0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
|
|
+0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
|
|
+0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
|
|
+0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
|
|
+0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
|
|
+0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
|
|
+0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
|
|
+0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
|
|
+0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
|
|
+0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
|
|
+0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
|
|
+0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
|
|
+0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
|
|
+0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
|
|
+0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
|
|
+},{
|
|
+/* nibble 6 */
|
|
+0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
|
|
+0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
|
|
+0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
|
|
+0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
|
|
+0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
|
|
+0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
|
|
+0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
|
|
+0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
|
|
+0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
|
|
+0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
|
|
+0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
|
|
+0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
|
|
+0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
|
|
+0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
|
|
+0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
|
|
+0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
|
|
+},{
|
|
+/* nibble 7 */
|
|
+0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
|
|
+0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
|
|
+0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
|
|
+0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
|
|
+0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
|
|
+0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
|
|
+0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
|
|
+0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
|
|
+0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
|
|
+0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
|
|
+0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
|
|
+0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
|
|
+0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
|
|
+0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
|
|
+0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
|
|
+0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
|
|
+}};
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/mast.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,33 @@
|
|
+struct mast_callbacks {
|
|
+ int (*packet_encap)(struct device *mast, void *context,
|
|
+ struct sk_buff *skb, int flowref);
|
|
+ int (*link_inquire)(struct device *mast, void *context);
|
|
+};
|
|
+
|
|
+
|
|
+struct device *mast_init (int family,
|
|
+ struct mast_callbacks *callbacks,
|
|
+ unsigned int flags,
|
|
+ unsigned int desired_unit,
|
|
+ unsigned int max_flowref,
|
|
+ void *context);
|
|
+
|
|
+int mast_destroy(struct device *mast);
|
|
+
|
|
+int mast_recv(struct device *mast, struct sk_buff *skb, int flowref);
|
|
+
|
|
+/* free this skb as being useless, increment failure count. */
|
|
+int mast_toast(struct device *mast, struct sk_buff *skb, int flowref);
|
|
+
|
|
+int mast_linkstat (struct device *mast, int flowref,
|
|
+ int status);
|
|
+
|
|
+int mast_setreference (struct device *mast,
|
|
+ int defaultSA);
|
|
+
|
|
+int mast_setneighbor (struct device *mast,
|
|
+ struct sockaddr *source,
|
|
+ struct sockaddr *destination,
|
|
+ int flowref);
|
|
+
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,518 @@
|
|
+#ifndef _OPENSWAN_H
|
|
+/*
|
|
+ * header file for FreeS/WAN library functions
|
|
+ * Copyright (C) 1998, 1999, 2000 Henry Spencer.
|
|
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: openswan.h,v 1.93 2005/04/14 20:21:51 mcr Exp $
|
|
+ */
|
|
+#define _OPENSWAN_H /* seen it, no need to see it again */
|
|
+
|
|
+/* you'd think this should be builtin to compiler... */
|
|
+#ifndef TRUE
|
|
+#define TRUE 1
|
|
+#endif
|
|
+
|
|
+#ifndef FALSE
|
|
+#define FALSE 0
|
|
+#endif
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * We've just got to have some datatypes defined... And annoyingly, just
|
|
+ * where we get them depends on whether we're in userland or not.
|
|
+ */
|
|
+/* things that need to come from one place or the other, depending */
|
|
+#ifdef __KERNEL__
|
|
+#include <linux/types.h>
|
|
+#include <linux/socket.h>
|
|
+#include <linux/in.h>
|
|
+#include <linux/string.h>
|
|
+#include <linux/ctype.h>
|
|
+#define user_assert(foo) /*nothing*/
|
|
+#else
|
|
+#include <sys/types.h>
|
|
+#include <netinet/in.h>
|
|
+#include <string.h>
|
|
+#include <ctype.h>
|
|
+#include <assert.h>
|
|
+#define user_assert(foo) assert(foo)
|
|
+#include <stdio.h>
|
|
+
|
|
+# define uint8_t u_int8_t
|
|
+# define uint16_t u_int16_t
|
|
+# define uint32_t u_int32_t
|
|
+# define uint64_t u_int64_t
|
|
+
|
|
+
|
|
+# define DEBUG_NO_STATIC static
|
|
+
|
|
+#endif
|
|
+
|
|
+#include <openswan/ipsec_param.h>
|
|
+
|
|
+
|
|
+/*
|
|
+ * Grab the kernel version to see if we have NET_21, and therefore
|
|
+ * IPv6. Some of this is repeated from ipsec_kversions.h. Of course,
|
|
+ * we aren't really testing if the kernel has IPv6, but rather if the
|
|
+ * the include files do.
|
|
+ */
|
|
+#include <linux/version.h>
|
|
+#ifndef KERNEL_VERSION
|
|
+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
|
|
+#define NET_21
|
|
+#endif
|
|
+
|
|
+#ifndef IPPROTO_COMP
|
|
+# define IPPROTO_COMP 108
|
|
+#endif /* !IPPROTO_COMP */
|
|
+
|
|
+#ifndef IPPROTO_INT
|
|
+# define IPPROTO_INT 61
|
|
+#endif /* !IPPROTO_INT */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+#ifndef DEBUG_NO_STATIC
|
|
+# define DEBUG_NO_STATIC
|
|
+#endif
|
|
+#else /* CONFIG_KLIPS_DEBUG */
|
|
+#ifndef DEBUG_NO_STATIC
|
|
+# define DEBUG_NO_STATIC static
|
|
+#endif
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+#if !defined(ESPINUDP_WITH_NON_IKE)
|
|
+#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
|
|
+#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * Basic data types for the address-handling functions.
|
|
+ * ip_address and ip_subnet are supposed to be opaque types; do not
|
|
+ * use their definitions directly, they are subject to change!
|
|
+ */
|
|
+
|
|
+/* first, some quick fakes in case we're on an old system with no IPv6 */
|
|
+#ifndef s6_addr16
|
|
+struct in6_addr {
|
|
+ union
|
|
+ {
|
|
+ __u8 u6_addr8[16];
|
|
+ __u16 u6_addr16[8];
|
|
+ __u32 u6_addr32[4];
|
|
+ } in6_u;
|
|
+#define s6_addr in6_u.u6_addr8
|
|
+#define s6_addr16 in6_u.u6_addr16
|
|
+#define s6_addr32 in6_u.u6_addr32
|
|
+};
|
|
+struct sockaddr_in6 {
|
|
+ unsigned short int sin6_family; /* AF_INET6 */
|
|
+ __u16 sin6_port; /* Transport layer port # */
|
|
+ __u32 sin6_flowinfo; /* IPv6 flow information */
|
|
+ struct in6_addr sin6_addr; /* IPv6 address */
|
|
+ __u32 sin6_scope_id; /* scope id (new in RFC2553) */
|
|
+};
|
|
+#endif /* !s6_addr16 */
|
|
+
|
|
+/* then the main types */
|
|
+typedef struct {
|
|
+ union {
|
|
+ struct sockaddr_in v4;
|
|
+ struct sockaddr_in6 v6;
|
|
+ } u;
|
|
+} ip_address;
|
|
+typedef struct {
|
|
+ ip_address addr;
|
|
+ int maskbits;
|
|
+} ip_subnet;
|
|
+
|
|
+/* and the SA ID stuff */
|
|
+#ifdef __KERNEL__
|
|
+typedef __u32 ipsec_spi_t;
|
|
+#else
|
|
+typedef u_int32_t ipsec_spi_t;
|
|
+#endif
|
|
+typedef struct { /* to identify an SA, we need: */
|
|
+ ip_address dst; /* A. destination host */
|
|
+ ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
|
|
+# define SPI_PASS 256 /* magic values... */
|
|
+# define SPI_DROP 257 /* ...for use... */
|
|
+# define SPI_REJECT 258 /* ...with SA_INT */
|
|
+# define SPI_HOLD 259
|
|
+# define SPI_TRAP 260
|
|
+# define SPI_TRAPSUBNET 261
|
|
+ int proto; /* C. protocol */
|
|
+# define SA_ESP 50 /* IPPROTO_ESP */
|
|
+# define SA_AH 51 /* IPPROTO_AH */
|
|
+# define SA_IPIP 4 /* IPPROTO_IPIP */
|
|
+# define SA_COMP 108 /* IPPROTO_COMP */
|
|
+# define SA_INT 61 /* IANA reserved for internal use */
|
|
+} ip_said;
|
|
+
|
|
+/* misc */
|
|
+typedef const char *err_t; /* error message, or NULL for success */
|
|
+struct prng { /* pseudo-random-number-generator guts */
|
|
+ unsigned char sbox[256];
|
|
+ int i, j;
|
|
+ unsigned long count;
|
|
+};
|
|
+
|
|
+
|
|
+/*
|
|
+ * definitions for user space, taken from freeswan/ipsec_sa.h
|
|
+ */
|
|
+typedef uint32_t IPsecSAref_t;
|
|
+
|
|
+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
|
|
+
|
|
+#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
|
|
+#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
|
|
+
|
|
+#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0))
|
|
+
|
|
+/* GCC magic for use in function definitions! */
|
|
+#ifdef GCC_LINT
|
|
+# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
|
|
+# define NEVER_RETURNS __attribute__ ((noreturn))
|
|
+# define UNUSED __attribute__ ((unused))
|
|
+# define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */
|
|
+#else
|
|
+# define PRINTF_LIKE(n) /* ignore */
|
|
+# define NEVER_RETURNS /* ignore */
|
|
+# define UNUSED /* ignore */
|
|
+# define BLANK_FORMAT ""
|
|
+#endif
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * new IPv6-compatible functions
|
|
+ */
|
|
+
|
|
+/* text conversions */
|
|
+err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
|
|
+size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
|
|
+#define ULTOT_BUF (22+1) /* holds 64 bits in octal */
|
|
+err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
|
|
+err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
|
|
+size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
|
|
+/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
|
|
+#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1)
|
|
+err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
|
|
+size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
|
|
+#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3)
|
|
+size_t subnetporttot(const ip_subnet *src, int format, char *buf, size_t buflen);
|
|
+#define SUBNETPROTOTOT_BUF (SUBNETTOTO_BUF + ULTOT_BUF)
|
|
+err_t ttosa(const char *src, size_t srclen, ip_said *dst);
|
|
+size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
|
|
+#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
|
|
+err_t ttodata(const char *src, size_t srclen, int base, char *buf,
|
|
+ size_t buflen, size_t *needed);
|
|
+err_t ttodatav(const char *src, size_t srclen, int base,
|
|
+ char *buf, size_t buflen, size_t *needed,
|
|
+ char *errp, size_t errlen, unsigned int flags);
|
|
+#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */
|
|
+#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/
|
|
+#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */
|
|
+
|
|
+size_t datatot(const char *src, size_t srclen, int format, char *buf,
|
|
+ size_t buflen);
|
|
+size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst,
|
|
+ size_t dstlen);
|
|
+size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
|
|
+ size_t mlen, char *dst, size_t dstlen);
|
|
+#define KEYID_BUF 10 /* up to 9 text digits plus NUL */
|
|
+err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port,
|
|
+ int *has_port_wildcard);
|
|
+
|
|
+/* initializations */
|
|
+void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
|
|
+err_t loopbackaddr(int af, ip_address *dst);
|
|
+err_t unspecaddr(int af, ip_address *dst);
|
|
+err_t anyaddr(int af, ip_address *dst);
|
|
+err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
|
|
+err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
|
|
+err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
|
|
+
|
|
+/* misc. conversions and related */
|
|
+err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
|
|
+int addrtypeof(const ip_address *src);
|
|
+int subnettypeof(const ip_subnet *src);
|
|
+size_t addrlenof(const ip_address *src);
|
|
+size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
|
|
+size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
|
|
+int masktocount(const ip_address *src);
|
|
+void networkof(const ip_subnet *src, ip_address *dst);
|
|
+void maskof(const ip_subnet *src, ip_address *dst);
|
|
+
|
|
+/* tests */
|
|
+int sameaddr(const ip_address *a, const ip_address *b);
|
|
+int addrcmp(const ip_address *a, const ip_address *b);
|
|
+int samesubnet(const ip_subnet *a, const ip_subnet *b);
|
|
+int addrinsubnet(const ip_address *a, const ip_subnet *s);
|
|
+int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
|
|
+int subnetishost(const ip_subnet *s);
|
|
+int samesaid(const ip_said *a, const ip_said *b);
|
|
+int sameaddrtype(const ip_address *a, const ip_address *b);
|
|
+int samesubnettype(const ip_subnet *a, const ip_subnet *b);
|
|
+int isanyaddr(const ip_address *src);
|
|
+int isunspecaddr(const ip_address *src);
|
|
+int isloopbackaddr(const ip_address *src);
|
|
+
|
|
+/* low-level grot */
|
|
+int portof(const ip_address *src);
|
|
+void setportof(int port, ip_address *dst);
|
|
+struct sockaddr *sockaddrof(ip_address *src);
|
|
+size_t sockaddrlenof(const ip_address *src);
|
|
+
|
|
+/* PRNG */
|
|
+void prng_init(struct prng *prng, const unsigned char *key, size_t keylen);
|
|
+void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen);
|
|
+unsigned long prng_count(struct prng *prng);
|
|
+void prng_final(struct prng *prng);
|
|
+
|
|
+/* odds and ends */
|
|
+const char *ipsec_version_code(void);
|
|
+const char *ipsec_version_string(void);
|
|
+const char **ipsec_copyright_notice(void);
|
|
+
|
|
+const char *dns_string_rr(int rr, char *buf, int bufsize);
|
|
+const char *dns_string_datetime(time_t seconds,
|
|
+ char *buf,
|
|
+ int bufsize);
|
|
+
|
|
+
|
|
+/*
|
|
+ * old functions, to be deleted eventually
|
|
+ */
|
|
+
|
|
+/* unsigned long */
|
|
+const char * /* NULL for success, else string literal */
|
|
+atoul(
|
|
+ const char *src,
|
|
+ size_t srclen, /* 0 means strlen(src) */
|
|
+ int base, /* 0 means figure it out */
|
|
+ unsigned long *resultp
|
|
+);
|
|
+size_t /* space needed for full conversion */
|
|
+ultoa(
|
|
+ unsigned long n,
|
|
+ int base,
|
|
+ char *dst,
|
|
+ size_t dstlen
|
|
+);
|
|
+#define ULTOA_BUF 21 /* just large enough for largest result, */
|
|
+ /* assuming 64-bit unsigned long! */
|
|
+
|
|
+/* Internet addresses */
|
|
+const char * /* NULL for success, else string literal */
|
|
+atoaddr(
|
|
+ const char *src,
|
|
+ size_t srclen, /* 0 means strlen(src) */
|
|
+ struct in_addr *addr
|
|
+);
|
|
+size_t /* space needed for full conversion */
|
|
+addrtoa(
|
|
+ struct in_addr addr,
|
|
+ int format, /* character; 0 means default */
|
|
+ char *dst,
|
|
+ size_t dstlen
|
|
+);
|
|
+#define ADDRTOA_BUF 16 /* just large enough for largest result */
|
|
+
|
|
+/* subnets */
|
|
+const char * /* NULL for success, else string literal */
|
|
+atosubnet(
|
|
+ const char *src,
|
|
+ size_t srclen, /* 0 means strlen(src) */
|
|
+ struct in_addr *addr,
|
|
+ struct in_addr *mask
|
|
+);
|
|
+size_t /* space needed for full conversion */
|
|
+subnettoa(
|
|
+ struct in_addr addr,
|
|
+ struct in_addr mask,
|
|
+ int format, /* character; 0 means default */
|
|
+ char *dst,
|
|
+ size_t dstlen
|
|
+);
|
|
+#define SUBNETTOA_BUF 32 /* large enough for worst case result */
|
|
+
|
|
+/* ranges */
|
|
+const char * /* NULL for success, else string literal */
|
|
+atoasr(
|
|
+ const char *src,
|
|
+ size_t srclen, /* 0 means strlen(src) */
|
|
+ char *type, /* 'a', 's', 'r' */
|
|
+ struct in_addr *addrs /* two-element array */
|
|
+);
|
|
+size_t /* space needed for full conversion */
|
|
+rangetoa(
|
|
+ struct in_addr *addrs, /* two-element array */
|
|
+ int format, /* character; 0 means default */
|
|
+ char *dst,
|
|
+ size_t dstlen
|
|
+);
|
|
+#define RANGETOA_BUF 34 /* large enough for worst case result */
|
|
+
|
|
+/* data types for SA conversion functions */
|
|
+
|
|
+/* generic data, e.g. keys */
|
|
+const char * /* NULL for success, else string literal */
|
|
+atobytes(
|
|
+ const char *src,
|
|
+ size_t srclen, /* 0 means strlen(src) */
|
|
+ char *dst,
|
|
+ size_t dstlen,
|
|
+ size_t *lenp /* NULL means don't bother telling me */
|
|
+);
|
|
+size_t /* 0 failure, else true size */
|
|
+bytestoa(
|
|
+ const char *src,
|
|
+ size_t srclen,
|
|
+ int format, /* character; 0 means default */
|
|
+ char *dst,
|
|
+ size_t dstlen
|
|
+);
|
|
+
|
|
+/* old versions of generic-data functions; deprecated */
|
|
+size_t /* 0 failure, else true size */
|
|
+atodata(
|
|
+ const char *src,
|
|
+ size_t srclen, /* 0 means strlen(src) */
|
|
+ char *dst,
|
|
+ size_t dstlen
|
|
+);
|
|
+size_t /* 0 failure, else true size */
|
|
+datatoa(
|
|
+ const char *src,
|
|
+ size_t srclen,
|
|
+ int format, /* character; 0 means default */
|
|
+ char *dst,
|
|
+ size_t dstlen
|
|
+);
|
|
+
|
|
+/* part extraction and special addresses */
|
|
+struct in_addr
|
|
+subnetof(
|
|
+ struct in_addr addr,
|
|
+ struct in_addr mask
|
|
+);
|
|
+struct in_addr
|
|
+hostof(
|
|
+ struct in_addr addr,
|
|
+ struct in_addr mask
|
|
+);
|
|
+struct in_addr
|
|
+broadcastof(
|
|
+ struct in_addr addr,
|
|
+ struct in_addr mask
|
|
+);
|
|
+
|
|
+/* mask handling */
|
|
+int
|
|
+goodmask(
|
|
+ struct in_addr mask
|
|
+);
|
|
+int
|
|
+masktobits(
|
|
+ struct in_addr mask
|
|
+);
|
|
+struct in_addr
|
|
+bitstomask(
|
|
+ int n
|
|
+);
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * general utilities
|
|
+ */
|
|
+
|
|
+#ifndef __KERNEL__
|
|
+/* option pickup from files (userland only because of use of FILE) */
|
|
+const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
|
|
+ int optind, FILE *errorreport);
|
|
+
|
|
+/* sanitize a string */
|
|
+extern size_t sanitize_string(char *buf, size_t size);
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
+/*
|
|
+ * ENUM of klips debugging values. Not currently used in klips.
|
|
+ * debug flag is actually 32 -bits, but only one bit is ever used,
|
|
+ * so we can actually pack it all into a single 32-bit word.
|
|
+ */
|
|
+enum klips_debug_flags {
|
|
+ KDF_VERBOSE = 0,
|
|
+ KDF_XMIT = 1,
|
|
+ KDF_NETLINK = 2, /* obsolete */
|
|
+ KDF_XFORM = 3,
|
|
+ KDF_EROUTE = 4,
|
|
+ KDF_SPI = 5,
|
|
+ KDF_RADIJ = 6,
|
|
+ KDF_ESP = 7,
|
|
+ KDF_AH = 8, /* obsolete */
|
|
+ KDF_RCV = 9,
|
|
+ KDF_TUNNEL = 10,
|
|
+ KDF_PFKEY = 11,
|
|
+ KDF_COMP = 12
|
|
+};
|
|
+
|
|
+
|
|
+/*
|
|
+ * Debugging levels for pfkey_lib_debug
|
|
+ */
|
|
+#define PF_KEY_DEBUG_PARSE_NONE 0
|
|
+#define PF_KEY_DEBUG_PARSE_PROBLEM 1
|
|
+#define PF_KEY_DEBUG_PARSE_STRUCT 2
|
|
+#define PF_KEY_DEBUG_PARSE_FLOW 4
|
|
+#define PF_KEY_DEBUG_BUILD 8
|
|
+#define PF_KEY_DEBUG_PARSE_MAX 15
|
|
+
|
|
+extern unsigned int pfkey_lib_debug; /* bits selecting what to report */
|
|
+
|
|
+/*
|
|
+ * pluto and lwdnsq need to know the maximum size of the commands to,
|
|
+ * and replies from lwdnsq.
|
|
+ */
|
|
+
|
|
+#define LWDNSQ_CMDBUF_LEN 1024
|
|
+#define LWDNSQ_RESULT_LEN_MAX 4096
|
|
+
|
|
+
|
|
+/* syntax for passthrough SA */
|
|
+#ifndef PASSTHROUGHNAME
|
|
+#define PASSTHROUGHNAME "%passthrough"
|
|
+#define PASSTHROUGH4NAME "%passthrough4"
|
|
+#define PASSTHROUGH6NAME "%passthrough6"
|
|
+#define PASSTHROUGHIS "tun0@0.0.0.0"
|
|
+#define PASSTHROUGH4IS "tun0@0.0.0.0"
|
|
+#define PASSTHROUGH6IS "tun0@::"
|
|
+#define PASSTHROUGHTYPE "tun"
|
|
+#define PASSTHROUGHSPI 0
|
|
+#define PASSTHROUGHDST 0
|
|
+#endif
|
|
+
|
|
+
|
|
+
|
|
+#endif /* _OPENSWAN_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipcomp.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,61 @@
|
|
+/*
|
|
+ * IPCOMP zlib interface code.
|
|
+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
|
|
+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+
|
|
+ RCSID $Id: ipcomp.h,v 1.14 2004/07/10 19:08:41 mcr Exp $
|
|
+
|
|
+ */
|
|
+
|
|
+/* SSS */
|
|
+
|
|
+#ifndef _IPCOMP_H
|
|
+#define _IPCOMP_H
|
|
+
|
|
+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
|
|
+#ifndef IPCOMP_PREFIX
|
|
+#define IPCOMP_PREFIX
|
|
+#endif /* IPCOMP_PREFIX */
|
|
+
|
|
+#ifndef IPPROTO_COMP
|
|
+#define IPPROTO_COMP 108
|
|
+#endif /* IPPROTO_COMP */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern int sysctl_ipsec_debug_ipcomp;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+struct ipcomphdr { /* IPCOMP header */
|
|
+ __u8 ipcomp_nh; /* Next header (protocol) */
|
|
+ __u8 ipcomp_flags; /* Reserved, must be 0 */
|
|
+ __u16 ipcomp_cpi; /* Compression Parameter Index */
|
|
+};
|
|
+
|
|
+extern struct inet_protocol comp_protocol;
|
|
+extern int sysctl_ipsec_debug_ipcomp;
|
|
+
|
|
+#define IPCOMP_UNCOMPRESSABLE 0x000000001
|
|
+#define IPCOMP_COMPRESSIONERROR 0x000000002
|
|
+#define IPCOMP_PARMERROR 0x000000004
|
|
+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
|
|
+
|
|
+#define IPCOMP_ADAPT_INITIAL_TRIES 8
|
|
+#define IPCOMP_ADAPT_INITIAL_SKIP 4
|
|
+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
|
|
+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
|
|
+
|
|
+/* Function prototypes */
|
|
+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
|
|
+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
|
|
+
|
|
+#endif /* _IPCOMP_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_ah.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,200 @@
|
|
+/*
|
|
+ * Authentication Header declarations
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_ah.h,v 1.26 2004/09/13 02:22:10 mcr Exp $
|
|
+ */
|
|
+
|
|
+#include "ipsec_md5h.h"
|
|
+#include "ipsec_sha1.h"
|
|
+
|
|
+#ifndef IPPROTO_AH
|
|
+#define IPPROTO_AH 51
|
|
+#endif /* IPPROTO_AH */
|
|
+
|
|
+#include "ipsec_auth.h"
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+extern struct inet_protocol ah_protocol;
|
|
+
|
|
+struct options;
|
|
+
|
|
+struct ahhdr /* Generic AH header */
|
|
+{
|
|
+ __u8 ah_nh; /* Next header (protocol) */
|
|
+ __u8 ah_hl; /* AH length, in 32-bit words */
|
|
+ __u16 ah_rv; /* reserved, must be 0 */
|
|
+ __u32 ah_spi; /* Security Parameters Index */
|
|
+ __u32 ah_rpl; /* Replay prevention */
|
|
+ __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */
|
|
+};
|
|
+#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi
|
|
+ * and the ah_hl, says how many bytes after that
|
|
+ * to cover. */
|
|
+
|
|
+extern struct xform_functions ah_xform_funcs[];
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern int debug_ah;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_ah.h,v $
|
|
+ * Revision 1.26 2004/09/13 02:22:10 mcr
|
|
+ * #define inet_protocol if necessary.
|
|
+ *
|
|
+ * Revision 1.25 2004/09/06 18:35:41 mcr
|
|
+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
|
|
+ * so adjust for that.
|
|
+ *
|
|
+ * Revision 1.24 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.23 2004/04/05 19:55:04 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_ah.h,v
|
|
+ *
|
|
+ * Revision 1.22 2004/04/05 19:41:05 mcr
|
|
+ * merged alg-branch code.
|
|
+ *
|
|
+ * Revision 1.21 2003/12/13 19:10:16 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.22 2003/12/11 20:14:58 mcr
|
|
+ * refactored the xmit code, to move all encapsulation
|
|
+ * code into protocol functions. Note that all functions
|
|
+ * are essentially done by a single function, which is probably
|
|
+ * wrong.
|
|
+ * the rcv_functions structures are renamed xform_functions.
|
|
+ *
|
|
+ * Revision 1.21 2003/12/06 21:21:19 mcr
|
|
+ * split up receive path into per-transform files, for
|
|
+ * easier later removal.
|
|
+ *
|
|
+ * Revision 1.20.8.1 2003/12/22 15:25:52 jjo
|
|
+ * Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.20 2003/02/06 02:21:34 rgb
|
|
+ *
|
|
+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
|
|
+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
|
|
+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
|
|
+ *
|
|
+ * Revision 1.19 2002/09/16 21:19:13 mcr
|
|
+ * fixes for west-ah-icmp-01 - length of AH header must be
|
|
+ * calculated properly, and next_header field properly copied.
|
|
+ *
|
|
+ * Revision 1.18 2002/05/14 02:37:02 rgb
|
|
+ * Change reference from _TDB to _IPSA.
|
|
+ *
|
|
+ * Revision 1.17 2002/04/24 07:36:46 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_ah.h,v
|
|
+ *
|
|
+ * Revision 1.16 2002/02/20 01:27:06 rgb
|
|
+ * Ditched a pile of structs only used by the old Netlink interface.
|
|
+ *
|
|
+ * Revision 1.15 2001/12/11 02:35:57 rgb
|
|
+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
|
|
+ *
|
|
+ * Revision 1.14 2001/11/26 09:23:47 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.13.2.1 2001/09/25 02:18:24 mcr
|
|
+ * replace "struct device" with "struct netdevice"
|
|
+ *
|
|
+ * Revision 1.13 2001/06/14 19:35:08 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.12 2000/09/12 03:21:20 rgb
|
|
+ * Cleared out unused htonq.
|
|
+ *
|
|
+ * Revision 1.11 2000/09/08 19:12:55 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.10 2000/01/21 06:13:10 rgb
|
|
+ * Tidied up spacing.
|
|
+ * Added macros for HMAC padding magic numbers.(kravietz)
|
|
+ *
|
|
+ * Revision 1.9 1999/12/07 18:16:23 rgb
|
|
+ * Fixed comments at end of #endif lines.
|
|
+ *
|
|
+ * Revision 1.8 1999/04/11 00:28:56 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.7 1999/04/06 04:54:25 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.6 1999/01/26 02:06:01 rgb
|
|
+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
|
|
+ *
|
|
+ * Revision 1.5 1999/01/22 06:17:49 rgb
|
|
+ * Updated macro comments.
|
|
+ * Added context types to support algorithm switch code.
|
|
+ * 64-bit clean-up -- converting 'u long long' to __u64.
|
|
+ *
|
|
+ * Revision 1.4 1998/07/14 15:54:56 rgb
|
|
+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
|
|
+ *
|
|
+ * Revision 1.3 1998/06/30 18:05:16 rgb
|
|
+ * Comment out references to htonq.
|
|
+ *
|
|
+ * Revision 1.2 1998/06/25 19:33:46 rgb
|
|
+ * Add prototype for protocol receive function.
|
|
+ * Rearrange for more logical layout.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:43 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.4 1998/05/18 22:28:43 rgb
|
|
+ * Disable key printing facilities from /proc/net/ipsec_*.
|
|
+ *
|
|
+ * Revision 1.3 1998/04/21 21:29:07 rgb
|
|
+ * Rearrange debug switches to change on the fly debug output from user
|
|
+ * space. Only kernel changes checked in at this time. radij.c was also
|
|
+ * changed to temporarily remove buggy debugging code in rj_delete causing
|
|
+ * an OOPS and hence, netlink device open errors.
|
|
+ *
|
|
+ * Revision 1.2 1998/04/12 22:03:17 rgb
|
|
+ * Updated ESP-3DES-HMAC-MD5-96,
|
|
+ * ESP-DES-HMAC-MD5-96,
|
|
+ * AH-HMAC-MD5-96,
|
|
+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
|
|
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
|
|
+ *
|
|
+ * Fixed eroute references in /proc/net/ipsec*.
|
|
+ *
|
|
+ * Started to patch module unloading memory leaks in ipsec_netlink and
|
|
+ * radij tree unloading.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:05:55 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * Added definitions for new AH transforms.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:35:48 ji
|
|
+ * Minor Cleanup.
|
|
+ * Rationalized debugging code.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_alg.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,248 @@
|
|
+/*
|
|
+ * Modular extensions service and registration functions interface
|
|
+ *
|
|
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
|
|
+ *
|
|
+ * ipsec_alg.h,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
|
|
+ *
|
|
+ */
|
|
+/*
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ */
|
|
+#ifndef IPSEC_ALG_H
|
|
+#define IPSEC_ALG_H
|
|
+
|
|
+/*
|
|
+ * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__
|
|
+ * *BUT* its a compiler variable.
|
|
+ */
|
|
+#if (__GNUC__ >= 3)
|
|
+#ifndef __FUNCTION__
|
|
+#define __FUNCTION__ __func__
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+/* Version 0.8.1-0 */
|
|
+#define IPSEC_ALG_VERSION 0x00080100
|
|
+
|
|
+#include <linux/types.h>
|
|
+#include <linux/list.h>
|
|
+#include <asm/atomic.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+/*
|
|
+ * The following structs are used via pointers in ipsec_alg object to
|
|
+ * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying
|
|
+ * module development
|
|
+ */
|
|
+struct ipsec_sa;
|
|
+struct esp;
|
|
+
|
|
+/**************************************
|
|
+ *
|
|
+ * Main registration object
|
|
+ *
|
|
+ *************************************/
|
|
+#define IPSEC_ALG_VERSION_QUAD(v) \
|
|
+ (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff)
|
|
+/*
|
|
+ * Main ipsec_alg objects: "OOPrograming wannabe"
|
|
+ * Hierachy (carefully handled with _minimal_ cast'ing):
|
|
+ *
|
|
+ * ipsec_alg+
|
|
+ * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT)
|
|
+ * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH)
|
|
+ */
|
|
+
|
|
+/***************************************************************
|
|
+ *
|
|
+ * INTERFACE object: struct ipsec_alg
|
|
+ *
|
|
+ ***************************************************************/
|
|
+
|
|
+#define ixt_alg_type ixt_support.ias_exttype
|
|
+#define ixt_alg_id ixt_support.ias_id
|
|
+
|
|
+#define IPSEC_ALG_ST_SUPP 0x01
|
|
+#define IPSEC_ALG_ST_REGISTERED 0x02
|
|
+#define IPSEC_ALG_ST_EXCL 0x04
|
|
+struct ipsec_alg {
|
|
+ unsigned ixt_version; /* only allow this version (or 'near')*/ \
|
|
+ struct list_head ixt_list; /* dlinked list */ \
|
|
+ struct module *ixt_module; /* THIS_MODULE */ \
|
|
+ unsigned ixt_state; /* state flags */ \
|
|
+ atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \
|
|
+ char ixt_name[16]; /* descriptive short name, eg. "3des" */ \
|
|
+ void *ixt_data; /* private for algo implementation */ \
|
|
+ uint8_t ixt_blocksize; /* blocksize in bytes */ \
|
|
+
|
|
+ struct ipsec_alg_supported ixt_support;
|
|
+};
|
|
+/*
|
|
+ * Note the const in cbc_encrypt IV arg:
|
|
+ * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy
|
|
+ */
|
|
+struct ipsec_alg_enc {
|
|
+ struct ipsec_alg ixt_common;
|
|
+ unsigned ixt_e_keylen; /* raw key length in bytes */
|
|
+ unsigned ixt_e_ctx_size; /* sa_p->key_e_size */
|
|
+ int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize);
|
|
+ __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize);
|
|
+ void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e);
|
|
+ int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt);
|
|
+};
|
|
+struct ipsec_alg_auth {
|
|
+ struct ipsec_alg ixt_common;
|
|
+ unsigned ixt_a_keylen; /* raw key length in bytes */
|
|
+ unsigned ixt_a_ctx_size; /* sa_p->key_a_size */
|
|
+ unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */
|
|
+ int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen);
|
|
+ int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen);
|
|
+};
|
|
+/*
|
|
+ * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT},
|
|
+ * to avoid header coupling for true constants
|
|
+ * about headers ... "cp is your friend" --Linus
|
|
+ */
|
|
+#define IPSEC_ALG_TYPE_AUTH 14
|
|
+#define IPSEC_ALG_TYPE_ENCRYPT 15
|
|
+
|
|
+/***************************************************************
|
|
+ *
|
|
+ * INTERFACE for module loading,testing, and unloading
|
|
+ *
|
|
+ ***************************************************************/
|
|
+/* - registration calls */
|
|
+int register_ipsec_alg(struct ipsec_alg *);
|
|
+int unregister_ipsec_alg(struct ipsec_alg *);
|
|
+/* - optional (simple test) for algos */
|
|
+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm);
|
|
+/* inline wrappers (usefull for type validation */
|
|
+static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
|
|
+ return register_ipsec_alg((struct ipsec_alg*)ixt);
|
|
+}
|
|
+static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
|
|
+ return unregister_ipsec_alg((struct ipsec_alg*)ixt);
|
|
+}
|
|
+static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
|
|
+ return register_ipsec_alg((struct ipsec_alg*)ixt);
|
|
+}
|
|
+static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
|
|
+ return unregister_ipsec_alg((struct ipsec_alg*)ixt);
|
|
+}
|
|
+
|
|
+/*****************************************************************
|
|
+ *
|
|
+ * INTERFACE for ENC services: key creation, encrypt function
|
|
+ *
|
|
+ *****************************************************************/
|
|
+
|
|
+#define IPSEC_ALG_ENCRYPT 1
|
|
+#define IPSEC_ALG_DECRYPT 0
|
|
+
|
|
+/* encryption key context creation function */
|
|
+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p);
|
|
+/*
|
|
+ * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns
|
|
+ * 0 or ERR<0
|
|
+ */
|
|
+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action);
|
|
+
|
|
+/***************************************************************
|
|
+ *
|
|
+ * INTERFACE for AUTH services: key creation, hash functions
|
|
+ *
|
|
+ ***************************************************************/
|
|
+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p);
|
|
+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ;
|
|
+#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0)
|
|
+
|
|
+/* only called from ipsec_init.c */
|
|
+int ipsec_alg_init(void);
|
|
+
|
|
+/* algo module glue for static algos */
|
|
+void ipsec_alg_static_init(void);
|
|
+typedef int (*ipsec_alg_init_func_t) (void);
|
|
+
|
|
+/**********************************************
|
|
+ *
|
|
+ * INTERFACE for ipsec_sa init and wipe
|
|
+ *
|
|
+ **********************************************/
|
|
+
|
|
+/* returns true if ipsec_sa has ipsec_alg obj attached */
|
|
+/*
|
|
+ * Initializes ipsec_sa's ipsec_alg object, using already loaded
|
|
+ * proto, authalg, encalg.; links ipsec_alg objects (enc, auth)
|
|
+ */
|
|
+int ipsec_alg_sa_init(struct ipsec_sa *sa_p);
|
|
+/*
|
|
+ * Destroys ipsec_sa's ipsec_alg object
|
|
+ * unlinking ipsec_alg objects
|
|
+ */
|
|
+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p);
|
|
+
|
|
+#define IPSEC_ALG_MODULE_INIT_MOD( func_name ) \
|
|
+ static int func_name(void); \
|
|
+ module_init(func_name); \
|
|
+ static int __init func_name(void)
|
|
+#define IPSEC_ALG_MODULE_EXIT_MOD( func_name ) \
|
|
+ static void func_name(void); \
|
|
+ module_exit(func_name); \
|
|
+ static void __exit func_name(void)
|
|
+
|
|
+#define IPSEC_ALG_MODULE_INIT_STATIC( func_name ) \
|
|
+ extern int func_name(void); \
|
|
+ int func_name(void)
|
|
+#define IPSEC_ALG_MODULE_EXIT_STATIC( func_name ) \
|
|
+ extern void func_name(void); \
|
|
+ void func_name(void)
|
|
+
|
|
+/**********************************************
|
|
+ *
|
|
+ * 2.2 backport for some 2.4 useful module stuff
|
|
+ *
|
|
+ **********************************************/
|
|
+#ifdef MODULE
|
|
+#ifndef THIS_MODULE
|
|
+#define THIS_MODULE (&__this_module)
|
|
+#endif
|
|
+#ifndef module_init
|
|
+typedef int (*__init_module_func_t)(void);
|
|
+typedef void (*__cleanup_module_func_t)(void);
|
|
+
|
|
+#define module_init(x) \
|
|
+ int init_module(void) __attribute__((alias(#x))); \
|
|
+ static inline __init_module_func_t __init_module_inline(void) \
|
|
+ { return x; }
|
|
+#define module_exit(x) \
|
|
+ void cleanup_module(void) __attribute__((alias(#x))); \
|
|
+ static inline __cleanup_module_func_t __cleanup_module_inline(void) \
|
|
+ { return x; }
|
|
+#endif
|
|
+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_MOD( func_name )
|
|
+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_MOD( func_name )
|
|
+
|
|
+#else /* not MODULE */
|
|
+#ifndef THIS_MODULE
|
|
+#define THIS_MODULE NULL
|
|
+#endif
|
|
+/*
|
|
+ * I only want module_init() magic
|
|
+ * when algo.c file *is THE MODULE*, in all other
|
|
+ * cases, initialization is called explicitely from ipsec_alg_init()
|
|
+ */
|
|
+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_STATIC(func_name)
|
|
+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_STATIC(func_name)
|
|
+#endif
|
|
+
|
|
+#endif /* IPSEC_ALG_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_alg_3des.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,12 @@
|
|
+struct TripleDES_context {
|
|
+ des_key_schedule s1;
|
|
+ des_key_schedule s2;
|
|
+ des_key_schedule s3;
|
|
+};
|
|
+typedef struct TripleDES_context TripleDES_context;
|
|
+
|
|
+#define ESP_3DES_KEY_SZ 3*(sizeof(des_cblock))
|
|
+#define ESP_3DES_CBC_BLK_LEN 8
|
|
+
|
|
+
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_auth.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,100 @@
|
|
+/*
|
|
+ * Authentication Header declarations
|
|
+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_auth.h,v 1.3 2004/04/06 02:49:08 mcr Exp $
|
|
+ */
|
|
+
|
|
+#include "ipsec_md5h.h"
|
|
+#include "ipsec_sha1.h"
|
|
+
|
|
+#ifndef IPSEC_AUTH_H
|
|
+#define IPSEC_AUTH_H
|
|
+
|
|
+#define AH_FLENGTH 12 /* size of fixed part */
|
|
+#define AHMD5_KMAX 64 /* MD5 max 512 bits key */
|
|
+#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */
|
|
+
|
|
+#define AHMD596_KLEN 16 /* MD5 128 bits key */
|
|
+#define AHSHA196_KLEN 20 /* SHA1 160 bits key */
|
|
+
|
|
+#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */
|
|
+#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */
|
|
+
|
|
+#define AHMD596_BLKLEN 64 /* MD5 block length */
|
|
+#define AHSHA196_BLKLEN 64 /* SHA1 block length */
|
|
+#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */
|
|
+#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */
|
|
+#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */
|
|
+
|
|
+#define AH_BLKLEN_MAX 128 /* keep up to date! */
|
|
+
|
|
+
|
|
+#define AH_AMAX AHSHA196_ALEN /* keep up to date! */
|
|
+#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */
|
|
+#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */
|
|
+
|
|
+#define DB_AH_PKTRX 0x0001
|
|
+#define DB_AH_PKTRX2 0x0002
|
|
+#define DB_AH_DMP 0x0004
|
|
+#define DB_AH_IPSA 0x0010
|
|
+#define DB_AH_XF 0x0020
|
|
+#define DB_AH_INAU 0x0040
|
|
+#define DB_AH_REPLAY 0x0100
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+/* General HMAC algorithm is described in RFC 2104 */
|
|
+
|
|
+#define HMAC_IPAD 0x36
|
|
+#define HMAC_OPAD 0x5C
|
|
+
|
|
+struct md5_ctx {
|
|
+ MD5_CTX ictx; /* context after H(K XOR ipad) */
|
|
+ MD5_CTX octx; /* context after H(K XOR opad) */
|
|
+};
|
|
+
|
|
+struct sha1_ctx {
|
|
+ SHA1_CTX ictx; /* context after H(K XOR ipad) */
|
|
+ SHA1_CTX octx; /* context after H(K XOR opad) */
|
|
+};
|
|
+
|
|
+struct auth_alg {
|
|
+ void (*init)(void *ctx);
|
|
+ void (*update)(void *ctx, unsigned char *bytes, __u32 len);
|
|
+ void (*final)(unsigned char *hash, void *ctx);
|
|
+ int hashlen;
|
|
+};
|
|
+
|
|
+struct options;
|
|
+
|
|
+#endif /* __KERNEL__ */
|
|
+#endif /* IPSEC_AUTH_H */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_auth.h,v $
|
|
+ * Revision 1.3 2004/04/06 02:49:08 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.2 2004/04/05 19:55:04 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_auth.h,v
|
|
+ *
|
|
+ * Revision 1.1 2003/12/13 19:10:16 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.1 2003/12/06 21:21:19 mcr
|
|
+ * split up receive path into per-transform files, for
|
|
+ * easier later removal.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_encap.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,149 @@
|
|
+/*
|
|
+ * declarations relevant to encapsulation-like operations
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_encap.h,v 1.19 2004/04/05 19:55:04 mcr Exp $
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_ENCAP_H_
|
|
+
|
|
+#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/
|
|
+ /* (2 * sizeof(struct in_addr)) */
|
|
+ /* sizeof(struct sockaddr_encap)
|
|
+ - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
|
|
+
|
|
+struct sockaddr_encap
|
|
+{
|
|
+ __u8 sen_len; /* length */
|
|
+ __u8 sen_family; /* AF_ENCAP */
|
|
+ __u16 sen_type; /* see SENT_* */
|
|
+ union
|
|
+ {
|
|
+ struct /* SENT_IP4 */
|
|
+ {
|
|
+ struct in_addr Src;
|
|
+ struct in_addr Dst;
|
|
+ __u8 Proto;
|
|
+ __u16 Sport;
|
|
+ __u16 Dport;
|
|
+ } Sip4;
|
|
+ } Sen;
|
|
+};
|
|
+
|
|
+#define sen_ip_src Sen.Sip4.Src
|
|
+#define sen_ip_dst Sen.Sip4.Dst
|
|
+#define sen_proto Sen.Sip4.Proto
|
|
+#define sen_sport Sen.Sip4.Sport
|
|
+#define sen_dport Sen.Sip4.Dport
|
|
+
|
|
+#ifndef AF_ENCAP
|
|
+#define AF_ENCAP 26
|
|
+#endif /* AF_ENCAP */
|
|
+
|
|
+#define _IPSEC_ENCAP_H_
|
|
+#endif /* _IPSEC_ENCAP_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_encap.h,v $
|
|
+ * Revision 1.19 2004/04/05 19:55:04 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_encap.h,v
|
|
+ *
|
|
+ * Revision 1.18 2003/10/31 02:27:05 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.17.30.1 2003/09/21 13:59:38 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.17 2002/04/24 07:36:46 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_encap.h,v
|
|
+ *
|
|
+ * Revision 1.16 2001/11/26 09:23:47 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.15.2.1 2001/09/25 02:18:54 mcr
|
|
+ * struct eroute moved to ipsec_eroute.h
|
|
+ *
|
|
+ * Revision 1.15 2001/09/14 16:58:36 rgb
|
|
+ * Added support for storing the first and last packets through a HOLD.
|
|
+ *
|
|
+ * Revision 1.14 2001/09/08 21:13:31 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.13 2001/06/14 19:35:08 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.12 2001/05/27 06:12:10 rgb
|
|
+ * Added structures for pid, packet count and last access time to eroute.
|
|
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
|
|
+ *
|
|
+ * Revision 1.11 2000/09/08 19:12:56 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.10 2000/03/22 16:15:36 rgb
|
|
+ * Fixed renaming of dev_get (MB).
|
|
+ *
|
|
+ * Revision 1.9 2000/01/21 06:13:26 rgb
|
|
+ * Added a macro for AF_ENCAP
|
|
+ *
|
|
+ * Revision 1.8 1999/12/31 14:56:55 rgb
|
|
+ * MB fix for 2.3 dev-use-count.
|
|
+ *
|
|
+ * Revision 1.7 1999/11/18 04:09:18 rgb
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ *
|
|
+ * Revision 1.6 1999/09/24 00:34:13 rgb
|
|
+ * Add Marc Boucher's support for 2.3.xx+.
|
|
+ *
|
|
+ * Revision 1.5 1999/04/11 00:28:57 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.4 1999/04/06 04:54:25 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.3 1998/10/19 14:44:28 rgb
|
|
+ * Added inclusion of freeswan.h.
|
|
+ * sa_id structure implemented and used: now includes protocol.
|
|
+ *
|
|
+ * Revision 1.2 1998/07/14 18:19:33 rgb
|
|
+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:44 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.2 1998/04/21 21:29:10 rgb
|
|
+ * Rearrange debug switches to change on the fly debug output from user
|
|
+ * space. Only kernel changes checked in at this time. radij.c was also
|
|
+ * changed to temporarily remove buggy debugging code in rj_delete causing
|
|
+ * an OOPS and hence, netlink device open errors.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:05:58 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * Minor cosmetic changes.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:35:48 ji
|
|
+ * Minor Cleanup.
|
|
+ * Rationalized debugging code.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_eroute.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,112 @@
|
|
+/*
|
|
+ * @(#) declarations of eroute structures
|
|
+ *
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_eroute.h,v 1.5 2004/04/05 19:55:05 mcr Exp $
|
|
+ *
|
|
+ * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_EROUTE_H_
|
|
+
|
|
+#include "radij.h"
|
|
+#include "ipsec_encap.h"
|
|
+#include "ipsec_radij.h"
|
|
+
|
|
+/*
|
|
+ * The "type" is really part of the address as far as the routing
|
|
+ * system is concerned. By using only one bit in the type field
|
|
+ * for each type, we sort-of make sure that different types of
|
|
+ * encapsulation addresses won't be matched against the wrong type.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * An entry in the radix tree
|
|
+ */
|
|
+
|
|
+struct rjtentry
|
|
+{
|
|
+ struct radij_node rd_nodes[2]; /* tree glue, and other values */
|
|
+#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
|
|
+#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
|
|
+ short rd_flags;
|
|
+ short rd_count;
|
|
+};
|
|
+
|
|
+struct ident
|
|
+{
|
|
+ __u16 type; /* identity type */
|
|
+ __u64 id; /* identity id */
|
|
+ __u8 len; /* identity len */
|
|
+ caddr_t data; /* identity data */
|
|
+};
|
|
+
|
|
+/*
|
|
+ * An encapsulation route consists of a pointer to a
|
|
+ * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
|
|
+ */
|
|
+
|
|
+struct eroute
|
|
+{
|
|
+ struct rjtentry er_rjt;
|
|
+ ip_said er_said;
|
|
+ uint32_t er_pid;
|
|
+ uint32_t er_count;
|
|
+ uint64_t er_lasttime;
|
|
+ struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
|
|
+ struct sockaddr_encap er_emask;
|
|
+ struct ident er_ident_s;
|
|
+ struct ident er_ident_d;
|
|
+ struct sk_buff* er_first;
|
|
+ struct sk_buff* er_last;
|
|
+};
|
|
+
|
|
+#define er_dst er_said.dst
|
|
+#define er_spi er_said.spi
|
|
+
|
|
+#define _IPSEC_EROUTE_H_
|
|
+#endif /* _IPSEC_EROUTE_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_eroute.h,v $
|
|
+ * Revision 1.5 2004/04/05 19:55:05 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_eroute.h,v
|
|
+ *
|
|
+ * Revision 1.4 2003/10/31 02:27:05 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.3.30.2 2003/10/29 01:10:19 mcr
|
|
+ * elimited "struct sa_id"
|
|
+ *
|
|
+ * Revision 1.3.30.1 2003/09/21 13:59:38 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.3 2002/04/24 07:36:46 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_eroute.h,v
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:13 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:18:54 mcr
|
|
+ * struct eroute moved to ipsec_eroute.h
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_errs.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,53 @@
|
|
+/*
|
|
+ * @(#) definition of ipsec_errs structure
|
|
+ *
|
|
+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * and Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_errs.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
|
|
+ *
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * This file describes the errors/statistics that FreeSWAN collects.
|
|
+ *
|
|
+ */
|
|
+
|
|
+struct ipsec_errs {
|
|
+ __u32 ips_alg_errs; /* number of algorithm errors */
|
|
+ __u32 ips_auth_errs; /* # of authentication errors */
|
|
+ __u32 ips_encsize_errs; /* # of encryption size errors*/
|
|
+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
|
|
+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
|
|
+};
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_errs.h,v $
|
|
+ * Revision 1.4 2004/04/05 19:55:05 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_errs.h,v
|
|
+ *
|
|
+ * Revision 1.3 2002/04/24 07:36:46 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_errs.h,v
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:13 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
|
|
+ * lifetime structure created and common functions created.
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_esp.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,157 @@
|
|
+/*
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_esp.h,v 1.28 2004/09/13 02:22:10 mcr Exp $
|
|
+ */
|
|
+
|
|
+#include "openswan/ipsec_md5h.h"
|
|
+#include "openswan/ipsec_sha1.h"
|
|
+
|
|
+#include "crypto/des.h"
|
|
+
|
|
+#ifndef IPPROTO_ESP
|
|
+#define IPPROTO_ESP 50
|
|
+#endif /* IPPROTO_ESP */
|
|
+
|
|
+#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/
|
|
+
|
|
+#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */
|
|
+#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */
|
|
+#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */
|
|
+#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */
|
|
+#define EMT_ESPDES_IV_SZ 8 /* IV size */
|
|
+#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */
|
|
+
|
|
+#define ESP_IV_MAXSZ 16 /* This is _critical_ */
|
|
+#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int))
|
|
+
|
|
+#define DB_ES_PKTRX 0x0001
|
|
+#define DB_ES_PKTRX2 0x0002
|
|
+#define DB_ES_IPSA 0x0010
|
|
+#define DB_ES_XF 0x0020
|
|
+#define DB_ES_IPAD 0x0040
|
|
+#define DB_ES_INAU 0x0080
|
|
+#define DB_ES_OINFO 0x0100
|
|
+#define DB_ES_OINFO2 0x0200
|
|
+#define DB_ES_OH 0x0400
|
|
+#define DB_ES_REPLAY 0x0800
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+struct des_eks {
|
|
+ des_key_schedule ks;
|
|
+};
|
|
+
|
|
+extern struct inet_protocol esp_protocol;
|
|
+
|
|
+struct options;
|
|
+
|
|
+struct esphdr
|
|
+{
|
|
+ __u32 esp_spi; /* Security Parameters Index */
|
|
+ __u32 esp_rpl; /* Replay counter */
|
|
+ __u8 esp_iv[8]; /* iv */
|
|
+};
|
|
+
|
|
+extern struct xform_functions esp_xform_funcs[];
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern int debug_esp;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_esp.h,v $
|
|
+ * Revision 1.28 2004/09/13 02:22:10 mcr
|
|
+ * #define inet_protocol if necessary.
|
|
+ *
|
|
+ * Revision 1.27 2004/09/06 18:35:41 mcr
|
|
+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
|
|
+ * so adjust for that.
|
|
+ *
|
|
+ * Revision 1.26 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.25 2004/04/06 02:49:08 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.24 2004/04/05 19:55:05 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_esp.h,v
|
|
+ *
|
|
+ * Revision 1.23 2004/04/05 19:41:05 mcr
|
|
+ * merged alg-branch code.
|
|
+ *
|
|
+ * Revision 1.22 2003/12/13 19:10:16 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.23 2003/12/11 20:14:58 mcr
|
|
+ * refactored the xmit code, to move all encapsulation
|
|
+ * code into protocol functions. Note that all functions
|
|
+ * are essentially done by a single function, which is probably
|
|
+ * wrong.
|
|
+ * the rcv_functions structures are renamed xform_functions.
|
|
+ *
|
|
+ * Revision 1.22 2003/12/06 21:21:19 mcr
|
|
+ * split up receive path into per-transform files, for
|
|
+ * easier later removal.
|
|
+ *
|
|
+ * Revision 1.21.8.1 2003/12/22 15:25:52 jjo
|
|
+ * Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.21 2003/02/06 02:21:34 rgb
|
|
+ *
|
|
+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
|
|
+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
|
|
+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
|
|
+ *
|
|
+ * Revision 1.20 2002/05/14 02:37:02 rgb
|
|
+ * Change reference from _TDB to _IPSA.
|
|
+ *
|
|
+ * Revision 1.19 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.18 2002/04/24 07:36:46 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_esp.h,v
|
|
+ *
|
|
+ * Revision 1.17 2002/02/20 01:27:07 rgb
|
|
+ * Ditched a pile of structs only used by the old Netlink interface.
|
|
+ *
|
|
+ * Revision 1.16 2001/12/11 02:35:57 rgb
|
|
+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
|
|
+ *
|
|
+ * Revision 1.15 2001/11/26 09:23:48 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.14.2.3 2001/10/23 04:16:42 mcr
|
|
+ * get definition of des_key_schedule from des.h
|
|
+ *
|
|
+ * Revision 1.14.2.2 2001/10/22 20:33:13 mcr
|
|
+ * use "des_key_schedule" structure instead of cooking our own.
|
|
+ *
|
|
+ * Revision 1.14.2.1 2001/09/25 02:18:25 mcr
|
|
+ * replace "struct device" with "struct netdevice"
|
|
+ *
|
|
+ * Revision 1.14 2001/06/14 19:35:08 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.13 2000/09/08 19:12:56 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.12 2000/08/01 14:51:50 rgb
|
|
+ * Removed _all_ remaining traces of DES.
|
|
+ *
|
|
+ * Revision 1.11 2000/01/10 16:36:20 rgb
|
|
+ * Ditch last of EME option flags, including initiator.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_ipcomp.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,94 @@
|
|
+/*
|
|
+ * IP compression header declations
|
|
+ *
|
|
+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_ipcomp.h,v 1.4 2004/07/10 19:08:41 mcr Exp $
|
|
+ */
|
|
+
|
|
+#ifndef IPSEC_IPCOMP_H
|
|
+#define IPSEC_IPCOMP_H
|
|
+
|
|
+#include "openswan/ipsec_auth.h"
|
|
+
|
|
+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
|
|
+#ifndef IPCOMP_PREFIX
|
|
+#define IPCOMP_PREFIX
|
|
+#endif /* IPCOMP_PREFIX */
|
|
+
|
|
+#ifndef IPPROTO_COMP
|
|
+#define IPPROTO_COMP 108
|
|
+#endif /* IPPROTO_COMP */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern int sysctl_ipsec_debug_ipcomp;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+struct ipcomphdr { /* IPCOMP header */
|
|
+ __u8 ipcomp_nh; /* Next header (protocol) */
|
|
+ __u8 ipcomp_flags; /* Reserved, must be 0 */
|
|
+ __u16 ipcomp_cpi; /* Compression Parameter Index */
|
|
+};
|
|
+
|
|
+extern struct inet_protocol comp_protocol;
|
|
+extern int sysctl_ipsec_debug_ipcomp;
|
|
+
|
|
+#define IPCOMP_UNCOMPRESSABLE 0x000000001
|
|
+#define IPCOMP_COMPRESSIONERROR 0x000000002
|
|
+#define IPCOMP_PARMERROR 0x000000004
|
|
+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
|
|
+
|
|
+#define IPCOMP_ADAPT_INITIAL_TRIES 8
|
|
+#define IPCOMP_ADAPT_INITIAL_SKIP 4
|
|
+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
|
|
+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
|
|
+
|
|
+/* Function prototypes */
|
|
+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
|
|
+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
|
|
+
|
|
+extern struct xform_functions ipcomp_xform_funcs[];
|
|
+
|
|
+#endif /* IPSEC_IPCOMP_H */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_ipcomp.h,v $
|
|
+ * Revision 1.4 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.3 2004/04/06 02:49:08 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.2 2004/04/05 19:55:05 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_ipcomp.h,v
|
|
+ *
|
|
+ * Revision 1.1 2003/12/13 19:10:16 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.2 2003/12/11 20:14:58 mcr
|
|
+ * refactored the xmit code, to move all encapsulation
|
|
+ * code into protocol functions. Note that all functions
|
|
+ * are essentially done by a single function, which is probably
|
|
+ * wrong.
|
|
+ * the rcv_functions structures are renamed xform_functions.
|
|
+ *
|
|
+ * Revision 1.1 2003/12/06 21:21:19 mcr
|
|
+ * split up receive path into per-transform files, for
|
|
+ * easier later removal.
|
|
+ *
|
|
+ *
|
|
+ *
|
|
+ */
|
|
+
|
|
+
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_ipe4.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,68 @@
|
|
+/*
|
|
+ * IP-in-IP Header declarations
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_ipe4.h,v 1.6 2004/04/05 19:55:05 mcr Exp $
|
|
+ */
|
|
+
|
|
+/* The packet header is an IP header! */
|
|
+
|
|
+struct ipe4_xdata /* transform table data */
|
|
+{
|
|
+ struct in_addr i4_src;
|
|
+ struct in_addr i4_dst;
|
|
+};
|
|
+
|
|
+#define EMT_IPE4_ULEN 8 /* coming from user mode */
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_ipe4.h,v $
|
|
+ * Revision 1.6 2004/04/05 19:55:05 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_ipe4.h,v
|
|
+ *
|
|
+ * Revision 1.5 2002/04/24 07:36:46 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v
|
|
+ *
|
|
+ * Revision 1.4 2001/06/14 19:35:08 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.3 1999/04/11 00:28:57 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.2 1999/04/06 04:54:25 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:47 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:07 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * No changes.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:48:53 ji
|
|
+ * Release update only.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_ipip.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,45 @@
|
|
+/*
|
|
+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_ipip.h,v 1.2 2004/04/05 19:55:05 mcr Exp $
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_IPIP_H_
|
|
+
|
|
+#ifndef IPPROTO_IPIP
|
|
+#define IPPROTO_IPIP 4
|
|
+#endif /* IPPROTO_ESP */
|
|
+
|
|
+extern struct xform_functions ipip_xform_funcs[];
|
|
+
|
|
+#define _IPSEC_IPIP_H_
|
|
+
|
|
+#endif /* _IPSEC_IPIP_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_ipip.h,v $
|
|
+ * Revision 1.2 2004/04/05 19:55:05 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_ipip.h,v
|
|
+ *
|
|
+ * Revision 1.1 2003/12/13 19:10:16 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.1 2003/12/11 20:14:58 mcr
|
|
+ * refactored the xmit code, to move all encapsulation
|
|
+ * code into protocol functions. Note that all functions
|
|
+ * are essentially done by a single function, which is probably
|
|
+ * wrong.
|
|
+ * the rcv_functions structures are renamed xform_functions.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_kern24.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,61 @@
|
|
+/*
|
|
+ * @(#) routines to makes kernel 2.4 compatible with 2.6 usage.
|
|
+ *
|
|
+ * Copyright (C) 2004 Michael Richardson <mcr@sandelman.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_kern24.h,v 1.4 2005/05/20 03:19:18 mcr Exp $
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_KERN24_H
|
|
+
|
|
+#ifndef NET_26
|
|
+#define sk_receive_queue receive_queue
|
|
+#define sk_destruct destruct
|
|
+#define sk_reuse reuse
|
|
+#define sk_zapped zapped
|
|
+#define sk_family family
|
|
+#define sk_protocol protocol
|
|
+#define sk_protinfo protinfo
|
|
+#define sk_sleep sleep
|
|
+#define sk_state_change state_change
|
|
+#define sk_shutdown shutdown
|
|
+#define sk_err err
|
|
+#define sk_stamp stamp
|
|
+#define sk_socket socket
|
|
+#define sk_sndbuf sndbuf
|
|
+#define sock_flag(sk, flag) sk->dead
|
|
+#define sk_for_each(sk, node, plist) for(sk=*plist; sk!=NULL; sk = sk->next)
|
|
+#endif
|
|
+
|
|
+/* deal with 2.4 vs 2.6 issues with module counts */
|
|
+
|
|
+/* in 2.6, all refcounts are maintained *outside* of the
|
|
+ * module to deal with race conditions.
|
|
+ */
|
|
+
|
|
+#ifdef NET_26
|
|
+#define KLIPS_INC_USE /* nothing */
|
|
+#define KLIPS_DEC_USE /* nothing */
|
|
+
|
|
+#else
|
|
+#define KLIPS_INC_USE MOD_INC_USE_COUNT
|
|
+#define KLIPS_DEC_USE MOD_DEC_USE_COUNT
|
|
+#endif
|
|
+
|
|
+extern int printk_ratelimit(void);
|
|
+
|
|
+
|
|
+#define _IPSEC_KERN24_H 1
|
|
+
|
|
+#endif /* _IPSEC_KERN24_H */
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_kversion.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,352 @@
|
|
+#ifndef _OPENSWAN_KVERSIONS_H
|
|
+/*
|
|
+ * header file for FreeS/WAN library functions
|
|
+ * Copyright (C) 1998, 1999, 2000 Henry Spencer.
|
|
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_kversion.h,v 1.15.2.11 2007/02/20 03:53:16 paul Exp $
|
|
+ */
|
|
+#define _OPENSWAN_KVERSIONS_H /* seen it, no need to see it again */
|
|
+
|
|
+/*
|
|
+ * this file contains a series of atomic defines that depend upon
|
|
+ * kernel version numbers. The kernel versions are arranged
|
|
+ * in version-order number (which is often not chronological)
|
|
+ * and each clause enables or disables a feature.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * First, assorted kernel-version-dependent trickery.
|
|
+ */
|
|
+#include <linux/version.h>
|
|
+#ifndef KERNEL_VERSION
|
|
+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
|
|
+#define HEADER_CACHE_BIND_21
|
|
+#error "KLIPS is no longer supported on Linux 2.0. Sorry"
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
|
|
+#define SPINLOCK
|
|
+#define PROC_FS_21
|
|
+#define NETLINK_SOCK
|
|
+#define NET_21
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
|
|
+#define net_device_stats enet_statistics
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
|
|
+#define SPINLOCK_23
|
|
+#define NETDEV_23
|
|
+# ifndef CONFIG_IP_ALIAS
|
|
+# define CONFIG_IP_ALIAS
|
|
+# endif
|
|
+#include <linux/socket.h>
|
|
+#include <linux/skbuff.h>
|
|
+#include <linux/netlink.h>
|
|
+# ifdef NETLINK_XFRM
|
|
+# define NETDEV_25
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
|
|
+#define PROC_FS_2325
|
|
+#undef PROC_FS_21
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
|
|
+#define PROC_NO_DUMMY
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
|
|
+#define SKB_COPY_EXPAND
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
|
|
+#define IP_SELECT_IDENT
|
|
+#endif
|
|
+
|
|
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
|
|
+#define SKB_RESET_NFCT
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
|
|
+#define IP_SELECT_IDENT_NEW
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
|
|
+#define IPH_is_SKB_PULLED
|
|
+#define SKB_COW_NEW
|
|
+#define PROTO_HANDLER_SINGLE_PARM
|
|
+#define IP_FRAGMENT_LINEARIZE 1
|
|
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
|
|
+# ifdef REDHAT_BOGOSITY
|
|
+# define IP_SELECT_IDENT_NEW
|
|
+# define IPH_is_SKB_PULLED
|
|
+# define SKB_COW_NEW
|
|
+# define PROTO_HANDLER_SINGLE_PARM
|
|
+# endif /* REDHAT_BOGOSITY */
|
|
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
|
|
+#define MALLOC_SLAB
|
|
+#define LINUX_KERNEL_HAS_SNPRINTF
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
|
+#define HAVE_NETDEV_PRINTK 1
|
|
+#define NET_26
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
|
|
+#define NEED_INET_PROTOCOL
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
|
|
+#define HAVE_SOCK_ZAPPED
|
|
+#define NET_26_12_SKALLOC
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
|
|
+#define HAVE_SOCK_SECURITY
|
|
+/* skb->nf_debug disappared completely in 2.6.13 */
|
|
+#define HAVE_SKB_NF_DEBUG
|
|
+#endif
|
|
+
|
|
+#define SYSCTL_IPSEC_DEFAULT_TTL sysctl_ip_default_ttl
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
|
|
+/* skb->stamp changed to skb->tstamp in 2.6.14 */
|
|
+#define HAVE_TSTAMP
|
|
+#define HAVE_INET_SK_SPORT
|
|
+#undef SYSCTL_IPSEC_DEFAULT_TTL
|
|
+#define SYSCTL_IPSEC_DEFAULT_TTL IPSEC_DEFAULT_TTL
|
|
+#else
|
|
+#define HAVE_SKB_LIST
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
|
|
+#define HAVE_NEW_SKB_LINEARIZE
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
|
|
+/* skb->nfmark changed to skb->mark in 2.6.20 */
|
|
+#define nfmark mark
|
|
+#endif
|
|
+
|
|
+#ifdef NET_21
|
|
+# include <linux/in6.h>
|
|
+#else
|
|
+ /* old kernel in.h has some IPv6 stuff, but not quite enough */
|
|
+# define s6_addr16 s6_addr
|
|
+# define AF_INET6 10
|
|
+# define uint8_t __u8
|
|
+# define uint16_t __u16
|
|
+# define uint32_t __u32
|
|
+# define uint64_t __u64
|
|
+#endif
|
|
+
|
|
+#ifdef NET_21
|
|
+# define ipsec_kfree_skb(a) kfree_skb(a)
|
|
+#else /* NET_21 */
|
|
+# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
|
|
+#endif /* NET_21 */
|
|
+
|
|
+#ifdef NETDEV_23
|
|
+#if 0
|
|
+#ifndef NETDEV_25
|
|
+#define device net_device
|
|
+#endif
|
|
+#endif
|
|
+# define ipsec_dev_get dev_get_by_name
|
|
+# define __ipsec_dev_get __dev_get_by_name
|
|
+# define ipsec_dev_put(x) dev_put(x)
|
|
+# define __ipsec_dev_put(x) __dev_put(x)
|
|
+# define ipsec_dev_hold(x) dev_hold(x)
|
|
+#else /* NETDEV_23 */
|
|
+# define ipsec_dev_get dev_get
|
|
+# define __ipsec_dev_put(x)
|
|
+# define ipsec_dev_put(x)
|
|
+# define ipsec_dev_hold(x)
|
|
+#endif /* NETDEV_23 */
|
|
+
|
|
+#ifndef SPINLOCK
|
|
+# include <linux/bios32.h>
|
|
+ /* simulate spin locks and read/write locks */
|
|
+ typedef struct {
|
|
+ volatile char lock;
|
|
+ } spinlock_t;
|
|
+
|
|
+ typedef struct {
|
|
+ volatile unsigned int lock;
|
|
+ } rwlock_t;
|
|
+
|
|
+# define spin_lock_init(x) { (x)->lock = 0;}
|
|
+# define rw_lock_init(x) { (x)->lock = 0; }
|
|
+
|
|
+# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
|
|
+# define spin_lock_irq(x) { cli(); spin_lock(x);}
|
|
+# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
|
|
+
|
|
+# define spin_unlock(x) { (x)->lock=0;}
|
|
+# define spin_unlock_irq(x) { spin_unlock(x); sti();}
|
|
+# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
|
|
+
|
|
+# define read_lock(x) spin_lock(x)
|
|
+# define read_lock_irq(x) spin_lock_irq(x)
|
|
+# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
|
|
+
|
|
+# define read_unlock(x) spin_unlock(x)
|
|
+# define read_unlock_irq(x) spin_unlock_irq(x)
|
|
+# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
|
|
+
|
|
+# define write_lock(x) spin_lock(x)
|
|
+# define write_lock_irq(x) spin_lock_irq(x)
|
|
+# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
|
|
+
|
|
+# define write_unlock(x) spin_unlock(x)
|
|
+# define write_unlock_irq(x) spin_unlock_irq(x)
|
|
+# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
|
|
+#endif /* !SPINLOCK */
|
|
+
|
|
+#ifndef SPINLOCK_23
|
|
+# define spin_lock_bh(x) spin_lock_irq(x)
|
|
+# define spin_unlock_bh(x) spin_unlock_irq(x)
|
|
+
|
|
+# define read_lock_bh(x) read_lock_irq(x)
|
|
+# define read_unlock_bh(x) read_unlock_irq(x)
|
|
+
|
|
+# define write_lock_bh(x) write_lock_irq(x)
|
|
+# define write_unlock_bh(x) write_unlock_irq(x)
|
|
+#endif /* !SPINLOCK_23 */
|
|
+
|
|
+#ifndef HAVE_NETDEV_PRINTK
|
|
+#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
|
|
+ printk(sevlevel "%s: " format , netdev->name , ## arg)
|
|
+#endif
|
|
+
|
|
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0)
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
|
|
+#include "openswan/ipsec_kern24.h"
|
|
+#else
|
|
+#error "kernels before 2.4 are not supported at this time"
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+
|
|
+#endif /* _OPENSWAN_KVERSIONS_H */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_kversion.h,v $
|
|
+ * Revision 1.15.2.11 2007/02/20 03:53:16 paul
|
|
+ * Added comment, made layout consistent with other checks.
|
|
+ *
|
|
+ * Revision 1.15.2.10 2007/02/16 19:08:12 paul
|
|
+ * Fix for compiling on 2.6.20 (nfmark is now called mark in sk_buff)
|
|
+ *
|
|
+ * Revision 1.15.2.9 2006/07/29 05:00:40 paul
|
|
+ * Added HAVE_NEW_SKB_LINEARIZE for 2.6.18+ kernels where skb_linearize
|
|
+ * only takes 1 argument.
|
|
+ *
|
|
+ * Revision 1.15.2.8 2006/05/01 14:31:52 mcr
|
|
+ * FREESWAN->OPENSWAN in #ifdef.
|
|
+ *
|
|
+ * Revision 1.15.2.7 2006/01/11 02:02:59 mcr
|
|
+ * updated patches and DEFAULT_TTL code to work
|
|
+ *
|
|
+ * Revision 1.15.2.6 2006/01/03 19:25:02 ken
|
|
+ * Remove duplicated #ifdef for TTL fix - bad patch
|
|
+ *
|
|
+ * Revision 1.15.2.5 2006/01/03 18:06:33 ken
|
|
+ * Fix for missing sysctl default ttl
|
|
+ *
|
|
+ * Revision 1.15.2.4 2005/11/27 21:40:14 paul
|
|
+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
|
|
+ * in for klips as module.
|
|
+ *
|
|
+ * Revision 1.15.2.3 2005/11/22 04:11:52 ken
|
|
+ * Backport fixes for 2.6.14 kernels from HEAD
|
|
+ *
|
|
+ * Revision 1.15.2.2 2005/09/01 01:57:19 paul
|
|
+ * michael's fixes for 2.6.13 from head
|
|
+ *
|
|
+ * Revision 1.15.2.1 2005/08/27 23:13:48 paul
|
|
+ * Fix for:
|
|
+ * 7 weeks ago: [NET]: Remove unused security member in sk_buff
|
|
+ * changeset 4280: 328ea53f5fee
|
|
+ * parent 4279: beb0afb0e3f8
|
|
+ * author: Thomas Graf <tgraf@suug.ch>
|
|
+ * date: Tue Jul 5 21:12:44 2005
|
|
+ * 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
|
|
+ *
|
|
+ * This should fix compilation on 2.6.13(rc) kernels
|
|
+ *
|
|
+ * Revision 1.15 2005/07/19 20:02:15 mcr
|
|
+ * sk_alloc() interface change.
|
|
+ *
|
|
+ * Revision 1.14 2005/07/08 16:20:05 mcr
|
|
+ * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
|
|
+ *
|
|
+ * Revision 1.13 2005/05/20 03:19:18 mcr
|
|
+ * modifications for use on 2.4.30 kernel, with backported
|
|
+ * printk_ratelimit(). all warnings removed.
|
|
+ *
|
|
+ * Revision 1.12 2005/04/13 22:46:21 mcr
|
|
+ * note that KLIPS does not work on Linux 2.0.
|
|
+ *
|
|
+ * Revision 1.11 2004/09/13 02:22:26 mcr
|
|
+ * #define inet_protocol if necessary.
|
|
+ *
|
|
+ * Revision 1.10 2004/08/03 18:17:15 mcr
|
|
+ * in 2.6, use "net_device" instead of #define device->net_device.
|
|
+ * this probably breaks 2.0 compiles.
|
|
+ *
|
|
+ * Revision 1.9 2004/04/05 19:55:05 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_kversion.h,v
|
|
+ *
|
|
+ * Revision 1.8 2003/12/13 19:10:16 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.7 2003/07/31 22:48:08 mcr
|
|
+ * derive NET25-ness from presence of NETLINK_XFRM macro.
|
|
+ *
|
|
+ * Revision 1.6 2003/06/24 20:22:32 mcr
|
|
+ * added new global: ipsecdevices[] so that we can keep track of
|
|
+ * the ipsecX devices. They will be referenced with dev_hold(),
|
|
+ * so 2.2 may need this as well.
|
|
+ *
|
|
+ * Revision 1.5 2003/04/03 17:38:09 rgb
|
|
+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
|
|
+ *
|
|
+ * Revision 1.4 2002/04/24 07:36:46 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
|
|
+ *
|
|
+ * Revision 1.3 2002/04/12 03:21:17 mcr
|
|
+ * three parameter version of ip_select_ident appears first
|
|
+ * in 2.4.2 (RH7.1) not 2.4.4.
|
|
+ *
|
|
+ * Revision 1.2 2002/03/08 21:35:22 rgb
|
|
+ * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
|
|
+ * 2.4.9. (Andreas Piesk).
|
|
+ *
|
|
+ * Revision 1.1 2002/01/29 02:11:42 mcr
|
|
+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
|
|
+ * updating of IPv6 structures to match latest in6.h version.
|
|
+ * removed dead code from freeswan.h that also duplicated kversions.h
|
|
+ * code.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,112 @@
|
|
+/*
|
|
+ * Definitions relevant to IPSEC lifetimes
|
|
+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * and Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_life.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
|
|
+ *
|
|
+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
|
|
+ *
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * This file describes the book keeping fields for the
|
|
+ * IPsec Security Association Structure. ("ipsec_sa")
|
|
+ *
|
|
+ * This structure is never allocated directly by kernel code,
|
|
+ * (it is always a static/auto or is part of a structure)
|
|
+ * so it does not have a reference count.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_LIFE_H_
|
|
+
|
|
+/*
|
|
+ * _count is total count.
|
|
+ * _hard is hard limit (kill SA after this number)
|
|
+ * _soft is soft limit (try to renew SA after this number)
|
|
+ * _last is used in some special cases.
|
|
+ *
|
|
+ */
|
|
+
|
|
+struct ipsec_lifetime64
|
|
+{
|
|
+ __u64 ipl_count;
|
|
+ __u64 ipl_soft;
|
|
+ __u64 ipl_hard;
|
|
+ __u64 ipl_last;
|
|
+};
|
|
+
|
|
+struct ipsec_lifetimes
|
|
+{
|
|
+ /* number of bytes processed */
|
|
+ struct ipsec_lifetime64 ipl_bytes;
|
|
+
|
|
+ /* number of packets processed */
|
|
+ struct ipsec_lifetime64 ipl_packets;
|
|
+
|
|
+ /* time since SA was added */
|
|
+ struct ipsec_lifetime64 ipl_addtime;
|
|
+
|
|
+ /* time since SA was first used */
|
|
+ struct ipsec_lifetime64 ipl_usetime;
|
|
+
|
|
+ /* from rfc2367:
|
|
+ * For CURRENT, the number of different connections,
|
|
+ * endpoints, or flows that the association has been
|
|
+ * allocated towards. For HARD and SOFT, the number of
|
|
+ * these the association may be allocated towards
|
|
+ * before it expires. The concept of a connection,
|
|
+ * flow, or endpoint is system specific.
|
|
+ *
|
|
+ * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
|
|
+ * They are maintained for PF_KEY compatibility.
|
|
+ */
|
|
+ struct ipsec_lifetime64 ipl_allocations;
|
|
+};
|
|
+
|
|
+enum ipsec_life_alive {
|
|
+ ipsec_life_harddied = -1,
|
|
+ ipsec_life_softdied = 0,
|
|
+ ipsec_life_okay = 1
|
|
+};
|
|
+
|
|
+enum ipsec_life_type {
|
|
+ ipsec_life_timebased = 1,
|
|
+ ipsec_life_countbased= 0
|
|
+};
|
|
+
|
|
+#define _IPSEC_LIFE_H_
|
|
+#endif /* _IPSEC_LIFE_H_ */
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_life.h,v $
|
|
+ * Revision 1.4 2004/04/05 19:55:05 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_life.h,v
|
|
+ *
|
|
+ * Revision 1.3 2002/04/24 07:36:46 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_life.h,v
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:14 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:25:58 mcr
|
|
+ * lifetime structure created and common functions created.
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,143 @@
|
|
+/*
|
|
+ * RCSID $Id: ipsec_md5h.h,v 1.10 2004/09/08 17:21:35 ken Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * The rest of this file is Copyright RSA DSI. See the following comments
|
|
+ * for the full Copyright notice.
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_MD5H_H_
|
|
+#define _IPSEC_MD5H_H_
|
|
+
|
|
+/* GLOBAL.H - RSAREF types and constants
|
|
+ */
|
|
+
|
|
+/* PROTOTYPES should be set to one if and only if the compiler supports
|
|
+ function argument prototyping.
|
|
+ The following makes PROTOTYPES default to 0 if it has not already
|
|
+ been defined with C compiler flags.
|
|
+ */
|
|
+#ifndef PROTOTYPES
|
|
+#define PROTOTYPES 1
|
|
+#endif /* !PROTOTYPES */
|
|
+
|
|
+/* POINTER defines a generic pointer type */
|
|
+typedef __u8 *POINTER;
|
|
+
|
|
+/* UINT2 defines a two byte word */
|
|
+typedef __u16 UINT2;
|
|
+
|
|
+/* UINT4 defines a four byte word */
|
|
+typedef __u32 UINT4;
|
|
+
|
|
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
|
|
+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
|
|
+ returns an empty list.
|
|
+ */
|
|
+
|
|
+#if PROTOTYPES
|
|
+#define PROTO_LIST(list) list
|
|
+#else /* PROTOTYPES */
|
|
+#define PROTO_LIST(list) ()
|
|
+#endif /* PROTOTYPES */
|
|
+
|
|
+
|
|
+/* MD5.H - header file for MD5C.C
|
|
+ */
|
|
+
|
|
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
|
+rights reserved.
|
|
+
|
|
+License to copy and use this software is granted provided that it
|
|
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
|
+Algorithm" in all material mentioning or referencing this software
|
|
+or this function.
|
|
+
|
|
+License is also granted to make and use derivative works provided
|
|
+that such works are identified as "derived from the RSA Data
|
|
+Security, Inc. MD5 Message-Digest Algorithm" in all material
|
|
+mentioning or referencing the derived work.
|
|
+
|
|
+RSA Data Security, Inc. makes no representations concerning either
|
|
+the merchantability of this software or the suitability of this
|
|
+software for any particular purpose. It is provided "as is"
|
|
+without express or implied warranty of any kind.
|
|
+
|
|
+These notices must be retained in any copies of any part of this
|
|
+documentation and/or software.
|
|
+ */
|
|
+
|
|
+/* MD5 context. */
|
|
+typedef struct {
|
|
+ UINT4 state[4]; /* state (ABCD) */
|
|
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
|
+ unsigned char buffer[64]; /* input buffer */
|
|
+} MD5_CTX;
|
|
+
|
|
+void osMD5Init PROTO_LIST ((void *));
|
|
+void osMD5Update PROTO_LIST
|
|
+ ((void *, unsigned char *, __u32));
|
|
+void osMD5Final PROTO_LIST ((unsigned char [16], void *));
|
|
+
|
|
+#endif /* _IPSEC_MD5H_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_md5h.h,v $
|
|
+ * Revision 1.10 2004/09/08 17:21:35 ken
|
|
+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
|
|
+ *
|
|
+ * Revision 1.9 2004/04/05 19:55:05 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_md5h.h,v
|
|
+ *
|
|
+ * Revision 1.8 2002/09/10 01:45:09 mcr
|
|
+ * changed type of MD5_CTX and SHA1_CTX to void * so that
|
|
+ * the function prototypes would match, and could be placed
|
|
+ * into a pointer to a function.
|
|
+ *
|
|
+ * Revision 1.7 2002/04/24 07:36:46 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
|
|
+ *
|
|
+ * Revision 1.6 1999/12/13 13:59:13 rgb
|
|
+ * Quick fix to argument size to Update bugs.
|
|
+ *
|
|
+ * Revision 1.5 1999/12/07 18:16:23 rgb
|
|
+ * Fixed comments at end of #endif lines.
|
|
+ *
|
|
+ * Revision 1.4 1999/04/06 04:54:26 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.3 1999/01/22 06:19:58 rgb
|
|
+ * 64-bit clean-up.
|
|
+ *
|
|
+ * Revision 1.2 1998/11/30 13:22:54 rgb
|
|
+ * Rationalised all the klips kernel file headers. They are much shorter
|
|
+ * now and won't conflict under RH5.2.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:48 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.2 1998/04/23 20:54:03 rgb
|
|
+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
|
|
+ * verified.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:04:21 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ * these two include files modified not to include others except in kernel
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * No changes.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:48:53 ji
|
|
+ * Release update only.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,387 @@
|
|
+/*
|
|
+ * @(#) Openswan tunable paramaters
|
|
+ *
|
|
+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * and Michael Richardson <mcr@freeswan.org>
|
|
+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_param.h,v 1.29.6.3 2006/05/01 14:32:31 mcr Exp $
|
|
+ *
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * This file provides a set of #define's which may be tuned by various
|
|
+ * people/configurations. It keeps all compile-time tunables in one place.
|
|
+ *
|
|
+ * This file should be included before all other IPsec kernel-only files.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_PARAM_H_
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+#include "ipsec_kversion.h"
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+/* Set number of ipsecX virtual devices here. */
|
|
+/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
|
|
+/* It must also be reasonable so as not to overload the memory and CPU */
|
|
+/* constraints of the host. */
|
|
+#define IPSEC_NUM_IF 4
|
|
+/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
|
|
+/* With "ipsec" being 5 characters, that means 10 is the max field width */
|
|
+/* but machine memory and CPU constraints are not likely to tollerate */
|
|
+/* more than 3 digits. The default is one digit. */
|
|
+/* Update: userland scripts get upset if they can't find "ipsec0", so */
|
|
+/* for now, no "0"-padding should be used (which would have been helpful */
|
|
+/* to make text-searches work */
|
|
+#define IPSEC_DEV_FORMAT "ipsec%d"
|
|
+/* For, say, 500 virtual ipsec devices, I would recommend: */
|
|
+/* #define IPSEC_NUM_IF 500 */
|
|
+/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
|
|
+/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
|
|
+
|
|
+/* use dynamic ipsecX device allocation */
|
|
+#ifndef CONFIG_KLIPS_DYNDEV
|
|
+#define CONFIG_KLIPS_DYNDEV 1
|
|
+#endif /* CONFIG_KLIPS_DYNDEV */
|
|
+
|
|
+
|
|
+#ifdef CONFIG_KLIPS_BIGGATE
|
|
+# define SADB_HASHMOD 8069
|
|
+#else /* CONFIG_KLIPS_BIGGATE */
|
|
+# define SADB_HASHMOD 257
|
|
+#endif /* CONFIG_KLIPS_BIGGATE */
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+/*
|
|
+ * This is for the SA reference table. This number is related to the
|
|
+ * maximum number of SAs that KLIPS can concurrently deal with, plus enough
|
|
+ * space for keeping expired SAs around.
|
|
+ *
|
|
+ * TABLE_MAX_WIDTH is the number of bits that we will use.
|
|
+ * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
|
|
+ *
|
|
+ */
|
|
+#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
|
|
+# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
|
|
+#endif
|
|
+
|
|
+#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
|
|
+# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
|
|
+#endif
|
|
+
|
|
+#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
|
|
+# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
|
|
+#endif
|
|
+
|
|
+#ifndef IPSEC_SA_REF_CODE
|
|
+# define IPSEC_SA_REF_CODE 1
|
|
+#endif
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+/* This is defined for 2.4, but not 2.2.... */
|
|
+#ifndef ARPHRD_VOID
|
|
+# define ARPHRD_VOID 0xFFFF
|
|
+#endif
|
|
+
|
|
+/* always turn on IPIP mode */
|
|
+#ifndef CONFIG_KLIPS_IPIP
|
|
+#define CONFIG_KLIPS_IPIP 1
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * Worry about PROC_FS stuff
|
|
+ */
|
|
+#if defined(PROC_FS_2325)
|
|
+/* kernel 2.4 */
|
|
+# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
|
|
+# define IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+# define IPSEC_PROC_SUBDIRS
|
|
+#else
|
|
+/* kernel <2.4 */
|
|
+# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
|
|
+
|
|
+# ifndef PROC_NO_DUMMY
|
|
+# define IPSEC_PROC_LAST_ARG , int dummy
|
|
+# else
|
|
+# define IPSEC_PROC_LAST_ARG
|
|
+# endif /* !PROC_NO_DUMMY */
|
|
+#endif /* PROC_FS_2325 */
|
|
+
|
|
+#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
|
|
+/* GNU CPP specific! */
|
|
+# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
|
|
+#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
|
|
+
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#ifndef KLIPS_FIXES_DES_PARITY
|
|
+# define KLIPS_FIXES_DES_PARITY 1
|
|
+#endif /* !KLIPS_FIXES_DES_PARITY */
|
|
+
|
|
+/* we don't really want to print these unless there are really big problems */
|
|
+#ifndef KLIPS_DIVULGE_CYPHER_KEY
|
|
+# define KLIPS_DIVULGE_CYPHER_KEY 0
|
|
+#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
|
|
+
|
|
+#ifndef KLIPS_DIVULGE_HMAC_KEY
|
|
+# define KLIPS_DIVULGE_HMAC_KEY 0
|
|
+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
|
|
+
|
|
+#ifndef IPSEC_DISALLOW_IPOPTIONS
|
|
+# define IPSEC_DISALLOW_IPOPTIONS 1
|
|
+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
|
|
+
|
|
+/* extra toggles for regression testing */
|
|
+#ifdef CONFIG_KLIPS_REGRESS
|
|
+
|
|
+/*
|
|
+ * should pfkey_acquire() become 100% lossy?
|
|
+ *
|
|
+ */
|
|
+extern int sysctl_ipsec_regress_pfkey_lossage;
|
|
+#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
|
|
+# ifdef CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE
|
|
+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
|
|
+# endif /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
|
|
+#else
|
|
+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
|
|
+#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
|
|
+
|
|
+#else /* CONFIG_KLIPS_REGRESS */
|
|
+#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
|
|
+
|
|
+#endif /* CONFIG_KLIPS_REGRESS */
|
|
+
|
|
+
|
|
+/*
|
|
+ * debugging routines.
|
|
+ */
|
|
+#define KLIPS_ERROR(flag, format, args...) if(printk_ratelimit() || flag) printk(KERN_ERR "KLIPS " format, ## args)
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern void ipsec_print_ip(struct iphdr *ip);
|
|
+
|
|
+# define KLIPS_PRINT(flag, format, args...) \
|
|
+ ((flag) ? printk(KERN_INFO format , ## args) : 0)
|
|
+# define KLIPS_PRINTMORE(flag, format, args...) \
|
|
+ ((flag) ? printk(format , ## args) : 0)
|
|
+# define KLIPS_IP_PRINT(flag, ip) \
|
|
+ ((flag) ? ipsec_print_ip(ip) : 0)
|
|
+#else /* CONFIG_KLIPS_DEBUG */
|
|
+# define KLIPS_PRINT(flag, format, args...) do ; while(0)
|
|
+# define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
|
|
+# define KLIPS_IP_PRINT(flag, ip) do ; while(0)
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+
|
|
+/*
|
|
+ * Stupid kernel API differences in APIs. Not only do some
|
|
+ * kernels not have ip_select_ident, but some have differing APIs,
|
|
+ * and SuSE has one with one parameter, but no way of checking to
|
|
+ * see what is really what.
|
|
+ */
|
|
+
|
|
+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
|
|
+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
|
|
+#else
|
|
+
|
|
+/* simplest case, nothing */
|
|
+#if !defined(IP_SELECT_IDENT)
|
|
+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
|
|
+#endif
|
|
+
|
|
+/* kernels > 2.3.37-ish */
|
|
+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
|
|
+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
|
|
+#endif
|
|
+
|
|
+/* kernels > 2.4.2 */
|
|
+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
|
|
+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
|
|
+#endif
|
|
+
|
|
+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
|
|
+
|
|
+/*
|
|
+ * make klips fail test:east-espiv-01.
|
|
+ * exploit is at testing/attacks/espiv
|
|
+ *
|
|
+ */
|
|
+#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
|
|
+
|
|
+
|
|
+/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
|
|
+#ifndef IP_FRAGMENT_LINEARIZE
|
|
+# define IP_FRAGMENT_LINEARIZE 0
|
|
+#endif /* IP_FRAGMENT_LINEARIZE */
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+#ifdef NEED_INET_PROTOCOL
|
|
+#define inet_protocol net_protocol
|
|
+#endif
|
|
+
|
|
+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+#define NAT_TRAVERSAL 1
|
|
+#else
|
|
+/* let people either #undef, or #define = 0 it */
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+#undef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#ifndef IPSEC_DEFAULT_TTL
|
|
+#define IPSEC_DEFAULT_TTL 64
|
|
+#endif
|
|
+
|
|
+#define _IPSEC_PARAM_H_
|
|
+#endif /* _IPSEC_PARAM_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_param.h,v $
|
|
+ * Revision 1.29.6.3 2006/05/01 14:32:31 mcr
|
|
+ * added KLIPS_ERROR and make sure that things work without CONFIG_KLIPS_REGRESS.
|
|
+ *
|
|
+ * Revision 1.29.6.2 2005/11/27 21:40:14 paul
|
|
+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
|
|
+ * in for klips as module.
|
|
+ *
|
|
+ * Revision 1.29.6.1 2005/08/12 16:24:18 ken
|
|
+ * Pull in NAT-T compile logic from HEAD
|
|
+ *
|
|
+ * Revision 1.29 2005/01/26 00:50:35 mcr
|
|
+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
|
|
+ * and make sure that NAT_TRAVERSAL is set as well to match
|
|
+ * userspace compiles of code.
|
|
+ *
|
|
+ * Revision 1.28 2004/09/13 15:50:15 mcr
|
|
+ * spell NEED_INET properly, not NET_INET.
|
|
+ *
|
|
+ * Revision 1.27 2004/09/13 02:21:45 mcr
|
|
+ * always turn on IPIP mode.
|
|
+ * #define inet_protocol if necessary.
|
|
+ *
|
|
+ * Revision 1.26 2004/08/17 03:25:43 mcr
|
|
+ * freeswan->openswan.
|
|
+ *
|
|
+ * Revision 1.25 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.24 2004/04/05 19:55:06 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_param.h,v
|
|
+ *
|
|
+ * Revision 1.23 2003/12/13 19:10:16 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.22 2003/10/31 02:27:05 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.21.4.1 2003/10/29 01:10:19 mcr
|
|
+ * elimited "struct sa_id"
|
|
+ *
|
|
+ * Revision 1.21 2003/04/03 17:38:18 rgb
|
|
+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
|
|
+ * Change indentation for readability.
|
|
+ *
|
|
+ * Revision 1.20 2003/03/14 08:09:26 rgb
|
|
+ * Fixed up CONFIG_IPSEC_DYNDEV definitions.
|
|
+ *
|
|
+ * Revision 1.19 2003/01/30 02:31:43 rgb
|
|
+ *
|
|
+ * Rename SAref table macro names for clarity.
|
|
+ *
|
|
+ * Revision 1.18 2002/09/30 19:06:26 rgb
|
|
+ * Reduce default table to 16 bits width.
|
|
+ *
|
|
+ * Revision 1.17 2002/09/20 15:40:29 rgb
|
|
+ * Define switch to activate new SAref code.
|
|
+ * Prefix macros with "IPSEC_".
|
|
+ * Rework saref freelist.
|
|
+ * Restrict some bits to kernel context for use to klips utils.
|
|
+ *
|
|
+ * Revision 1.16 2002/09/20 05:00:31 rgb
|
|
+ * Define switch to divulge hmac keys for debugging.
|
|
+ * Added IPOPTIONS switch.
|
|
+ *
|
|
+ * Revision 1.15 2002/09/19 02:34:24 mcr
|
|
+ * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
|
|
+ * to decide if we are to create /proc/net/ipsec/.
|
|
+ *
|
|
+ * Revision 1.14 2002/08/30 01:20:54 mcr
|
|
+ * reorganized 2.0/2.2/2.4 procfs support macro so match
|
|
+ * 2.4 values/typedefs.
|
|
+ *
|
|
+ * Revision 1.13 2002/07/28 22:03:28 mcr
|
|
+ * added some documentation to SA_REF_*
|
|
+ * turned on fix for ESPIV attack, now that we have the attack code.
|
|
+ *
|
|
+ * Revision 1.12 2002/07/26 08:48:31 rgb
|
|
+ * Added SA ref table code.
|
|
+ *
|
|
+ * Revision 1.11 2002/07/23 02:57:45 rgb
|
|
+ * Define ARPHRD_VOID for < 2.4 kernels.
|
|
+ *
|
|
+ * Revision 1.10 2002/05/27 21:37:28 rgb
|
|
+ * Set the defaults sanely for those adventurous enough to try more than 1
|
|
+ * digit of ipsec devices.
|
|
+ *
|
|
+ * Revision 1.9 2002/05/27 18:56:07 rgb
|
|
+ * Convert to dynamic ipsec device allocation.
|
|
+ *
|
|
+ * Revision 1.8 2002/04/24 07:36:47 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_param.h,v
|
|
+ *
|
|
+ * Revision 1.7 2002/04/20 00:12:25 rgb
|
|
+ * Added esp IV CBC attack fix, disabled.
|
|
+ *
|
|
+ * Revision 1.6 2002/01/29 02:11:42 mcr
|
|
+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
|
|
+ * updating of IPv6 structures to match latest in6.h version.
|
|
+ * removed dead code from freeswan.h that also duplicated kversions.h
|
|
+ * code.
|
|
+ *
|
|
+ * Revision 1.5 2002/01/28 19:22:01 mcr
|
|
+ * by default, turn off LINEARIZE option
|
|
+ * (let kversions.h turn it on)
|
|
+ *
|
|
+ * Revision 1.4 2002/01/20 20:19:36 mcr
|
|
+ * renamed option to IP_FRAGMENT_LINEARIZE.
|
|
+ *
|
|
+ * Revision 1.3 2002/01/12 02:57:25 mcr
|
|
+ * first regression test causes acquire messages to be lost
|
|
+ * 100% of the time. This is to help testing of pluto.
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:14 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.1.2.3 2001/10/23 04:40:16 mcr
|
|
+ * added #define for DIVULGING session keys in debug output.
|
|
+ *
|
|
+ * Revision 1.1.2.2 2001/10/22 20:53:25 mcr
|
|
+ * added a define to control forcing of DES parity.
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:20:19 mcr
|
|
+ * many common kernel configuration questions centralized.
|
|
+ * more things remain that should be moved from freeswan.h.
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,217 @@
|
|
+#ifndef _IPSEC_POLICY_H
|
|
+/*
|
|
+ * policy interface file between pluto and applications
|
|
+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_policy.h,v 1.7.6.1 2005/07/26 01:53:07 ken Exp $
|
|
+ */
|
|
+#define _IPSEC_POLICY_H /* seen it, no need to see it again */
|
|
+
|
|
+
|
|
+/*
|
|
+ * this file defines an interface between an application (or rather an
|
|
+ * application library) and a key/policy daemon. It provides for inquiries
|
|
+ * as to the current state of a connected socket, as well as for general
|
|
+ * questions.
|
|
+ *
|
|
+ * In general, the interface is defined as a series of functional interfaces,
|
|
+ * and the policy messages should be internal. However, because this is in
|
|
+ * fact an ABI between pieces of the system that may get compiled and revised
|
|
+ * seperately, this ABI must be public and revision controlled.
|
|
+ *
|
|
+ * It is expected that the daemon will always support previous versions.
|
|
+ */
|
|
+
|
|
+#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
|
|
+
|
|
+enum ipsec_policy_command {
|
|
+ IPSEC_CMD_QUERY_FD = 1,
|
|
+ IPSEC_CMD_QUERY_HOSTPAIR = 2,
|
|
+ IPSEC_CMD_QUERY_DSTONLY = 3,
|
|
+};
|
|
+
|
|
+struct ipsec_policy_msg_head {
|
|
+ u_int32_t ipm_version;
|
|
+ u_int32_t ipm_msg_len;
|
|
+ u_int32_t ipm_msg_type;
|
|
+ u_int32_t ipm_msg_seq;
|
|
+};
|
|
+
|
|
+enum ipsec_privacy_quality {
|
|
+ IPSEC_PRIVACY_NONE = 0,
|
|
+ IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
|
|
+ IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
|
|
+ IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
|
|
+ IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
|
|
+ IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
|
|
+ IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
|
|
+ IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
|
|
+ IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
|
|
+};
|
|
+
|
|
+enum ipsec_bandwidth_quality {
|
|
+ IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
|
|
+ IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
|
|
+ Good enough for telnet/ssh. */
|
|
+ IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
|
|
+ IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
|
|
+ offloaded, but latency/jitter may be bad */
|
|
+ IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
|
|
+};
|
|
+
|
|
+/* moved from programs/pluto/constants.h */
|
|
+/* IPsec AH transform values
|
|
+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
|
|
+ * and in http://www.iana.org/assignments/isakmp-registry
|
|
+ */
|
|
+enum ipsec_authentication_algo {
|
|
+ AH_MD5=2,
|
|
+ AH_SHA=3,
|
|
+ AH_DES=4,
|
|
+ AH_SHA2_256=5,
|
|
+ AH_SHA2_384=6,
|
|
+ AH_SHA2_512=7
|
|
+};
|
|
+
|
|
+/* IPsec ESP transform values
|
|
+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
|
|
+ * and from http://www.iana.org/assignments/isakmp-registry
|
|
+ */
|
|
+
|
|
+enum ipsec_cipher_algo {
|
|
+ ESP_reserved=0,
|
|
+ ESP_DES_IV64=1,
|
|
+ ESP_DES=2,
|
|
+ ESP_3DES=3,
|
|
+ ESP_RC5=4,
|
|
+ ESP_IDEA=5,
|
|
+ ESP_CAST=6,
|
|
+ ESP_BLOWFISH=7,
|
|
+ ESP_3IDEA=8,
|
|
+ ESP_DES_IV32=9,
|
|
+ ESP_RC4=10,
|
|
+ ESP_NULL=11,
|
|
+ ESP_AES=12, /* 128 bit AES */
|
|
+};
|
|
+
|
|
+/* IPCOMP transform values
|
|
+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
|
|
+ */
|
|
+
|
|
+enum ipsec_comp_algo {
|
|
+ IPCOMP_OUI= 1,
|
|
+ IPCOMP_DEFLATE= 2,
|
|
+ IPCOMP_LZS= 3,
|
|
+ IPCOMP_V42BIS= 4
|
|
+};
|
|
+
|
|
+/* Identification type values
|
|
+ * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
|
|
+ */
|
|
+
|
|
+enum ipsec_id_type {
|
|
+ ID_IMPOSSIBLE= (-2), /* private to Pluto */
|
|
+ ID_MYID= (-1), /* private to Pluto */
|
|
+ ID_NONE= 0, /* private to Pluto */
|
|
+ ID_IPV4_ADDR= 1,
|
|
+ ID_FQDN= 2,
|
|
+ ID_USER_FQDN= 3,
|
|
+ ID_IPV4_ADDR_SUBNET= 4,
|
|
+ ID_IPV6_ADDR= 5,
|
|
+ ID_IPV6_ADDR_SUBNET= 6,
|
|
+ ID_IPV4_ADDR_RANGE= 7,
|
|
+ ID_IPV6_ADDR_RANGE= 8,
|
|
+ ID_DER_ASN1_DN= 9,
|
|
+ ID_DER_ASN1_GN= 10,
|
|
+ ID_KEY_ID= 11
|
|
+};
|
|
+
|
|
+/* Certificate type values
|
|
+ * RFC 2408 ISAKMP, chapter 3.9
|
|
+ */
|
|
+enum ipsec_cert_type {
|
|
+ CERT_NONE= 0, /* none, or guess from file contents */
|
|
+ CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */
|
|
+ CERT_PGP= 2,
|
|
+ CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */
|
|
+ CERT_X509_SIGNATURE= 4,
|
|
+ CERT_X509_KEY_EXCHANGE= 5,
|
|
+ CERT_KERBEROS_TOKENS= 6,
|
|
+ CERT_CRL= 7,
|
|
+ CERT_ARL= 8,
|
|
+ CERT_SPKI= 9,
|
|
+ CERT_X509_ATTRIBUTE= 10,
|
|
+ CERT_RAW_RSA= 11, /* raw RSA from config file */
|
|
+};
|
|
+
|
|
+/* a SIG record in ASCII */
|
|
+struct ipsec_dns_sig {
|
|
+ char fqdn[256];
|
|
+ char dns_sig[768]; /* empty string if not signed */
|
|
+};
|
|
+
|
|
+struct ipsec_raw_key {
|
|
+ char id_name[256];
|
|
+ char fs_keyid[8];
|
|
+};
|
|
+
|
|
+struct ipsec_identity {
|
|
+ enum ipsec_id_type ii_type;
|
|
+ enum ipsec_cert_type ii_format;
|
|
+ union {
|
|
+ struct ipsec_dns_sig ipsec_dns_signed;
|
|
+ /* some thing for PGP */
|
|
+ /* some thing for PKIX */
|
|
+ struct ipsec_raw_key ipsec_raw_key;
|
|
+ } ii_credential;
|
|
+};
|
|
+
|
|
+#define IPSEC_MAX_CREDENTIALS 32
|
|
+
|
|
+struct ipsec_policy_cmd_query {
|
|
+ struct ipsec_policy_msg_head head;
|
|
+
|
|
+ /* Query section */
|
|
+ ip_address query_local; /* us */
|
|
+ ip_address query_remote; /* them */
|
|
+ u_int8_t proto; /* TCP, ICMP, etc. */
|
|
+ u_short src_port, dst_port;
|
|
+
|
|
+ /* Answer section */
|
|
+ enum ipsec_privacy_quality strength;
|
|
+ enum ipsec_bandwidth_quality bandwidth;
|
|
+ enum ipsec_authentication_algo auth_detail;
|
|
+ enum ipsec_cipher_algo esp_detail;
|
|
+ enum ipsec_comp_algo comp_detail;
|
|
+
|
|
+ int credential_count;
|
|
+
|
|
+ struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
|
|
+};
|
|
+
|
|
+#define IPSEC_POLICY_SOCKET "/var/run/pluto/pluto.info"
|
|
+
|
|
+/* prototypes */
|
|
+extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
|
|
+extern err_t ipsec_policy_init(void);
|
|
+extern err_t ipsec_policy_final(void);
|
|
+extern err_t ipsec_policy_readmsg(int policysock,
|
|
+ unsigned char *buf, size_t buflen);
|
|
+extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
|
|
+extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
|
|
+
|
|
+
|
|
+extern const char *ipsec_policy_version_code(void);
|
|
+extern const char *ipsec_policy_version_string(void);
|
|
+
|
|
+#endif /* _IPSEC_POLICY_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,199 @@
|
|
+/*
|
|
+ * @(#) prototypes for FreeSWAN functions
|
|
+ *
|
|
+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * and Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_proto.h,v 1.14 2005/04/29 04:50:03 mcr Exp $
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_PROTO_H_
|
|
+
|
|
+#include "ipsec_param.h"
|
|
+
|
|
+/*
|
|
+ * This file is a kernel only file that declares prototypes for
|
|
+ * all intra-module function calls and global data structures.
|
|
+ *
|
|
+ * Include this file last.
|
|
+ *
|
|
+ */
|
|
+
|
|
+/* forward references */
|
|
+enum ipsec_direction;
|
|
+enum ipsec_life_type;
|
|
+struct ipsec_lifetime64;
|
|
+struct ident;
|
|
+struct sockaddr_encap;
|
|
+struct ipsec_sa;
|
|
+
|
|
+/* ipsec_init.c */
|
|
+extern struct prng ipsec_prng;
|
|
+
|
|
+/* ipsec_sa.c */
|
|
+extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
|
|
+extern spinlock_t tdb_lock;
|
|
+extern int ipsec_sadb_init(void);
|
|
+extern int ipsec_sadb_cleanup(__u8);
|
|
+
|
|
+extern struct ipsec_sa *ipsec_sa_alloc(int*error);
|
|
+
|
|
+
|
|
+extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *);
|
|
+extern int ipsec_sa_put(struct ipsec_sa *);
|
|
+extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
|
|
+extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
|
|
+extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
|
|
+
|
|
+extern int ipsec_sa_init(struct ipsec_sa *ipsp);
|
|
+extern int ipsec_sa_wipe(struct ipsec_sa *ipsp);
|
|
+
|
|
+/* debug declarations */
|
|
+
|
|
+/* ipsec_proc.c */
|
|
+extern int ipsec_proc_init(void);
|
|
+extern void ipsec_proc_cleanup(void);
|
|
+
|
|
+/* ipsec_rcv.c */
|
|
+extern int ipsec_rcv(struct sk_buff *skb);
|
|
+extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
|
|
+
|
|
+/* ipsec_xmit.c */
|
|
+struct ipsec_xmit_state;
|
|
+extern enum ipsec_xmit_value ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
|
|
+extern enum ipsec_xmit_value ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
|
|
+extern void ipsec_print_ip(struct iphdr *ip);
|
|
+
|
|
+
|
|
+
|
|
+/* ipsec_radij.c */
|
|
+extern int ipsec_makeroute(struct sockaddr_encap *ea,
|
|
+ struct sockaddr_encap *em,
|
|
+ ip_said said,
|
|
+ uint32_t pid,
|
|
+ struct sk_buff *skb,
|
|
+ struct ident *ident_s,
|
|
+ struct ident *ident_d);
|
|
+
|
|
+extern int ipsec_breakroute(struct sockaddr_encap *ea,
|
|
+ struct sockaddr_encap *em,
|
|
+ struct sk_buff **first,
|
|
+ struct sk_buff **last);
|
|
+
|
|
+int ipsec_radijinit(void);
|
|
+int ipsec_cleareroutes(void);
|
|
+int ipsec_radijcleanup(void);
|
|
+
|
|
+/* ipsec_life.c */
|
|
+extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
|
|
+ const char *lifename,
|
|
+ const char *saname,
|
|
+ enum ipsec_life_type ilt,
|
|
+ enum ipsec_direction idir,
|
|
+ struct ipsec_sa *ips);
|
|
+
|
|
+
|
|
+extern int ipsec_lifetime_format(char *buffer,
|
|
+ int buflen,
|
|
+ char *lifename,
|
|
+ enum ipsec_life_type timebaselife,
|
|
+ struct ipsec_lifetime64 *lifetime);
|
|
+
|
|
+extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
|
|
+ __u64 newvalue);
|
|
+
|
|
+extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
|
|
+ __u64 newvalue);
|
|
+
|
|
+/* ipsec_snprintf.c */
|
|
+extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
|
|
+extern void ipsec_dmp_block(char *s, caddr_t bb, int len);
|
|
+
|
|
+
|
|
+/* ipsec_alg.c */
|
|
+extern int ipsec_alg_init(void);
|
|
+
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+
|
|
+extern int debug_xform;
|
|
+extern int debug_eroute;
|
|
+extern int debug_spi;
|
|
+extern int debug_netlink;
|
|
+
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+#define _IPSEC_PROTO_H
|
|
+#endif /* _IPSEC_PROTO_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_proto.h,v $
|
|
+ * Revision 1.14 2005/04/29 04:50:03 mcr
|
|
+ * prototypes for xmit and alg code.
|
|
+ *
|
|
+ * Revision 1.13 2005/04/17 03:46:07 mcr
|
|
+ * added prototypes for ipsec_rcv() routines.
|
|
+ *
|
|
+ * Revision 1.12 2005/04/14 20:28:37 mcr
|
|
+ * added additional prototypes.
|
|
+ *
|
|
+ * Revision 1.11 2005/04/14 01:16:28 mcr
|
|
+ * add prototypes for snprintf.
|
|
+ *
|
|
+ * Revision 1.10 2005/04/13 22:47:28 mcr
|
|
+ * make sure that forward references are available.
|
|
+ *
|
|
+ * Revision 1.9 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.8 2004/04/05 19:55:06 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_proto.h,v
|
|
+ *
|
|
+ * Revision 1.7 2003/10/31 02:27:05 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.6.30.1 2003/10/29 01:10:19 mcr
|
|
+ * elimited "struct sa_id"
|
|
+ *
|
|
+ * Revision 1.6 2002/05/23 07:13:48 rgb
|
|
+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
|
|
+ *
|
|
+ * Revision 1.5 2002/05/14 02:36:40 rgb
|
|
+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
|
|
+ * with "put" usage in the kernel.
|
|
+ *
|
|
+ * Revision 1.4 2002/04/24 07:36:47 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_proto.h,v
|
|
+ *
|
|
+ * Revision 1.3 2002/04/20 00:12:25 rgb
|
|
+ * Added esp IV CBC attack fix, disabled.
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:15 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:21:01 mcr
|
|
+ * ipsec_proto.h created to keep prototypes rather than deal with
|
|
+ * cyclic dependancies of structures and prototypes in .h files.
|
|
+ *
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,179 @@
|
|
+/*
|
|
+ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_radij.h,v 1.22 2004/07/10 19:08:41 mcr Exp $
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_RADIJ_H
|
|
+
|
|
+#include <openswan.h>
|
|
+
|
|
+int ipsec_walk(char *);
|
|
+
|
|
+int ipsec_rj_walker_procprint(struct radij_node *, void *);
|
|
+int ipsec_rj_walker_delete(struct radij_node *, void *);
|
|
+
|
|
+/* This structure is used to pass information between
|
|
+ * ipsec_eroute_get_info and ipsec_rj_walker_procprint
|
|
+ * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
|
|
+ */
|
|
+struct wsbuf
|
|
+{
|
|
+ /* from caller of ipsec_eroute_get_info: */
|
|
+ char *const buffer; /* start of buffer provided */
|
|
+ const int length; /* length of buffer provided */
|
|
+ const off_t offset; /* file position of first character of interest */
|
|
+ /* accumulated by ipsec_rj_walker_procprint: */
|
|
+ int len; /* number of character filled into buffer */
|
|
+ off_t begin; /* file position contained in buffer[0] (<=offset) */
|
|
+};
|
|
+
|
|
+extern struct radij_node_head *rnh;
|
|
+extern spinlock_t eroute_lock;
|
|
+
|
|
+struct eroute * ipsec_findroute(struct sockaddr_encap *);
|
|
+
|
|
+#define O1(x) (int)(((x)>>24)&0xff)
|
|
+#define O2(x) (int)(((x)>>16)&0xff)
|
|
+#define O3(x) (int)(((x)>>8)&0xff)
|
|
+#define O4(x) (int)(((x))&0xff)
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern int debug_radij;
|
|
+void rj_dumptrees(void);
|
|
+
|
|
+#define DB_RJ_DUMPTREES 0x0001
|
|
+#define DB_RJ_FINDROUTE 0x0002
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+#define _IPSEC_RADIJ_H
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_radij.h,v $
|
|
+ * Revision 1.22 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.21 2004/04/29 11:06:42 ken
|
|
+ * Last bits from 2.06 procfs updates
|
|
+ *
|
|
+ * Revision 1.20 2004/04/06 02:49:08 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.19 2004/04/05 19:55:06 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_radij.h,v
|
|
+ *
|
|
+ * Revision 1.18 2002/04/24 07:36:47 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_radij.h,v
|
|
+ *
|
|
+ * Revision 1.17 2001/11/26 09:23:49 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.16.2.1 2001/09/25 02:21:17 mcr
|
|
+ * ipsec_proto.h created to keep prototypes rather than deal with
|
|
+ * cyclic dependancies of structures and prototypes in .h files.
|
|
+ *
|
|
+ * Revision 1.16 2001/09/15 16:24:04 rgb
|
|
+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
|
|
+ *
|
|
+ * Revision 1.15 2001/09/14 16:58:37 rgb
|
|
+ * Added support for storing the first and last packets through a HOLD.
|
|
+ *
|
|
+ * Revision 1.14 2001/09/08 21:13:32 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.13 2001/06/14 19:35:09 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.12 2001/05/27 06:12:11 rgb
|
|
+ * Added structures for pid, packet count and last access time to eroute.
|
|
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
|
|
+ *
|
|
+ * Revision 1.11 2000/09/08 19:12:56 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.10 1999/11/17 15:53:39 rgb
|
|
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
|
|
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
|
|
+ * klips/net/ipsec/Makefile.
|
|
+ *
|
|
+ * Revision 1.9 1999/10/01 00:01:23 rgb
|
|
+ * Added eroute structure locking.
|
|
+ *
|
|
+ * Revision 1.8 1999/04/11 00:28:59 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.7 1999/04/06 04:54:26 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.6 1999/01/22 06:23:26 rgb
|
|
+ * Cruft clean-out.
|
|
+ *
|
|
+ * Revision 1.5 1998/10/25 02:42:08 rgb
|
|
+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
|
|
+ * argument to be able to transmit more infomation about errors.
|
|
+ *
|
|
+ * Revision 1.4 1998/10/19 14:44:29 rgb
|
|
+ * Added inclusion of freeswan.h.
|
|
+ * sa_id structure implemented and used: now includes protocol.
|
|
+ *
|
|
+ * Revision 1.3 1998/07/28 00:03:31 rgb
|
|
+ * Comment out temporary inet_nto4u() kluge.
|
|
+ *
|
|
+ * Revision 1.2 1998/07/14 18:22:00 rgb
|
|
+ * Add function to clear the eroute table.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:49 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.5 1998/05/25 20:30:38 rgb
|
|
+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
|
|
+ *
|
|
+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
|
|
+ * add ipsec_rj_walker_delete.
|
|
+ *
|
|
+ * Revision 1.4 1998/05/21 13:02:56 rgb
|
|
+ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
|
|
+ * limit fix.
|
|
+ *
|
|
+ * Revision 1.3 1998/04/21 21:29:09 rgb
|
|
+ * Rearrange debug switches to change on the fly debug output from user
|
|
+ * space. Only kernel changes checked in at this time. radij.c was also
|
|
+ * changed to temporarily remove buggy debugging code in rj_delete causing
|
|
+ * an OOPS and hence, netlink device open errors.
|
|
+ *
|
|
+ * Revision 1.2 1998/04/14 17:30:39 rgb
|
|
+ * Fix up compiling errors for radij tree memory reclamation.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:10 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * No changes.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:39:04 ji
|
|
+ * Minor cleanups.
|
|
+ * Rationalized debugging code.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,199 @@
|
|
+/*
|
|
+ *
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_rcv.h,v 1.28.2.2 2006/10/06 21:39:26 paul Exp $
|
|
+ */
|
|
+
|
|
+#ifndef IPSEC_RCV_H
|
|
+#define IPSEC_RCV_H
|
|
+
|
|
+#include "openswan/ipsec_auth.h"
|
|
+
|
|
+#define DB_RX_PKTRX 0x0001
|
|
+#define DB_RX_PKTRX2 0x0002
|
|
+#define DB_RX_DMP 0x0004
|
|
+#define DB_RX_IPSA 0x0010
|
|
+#define DB_RX_XF 0x0020
|
|
+#define DB_RX_IPAD 0x0040
|
|
+#define DB_RX_INAU 0x0080
|
|
+#define DB_RX_OINFO 0x0100
|
|
+#define DB_RX_OINFO2 0x0200
|
|
+#define DB_RX_OH 0x0400
|
|
+#define DB_RX_REPLAY 0x0800
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+/* struct options; */
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
|
|
+#endif
|
|
+#ifdef CONFIG_MODULES
|
|
+#include <linux/module.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#include <openswan.h>
|
|
+
|
|
+#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
|
|
+
|
|
+struct ipsec_birth_reply {
|
|
+ int packet_template_len;
|
|
+ unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
|
|
+};
|
|
+
|
|
+extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
|
|
+extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
|
|
+
|
|
+enum ipsec_rcv_value {
|
|
+ IPSEC_RCV_LASTPROTO=1,
|
|
+ IPSEC_RCV_OK=0,
|
|
+ IPSEC_RCV_BADPROTO=-1,
|
|
+ IPSEC_RCV_BADLEN=-2,
|
|
+ IPSEC_RCV_ESP_BADALG=-3,
|
|
+ IPSEC_RCV_3DES_BADBLOCKING=-4,
|
|
+ IPSEC_RCV_ESP_DECAPFAIL=-5,
|
|
+ IPSEC_RCV_DECAPFAIL=-6,
|
|
+ IPSEC_RCV_SAIDNOTFOUND=-7,
|
|
+ IPSEC_RCV_IPCOMPALONE=-8,
|
|
+ IPSEC_RCV_IPCOMPFAILED=-10,
|
|
+ IPSEC_RCV_SAIDNOTLIVE=-11,
|
|
+ IPSEC_RCV_FAILEDINBOUND=-12,
|
|
+ IPSEC_RCV_LIFETIMEFAILED=-13,
|
|
+ IPSEC_RCV_BADAUTH=-14,
|
|
+ IPSEC_RCV_REPLAYFAILED=-15,
|
|
+ IPSEC_RCV_AUTHFAILED=-16,
|
|
+ IPSEC_RCV_REPLAYROLLED=-17,
|
|
+ IPSEC_RCV_BAD_DECRYPT=-18
|
|
+};
|
|
+
|
|
+struct ipsec_rcv_state {
|
|
+ struct sk_buff *skb;
|
|
+ struct net_device_stats *stats;
|
|
+ struct iphdr *ipp; /* the IP header */
|
|
+ struct ipsec_sa *ipsp; /* current SA being processed */
|
|
+ int len; /* length of packet */
|
|
+ int ilen; /* length of inner payload (-authlen) */
|
|
+ int authlen; /* how big is the auth data at end */
|
|
+ int hard_header_len; /* layer 2 size */
|
|
+ int iphlen; /* how big is IP header */
|
|
+ struct auth_alg *authfuncs;
|
|
+ ip_said said;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+ __u8 next_header;
|
|
+ __u8 hash[AH_AMAX];
|
|
+ char ipsaddr_txt[ADDRTOA_BUF];
|
|
+ char ipdaddr_txt[ADDRTOA_BUF];
|
|
+ __u8 *octx;
|
|
+ __u8 *ictx;
|
|
+ int ictx_len;
|
|
+ int octx_len;
|
|
+ union {
|
|
+ struct {
|
|
+ struct esphdr *espp;
|
|
+ } espstuff;
|
|
+ struct {
|
|
+ struct ahhdr *ahp;
|
|
+ } ahstuff;
|
|
+ struct {
|
|
+ struct ipcomphdr *compp;
|
|
+ } ipcompstuff;
|
|
+ } protostuff;
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ __u8 natt_type;
|
|
+ __u16 natt_sport;
|
|
+ __u16 natt_dport;
|
|
+ int natt_len;
|
|
+#endif
|
|
+};
|
|
+
|
|
+extern int
|
|
+#ifdef PROTO_HANDLER_SINGLE_PARM
|
|
+ipsec_rcv(struct sk_buff *skb);
|
|
+#else /* PROTO_HANDLER_SINGLE_PARM */
|
|
+ipsec_rcv(struct sk_buff *skb,
|
|
+ unsigned short xlen);
|
|
+#endif /* PROTO_HANDLER_SINGLE_PARM */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern int debug_rcv;
|
|
+#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
|
|
+#else
|
|
+#define ipsec_rcv_dmp(_x,_y, _z) do {} while(0)
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+extern int sysctl_ipsec_inbound_policy_check;
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
|
|
+
|
|
+
|
|
+#endif /* IPSEC_RCV_H */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_rcv.h,v $
|
|
+ * Revision 1.28.2.2 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.28.2.1 2006/07/10 15:52:20 paul
|
|
+ * Fix for bug #642 by Bart Trojanowski
|
|
+ *
|
|
+ * Revision 1.28 2005/05/11 00:59:45 mcr
|
|
+ * do not call debug routines if !defined KLIPS_DEBUG.
|
|
+ *
|
|
+ * Revision 1.27 2005/04/29 04:59:46 mcr
|
|
+ * use ipsec_dmp_block.
|
|
+ *
|
|
+ * Revision 1.26 2005/04/13 22:48:35 mcr
|
|
+ * added comments, and removed some log.
|
|
+ * removed Linux 2.0 support.
|
|
+ *
|
|
+ * Revision 1.25 2005/04/08 18:25:37 mcr
|
|
+ * prototype klips26 encap receive function
|
|
+ *
|
|
+ * Revision 1.24 2004/08/20 21:45:37 mcr
|
|
+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
|
|
+ * be 26sec compatible. But, some defines where changed.
|
|
+ *
|
|
+ * Revision 1.23 2004/08/03 18:17:40 mcr
|
|
+ * in 2.6, use "net_device" instead of #define device->net_device.
|
|
+ * this probably breaks 2.0 compiles.
|
|
+ *
|
|
+ * Revision 1.22 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.21 2004/04/06 02:49:08 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.20 2004/04/05 19:55:06 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_rcv.h,v
|
|
+ *
|
|
+ * Revision 1.19 2003/12/15 18:13:09 mcr
|
|
+ * when compiling with NAT traversal, don't assume that the
|
|
+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
|
|
+ * is set.
|
|
+ *
|
|
+ * history elided 2005-04-12.
|
|
+ *
|
|
+ * Local Variables:
|
|
+ * c-basic-offset:8
|
|
+ * c-style:linux
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
+
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,355 @@
|
|
+/*
|
|
+ * @(#) Definitions of IPsec Security Association (ipsec_sa)
|
|
+ *
|
|
+ * Copyright (C) 2001, 2002, 2003
|
|
+ * Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * and Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_sa.h,v 1.23 2005/05/11 01:18:59 mcr Exp $
|
|
+ *
|
|
+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
|
|
+ *
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * This file describes the IPsec Security Association Structure.
|
|
+ *
|
|
+ * This structure keeps track of a single transform that may be done
|
|
+ * to a set of packets. It can describe applying the transform or
|
|
+ * apply the reverse. (e.g. compression vs expansion). However, it
|
|
+ * only describes one at a time. To describe both, two structures would
|
|
+ * be used, but since the sides of the transform are performed
|
|
+ * on different machines typically it is usual to have only one side
|
|
+ * of each association.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_SA_H_
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+#include "openswan/ipsec_stats.h"
|
|
+#include "openswan/ipsec_life.h"
|
|
+#include "openswan/ipsec_eroute.h"
|
|
+#endif /* __KERNEL__ */
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#include "pfkeyv2.h"
|
|
+
|
|
+
|
|
+/* SAs are held in a table.
|
|
+ * Entries in this table are referenced by IPsecSAref_t values.
|
|
+ * IPsecSAref_t values are conceptually subscripts. Because
|
|
+ * we want to allocate the table piece-meal, the subscripting
|
|
+ * is implemented with two levels, a bit like paged virtual memory.
|
|
+ * This representation mechanism is known as an Iliffe Vector.
|
|
+ *
|
|
+ * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
|
|
+ * pointers to subtables.
|
|
+ * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
|
|
+ * is a pointer to an SA.
|
|
+ *
|
|
+ * An IPsecSAref_t contains either an exceptional value (signified by the
|
|
+ * high-order bit being on) or a reference to a table entry. A table entry
|
|
+ * reference has the subtable subscript in the low-order
|
|
+ * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
|
|
+ * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
|
|
+ *
|
|
+ * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
|
|
+ * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
|
|
+ *
|
|
+ * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
|
|
+ * struct ipsec_sa*. The macro definition clearly shows the two-level
|
|
+ * access needed to find the SA pointer.
|
|
+ *
|
|
+ * The Maintable is allocated when IPsec is initialized.
|
|
+ * Each subtable is allocated when needed, but the first is allocated
|
|
+ * when IPsec is initialized.
|
|
+ *
|
|
+ * IPsecSAref_t is designed to be smaller than an NFmark so that
|
|
+ * they can be stored in NFmarks and still leave a few bits for other
|
|
+ * purposes. The spare bits are in the low order of the NFmark
|
|
+ * but in the high order of the IPsecSAref_t, so conversion is required.
|
|
+ * We pick the upper bits of NFmark on the theory that they are less likely to
|
|
+ * interfere with more pedestrian uses of nfmark.
|
|
+ */
|
|
+
|
|
+
|
|
+typedef unsigned short int IPsecRefTableUnusedCount;
|
|
+
|
|
+#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
|
|
+#error "IPSEC_SA_REF_TABLE_IDX_WIDTH("IPSEC_SA_REF_TABLE_IDX_WIDTH") MUST be < 1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH("IPSEC_SA_REF_MAINTABLE_IDX_WIDTH")"
|
|
+#endif
|
|
+
|
|
+#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
|
|
+
|
|
+#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
|
|
+#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
|
|
+
|
|
+#ifdef CONFIG_NETFILTER
|
|
+#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
|
|
+#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
|
|
+#else /* CONFIG_NETFILTER */
|
|
+/* just make it work for now, it doesn't matter, since there is no nfmark */
|
|
+#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
|
|
+#endif /* CONFIG_NETFILTER */
|
|
+#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
|
|
+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
|
|
+
|
|
+#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
|
|
+#define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
|
|
+#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
|
|
+
|
|
+#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
|
|
+#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
|
|
+#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
|
|
+
|
|
+#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
|
|
+#define IPsecSA2SAref(x) ((x)->ips_ref)
|
|
+
|
|
+#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
|
|
+
|
|
+/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
|
|
+struct ipsec_sa
|
|
+{
|
|
+ IPsecSAref_t ips_ref; /* reference table entry number */
|
|
+ atomic_t ips_refcount; /* reference count for this struct */
|
|
+ struct ipsec_sa *ips_hnext; /* next in hash chain */
|
|
+ struct ipsec_sa *ips_inext; /* pointer to next xform */
|
|
+ struct ipsec_sa *ips_onext; /* pointer to prev xform */
|
|
+
|
|
+ struct ifnet *ips_rcvif; /* related rcv encap interface */
|
|
+
|
|
+ ip_said ips_said; /* SA ID */
|
|
+
|
|
+ __u32 ips_seq; /* seq num of msg that initiated this SA */
|
|
+ __u32 ips_pid; /* PID of process that initiated this SA */
|
|
+ __u8 ips_authalg; /* auth algorithm for this SA */
|
|
+ __u8 ips_encalg; /* enc algorithm for this SA */
|
|
+
|
|
+ struct ipsec_stats ips_errs;
|
|
+
|
|
+ __u8 ips_replaywin; /* replay window size */
|
|
+ enum sadb_sastate ips_state; /* state of SA */
|
|
+ __u32 ips_replaywin_lastseq; /* last pkt sequence num */
|
|
+ __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
|
|
+ __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
|
|
+
|
|
+ __u32 ips_flags; /* generic xform flags */
|
|
+
|
|
+
|
|
+ struct ipsec_lifetimes ips_life; /* lifetime records */
|
|
+
|
|
+ /* selector information */
|
|
+ __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */
|
|
+ struct sockaddr*ips_addr_s; /* src sockaddr */
|
|
+ struct sockaddr*ips_addr_d; /* dst sockaddr */
|
|
+ struct sockaddr*ips_addr_p; /* proxy sockaddr */
|
|
+ __u16 ips_addr_s_size;
|
|
+ __u16 ips_addr_d_size;
|
|
+ __u16 ips_addr_p_size;
|
|
+ ip_address ips_flow_s;
|
|
+ ip_address ips_flow_d;
|
|
+ ip_address ips_mask_s;
|
|
+ ip_address ips_mask_d;
|
|
+
|
|
+ __u16 ips_key_bits_a; /* size of authkey in bits */
|
|
+ __u16 ips_auth_bits; /* size of authenticator in bits */
|
|
+ __u16 ips_key_bits_e; /* size of enckey in bits */
|
|
+ __u16 ips_iv_bits; /* size of IV in bits */
|
|
+ __u8 ips_iv_size;
|
|
+ __u16 ips_key_a_size;
|
|
+ __u16 ips_key_e_size;
|
|
+
|
|
+ caddr_t ips_key_a; /* authentication key */
|
|
+ caddr_t ips_key_e; /* encryption key */
|
|
+ caddr_t ips_iv; /* Initialisation Vector */
|
|
+
|
|
+ struct ident ips_ident_s; /* identity src */
|
|
+ struct ident ips_ident_d; /* identity dst */
|
|
+
|
|
+ /* these are included even if CONFIG_KLIPS_IPCOMP is off */
|
|
+ __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
|
|
+ __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
|
|
+ __u64 ips_comp_ratio_cbytes; /* compressed bytes */
|
|
+ __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
|
|
+
|
|
+ /* these are included even if CONFIG_IPSEC_NAT_TRAVERSAL is off */
|
|
+ __u8 ips_natt_type;
|
|
+ __u8 ips_natt_reserved[3];
|
|
+ __u16 ips_natt_sport;
|
|
+ __u16 ips_natt_dport;
|
|
+
|
|
+ struct sockaddr *ips_natt_oa;
|
|
+ __u16 ips_natt_oa_size;
|
|
+ __u16 ips_natt_reserved2;
|
|
+
|
|
+#if 0
|
|
+ __u32 ips_sens_dpd;
|
|
+ __u8 ips_sens_sens_level;
|
|
+ __u8 ips_sens_sens_len;
|
|
+ __u64* ips_sens_sens_bitmap;
|
|
+ __u8 ips_sens_integ_level;
|
|
+ __u8 ips_sens_integ_len;
|
|
+ __u64* ips_sens_integ_bitmap;
|
|
+#endif
|
|
+ struct ipsec_alg_enc *ips_alg_enc;
|
|
+ struct ipsec_alg_auth *ips_alg_auth;
|
|
+ IPsecSAref_t ips_ref_rel;
|
|
+};
|
|
+
|
|
+struct IPsecSArefSubTable
|
|
+{
|
|
+ struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
|
|
+};
|
|
+
|
|
+struct ipsec_sadb {
|
|
+ struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
|
|
+ IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
|
|
+ int refFreeListHead;
|
|
+ int refFreeListTail;
|
|
+ IPsecSAref_t refFreeListCont;
|
|
+ IPsecSAref_t said_hash[SADB_HASHMOD];
|
|
+ spinlock_t sadb_lock;
|
|
+};
|
|
+
|
|
+extern struct ipsec_sadb ipsec_sadb;
|
|
+
|
|
+extern int ipsec_SAref_recycle(void);
|
|
+extern int ipsec_SArefSubTable_alloc(unsigned table);
|
|
+extern int ipsec_saref_freelist_init(void);
|
|
+extern int ipsec_sadb_init(void);
|
|
+extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
|
|
+extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
|
|
+extern int ipsec_sa_free(struct ipsec_sa* ips);
|
|
+extern int ipsec_sa_put(struct ipsec_sa *ips);
|
|
+extern int ipsec_sa_add(struct ipsec_sa *ips);
|
|
+extern int ipsec_sa_del(struct ipsec_sa *ips);
|
|
+extern int ipsec_sa_delchain(struct ipsec_sa *ips);
|
|
+extern int ipsec_sadb_cleanup(__u8 proto);
|
|
+extern int ipsec_sadb_free(void);
|
|
+extern int ipsec_sa_wipe(struct ipsec_sa *ips);
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+enum ipsec_direction {
|
|
+ ipsec_incoming = 1,
|
|
+ ipsec_outgoing = 2
|
|
+};
|
|
+
|
|
+#define _IPSEC_SA_H_
|
|
+#endif /* _IPSEC_SA_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_sa.h,v $
|
|
+ * Revision 1.23 2005/05/11 01:18:59 mcr
|
|
+ * do not change structure based upon options, to avoid
|
|
+ * too many #ifdef.
|
|
+ *
|
|
+ * Revision 1.22 2005/04/14 01:17:09 mcr
|
|
+ * change sadb_state to an enum.
|
|
+ *
|
|
+ * Revision 1.21 2004/08/20 21:45:37 mcr
|
|
+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
|
|
+ * be 26sec compatible. But, some defines where changed.
|
|
+ *
|
|
+ * Revision 1.20 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.19 2004/04/05 19:55:06 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_sa.h,v
|
|
+ *
|
|
+ * Revision 1.18 2004/04/05 19:41:05 mcr
|
|
+ * merged alg-branch code.
|
|
+ *
|
|
+ * Revision 1.17.2.1 2003/12/22 15:25:52 jjo
|
|
+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.17 2003/12/10 01:20:06 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.16 2003/10/31 02:27:05 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.15.4.1 2003/10/29 01:10:19 mcr
|
|
+ * elimited "struct sa_id"
|
|
+ *
|
|
+ * Revision 1.15 2003/05/11 00:53:09 mcr
|
|
+ * IPsecSAref_t and macros were moved to freeswan.h.
|
|
+ *
|
|
+ * Revision 1.14 2003/02/12 19:31:55 rgb
|
|
+ * Fixed bug in "file seen" machinery.
|
|
+ * Updated copyright year.
|
|
+ *
|
|
+ * Revision 1.13 2003/01/30 02:31:52 rgb
|
|
+ *
|
|
+ * Re-wrote comments describing SAref system for accuracy.
|
|
+ * Rename SAref table macro names for clarity.
|
|
+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
|
|
+ * Transmit error code through to caller from callee for better diagnosis of problems.
|
|
+ * Enclose all macro arguments in parens to avoid any possible obscrure bugs.
|
|
+ *
|
|
+ * Revision 1.12 2002/10/07 18:31:19 rgb
|
|
+ * Change comment to reflect the flexible nature of the main and sub-table widths.
|
|
+ * Added a counter for the number of unused entries in each subtable.
|
|
+ * Further break up host field type macro to host field.
|
|
+ * Move field width sanity checks to ipsec_sa.c
|
|
+ * Define a mask for an entire saref.
|
|
+ *
|
|
+ * Revision 1.11 2002/09/20 15:40:33 rgb
|
|
+ * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys.
|
|
+ * Fixed SAref/nfmark macros.
|
|
+ * Rework saref freeslist.
|
|
+ * Place all ipsec sadb globals into one struct.
|
|
+ * Restrict some bits to kernel context for use to klips utils.
|
|
+ *
|
|
+ * Revision 1.10 2002/09/20 05:00:34 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.9 2002/09/17 17:19:29 mcr
|
|
+ * make it compile even if there is no netfilter - we lost
|
|
+ * functionality, but it works, especially on 2.2.
|
|
+ *
|
|
+ * Revision 1.8 2002/07/28 22:59:53 mcr
|
|
+ * clarified/expanded one comment.
|
|
+ *
|
|
+ * Revision 1.7 2002/07/26 08:48:31 rgb
|
|
+ * Added SA ref table code.
|
|
+ *
|
|
+ * Revision 1.6 2002/05/31 17:27:48 rgb
|
|
+ * Comment fix.
|
|
+ *
|
|
+ * Revision 1.5 2002/05/27 18:55:03 rgb
|
|
+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
|
|
+ *
|
|
+ * Revision 1.4 2002/05/23 07:13:36 rgb
|
|
+ * Convert "usecount" to "refcount" to remove ambiguity.
|
|
+ *
|
|
+ * Revision 1.3 2002/04/24 07:36:47 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_sa.h,v
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:15 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:24:58 mcr
|
|
+ * struct tdb -> struct ipsec_sa.
|
|
+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
|
|
+ * ipsec_xform.c removed. header file still contains useful things.
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,79 @@
|
|
+/*
|
|
+ * RCSID $Id: ipsec_sha1.h,v 1.8 2004/04/05 19:55:07 mcr Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Here is the original comment from the distribution:
|
|
+
|
|
+SHA-1 in C
|
|
+By Steve Reid <steve@edmweb.com>
|
|
+100% Public Domain
|
|
+
|
|
+ * Adapted for use by the IPSEC code by John Ioannidis
|
|
+ */
|
|
+
|
|
+
|
|
+#ifndef _IPSEC_SHA1_H_
|
|
+#define _IPSEC_SHA1_H_
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ __u32 state[5];
|
|
+ __u32 count[2];
|
|
+ __u8 buffer[64];
|
|
+} SHA1_CTX;
|
|
+
|
|
+void SHA1Transform(__u32 state[5], __u8 buffer[64]);
|
|
+void SHA1Init(void *context);
|
|
+void SHA1Update(void *context, unsigned char *data, __u32 len);
|
|
+void SHA1Final(unsigned char digest[20], void *context);
|
|
+
|
|
+
|
|
+#endif /* _IPSEC_SHA1_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_sha1.h,v $
|
|
+ * Revision 1.8 2004/04/05 19:55:07 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_sha1.h,v
|
|
+ *
|
|
+ * Revision 1.7 2002/09/10 01:45:09 mcr
|
|
+ * changed type of MD5_CTX and SHA1_CTX to void * so that
|
|
+ * the function prototypes would match, and could be placed
|
|
+ * into a pointer to a function.
|
|
+ *
|
|
+ * Revision 1.6 2002/04/24 07:36:47 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
|
|
+ *
|
|
+ * Revision 1.5 1999/12/13 13:59:13 rgb
|
|
+ * Quick fix to argument size to Update bugs.
|
|
+ *
|
|
+ * Revision 1.4 1999/12/07 18:16:23 rgb
|
|
+ * Fixed comments at end of #endif lines.
|
|
+ *
|
|
+ * Revision 1.3 1999/04/06 04:54:27 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.2 1998/11/30 13:22:54 rgb
|
|
+ * Rationalised all the klips kernel file headers. They are much shorter
|
|
+ * now and won't conflict under RH5.2.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:50 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.2 1998/04/23 20:54:05 rgb
|
|
+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
|
|
+ * verified.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:04:21 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ * these two include files modified not to include others except in kernel
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * New transform
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,76 @@
|
|
+/*
|
|
+ * @(#) definition of ipsec_stats structure
|
|
+ *
|
|
+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * and Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_stats.h,v 1.7 2005/04/14 01:17:45 mcr Exp $
|
|
+ *
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * This file describes the errors/statistics that FreeSWAN collects.
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_STATS_H_
|
|
+
|
|
+struct ipsec_stats {
|
|
+ __u32 ips_alg_errs; /* number of algorithm errors */
|
|
+ __u32 ips_auth_errs; /* # of authentication errors */
|
|
+ __u32 ips_encsize_errs; /* # of encryption size errors*/
|
|
+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
|
|
+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
|
|
+};
|
|
+
|
|
+#define _IPSEC_STATS_H_
|
|
+#endif /* _IPSEC_STATS_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_stats.h,v $
|
|
+ * Revision 1.7 2005/04/14 01:17:45 mcr
|
|
+ * add prototypes for snprintf.
|
|
+ *
|
|
+ * Revision 1.6 2004/04/05 19:55:07 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_stats.h,v
|
|
+ *
|
|
+ * Revision 1.5 2004/04/05 19:41:05 mcr
|
|
+ * merged alg-branch code.
|
|
+ *
|
|
+ * Revision 1.4 2004/03/28 20:27:19 paul
|
|
+ * Included tested and confirmed fixes mcr made and dhr verified for
|
|
+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
|
|
+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
|
|
+ * dhr. (thanks dhr!)
|
|
+ *
|
|
+ * Revision 1.4 2004/03/24 01:58:31 mcr
|
|
+ * sprintf->snprintf for formatting into proc buffer.
|
|
+ *
|
|
+ * Revision 1.3.34.1 2004/04/05 04:30:46 mcr
|
|
+ * patches for alg-branch to compile/work with 2.x openswan
|
|
+ *
|
|
+ * Revision 1.3 2002/04/24 07:36:47 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_stats.h,v
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:16 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:27:00 mcr
|
|
+ * statistics moved to seperate structure.
|
|
+ *
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,280 @@
|
|
+/*
|
|
+ * IPSEC tunneling code
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_tunnel.h,v 1.33 2005/06/04 16:06:05 mcr Exp $
|
|
+ */
|
|
+
|
|
+
|
|
+#ifdef NET_21
|
|
+# define DEV_QUEUE_XMIT(skb, device, pri) {\
|
|
+ skb->dev = device; \
|
|
+ neigh_compat_output(skb); \
|
|
+ /* skb->dst->output(skb); */ \
|
|
+ }
|
|
+# define ICMP_SEND(skb_in, type, code, info, dev) \
|
|
+ icmp_send(skb_in, type, code, htonl(info))
|
|
+# define IP_SEND(skb, dev) \
|
|
+ ip_send(skb);
|
|
+#else /* NET_21 */
|
|
+# define DEV_QUEUE_XMIT(skb, device, pri) {\
|
|
+ dev_queue_xmit(skb, device, pri); \
|
|
+ }
|
|
+# define ICMP_SEND(skb_in, type, code, info, dev) \
|
|
+ icmp_send(skb_in, type, code, info, dev)
|
|
+# define IP_SEND(skb, dev) \
|
|
+ if(ntohs(iph->tot_len) > physmtu) { \
|
|
+ ip_fragment(NULL, skb, dev, 0); \
|
|
+ ipsec_kfree_skb(skb); \
|
|
+ } else { \
|
|
+ dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
|
|
+ }
|
|
+#endif /* NET_21 */
|
|
+
|
|
+
|
|
+/*
|
|
+ * Heavily based on drivers/net/new_tunnel.c. Lots
|
|
+ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
|
|
+ */
|
|
+
|
|
+struct ipsectunnelconf
|
|
+{
|
|
+ __u32 cf_cmd;
|
|
+ union
|
|
+ {
|
|
+ char cfu_name[12];
|
|
+ } cf_u;
|
|
+#define cf_name cf_u.cfu_name
|
|
+};
|
|
+
|
|
+#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
|
|
+#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
|
|
+#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+#include <linux/version.h>
|
|
+#ifndef KERNEL_VERSION
|
|
+# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
|
|
+#endif
|
|
+struct ipsecpriv
|
|
+{
|
|
+ struct sk_buff_head sendq;
|
|
+ struct net_device *dev;
|
|
+ struct wait_queue *wait_queue;
|
|
+ char locked;
|
|
+ int (*hard_start_xmit) (struct sk_buff *skb,
|
|
+ struct net_device *dev);
|
|
+ int (*hard_header) (struct sk_buff *skb,
|
|
+ struct net_device *dev,
|
|
+ unsigned short type,
|
|
+ void *daddr,
|
|
+ void *saddr,
|
|
+ unsigned len);
|
|
+#ifdef NET_21
|
|
+ int (*rebuild_header)(struct sk_buff *skb);
|
|
+#else /* NET_21 */
|
|
+ int (*rebuild_header)(void *buff, struct net_device *dev,
|
|
+ unsigned long raddr, struct sk_buff *skb);
|
|
+#endif /* NET_21 */
|
|
+ int (*set_mac_address)(struct net_device *dev, void *addr);
|
|
+#ifndef NET_21
|
|
+ void (*header_cache_bind)(struct hh_cache **hhp, struct net_device *dev,
|
|
+ unsigned short htype, __u32 daddr);
|
|
+#endif /* !NET_21 */
|
|
+ void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr);
|
|
+ struct net_device_stats *(*get_stats)(struct net_device *dev);
|
|
+ struct net_device_stats mystats;
|
|
+ int mtu; /* What is the desired MTU? */
|
|
+};
|
|
+
|
|
+extern char ipsec_tunnel_c_version[];
|
|
+
|
|
+extern struct net_device *ipsecdevices[IPSEC_NUM_IF];
|
|
+
|
|
+int ipsec_tunnel_init_devices(void);
|
|
+
|
|
+/* void */ int ipsec_tunnel_cleanup_devices(void);
|
|
+
|
|
+extern /* void */ int ipsec_init(void);
|
|
+
|
|
+extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev);
|
|
+extern struct net_device *ipsec_get_device(int inst);
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern int debug_tunnel;
|
|
+extern int sysctl_ipsec_debug_verbose;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+#define DB_TN_INIT 0x0001
|
|
+#define DB_TN_PROCFS 0x0002
|
|
+#define DB_TN_XMIT 0x0010
|
|
+#define DB_TN_OHDR 0x0020
|
|
+#define DB_TN_CROUT 0x0040
|
|
+#define DB_TN_OXFS 0x0080
|
|
+#define DB_TN_REVEC 0x0100
|
|
+#define DB_TN_ENCAP 0x0200
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_tunnel.h,v $
|
|
+ * Revision 1.33 2005/06/04 16:06:05 mcr
|
|
+ * better patch for nat-t rcv-device code.
|
|
+ *
|
|
+ * Revision 1.32 2005/05/21 03:18:35 mcr
|
|
+ * added additional debug flag tunnelling.
|
|
+ *
|
|
+ * Revision 1.31 2004/08/03 18:18:02 mcr
|
|
+ * in 2.6, use "net_device" instead of #define device->net_device.
|
|
+ * this probably breaks 2.0 compiles.
|
|
+ *
|
|
+ * Revision 1.30 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.29 2004/04/05 19:55:07 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_tunnel.h,v
|
|
+ *
|
|
+ * Revision 1.28 2003/06/24 20:22:32 mcr
|
|
+ * added new global: ipsecdevices[] so that we can keep track of
|
|
+ * the ipsecX devices. They will be referenced with dev_hold(),
|
|
+ * so 2.2 may need this as well.
|
|
+ *
|
|
+ * Revision 1.27 2003/04/03 17:38:09 rgb
|
|
+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
|
|
+ *
|
|
+ * Revision 1.26 2003/02/12 19:32:20 rgb
|
|
+ * Updated copyright year.
|
|
+ *
|
|
+ * Revision 1.25 2002/05/27 18:56:07 rgb
|
|
+ * Convert to dynamic ipsec device allocation.
|
|
+ *
|
|
+ * Revision 1.24 2002/04/24 07:36:48 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
|
|
+ *
|
|
+ * Revision 1.23 2001/11/06 19:50:44 rgb
|
|
+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
|
|
+ * use also by pfkey_v2_parser.c
|
|
+ *
|
|
+ * Revision 1.22 2001/09/15 16:24:05 rgb
|
|
+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
|
|
+ *
|
|
+ * Revision 1.21 2001/06/14 19:35:10 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.20 2000/09/15 11:37:02 rgb
|
|
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
|
|
+ * IPCOMP zlib deflate code.
|
|
+ *
|
|
+ * Revision 1.19 2000/09/08 19:12:56 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.18 2000/07/28 13:50:54 rgb
|
|
+ * Changed enet_statistics to net_device_stats and added back compatibility
|
|
+ * for pre-2.1.19.
|
|
+ *
|
|
+ * Revision 1.17 1999/11/19 01:12:15 rgb
|
|
+ * Purge unneeded proc_info prototypes, now that static linking uses
|
|
+ * dynamic proc_info registration.
|
|
+ *
|
|
+ * Revision 1.16 1999/11/18 18:51:00 rgb
|
|
+ * Changed all device registrations for static linking to
|
|
+ * dynamic to reduce the number and size of patches.
|
|
+ *
|
|
+ * Revision 1.15 1999/11/18 04:14:21 rgb
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
|
|
+ * Added Marc Boucher's 2.3.25 proc patches.
|
|
+ *
|
|
+ * Revision 1.14 1999/05/25 02:50:10 rgb
|
|
+ * Fix kernel version macros for 2.0.x static linking.
|
|
+ *
|
|
+ * Revision 1.13 1999/05/25 02:41:06 rgb
|
|
+ * Add ipsec_klipsdebug support for static linking.
|
|
+ *
|
|
+ * Revision 1.12 1999/05/05 22:02:32 rgb
|
|
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
|
|
+ *
|
|
+ * Revision 1.11 1999/04/29 15:19:50 rgb
|
|
+ * Add return values to init and cleanup functions.
|
|
+ *
|
|
+ * Revision 1.10 1999/04/16 16:02:39 rgb
|
|
+ * Bump up macro to 4 ipsec I/Fs.
|
|
+ *
|
|
+ * Revision 1.9 1999/04/15 15:37:25 rgb
|
|
+ * Forward check changes from POST1_00 branch.
|
|
+ *
|
|
+ * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
|
|
+ * Backcheck from HEAD, pre1.0.
|
|
+ *
|
|
+ * Revision 1.8 1999/04/11 00:29:01 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.7 1999/04/06 04:54:28 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.6 1999/03/31 05:44:48 rgb
|
|
+ * Keep PMTU reduction private.
|
|
+ *
|
|
+ * Revision 1.5 1999/02/10 22:31:20 rgb
|
|
+ * Change rebuild_header member to reflect generality of link layer.
|
|
+ *
|
|
+ * Revision 1.4 1998/12/01 13:22:04 rgb
|
|
+ * Added support for debug printing of version info.
|
|
+ *
|
|
+ * Revision 1.3 1998/07/29 20:42:46 rgb
|
|
+ * Add a macro for clearing all tunnel devices.
|
|
+ * Rearrange structures and declarations for sharing with userspace.
|
|
+ *
|
|
+ * Revision 1.2 1998/06/25 20:01:45 rgb
|
|
+ * Make prototypes available for ipsec_init and ipsec proc_dir_entries
|
|
+ * for static linking.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:50 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.3 1998/05/18 21:51:50 rgb
|
|
+ * Added macros for num of I/F's and a procfs debug switch.
|
|
+ *
|
|
+ * Revision 1.2 1998/04/21 21:29:09 rgb
|
|
+ * Rearrange debug switches to change on the fly debug output from user
|
|
+ * space. Only kernel changes checked in at this time. radij.c was also
|
|
+ * changed to temporarily remove buggy debugging code in rj_delete causing
|
|
+ * an OOPS and hence, netlink device open errors.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:13 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.5 1997/06/03 04:24:48 ji
|
|
+ * Added transport mode.
|
|
+ * Changed the way routing is done.
|
|
+ * Lots of bug fixes.
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * No changes.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:39:04 ji
|
|
+ * Minor cleanups.
|
|
+ * Rationalized debugging code.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,257 @@
|
|
+/*
|
|
+ * Definitions relevant to IPSEC transformations
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_xform.h,v 1.41 2004/07/10 19:08:41 mcr Exp $
|
|
+ */
|
|
+
|
|
+#ifndef _IPSEC_XFORM_H_
|
|
+
|
|
+#include <openswan.h>
|
|
+
|
|
+#define XF_NONE 0 /* No transform set */
|
|
+#define XF_IP4 1 /* IPv4 inside IPv4 */
|
|
+#define XF_AHMD5 2 /* AH MD5 */
|
|
+#define XF_AHSHA 3 /* AH SHA */
|
|
+#define XF_ESP3DES 5 /* ESP DES3-CBC */
|
|
+#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
|
|
+#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
|
|
+#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
|
|
+#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
|
|
+#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
|
|
+#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
|
|
+#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
|
|
+#define XF_IP6 15 /* IPv6 inside IPv6 */
|
|
+#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
|
|
+
|
|
+#define XF_CLR 126 /* Clear SA table */
|
|
+#define XF_DEL 127 /* Delete SA */
|
|
+
|
|
+/* IPsec AH transform values
|
|
+ * RFC 2407
|
|
+ * draft-ietf-ipsec-doi-tc-mib-02.txt
|
|
+ */
|
|
+
|
|
+#define AH_NONE 0
|
|
+#define AH_MD5 2
|
|
+#define AH_SHA 3
|
|
+/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */
|
|
+#define AH_SHA2_256 5
|
|
+#define AH_SHA2_384 6
|
|
+#define AH_SHA2_512 7
|
|
+#define AH_RIPEMD 8
|
|
+#define AH_MAX 15
|
|
+
|
|
+/* IPsec ESP transform values */
|
|
+
|
|
+#define ESP_NONE 0
|
|
+#define ESP_DES 2
|
|
+#define ESP_3DES 3
|
|
+#define ESP_RC5 4
|
|
+#define ESP_IDEA 5
|
|
+#define ESP_CAST 6
|
|
+#define ESP_BLOWFISH 7
|
|
+#define ESP_3IDEA 8
|
|
+#define ESP_RC4 10
|
|
+#define ESP_NULL 11
|
|
+#define ESP_AES 12
|
|
+
|
|
+/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */
|
|
+#define ESP_MARS 249
|
|
+#define ESP_RC6 250
|
|
+#define ESP_SERPENT 252
|
|
+#define ESP_TWOFISH 253
|
|
+
|
|
+/* IPCOMP transform values */
|
|
+
|
|
+#define IPCOMP_NONE 0
|
|
+#define IPCOMP_OUI 1
|
|
+#define IPCOMP_DEFLAT 2
|
|
+#define IPCOMP_LZS 3
|
|
+#define IPCOMP_V42BIS 4
|
|
+
|
|
+#define XFT_AUTH 0x0001
|
|
+#define XFT_CONF 0x0100
|
|
+
|
|
+/* available if CONFIG_KLIPS_DEBUG is defined */
|
|
+#define DB_XF_INIT 0x0001
|
|
+
|
|
+#define PROTO2TXT(x) \
|
|
+ (x) == IPPROTO_AH ? "AH" : \
|
|
+ (x) == IPPROTO_ESP ? "ESP" : \
|
|
+ (x) == IPPROTO_IPIP ? "IPIP" : \
|
|
+ (x) == IPPROTO_COMP ? "COMP" : \
|
|
+ "UNKNOWN_proto"
|
|
+static inline const char *enc_name_id (unsigned id) {
|
|
+ static char buf[16];
|
|
+ snprintf(buf, sizeof(buf), "_ID%d", id);
|
|
+ return buf;
|
|
+}
|
|
+static inline const char *auth_name_id (unsigned id) {
|
|
+ static char buf[16];
|
|
+ snprintf(buf, sizeof(buf), "_ID%d", id);
|
|
+ return buf;
|
|
+}
|
|
+#define IPS_XFORM_NAME(x) \
|
|
+ PROTO2TXT((x)->ips_said.proto), \
|
|
+ (x)->ips_said.proto == IPPROTO_COMP ? \
|
|
+ ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
|
|
+ "_DEFLATE" : "_UNKNOWN_comp") : \
|
|
+ (x)->ips_encalg == ESP_NONE ? "" : \
|
|
+ (x)->ips_encalg == ESP_3DES ? "_3DES" : \
|
|
+ (x)->ips_encalg == ESP_AES ? "_AES" : \
|
|
+ (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
|
|
+ (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
|
|
+ enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
|
|
+ (x)->ips_authalg == AH_NONE ? "" : \
|
|
+ (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
|
|
+ (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
|
|
+ (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
|
|
+ (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
|
|
+ (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
|
|
+ auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+struct ipsec_rcv_state;
|
|
+struct ipsec_xmit_state;
|
|
+
|
|
+struct xform_functions {
|
|
+ enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb);
|
|
+ enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
|
|
+
|
|
+ enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb,
|
|
+ __u32 *replay,
|
|
+ unsigned char **authenticator);
|
|
+ enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb);
|
|
+
|
|
+ enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
|
|
+ enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
|
|
+
|
|
+ enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
|
|
+ struct sk_buff *skb,
|
|
+ __u32 *replay,
|
|
+ unsigned char **authenticator);
|
|
+ enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
|
|
+ struct sk_buff *skb);
|
|
+ int xmit_headroom;
|
|
+ int xmit_needtailroom;
|
|
+};
|
|
+
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern void ipsec_dmp(char *s, caddr_t bb, int len);
|
|
+#else /* CONFIG_KLIPS_DEBUG */
|
|
+#define ipsec_dmp(_x, _y, _z)
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+
|
|
+#define _IPSEC_XFORM_H_
|
|
+#endif /* _IPSEC_XFORM_H_ */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_xform.h,v $
|
|
+ * Revision 1.41 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.40 2004/04/06 02:49:08 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.39 2004/04/05 19:55:07 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_xform.h,v
|
|
+ *
|
|
+ * Revision 1.38 2004/04/05 19:41:05 mcr
|
|
+ * merged alg-branch code.
|
|
+ *
|
|
+ * Revision 1.37 2003/12/13 19:10:16 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.36.34.1 2003/12/22 15:25:52 jjo
|
|
+ * Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.36 2002/04/24 07:36:48 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_xform.h,v
|
|
+ *
|
|
+ * Revision 1.35 2001/11/26 09:23:51 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.33.2.1 2001/09/25 02:24:58 mcr
|
|
+ * struct tdb -> struct ipsec_sa.
|
|
+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
|
|
+ * ipsec_xform.c removed. header file still contains useful things.
|
|
+ *
|
|
+ * Revision 1.34 2001/11/06 19:47:17 rgb
|
|
+ * Changed lifetime_packets to uint32 from uint64.
|
|
+ *
|
|
+ * Revision 1.33 2001/09/08 21:13:34 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.32 2001/07/06 07:40:01 rgb
|
|
+ * Reformatted for readability.
|
|
+ * Added inbound policy checking fields for use with IPIP SAs.
|
|
+ *
|
|
+ * Revision 1.31 2001/06/14 19:35:11 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.30 2001/05/30 08:14:03 rgb
|
|
+ * Removed vestiges of esp-null transforms.
|
|
+ *
|
|
+ * Revision 1.29 2001/01/30 23:42:47 rgb
|
|
+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
|
|
+ * and subsequent ADD or UDATE.
|
|
+ *
|
|
+ * Revision 1.28 2000/11/06 04:30:40 rgb
|
|
+ * Add Svenning's adaptive content compression.
|
|
+ *
|
|
+ * Revision 1.27 2000/09/19 00:38:25 rgb
|
|
+ * Fixed algorithm name bugs introduced for ipcomp.
|
|
+ *
|
|
+ * Revision 1.26 2000/09/17 21:36:48 rgb
|
|
+ * Added proto2txt macro.
|
|
+ *
|
|
+ * Revision 1.25 2000/09/17 18:56:47 rgb
|
|
+ * Added IPCOMP support.
|
|
+ *
|
|
+ * Revision 1.24 2000/09/12 19:34:12 rgb
|
|
+ * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
|
|
+ *
|
|
+ * Revision 1.23 2000/09/12 03:23:14 rgb
|
|
+ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
|
|
+ *
|
|
+ * Revision 1.22 2000/09/08 19:12:56 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.21 2000/09/01 18:32:43 rgb
|
|
+ * Added (disabled) sensitivity members to tdb struct.
|
|
+ *
|
|
+ * Revision 1.20 2000/08/30 05:31:01 rgb
|
|
+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
|
|
+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
|
|
+ *
|
|
+ * Revision 1.19 2000/08/01 14:51:52 rgb
|
|
+ * Removed _all_ remaining traces of DES.
|
|
+ *
|
|
+ * Revision 1.18 2000/01/21 06:17:45 rgb
|
|
+ * Tidied up spacing.
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,198 @@
|
|
+/*
|
|
+ * IPSEC tunneling code
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_xmit.h,v 1.14 2005/05/11 01:00:26 mcr Exp $
|
|
+ */
|
|
+
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+{
|
|
+ IPSEC_XMIT_STOLEN=2,
|
|
+ IPSEC_XMIT_PASS=1,
|
|
+ IPSEC_XMIT_OK=0,
|
|
+ IPSEC_XMIT_ERRMEMALLOC=-1,
|
|
+ IPSEC_XMIT_ESP_BADALG=-2,
|
|
+ IPSEC_XMIT_BADPROTO=-3,
|
|
+ IPSEC_XMIT_ESP_PUSHPULLERR=-4,
|
|
+ IPSEC_XMIT_BADLEN=-5,
|
|
+ IPSEC_XMIT_AH_BADALG=-6,
|
|
+ IPSEC_XMIT_SAIDNOTFOUND=-7,
|
|
+ IPSEC_XMIT_SAIDNOTLIVE=-8,
|
|
+ IPSEC_XMIT_REPLAYROLLED=-9,
|
|
+ IPSEC_XMIT_LIFETIMEFAILED=-10,
|
|
+ IPSEC_XMIT_CANNOTFRAG=-11,
|
|
+ IPSEC_XMIT_MSSERR=-12,
|
|
+ IPSEC_XMIT_ERRSKBALLOC=-13,
|
|
+ IPSEC_XMIT_ENCAPFAIL=-14,
|
|
+ IPSEC_XMIT_NODEV=-15,
|
|
+ IPSEC_XMIT_NOPRIVDEV=-16,
|
|
+ IPSEC_XMIT_NOPHYSDEV=-17,
|
|
+ IPSEC_XMIT_NOSKB=-18,
|
|
+ IPSEC_XMIT_NOIPV6=-19,
|
|
+ IPSEC_XMIT_NOIPOPTIONS=-20,
|
|
+ IPSEC_XMIT_TTLEXPIRED=-21,
|
|
+ IPSEC_XMIT_BADHHLEN=-22,
|
|
+ IPSEC_XMIT_PUSHPULLERR=-23,
|
|
+ IPSEC_XMIT_ROUTEERR=-24,
|
|
+ IPSEC_XMIT_RECURSDETECT=-25,
|
|
+ IPSEC_XMIT_IPSENDFAILURE=-26,
|
|
+ IPSEC_XMIT_ESPUDP=-27,
|
|
+ IPSEC_XMIT_ESPUDP_BADTYPE=-28,
|
|
+};
|
|
+
|
|
+struct ipsec_xmit_state
|
|
+{
|
|
+ struct sk_buff *skb; /* working skb pointer */
|
|
+ struct net_device *dev; /* working dev pointer */
|
|
+ struct ipsecpriv *prv; /* Our device' private space */
|
|
+ struct sk_buff *oskb; /* Original skb pointer */
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+ struct iphdr *iph; /* Our new IP header */
|
|
+ __u32 newdst; /* The other SG's IP address */
|
|
+ __u32 orgdst; /* Original IP destination address */
|
|
+ __u32 orgedst; /* 1st SG's IP address */
|
|
+ __u32 newsrc; /* The new source SG's IP address */
|
|
+ __u32 orgsrc; /* Original IP source address */
|
|
+ __u32 innersrc; /* Innermost IP source address */
|
|
+ int iphlen; /* IP header length */
|
|
+ int pyldsz; /* upper protocol payload size */
|
|
+ int headroom;
|
|
+ int tailroom;
|
|
+ int authlen;
|
|
+ int max_headroom; /* The extra header space needed */
|
|
+ int max_tailroom; /* The extra stuffing needed */
|
|
+ int ll_headroom; /* The extra link layer hard_header space needed */
|
|
+ int tot_headroom; /* The total header space needed */
|
|
+ int tot_tailroom; /* The totalstuffing needed */
|
|
+ __u8 *saved_header; /* saved copy of the hard header */
|
|
+ unsigned short sport, dport;
|
|
+
|
|
+ struct sockaddr_encap matcher; /* eroute search key */
|
|
+ struct eroute *eroute;
|
|
+ struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */
|
|
+ char sa_txt[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+ int hard_header_stripped; /* has the hard header been removed yet? */
|
|
+ int hard_header_len;
|
|
+ struct net_device *physdev;
|
|
+/* struct device *virtdev; */
|
|
+ short physmtu;
|
|
+ short cur_mtu; /* copy of prv->mtu, cause prv may == NULL */
|
|
+ short mtudiff;
|
|
+#ifdef NET_21
|
|
+ struct rtable *route;
|
|
+#endif /* NET_21 */
|
|
+ ip_said outgoing_said;
|
|
+#ifdef NET_21
|
|
+ int pass;
|
|
+#endif /* NET_21 */
|
|
+ int error;
|
|
+ uint32_t eroute_pid;
|
|
+ struct ipsec_sa ips;
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ uint8_t natt_type;
|
|
+ uint8_t natt_head;
|
|
+ uint16_t natt_sport;
|
|
+ uint16_t natt_dport;
|
|
+#endif
|
|
+};
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
|
|
+
|
|
+extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
|
|
+
|
|
+
|
|
+extern int ipsec_xmit_trap_count;
|
|
+extern int ipsec_xmit_trap_sendcount;
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern int debug_tunnel;
|
|
+
|
|
+#define debug_xmit debug_tunnel
|
|
+
|
|
+#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
|
|
+#else
|
|
+#define ipsec_xmit_dmp(_x,_y, _z) do {} while(0)
|
|
+
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+extern int sysctl_ipsec_debug_verbose;
|
|
+extern int sysctl_ipsec_icmp;
|
|
+extern int sysctl_ipsec_tos;
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_xmit.h,v $
|
|
+ * Revision 1.14 2005/05/11 01:00:26 mcr
|
|
+ * do not call debug routines if !defined KLIPS_DEBUG.
|
|
+ *
|
|
+ * Revision 1.13 2005/04/29 05:01:38 mcr
|
|
+ * use ipsec_dmp_block.
|
|
+ * added cur_mtu to ixs instead of using ixs->dev.
|
|
+ *
|
|
+ * Revision 1.12 2004/08/20 21:45:37 mcr
|
|
+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
|
|
+ * be 26sec compatible. But, some defines where changed.
|
|
+ *
|
|
+ * Revision 1.11 2004/08/03 18:18:21 mcr
|
|
+ * in 2.6, use "net_device" instead of #define device->net_device.
|
|
+ * this probably breaks 2.0 compiles.
|
|
+ *
|
|
+ * Revision 1.10 2004/07/10 19:08:41 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.9 2004/04/06 02:49:08 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.8 2004/04/05 19:55:07 mcr
|
|
+ * Moved from linux/include/freeswan/ipsec_xmit.h,v
|
|
+ *
|
|
+ * Revision 1.7 2004/02/03 03:11:40 mcr
|
|
+ * new xmit type if the UDP encapsulation is wrong.
|
|
+ *
|
|
+ * Revision 1.6 2003/12/13 19:10:16 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.5 2003/12/10 01:20:06 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.4 2003/12/06 16:37:04 mcr
|
|
+ * 1.4.7a X.509 patch applied.
|
|
+ *
|
|
+ * Revision 1.3 2003/10/31 02:27:05 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.2.4.2 2003/10/29 01:10:19 mcr
|
|
+ * elimited "struct sa_id"
|
|
+ *
|
|
+ * Revision 1.2.4.1 2003/09/21 13:59:38 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.2 2003/06/20 01:42:13 mcr
|
|
+ * added counters to measure how many ACQUIREs we send to pluto,
|
|
+ * and how many are successfully sent.
|
|
+ *
|
|
+ * Revision 1.1 2003/02/12 19:31:03 rgb
|
|
+ * Refactored from ipsec_tunnel.c
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,75 @@
|
|
+/*
|
|
+ * sanitize a string into a printable format.
|
|
+ *
|
|
+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
|
|
+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: passert.h,v 1.7 2004/10/21 18:44:42 mcr Exp $
|
|
+ */
|
|
+
|
|
+#include "openswan.h"
|
|
+
|
|
+#ifndef _OPENSWAN_PASSERT_H
|
|
+#define _OPENSWAN_PASSERT_H
|
|
+/* our versions of assert: log result */
|
|
+
|
|
+#ifdef DEBUG
|
|
+
|
|
+typedef void (*openswan_passert_fail_t)(const char *pred_str,
|
|
+ const char *file_str,
|
|
+ unsigned long line_no) NEVER_RETURNS;
|
|
+
|
|
+openswan_passert_fail_t openswan_passert_fail;
|
|
+
|
|
+extern void pexpect_log(const char *pred_str
|
|
+ , const char *file_str, unsigned long line_no);
|
|
+
|
|
+# define impossible() do { \
|
|
+ if(openswan_passert_fail) { \
|
|
+ (*openswan_passert_fail)("impossible", __FILE__, __LINE__); \
|
|
+ }} while(0)
|
|
+
|
|
+extern void switch_fail(int n
|
|
+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
|
|
+
|
|
+# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
|
|
+
|
|
+# define passert(pred) do { \
|
|
+ if (!(pred)) \
|
|
+ if(openswan_passert_fail) { \
|
|
+ (*openswan_passert_fail)(#pred, __FILE__, __LINE__); \
|
|
+ } \
|
|
+ } while(0)
|
|
+
|
|
+# define pexpect(pred) do { \
|
|
+ if (!(pred)) \
|
|
+ pexpect_log(#pred, __FILE__, __LINE__); \
|
|
+ } while(0)
|
|
+
|
|
+/* assert that an err_t is NULL; evaluate exactly once */
|
|
+# define happy(x) { \
|
|
+ err_t ugh = x; \
|
|
+ if (ugh != NULL) \
|
|
+ if(openswan_passert_fail) { (*openswan_passert_fail)(ugh, __FILE__, __LINE__); } \
|
|
+ }
|
|
+
|
|
+#else /*!DEBUG*/
|
|
+
|
|
+# define impossible() abort()
|
|
+# define bad_case(n) abort()
|
|
+# define passert(pred) { } /* do nothing */
|
|
+# define happy(x) { (void) x; } /* evaluate non-judgementally */
|
|
+
|
|
+#endif /*!DEBUG*/
|
|
+
|
|
+#endif /* _OPENSWAN_PASSERT_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,54 @@
|
|
+/*
|
|
+ * sanitize a string into a printable format.
|
|
+ *
|
|
+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
|
|
+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: pfkey_debug.h,v 1.3 2004/04/05 19:55:07 mcr Exp $
|
|
+ */
|
|
+
|
|
+#ifndef _FREESWAN_PFKEY_DEBUG_H
|
|
+#define _FREESWAN_PFKEY_DEBUG_H
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+/* note, kernel version ignores pfkey levels */
|
|
+# define DEBUGGING(level,args...) \
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
|
|
+
|
|
+# define ERROR(args...) printk(KERN_ERR "klips:" args)
|
|
+
|
|
+#else
|
|
+
|
|
+extern unsigned int pfkey_lib_debug;
|
|
+
|
|
+extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
|
|
+extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
|
|
+
|
|
+#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \
|
|
+ if(pfkey_debug_func != NULL) { \
|
|
+ (*pfkey_debug_func)("pfkey_lib_debug:" args); \
|
|
+ } else { \
|
|
+ printf("pfkey_lib_debug:" args); \
|
|
+ } }
|
|
+
|
|
+#define ERROR(args...) if(pfkey_error_func != NULL) { \
|
|
+ (*pfkey_error_func)("pfkey_lib_debug:" args); \
|
|
+ }
|
|
+
|
|
+# define MALLOC(size) malloc(size)
|
|
+# define FREE(obj) free(obj)
|
|
+
|
|
+#endif
|
|
+
|
|
+#endif
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,280 @@
|
|
+/*
|
|
+ * RCSID $Id: radij.h,v 1.13 2004/04/05 19:55:08 mcr Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
|
|
+ *
|
|
+ * Variable and procedure names have been modified so that they don't
|
|
+ * conflict with the original BSD code, as a small number of modifications
|
|
+ * have been introduced and we may want to reuse this code in BSD.
|
|
+ *
|
|
+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
|
|
+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
|
|
+ * spanish j as in Juan. It is not as far back in the throat like
|
|
+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
|
|
+ * It has nothing to do with the Dutch ij sound.
|
|
+ *
|
|
+ * Here is the appropriate copyright notice:
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Copyright (c) 1988, 1989, 1993
|
|
+ * The Regents of the University of California. All rights reserved.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * This product includes software developed by the University of
|
|
+ * California, Berkeley and its contributors.
|
|
+ * 4. Neither the name of the University nor the names of its contributors
|
|
+ * may be used to endorse or promote products derived from this software
|
|
+ * without specific prior written permission.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * @(#)radix.h 8.1 (Berkeley) 6/10/93
|
|
+ */
|
|
+
|
|
+#ifndef _RADIJ_H_
|
|
+#define _RADIJ_H_
|
|
+
|
|
+/*
|
|
+#define RJ_DEBUG
|
|
+*/
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+#ifndef __P
|
|
+#ifdef __STDC__
|
|
+#define __P(x) x
|
|
+#else
|
|
+#define __P(x) ()
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * Radix search tree node layout.
|
|
+ */
|
|
+
|
|
+struct radij_node
|
|
+{
|
|
+ struct radij_mask *rj_mklist; /* list of masks contained in subtree */
|
|
+ struct radij_node *rj_p; /* parent */
|
|
+ short rj_b; /* bit offset; -1-index(netmask) */
|
|
+ char rj_bmask; /* node: mask for bit test*/
|
|
+ u_char rj_flags; /* enumerated next */
|
|
+#define RJF_NORMAL 1 /* leaf contains normal route */
|
|
+#define RJF_ROOT 2 /* leaf is root leaf for tree */
|
|
+#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
|
|
+ union {
|
|
+ struct { /* leaf only data: */
|
|
+ caddr_t rj_Key; /* object of search */
|
|
+ caddr_t rj_Mask; /* netmask, if present */
|
|
+ struct radij_node *rj_Dupedkey;
|
|
+ } rj_leaf;
|
|
+ struct { /* node only data: */
|
|
+ int rj_Off; /* where to start compare */
|
|
+ struct radij_node *rj_L;/* progeny */
|
|
+ struct radij_node *rj_R;/* progeny */
|
|
+ }rj_node;
|
|
+ } rj_u;
|
|
+#ifdef RJ_DEBUG
|
|
+ int rj_info;
|
|
+ struct radij_node *rj_twin;
|
|
+ struct radij_node *rj_ybro;
|
|
+#endif
|
|
+};
|
|
+
|
|
+#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
|
|
+#define rj_key rj_u.rj_leaf.rj_Key
|
|
+#define rj_mask rj_u.rj_leaf.rj_Mask
|
|
+#define rj_off rj_u.rj_node.rj_Off
|
|
+#define rj_l rj_u.rj_node.rj_L
|
|
+#define rj_r rj_u.rj_node.rj_R
|
|
+
|
|
+/*
|
|
+ * Annotations to tree concerning potential routes applying to subtrees.
|
|
+ */
|
|
+
|
|
+extern struct radij_mask {
|
|
+ short rm_b; /* bit offset; -1-index(netmask) */
|
|
+ char rm_unused; /* cf. rj_bmask */
|
|
+ u_char rm_flags; /* cf. rj_flags */
|
|
+ struct radij_mask *rm_mklist; /* more masks to try */
|
|
+ caddr_t rm_mask; /* the mask */
|
|
+ int rm_refs; /* # of references to this struct */
|
|
+} *rj_mkfreelist;
|
|
+
|
|
+#define MKGet(m) {\
|
|
+ if (rj_mkfreelist) {\
|
|
+ m = rj_mkfreelist; \
|
|
+ rj_mkfreelist = (m)->rm_mklist; \
|
|
+ } else \
|
|
+ R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
|
|
+
|
|
+#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
|
|
+
|
|
+struct radij_node_head {
|
|
+ struct radij_node *rnh_treetop;
|
|
+ int rnh_addrsize; /* permit, but not require fixed keys */
|
|
+ int rnh_pktsize; /* permit, but not require fixed keys */
|
|
+#if 0
|
|
+ struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
|
|
+ __P((void *v, void *mask,
|
|
+ struct radij_node_head *head, struct radij_node nodes[]));
|
|
+#endif
|
|
+ int (*rnh_addaddr) /* add based on sockaddr */
|
|
+ __P((void *v, void *mask,
|
|
+ struct radij_node_head *head, struct radij_node nodes[]));
|
|
+ struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
|
|
+ __P((void *v, void *mask,
|
|
+ struct radij_node_head *head, struct radij_node nodes[]));
|
|
+#if 0
|
|
+ struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
|
|
+ __P((void *v, void *mask, struct radij_node_head *head));
|
|
+#endif
|
|
+ int (*rnh_deladdr) /* remove based on sockaddr */
|
|
+ __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
|
|
+ struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
|
|
+ __P((void *v, void *mask, struct radij_node_head *head));
|
|
+ struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
|
|
+ __P((void *v, struct radij_node_head *head));
|
|
+ struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
|
|
+ __P((void *v, struct radij_node_head *head));
|
|
+ int (*rnh_walktree) /* traverse tree */
|
|
+ __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
|
|
+ struct radij_node rnh_nodes[3]; /* empty tree for common case */
|
|
+};
|
|
+
|
|
+
|
|
+#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
|
|
+#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
|
|
+#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
|
|
+#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
|
|
+#define Free(p) kfree((caddr_t)p);
|
|
+
|
|
+void rj_init __P((void));
|
|
+int rj_inithead __P((void **, int));
|
|
+int rj_refines __P((void *, void *));
|
|
+int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
|
|
+struct radij_node
|
|
+ *rj_addmask __P((void *, int, int)) /* , rgb */ ;
|
|
+int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
|
|
+ struct radij_node [2])) /* , rgb */ ;
|
|
+int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
|
|
+struct radij_node /* rgb */
|
|
+ *rj_insert __P((void *, struct radij_node_head *, int *,
|
|
+ struct radij_node [2])),
|
|
+ *rj_match __P((void *, struct radij_node_head *)),
|
|
+ *rj_newpair __P((void *, int, struct radij_node[2])),
|
|
+ *rj_search __P((void *, struct radij_node *)),
|
|
+ *rj_search_m __P((void *, struct radij_node *, void *));
|
|
+
|
|
+void rj_deltree(struct radij_node_head *);
|
|
+void rj_delnodes(struct radij_node *);
|
|
+void rj_free_mkfreelist(void);
|
|
+int radijcleartree(void);
|
|
+int radijcleanup(void);
|
|
+
|
|
+extern struct radij_node_head *mask_rjhead;
|
|
+extern int maj_keylen;
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+#endif /* _RADIJ_H_ */
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: radij.h,v $
|
|
+ * Revision 1.13 2004/04/05 19:55:08 mcr
|
|
+ * Moved from linux/include/freeswan/radij.h,v
|
|
+ *
|
|
+ * Revision 1.12 2002/04/24 07:36:48 mcr
|
|
+ * Moved from ./klips/net/ipsec/radij.h,v
|
|
+ *
|
|
+ * Revision 1.11 2001/09/20 15:33:00 rgb
|
|
+ * Min/max cleanup.
|
|
+ *
|
|
+ * Revision 1.10 1999/11/18 04:09:20 rgb
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ *
|
|
+ * Revision 1.9 1999/05/05 22:02:33 rgb
|
|
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
|
|
+ *
|
|
+ * Revision 1.8 1999/04/29 15:24:58 rgb
|
|
+ * Add check for existence of macros min/max.
|
|
+ *
|
|
+ * Revision 1.7 1999/04/11 00:29:02 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.6 1999/04/06 04:54:29 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.5 1999/01/22 06:30:32 rgb
|
|
+ * 64-bit clean-up.
|
|
+ *
|
|
+ * Revision 1.4 1998/11/30 13:22:55 rgb
|
|
+ * Rationalised all the klips kernel file headers. They are much shorter
|
|
+ * now and won't conflict under RH5.2.
|
|
+ *
|
|
+ * Revision 1.3 1998/10/25 02:43:27 rgb
|
|
+ * Change return type on rj_addroute and rj_delete and add and argument
|
|
+ * to the latter to be able to transmit more infomation about errors.
|
|
+ *
|
|
+ * Revision 1.2 1998/07/14 18:09:51 rgb
|
|
+ * Add a routine to clear eroute table.
|
|
+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:30:22 henry
|
|
+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
|
|
+ * build scripts happier about symlinks
|
|
+ *
|
|
+ * Revision 1.4 1998/05/25 20:34:16 rgb
|
|
+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
|
|
+ *
|
|
+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
|
|
+ * add ipsec_rj_walker_delete.
|
|
+ *
|
|
+ * Recover memory for eroute table on unload of module.
|
|
+ *
|
|
+ * Revision 1.3 1998/04/22 16:51:37 rgb
|
|
+ * Tidy up radij debug code from recent rash of modifications to debug code.
|
|
+ *
|
|
+ * Revision 1.2 1998/04/14 17:30:38 rgb
|
|
+ * Fix up compiling errors for radij tree memory reclamation.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:16 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * No changes.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:44:45 ji
|
|
+ * Release update only.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/pfkey.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,529 @@
|
|
+/*
|
|
+ * FreeS/WAN specific PF_KEY headers
|
|
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: pfkey.h,v 1.49 2005/05/11 00:57:29 mcr Exp $
|
|
+ */
|
|
+
|
|
+#ifndef __NET_IPSEC_PF_KEY_H
|
|
+#define __NET_IPSEC_PF_KEY_H
|
|
+#ifdef __KERNEL__
|
|
+extern struct proto_ops pfkey_proto_ops;
|
|
+typedef struct sock pfkey_sock;
|
|
+extern int debug_pfkey;
|
|
+
|
|
+extern /* void */ int pfkey_init(void);
|
|
+extern /* void */ int pfkey_cleanup(void);
|
|
+
|
|
+struct socket_list
|
|
+{
|
|
+ struct socket *socketp;
|
|
+ struct socket_list *next;
|
|
+};
|
|
+extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
|
|
+extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
|
|
+extern struct socket_list *pfkey_open_sockets;
|
|
+extern struct socket_list *pfkey_registered_sockets[];
|
|
+
|
|
+struct ipsec_alg_supported
|
|
+{
|
|
+ uint16_t ias_exttype;
|
|
+ uint8_t ias_id;
|
|
+ uint8_t ias_ivlen;
|
|
+ uint16_t ias_keyminbits;
|
|
+ uint16_t ias_keymaxbits;
|
|
+ char *ias_name;
|
|
+};
|
|
+
|
|
+extern struct supported_list *pfkey_supported_list[];
|
|
+struct supported_list
|
|
+{
|
|
+ struct ipsec_alg_supported *supportedp;
|
|
+ struct supported_list *next;
|
|
+};
|
|
+extern int pfkey_list_insert_supported(struct ipsec_alg_supported*, struct supported_list**);
|
|
+extern int pfkey_list_remove_supported(struct ipsec_alg_supported*, struct supported_list**);
|
|
+
|
|
+struct sockaddr_key
|
|
+{
|
|
+ uint16_t key_family; /* PF_KEY */
|
|
+ uint16_t key_pad; /* not used */
|
|
+ uint32_t key_pid; /* process ID */
|
|
+};
|
|
+
|
|
+struct pfkey_extracted_data
|
|
+{
|
|
+ struct ipsec_sa* ips;
|
|
+ struct ipsec_sa* ips2;
|
|
+ struct eroute *eroute;
|
|
+};
|
|
+
|
|
+/* forward reference */
|
|
+struct sadb_ext;
|
|
+struct sadb_msg;
|
|
+struct sockaddr;
|
|
+struct sadb_comb;
|
|
+struct sadb_sadb;
|
|
+struct sadb_alg;
|
|
+
|
|
+extern int
|
|
+pfkey_alloc_eroute(struct eroute** eroute);
|
|
+
|
|
+extern int
|
|
+pfkey_sa_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_address_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_key_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_ident_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_sens_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_prop_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_supported_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_spirange_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int
|
|
+pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data* extr);
|
|
+
|
|
+extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
|
|
+extern int pfkey_expire(struct ipsec_sa *, int);
|
|
+extern int pfkey_acquire(struct ipsec_sa *);
|
|
+#else /* ! __KERNEL__ */
|
|
+
|
|
+extern void (*pfkey_debug_func)(const char *message, ...);
|
|
+extern void (*pfkey_error_func)(const char *message, ...);
|
|
+extern void pfkey_print(struct sadb_msg *msg, FILE *out);
|
|
+
|
|
+
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+extern uint8_t satype2proto(uint8_t satype);
|
|
+extern uint8_t proto2satype(uint8_t proto);
|
|
+extern char* satype2name(uint8_t satype);
|
|
+extern char* proto2name(uint8_t proto);
|
|
+
|
|
+struct key_opt
|
|
+{
|
|
+ uint32_t key_pid; /* process ID */
|
|
+ struct sock *sk;
|
|
+};
|
|
+
|
|
+#define key_pid(sk) ((struct key_opt*)&((sk)->sk_protinfo))->key_pid
|
|
+
|
|
+/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
|
|
+ * words.
|
|
+ */
|
|
+#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
|
|
+#define BITS_PER_OCTET 8
|
|
+#define OCTETBITS 8
|
|
+#define PFKEYBITS 64
|
|
+#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
|
|
+#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
|
|
+
|
|
+#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN)
|
|
+#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN)
|
|
+
|
|
+
|
|
+#define PFKEYv2_MAX_MSGSIZE 4096
|
|
+
|
|
+/*
|
|
+ * PF_KEYv2 permitted and required extensions in and out bitmaps
|
|
+ */
|
|
+struct pf_key_ext_parsers_def {
|
|
+ int (*parser)(struct sadb_ext*);
|
|
+ char *parser_name;
|
|
+};
|
|
+
|
|
+
|
|
+#define SADB_EXTENSIONS_MAX 31
|
|
+extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX];
|
|
+#define EXT_BITS_IN 0
|
|
+#define EXT_BITS_OUT 1
|
|
+#define EXT_BITS_PERM 0
|
|
+#define EXT_BITS_REQ 1
|
|
+
|
|
+extern void pfkey_extensions_init(struct sadb_ext *extensions[]);
|
|
+extern void pfkey_extensions_free(struct sadb_ext *extensions[]);
|
|
+extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
|
|
+
|
|
+extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
|
|
+ struct pf_key_ext_parsers_def *ext_parsers[],
|
|
+ struct sadb_ext **extensions,
|
|
+ int dir);
|
|
+
|
|
+extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg);
|
|
+
|
|
+/*
|
|
+ * PF_KEYv2 build function prototypes
|
|
+ */
|
|
+
|
|
+int
|
|
+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
|
|
+ uint8_t msg_type,
|
|
+ uint8_t satype,
|
|
+ uint8_t msg_errno,
|
|
+ uint32_t seq,
|
|
+ uint32_t pid);
|
|
+
|
|
+int
|
|
+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint32_t spi, /* in network order */
|
|
+ uint8_t replay_window,
|
|
+ uint8_t sa_state,
|
|
+ uint8_t auth,
|
|
+ uint8_t encrypt,
|
|
+ uint32_t flags,
|
|
+ uint32_t/*IPsecSAref_t*/ ref);
|
|
+
|
|
+int
|
|
+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint32_t spi, /* in network order */
|
|
+ uint8_t replay_window,
|
|
+ uint8_t sa_state,
|
|
+ uint8_t auth,
|
|
+ uint8_t encrypt,
|
|
+ uint32_t flags);
|
|
+
|
|
+int
|
|
+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint32_t allocations,
|
|
+ uint64_t bytes,
|
|
+ uint64_t addtime,
|
|
+ uint64_t usetime,
|
|
+ uint32_t packets);
|
|
+
|
|
+int
|
|
+pfkey_address_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint8_t proto,
|
|
+ uint8_t prefixlen,
|
|
+ struct sockaddr* address);
|
|
+
|
|
+int
|
|
+pfkey_key_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint16_t key_bits,
|
|
+ char* key);
|
|
+
|
|
+int
|
|
+pfkey_ident_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint16_t ident_type,
|
|
+ uint64_t ident_id,
|
|
+ uint8_t ident_len,
|
|
+ char* ident_string);
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
|
|
+extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
|
|
+extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
|
|
+#endif /* __KERNEL__ */
|
|
+int
|
|
+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
|
|
+ uint8_t type);
|
|
+int
|
|
+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint16_t port);
|
|
+
|
|
+int
|
|
+pfkey_sens_build(struct sadb_ext** pfkey_ext,
|
|
+ uint32_t dpd,
|
|
+ uint8_t sens_level,
|
|
+ uint8_t sens_len,
|
|
+ uint64_t* sens_bitmap,
|
|
+ uint8_t integ_level,
|
|
+ uint8_t integ_len,
|
|
+ uint64_t* integ_bitmap);
|
|
+
|
|
+int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
|
|
+
|
|
+
|
|
+int
|
|
+pfkey_prop_build(struct sadb_ext** pfkey_ext,
|
|
+ uint8_t replay,
|
|
+ unsigned int comb_num,
|
|
+ struct sadb_comb* comb);
|
|
+
|
|
+int
|
|
+pfkey_supported_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ unsigned int alg_num,
|
|
+ struct sadb_alg* alg);
|
|
+
|
|
+int
|
|
+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint32_t min,
|
|
+ uint32_t max);
|
|
+
|
|
+int
|
|
+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
|
|
+
|
|
+int
|
|
+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
|
|
+ uint8_t satype);
|
|
+
|
|
+int
|
|
+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
|
|
+ uint32_t tunnel,
|
|
+ uint32_t netlink,
|
|
+ uint32_t xform,
|
|
+ uint32_t eroute,
|
|
+ uint32_t spi,
|
|
+ uint32_t radij,
|
|
+ uint32_t esp,
|
|
+ uint32_t ah,
|
|
+ uint32_t rcv,
|
|
+ uint32_t pfkey,
|
|
+ uint32_t ipcomp,
|
|
+ uint32_t verbose);
|
|
+
|
|
+int
|
|
+pfkey_msg_build(struct sadb_msg** pfkey_msg,
|
|
+ struct sadb_ext* extensions[],
|
|
+ int dir);
|
|
+
|
|
+/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
|
|
+const char *
|
|
+pfkey_v2_sadb_ext_string(int extnum);
|
|
+
|
|
+const char *
|
|
+pfkey_v2_sadb_type_string(int sadb_type);
|
|
+
|
|
+
|
|
+#endif /* __NET_IPSEC_PF_KEY_H */
|
|
+
|
|
+/*
|
|
+ * $Log: pfkey.h,v $
|
|
+ * Revision 1.49 2005/05/11 00:57:29 mcr
|
|
+ * rename struct supported -> struct ipsec_alg_supported.
|
|
+ * make pfkey.h more standalone.
|
|
+ *
|
|
+ * Revision 1.48 2005/05/01 03:12:50 mcr
|
|
+ * include name of algorithm in datastructure.
|
|
+ *
|
|
+ * Revision 1.47 2004/08/21 00:44:14 mcr
|
|
+ * simplify definition of nat_t related prototypes.
|
|
+ *
|
|
+ * Revision 1.46 2004/08/04 16:27:22 mcr
|
|
+ * 2.6 sk_ options.
|
|
+ *
|
|
+ * Revision 1.45 2004/04/06 02:49:00 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.44 2003/12/10 01:20:01 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.43 2003/10/31 02:26:44 mcr
|
|
+ * pulled up port-selector patches.
|
|
+ *
|
|
+ * Revision 1.42.2.2 2003/10/29 01:09:32 mcr
|
|
+ * added debugging for pfkey library.
|
|
+ *
|
|
+ * Revision 1.42.2.1 2003/09/21 13:59:34 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.42 2003/08/25 22:08:19 mcr
|
|
+ * removed pfkey_proto_init() from pfkey.h for 2.6 support.
|
|
+ *
|
|
+ * Revision 1.41 2003/05/07 17:28:57 mcr
|
|
+ * new function pfkey_debug_func added for us in debugging from
|
|
+
|
|
+ * pfkey library.
|
|
+ *
|
|
+ * Revision 1.40 2003/01/30 02:31:34 rgb
|
|
+ *
|
|
+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
|
|
+ *
|
|
+ * Revision 1.39 2002/09/20 15:40:21 rgb
|
|
+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
|
|
+ * Added ref parameter to pfkey_sa_build().
|
|
+ * Cleaned out unused cruft.
|
|
+ *
|
|
+ * Revision 1.38 2002/05/14 02:37:24 rgb
|
|
+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
|
|
+ * ipsec_sa or ipsec_sa.
|
|
+ * Added function prototypes for the functions moved to
|
|
+ * pfkey_v2_ext_process.c.
|
|
+ *
|
|
+ * Revision 1.37 2002/04/24 07:36:49 mcr
|
|
+ * Moved from ./lib/pfkey.h,v
|
|
+ *
|
|
+ * Revision 1.36 2002/01/20 20:34:49 mcr
|
|
+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
|
|
+ *
|
|
+ * Revision 1.35 2001/11/27 05:27:47 mcr
|
|
+ * pfkey parses are now maintained by a structure
|
|
+ * that includes their name for debug purposes.
|
|
+ *
|
|
+ * Revision 1.34 2001/11/26 09:23:53 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.33 2001/11/06 19:47:47 rgb
|
|
+ * Added packet parameter to lifetime and comb structures.
|
|
+ *
|
|
+ * Revision 1.32 2001/09/08 21:13:34 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.31 2001/06/14 19:35:16 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.30 2001/02/27 07:04:52 rgb
|
|
+ * Added satype2name prototype.
|
|
+ *
|
|
+ * Revision 1.29 2001/02/26 19:59:33 rgb
|
|
+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
|
|
+ *
|
|
+ * Revision 1.28 2000/10/10 20:10:19 rgb
|
|
+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
|
|
+ *
|
|
+ * Revision 1.27 2000/09/21 04:20:45 rgb
|
|
+ * Fixed array size off-by-one error. (Thanks Svenning!)
|
|
+ *
|
|
+ * Revision 1.26 2000/09/12 03:26:05 rgb
|
|
+ * Added pfkey_acquire prototype.
|
|
+ *
|
|
+ * Revision 1.25 2000/09/08 19:21:28 rgb
|
|
+ * Fix pfkey_prop_build() parameter to be only single indirection.
|
|
+ *
|
|
+ * Revision 1.24 2000/09/01 18:46:42 rgb
|
|
+ * Added a supported algorithms array lists, one per satype and registered
|
|
+ * existing algorithms.
|
|
+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
|
|
+ * list.
|
|
+ *
|
|
+ * Revision 1.23 2000/08/27 01:55:26 rgb
|
|
+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
|
|
+ *
|
|
+ * Revision 1.22 2000/08/20 21:39:23 rgb
|
|
+ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
|
|
+ * pfkey_expire().
|
|
+ *
|
|
+ * Revision 1.21 2000/08/15 17:29:23 rgb
|
|
+ * Fixes from SZI to untested pfkey_prop_build().
|
|
+ *
|
|
+ * Revision 1.20 2000/05/10 20:14:19 rgb
|
|
+ * Fleshed out sensitivity, proposal and supported extensions.
|
|
+ *
|
|
+ * Revision 1.19 2000/03/16 14:07:23 rgb
|
|
+ * Renamed ALIGN macro to avoid fighting with others in kernel.
|
|
+ *
|
|
+ * Revision 1.18 2000/01/22 23:24:06 rgb
|
|
+ * Added prototypes for proto2satype(), satype2proto() and proto2name().
|
|
+ *
|
|
+ * Revision 1.17 2000/01/21 06:26:59 rgb
|
|
+ * Converted from double tdb arguments to one structure (extr)
|
|
+ * containing pointers to all temporary information structures.
|
|
+ * Added klipsdebug switching capability.
|
|
+ * Dropped unused argument to pfkey_x_satype_build().
|
|
+ *
|
|
+ * Revision 1.16 1999/12/29 21:17:41 rgb
|
|
+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
|
|
+ * parameter for cleaner manipulation of extensions[] and to guard
|
|
+ * against potential memory leaks.
|
|
+ * Changed the I/F to pfkey_msg_free() for the same reason.
|
|
+ *
|
|
+ * Revision 1.15 1999/12/09 23:12:54 rgb
|
|
+ * Added macro for BITS_PER_OCTET.
|
|
+ * Added argument to pfkey_sa_build() to do eroutes.
|
|
+ *
|
|
+ * Revision 1.14 1999/12/08 20:33:25 rgb
|
|
+ * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
|
|
+ *
|
|
+ * Revision 1.13 1999/12/07 19:53:40 rgb
|
|
+ * Removed unused first argument from extension parsers.
|
|
+ * Changed __u* types to uint* to avoid use of asm/types.h and
|
|
+ * sys/types.h in userspace code.
|
|
+ * Added function prototypes for pfkey message and extensions
|
|
+ * initialisation and cleanup.
|
|
+ *
|
|
+ * Revision 1.12 1999/12/01 22:19:38 rgb
|
|
+ * Change pfkey_sa_build to accept an SPI in network byte order.
|
|
+ *
|
|
+ * Revision 1.11 1999/11/27 11:55:26 rgb
|
|
+ * Added extern sadb_satype2proto to enable moving protocol lookup table
|
|
+ * to lib/pfkey_v2_parse.c.
|
|
+ * Delete unused, moved typedefs.
|
|
+ * Add argument to pfkey_msg_parse() for direction.
|
|
+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
|
|
+ *
|
|
+ * Revision 1.10 1999/11/23 22:29:21 rgb
|
|
+ * This file has been moved in the distribution from klips/net/ipsec to
|
|
+ * lib.
|
|
+ * Add macros for dealing with alignment and rounding up more opaquely.
|
|
+ * The uint<n>_t type defines have been moved to freeswan.h to avoid
|
|
+ * chicken-and-egg problems.
|
|
+ * Add macros for dealing with alignment and rounding up more opaque.
|
|
+ * Added prototypes for using extention header bitmaps.
|
|
+ * Added prototypes of all the build functions.
|
|
+ *
|
|
+ * Revision 1.9 1999/11/20 21:59:48 rgb
|
|
+ * Moved socketlist type declarations and prototypes for shared use.
|
|
+ * Slightly modified scope of sockaddr_key declaration.
|
|
+ *
|
|
+ * Revision 1.8 1999/11/17 14:34:25 rgb
|
|
+ * Protect sa_family_t from being used in userspace with GLIBC<2.
|
|
+ *
|
|
+ * Revision 1.7 1999/10/27 19:40:35 rgb
|
|
+ * Add a maximum PFKEY packet size macro.
|
|
+ *
|
|
+ * Revision 1.6 1999/10/26 16:58:58 rgb
|
|
+ * Created a sockaddr_key and key_opt socket extension structures.
|
|
+ *
|
|
+ * Revision 1.5 1999/06/10 05:24:41 rgb
|
|
+ * Renamed variables to reduce confusion.
|
|
+ *
|
|
+ * Revision 1.4 1999/04/29 15:21:11 rgb
|
|
+ * Add pfkey support to debugging.
|
|
+ * Add return values to init and cleanup functions.
|
|
+ *
|
|
+ * Revision 1.3 1999/04/15 17:58:07 rgb
|
|
+ * Add RCSID labels.
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/pfkeyv2.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,472 @@
|
|
+/*
|
|
+ * RCSID $Id: pfkeyv2.h,v 1.31 2005/04/14 01:14:54 mcr Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+RFC 2367 PF_KEY Key Management API July 1998
|
|
+
|
|
+
|
|
+Appendix D: Sample Header File
|
|
+
|
|
+This file defines structures and symbols for the PF_KEY Version 2
|
|
+key management interface. It was written at the U.S. Naval Research
|
|
+Laboratory. This file is in the public domain. The authors ask that
|
|
+you leave this credit intact on any copies of this file.
|
|
+*/
|
|
+#ifndef __PFKEY_V2_H
|
|
+#define __PFKEY_V2_H 1
|
|
+
|
|
+#define PF_KEY_V2 2
|
|
+#define PFKEYV2_REVISION 199806L
|
|
+
|
|
+#define SADB_RESERVED 0
|
|
+#define SADB_GETSPI 1
|
|
+#define SADB_UPDATE 2
|
|
+#define SADB_ADD 3
|
|
+#define SADB_DELETE 4
|
|
+#define SADB_GET 5
|
|
+#define SADB_ACQUIRE 6
|
|
+#define SADB_REGISTER 7
|
|
+#define SADB_EXPIRE 8
|
|
+#define SADB_FLUSH 9
|
|
+#define SADB_DUMP 10
|
|
+#define SADB_X_PROMISC 11
|
|
+#define SADB_X_PCHANGE 12
|
|
+#define SADB_X_GRPSA 13
|
|
+#define SADB_X_ADDFLOW 14
|
|
+#define SADB_X_DELFLOW 15
|
|
+#define SADB_X_DEBUG 16
|
|
+#define SADB_X_NAT_T_NEW_MAPPING 17
|
|
+#define SADB_MAX 17
|
|
+
|
|
+struct sadb_msg {
|
|
+ uint8_t sadb_msg_version;
|
|
+ uint8_t sadb_msg_type;
|
|
+ uint8_t sadb_msg_errno;
|
|
+ uint8_t sadb_msg_satype;
|
|
+ uint16_t sadb_msg_len;
|
|
+ uint16_t sadb_msg_reserved;
|
|
+ uint32_t sadb_msg_seq;
|
|
+ uint32_t sadb_msg_pid;
|
|
+};
|
|
+
|
|
+struct sadb_ext {
|
|
+ uint16_t sadb_ext_len;
|
|
+ uint16_t sadb_ext_type;
|
|
+};
|
|
+
|
|
+struct sadb_sa {
|
|
+ uint16_t sadb_sa_len;
|
|
+ uint16_t sadb_sa_exttype;
|
|
+ uint32_t sadb_sa_spi;
|
|
+ uint8_t sadb_sa_replay;
|
|
+ uint8_t sadb_sa_state;
|
|
+ uint8_t sadb_sa_auth;
|
|
+ uint8_t sadb_sa_encrypt;
|
|
+ uint32_t sadb_sa_flags;
|
|
+ uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
|
|
+ uint8_t sadb_x_reserved[4];
|
|
+};
|
|
+
|
|
+struct sadb_sa_v1 {
|
|
+ uint16_t sadb_sa_len;
|
|
+ uint16_t sadb_sa_exttype;
|
|
+ uint32_t sadb_sa_spi;
|
|
+ uint8_t sadb_sa_replay;
|
|
+ uint8_t sadb_sa_state;
|
|
+ uint8_t sadb_sa_auth;
|
|
+ uint8_t sadb_sa_encrypt;
|
|
+ uint32_t sadb_sa_flags;
|
|
+};
|
|
+
|
|
+struct sadb_lifetime {
|
|
+ uint16_t sadb_lifetime_len;
|
|
+ uint16_t sadb_lifetime_exttype;
|
|
+ uint32_t sadb_lifetime_allocations;
|
|
+ uint64_t sadb_lifetime_bytes;
|
|
+ uint64_t sadb_lifetime_addtime;
|
|
+ uint64_t sadb_lifetime_usetime;
|
|
+ uint32_t sadb_x_lifetime_packets;
|
|
+ uint32_t sadb_x_lifetime_reserved;
|
|
+};
|
|
+
|
|
+struct sadb_address {
|
|
+ uint16_t sadb_address_len;
|
|
+ uint16_t sadb_address_exttype;
|
|
+ uint8_t sadb_address_proto;
|
|
+ uint8_t sadb_address_prefixlen;
|
|
+ uint16_t sadb_address_reserved;
|
|
+};
|
|
+
|
|
+struct sadb_key {
|
|
+ uint16_t sadb_key_len;
|
|
+ uint16_t sadb_key_exttype;
|
|
+ uint16_t sadb_key_bits;
|
|
+ uint16_t sadb_key_reserved;
|
|
+};
|
|
+
|
|
+struct sadb_ident {
|
|
+ uint16_t sadb_ident_len;
|
|
+ uint16_t sadb_ident_exttype;
|
|
+ uint16_t sadb_ident_type;
|
|
+ uint16_t sadb_ident_reserved;
|
|
+ uint64_t sadb_ident_id;
|
|
+};
|
|
+
|
|
+struct sadb_sens {
|
|
+ uint16_t sadb_sens_len;
|
|
+ uint16_t sadb_sens_exttype;
|
|
+ uint32_t sadb_sens_dpd;
|
|
+ uint8_t sadb_sens_sens_level;
|
|
+ uint8_t sadb_sens_sens_len;
|
|
+ uint8_t sadb_sens_integ_level;
|
|
+ uint8_t sadb_sens_integ_len;
|
|
+ uint32_t sadb_sens_reserved;
|
|
+};
|
|
+
|
|
+struct sadb_prop {
|
|
+ uint16_t sadb_prop_len;
|
|
+ uint16_t sadb_prop_exttype;
|
|
+ uint8_t sadb_prop_replay;
|
|
+ uint8_t sadb_prop_reserved[3];
|
|
+};
|
|
+
|
|
+struct sadb_comb {
|
|
+ uint8_t sadb_comb_auth;
|
|
+ uint8_t sadb_comb_encrypt;
|
|
+ uint16_t sadb_comb_flags;
|
|
+ uint16_t sadb_comb_auth_minbits;
|
|
+ uint16_t sadb_comb_auth_maxbits;
|
|
+ uint16_t sadb_comb_encrypt_minbits;
|
|
+ uint16_t sadb_comb_encrypt_maxbits;
|
|
+ uint32_t sadb_comb_reserved;
|
|
+ uint32_t sadb_comb_soft_allocations;
|
|
+ uint32_t sadb_comb_hard_allocations;
|
|
+ uint64_t sadb_comb_soft_bytes;
|
|
+ uint64_t sadb_comb_hard_bytes;
|
|
+ uint64_t sadb_comb_soft_addtime;
|
|
+ uint64_t sadb_comb_hard_addtime;
|
|
+ uint64_t sadb_comb_soft_usetime;
|
|
+ uint64_t sadb_comb_hard_usetime;
|
|
+ uint32_t sadb_x_comb_soft_packets;
|
|
+ uint32_t sadb_x_comb_hard_packets;
|
|
+};
|
|
+
|
|
+struct sadb_supported {
|
|
+ uint16_t sadb_supported_len;
|
|
+ uint16_t sadb_supported_exttype;
|
|
+ uint32_t sadb_supported_reserved;
|
|
+};
|
|
+
|
|
+struct sadb_alg {
|
|
+ uint8_t sadb_alg_id;
|
|
+ uint8_t sadb_alg_ivlen;
|
|
+ uint16_t sadb_alg_minbits;
|
|
+ uint16_t sadb_alg_maxbits;
|
|
+ uint16_t sadb_alg_reserved;
|
|
+};
|
|
+
|
|
+struct sadb_spirange {
|
|
+ uint16_t sadb_spirange_len;
|
|
+ uint16_t sadb_spirange_exttype;
|
|
+ uint32_t sadb_spirange_min;
|
|
+ uint32_t sadb_spirange_max;
|
|
+ uint32_t sadb_spirange_reserved;
|
|
+};
|
|
+
|
|
+struct sadb_x_kmprivate {
|
|
+ uint16_t sadb_x_kmprivate_len;
|
|
+ uint16_t sadb_x_kmprivate_exttype;
|
|
+ uint32_t sadb_x_kmprivate_reserved;
|
|
+};
|
|
+
|
|
+struct sadb_x_satype {
|
|
+ uint16_t sadb_x_satype_len;
|
|
+ uint16_t sadb_x_satype_exttype;
|
|
+ uint8_t sadb_x_satype_satype;
|
|
+ uint8_t sadb_x_satype_reserved[3];
|
|
+};
|
|
+
|
|
+struct sadb_x_policy {
|
|
+ uint16_t sadb_x_policy_len;
|
|
+ uint16_t sadb_x_policy_exttype;
|
|
+ uint16_t sadb_x_policy_type;
|
|
+ uint8_t sadb_x_policy_dir;
|
|
+ uint8_t sadb_x_policy_reserved;
|
|
+ uint32_t sadb_x_policy_id;
|
|
+ uint32_t sadb_x_policy_reserved2;
|
|
+};
|
|
+
|
|
+struct sadb_x_debug {
|
|
+ uint16_t sadb_x_debug_len;
|
|
+ uint16_t sadb_x_debug_exttype;
|
|
+ uint32_t sadb_x_debug_tunnel;
|
|
+ uint32_t sadb_x_debug_netlink;
|
|
+ uint32_t sadb_x_debug_xform;
|
|
+ uint32_t sadb_x_debug_eroute;
|
|
+ uint32_t sadb_x_debug_spi;
|
|
+ uint32_t sadb_x_debug_radij;
|
|
+ uint32_t sadb_x_debug_esp;
|
|
+ uint32_t sadb_x_debug_ah;
|
|
+ uint32_t sadb_x_debug_rcv;
|
|
+ uint32_t sadb_x_debug_pfkey;
|
|
+ uint32_t sadb_x_debug_ipcomp;
|
|
+ uint32_t sadb_x_debug_verbose;
|
|
+ uint8_t sadb_x_debug_reserved[4];
|
|
+};
|
|
+
|
|
+struct sadb_x_nat_t_type {
|
|
+ uint16_t sadb_x_nat_t_type_len;
|
|
+ uint16_t sadb_x_nat_t_type_exttype;
|
|
+ uint8_t sadb_x_nat_t_type_type;
|
|
+ uint8_t sadb_x_nat_t_type_reserved[3];
|
|
+};
|
|
+struct sadb_x_nat_t_port {
|
|
+ uint16_t sadb_x_nat_t_port_len;
|
|
+ uint16_t sadb_x_nat_t_port_exttype;
|
|
+ uint16_t sadb_x_nat_t_port_port;
|
|
+ uint16_t sadb_x_nat_t_port_reserved;
|
|
+};
|
|
+
|
|
+/*
|
|
+ * A protocol structure for passing through the transport level
|
|
+ * protocol. It contains more fields than are actually used/needed
|
|
+ * but it is this way to be compatible with the structure used in
|
|
+ * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
|
|
+ */
|
|
+struct sadb_protocol {
|
|
+ uint16_t sadb_protocol_len;
|
|
+ uint16_t sadb_protocol_exttype;
|
|
+ uint8_t sadb_protocol_proto;
|
|
+ uint8_t sadb_protocol_direction;
|
|
+ uint8_t sadb_protocol_flags;
|
|
+ uint8_t sadb_protocol_reserved2;
|
|
+};
|
|
+
|
|
+#define SADB_EXT_RESERVED 0
|
|
+#define SADB_EXT_SA 1
|
|
+#define SADB_EXT_LIFETIME_CURRENT 2
|
|
+#define SADB_EXT_LIFETIME_HARD 3
|
|
+#define SADB_EXT_LIFETIME_SOFT 4
|
|
+#define SADB_EXT_ADDRESS_SRC 5
|
|
+#define SADB_EXT_ADDRESS_DST 6
|
|
+#define SADB_EXT_ADDRESS_PROXY 7
|
|
+#define SADB_EXT_KEY_AUTH 8
|
|
+#define SADB_EXT_KEY_ENCRYPT 9
|
|
+#define SADB_EXT_IDENTITY_SRC 10
|
|
+#define SADB_EXT_IDENTITY_DST 11
|
|
+#define SADB_EXT_SENSITIVITY 12
|
|
+#define SADB_EXT_PROPOSAL 13
|
|
+#define SADB_EXT_SUPPORTED_AUTH 14
|
|
+#define SADB_EXT_SUPPORTED_ENCRYPT 15
|
|
+#define SADB_EXT_SPIRANGE 16
|
|
+#define SADB_X_EXT_KMPRIVATE 17
|
|
+#define SADB_X_EXT_SATYPE2 18
|
|
+#ifdef KERNEL26_HAS_KAME_DUPLICATES
|
|
+#define SADB_X_EXT_POLICY 18
|
|
+#endif
|
|
+#define SADB_X_EXT_SA2 19
|
|
+#define SADB_X_EXT_ADDRESS_DST2 20
|
|
+#define SADB_X_EXT_ADDRESS_SRC_FLOW 21
|
|
+#define SADB_X_EXT_ADDRESS_DST_FLOW 22
|
|
+#define SADB_X_EXT_ADDRESS_SRC_MASK 23
|
|
+#define SADB_X_EXT_ADDRESS_DST_MASK 24
|
|
+#define SADB_X_EXT_DEBUG 25
|
|
+#define SADB_X_EXT_PROTOCOL 26
|
|
+#define SADB_X_EXT_NAT_T_TYPE 27
|
|
+#define SADB_X_EXT_NAT_T_SPORT 28
|
|
+#define SADB_X_EXT_NAT_T_DPORT 29
|
|
+#define SADB_X_EXT_NAT_T_OA 30
|
|
+#define SADB_EXT_MAX 30
|
|
+
|
|
+/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
|
|
+#define SADB_X_EXT_ADDRESS_DELFLOW \
|
|
+ ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
|
|
+ | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
|
|
+ | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
|
|
+ | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
|
|
+
|
|
+#define SADB_SATYPE_UNSPEC 0
|
|
+#define SADB_SATYPE_AH 2
|
|
+#define SADB_SATYPE_ESP 3
|
|
+#define SADB_SATYPE_RSVP 5
|
|
+#define SADB_SATYPE_OSPFV2 6
|
|
+#define SADB_SATYPE_RIPV2 7
|
|
+#define SADB_SATYPE_MIP 8
|
|
+#define SADB_X_SATYPE_IPIP 9
|
|
+#ifdef KERNEL26_HAS_KAME_DUPLICATES
|
|
+#define SADB_X_SATYPE_IPCOMP 9 /* ICK! */
|
|
+#endif
|
|
+#define SADB_X_SATYPE_COMP 10
|
|
+#define SADB_X_SATYPE_INT 11
|
|
+#define SADB_SATYPE_MAX 11
|
|
+
|
|
+enum sadb_sastate {
|
|
+ SADB_SASTATE_LARVAL=0,
|
|
+ SADB_SASTATE_MATURE=1,
|
|
+ SADB_SASTATE_DYING=2,
|
|
+ SADB_SASTATE_DEAD=3
|
|
+};
|
|
+#define SADB_SASTATE_MAX 3
|
|
+
|
|
+#define SADB_SAFLAGS_PFS 1
|
|
+#define SADB_X_SAFLAGS_REPLACEFLOW 2
|
|
+#define SADB_X_SAFLAGS_CLEARFLOW 4
|
|
+#define SADB_X_SAFLAGS_INFLOW 8
|
|
+
|
|
+/* not obvious, but these are the same values as used in isakmp,
|
|
+ * and in freeswan/ipsec_policy.h. If you need to add any, they
|
|
+ * should be added as according to
|
|
+ * http://www.iana.org/assignments/isakmp-registry
|
|
+ *
|
|
+ * and if not, then please try to use a private-use value, and
|
|
+ * consider asking IANA to assign a value.
|
|
+ */
|
|
+#define SADB_AALG_NONE 0
|
|
+#define SADB_AALG_MD5HMAC 2
|
|
+#define SADB_AALG_SHA1HMAC 3
|
|
+#define SADB_X_AALG_SHA2_256HMAC 5
|
|
+#define SADB_X_AALG_SHA2_384HMAC 6
|
|
+#define SADB_X_AALG_SHA2_512HMAC 7
|
|
+#define SADB_X_AALG_RIPEMD160HMAC 8
|
|
+#define SADB_X_AALG_NULL 251 /* kame */
|
|
+#define SADB_AALG_MAX 251
|
|
+
|
|
+#define SADB_EALG_NONE 0
|
|
+#define SADB_EALG_DESCBC 2
|
|
+#define SADB_EALG_3DESCBC 3
|
|
+#define SADB_X_EALG_CASTCBC 6
|
|
+#define SADB_X_EALG_BLOWFISHCBC 7
|
|
+#define SADB_EALG_NULL 11
|
|
+#define SADB_X_EALG_AESCBC 12
|
|
+#define SADB_EALG_MAX 255
|
|
+
|
|
+#define SADB_X_CALG_NONE 0
|
|
+#define SADB_X_CALG_OUI 1
|
|
+#define SADB_X_CALG_DEFLATE 2
|
|
+#define SADB_X_CALG_LZS 3
|
|
+#define SADB_X_CALG_V42BIS 4
|
|
+#ifdef KERNEL26_HAS_KAME_DUPLICATES
|
|
+#define SADB_X_CALG_LZJH 4
|
|
+#endif
|
|
+#define SADB_X_CALG_MAX 4
|
|
+
|
|
+#define SADB_X_TALG_NONE 0
|
|
+#define SADB_X_TALG_IPv4_in_IPv4 1
|
|
+#define SADB_X_TALG_IPv6_in_IPv4 2
|
|
+#define SADB_X_TALG_IPv4_in_IPv6 3
|
|
+#define SADB_X_TALG_IPv6_in_IPv6 4
|
|
+#define SADB_X_TALG_MAX 4
|
|
+
|
|
+
|
|
+#define SADB_IDENTTYPE_RESERVED 0
|
|
+#define SADB_IDENTTYPE_PREFIX 1
|
|
+#define SADB_IDENTTYPE_FQDN 2
|
|
+#define SADB_IDENTTYPE_USERFQDN 3
|
|
+#define SADB_X_IDENTTYPE_CONNECTION 4
|
|
+#define SADB_IDENTTYPE_MAX 4
|
|
+
|
|
+#define SADB_KEY_FLAGS_MAX 0
|
|
+#endif /* __PFKEY_V2_H */
|
|
+
|
|
+/*
|
|
+ * $Log: pfkeyv2.h,v $
|
|
+ * Revision 1.31 2005/04/14 01:14:54 mcr
|
|
+ * change sadb_state to an enum.
|
|
+ *
|
|
+ * Revision 1.30 2004/04/06 02:49:00 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.29 2003/12/22 21:35:58 mcr
|
|
+ * new patches from Dr{Who}.
|
|
+ *
|
|
+ * Revision 1.28 2003/12/22 19:33:15 mcr
|
|
+ * added 0.6c NAT-T patch.
|
|
+ *
|
|
+ * Revision 1.27 2003/12/10 01:20:01 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.26 2003/10/31 02:26:44 mcr
|
|
+ * pulled up port-selector patches.
|
|
+ *
|
|
+ * Revision 1.25.4.1 2003/09/21 13:59:34 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.25 2003/07/31 23:59:17 mcr
|
|
+ * re-introduce kernel 2.6 duplicate values for now.
|
|
+ * hope to get them changed!
|
|
+ *
|
|
+ * Revision 1.24 2003/07/31 22:55:27 mcr
|
|
+ * added some definitions to keep pfkeyv2.h files in sync.
|
|
+ *
|
|
+ * Revision 1.23 2003/05/11 00:43:48 mcr
|
|
+ * added comment about origin of values used
|
|
+ *
|
|
+ * Revision 1.22 2003/01/30 02:31:34 rgb
|
|
+ *
|
|
+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
|
|
+ *
|
|
+ * Revision 1.21 2002/12/16 19:26:49 mcr
|
|
+ * added definition of FS 1.xx sadb structure
|
|
+ *
|
|
+ * Revision 1.20 2002/09/20 15:40:25 rgb
|
|
+ * Added sadb_x_sa_ref to struct sadb_sa.
|
|
+ *
|
|
+ * Revision 1.19 2002/04/24 07:36:49 mcr
|
|
+ * Moved from ./lib/pfkeyv2.h,v
|
|
+ *
|
|
+ * Revision 1.18 2001/11/06 19:47:47 rgb
|
|
+ * Added packet parameter to lifetime and comb structures.
|
|
+ *
|
|
+ * Revision 1.17 2001/09/08 21:13:35 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.16 2001/07/06 19:49:46 rgb
|
|
+ * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks.
|
|
+ *
|
|
+ * Revision 1.15 2001/02/26 20:00:43 rgb
|
|
+ * Added internal IP protocol 61 for magic SAs.
|
|
+ *
|
|
+ * Revision 1.14 2001/02/08 18:51:05 rgb
|
|
+ * Include RFC document title and appendix subsection title.
|
|
+ *
|
|
+ * Revision 1.13 2000/10/10 20:10:20 rgb
|
|
+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
|
|
+ *
|
|
+ * Revision 1.12 2000/09/15 06:41:50 rgb
|
|
+ * Added V42BIS constant.
|
|
+ *
|
|
+ * Revision 1.11 2000/09/12 22:35:37 rgb
|
|
+ * Restructured to remove unused extensions from CLEARFLOW messages.
|
|
+ *
|
|
+ * Revision 1.10 2000/09/12 18:50:09 rgb
|
|
+ * Added IPIP tunnel types as algo support.
|
|
+ *
|
|
+ * Revision 1.9 2000/08/21 16:47:19 rgb
|
|
+ * Added SADB_X_CALG_* macros for IPCOMP.
|
|
+ *
|
|
+ * Revision 1.8 2000/08/09 20:43:34 rgb
|
|
+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
|
|
+ *
|
|
+ * Revision 1.7 2000/01/21 06:28:37 rgb
|
|
+ * Added flow add/delete message type macros.
|
|
+ * Added flow address extension type macros.
|
|
+ * Tidied up spacing.
|
|
+ * Added klipsdebug switching capability.
|
|
+ *
|
|
+ * Revision 1.6 1999/11/27 11:56:08 rgb
|
|
+ * Add SADB_X_SATYPE_COMP for compression, eventually.
|
|
+ *
|
|
+ * Revision 1.5 1999/11/23 22:23:16 rgb
|
|
+ * This file has been moved in the distribution from klips/net/ipsec to
|
|
+ * lib.
|
|
+ *
|
|
+ * Revision 1.4 1999/04/29 15:23:29 rgb
|
|
+ * Add GRPSA support.
|
|
+ * Add support for a second SATYPE, SA and DST_ADDRESS.
|
|
+ * Add IPPROTO_IPIP support.
|
|
+ *
|
|
+ * Revision 1.3 1999/04/15 17:58:08 rgb
|
|
+ * Add RCSID labels.
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/zlib/zconf.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,309 @@
|
|
+/* zconf.h -- configuration of the zlib compression library
|
|
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* @(#) $Id: zconf.h,v 1.4 2004/07/10 07:48:40 mcr Exp $ */
|
|
+
|
|
+#ifndef _ZCONF_H
|
|
+#define _ZCONF_H
|
|
+
|
|
+/*
|
|
+ * If you *really* need a unique prefix for all types and library functions,
|
|
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
|
+ */
|
|
+#ifdef IPCOMP_PREFIX
|
|
+# define deflateInit_ ipcomp_deflateInit_
|
|
+# define deflate ipcomp_deflate
|
|
+# define deflateEnd ipcomp_deflateEnd
|
|
+# define inflateInit_ ipcomp_inflateInit_
|
|
+# define inflate ipcomp_inflate
|
|
+# define inflateEnd ipcomp_inflateEnd
|
|
+# define deflateInit2_ ipcomp_deflateInit2_
|
|
+# define deflateSetDictionary ipcomp_deflateSetDictionary
|
|
+# define deflateCopy ipcomp_deflateCopy
|
|
+# define deflateReset ipcomp_deflateReset
|
|
+# define deflateParams ipcomp_deflateParams
|
|
+# define inflateInit2_ ipcomp_inflateInit2_
|
|
+# define inflateSetDictionary ipcomp_inflateSetDictionary
|
|
+# define inflateSync ipcomp_inflateSync
|
|
+# define inflateSyncPoint ipcomp_inflateSyncPoint
|
|
+# define inflateReset ipcomp_inflateReset
|
|
+# define compress ipcomp_compress
|
|
+# define compress2 ipcomp_compress2
|
|
+# define uncompress ipcomp_uncompress
|
|
+# define adler32 ipcomp_adler32
|
|
+# define crc32 ipcomp_crc32
|
|
+# define get_crc_table ipcomp_get_crc_table
|
|
+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
|
|
+# define inflate_blocks ipcomp_deflate_blocks
|
|
+# define inflate_blocks_free ipcomp_deflate_blocks_free
|
|
+# define inflate_blocks_new ipcomp_inflate_blocks_new
|
|
+# define inflate_blocks_reset ipcomp_inflate_blocks_reset
|
|
+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
|
|
+# define inflate_set_dictionary ipcomp_inflate_set_dictionary
|
|
+# define inflate_codes ipcomp_inflate_codes
|
|
+# define inflate_codes_free ipcomp_inflate_codes_free
|
|
+# define inflate_codes_new ipcomp_inflate_codes_new
|
|
+# define inflate_fast ipcomp_inflate_fast
|
|
+# define inflate_trees_bits ipcomp_inflate_trees_bits
|
|
+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
|
|
+# define inflate_trees_fixed ipcomp_inflate_trees_fixed
|
|
+# define inflate_flush ipcomp_inflate_flush
|
|
+# define inflate_mask ipcomp_inflate_mask
|
|
+# define _dist_code _ipcomp_dist_code
|
|
+# define _length_code _ipcomp_length_code
|
|
+# define _tr_align _ipcomp_tr_align
|
|
+# define _tr_flush_block _ipcomp_tr_flush_block
|
|
+# define _tr_init _ipcomp_tr_init
|
|
+# define _tr_stored_block _ipcomp_tr_stored_block
|
|
+# define _tr_tally _ipcomp_tr_tally
|
|
+# define zError ipcomp_zError
|
|
+# define z_errmsg ipcomp_z_errmsg
|
|
+# define zlibVersion ipcomp_zlibVersion
|
|
+# define match_init ipcomp_match_init
|
|
+# define longest_match ipcomp_longest_match
|
|
+#endif
|
|
+
|
|
+#ifdef Z_PREFIX
|
|
+# define Byte z_Byte
|
|
+# define uInt z_uInt
|
|
+# define uLong z_uLong
|
|
+# define Bytef z_Bytef
|
|
+# define charf z_charf
|
|
+# define intf z_intf
|
|
+# define uIntf z_uIntf
|
|
+# define uLongf z_uLongf
|
|
+# define voidpf z_voidpf
|
|
+# define voidp z_voidp
|
|
+#endif
|
|
+
|
|
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
|
+# define WIN32
|
|
+#endif
|
|
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
|
|
+# ifndef __32BIT__
|
|
+# define __32BIT__
|
|
+# endif
|
|
+#endif
|
|
+#if defined(__MSDOS__) && !defined(MSDOS)
|
|
+# define MSDOS
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
|
+ * than 64k bytes at a time (needed on systems with 16-bit int).
|
|
+ */
|
|
+#if defined(MSDOS) && !defined(__32BIT__)
|
|
+# define MAXSEG_64K
|
|
+#endif
|
|
+#ifdef MSDOS
|
|
+# define UNALIGNED_OK
|
|
+#endif
|
|
+
|
|
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
|
|
+# define STDC
|
|
+#endif
|
|
+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
|
|
+# ifndef STDC
|
|
+# define STDC
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+#ifndef STDC
|
|
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
|
+# define const
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+/* Some Mac compilers merge all .h files incorrectly: */
|
|
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
|
|
+# define NO_DUMMY_DECL
|
|
+#endif
|
|
+
|
|
+/* Old Borland C incorrectly complains about missing returns: */
|
|
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
|
|
+# define NEED_DUMMY_RETURN
|
|
+#endif
|
|
+
|
|
+
|
|
+/* Maximum value for memLevel in deflateInit2 */
|
|
+#ifndef MAX_MEM_LEVEL
|
|
+# ifdef MAXSEG_64K
|
|
+# define MAX_MEM_LEVEL 8
|
|
+# else
|
|
+# define MAX_MEM_LEVEL 9
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
|
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
|
+ * created by gzip. (Files created by minigzip can still be extracted by
|
|
+ * gzip.)
|
|
+ */
|
|
+#ifndef MAX_WBITS
|
|
+# define MAX_WBITS 15 /* 32K LZ77 window */
|
|
+#endif
|
|
+
|
|
+/* The memory requirements for deflate are (in bytes):
|
|
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
|
|
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
|
+ plus a few kilobytes for small objects. For example, if you want to reduce
|
|
+ the default memory requirements from 256K to 128K, compile with
|
|
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
|
+ Of course this will generally degrade compression (there's no free lunch).
|
|
+
|
|
+ The memory requirements for inflate are (in bytes) 1 << windowBits
|
|
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
|
+ for small objects.
|
|
+*/
|
|
+
|
|
+ /* Type declarations */
|
|
+
|
|
+#ifndef OF /* function prototypes */
|
|
+# ifdef STDC
|
|
+# define OF(args) args
|
|
+# else
|
|
+# define OF(args) ()
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+/* The following definitions for FAR are needed only for MSDOS mixed
|
|
+ * model programming (small or medium model with some far allocations).
|
|
+ * This was tested only with MSC; for other MSDOS compilers you may have
|
|
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
|
+ * just define FAR to be empty.
|
|
+ */
|
|
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
|
|
+ /* MSC small or medium model */
|
|
+# define SMALL_MEDIUM
|
|
+# ifdef _MSC_VER
|
|
+# define FAR _far
|
|
+# else
|
|
+# define FAR far
|
|
+# endif
|
|
+#endif
|
|
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
|
|
+# ifndef __32BIT__
|
|
+# define SMALL_MEDIUM
|
|
+# define FAR _far
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+/* Compile with -DZLIB_DLL for Windows DLL support */
|
|
+#if defined(ZLIB_DLL)
|
|
+# if defined(_WINDOWS) || defined(WINDOWS)
|
|
+# ifdef FAR
|
|
+# undef FAR
|
|
+# endif
|
|
+# include <windows.h>
|
|
+# define ZEXPORT WINAPI
|
|
+# ifdef WIN32
|
|
+# define ZEXPORTVA WINAPIV
|
|
+# else
|
|
+# define ZEXPORTVA FAR _cdecl _export
|
|
+# endif
|
|
+# endif
|
|
+# if defined (__BORLANDC__)
|
|
+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
|
|
+# include <windows.h>
|
|
+# define ZEXPORT __declspec(dllexport) WINAPI
|
|
+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
|
|
+# else
|
|
+# if defined (_Windows) && defined (__DLL__)
|
|
+# define ZEXPORT _export
|
|
+# define ZEXPORTVA _export
|
|
+# endif
|
|
+# endif
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+#if defined (__BEOS__)
|
|
+# if defined (ZLIB_DLL)
|
|
+# define ZEXTERN extern __declspec(dllexport)
|
|
+# else
|
|
+# define ZEXTERN extern __declspec(dllimport)
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+#ifndef ZEXPORT
|
|
+# define ZEXPORT
|
|
+#endif
|
|
+#ifndef ZEXPORTVA
|
|
+# define ZEXPORTVA
|
|
+#endif
|
|
+#ifndef ZEXTERN
|
|
+# define ZEXTERN extern
|
|
+#endif
|
|
+
|
|
+#ifndef FAR
|
|
+# define FAR
|
|
+#endif
|
|
+
|
|
+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
|
|
+typedef unsigned char Byte; /* 8 bits */
|
|
+#endif
|
|
+typedef unsigned int uInt; /* 16 bits or more */
|
|
+typedef unsigned long uLong; /* 32 bits or more */
|
|
+
|
|
+#ifdef SMALL_MEDIUM
|
|
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
|
+# define Bytef Byte FAR
|
|
+#else
|
|
+ typedef Byte FAR Bytef;
|
|
+#endif
|
|
+typedef char FAR charf;
|
|
+typedef int FAR intf;
|
|
+typedef uInt FAR uIntf;
|
|
+typedef uLong FAR uLongf;
|
|
+
|
|
+#ifdef STDC
|
|
+ typedef void FAR *voidpf;
|
|
+ typedef void *voidp;
|
|
+#else
|
|
+ typedef Byte FAR *voidpf;
|
|
+ typedef Byte *voidp;
|
|
+#endif
|
|
+
|
|
+#ifdef HAVE_UNISTD_H
|
|
+# include <sys/types.h> /* for off_t */
|
|
+# include <unistd.h> /* for SEEK_* and off_t */
|
|
+# define z_off_t off_t
|
|
+#endif
|
|
+#ifndef SEEK_SET
|
|
+# define SEEK_SET 0 /* Seek from beginning of file. */
|
|
+# define SEEK_CUR 1 /* Seek from current position. */
|
|
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
|
+#endif
|
|
+#ifndef z_off_t
|
|
+# define z_off_t long
|
|
+#endif
|
|
+
|
|
+/* MVS linker does not support external names larger than 8 bytes */
|
|
+#if defined(__MVS__)
|
|
+# pragma map(deflateInit_,"DEIN")
|
|
+# pragma map(deflateInit2_,"DEIN2")
|
|
+# pragma map(deflateEnd,"DEEND")
|
|
+# pragma map(inflateInit_,"ININ")
|
|
+# pragma map(inflateInit2_,"ININ2")
|
|
+# pragma map(inflateEnd,"INEND")
|
|
+# pragma map(inflateSync,"INSY")
|
|
+# pragma map(inflateSetDictionary,"INSEDI")
|
|
+# pragma map(inflate_blocks,"INBL")
|
|
+# pragma map(inflate_blocks_new,"INBLNE")
|
|
+# pragma map(inflate_blocks_free,"INBLFR")
|
|
+# pragma map(inflate_blocks_reset,"INBLRE")
|
|
+# pragma map(inflate_codes_free,"INCOFR")
|
|
+# pragma map(inflate_codes,"INCO")
|
|
+# pragma map(inflate_fast,"INFA")
|
|
+# pragma map(inflate_flush,"INFLU")
|
|
+# pragma map(inflate_mask,"INMA")
|
|
+# pragma map(inflate_set_dictionary,"INSEDI2")
|
|
+# pragma map(ipcomp_inflate_copyright,"INCOPY")
|
|
+# pragma map(inflate_trees_bits,"INTRBI")
|
|
+# pragma map(inflate_trees_dynamic,"INTRDY")
|
|
+# pragma map(inflate_trees_fixed,"INTRFI")
|
|
+# pragma map(inflate_trees_free,"INTRFR")
|
|
+#endif
|
|
+
|
|
+#endif /* _ZCONF_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,893 @@
|
|
+/* zlib.h -- interface of the 'zlib' general purpose compression library
|
|
+ version 1.1.4, March 11th, 2002
|
|
+
|
|
+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
|
|
+
|
|
+ This software is provided 'as-is', without any express or implied
|
|
+ warranty. In no event will the authors be held liable for any damages
|
|
+ arising from the use of this software.
|
|
+
|
|
+ Permission is granted to anyone to use this software for any purpose,
|
|
+ including commercial applications, and to alter it and redistribute it
|
|
+ freely, subject to the following restrictions:
|
|
+
|
|
+ 1. The origin of this software must not be misrepresented; you must not
|
|
+ claim that you wrote the original software. If you use this software
|
|
+ in a product, an acknowledgment in the product documentation would be
|
|
+ appreciated but is not required.
|
|
+ 2. Altered source versions must be plainly marked as such, and must not be
|
|
+ misrepresented as being the original software.
|
|
+ 3. This notice may not be removed or altered from any source distribution.
|
|
+
|
|
+ Jean-loup Gailly Mark Adler
|
|
+ jloup@gzip.org madler@alumni.caltech.edu
|
|
+
|
|
+
|
|
+ The data format used by the zlib library is described by RFCs (Request for
|
|
+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
|
|
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
|
+*/
|
|
+
|
|
+#ifndef _ZLIB_H
|
|
+#define _ZLIB_H
|
|
+
|
|
+#include "zconf.h"
|
|
+
|
|
+#ifdef __cplusplus
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+#define ZLIB_VERSION "1.1.4"
|
|
+
|
|
+/*
|
|
+ The 'zlib' compression library provides in-memory compression and
|
|
+ decompression functions, including integrity checks of the uncompressed
|
|
+ data. This version of the library supports only one compression method
|
|
+ (deflation) but other algorithms will be added later and will have the same
|
|
+ stream interface.
|
|
+
|
|
+ Compression can be done in a single step if the buffers are large
|
|
+ enough (for example if an input file is mmap'ed), or can be done by
|
|
+ repeated calls of the compression function. In the latter case, the
|
|
+ application must provide more input and/or consume the output
|
|
+ (providing more output space) before each call.
|
|
+
|
|
+ The library also supports reading and writing files in gzip (.gz) format
|
|
+ with an interface similar to that of stdio.
|
|
+
|
|
+ The library does not install any signal handler. The decoder checks
|
|
+ the consistency of the compressed data, so the library should never
|
|
+ crash even in case of corrupted input.
|
|
+*/
|
|
+
|
|
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
|
|
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
|
|
+
|
|
+struct internal_state;
|
|
+
|
|
+typedef struct z_stream_s {
|
|
+ Bytef *next_in; /* next input byte */
|
|
+ uInt avail_in; /* number of bytes available at next_in */
|
|
+ uLong total_in; /* total nb of input bytes read so far */
|
|
+
|
|
+ Bytef *next_out; /* next output byte should be put there */
|
|
+ uInt avail_out; /* remaining free space at next_out */
|
|
+ uLong total_out; /* total nb of bytes output so far */
|
|
+
|
|
+ const char *msg; /* last error message, NULL if no error */
|
|
+ struct internal_state FAR *state; /* not visible by applications */
|
|
+
|
|
+ alloc_func zalloc; /* used to allocate the internal state */
|
|
+ free_func zfree; /* used to free the internal state */
|
|
+ voidpf opaque; /* private data object passed to zalloc and zfree */
|
|
+
|
|
+ int data_type; /* best guess about the data type: ascii or binary */
|
|
+ uLong adler; /* adler32 value of the uncompressed data */
|
|
+ uLong reserved; /* reserved for future use */
|
|
+} z_stream;
|
|
+
|
|
+typedef z_stream FAR *z_streamp;
|
|
+
|
|
+/*
|
|
+ The application must update next_in and avail_in when avail_in has
|
|
+ dropped to zero. It must update next_out and avail_out when avail_out
|
|
+ has dropped to zero. The application must initialize zalloc, zfree and
|
|
+ opaque before calling the init function. All other fields are set by the
|
|
+ compression library and must not be updated by the application.
|
|
+
|
|
+ The opaque value provided by the application will be passed as the first
|
|
+ parameter for calls of zalloc and zfree. This can be useful for custom
|
|
+ memory management. The compression library attaches no meaning to the
|
|
+ opaque value.
|
|
+
|
|
+ zalloc must return Z_NULL if there is not enough memory for the object.
|
|
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
|
|
+ thread safe.
|
|
+
|
|
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
|
|
+ exactly 65536 bytes, but will not be required to allocate more than this
|
|
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
|
|
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
|
|
+ have their offset normalized to zero. The default allocation function
|
|
+ provided by this library ensures this (see zutil.c). To reduce memory
|
|
+ requirements and avoid any allocation of 64K objects, at the expense of
|
|
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
|
|
+
|
|
+ The fields total_in and total_out can be used for statistics or
|
|
+ progress reports. After compression, total_in holds the total size of
|
|
+ the uncompressed data and may be saved for use in the decompressor
|
|
+ (particularly if the decompressor wants to decompress everything in
|
|
+ a single step).
|
|
+*/
|
|
+
|
|
+ /* constants */
|
|
+
|
|
+#define Z_NO_FLUSH 0
|
|
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
|
|
+#define Z_SYNC_FLUSH 2
|
|
+#define Z_FULL_FLUSH 3
|
|
+#define Z_FINISH 4
|
|
+/* Allowed flush values; see deflate() below for details */
|
|
+
|
|
+#define Z_OK 0
|
|
+#define Z_STREAM_END 1
|
|
+#define Z_NEED_DICT 2
|
|
+#define Z_ERRNO (-1)
|
|
+#define Z_STREAM_ERROR (-2)
|
|
+#define Z_DATA_ERROR (-3)
|
|
+#define Z_MEM_ERROR (-4)
|
|
+#define Z_BUF_ERROR (-5)
|
|
+#define Z_VERSION_ERROR (-6)
|
|
+/* Return codes for the compression/decompression functions. Negative
|
|
+ * values are errors, positive values are used for special but normal events.
|
|
+ */
|
|
+
|
|
+#define Z_NO_COMPRESSION 0
|
|
+#define Z_BEST_SPEED 1
|
|
+#define Z_BEST_COMPRESSION 9
|
|
+#define Z_DEFAULT_COMPRESSION (-1)
|
|
+/* compression levels */
|
|
+
|
|
+#define Z_FILTERED 1
|
|
+#define Z_HUFFMAN_ONLY 2
|
|
+#define Z_DEFAULT_STRATEGY 0
|
|
+/* compression strategy; see deflateInit2() below for details */
|
|
+
|
|
+#define Z_BINARY 0
|
|
+#define Z_ASCII 1
|
|
+#define Z_UNKNOWN 2
|
|
+/* Possible values of the data_type field */
|
|
+
|
|
+#define Z_DEFLATED 8
|
|
+/* The deflate compression method (the only one supported in this version) */
|
|
+
|
|
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
|
|
+
|
|
+#define zlib_version zlibVersion()
|
|
+/* for compatibility with versions < 1.0.2 */
|
|
+
|
|
+ /* basic functions */
|
|
+
|
|
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
|
|
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
|
|
+ If the first character differs, the library code actually used is
|
|
+ not compatible with the zlib.h header file used by the application.
|
|
+ This check is automatically made by deflateInit and inflateInit.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
|
|
+
|
|
+ Initializes the internal stream state for compression. The fields
|
|
+ zalloc, zfree and opaque must be initialized before by the caller.
|
|
+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
|
|
+ use default allocation functions.
|
|
+
|
|
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
|
|
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
|
|
+ all (the input data is simply copied a block at a time).
|
|
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
|
|
+ compression (currently equivalent to level 6).
|
|
+
|
|
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
|
|
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
|
|
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
|
|
+ with the version assumed by the caller (ZLIB_VERSION).
|
|
+ msg is set to null if there is no error message. deflateInit does not
|
|
+ perform any compression: this will be done by deflate().
|
|
+*/
|
|
+
|
|
+
|
|
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
|
+/*
|
|
+ deflate compresses as much data as possible, and stops when the input
|
|
+ buffer becomes empty or the output buffer becomes full. It may introduce some
|
|
+ output latency (reading input without producing any output) except when
|
|
+ forced to flush.
|
|
+
|
|
+ The detailed semantics are as follows. deflate performs one or both of the
|
|
+ following actions:
|
|
+
|
|
+ - Compress more input starting at next_in and update next_in and avail_in
|
|
+ accordingly. If not all input can be processed (because there is not
|
|
+ enough room in the output buffer), next_in and avail_in are updated and
|
|
+ processing will resume at this point for the next call of deflate().
|
|
+
|
|
+ - Provide more output starting at next_out and update next_out and avail_out
|
|
+ accordingly. This action is forced if the parameter flush is non zero.
|
|
+ Forcing flush frequently degrades the compression ratio, so this parameter
|
|
+ should be set only when necessary (in interactive applications).
|
|
+ Some output may be provided even if flush is not set.
|
|
+
|
|
+ Before the call of deflate(), the application should ensure that at least
|
|
+ one of the actions is possible, by providing more input and/or consuming
|
|
+ more output, and updating avail_in or avail_out accordingly; avail_out
|
|
+ should never be zero before the call. The application can consume the
|
|
+ compressed output when it wants, for example when the output buffer is full
|
|
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
|
|
+ and with zero avail_out, it must be called again after making room in the
|
|
+ output buffer because there might be more output pending.
|
|
+
|
|
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
|
|
+ flushed to the output buffer and the output is aligned on a byte boundary, so
|
|
+ that the decompressor can get all input data available so far. (In particular
|
|
+ avail_in is zero after the call if enough output space has been provided
|
|
+ before the call.) Flushing may degrade compression for some compression
|
|
+ algorithms and so it should be used only when necessary.
|
|
+
|
|
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
|
|
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
|
|
+ restart from this point if previous compressed data has been damaged or if
|
|
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
|
|
+ the compression.
|
|
+
|
|
+ If deflate returns with avail_out == 0, this function must be called again
|
|
+ with the same value of the flush parameter and more output space (updated
|
|
+ avail_out), until the flush is complete (deflate returns with non-zero
|
|
+ avail_out).
|
|
+
|
|
+ If the parameter flush is set to Z_FINISH, pending input is processed,
|
|
+ pending output is flushed and deflate returns with Z_STREAM_END if there
|
|
+ was enough output space; if deflate returns with Z_OK, this function must be
|
|
+ called again with Z_FINISH and more output space (updated avail_out) but no
|
|
+ more input data, until it returns with Z_STREAM_END or an error. After
|
|
+ deflate has returned Z_STREAM_END, the only possible operations on the
|
|
+ stream are deflateReset or deflateEnd.
|
|
+
|
|
+ Z_FINISH can be used immediately after deflateInit if all the compression
|
|
+ is to be done in a single step. In this case, avail_out must be at least
|
|
+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
|
|
+ Z_STREAM_END, then it must be called again as described above.
|
|
+
|
|
+ deflate() sets strm->adler to the adler32 checksum of all input read
|
|
+ so far (that is, total_in bytes).
|
|
+
|
|
+ deflate() may update data_type if it can make a good guess about
|
|
+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
|
|
+ binary. This field is only for information purposes and does not affect
|
|
+ the compression algorithm in any manner.
|
|
+
|
|
+ deflate() returns Z_OK if some progress has been made (more input
|
|
+ processed or more output produced), Z_STREAM_END if all input has been
|
|
+ consumed and all output has been produced (only when flush is set to
|
|
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
|
|
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
|
|
+ (for example avail_in or avail_out was zero).
|
|
+*/
|
|
+
|
|
+
|
|
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
|
|
+/*
|
|
+ All dynamically allocated data structures for this stream are freed.
|
|
+ This function discards any unprocessed input and does not flush any
|
|
+ pending output.
|
|
+
|
|
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
|
|
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
|
|
+ prematurely (some input or output was discarded). In the error case,
|
|
+ msg may be set but then points to a static string (which must not be
|
|
+ deallocated).
|
|
+*/
|
|
+
|
|
+
|
|
+/*
|
|
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
|
|
+
|
|
+ Initializes the internal stream state for decompression. The fields
|
|
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
|
|
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
|
|
+ value depends on the compression method), inflateInit determines the
|
|
+ compression method from the zlib header and allocates all data structures
|
|
+ accordingly; otherwise the allocation will be deferred to the first call of
|
|
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
|
|
+ use default allocation functions.
|
|
+
|
|
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
|
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
|
|
+ version assumed by the caller. msg is set to null if there is no error
|
|
+ message. inflateInit does not perform any decompression apart from reading
|
|
+ the zlib header if present: this will be done by inflate(). (So next_in and
|
|
+ avail_in may be modified, but next_out and avail_out are unchanged.)
|
|
+*/
|
|
+
|
|
+
|
|
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
|
+/*
|
|
+ inflate decompresses as much data as possible, and stops when the input
|
|
+ buffer becomes empty or the output buffer becomes full. It may some
|
|
+ introduce some output latency (reading input without producing any output)
|
|
+ except when forced to flush.
|
|
+
|
|
+ The detailed semantics are as follows. inflate performs one or both of the
|
|
+ following actions:
|
|
+
|
|
+ - Decompress more input starting at next_in and update next_in and avail_in
|
|
+ accordingly. If not all input can be processed (because there is not
|
|
+ enough room in the output buffer), next_in is updated and processing
|
|
+ will resume at this point for the next call of inflate().
|
|
+
|
|
+ - Provide more output starting at next_out and update next_out and avail_out
|
|
+ accordingly. inflate() provides as much output as possible, until there
|
|
+ is no more input data or no more space in the output buffer (see below
|
|
+ about the flush parameter).
|
|
+
|
|
+ Before the call of inflate(), the application should ensure that at least
|
|
+ one of the actions is possible, by providing more input and/or consuming
|
|
+ more output, and updating the next_* and avail_* values accordingly.
|
|
+ The application can consume the uncompressed output when it wants, for
|
|
+ example when the output buffer is full (avail_out == 0), or after each
|
|
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
|
|
+ must be called again after making room in the output buffer because there
|
|
+ might be more output pending.
|
|
+
|
|
+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
|
|
+ output as possible to the output buffer. The flushing behavior of inflate is
|
|
+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
|
|
+ and Z_FINISH, but the current implementation actually flushes as much output
|
|
+ as possible anyway.
|
|
+
|
|
+ inflate() should normally be called until it returns Z_STREAM_END or an
|
|
+ error. However if all decompression is to be performed in a single step
|
|
+ (a single call of inflate), the parameter flush should be set to
|
|
+ Z_FINISH. In this case all pending input is processed and all pending
|
|
+ output is flushed; avail_out must be large enough to hold all the
|
|
+ uncompressed data. (The size of the uncompressed data may have been saved
|
|
+ by the compressor for this purpose.) The next operation on this stream must
|
|
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
|
|
+ is never required, but can be used to inform inflate that a faster routine
|
|
+ may be used for the single inflate() call.
|
|
+
|
|
+ If a preset dictionary is needed at this point (see inflateSetDictionary
|
|
+ below), inflate sets strm-adler to the adler32 checksum of the
|
|
+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
|
|
+ it sets strm->adler to the adler32 checksum of all output produced
|
|
+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
|
|
+ an error code as described below. At the end of the stream, inflate()
|
|
+ checks that its computed adler32 checksum is equal to that saved by the
|
|
+ compressor and returns Z_STREAM_END only if the checksum is correct.
|
|
+
|
|
+ inflate() returns Z_OK if some progress has been made (more input processed
|
|
+ or more output produced), Z_STREAM_END if the end of the compressed data has
|
|
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
|
|
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
|
|
+ corrupted (input stream not conforming to the zlib format or incorrect
|
|
+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
|
|
+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
|
|
+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
|
|
+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
|
|
+ case, the application may then call inflateSync to look for a good
|
|
+ compression block.
|
|
+*/
|
|
+
|
|
+
|
|
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
|
|
+/*
|
|
+ All dynamically allocated data structures for this stream are freed.
|
|
+ This function discards any unprocessed input and does not flush any
|
|
+ pending output.
|
|
+
|
|
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
|
|
+ was inconsistent. In the error case, msg may be set but then points to a
|
|
+ static string (which must not be deallocated).
|
|
+*/
|
|
+
|
|
+ /* Advanced functions */
|
|
+
|
|
+/*
|
|
+ The following functions are needed only in some special applications.
|
|
+*/
|
|
+
|
|
+/*
|
|
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
|
|
+ int level,
|
|
+ int method,
|
|
+ int windowBits,
|
|
+ int memLevel,
|
|
+ int strategy));
|
|
+
|
|
+ This is another version of deflateInit with more compression options. The
|
|
+ fields next_in, zalloc, zfree and opaque must be initialized before by
|
|
+ the caller.
|
|
+
|
|
+ The method parameter is the compression method. It must be Z_DEFLATED in
|
|
+ this version of the library.
|
|
+
|
|
+ The windowBits parameter is the base two logarithm of the window size
|
|
+ (the size of the history buffer). It should be in the range 8..15 for this
|
|
+ version of the library. Larger values of this parameter result in better
|
|
+ compression at the expense of memory usage. The default value is 15 if
|
|
+ deflateInit is used instead.
|
|
+
|
|
+ The memLevel parameter specifies how much memory should be allocated
|
|
+ for the internal compression state. memLevel=1 uses minimum memory but
|
|
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
|
|
+ for optimal speed. The default value is 8. See zconf.h for total memory
|
|
+ usage as a function of windowBits and memLevel.
|
|
+
|
|
+ The strategy parameter is used to tune the compression algorithm. Use the
|
|
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
|
|
+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
|
|
+ string match). Filtered data consists mostly of small values with a
|
|
+ somewhat random distribution. In this case, the compression algorithm is
|
|
+ tuned to compress them better. The effect of Z_FILTERED is to force more
|
|
+ Huffman coding and less string matching; it is somewhat intermediate
|
|
+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
|
|
+ the compression ratio but not the correctness of the compressed output even
|
|
+ if it is not set appropriately.
|
|
+
|
|
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
|
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
|
|
+ method). msg is set to null if there is no error message. deflateInit2 does
|
|
+ not perform any compression: this will be done by deflate().
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
|
+ const Bytef *dictionary,
|
|
+ uInt dictLength));
|
|
+/*
|
|
+ Initializes the compression dictionary from the given byte sequence
|
|
+ without producing any compressed output. This function must be called
|
|
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
|
|
+ call of deflate. The compressor and decompressor must use exactly the same
|
|
+ dictionary (see inflateSetDictionary).
|
|
+
|
|
+ The dictionary should consist of strings (byte sequences) that are likely
|
|
+ to be encountered later in the data to be compressed, with the most commonly
|
|
+ used strings preferably put towards the end of the dictionary. Using a
|
|
+ dictionary is most useful when the data to be compressed is short and can be
|
|
+ predicted with good accuracy; the data can then be compressed better than
|
|
+ with the default empty dictionary.
|
|
+
|
|
+ Depending on the size of the compression data structures selected by
|
|
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
|
|
+ discarded, for example if the dictionary is larger than the window size in
|
|
+ deflate or deflate2. Thus the strings most likely to be useful should be
|
|
+ put at the end of the dictionary, not at the front.
|
|
+
|
|
+ Upon return of this function, strm->adler is set to the Adler32 value
|
|
+ of the dictionary; the decompressor may later use this value to determine
|
|
+ which dictionary has been used by the compressor. (The Adler32 value
|
|
+ applies to the whole dictionary even if only a subset of the dictionary is
|
|
+ actually used by the compressor.)
|
|
+
|
|
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
|
|
+ parameter is invalid (such as NULL dictionary) or the stream state is
|
|
+ inconsistent (for example if deflate has already been called for this stream
|
|
+ or if the compression method is bsort). deflateSetDictionary does not
|
|
+ perform any compression: this will be done by deflate().
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
|
|
+ z_streamp source));
|
|
+/*
|
|
+ Sets the destination stream as a complete copy of the source stream.
|
|
+
|
|
+ This function can be useful when several compression strategies will be
|
|
+ tried, for example when there are several ways of pre-processing the input
|
|
+ data with a filter. The streams that will be discarded should then be freed
|
|
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
|
|
+ compression state which can be quite large, so this strategy is slow and
|
|
+ can consume lots of memory.
|
|
+
|
|
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
|
|
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
|
|
+ (such as zalloc being NULL). msg is left unchanged in both source and
|
|
+ destination.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
|
|
+/*
|
|
+ This function is equivalent to deflateEnd followed by deflateInit,
|
|
+ but does not free and reallocate all the internal compression state.
|
|
+ The stream will keep the same compression level and any other attributes
|
|
+ that may have been set by deflateInit2.
|
|
+
|
|
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
|
|
+ stream state was inconsistent (such as zalloc or state being NULL).
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
|
|
+ int level,
|
|
+ int strategy));
|
|
+/*
|
|
+ Dynamically update the compression level and compression strategy. The
|
|
+ interpretation of level and strategy is as in deflateInit2. This can be
|
|
+ used to switch between compression and straight copy of the input data, or
|
|
+ to switch to a different kind of input data requiring a different
|
|
+ strategy. If the compression level is changed, the input available so far
|
|
+ is compressed with the old level (and may be flushed); the new level will
|
|
+ take effect only at the next call of deflate().
|
|
+
|
|
+ Before the call of deflateParams, the stream state must be set as for
|
|
+ a call of deflate(), since the currently available input may have to
|
|
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
|
|
+
|
|
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
|
|
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
|
|
+ if strm->avail_out was zero.
|
|
+*/
|
|
+
|
|
+/*
|
|
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
|
|
+ int windowBits));
|
|
+
|
|
+ This is another version of inflateInit with an extra parameter. The
|
|
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
|
|
+ before by the caller.
|
|
+
|
|
+ The windowBits parameter is the base two logarithm of the maximum window
|
|
+ size (the size of the history buffer). It should be in the range 8..15 for
|
|
+ this version of the library. The default value is 15 if inflateInit is used
|
|
+ instead. If a compressed stream with a larger window size is given as
|
|
+ input, inflate() will return with the error code Z_DATA_ERROR instead of
|
|
+ trying to allocate a larger window.
|
|
+
|
|
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
|
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
|
|
+ memLevel). msg is set to null if there is no error message. inflateInit2
|
|
+ does not perform any decompression apart from reading the zlib header if
|
|
+ present: this will be done by inflate(). (So next_in and avail_in may be
|
|
+ modified, but next_out and avail_out are unchanged.)
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
|
+ const Bytef *dictionary,
|
|
+ uInt dictLength));
|
|
+/*
|
|
+ Initializes the decompression dictionary from the given uncompressed byte
|
|
+ sequence. This function must be called immediately after a call of inflate
|
|
+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
|
+ can be determined from the Adler32 value returned by this call of
|
|
+ inflate. The compressor and decompressor must use exactly the same
|
|
+ dictionary (see deflateSetDictionary).
|
|
+
|
|
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
|
+ parameter is invalid (such as NULL dictionary) or the stream state is
|
|
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
|
|
+ expected one (incorrect Adler32 value). inflateSetDictionary does not
|
|
+ perform any decompression: this will be done by subsequent calls of
|
|
+ inflate().
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
|
|
+/*
|
|
+ Skips invalid compressed data until a full flush point (see above the
|
|
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
|
|
+ available input is skipped. No output is provided.
|
|
+
|
|
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
|
|
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
|
|
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
|
|
+ case, the application may save the current current value of total_in which
|
|
+ indicates where valid compressed data was found. In the error case, the
|
|
+ application may repeatedly call inflateSync, providing more input each time,
|
|
+ until success or end of the input data.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
|
|
+/*
|
|
+ This function is equivalent to inflateEnd followed by inflateInit,
|
|
+ but does not free and reallocate all the internal decompression state.
|
|
+ The stream will keep attributes that may have been set by inflateInit2.
|
|
+
|
|
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
|
|
+ stream state was inconsistent (such as zalloc or state being NULL).
|
|
+*/
|
|
+
|
|
+
|
|
+ /* utility functions */
|
|
+
|
|
+/*
|
|
+ The following utility functions are implemented on top of the
|
|
+ basic stream-oriented functions. To simplify the interface, some
|
|
+ default options are assumed (compression level and memory usage,
|
|
+ standard memory allocation functions). The source code of these
|
|
+ utility functions can easily be modified if you need special options.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
|
|
+ const Bytef *source, uLong sourceLen));
|
|
+/*
|
|
+ Compresses the source buffer into the destination buffer. sourceLen is
|
|
+ the byte length of the source buffer. Upon entry, destLen is the total
|
|
+ size of the destination buffer, which must be at least 0.1% larger than
|
|
+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
|
|
+ compressed buffer.
|
|
+ This function can be used to compress a whole file at once if the
|
|
+ input file is mmap'ed.
|
|
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
|
|
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
|
|
+ buffer.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
|
|
+ const Bytef *source, uLong sourceLen,
|
|
+ int level));
|
|
+/*
|
|
+ Compresses the source buffer into the destination buffer. The level
|
|
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
|
|
+ length of the source buffer. Upon entry, destLen is the total size of the
|
|
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
|
|
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
|
|
+
|
|
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
|
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
|
|
+ Z_STREAM_ERROR if the level parameter is invalid.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
|
+ const Bytef *source, uLong sourceLen));
|
|
+/*
|
|
+ Decompresses the source buffer into the destination buffer. sourceLen is
|
|
+ the byte length of the source buffer. Upon entry, destLen is the total
|
|
+ size of the destination buffer, which must be large enough to hold the
|
|
+ entire uncompressed data. (The size of the uncompressed data must have
|
|
+ been saved previously by the compressor and transmitted to the decompressor
|
|
+ by some mechanism outside the scope of this compression library.)
|
|
+ Upon exit, destLen is the actual size of the compressed buffer.
|
|
+ This function can be used to decompress a whole file at once if the
|
|
+ input file is mmap'ed.
|
|
+
|
|
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
|
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
|
|
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
|
|
+*/
|
|
+
|
|
+
|
|
+typedef voidp gzFile;
|
|
+
|
|
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
|
+/*
|
|
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
|
|
+ is as in fopen ("rb" or "wb") but can also include a compression level
|
|
+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
|
|
+ Huffman only compression as in "wb1h". (See the description
|
|
+ of deflateInit2 for more information about the strategy parameter.)
|
|
+
|
|
+ gzopen can be used to read a file which is not in gzip format; in this
|
|
+ case gzread will directly read from the file without decompression.
|
|
+
|
|
+ gzopen returns NULL if the file could not be opened or if there was
|
|
+ insufficient memory to allocate the (de)compression state; errno
|
|
+ can be checked to distinguish the two cases (if errno is zero, the
|
|
+ zlib error is Z_MEM_ERROR). */
|
|
+
|
|
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
|
|
+/*
|
|
+ gzdopen() associates a gzFile with the file descriptor fd. File
|
|
+ descriptors are obtained from calls like open, dup, creat, pipe or
|
|
+ fileno (in the file has been previously opened with fopen).
|
|
+ The mode parameter is as in gzopen.
|
|
+ The next call of gzclose on the returned gzFile will also close the
|
|
+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
|
|
+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
|
|
+ gzdopen returns NULL if there was insufficient memory to allocate
|
|
+ the (de)compression state.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
|
|
+/*
|
|
+ Dynamically update the compression level or strategy. See the description
|
|
+ of deflateInit2 for the meaning of these parameters.
|
|
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
|
|
+ opened for writing.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
|
+/*
|
|
+ Reads the given number of uncompressed bytes from the compressed file.
|
|
+ If the input file was not in gzip format, gzread copies the given number
|
|
+ of bytes into the buffer.
|
|
+ gzread returns the number of uncompressed bytes actually read (0 for
|
|
+ end of file, -1 for error). */
|
|
+
|
|
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
|
|
+ const voidp buf, unsigned len));
|
|
+/*
|
|
+ Writes the given number of uncompressed bytes into the compressed file.
|
|
+ gzwrite returns the number of uncompressed bytes actually written
|
|
+ (0 in case of error).
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
|
|
+/*
|
|
+ Converts, formats, and writes the args to the compressed file under
|
|
+ control of the format string, as in fprintf. gzprintf returns the number of
|
|
+ uncompressed bytes actually written (0 in case of error).
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
|
|
+/*
|
|
+ Writes the given null-terminated string to the compressed file, excluding
|
|
+ the terminating null character.
|
|
+ gzputs returns the number of characters written, or -1 in case of error.
|
|
+*/
|
|
+
|
|
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
|
|
+/*
|
|
+ Reads bytes from the compressed file until len-1 characters are read, or
|
|
+ a newline character is read and transferred to buf, or an end-of-file
|
|
+ condition is encountered. The string is then terminated with a null
|
|
+ character.
|
|
+ gzgets returns buf, or Z_NULL in case of error.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
|
|
+/*
|
|
+ Writes c, converted to an unsigned char, into the compressed file.
|
|
+ gzputc returns the value that was written, or -1 in case of error.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
|
+/*
|
|
+ Reads one byte from the compressed file. gzgetc returns this byte
|
|
+ or -1 in case of end of file or error.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
|
|
+/*
|
|
+ Flushes all pending output into the compressed file. The parameter
|
|
+ flush is as in the deflate() function. The return value is the zlib
|
|
+ error number (see function gzerror below). gzflush returns Z_OK if
|
|
+ the flush parameter is Z_FINISH and all output could be flushed.
|
|
+ gzflush should be called only when strictly necessary because it can
|
|
+ degrade compression.
|
|
+*/
|
|
+
|
|
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
|
|
+ z_off_t offset, int whence));
|
|
+/*
|
|
+ Sets the starting position for the next gzread or gzwrite on the
|
|
+ given compressed file. The offset represents a number of bytes in the
|
|
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
|
|
+ the value SEEK_END is not supported.
|
|
+ If the file is opened for reading, this function is emulated but can be
|
|
+ extremely slow. If the file is opened for writing, only forward seeks are
|
|
+ supported; gzseek then compresses a sequence of zeroes up to the new
|
|
+ starting position.
|
|
+
|
|
+ gzseek returns the resulting offset location as measured in bytes from
|
|
+ the beginning of the uncompressed stream, or -1 in case of error, in
|
|
+ particular if the file is opened for writing and the new starting position
|
|
+ would be before the current position.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
|
|
+/*
|
|
+ Rewinds the given file. This function is supported only for reading.
|
|
+
|
|
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
|
|
+*/
|
|
+
|
|
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
|
|
+/*
|
|
+ Returns the starting position for the next gzread or gzwrite on the
|
|
+ given compressed file. This position represents a number of bytes in the
|
|
+ uncompressed data stream.
|
|
+
|
|
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
|
+/*
|
|
+ Returns 1 when EOF has previously been detected reading the given
|
|
+ input stream, otherwise zero.
|
|
+*/
|
|
+
|
|
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
|
+/*
|
|
+ Flushes all pending output if necessary, closes the compressed file
|
|
+ and deallocates all the (de)compression state. The return value is the zlib
|
|
+ error number (see function gzerror below).
|
|
+*/
|
|
+
|
|
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
|
|
+/*
|
|
+ Returns the error message for the last error which occurred on the
|
|
+ given compressed file. errnum is set to zlib error number. If an
|
|
+ error occurred in the file system and not in the compression library,
|
|
+ errnum is set to Z_ERRNO and the application may consult errno
|
|
+ to get the exact error code.
|
|
+*/
|
|
+
|
|
+ /* checksum functions */
|
|
+
|
|
+/*
|
|
+ These functions are not related to compression but are exported
|
|
+ anyway because they might be useful in applications using the
|
|
+ compression library.
|
|
+*/
|
|
+
|
|
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
|
|
+
|
|
+/*
|
|
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
|
|
+ return the updated checksum. If buf is NULL, this function returns
|
|
+ the required initial value for the checksum.
|
|
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
|
|
+ much faster. Usage example:
|
|
+
|
|
+ uLong adler = adler32(0L, Z_NULL, 0);
|
|
+
|
|
+ while (read_buffer(buffer, length) != EOF) {
|
|
+ adler = adler32(adler, buffer, length);
|
|
+ }
|
|
+ if (adler != original_adler) error();
|
|
+*/
|
|
+
|
|
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
|
+/*
|
|
+ Update a running crc with the bytes buf[0..len-1] and return the updated
|
|
+ crc. If buf is NULL, this function returns the required initial value
|
|
+ for the crc. Pre- and post-conditioning (one's complement) is performed
|
|
+ within this function so it shouldn't be done by the application.
|
|
+ Usage example:
|
|
+
|
|
+ uLong crc = crc32(0L, Z_NULL, 0);
|
|
+
|
|
+ while (read_buffer(buffer, length) != EOF) {
|
|
+ crc = crc32(crc, buffer, length);
|
|
+ }
|
|
+ if (crc != original_crc) error();
|
|
+*/
|
|
+
|
|
+
|
|
+ /* various hacks, don't look :) */
|
|
+
|
|
+/* deflateInit and inflateInit are macros to allow checking the zlib version
|
|
+ * and the compiler's view of z_stream:
|
|
+ */
|
|
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
|
|
+ const char *version, int stream_size));
|
|
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
|
|
+ const char *version, int stream_size));
|
|
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
|
|
+ int windowBits, int memLevel,
|
|
+ int strategy, const char *version,
|
|
+ int stream_size));
|
|
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
|
|
+ const char *version, int stream_size));
|
|
+#define deflateInit(strm, level) \
|
|
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
|
|
+#define inflateInit(strm) \
|
|
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
|
|
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
|
|
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
|
|
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
|
|
+#define inflateInit2(strm, windowBits) \
|
|
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
|
|
+
|
|
+
|
|
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
|
|
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
|
|
+#endif
|
|
+
|
|
+ZEXTERN const char * ZEXPORT zError OF((int err));
|
|
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
|
|
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
|
|
+
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+
|
|
+#endif /* _ZLIB_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,225 @@
|
|
+/* zutil.h -- internal interface and configuration of the compression library
|
|
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* WARNING: this file should *not* be used by applications. It is
|
|
+ part of the implementation of the compression library and is
|
|
+ subject to change. Applications should only use zlib.h.
|
|
+ */
|
|
+
|
|
+/* @(#) $Id: zutil.h,v 1.4 2002/04/24 07:36:48 mcr Exp $ */
|
|
+
|
|
+#ifndef _Z_UTIL_H
|
|
+#define _Z_UTIL_H
|
|
+
|
|
+#include "zlib.h"
|
|
+
|
|
+#include <linux/string.h>
|
|
+#define HAVE_MEMCPY
|
|
+
|
|
+#if 0 // #ifdef STDC
|
|
+# include <stddef.h>
|
|
+# include <string.h>
|
|
+# include <stdlib.h>
|
|
+#endif
|
|
+#ifndef __KERNEL__
|
|
+#ifdef NO_ERRNO_H
|
|
+ extern int errno;
|
|
+#else
|
|
+# include <errno.h>
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#ifndef local
|
|
+# define local static
|
|
+#endif
|
|
+/* compile with -Dlocal if your debugger can't find static symbols */
|
|
+
|
|
+typedef unsigned char uch;
|
|
+typedef uch FAR uchf;
|
|
+typedef unsigned short ush;
|
|
+typedef ush FAR ushf;
|
|
+typedef unsigned long ulg;
|
|
+
|
|
+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
|
|
+/* (size given to avoid silly warnings with Visual C++) */
|
|
+
|
|
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
|
|
+
|
|
+#define ERR_RETURN(strm,err) \
|
|
+ return (strm->msg = ERR_MSG(err), (err))
|
|
+/* To be used only when the state is known to be valid */
|
|
+
|
|
+ /* common constants */
|
|
+
|
|
+#ifndef DEF_WBITS
|
|
+# define DEF_WBITS MAX_WBITS
|
|
+#endif
|
|
+/* default windowBits for decompression. MAX_WBITS is for compression only */
|
|
+
|
|
+#if MAX_MEM_LEVEL >= 8
|
|
+# define DEF_MEM_LEVEL 8
|
|
+#else
|
|
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
|
+#endif
|
|
+/* default memLevel */
|
|
+
|
|
+#define STORED_BLOCK 0
|
|
+#define STATIC_TREES 1
|
|
+#define DYN_TREES 2
|
|
+/* The three kinds of block type */
|
|
+
|
|
+#define MIN_MATCH 3
|
|
+#define MAX_MATCH 258
|
|
+/* The minimum and maximum match lengths */
|
|
+
|
|
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
|
|
+
|
|
+ /* target dependencies */
|
|
+
|
|
+#ifdef MSDOS
|
|
+# define OS_CODE 0x00
|
|
+# if defined(__TURBOC__) || defined(__BORLANDC__)
|
|
+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
|
+ /* Allow compilation with ANSI keywords only enabled */
|
|
+ void _Cdecl farfree( void *block );
|
|
+ void *_Cdecl farmalloc( unsigned long nbytes );
|
|
+# else
|
|
+# include <alloc.h>
|
|
+# endif
|
|
+# else /* MSC or DJGPP */
|
|
+# include <malloc.h>
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+#ifdef OS2
|
|
+# define OS_CODE 0x06
|
|
+#endif
|
|
+
|
|
+#ifdef WIN32 /* Window 95 & Windows NT */
|
|
+# define OS_CODE 0x0b
|
|
+#endif
|
|
+
|
|
+#if defined(VAXC) || defined(VMS)
|
|
+# define OS_CODE 0x02
|
|
+# define F_OPEN(name, mode) \
|
|
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
|
|
+#endif
|
|
+
|
|
+#ifdef AMIGA
|
|
+# define OS_CODE 0x01
|
|
+#endif
|
|
+
|
|
+#if defined(ATARI) || defined(atarist)
|
|
+# define OS_CODE 0x05
|
|
+#endif
|
|
+
|
|
+#if defined(MACOS) || defined(TARGET_OS_MAC)
|
|
+# define OS_CODE 0x07
|
|
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
|
+# include <unix.h> /* for fdopen */
|
|
+# else
|
|
+# ifndef fdopen
|
|
+# define fdopen(fd,mode) NULL /* No fdopen() */
|
|
+# endif
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+#ifdef __50SERIES /* Prime/PRIMOS */
|
|
+# define OS_CODE 0x0F
|
|
+#endif
|
|
+
|
|
+#ifdef TOPS20
|
|
+# define OS_CODE 0x0a
|
|
+#endif
|
|
+
|
|
+#if defined(_BEOS_) || defined(RISCOS)
|
|
+# define fdopen(fd,mode) NULL /* No fdopen() */
|
|
+#endif
|
|
+
|
|
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
|
|
+# define fdopen(fd,type) _fdopen(fd,type)
|
|
+#endif
|
|
+
|
|
+
|
|
+ /* Common defaults */
|
|
+
|
|
+#ifndef OS_CODE
|
|
+# define OS_CODE 0x03 /* assume Unix */
|
|
+#endif
|
|
+
|
|
+#ifndef F_OPEN
|
|
+# define F_OPEN(name, mode) fopen((name), (mode))
|
|
+#endif
|
|
+
|
|
+ /* functions */
|
|
+
|
|
+#ifdef HAVE_STRERROR
|
|
+ extern char *strerror OF((int));
|
|
+# define zstrerror(errnum) strerror(errnum)
|
|
+#else
|
|
+# define zstrerror(errnum) ""
|
|
+#endif
|
|
+
|
|
+#if defined(pyr)
|
|
+# define NO_MEMCPY
|
|
+#endif
|
|
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
|
+ /* Use our own functions for small and medium model with MSC <= 5.0.
|
|
+ * You may have to use the same strategy for Borland C (untested).
|
|
+ * The __SC__ check is for Symantec.
|
|
+ */
|
|
+# define NO_MEMCPY
|
|
+#endif
|
|
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
|
|
+# define HAVE_MEMCPY
|
|
+#endif
|
|
+#ifdef HAVE_MEMCPY
|
|
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
|
|
+# define zmemcpy _fmemcpy
|
|
+# define zmemcmp _fmemcmp
|
|
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
|
|
+# else
|
|
+# define zmemcpy memcpy
|
|
+# define zmemcmp memcmp
|
|
+# define zmemzero(dest, len) memset(dest, 0, len)
|
|
+# endif
|
|
+#else
|
|
+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
|
|
+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
|
|
+ extern void zmemzero OF((Bytef* dest, uInt len));
|
|
+#endif
|
|
+
|
|
+/* Diagnostic functions */
|
|
+#ifdef DEBUG
|
|
+# include <stdio.h>
|
|
+ extern int z_verbose;
|
|
+ extern void z_error OF((char *m));
|
|
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
|
|
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
|
|
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
|
|
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
|
|
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
|
|
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
|
|
+#else
|
|
+# define Assert(cond,msg)
|
|
+# define Trace(x)
|
|
+# define Tracev(x)
|
|
+# define Tracevv(x)
|
|
+# define Tracec(c,x)
|
|
+# define Tracecv(c,x)
|
|
+#endif
|
|
+
|
|
+
|
|
+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
|
|
+ uInt len));
|
|
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
|
|
+void zcfree OF((voidpf opaque, voidpf ptr));
|
|
+
|
|
+#define ZALLOC(strm, items, size) \
|
|
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
|
|
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
|
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
|
+
|
|
+#endif /* _Z_UTIL_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/lib/libfreeswan/Makefile.objs Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,21 @@
|
|
+obj-y += satot.o
|
|
+obj-y += addrtot.o
|
|
+obj-y += ultot.o
|
|
+obj-y += addrtypeof.o
|
|
+obj-y += anyaddr.o
|
|
+obj-y += initaddr.o
|
|
+obj-y += ultoa.o
|
|
+obj-y += addrtoa.o
|
|
+obj-y += subnettoa.o
|
|
+obj-y += subnetof.o
|
|
+obj-y += goodmask.o
|
|
+obj-y += datatot.o
|
|
+obj-y += rangetoa.o
|
|
+obj-y += prng.o
|
|
+obj-y += pfkey_v2_parse.o
|
|
+obj-y += pfkey_v2_build.o
|
|
+obj-y += pfkey_v2_debug.o
|
|
+obj-y += pfkey_v2_ext_bits.o
|
|
+
|
|
+#version.c: ${LIBFREESWANDIR}/version.in.c ${OPENSWANSRCDIR}/Makefile.ver
|
|
+# sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/lib/zlib/Makefile Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,118 @@
|
|
+# (kernel) Makefile for IPCOMP zlib deflate code
|
|
+# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+# Copyright (C) 2000 Svenning Soerensen
|
|
+#
|
|
+# This program is free software; you can redistribute it and/or modify it
|
|
+# under the terms of the GNU General Public License as published by the
|
|
+# Free Software Foundation; either version 2 of the License, or (at your
|
|
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+#
|
|
+# This program is distributed in the hope that it will be useful, but
|
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+# for more details.
|
|
+#
|
|
+# RCSID $Id: Makefile,v 1.9 2002/04/24 07:55:32 mcr Exp $
|
|
+#
|
|
+
|
|
+
|
|
+
|
|
+include ../Makefile.inc
|
|
+
|
|
+
|
|
+
|
|
+ifndef TOPDIR
|
|
+TOPDIR := /usr/src/linux
|
|
+endif
|
|
+
|
|
+
|
|
+L_TARGET := zlib.a
|
|
+
|
|
+obj-y :=
|
|
+
|
|
+include Makefile.objs
|
|
+
|
|
+EXTRA_CFLAGS += $(KLIPSCOMPILE)
|
|
+
|
|
+EXTRA_CFLAGS += -Wall
|
|
+#EXTRA_CFLAGS += -Wconversion
|
|
+#EXTRA_CFLAGS += -Wmissing-prototypes
|
|
+EXTRA_CFLAGS += -Wpointer-arith
|
|
+#EXTRA_CFLAGS += -Wcast-qual
|
|
+#EXTRA_CFLAGS += -Wmissing-declarations
|
|
+EXTRA_CFLAGS += -Wstrict-prototypes
|
|
+#EXTRA_CFLAGS += -pedantic
|
|
+#EXTRA_CFLAGS += -W
|
|
+#EXTRA_CFLAGS += -Wwrite-strings
|
|
+EXTRA_CFLAGS += -Wbad-function-cast
|
|
+EXTRA_CFLAGS += -DIPCOMP_PREFIX
|
|
+
|
|
+.S.o:
|
|
+ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o
|
|
+
|
|
+asm-obj-$(CONFIG_M586) += match586.o
|
|
+asm-obj-$(CONFIG_M586TSC) += match586.o
|
|
+asm-obj-$(CONFIG_M586MMX) += match586.o
|
|
+asm-obj-$(CONFIG_M686) += match686.o
|
|
+asm-obj-$(CONFIG_MPENTIUMIII) += match686.o
|
|
+asm-obj-$(CONFIG_MPENTIUM4) += match686.o
|
|
+asm-obj-$(CONFIG_MK6) += match586.o
|
|
+asm-obj-$(CONFIG_MK7) += match686.o
|
|
+asm-obj-$(CONFIG_MCRUSOE) += match586.o
|
|
+asm-obj-$(CONFIG_MWINCHIPC6) += match586.o
|
|
+asm-obj-$(CONFIG_MWINCHIP2) += match686.o
|
|
+asm-obj-$(CONFIG_MWINCHIP3D) += match686.o
|
|
+
|
|
+obj-y += $(asm-obj-y)
|
|
+ifneq ($(strip $(asm-obj-y)),)
|
|
+ EXTRA_CFLAGS += -DASMV
|
|
+endif
|
|
+
|
|
+active-objs := $(sort $(obj-y) $(obj-m))
|
|
+L_OBJS := $(obj-y)
|
|
+M_OBJS := $(obj-m)
|
|
+MIX_OBJS := $(filter $(export-objs), $(active-objs))
|
|
+
|
|
+include $(TOPDIR)/Rules.make
|
|
+
|
|
+$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
|
|
+
|
|
+
|
|
+clean:
|
|
+ -rm -f *.o *.a
|
|
+
|
|
+checkprograms:
|
|
+programs: $(L_TARGET)
|
|
+
|
|
+#
|
|
+# $Log: Makefile,v $
|
|
+# Revision 1.9 2002/04/24 07:55:32 mcr
|
|
+# #include patches and Makefiles for post-reorg compilation.
|
|
+#
|
|
+# Revision 1.8 2002/04/24 07:36:44 mcr
|
|
+# Moved from ./zlib/Makefile,v
|
|
+#
|
|
+# Revision 1.7 2002/03/27 23:34:35 mcr
|
|
+# added programs: target
|
|
+#
|
|
+# Revision 1.6 2001/12/05 20:19:08 henry
|
|
+# use new compile-control variable
|
|
+#
|
|
+# Revision 1.5 2001/11/27 16:38:08 mcr
|
|
+# added new "checkprograms" target to deal with programs that
|
|
+# are required for "make check", but that may not be ready to
|
|
+# build for every user due to external dependancies.
|
|
+#
|
|
+# Revision 1.4 2001/10/24 14:46:24 henry
|
|
+# Makefile.inc
|
|
+#
|
|
+# Revision 1.3 2001/04/21 23:05:24 rgb
|
|
+# Update asm directives for 2.4 style makefiles.
|
|
+#
|
|
+# Revision 1.2 2001/01/29 22:22:00 rgb
|
|
+# Convert to 2.4 new style with back compat.
|
|
+#
|
|
+# Revision 1.1.1.1 2000/09/29 18:51:33 rgb
|
|
+# zlib_beginnings
|
|
+#
|
|
+#
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/lib/zlib/Makefile.objs Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,27 @@
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += trees.o
|
|
+obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o
|
|
+
|
|
+asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o
|
|
+asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o
|
|
+asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o
|
|
+asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o
|
|
+asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o
|
|
+asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o
|
|
+asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o
|
|
+asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o
|
|
+asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o
|
|
+asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o
|
|
+asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o
|
|
+asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o
|
|
+
|
|
+EXTRA_CFLAGS += -DIPCOMP_PREFIX
|
|
+
|
|
+
|
|
--- swan26/net/Kconfig.preipsec 2005-09-01 18:15:19.000000000 -0400
|
|
+++ swan26/net/Kconfig 2005-09-03 16:51:17.000000000 -0400
|
|
@@ -215,2 +215,6 @@
|
|
|
|
+if INET
|
|
+source "net/ipsec/Kconfig"
|
|
+endif # if INET
|
|
+
|
|
endif # if NET
|
|
--- /distros/kernel/linux-2.6.3-rc4/net/Makefile Mon Feb 16 21:22:12 2004
|
|
+++ ref26/net/Makefile Thu Feb 19 21:02:25 2004
|
|
@@ -42,3 +42,6 @@
|
|
ifeq ($(CONFIG_NET),y)
|
|
obj-$(CONFIG_SYSCTL) += sysctl_net.o
|
|
endif
|
|
+
|
|
+obj-$(CONFIG_KLIPS) += ipsec/
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/Kconfig Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,161 @@
|
|
+#
|
|
+# IPSEC configuration
|
|
+# Copyright (C) 2004 Michael Richardson <mcr@freeswan.org>
|
|
+#
|
|
+# This program is free software; you can redistribute it and/or modify it
|
|
+# under the terms of the GNU General Public License as published by the
|
|
+# Free Software Foundation; either version 2 of the License, or (at your
|
|
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+#
|
|
+# This program is distributed in the hope that it will be useful, but
|
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+# for more details.
|
|
+#
|
|
+# RCSID $Id: Kconfig,v 1.6.2.2 2006/10/11 18:14:33 paul Exp $
|
|
+
|
|
+config KLIPS
|
|
+ tristate "Openswan IPsec (KLIPS26)"
|
|
+ default n
|
|
+ help
|
|
+ KLIPS is the Openswan (www.openswan.org) Kernel Level IP Security
|
|
+ system. It is extensively tested, and has interoperated with
|
|
+ many other systems.
|
|
+ It provides "ipsecX" devices on which one can do firewalling.
|
|
+ The userland, is compatible with both KLIPS and 26sec.
|
|
+
|
|
+menu "KLIPS options"
|
|
+ depends on KLIPS
|
|
+
|
|
+config KLIPS_ESP
|
|
+ bool 'Encapsulating Security Payload - ESP ("VPN")'
|
|
+ default y
|
|
+ help
|
|
+ This option provides support for the IPSEC Encapsulation Security
|
|
+ Payload (IP protocol 50) which provides packet layer content
|
|
+ hiding, and content authentication.
|
|
+ It is recommended to enable this. RFC2406
|
|
+
|
|
+config KLIPS_AH
|
|
+ bool 'Authentication Header - AH'
|
|
+ default n
|
|
+ help
|
|
+ This option provides support for the IPSEC Authentication Header
|
|
+ (IP protocol 51) which provides packet layer sender and content
|
|
+ authentication. It does not provide for confidentiality.
|
|
+ It is not recommended to enable this. RFC2402
|
|
+
|
|
+config KLIPS_AUTH_HMAC_MD5
|
|
+ bool 'HMAC-MD5 authentication algorithm'
|
|
+ default y
|
|
+ help
|
|
+ The HMAC-MD5 algorithm is used by ESP (and AH) to guarantee packet
|
|
+ integrity. There is little reason not to include it.
|
|
+
|
|
+config KLIPS_AUTH_HMAC_SHA1
|
|
+ bool 'HMAC-SHA1 authentication algorithm'
|
|
+ default y
|
|
+ help
|
|
+ The HMAC-SHA1 algorithm is used by ESP (and AH) to guarantee packet
|
|
+ integrity. SHA1 is a little slower than MD5, but is said to be
|
|
+ a bit more secure. There is little reason not to include it.
|
|
+
|
|
+config KLIPS_ENC_CRYPTOAPI
|
|
+ bool 'CryptoAPI algorithm interface'
|
|
+ default n
|
|
+ help
|
|
+ Enable the algorithm interface to make all CryptoAPI 1.0 algorithms
|
|
+ available to KLIPS.
|
|
+
|
|
+config KLIPS_ENC_1DES
|
|
+ bool 'Include 1DES with CryptoAPI'
|
|
+ default n
|
|
+ depends on KLIPS_ENC_CRYPTOAPI
|
|
+ help
|
|
+ The CryptoAPI interface does not include support for every algorithm
|
|
+ yet, and one that it doesn't support by default is the VERY WEAK
|
|
+ 1DES. Select this if you are terminally stupid.
|
|
+
|
|
+config KLIPS_ENC_3DES
|
|
+ bool '3DES encryption algorithm'
|
|
+ default y
|
|
+ help
|
|
+ The 3DES algorithm is used by ESP to provide for packet privacy.
|
|
+ 3DES is 3-repeats of the DES algorithm. 3DES is widely supported,
|
|
+ and analyzed and is considered very secure. 1DES is not supported.
|
|
+
|
|
+config KLIPS_ENC_AES
|
|
+ bool 'AES encryption algorithm'
|
|
+ default y
|
|
+ help
|
|
+ The AES algorithm is used by ESP to provide for packet privacy.
|
|
+ AES the NIST replacement for DES. AES is being widely analyzed,
|
|
+ and is very fast.
|
|
+
|
|
+config KLIPS_ENC_NULL
|
|
+ bool 'NULL NON-encryption algorithm'
|
|
+ default n
|
|
+ help
|
|
+ NON encryption algo , maybe useful for ESP auth only scenarios
|
|
+ (eg: with NAT-T), see RFC 2410.
|
|
+
|
|
+config KLIPS_IPCOMP
|
|
+ bool 'IP compression'
|
|
+ default y
|
|
+ help
|
|
+ The IPcomp protocol is used prior to ESP to make the packet
|
|
+ smaller. Once encrypted, compression will fail, so any link
|
|
+ layer efforts (e.g. PPP) will not work.
|
|
+
|
|
+config KLIPS_DEBUG
|
|
+ bool 'IPsec debugging'
|
|
+ default y
|
|
+ help
|
|
+ KLIPS includes a lot of debugging code. Unless there is a real
|
|
+ tangible benefit to removing this code, it should be left in place.
|
|
+ Debugging connections without access to kernel level debugging is
|
|
+ essentially impossible. Leave this on.
|
|
+
|
|
+endmenu
|
|
+
|
|
+#
|
|
+#
|
|
+# $Log: Kconfig,v $
|
|
+# Revision 1.6.2.2 2006/10/11 18:14:33 paul
|
|
+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
|
|
+# per default.
|
|
+#
|
|
+# Revision 1.6.2.1 2006/04/20 16:33:06 mcr
|
|
+# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
|
|
+# Fix in-kernel module compilation. Sub-makefiles do not work.
|
|
+#
|
|
+# Revision 1.6 2005/05/18 20:55:27 mcr
|
|
+# default cryptoapi to n.
|
|
+#
|
|
+# Revision 1.5 2005/05/11 01:23:25 mcr
|
|
+# added 1DES option to cryptoapi.
|
|
+#
|
|
+# Revision 1.4 2005/04/29 05:29:54 mcr
|
|
+# add option to include cryptoapi algorithms.
|
|
+#
|
|
+# Revision 1.3 2004/08/17 03:27:23 mcr
|
|
+# klips 2.6 edits.
|
|
+#
|
|
+# Revision 1.2 2004/08/14 03:27:39 mcr
|
|
+# 2.6 kernel build/configuration files.
|
|
+#
|
|
+# Revision 1.1 2004/08/14 02:47:55 mcr
|
|
+# kernel build/config patches
|
|
+#
|
|
+# Revision 1.3 2004/02/24 17:17:04 mcr
|
|
+# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
|
|
+# turn it on/off as well.
|
|
+#
|
|
+# Revision 1.2 2004/02/22 06:50:42 mcr
|
|
+# kernel 2.6 port - merged with 2.4 code.
|
|
+#
|
|
+# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
|
|
+# module configuration for KLIPS 2.6
|
|
+#
|
|
+#
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,195 @@
|
|
+# Makefile for KLIPS kernel code as a module for 2.6 kernels
|
|
+#
|
|
+# Makefile for KLIPS kernel code as a module
|
|
+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
|
|
+# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
|
|
+#
|
|
+# This program is free software; you can redistribute it and/or modify it
|
|
+# under the terms of the GNU General Public License as published by the
|
|
+# Free Software Foundation; either version 2 of the License, or (at your
|
|
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+#
|
|
+# This program is distributed in the hope that it will be useful, but
|
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+# for more details.
|
|
+#
|
|
+# RCSID $Id: Makefile.fs2_6,v 1.8.2.2 2006/10/11 18:14:33 paul Exp $
|
|
+#
|
|
+# Note! Dependencies are done automagically by 'make dep', which also
|
|
+# removes any old dependencies. DON'T put your own dependencies here
|
|
+# unless it's something special (ie not a .c file).
|
|
+#
|
|
+
|
|
+OPENSWANSRCDIR?=.
|
|
+KLIPS_TOP?=.
|
|
+
|
|
+-include ${OPENSWANSRCDIR}/Makefile.ver
|
|
+
|
|
+base-klips-objs :=
|
|
+
|
|
+base-klips-objs+= ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
|
|
+base-klips-objs+= ipsec_life.o ipsec_proc.o
|
|
+base-klips-objs+= ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
|
|
+base-klips-objs+= ipsec_snprintf.o
|
|
+base-klips-objs+= sysctl_net_ipsec.o
|
|
+base-klips-objs+= pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
|
|
+base-klips-objs+= version.o
|
|
+
|
|
+base-klips-objs+= satot.o
|
|
+base-klips-objs+= addrtot.o
|
|
+base-klips-objs+= ultot.o
|
|
+base-klips-objs+= addrtypeof.o
|
|
+base-klips-objs+= anyaddr.o
|
|
+base-klips-objs+= initaddr.o
|
|
+base-klips-objs+= ultoa.o
|
|
+base-klips-objs+= addrtoa.o
|
|
+base-klips-objs+= subnettoa.o
|
|
+base-klips-objs+= subnetof.o
|
|
+base-klips-objs+= goodmask.o
|
|
+base-klips-objs+= datatot.o
|
|
+base-klips-objs+= rangetoa.o
|
|
+base-klips-objs+= prng.o
|
|
+base-klips-objs+= pfkey_v2_parse.o
|
|
+base-klips-objs+= pfkey_v2_build.o
|
|
+base-klips-objs+= pfkey_v2_debug.o
|
|
+base-klips-objs+= pfkey_v2_ext_bits.o
|
|
+base-klips-objs+= version.o
|
|
+
|
|
+obj-${CONFIG_KLIPS} += ipsec.o
|
|
+
|
|
+ipsec-objs += ${base-klips-objs}
|
|
+
|
|
+ipsec-$(CONFIG_KLIPS_ESP) += ipsec_esp.o
|
|
+ipsec-$(CONFIG_KLIPS_IPCOMP) += ipsec_ipcomp.o
|
|
+ipsec-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
|
|
+ipsec-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
|
|
+
|
|
+# AH, if you really think you need it.
|
|
+ipsec-$(CONFIG_KLIPS_AH) += ipsec_ah.o
|
|
+
|
|
+ipsec-y += ipsec_alg.o
|
|
+
|
|
+# include code from DES subdir
|
|
+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ipsec_alg_3des.o
|
|
+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/cbc_enc.o
|
|
+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ecb_enc.o
|
|
+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/set_key.o
|
|
+
|
|
+ifeq ($(strip ${SUBARCH}),)
|
|
+SUBARCH:=${ARCH}
|
|
+endif
|
|
+
|
|
+# the assembly version expects frame pointers, which are
|
|
+# optional in many kernel builds. If you want speed, you should
|
|
+# probably use cryptoapi code instead.
|
|
+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
|
|
+ifeq (${USEASSEMBLY},i386y)
|
|
+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/dx86unix.o
|
|
+else
|
|
+crypto-$(CONFIG_KLIPS_ENC_3DES) += des/des_enc.o
|
|
+endif
|
|
+
|
|
+# include code from AES subdir
|
|
+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/ipsec_alg_aes.o
|
|
+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_xcbc_mac.o
|
|
+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_cbc.o
|
|
+
|
|
+ifeq ($(strip ${SUBARCH}),)
|
|
+SUBARCH:=${ARCH}
|
|
+endif
|
|
+
|
|
+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
|
|
+ifeq (${USEASSEMBLY},i386y)
|
|
+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes-i586.o
|
|
+else
|
|
+crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes.o
|
|
+endif
|
|
+
|
|
+crypto-$(CONFIG_KLIPS_ENC_NULL) += null/ipsec_alg_null.o
|
|
+
|
|
+ipsec-y += ${crypto-y}
|
|
+
|
|
+ipsec-$(CONFIG_KLIPS_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o
|
|
+
|
|
+# IPcomp stuff
|
|
+base-ipcomp-objs := ipcomp.o
|
|
+base-ipcomp-objs += adler32.o
|
|
+base-ipcomp-objs += deflate.o
|
|
+base-ipcomp-objs += infblock.o
|
|
+base-ipcomp-objs += infcodes.o
|
|
+base-ipcomp-objs += inffast.o
|
|
+base-ipcomp-objs += inflate.o
|
|
+base-ipcomp-objs += inftrees.o
|
|
+base-ipcomp-objs += infutil.o
|
|
+base-ipcomp-objs += trees.o
|
|
+base-ipcomp-objs += zutil.o
|
|
+asm-ipcomp-obj-$(CONFIG_M586) += match586.o
|
|
+asm-ipcomp-obj-$(CONFIG_M586TSC) += match586.o
|
|
+asm-ipcomp-obj-$(CONFIG_M586MMX) += match586.o
|
|
+asm-ipcomp-obj-$(CONFIG_M686) += match686.o
|
|
+asm-ipcomp-obj-$(CONFIG_MPENTIUMIII) += match686.o
|
|
+asm-ipcomp-obj-$(CONFIG_MPENTIUM4) += match686.o
|
|
+asm-ipcomp-obj-$(CONFIG_MK6) += match586.o
|
|
+asm-ipcomp-obj-$(CONFIG_MK7) += match686.o
|
|
+asm-ipcomp-obj-$(CONFIG_MCRUSOE) += match586.o
|
|
+asm-ipcomp-obj-$(CONFIG_MWINCHIPC6) += match586.o
|
|
+asm-ipcomp-obj-$(CONFIG_MWINCHIP2) += match686.o
|
|
+asm-ipcomp-obj-$(CONFIG_MWINCHIP3D) += match686.o
|
|
+base-ipcomp-objs += ${asm-ipcomp-obj-y}
|
|
+
|
|
+ipsec-$(CONFIG_KLIPS_IPCOMP) += ${base-ipcomp-objs}
|
|
+
|
|
+EXTRA_CFLAGS += -DIPCOMP_PREFIX
|
|
+
|
|
+#
|
|
+# $Log: Makefile.fs2_6,v $
|
|
+# Revision 1.8.2.2 2006/10/11 18:14:33 paul
|
|
+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
|
|
+# per default.
|
|
+#
|
|
+# Revision 1.8.2.1 2006/04/20 16:33:06 mcr
|
|
+# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
|
|
+# Fix in-kernel module compilation. Sub-makefiles do not work.
|
|
+#
|
|
+# Revision 1.8 2005/05/11 03:15:42 mcr
|
|
+# adjusted makefiles to sanely build modules properly.
|
|
+#
|
|
+# Revision 1.7 2005/04/13 22:52:12 mcr
|
|
+# moved KLIPS specific snprintf() wrapper to seperate file.
|
|
+#
|
|
+# Revision 1.6 2004/08/22 05:02:03 mcr
|
|
+# organized symbols such that it is easier to build modules.
|
|
+#
|
|
+# Revision 1.5 2004/08/18 01:43:56 mcr
|
|
+# adjusted makefile enumation so that it can be used by module
|
|
+# wrapper.
|
|
+#
|
|
+# Revision 1.4 2004/08/17 03:27:23 mcr
|
|
+# klips 2.6 edits.
|
|
+#
|
|
+# Revision 1.3 2004/08/04 16:50:13 mcr
|
|
+# removed duplicate definition of dx86unix.o
|
|
+#
|
|
+# Revision 1.2 2004/08/03 18:21:09 mcr
|
|
+# only set KLIPS_TOP and OPENSWANSRCDIR if not already set.
|
|
+#
|
|
+# Revision 1.1 2004/07/26 15:02:22 mcr
|
|
+# makefile for KLIPS module for 2.6.
|
|
+#
|
|
+# Revision 1.3 2004/02/24 17:17:04 mcr
|
|
+# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
|
|
+# turn it on/off as well.
|
|
+#
|
|
+# Revision 1.2 2004/02/22 06:50:42 mcr
|
|
+# kernel 2.6 port - merged with 2.4 code.
|
|
+#
|
|
+# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
|
|
+# module configuration for KLIPS 2.6
|
|
+#
|
|
+#
|
|
+# Local Variables:
|
|
+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
|
|
+# End Variables:
|
|
+#
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/README-zlib Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,147 @@
|
|
+zlib 1.1.4 is a general purpose data compression library. All the code
|
|
+is thread safe. The data format used by the zlib library
|
|
+is described by RFCs (Request for Comments) 1950 to 1952 in the files
|
|
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
|
|
+format) and rfc1952.txt (gzip format). These documents are also available in
|
|
+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
|
|
+
|
|
+All functions of the compression library are documented in the file zlib.h
|
|
+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
|
|
+example of the library is given in the file example.c which also tests that
|
|
+the library is working correctly. Another example is given in the file
|
|
+minigzip.c. The compression library itself is composed of all source files
|
|
+except example.c and minigzip.c.
|
|
+
|
|
+To compile all files and run the test program, follow the instructions
|
|
+given at the top of Makefile. In short "make test; make install"
|
|
+should work for most machines. For Unix: "./configure; make test; make install"
|
|
+For MSDOS, use one of the special makefiles such as Makefile.msc.
|
|
+For VMS, use Make_vms.com or descrip.mms.
|
|
+
|
|
+Questions about zlib should be sent to <zlib@gzip.org>, or to
|
|
+Gilles Vollant <info@winimage.com> for the Windows DLL version.
|
|
+The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
|
|
+Before reporting a problem, please check this site to verify that
|
|
+you have the latest version of zlib; otherwise get the latest version and
|
|
+check whether the problem still exists or not.
|
|
+
|
|
+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
|
|
+before asking for help.
|
|
+
|
|
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
|
+issue of Dr. Dobb's Journal; a copy of the article is available in
|
|
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
|
|
+
|
|
+The changes made in version 1.1.4 are documented in the file ChangeLog.
|
|
+The only changes made since 1.1.3 are bug corrections:
|
|
+
|
|
+- ZFREE was repeated on same allocation on some error conditions.
|
|
+ This creates a security problem described in
|
|
+ http://www.zlib.org/advisory-2002-03-11.txt
|
|
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
|
|
+- Avoid accesses before window for invalid distances with inflate window
|
|
+ less than 32K.
|
|
+- force windowBits > 8 to avoid a bug in the encoder for a window size
|
|
+ of 256 bytes. (A complete fix will be available in 1.1.5).
|
|
+
|
|
+The beta version 1.1.5beta includes many more changes. A new official
|
|
+version 1.1.5 will be released as soon as extensive testing has been
|
|
+completed on it.
|
|
+
|
|
+
|
|
+Unsupported third party contributions are provided in directory "contrib".
|
|
+
|
|
+A Java implementation of zlib is available in the Java Development Kit
|
|
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
|
|
+See the zlib home page http://www.zlib.org for details.
|
|
+
|
|
+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
|
|
+is in the CPAN (Comprehensive Perl Archive Network) sites
|
|
+http://www.cpan.org/modules/by-module/Compress/
|
|
+
|
|
+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
|
|
+is available in Python 1.5 and later versions, see
|
|
+http://www.python.org/doc/lib/module-zlib.html
|
|
+
|
|
+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
|
|
+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
|
|
+
|
|
+An experimental package to read and write files in .zip format,
|
|
+written on top of zlib by Gilles Vollant <info@winimage.com>, is
|
|
+available at http://www.winimage.com/zLibDll/unzip.html
|
|
+and also in the contrib/minizip directory of zlib.
|
|
+
|
|
+
|
|
+Notes for some targets:
|
|
+
|
|
+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
|
|
+ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
|
|
+ The zlib DLL support was initially done by Alessandro Iacopetti and is
|
|
+ now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
|
|
+ home page at http://www.winimage.com/zLibDll
|
|
+
|
|
+ From Visual Basic, you can call the DLL functions which do not take
|
|
+ a structure as argument: compress, uncompress and all gz* functions.
|
|
+ See contrib/visual-basic.txt for more information, or get
|
|
+ http://www.tcfb.com/dowseware/cmp-z-it.zip
|
|
+
|
|
+- For 64-bit Irix, deflate.c must be compiled without any optimization.
|
|
+ With -O, one libpng test fails. The test works in 32 bit mode (with
|
|
+ the -n32 compiler flag). The compiler bug has been reported to SGI.
|
|
+
|
|
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
|
|
+ it works when compiled with cc.
|
|
+
|
|
+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
|
|
+ is necessary to get gzprintf working correctly. This is done by configure.
|
|
+
|
|
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
|
|
+ with other compilers. Use "make test" to check your compiler.
|
|
+
|
|
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
|
|
+
|
|
+- For Turbo C the small model is supported only with reduced performance to
|
|
+ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
|
|
+
|
|
+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
|
|
+ Per Harald Myrvang <perm@stud.cs.uit.no>
|
|
+
|
|
+
|
|
+Acknowledgments:
|
|
+
|
|
+ The deflate format used by zlib was defined by Phil Katz. The deflate
|
|
+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
|
|
+ people who reported problems and suggested various improvements in zlib;
|
|
+ they are too numerous to cite here.
|
|
+
|
|
+Copyright notice:
|
|
+
|
|
+ (C) 1995-2002 Jean-loup Gailly and Mark Adler
|
|
+
|
|
+ This software is provided 'as-is', without any express or implied
|
|
+ warranty. In no event will the authors be held liable for any damages
|
|
+ arising from the use of this software.
|
|
+
|
|
+ Permission is granted to anyone to use this software for any purpose,
|
|
+ including commercial applications, and to alter it and redistribute it
|
|
+ freely, subject to the following restrictions:
|
|
+
|
|
+ 1. The origin of this software must not be misrepresented; you must not
|
|
+ claim that you wrote the original software. If you use this software
|
|
+ in a product, an acknowledgment in the product documentation would be
|
|
+ appreciated but is not required.
|
|
+ 2. Altered source versions must be plainly marked as such, and must not be
|
|
+ misrepresented as being the original software.
|
|
+ 3. This notice may not be removed or altered from any source distribution.
|
|
+
|
|
+ Jean-loup Gailly Mark Adler
|
|
+ jloup@gzip.org madler@alumni.caltech.edu
|
|
+
|
|
+If you use the zlib library in a product, we would appreciate *not*
|
|
+receiving lengthy legal documents to sign. The sources are provided
|
|
+for free but without warranty of any kind. The library has been
|
|
+entirely written by Jean-loup Gailly and Mark Adler; it does not
|
|
+include third-party code.
|
|
+
|
|
+If you redistribute modified sources, we would appreciate that you include
|
|
+in the file ChangeLog history information documenting your changes.
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/README-zlib.freeswan Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,13 @@
|
|
+The only changes made to these files for use in FreeS/WAN are:
|
|
+
|
|
+ - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
|
|
+ (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
|
|
+ - The copyright strings are defined local (static)
|
|
+
|
|
+ The above changes are made to avoid name collisions with ppp_deflate
|
|
+ and ext2compr.
|
|
+
|
|
+ - Files not needed for FreeS/WAN have been removed
|
|
+
|
|
+ See the "README" file for information about where to obtain the complete
|
|
+ zlib package.
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/addrtoa.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,67 @@
|
|
+/*
|
|
+ * addresses to ASCII
|
|
+ * Copyright (C) 1998, 1999 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: addrtoa.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+#define NBYTES 4 /* bytes in an address */
|
|
+#define PERBYTE 4 /* three digits plus a dot or NUL */
|
|
+#define BUFLEN (NBYTES*PERBYTE)
|
|
+
|
|
+#if BUFLEN != ADDRTOA_BUF
|
|
+#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code"
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ - addrtoa - convert binary address to ASCII dotted decimal
|
|
+ */
|
|
+size_t /* space needed for full conversion */
|
|
+addrtoa(addr, format, dst, dstlen)
|
|
+struct in_addr addr;
|
|
+int format; /* character */
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ unsigned long a = ntohl(addr.s_addr);
|
|
+ int i;
|
|
+ size_t n;
|
|
+ unsigned long byte;
|
|
+ char buf[BUFLEN];
|
|
+ char *p;
|
|
+
|
|
+ switch (format) {
|
|
+ case 0:
|
|
+ break;
|
|
+ default:
|
|
+ return 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ p = buf;
|
|
+ for (i = NBYTES-1; i >= 0; i--) {
|
|
+ byte = (a >> (i*8)) & 0xff;
|
|
+ p += ultoa(byte, 10, p, PERBYTE);
|
|
+ if (i != 0)
|
|
+ *(p-1) = '.';
|
|
+ }
|
|
+ n = p - buf;
|
|
+
|
|
+ if (dstlen > 0) {
|
|
+ if (n > dstlen)
|
|
+ buf[dstlen - 1] = '\0';
|
|
+ strcpy(dst, buf);
|
|
+ }
|
|
+ return n;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/addrtot.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,423 @@
|
|
+/*
|
|
+ * addresses to text
|
|
+ * Copyright (C) 2000 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: addrtot.c,v 1.22.2.1 2005/11/17 22:30:49 paul Exp $
|
|
+ */
|
|
+
|
|
+#if defined(__KERNEL__) && defined(__HAVE_ARCH_STRSTR)
|
|
+#include <linux/string.h>
|
|
+#endif
|
|
+
|
|
+#include "openswan.h"
|
|
+
|
|
+#define IP4BYTES 4 /* bytes in an IPv4 address */
|
|
+#define PERBYTE 4 /* three digits plus a dot or NUL */
|
|
+#define IP6BYTES 16 /* bytes in an IPv6 address */
|
|
+
|
|
+/* forwards */
|
|
+static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
|
|
+static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
|
|
+static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
|
|
+static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
|
|
+
|
|
+#if defined(__KERNEL__) && !defined(__HAVE_ARCH_STRSTR)
|
|
+#define strstr ipsec_strstr
|
|
+/*
|
|
+ * Find the first occurrence of find in s.
|
|
+ * (from NetBSD 1.6's /src/lib/libc/string/strstr.c)
|
|
+ */
|
|
+static char *
|
|
+strstr(s, find)
|
|
+ const char *s, *find;
|
|
+{
|
|
+ char c, sc;
|
|
+ size_t len;
|
|
+
|
|
+ if ((c = *find++) != 0) {
|
|
+ len = strlen(find);
|
|
+ do {
|
|
+ do {
|
|
+ if ((sc = *s++) == 0)
|
|
+ return (NULL);
|
|
+ } while (sc != c);
|
|
+ } while (strncmp(s, find, len) != 0);
|
|
+ s--;
|
|
+ }
|
|
+ /* LINTED interface specification */
|
|
+ return ((char *)s);
|
|
+}
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ - addrtot - convert binary address to text (dotted decimal or IPv6 string)
|
|
+ */
|
|
+size_t /* space needed for full conversion */
|
|
+addrtot(src, format, dst, dstlen)
|
|
+const ip_address *src;
|
|
+int format; /* character */
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ const unsigned char *b;
|
|
+ size_t n;
|
|
+ char buf[1+ADDRTOT_BUF+1]; /* :address: */
|
|
+ char *p;
|
|
+ int t = addrtypeof(src);
|
|
+# define TF(t, f) (((t)<<8) | (f))
|
|
+
|
|
+ n = addrbytesptr(src, &b);
|
|
+ if (n == 0) {
|
|
+ bad:
|
|
+ dst[0]='\0';
|
|
+ strncat(dst, "<invalid>", dstlen);
|
|
+ return sizeof("<invalid>");
|
|
+ }
|
|
+
|
|
+ switch (TF(t, format)) {
|
|
+ case TF(AF_INET, 0):
|
|
+ n = normal4(b, n, buf, &p);
|
|
+ break;
|
|
+ case TF(AF_INET6, 0):
|
|
+ n = normal6(b, n, buf, &p, 1);
|
|
+ break;
|
|
+ case TF(AF_INET, 'Q'):
|
|
+ n = normal4(b, n, buf, &p);
|
|
+ break;
|
|
+ case TF(AF_INET6, 'Q'):
|
|
+ n = normal6(b, n, buf, &p, 0);
|
|
+ break;
|
|
+ case TF(AF_INET, 'r'):
|
|
+ n = reverse4(b, n, buf, &p);
|
|
+ break;
|
|
+ case TF(AF_INET6, 'r'):
|
|
+ n = reverse6(b, n, buf, &p);
|
|
+ break;
|
|
+ default: /* including (AF_INET, 'R') */
|
|
+ goto bad;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (dstlen > 0) {
|
|
+ if (dstlen < n)
|
|
+ p[dstlen - 1] = '\0';
|
|
+ strcpy(dst, p);
|
|
+ }
|
|
+ return n;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - normal4 - normal IPv4 address-text conversion
|
|
+ */
|
|
+static size_t /* size of text, including NUL */
|
|
+normal4(srcp, srclen, buf, dstp)
|
|
+const unsigned char *srcp;
|
|
+size_t srclen;
|
|
+char *buf; /* guaranteed large enough */
|
|
+char **dstp; /* where to put result pointer */
|
|
+{
|
|
+ int i;
|
|
+ char *p;
|
|
+
|
|
+ if (srclen != IP4BYTES) /* "can't happen" */
|
|
+ return 0;
|
|
+ p = buf;
|
|
+ for (i = 0; i < IP4BYTES; i++) {
|
|
+ p += ultot(srcp[i], 10, p, PERBYTE);
|
|
+ if (i != IP4BYTES - 1)
|
|
+ *(p-1) = '.'; /* overwrites the NUL */
|
|
+ }
|
|
+ *dstp = buf;
|
|
+ return p - buf;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - normal6 - normal IPv6 address-text conversion
|
|
+ */
|
|
+static size_t /* size of text, including NUL */
|
|
+normal6(srcp, srclen, buf, dstp, squish)
|
|
+const unsigned char *srcp;
|
|
+size_t srclen;
|
|
+char *buf; /* guaranteed large enough, plus 2 */
|
|
+char **dstp; /* where to put result pointer */
|
|
+int squish; /* whether to squish out 0:0 */
|
|
+{
|
|
+ int i;
|
|
+ unsigned long piece;
|
|
+ char *p;
|
|
+ char *q;
|
|
+
|
|
+ if (srclen != IP6BYTES) /* "can't happen" */
|
|
+ return 0;
|
|
+ p = buf;
|
|
+ *p++ = ':';
|
|
+ for (i = 0; i < IP6BYTES/2; i++) {
|
|
+ piece = (srcp[2*i] << 8) + srcp[2*i + 1];
|
|
+ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
|
|
+ *(p-1) = ':'; /* overwrites the NUL */
|
|
+ }
|
|
+ *p = '\0';
|
|
+ q = strstr(buf, ":0:0:");
|
|
+ if (squish && q != NULL) { /* zero squishing is possible */
|
|
+ p = q + 1;
|
|
+ while (*p == '0' && *(p+1) == ':')
|
|
+ p += 2;
|
|
+ q++;
|
|
+ *q++ = ':'; /* overwrite first 0 */
|
|
+ while (*p != '\0')
|
|
+ *q++ = *p++;
|
|
+ *q = '\0';
|
|
+ if (!(*(q-1) == ':' && *(q-2) == ':'))
|
|
+ *--q = '\0'; /* strip final : unless :: */
|
|
+ p = buf;
|
|
+ if (!(*p == ':' && *(p+1) == ':'))
|
|
+ p++; /* skip initial : unless :: */
|
|
+ } else {
|
|
+ q = p;
|
|
+ *--q = '\0'; /* strip final : */
|
|
+ p = buf + 1; /* skip initial : */
|
|
+ }
|
|
+ *dstp = p;
|
|
+ return q - p + 1;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - reverse4 - IPv4 reverse-lookup conversion
|
|
+ */
|
|
+static size_t /* size of text, including NUL */
|
|
+reverse4(srcp, srclen, buf, dstp)
|
|
+const unsigned char *srcp;
|
|
+size_t srclen;
|
|
+char *buf; /* guaranteed large enough */
|
|
+char **dstp; /* where to put result pointer */
|
|
+{
|
|
+ int i;
|
|
+ char *p;
|
|
+
|
|
+ if (srclen != IP4BYTES) /* "can't happen" */
|
|
+ return 0;
|
|
+ p = buf;
|
|
+ for (i = IP4BYTES-1; i >= 0; i--) {
|
|
+ p += ultot(srcp[i], 10, p, PERBYTE);
|
|
+ *(p-1) = '.'; /* overwrites the NUL */
|
|
+ }
|
|
+ strcpy(p, "IN-ADDR.ARPA.");
|
|
+ *dstp = buf;
|
|
+ return strlen(buf) + 1;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
|
|
+ * A trifle inefficient, really shouldn't use ultot...
|
|
+ */
|
|
+static size_t /* size of text, including NUL */
|
|
+reverse6(srcp, srclen, buf, dstp)
|
|
+const unsigned char *srcp;
|
|
+size_t srclen;
|
|
+char *buf; /* guaranteed large enough */
|
|
+char **dstp; /* where to put result pointer */
|
|
+{
|
|
+ int i;
|
|
+ unsigned long piece;
|
|
+ char *p;
|
|
+
|
|
+ if (srclen != IP6BYTES) /* "can't happen" */
|
|
+ return 0;
|
|
+ p = buf;
|
|
+ for (i = IP6BYTES-1; i >= 0; i--) {
|
|
+ piece = srcp[i];
|
|
+ p += ultot(piece&0xf, 16, p, 2);
|
|
+ *(p-1) = '.';
|
|
+ p += ultot(piece>>4, 16, p, 2);
|
|
+ *(p-1) = '.';
|
|
+ }
|
|
+ strcpy(p, "IP6.ARPA.");
|
|
+ *dstp = buf;
|
|
+ return strlen(buf) + 1;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
|
|
+ * this version removed as it was obsoleted in the end.
|
|
+ */
|
|
+
|
|
+#ifdef ADDRTOT_MAIN
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <sys/socket.h>
|
|
+#include <netinet/in.h>
|
|
+#include <arpa/inet.h>
|
|
+
|
|
+void regress(void);
|
|
+
|
|
+int
|
|
+main(int argc, char *argv[])
|
|
+{
|
|
+ if (argc < 2) {
|
|
+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
|
|
+ argv[0]);
|
|
+ exit(2);
|
|
+ }
|
|
+
|
|
+ if (strcmp(argv[1], "-r") == 0) {
|
|
+ regress();
|
|
+ fprintf(stderr, "regress() returned?!?\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ exit(0);
|
|
+}
|
|
+
|
|
+struct rtab {
|
|
+ char *input;
|
|
+ char format;
|
|
+ char *output; /* NULL means error expected */
|
|
+} rtab[] = {
|
|
+ {"1.2.3.0", 0, "1.2.3.0"},
|
|
+ {"1:2::3:4", 0, "1:2::3:4"},
|
|
+ {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
|
|
+ {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
|
|
+ {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
|
|
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
|
+ {"1:2::3:4", 'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."},
|
|
+ {NULL, 0, NULL}
|
|
+};
|
|
+
|
|
+void
|
|
+regress()
|
|
+{
|
|
+ struct rtab *r;
|
|
+ int status = 0;
|
|
+ ip_address a;
|
|
+ char in[100];
|
|
+ char buf[100];
|
|
+ const char *oops;
|
|
+ size_t n;
|
|
+
|
|
+ for (r = rtab; r->input != NULL; r++) {
|
|
+ strcpy(in, r->input);
|
|
+
|
|
+ /* convert it *to* internal format */
|
|
+ oops = ttoaddr(in, strlen(in), 0, &a);
|
|
+
|
|
+ /* now convert it back */
|
|
+
|
|
+ n = addrtot(&a, r->format, buf, sizeof(buf));
|
|
+
|
|
+ if (n == 0 && r->output == NULL)
|
|
+ {} /* okay, error expected */
|
|
+
|
|
+ else if (n == 0) {
|
|
+ printf("`%s' atoasr failed\n", r->input);
|
|
+ status = 1;
|
|
+
|
|
+ } else if (r->output == NULL) {
|
|
+ printf("`%s' atoasr succeeded unexpectedly '%c'\n",
|
|
+ r->input, r->format);
|
|
+ status = 1;
|
|
+ } else {
|
|
+ if (strcasecmp(r->output, buf) != 0) {
|
|
+ printf("`%s' '%c' gave `%s', expected `%s'\n",
|
|
+ r->input, r->format, buf, r->output);
|
|
+ status = 1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ exit(status);
|
|
+}
|
|
+
|
|
+#endif /* ADDRTOT_MAIN */
|
|
+
|
|
+/*
|
|
+ * $Log: addrtot.c,v $
|
|
+ * Revision 1.22.2.1 2005/11/17 22:30:49 paul
|
|
+ * pull up strstr fix from head.
|
|
+ *
|
|
+ * Revision 1.22 2005/05/20 16:47:40 mcr
|
|
+ * make strstr static if we need it.
|
|
+ *
|
|
+ * Revision 1.21 2005/03/21 00:35:12 mcr
|
|
+ * test for strstr properly
|
|
+ *
|
|
+ * Revision 1.20 2004/11/09 22:52:20 mcr
|
|
+ * until we figure out which kernels have strsep and which
|
|
+ * do not (UML does not under certain circumstances), then
|
|
+ * let's just provide our own.
|
|
+ *
|
|
+ * Revision 1.19 2004/10/08 16:30:33 mcr
|
|
+ * pull-up of initial crypto-offload work.
|
|
+ *
|
|
+ * Revision 1.18 2004/09/18 19:33:08 mcr
|
|
+ * use an appropriate kernel happy ifdef for strstr.
|
|
+ *
|
|
+ * Revision 1.17 2004/09/15 21:49:02 mcr
|
|
+ * use local copy of strstr() if this is going in the kernel.
|
|
+ * Not clear why this worked before, or why this shows up
|
|
+ * for modules only.
|
|
+ *
|
|
+ * Revision 1.16 2004/07/10 07:43:47 mcr
|
|
+ * Moved from linux/lib/libfreeswan/addrtot.c,v
|
|
+ *
|
|
+ * Revision 1.15 2004/04/11 17:39:25 mcr
|
|
+ * removed internal.h requirements.
|
|
+ *
|
|
+ * Revision 1.14 2004/03/08 01:59:08 ken
|
|
+ * freeswan.h -> openswan.h
|
|
+ *
|
|
+ * Revision 1.13 2004/01/05 23:21:05 mcr
|
|
+ * if the address type is invalid, then return length of <invalid>
|
|
+ * string!
|
|
+ *
|
|
+ * Revision 1.12 2003/12/30 06:42:48 mcr
|
|
+ * added $Log: addrtot.c,v $
|
|
+ * added Revision 1.22.2.1 2005/11/17 22:30:49 paul
|
|
+ * added pull up strstr fix from head.
|
|
+ * added
|
|
+ * added Revision 1.22 2005/05/20 16:47:40 mcr
|
|
+ * added make strstr static if we need it.
|
|
+ * added
|
|
+ * added Revision 1.21 2005/03/21 00:35:12 mcr
|
|
+ * added test for strstr properly
|
|
+ * added
|
|
+ * added Revision 1.20 2004/11/09 22:52:20 mcr
|
|
+ * added until we figure out which kernels have strsep and which
|
|
+ * added do not (UML does not under certain circumstances), then
|
|
+ * added let's just provide our own.
|
|
+ * added
|
|
+ * added Revision 1.19 2004/10/08 16:30:33 mcr
|
|
+ * added pull-up of initial crypto-offload work.
|
|
+ * added
|
|
+ * added Revision 1.18 2004/09/18 19:33:08 mcr
|
|
+ * added use an appropriate kernel happy ifdef for strstr.
|
|
+ * added
|
|
+ * added Revision 1.17 2004/09/15 21:49:02 mcr
|
|
+ * added use local copy of strstr() if this is going in the kernel.
|
|
+ * added Not clear why this worked before, or why this shows up
|
|
+ * added for modules only.
|
|
+ * added
|
|
+ * added Revision 1.16 2004/07/10 07:43:47 mcr
|
|
+ * added Moved from linux/lib/libfreeswan/addrtot.c,v
|
|
+ * added
|
|
+ * added Revision 1.15 2004/04/11 17:39:25 mcr
|
|
+ * added removed internal.h requirements.
|
|
+ * added
|
|
+ * added Revision 1.14 2004/03/08 01:59:08 ken
|
|
+ * added freeswan.h -> openswan.h
|
|
+ * added
|
|
+ * added Revision 1.13 2004/01/05 23:21:05 mcr
|
|
+ * added if the address type is invalid, then return length of <invalid>
|
|
+ * added string!
|
|
+ * added
|
|
+ *
|
|
+ *
|
|
+ */
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/addrtypeof.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,93 @@
|
|
+/*
|
|
+ * extract parts of an ip_address
|
|
+ * Copyright (C) 2000 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: addrtypeof.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+/*
|
|
+ - addrtypeof - get the type of an ip_address
|
|
+ */
|
|
+int
|
|
+addrtypeof(src)
|
|
+const ip_address *src;
|
|
+{
|
|
+ return src->u.v4.sin_family;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - addrbytesptr - get pointer to the address bytes of an ip_address
|
|
+ */
|
|
+size_t /* 0 for error */
|
|
+addrbytesptr(src, dstp)
|
|
+const ip_address *src;
|
|
+const unsigned char **dstp; /* NULL means just a size query */
|
|
+{
|
|
+ const unsigned char *p;
|
|
+ size_t n;
|
|
+
|
|
+ switch (src->u.v4.sin_family) {
|
|
+ case AF_INET:
|
|
+ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
|
|
+ n = 4;
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ p = (const unsigned char *)&src->u.v6.sin6_addr;
|
|
+ n = 16;
|
|
+ break;
|
|
+ default:
|
|
+ return 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (dstp != NULL)
|
|
+ *dstp = p;
|
|
+ return n;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - addrlenof - get length of the address bytes of an ip_address
|
|
+ */
|
|
+size_t /* 0 for error */
|
|
+addrlenof(src)
|
|
+const ip_address *src;
|
|
+{
|
|
+ return addrbytesptr(src, NULL);
|
|
+}
|
|
+
|
|
+/*
|
|
+ - addrbytesof - get the address bytes of an ip_address
|
|
+ */
|
|
+size_t /* 0 for error */
|
|
+addrbytesof(src, dst, dstlen)
|
|
+const ip_address *src;
|
|
+unsigned char *dst;
|
|
+size_t dstlen;
|
|
+{
|
|
+ const unsigned char *p;
|
|
+ size_t n;
|
|
+ size_t ncopy;
|
|
+
|
|
+ n = addrbytesptr(src, &p);
|
|
+ if (n == 0)
|
|
+ return 0;
|
|
+
|
|
+ if (dstlen > 0) {
|
|
+ ncopy = n;
|
|
+ if (ncopy > dstlen)
|
|
+ ncopy = dstlen;
|
|
+ memcpy(dst, p, ncopy);
|
|
+ }
|
|
+ return n;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/adler32.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,49 @@
|
|
+/* adler32.c -- compute the Adler-32 checksum of a data stream
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* @(#) $Id: adler32.c,v 1.6 2004/07/10 19:11:18 mcr Exp $ */
|
|
+
|
|
+#include <zlib/zlib.h>
|
|
+#include <zlib/zconf.h>
|
|
+
|
|
+#define BASE 65521L /* largest prime smaller than 65536 */
|
|
+#define NMAX 5552
|
|
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
|
+
|
|
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
|
|
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
|
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
|
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
|
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
|
+
|
|
+/* ========================================================================= */
|
|
+uLong ZEXPORT adler32(adler, buf, len)
|
|
+ uLong adler;
|
|
+ const Bytef *buf;
|
|
+ uInt len;
|
|
+{
|
|
+ unsigned long s1 = adler & 0xffff;
|
|
+ unsigned long s2 = (adler >> 16) & 0xffff;
|
|
+ int k;
|
|
+
|
|
+ if (buf == Z_NULL) return 1L;
|
|
+
|
|
+ while (len > 0) {
|
|
+ k = len < NMAX ? len : NMAX;
|
|
+ len -= k;
|
|
+ while (k >= 16) {
|
|
+ DO16(buf);
|
|
+ buf += 16;
|
|
+ k -= 16;
|
|
+ }
|
|
+ if (k != 0) do {
|
|
+ s1 += *buf++;
|
|
+ s2 += s1;
|
|
+ } while (--k);
|
|
+ s1 %= BASE;
|
|
+ s2 %= BASE;
|
|
+ }
|
|
+ return (s2 << 16) | s1;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/aes/Makefile Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,59 @@
|
|
+# Makefile for KLIPS 3DES kernel code as a module for 2.6 kernels
|
|
+#
|
|
+# Makefile for KLIPS kernel code as a module
|
|
+# Copyright (C) 2002-2004 Michael Richardson <mcr@xelerance.com>
|
|
+#
|
|
+# This program is free software; you can redistribute it and/or modify it
|
|
+# under the terms of the GNU General Public License as published by the
|
|
+# Free Software Foundation; either version 2 of the License, or (at your
|
|
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+#
|
|
+# This program is distributed in the hope that it will be useful, but
|
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+# for more details.
|
|
+#
|
|
+# RCSID $Id: Makefile.fs2_6,v 1.1.10.1 2005/08/12 16:10:05 ken Exp $
|
|
+#
|
|
+# Note! Dependencies are done automagically by 'make dep', which also
|
|
+# removes any old dependencies. DON'T put your own dependencies here
|
|
+# unless it's something special (ie not a .c file).
|
|
+#
|
|
+
|
|
+obj-$(CONFIG_KLIPS_ENC_AES) += ipsec_alg_aes.o
|
|
+obj-$(CONFIG_KLIPS_ENC_AES) += aes_xcbc_mac.o
|
|
+obj-$(CONFIG_KLIPS_ENC_AES) += aes_cbc.o
|
|
+
|
|
+ifeq ($(strip ${SUBARCH}),)
|
|
+SUBARCH:=${ARCH}
|
|
+endif
|
|
+
|
|
+# the assembly version expects frame pointers, which are
|
|
+# optional in many kernel builds. If you want speed, you should
|
|
+# probably use cryptoapi code instead.
|
|
+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
|
|
+ifeq (${USEASSEMBLY},i386y)
|
|
+obj-$(CONFIG_KLIPS_ENC_AES) += aes-i586.o
|
|
+else
|
|
+obj-$(CONFIG_KLIPS_ENC_AES) += aes.o
|
|
+endif
|
|
+
|
|
+
|
|
+#
|
|
+# $Log: Makefile.fs2_6,v $
|
|
+# Revision 1.1.10.1 2005/08/12 16:10:05 ken
|
|
+# do not use assembly code with there are no frame pointers
|
|
+#
|
|
+# Revision 1.2 2005/08/12 14:13:58 mcr
|
|
+# do not use assembly code with there are no frame pointers,
|
|
+# as it does not have the right linkages.
|
|
+#
|
|
+# Revision 1.1 2004/08/17 03:31:34 mcr
|
|
+# klips 2.6 edits.
|
|
+#
|
|
+#
|
|
+# Local Variables:
|
|
+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
|
|
+# End Variables:
|
|
+#
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/aes/aes-i586.S Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,892 @@
|
|
+//
|
|
+// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
|
|
+// All rights reserved.
|
|
+//
|
|
+// TERMS
|
|
+//
|
|
+// Redistribution and use in source and binary forms, with or without
|
|
+// modification, are permitted subject to the following conditions:
|
|
+//
|
|
+// 1. Redistributions of source code must retain the above copyright
|
|
+// notice, this list of conditions and the following disclaimer.
|
|
+//
|
|
+// 2. Redistributions in binary form must reproduce the above copyright
|
|
+// notice, this list of conditions and the following disclaimer in the
|
|
+// documentation and/or other materials provided with the distribution.
|
|
+//
|
|
+// 3. The copyright holder's name must not be used to endorse or promote
|
|
+// any products derived from this software without his specific prior
|
|
+// written permission.
|
|
+//
|
|
+// This software is provided 'as is' with no express or implied warranties
|
|
+// of correctness or fitness for purpose.
|
|
+
|
|
+// Modified by Jari Ruusu, December 24 2001
|
|
+// - Converted syntax to GNU CPP/assembler syntax
|
|
+// - C programming interface converted back to "old" API
|
|
+// - Minor portability cleanups and speed optimizations
|
|
+
|
|
+// An AES (Rijndael) implementation for the Pentium. This version only
|
|
+// implements the standard AES block length (128 bits, 16 bytes). This code
|
|
+// does not preserve the eax, ecx or edx registers or the artihmetic status
|
|
+// flags. However, the ebx, esi, edi, and ebp registers are preserved across
|
|
+// calls.
|
|
+
|
|
+// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
|
|
+// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
|
|
+// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
|
|
+
|
|
+#if defined(USE_UNDERLINE)
|
|
+# define aes_set_key _aes_set_key
|
|
+# define aes_encrypt _aes_encrypt
|
|
+# define aes_decrypt _aes_decrypt
|
|
+#endif
|
|
+#if !defined(ALIGN32BYTES)
|
|
+# define ALIGN32BYTES 32
|
|
+#endif
|
|
+
|
|
+ .file "aes-i586.S"
|
|
+ .globl aes_set_key
|
|
+ .globl aes_encrypt
|
|
+ .globl aes_decrypt
|
|
+
|
|
+#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
|
|
+
|
|
+// offsets to parameters with one register pushed onto stack
|
|
+
|
|
+#define ctx 8 // AES context structure
|
|
+#define in_blk 12 // input byte array address parameter
|
|
+#define out_blk 16 // output byte array address parameter
|
|
+
|
|
+// offsets in context structure
|
|
+
|
|
+#define nkey 0 // key length, size 4
|
|
+#define nrnd 4 // number of rounds, size 4
|
|
+#define ekey 8 // encryption key schedule base address, size 256
|
|
+#define dkey 264 // decryption key schedule base address, size 256
|
|
+
|
|
+// This macro performs a forward encryption cycle. It is entered with
|
|
+// the first previous round column values in %eax, %ebx, %esi and %edi and
|
|
+// exits with the final values in the same registers.
|
|
+
|
|
+#define fwd_rnd(p1,p2) \
|
|
+ mov %ebx,(%esp) ;\
|
|
+ movzbl %al,%edx ;\
|
|
+ mov %eax,%ecx ;\
|
|
+ mov p2(%ebp),%eax ;\
|
|
+ mov %edi,4(%esp) ;\
|
|
+ mov p2+12(%ebp),%edi ;\
|
|
+ xor p1(,%edx,4),%eax ;\
|
|
+ movzbl %ch,%edx ;\
|
|
+ shr $16,%ecx ;\
|
|
+ mov p2+4(%ebp),%ebx ;\
|
|
+ xor p1+tlen(,%edx,4),%edi ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ movzbl %ch,%ecx ;\
|
|
+ xor p1+3*tlen(,%ecx,4),%ebx ;\
|
|
+ mov %esi,%ecx ;\
|
|
+ mov p1+2*tlen(,%edx,4),%esi ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ xor p1(,%edx,4),%esi ;\
|
|
+ movzbl %ch,%edx ;\
|
|
+ shr $16,%ecx ;\
|
|
+ xor p1+tlen(,%edx,4),%ebx ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ movzbl %ch,%ecx ;\
|
|
+ xor p1+2*tlen(,%edx,4),%eax ;\
|
|
+ mov (%esp),%edx ;\
|
|
+ xor p1+3*tlen(,%ecx,4),%edi ;\
|
|
+ movzbl %dl,%ecx ;\
|
|
+ xor p2+8(%ebp),%esi ;\
|
|
+ xor p1(,%ecx,4),%ebx ;\
|
|
+ movzbl %dh,%ecx ;\
|
|
+ shr $16,%edx ;\
|
|
+ xor p1+tlen(,%ecx,4),%eax ;\
|
|
+ movzbl %dl,%ecx ;\
|
|
+ movzbl %dh,%edx ;\
|
|
+ xor p1+2*tlen(,%ecx,4),%edi ;\
|
|
+ mov 4(%esp),%ecx ;\
|
|
+ xor p1+3*tlen(,%edx,4),%esi ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ xor p1(,%edx,4),%edi ;\
|
|
+ movzbl %ch,%edx ;\
|
|
+ shr $16,%ecx ;\
|
|
+ xor p1+tlen(,%edx,4),%esi ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ movzbl %ch,%ecx ;\
|
|
+ xor p1+2*tlen(,%edx,4),%ebx ;\
|
|
+ xor p1+3*tlen(,%ecx,4),%eax
|
|
+
|
|
+// This macro performs an inverse encryption cycle. It is entered with
|
|
+// the first previous round column values in %eax, %ebx, %esi and %edi and
|
|
+// exits with the final values in the same registers.
|
|
+
|
|
+#define inv_rnd(p1,p2) \
|
|
+ movzbl %al,%edx ;\
|
|
+ mov %ebx,(%esp) ;\
|
|
+ mov %eax,%ecx ;\
|
|
+ mov p2(%ebp),%eax ;\
|
|
+ mov %edi,4(%esp) ;\
|
|
+ mov p2+4(%ebp),%ebx ;\
|
|
+ xor p1(,%edx,4),%eax ;\
|
|
+ movzbl %ch,%edx ;\
|
|
+ shr $16,%ecx ;\
|
|
+ mov p2+12(%ebp),%edi ;\
|
|
+ xor p1+tlen(,%edx,4),%ebx ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ movzbl %ch,%ecx ;\
|
|
+ xor p1+3*tlen(,%ecx,4),%edi ;\
|
|
+ mov %esi,%ecx ;\
|
|
+ mov p1+2*tlen(,%edx,4),%esi ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ xor p1(,%edx,4),%esi ;\
|
|
+ movzbl %ch,%edx ;\
|
|
+ shr $16,%ecx ;\
|
|
+ xor p1+tlen(,%edx,4),%edi ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ movzbl %ch,%ecx ;\
|
|
+ xor p1+2*tlen(,%edx,4),%eax ;\
|
|
+ mov (%esp),%edx ;\
|
|
+ xor p1+3*tlen(,%ecx,4),%ebx ;\
|
|
+ movzbl %dl,%ecx ;\
|
|
+ xor p2+8(%ebp),%esi ;\
|
|
+ xor p1(,%ecx,4),%ebx ;\
|
|
+ movzbl %dh,%ecx ;\
|
|
+ shr $16,%edx ;\
|
|
+ xor p1+tlen(,%ecx,4),%esi ;\
|
|
+ movzbl %dl,%ecx ;\
|
|
+ movzbl %dh,%edx ;\
|
|
+ xor p1+2*tlen(,%ecx,4),%edi ;\
|
|
+ mov 4(%esp),%ecx ;\
|
|
+ xor p1+3*tlen(,%edx,4),%eax ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ xor p1(,%edx,4),%edi ;\
|
|
+ movzbl %ch,%edx ;\
|
|
+ shr $16,%ecx ;\
|
|
+ xor p1+tlen(,%edx,4),%eax ;\
|
|
+ movzbl %cl,%edx ;\
|
|
+ movzbl %ch,%ecx ;\
|
|
+ xor p1+2*tlen(,%edx,4),%ebx ;\
|
|
+ xor p1+3*tlen(,%ecx,4),%esi
|
|
+
|
|
+// AES (Rijndael) Encryption Subroutine
|
|
+
|
|
+ .text
|
|
+ .align ALIGN32BYTES
|
|
+aes_encrypt:
|
|
+ push %ebp
|
|
+ mov ctx(%esp),%ebp // pointer to context
|
|
+ mov in_blk(%esp),%ecx
|
|
+ push %ebx
|
|
+ push %esi
|
|
+ push %edi
|
|
+ mov nrnd(%ebp),%edx // number of rounds
|
|
+ lea ekey+16(%ebp),%ebp // key pointer
|
|
+
|
|
+// input four columns and xor in first round key
|
|
+
|
|
+ mov (%ecx),%eax
|
|
+ mov 4(%ecx),%ebx
|
|
+ mov 8(%ecx),%esi
|
|
+ mov 12(%ecx),%edi
|
|
+ xor -16(%ebp),%eax
|
|
+ xor -12(%ebp),%ebx
|
|
+ xor -8(%ebp),%esi
|
|
+ xor -4(%ebp),%edi
|
|
+
|
|
+ sub $8,%esp // space for register saves on stack
|
|
+
|
|
+ sub $10,%edx
|
|
+ je aes_15
|
|
+ add $32,%ebp
|
|
+ sub $2,%edx
|
|
+ je aes_13
|
|
+ add $32,%ebp
|
|
+
|
|
+ fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
|
|
+ fwd_rnd(aes_ft_tab,-48)
|
|
+aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
|
|
+ fwd_rnd(aes_ft_tab,-16)
|
|
+aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
|
|
+ fwd_rnd(aes_ft_tab,16)
|
|
+ fwd_rnd(aes_ft_tab,32)
|
|
+ fwd_rnd(aes_ft_tab,48)
|
|
+ fwd_rnd(aes_ft_tab,64)
|
|
+ fwd_rnd(aes_ft_tab,80)
|
|
+ fwd_rnd(aes_ft_tab,96)
|
|
+ fwd_rnd(aes_ft_tab,112)
|
|
+ fwd_rnd(aes_ft_tab,128)
|
|
+ fwd_rnd(aes_fl_tab,144) // last round uses a different table
|
|
+
|
|
+// move final values to the output array.
|
|
+
|
|
+ mov out_blk+20(%esp),%ebp
|
|
+ add $8,%esp
|
|
+ mov %eax,(%ebp)
|
|
+ mov %ebx,4(%ebp)
|
|
+ mov %esi,8(%ebp)
|
|
+ mov %edi,12(%ebp)
|
|
+ pop %edi
|
|
+ pop %esi
|
|
+ pop %ebx
|
|
+ pop %ebp
|
|
+ ret
|
|
+
|
|
+
|
|
+// AES (Rijndael) Decryption Subroutine
|
|
+
|
|
+ .align ALIGN32BYTES
|
|
+aes_decrypt:
|
|
+ push %ebp
|
|
+ mov ctx(%esp),%ebp // pointer to context
|
|
+ mov in_blk(%esp),%ecx
|
|
+ push %ebx
|
|
+ push %esi
|
|
+ push %edi
|
|
+ mov nrnd(%ebp),%edx // number of rounds
|
|
+ lea dkey+16(%ebp),%ebp // key pointer
|
|
+
|
|
+// input four columns and xor in first round key
|
|
+
|
|
+ mov (%ecx),%eax
|
|
+ mov 4(%ecx),%ebx
|
|
+ mov 8(%ecx),%esi
|
|
+ mov 12(%ecx),%edi
|
|
+ xor -16(%ebp),%eax
|
|
+ xor -12(%ebp),%ebx
|
|
+ xor -8(%ebp),%esi
|
|
+ xor -4(%ebp),%edi
|
|
+
|
|
+ sub $8,%esp // space for register saves on stack
|
|
+
|
|
+ sub $10,%edx
|
|
+ je aes_25
|
|
+ add $32,%ebp
|
|
+ sub $2,%edx
|
|
+ je aes_23
|
|
+ add $32,%ebp
|
|
+
|
|
+ inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
|
|
+ inv_rnd(aes_it_tab,-48)
|
|
+aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
|
|
+ inv_rnd(aes_it_tab,-16)
|
|
+aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
|
|
+ inv_rnd(aes_it_tab,16)
|
|
+ inv_rnd(aes_it_tab,32)
|
|
+ inv_rnd(aes_it_tab,48)
|
|
+ inv_rnd(aes_it_tab,64)
|
|
+ inv_rnd(aes_it_tab,80)
|
|
+ inv_rnd(aes_it_tab,96)
|
|
+ inv_rnd(aes_it_tab,112)
|
|
+ inv_rnd(aes_it_tab,128)
|
|
+ inv_rnd(aes_il_tab,144) // last round uses a different table
|
|
+
|
|
+// move final values to the output array.
|
|
+
|
|
+ mov out_blk+20(%esp),%ebp
|
|
+ add $8,%esp
|
|
+ mov %eax,(%ebp)
|
|
+ mov %ebx,4(%ebp)
|
|
+ mov %esi,8(%ebp)
|
|
+ mov %edi,12(%ebp)
|
|
+ pop %edi
|
|
+ pop %esi
|
|
+ pop %ebx
|
|
+ pop %ebp
|
|
+ ret
|
|
+
|
|
+// AES (Rijndael) Key Schedule Subroutine
|
|
+
|
|
+// input/output parameters
|
|
+
|
|
+#define aes_cx 12 // AES context
|
|
+#define in_key 16 // key input array address
|
|
+#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
|
|
+#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
|
|
+
|
|
+// offsets for locals
|
|
+
|
|
+#define cnt -4
|
|
+#define kpf -8
|
|
+#define slen 8
|
|
+
|
|
+// This macro performs a column mixing operation on an input 32-bit
|
|
+// word to give a 32-bit result. It uses each of the 4 bytes in the
|
|
+// the input column to index 4 different tables of 256 32-bit words
|
|
+// that are xored together to form the output value.
|
|
+
|
|
+#define mix_col(p1) \
|
|
+ movzbl %bl,%ecx ;\
|
|
+ mov p1(,%ecx,4),%eax ;\
|
|
+ movzbl %bh,%ecx ;\
|
|
+ ror $16,%ebx ;\
|
|
+ xor p1+tlen(,%ecx,4),%eax ;\
|
|
+ movzbl %bl,%ecx ;\
|
|
+ xor p1+2*tlen(,%ecx,4),%eax ;\
|
|
+ movzbl %bh,%ecx ;\
|
|
+ xor p1+3*tlen(,%ecx,4),%eax
|
|
+
|
|
+// Key Schedule Macros
|
|
+
|
|
+#define ksc4(p1) \
|
|
+ rol $24,%ebx ;\
|
|
+ mix_col(aes_fl_tab) ;\
|
|
+ ror $8,%ebx ;\
|
|
+ xor 4*p1+aes_rcon_tab,%eax ;\
|
|
+ xor %eax,%esi ;\
|
|
+ xor %esi,%ebp ;\
|
|
+ mov %esi,16*p1(%edi) ;\
|
|
+ mov %ebp,16*p1+4(%edi) ;\
|
|
+ xor %ebp,%edx ;\
|
|
+ xor %edx,%ebx ;\
|
|
+ mov %edx,16*p1+8(%edi) ;\
|
|
+ mov %ebx,16*p1+12(%edi)
|
|
+
|
|
+#define ksc6(p1) \
|
|
+ rol $24,%ebx ;\
|
|
+ mix_col(aes_fl_tab) ;\
|
|
+ ror $8,%ebx ;\
|
|
+ xor 4*p1+aes_rcon_tab,%eax ;\
|
|
+ xor 24*p1-24(%edi),%eax ;\
|
|
+ mov %eax,24*p1(%edi) ;\
|
|
+ xor 24*p1-20(%edi),%eax ;\
|
|
+ mov %eax,24*p1+4(%edi) ;\
|
|
+ xor %eax,%esi ;\
|
|
+ xor %esi,%ebp ;\
|
|
+ mov %esi,24*p1+8(%edi) ;\
|
|
+ mov %ebp,24*p1+12(%edi) ;\
|
|
+ xor %ebp,%edx ;\
|
|
+ xor %edx,%ebx ;\
|
|
+ mov %edx,24*p1+16(%edi) ;\
|
|
+ mov %ebx,24*p1+20(%edi)
|
|
+
|
|
+#define ksc8(p1) \
|
|
+ rol $24,%ebx ;\
|
|
+ mix_col(aes_fl_tab) ;\
|
|
+ ror $8,%ebx ;\
|
|
+ xor 4*p1+aes_rcon_tab,%eax ;\
|
|
+ xor 32*p1-32(%edi),%eax ;\
|
|
+ mov %eax,32*p1(%edi) ;\
|
|
+ xor 32*p1-28(%edi),%eax ;\
|
|
+ mov %eax,32*p1+4(%edi) ;\
|
|
+ xor 32*p1-24(%edi),%eax ;\
|
|
+ mov %eax,32*p1+8(%edi) ;\
|
|
+ xor 32*p1-20(%edi),%eax ;\
|
|
+ mov %eax,32*p1+12(%edi) ;\
|
|
+ push %ebx ;\
|
|
+ mov %eax,%ebx ;\
|
|
+ mix_col(aes_fl_tab) ;\
|
|
+ pop %ebx ;\
|
|
+ xor %eax,%esi ;\
|
|
+ xor %esi,%ebp ;\
|
|
+ mov %esi,32*p1+16(%edi) ;\
|
|
+ mov %ebp,32*p1+20(%edi) ;\
|
|
+ xor %ebp,%edx ;\
|
|
+ xor %edx,%ebx ;\
|
|
+ mov %edx,32*p1+24(%edi) ;\
|
|
+ mov %ebx,32*p1+28(%edi)
|
|
+
|
|
+ .align ALIGN32BYTES
|
|
+aes_set_key:
|
|
+ pushfl
|
|
+ push %ebp
|
|
+ mov %esp,%ebp
|
|
+ sub $slen,%esp
|
|
+ push %ebx
|
|
+ push %esi
|
|
+ push %edi
|
|
+
|
|
+ mov aes_cx(%ebp),%edx // edx -> AES context
|
|
+
|
|
+ mov key_ln(%ebp),%ecx // key length
|
|
+ cmpl $128,%ecx
|
|
+ jb aes_30
|
|
+ shr $3,%ecx
|
|
+aes_30: cmpl $32,%ecx
|
|
+ je aes_32
|
|
+ cmpl $24,%ecx
|
|
+ je aes_32
|
|
+ mov $16,%ecx
|
|
+aes_32: shr $2,%ecx
|
|
+ mov %ecx,nkey(%edx)
|
|
+
|
|
+ lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
|
|
+ mov %eax,nrnd(%edx)
|
|
+
|
|
+ mov in_key(%ebp),%esi // key input array
|
|
+ lea ekey(%edx),%edi // key position in AES context
|
|
+ cld
|
|
+ push %ebp
|
|
+ mov %ecx,%eax // save key length in eax
|
|
+ rep ; movsl // words in the key schedule
|
|
+ mov -4(%esi),%ebx // put some values in registers
|
|
+ mov -8(%esi),%edx // to allow faster code
|
|
+ mov -12(%esi),%ebp
|
|
+ mov -16(%esi),%esi
|
|
+
|
|
+ cmpl $4,%eax // jump on key size
|
|
+ je aes_36
|
|
+ cmpl $6,%eax
|
|
+ je aes_35
|
|
+
|
|
+ ksc8(0)
|
|
+ ksc8(1)
|
|
+ ksc8(2)
|
|
+ ksc8(3)
|
|
+ ksc8(4)
|
|
+ ksc8(5)
|
|
+ ksc8(6)
|
|
+ jmp aes_37
|
|
+aes_35: ksc6(0)
|
|
+ ksc6(1)
|
|
+ ksc6(2)
|
|
+ ksc6(3)
|
|
+ ksc6(4)
|
|
+ ksc6(5)
|
|
+ ksc6(6)
|
|
+ ksc6(7)
|
|
+ jmp aes_37
|
|
+aes_36: ksc4(0)
|
|
+ ksc4(1)
|
|
+ ksc4(2)
|
|
+ ksc4(3)
|
|
+ ksc4(4)
|
|
+ ksc4(5)
|
|
+ ksc4(6)
|
|
+ ksc4(7)
|
|
+ ksc4(8)
|
|
+ ksc4(9)
|
|
+aes_37: pop %ebp
|
|
+ mov aes_cx(%ebp),%edx // edx -> AES context
|
|
+ cmpl $0,ed_flg(%ebp)
|
|
+ jne aes_39
|
|
+
|
|
+// compile decryption key schedule from encryption schedule - reverse
|
|
+// order and do mix_column operation on round keys except first and last
|
|
+
|
|
+ mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
|
|
+ shl $2,%eax
|
|
+ lea dkey(%edx,%eax,4),%edi
|
|
+ lea ekey(%edx),%esi // kf = cx->e_key
|
|
+
|
|
+ movsl // copy first round key (unmodified)
|
|
+ movsl
|
|
+ movsl
|
|
+ movsl
|
|
+ sub $32,%edi
|
|
+ movl $1,cnt(%ebp)
|
|
+aes_38: // do mix column on each column of
|
|
+ lodsl // each round key
|
|
+ mov %eax,%ebx
|
|
+ mix_col(aes_im_tab)
|
|
+ stosl
|
|
+ lodsl
|
|
+ mov %eax,%ebx
|
|
+ mix_col(aes_im_tab)
|
|
+ stosl
|
|
+ lodsl
|
|
+ mov %eax,%ebx
|
|
+ mix_col(aes_im_tab)
|
|
+ stosl
|
|
+ lodsl
|
|
+ mov %eax,%ebx
|
|
+ mix_col(aes_im_tab)
|
|
+ stosl
|
|
+ sub $32,%edi
|
|
+
|
|
+ incl cnt(%ebp)
|
|
+ mov cnt(%ebp),%eax
|
|
+ cmp nrnd(%edx),%eax
|
|
+ jb aes_38
|
|
+
|
|
+ movsl // copy last round key (unmodified)
|
|
+ movsl
|
|
+ movsl
|
|
+ movsl
|
|
+aes_39: pop %edi
|
|
+ pop %esi
|
|
+ pop %ebx
|
|
+ mov %ebp,%esp
|
|
+ pop %ebp
|
|
+ popfl
|
|
+ ret
|
|
+
|
|
+
|
|
+// finite field multiplies by {02}, {04} and {08}
|
|
+
|
|
+#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
|
|
+#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
|
|
+#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
|
|
+
|
|
+// finite field multiplies required in table generation
|
|
+
|
|
+#define f3(x) (f2(x) ^ x)
|
|
+#define f9(x) (f8(x) ^ x)
|
|
+#define fb(x) (f8(x) ^ f2(x) ^ x)
|
|
+#define fd(x) (f8(x) ^ f4(x) ^ x)
|
|
+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
|
|
+
|
|
+// These defines generate the forward table entries
|
|
+
|
|
+#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
|
|
+#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
|
|
+#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
|
|
+#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
|
|
+
|
|
+// These defines generate the inverse table entries
|
|
+
|
|
+#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
|
|
+#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
|
|
+#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
|
|
+#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
|
|
+
|
|
+// These defines generate entries for the last round tables
|
|
+
|
|
+#define w0(x) (x)
|
|
+#define w1(x) (x << 8)
|
|
+#define w2(x) (x << 16)
|
|
+#define w3(x) (x << 24)
|
|
+
|
|
+// macro to generate inverse mix column tables (needed for the key schedule)
|
|
+
|
|
+#define im_data0(p1) \
|
|
+ .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
|
|
+ .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
|
|
+ .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
|
|
+ .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
|
|
+#define im_data1(p1) \
|
|
+ .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
|
|
+ .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
|
|
+ .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
|
|
+ .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
|
|
+#define im_data2(p1) \
|
|
+ .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
|
|
+ .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
|
|
+ .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
|
|
+ .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
|
|
+#define im_data3(p1) \
|
|
+ .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
|
|
+ .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
|
|
+ .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
|
|
+ .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
|
|
+#define im_data4(p1) \
|
|
+ .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
|
|
+ .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
|
|
+ .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
|
|
+ .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
|
|
+#define im_data5(p1) \
|
|
+ .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
|
|
+ .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
|
|
+ .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
|
|
+ .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
|
|
+#define im_data6(p1) \
|
|
+ .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
|
|
+ .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
|
|
+ .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
|
|
+ .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
|
|
+#define im_data7(p1) \
|
|
+ .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
|
|
+ .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
|
|
+ .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
|
|
+ .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
|
|
+
|
|
+// S-box data - 256 entries
|
|
+
|
|
+#define sb_data0(p1) \
|
|
+ .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
|
|
+ .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
|
|
+ .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
|
|
+ .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
|
|
+#define sb_data1(p1) \
|
|
+ .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
|
|
+ .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
|
|
+ .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
|
|
+ .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
|
|
+#define sb_data2(p1) \
|
|
+ .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
|
|
+ .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
|
|
+ .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
|
|
+ .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
|
|
+#define sb_data3(p1) \
|
|
+ .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
|
|
+ .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
|
|
+ .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
|
|
+ .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
|
|
+#define sb_data4(p1) \
|
|
+ .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
|
|
+ .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
|
|
+ .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
|
|
+ .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
|
|
+#define sb_data5(p1) \
|
|
+ .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
|
|
+ .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
|
|
+ .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
|
|
+ .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
|
|
+#define sb_data6(p1) \
|
|
+ .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
|
|
+ .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
|
|
+ .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
|
|
+ .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
|
|
+#define sb_data7(p1) \
|
|
+ .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
|
|
+ .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
|
|
+ .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
|
|
+ .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
|
|
+
|
|
+// Inverse S-box data - 256 entries
|
|
+
|
|
+#define ib_data0(p1) \
|
|
+ .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
|
|
+ .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
|
|
+ .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
|
|
+ .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
|
|
+#define ib_data1(p1) \
|
|
+ .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
|
|
+ .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
|
|
+ .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
|
|
+ .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
|
|
+#define ib_data2(p1) \
|
|
+ .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
|
|
+ .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
|
|
+ .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
|
|
+ .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
|
|
+#define ib_data3(p1) \
|
|
+ .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
|
|
+ .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
|
|
+ .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
|
|
+ .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
|
|
+#define ib_data4(p1) \
|
|
+ .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
|
|
+ .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
|
|
+ .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
|
|
+ .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
|
|
+#define ib_data5(p1) \
|
|
+ .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
|
|
+ .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
|
|
+ .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
|
|
+ .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
|
|
+#define ib_data6(p1) \
|
|
+ .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
|
|
+ .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
|
|
+ .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
|
|
+ .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
|
|
+#define ib_data7(p1) \
|
|
+ .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
|
|
+ .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
|
|
+ .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
|
|
+ .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
|
|
+
|
|
+// The rcon_table (needed for the key schedule)
|
|
+//
|
|
+// Here is original Dr Brian Gladman's source code:
|
|
+// _rcon_tab:
|
|
+// %assign x 1
|
|
+// %rep 29
|
|
+// dd x
|
|
+// %assign x f2(x)
|
|
+// %endrep
|
|
+//
|
|
+// Here is precomputed output (it's more portable this way):
|
|
+
|
|
+ .align ALIGN32BYTES
|
|
+aes_rcon_tab:
|
|
+ .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
|
|
+ .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
|
|
+ .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
|
|
+ .long 0xb3,0x7d,0xfa,0xef,0xc5
|
|
+
|
|
+// The forward xor tables
|
|
+
|
|
+ .align ALIGN32BYTES
|
|
+aes_ft_tab:
|
|
+ sb_data0(u0)
|
|
+ sb_data1(u0)
|
|
+ sb_data2(u0)
|
|
+ sb_data3(u0)
|
|
+ sb_data4(u0)
|
|
+ sb_data5(u0)
|
|
+ sb_data6(u0)
|
|
+ sb_data7(u0)
|
|
+
|
|
+ sb_data0(u1)
|
|
+ sb_data1(u1)
|
|
+ sb_data2(u1)
|
|
+ sb_data3(u1)
|
|
+ sb_data4(u1)
|
|
+ sb_data5(u1)
|
|
+ sb_data6(u1)
|
|
+ sb_data7(u1)
|
|
+
|
|
+ sb_data0(u2)
|
|
+ sb_data1(u2)
|
|
+ sb_data2(u2)
|
|
+ sb_data3(u2)
|
|
+ sb_data4(u2)
|
|
+ sb_data5(u2)
|
|
+ sb_data6(u2)
|
|
+ sb_data7(u2)
|
|
+
|
|
+ sb_data0(u3)
|
|
+ sb_data1(u3)
|
|
+ sb_data2(u3)
|
|
+ sb_data3(u3)
|
|
+ sb_data4(u3)
|
|
+ sb_data5(u3)
|
|
+ sb_data6(u3)
|
|
+ sb_data7(u3)
|
|
+
|
|
+ .align ALIGN32BYTES
|
|
+aes_fl_tab:
|
|
+ sb_data0(w0)
|
|
+ sb_data1(w0)
|
|
+ sb_data2(w0)
|
|
+ sb_data3(w0)
|
|
+ sb_data4(w0)
|
|
+ sb_data5(w0)
|
|
+ sb_data6(w0)
|
|
+ sb_data7(w0)
|
|
+
|
|
+ sb_data0(w1)
|
|
+ sb_data1(w1)
|
|
+ sb_data2(w1)
|
|
+ sb_data3(w1)
|
|
+ sb_data4(w1)
|
|
+ sb_data5(w1)
|
|
+ sb_data6(w1)
|
|
+ sb_data7(w1)
|
|
+
|
|
+ sb_data0(w2)
|
|
+ sb_data1(w2)
|
|
+ sb_data2(w2)
|
|
+ sb_data3(w2)
|
|
+ sb_data4(w2)
|
|
+ sb_data5(w2)
|
|
+ sb_data6(w2)
|
|
+ sb_data7(w2)
|
|
+
|
|
+ sb_data0(w3)
|
|
+ sb_data1(w3)
|
|
+ sb_data2(w3)
|
|
+ sb_data3(w3)
|
|
+ sb_data4(w3)
|
|
+ sb_data5(w3)
|
|
+ sb_data6(w3)
|
|
+ sb_data7(w3)
|
|
+
|
|
+// The inverse xor tables
|
|
+
|
|
+ .align ALIGN32BYTES
|
|
+aes_it_tab:
|
|
+ ib_data0(v0)
|
|
+ ib_data1(v0)
|
|
+ ib_data2(v0)
|
|
+ ib_data3(v0)
|
|
+ ib_data4(v0)
|
|
+ ib_data5(v0)
|
|
+ ib_data6(v0)
|
|
+ ib_data7(v0)
|
|
+
|
|
+ ib_data0(v1)
|
|
+ ib_data1(v1)
|
|
+ ib_data2(v1)
|
|
+ ib_data3(v1)
|
|
+ ib_data4(v1)
|
|
+ ib_data5(v1)
|
|
+ ib_data6(v1)
|
|
+ ib_data7(v1)
|
|
+
|
|
+ ib_data0(v2)
|
|
+ ib_data1(v2)
|
|
+ ib_data2(v2)
|
|
+ ib_data3(v2)
|
|
+ ib_data4(v2)
|
|
+ ib_data5(v2)
|
|
+ ib_data6(v2)
|
|
+ ib_data7(v2)
|
|
+
|
|
+ ib_data0(v3)
|
|
+ ib_data1(v3)
|
|
+ ib_data2(v3)
|
|
+ ib_data3(v3)
|
|
+ ib_data4(v3)
|
|
+ ib_data5(v3)
|
|
+ ib_data6(v3)
|
|
+ ib_data7(v3)
|
|
+
|
|
+ .align ALIGN32BYTES
|
|
+aes_il_tab:
|
|
+ ib_data0(w0)
|
|
+ ib_data1(w0)
|
|
+ ib_data2(w0)
|
|
+ ib_data3(w0)
|
|
+ ib_data4(w0)
|
|
+ ib_data5(w0)
|
|
+ ib_data6(w0)
|
|
+ ib_data7(w0)
|
|
+
|
|
+ ib_data0(w1)
|
|
+ ib_data1(w1)
|
|
+ ib_data2(w1)
|
|
+ ib_data3(w1)
|
|
+ ib_data4(w1)
|
|
+ ib_data5(w1)
|
|
+ ib_data6(w1)
|
|
+ ib_data7(w1)
|
|
+
|
|
+ ib_data0(w2)
|
|
+ ib_data1(w2)
|
|
+ ib_data2(w2)
|
|
+ ib_data3(w2)
|
|
+ ib_data4(w2)
|
|
+ ib_data5(w2)
|
|
+ ib_data6(w2)
|
|
+ ib_data7(w2)
|
|
+
|
|
+ ib_data0(w3)
|
|
+ ib_data1(w3)
|
|
+ ib_data2(w3)
|
|
+ ib_data3(w3)
|
|
+ ib_data4(w3)
|
|
+ ib_data5(w3)
|
|
+ ib_data6(w3)
|
|
+ ib_data7(w3)
|
|
+
|
|
+// The inverse mix column tables
|
|
+
|
|
+ .align ALIGN32BYTES
|
|
+aes_im_tab:
|
|
+ im_data0(v0)
|
|
+ im_data1(v0)
|
|
+ im_data2(v0)
|
|
+ im_data3(v0)
|
|
+ im_data4(v0)
|
|
+ im_data5(v0)
|
|
+ im_data6(v0)
|
|
+ im_data7(v0)
|
|
+
|
|
+ im_data0(v1)
|
|
+ im_data1(v1)
|
|
+ im_data2(v1)
|
|
+ im_data3(v1)
|
|
+ im_data4(v1)
|
|
+ im_data5(v1)
|
|
+ im_data6(v1)
|
|
+ im_data7(v1)
|
|
+
|
|
+ im_data0(v2)
|
|
+ im_data1(v2)
|
|
+ im_data2(v2)
|
|
+ im_data3(v2)
|
|
+ im_data4(v2)
|
|
+ im_data5(v2)
|
|
+ im_data6(v2)
|
|
+ im_data7(v2)
|
|
+
|
|
+ im_data0(v3)
|
|
+ im_data1(v3)
|
|
+ im_data2(v3)
|
|
+ im_data3(v3)
|
|
+ im_data4(v3)
|
|
+ im_data5(v3)
|
|
+ im_data6(v3)
|
|
+ im_data7(v3)
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/aes/aes.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1415 @@
|
|
+// I retain copyright in this code but I encourage its free use provided
|
|
+// that I don't carry any responsibility for the results. I am especially
|
|
+// happy to see it used in free and open source software. If you do use
|
|
+// it I would appreciate an acknowledgement of its origin in the code or
|
|
+// the product that results and I would also appreciate knowing a little
|
|
+// about the use to which it is being put. I am grateful to Frank Yellin
|
|
+// for some ideas that are used in this implementation.
|
|
+//
|
|
+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
|
|
+//
|
|
+// This is an implementation of the AES encryption algorithm (Rijndael)
|
|
+// designed by Joan Daemen and Vincent Rijmen. This version is designed
|
|
+// to provide both fixed and dynamic block and key lengths and can also
|
|
+// run with either big or little endian internal byte order (see aes.h).
|
|
+// It inputs block and key lengths in bytes with the legal values being
|
|
+// 16, 24 and 32.
|
|
+
|
|
+/*
|
|
+ * Modified by Jari Ruusu, May 1 2001
|
|
+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
|
|
+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
|
|
+ * - Major name space cleanup: Names visible to outside now begin
|
|
+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
|
|
+ * - Removed C++ and DLL support as part of name space cleanup.
|
|
+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
|
|
+ * - Merged precomputed constant tables to aes.c file.
|
|
+ * - Removed data alignment restrictions for portability reasons.
|
|
+ * - Made block and key lengths accept bit count (128/192/256)
|
|
+ * as well byte count (16/24/32).
|
|
+ * - Removed all error checks. This change also eliminated the need
|
|
+ * to preinitialize the context struct to zero.
|
|
+ * - Removed some totally unused constants.
|
|
+ */
|
|
+
|
|
+#include "crypto/aes.h"
|
|
+
|
|
+// CONFIGURATION OPTIONS (see also aes.h)
|
|
+//
|
|
+// 1. Define UNROLL for full loop unrolling in encryption and decryption.
|
|
+// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
|
|
+// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
|
|
+// 4. Define FF_TABLES to use tables for field multiplies and inverses.
|
|
+// Do not enable this without understanding stack space requirements.
|
|
+// 5. Define ARRAYS to use arrays to hold the local state block. If this
|
|
+// is not defined, individually declared 32-bit words are used.
|
|
+// 6. Define FAST_VARIABLE if a high speed variable block implementation
|
|
+// is needed (essentially three separate fixed block size code sequences)
|
|
+// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
|
|
+// version using 1 table (2 kbytes of table space) or 4 tables (8
|
|
+// kbytes of table space) for higher speed.
|
|
+// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
|
|
+// increase by using tables for the last rounds but with more table
|
|
+// space (2 or 8 kbytes extra).
|
|
+// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
|
|
+// slower version is provided.
|
|
+// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
|
|
+// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
|
|
+
|
|
+#define UNROLL
|
|
+//#define PARTIAL_UNROLL
|
|
+
|
|
+#define FIXED_TABLES
|
|
+//#define FF_TABLES
|
|
+//#define ARRAYS
|
|
+#define FAST_VARIABLE
|
|
+
|
|
+//#define ONE_TABLE
|
|
+#define FOUR_TABLES
|
|
+
|
|
+//#define ONE_LR_TABLE
|
|
+#define FOUR_LR_TABLES
|
|
+
|
|
+//#define ONE_IM_TABLE
|
|
+#define FOUR_IM_TABLES
|
|
+
|
|
+#if defined(UNROLL) && defined (PARTIAL_UNROLL)
|
|
+#error both UNROLL and PARTIAL_UNROLL are defined
|
|
+#endif
|
|
+
|
|
+#if defined(ONE_TABLE) && defined (FOUR_TABLES)
|
|
+#error both ONE_TABLE and FOUR_TABLES are defined
|
|
+#endif
|
|
+
|
|
+#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
|
|
+#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
|
|
+#endif
|
|
+
|
|
+#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
|
|
+#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
|
|
+#endif
|
|
+
|
|
+#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
|
|
+#error an illegal block size has been specified
|
|
+#endif
|
|
+
|
|
+// upr(x,n): rotates bytes within words by n positions, moving bytes
|
|
+// to higher index positions with wrap around into low positions
|
|
+// ups(x,n): moves bytes by n positions to higher index positions in
|
|
+// words but without wrap around
|
|
+// bval(x,n): extracts a byte from a word
|
|
+
|
|
+#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
|
|
+#define ups(x,n) ((x) << 8 * (n))
|
|
+#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
|
|
+#define bytes2word(b0, b1, b2, b3) \
|
|
+ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
|
|
+
|
|
+
|
|
+/* little endian processor without data alignment restrictions: AES_LE_OK */
|
|
+/* original code: i386 */
|
|
+#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
|
|
+#define AES_LE_OK 1
|
|
+/* added (tested): alpha --jjo */
|
|
+#elif defined(__alpha__)|| defined (__alpha)
|
|
+#define AES_LE_OK 1
|
|
+/* added (tested): ia64 --jjo */
|
|
+#elif defined(__ia64__)|| defined (__ia64)
|
|
+#define AES_LE_OK 1
|
|
+#endif
|
|
+
|
|
+#ifdef AES_LE_OK
|
|
+/* little endian processor without data alignment restrictions */
|
|
+#define word_in(x) *(u_int32_t*)(x)
|
|
+#define const_word_in(x) *(const u_int32_t*)(x)
|
|
+#define word_out(x,v) *(u_int32_t*)(x) = (v)
|
|
+#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
|
|
+#else
|
|
+/* slower but generic big endian or with data alignment restrictions */
|
|
+/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
|
|
+#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
|
|
+#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24))
|
|
+#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
|
|
+#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24)
|
|
+#endif
|
|
+
|
|
+// Disable at least some poor combinations of options
|
|
+
|
|
+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
|
|
+#define FIXED_TABLES
|
|
+#undef UNROLL
|
|
+#undef ONE_LR_TABLE
|
|
+#undef FOUR_LR_TABLES
|
|
+#undef ONE_IM_TABLE
|
|
+#undef FOUR_IM_TABLES
|
|
+#elif !defined(FOUR_TABLES)
|
|
+#ifdef FOUR_LR_TABLES
|
|
+#undef FOUR_LR_TABLES
|
|
+#define ONE_LR_TABLE
|
|
+#endif
|
|
+#ifdef FOUR_IM_TABLES
|
|
+#undef FOUR_IM_TABLES
|
|
+#define ONE_IM_TABLE
|
|
+#endif
|
|
+#elif !defined(AES_BLOCK_SIZE)
|
|
+#if defined(UNROLL)
|
|
+#define PARTIAL_UNROLL
|
|
+#undef UNROLL
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+// the finite field modular polynomial and elements
|
|
+
|
|
+#define ff_poly 0x011b
|
|
+#define ff_hi 0x80
|
|
+
|
|
+// multiply four bytes in GF(2^8) by 'x' {02} in parallel
|
|
+
|
|
+#define m1 0x80808080
|
|
+#define m2 0x7f7f7f7f
|
|
+#define m3 0x0000001b
|
|
+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
|
|
+
|
|
+// The following defines provide alternative definitions of FFmulX that might
|
|
+// give improved performance if a fast 32-bit multiply is not available. Note
|
|
+// that a temporary variable u needs to be defined where FFmulX is used.
|
|
+
|
|
+// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
|
|
+// #define m4 0x1b1b1b1b
|
|
+// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
|
|
+
|
|
+// perform column mix operation on four bytes in parallel
|
|
+
|
|
+#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
|
|
+
|
|
+#if defined(FIXED_TABLES)
|
|
+
|
|
+// the S-Box table
|
|
+
|
|
+static const unsigned char s_box[256] =
|
|
+{
|
|
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
|
|
+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
|
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
|
|
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
|
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
|
|
+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
|
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
|
|
+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
|
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
|
|
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
|
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
|
|
+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
|
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
|
|
+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
|
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
|
|
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
|
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
|
|
+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
|
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
|
|
+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
|
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
|
|
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
|
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
|
|
+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
|
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
|
|
+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
|
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
|
|
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
|
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
|
|
+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
|
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
|
|
+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
|
+};
|
|
+
|
|
+// the inverse S-Box table
|
|
+
|
|
+static const unsigned char inv_s_box[256] =
|
|
+{
|
|
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
|
|
+ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
|
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
|
|
+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
|
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
|
|
+ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
|
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
|
|
+ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
|
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
|
|
+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
|
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
|
|
+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
|
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
|
|
+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
|
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
|
|
+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
|
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
|
|
+ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
|
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
|
|
+ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
|
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
|
|
+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
|
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
|
|
+ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
|
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
|
|
+ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
|
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
|
|
+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
|
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
|
|
+ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
|
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
|
|
+ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
|
+};
|
|
+
|
|
+#define w0(p) 0x000000##p
|
|
+
|
|
+// Number of elements required in this table for different
|
|
+// block and key lengths is:
|
|
+//
|
|
+// Nk = 4 6 8
|
|
+// ----------
|
|
+// Nb = 4 | 10 8 7
|
|
+// 6 | 19 12 11
|
|
+// 8 | 29 19 14
|
|
+//
|
|
+// this table can be a table of bytes if the key schedule
|
|
+// code is adjusted accordingly
|
|
+
|
|
+static const u_int32_t rcon_tab[29] =
|
|
+{
|
|
+ w0(01), w0(02), w0(04), w0(08),
|
|
+ w0(10), w0(20), w0(40), w0(80),
|
|
+ w0(1b), w0(36), w0(6c), w0(d8),
|
|
+ w0(ab), w0(4d), w0(9a), w0(2f),
|
|
+ w0(5e), w0(bc), w0(63), w0(c6),
|
|
+ w0(97), w0(35), w0(6a), w0(d4),
|
|
+ w0(b3), w0(7d), w0(fa), w0(ef),
|
|
+ w0(c5)
|
|
+};
|
|
+
|
|
+#undef w0
|
|
+
|
|
+#define r0(p,q,r,s) 0x##p##q##r##s
|
|
+#define r1(p,q,r,s) 0x##q##r##s##p
|
|
+#define r2(p,q,r,s) 0x##r##s##p##q
|
|
+#define r3(p,q,r,s) 0x##s##p##q##r
|
|
+#define w0(p) 0x000000##p
|
|
+#define w1(p) 0x0000##p##00
|
|
+#define w2(p) 0x00##p##0000
|
|
+#define w3(p) 0x##p##000000
|
|
+
|
|
+#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
|
|
+
|
|
+// data for forward tables (other than last round)
|
|
+
|
|
+#define f_table \
|
|
+ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
|
|
+ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
|
|
+ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
|
|
+ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
|
|
+ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
|
|
+ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
|
|
+ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
|
|
+ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
|
|
+ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
|
|
+ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
|
|
+ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
|
|
+ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
|
|
+ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
|
|
+ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
|
|
+ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
|
|
+ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
|
|
+ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
|
|
+ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
|
|
+ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
|
|
+ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
|
|
+ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
|
|
+ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
|
|
+ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
|
|
+ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
|
|
+ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
|
|
+ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
|
|
+ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
|
|
+ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
|
|
+ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
|
|
+ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
|
|
+ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
|
|
+ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
|
|
+ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
|
|
+ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
|
|
+ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
|
|
+ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
|
|
+ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
|
|
+ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
|
|
+ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
|
|
+ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
|
|
+ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
|
|
+ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
|
|
+ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
|
|
+ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
|
|
+ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
|
|
+ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
|
|
+ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
|
|
+ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
|
|
+ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
|
|
+ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
|
|
+ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
|
|
+ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
|
|
+ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
|
|
+ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
|
|
+ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
|
|
+ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
|
|
+ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
|
|
+ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
|
|
+ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
|
|
+ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
|
|
+ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
|
|
+ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
|
|
+ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
|
|
+ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
|
|
+
|
|
+// data for inverse tables (other than last round)
|
|
+
|
|
+#define i_table \
|
|
+ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
|
|
+ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
|
|
+ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
|
|
+ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
|
|
+ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
|
|
+ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
|
|
+ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
|
|
+ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
|
|
+ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
|
|
+ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
|
|
+ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
|
|
+ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
|
|
+ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
|
|
+ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
|
|
+ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
|
|
+ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
|
|
+ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
|
|
+ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
|
|
+ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
|
|
+ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
|
|
+ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
|
|
+ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
|
|
+ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
|
|
+ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
|
|
+ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
|
|
+ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
|
|
+ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
|
|
+ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
|
|
+ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
|
|
+ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
|
|
+ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
|
|
+ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
|
|
+ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
|
|
+ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
|
|
+ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
|
|
+ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
|
|
+ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
|
|
+ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
|
|
+ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
|
|
+ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
|
|
+ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
|
|
+ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
|
|
+ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
|
|
+ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
|
|
+ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
|
|
+ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
|
|
+ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
|
|
+ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
|
|
+ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
|
|
+ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
|
|
+ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
|
|
+ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
|
|
+ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
|
|
+ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
|
|
+ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
|
|
+ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
|
|
+ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
|
|
+ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
|
|
+ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
|
|
+ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
|
|
+ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
|
|
+ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
|
|
+ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
|
|
+ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
|
|
+
|
|
+// generate the required tables in the desired endian format
|
|
+
|
|
+#undef r
|
|
+#define r r0
|
|
+
|
|
+#if defined(ONE_TABLE)
|
|
+static const u_int32_t ft_tab[256] =
|
|
+ { f_table };
|
|
+#elif defined(FOUR_TABLES)
|
|
+static const u_int32_t ft_tab[4][256] =
|
|
+{ { f_table },
|
|
+#undef r
|
|
+#define r r1
|
|
+ { f_table },
|
|
+#undef r
|
|
+#define r r2
|
|
+ { f_table },
|
|
+#undef r
|
|
+#define r r3
|
|
+ { f_table }
|
|
+};
|
|
+#endif
|
|
+
|
|
+#undef r
|
|
+#define r r0
|
|
+#if defined(ONE_TABLE)
|
|
+static const u_int32_t it_tab[256] =
|
|
+ { i_table };
|
|
+#elif defined(FOUR_TABLES)
|
|
+static const u_int32_t it_tab[4][256] =
|
|
+{ { i_table },
|
|
+#undef r
|
|
+#define r r1
|
|
+ { i_table },
|
|
+#undef r
|
|
+#define r r2
|
|
+ { i_table },
|
|
+#undef r
|
|
+#define r r3
|
|
+ { i_table }
|
|
+};
|
|
+#endif
|
|
+
|
|
+#endif
|
|
+
|
|
+#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
|
|
+
|
|
+// data for inverse tables (last round)
|
|
+
|
|
+#define li_table \
|
|
+ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
|
|
+ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
|
|
+ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
|
|
+ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
|
|
+ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
|
|
+ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
|
|
+ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
|
|
+ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
|
|
+ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
|
|
+ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
|
|
+ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
|
|
+ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
|
|
+ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
|
|
+ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
|
|
+ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
|
|
+ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
|
|
+ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
|
|
+ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
|
|
+ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
|
|
+ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
|
|
+ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
|
|
+ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
|
|
+ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
|
|
+ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
|
|
+ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
|
|
+ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
|
|
+ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
|
|
+ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
|
|
+ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
|
|
+ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
|
|
+ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
|
|
+ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
|
|
+
|
|
+// generate the required tables in the desired endian format
|
|
+
|
|
+#undef r
|
|
+#define r(p,q,r,s) w0(q)
|
|
+#if defined(ONE_LR_TABLE)
|
|
+static const u_int32_t fl_tab[256] =
|
|
+ { f_table };
|
|
+#elif defined(FOUR_LR_TABLES)
|
|
+static const u_int32_t fl_tab[4][256] =
|
|
+{ { f_table },
|
|
+#undef r
|
|
+#define r(p,q,r,s) w1(q)
|
|
+ { f_table },
|
|
+#undef r
|
|
+#define r(p,q,r,s) w2(q)
|
|
+ { f_table },
|
|
+#undef r
|
|
+#define r(p,q,r,s) w3(q)
|
|
+ { f_table }
|
|
+};
|
|
+#endif
|
|
+
|
|
+#undef w
|
|
+#define w w0
|
|
+#if defined(ONE_LR_TABLE)
|
|
+static const u_int32_t il_tab[256] =
|
|
+ { li_table };
|
|
+#elif defined(FOUR_LR_TABLES)
|
|
+static const u_int32_t il_tab[4][256] =
|
|
+{ { li_table },
|
|
+#undef w
|
|
+#define w w1
|
|
+ { li_table },
|
|
+#undef w
|
|
+#define w w2
|
|
+ { li_table },
|
|
+#undef w
|
|
+#define w w3
|
|
+ { li_table }
|
|
+};
|
|
+#endif
|
|
+
|
|
+#endif
|
|
+
|
|
+#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
|
|
+
|
|
+#define m_table \
|
|
+ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
|
|
+ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
|
|
+ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
|
|
+ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
|
|
+ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
|
|
+ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
|
|
+ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
|
|
+ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
|
|
+ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
|
|
+ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
|
|
+ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
|
|
+ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
|
|
+ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
|
|
+ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
|
|
+ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
|
|
+ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
|
|
+ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
|
|
+ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
|
|
+ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
|
|
+ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
|
|
+ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
|
|
+ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
|
|
+ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
|
|
+ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
|
|
+ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
|
|
+ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
|
|
+ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
|
|
+ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
|
|
+ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
|
|
+ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
|
|
+ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
|
|
+ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
|
|
+ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
|
|
+ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
|
|
+ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
|
|
+ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
|
|
+ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
|
|
+ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
|
|
+ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
|
|
+ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
|
|
+ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
|
|
+ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
|
|
+ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
|
|
+ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
|
|
+ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
|
|
+ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
|
|
+ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
|
|
+ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
|
|
+ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
|
|
+ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
|
|
+ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
|
|
+ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
|
|
+ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
|
|
+ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
|
|
+ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
|
|
+ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
|
|
+ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
|
|
+ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
|
|
+ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
|
|
+ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
|
|
+ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
|
|
+ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
|
|
+ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
|
|
+ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
|
|
+
|
|
+#undef r
|
|
+#define r r0
|
|
+
|
|
+#if defined(ONE_IM_TABLE)
|
|
+static const u_int32_t im_tab[256] =
|
|
+ { m_table };
|
|
+#elif defined(FOUR_IM_TABLES)
|
|
+static const u_int32_t im_tab[4][256] =
|
|
+{ { m_table },
|
|
+#undef r
|
|
+#define r r1
|
|
+ { m_table },
|
|
+#undef r
|
|
+#define r r2
|
|
+ { m_table },
|
|
+#undef r
|
|
+#define r r3
|
|
+ { m_table }
|
|
+};
|
|
+#endif
|
|
+
|
|
+#endif
|
|
+
|
|
+#else
|
|
+
|
|
+static int tab_gen = 0;
|
|
+
|
|
+static unsigned char s_box[256]; // the S box
|
|
+static unsigned char inv_s_box[256]; // the inverse S box
|
|
+static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
|
|
+
|
|
+#if defined(ONE_TABLE)
|
|
+static u_int32_t ft_tab[256];
|
|
+static u_int32_t it_tab[256];
|
|
+#elif defined(FOUR_TABLES)
|
|
+static u_int32_t ft_tab[4][256];
|
|
+static u_int32_t it_tab[4][256];
|
|
+#endif
|
|
+
|
|
+#if defined(ONE_LR_TABLE)
|
|
+static u_int32_t fl_tab[256];
|
|
+static u_int32_t il_tab[256];
|
|
+#elif defined(FOUR_LR_TABLES)
|
|
+static u_int32_t fl_tab[4][256];
|
|
+static u_int32_t il_tab[4][256];
|
|
+#endif
|
|
+
|
|
+#if defined(ONE_IM_TABLE)
|
|
+static u_int32_t im_tab[256];
|
|
+#elif defined(FOUR_IM_TABLES)
|
|
+static u_int32_t im_tab[4][256];
|
|
+#endif
|
|
+
|
|
+// Generate the tables for the dynamic table option
|
|
+
|
|
+#if !defined(FF_TABLES)
|
|
+
|
|
+// It will generally be sensible to use tables to compute finite
|
|
+// field multiplies and inverses but where memory is scarse this
|
|
+// code might sometimes be better.
|
|
+
|
|
+// return 2 ^ (n - 1) where n is the bit number of the highest bit
|
|
+// set in x with x in the range 1 < x < 0x00000200. This form is
|
|
+// used so that locals within FFinv can be bytes rather than words
|
|
+
|
|
+static unsigned char hibit(const u_int32_t x)
|
|
+{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
|
|
+
|
|
+ r |= (r >> 2);
|
|
+ r |= (r >> 4);
|
|
+ return (r + 1) >> 1;
|
|
+}
|
|
+
|
|
+// return the inverse of the finite field element x
|
|
+
|
|
+static unsigned char FFinv(const unsigned char x)
|
|
+{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
|
|
+
|
|
+ if(x < 2) return x;
|
|
+
|
|
+ for(;;)
|
|
+ {
|
|
+ if(!n1) return v1;
|
|
+
|
|
+ while(n2 >= n1)
|
|
+ {
|
|
+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
|
|
+ }
|
|
+
|
|
+ if(!n2) return v2;
|
|
+
|
|
+ while(n1 >= n2)
|
|
+ {
|
|
+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+// define the finite field multiplies required for Rijndael
|
|
+
|
|
+#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
|
|
+#define FFmul03(x) ((x) ^ FFmul02(x))
|
|
+#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
|
|
+#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
|
|
+#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
|
|
+#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
|
|
+
|
|
+#else
|
|
+
|
|
+#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
|
|
+
|
|
+#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
|
|
+#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
|
|
+#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
|
|
+#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
|
|
+#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
|
|
+#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
|
|
+
|
|
+#endif
|
|
+
|
|
+// The forward and inverse affine transformations used in the S-box
|
|
+
|
|
+#define fwd_affine(x) \
|
|
+ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
|
|
+
|
|
+#define inv_affine(x) \
|
|
+ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
|
|
+
|
|
+static void gen_tabs(void)
|
|
+{ u_int32_t i, w;
|
|
+
|
|
+#if defined(FF_TABLES)
|
|
+
|
|
+ unsigned char pow[512], log[256];
|
|
+
|
|
+ // log and power tables for GF(2^8) finite field with
|
|
+ // 0x011b as modular polynomial - the simplest primitive
|
|
+ // root is 0x03, used here to generate the tables
|
|
+
|
|
+ i = 0; w = 1;
|
|
+ do
|
|
+ {
|
|
+ pow[i] = (unsigned char)w;
|
|
+ pow[i + 255] = (unsigned char)w;
|
|
+ log[w] = (unsigned char)i++;
|
|
+ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
|
|
+ }
|
|
+ while (w != 1);
|
|
+
|
|
+#endif
|
|
+
|
|
+ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
|
|
+ {
|
|
+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
|
|
+ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
|
|
+ }
|
|
+
|
|
+ for(i = 0; i < 256; ++i)
|
|
+ { unsigned char b;
|
|
+
|
|
+ s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
|
|
+
|
|
+ w = bytes2word(b, 0, 0, 0);
|
|
+#if defined(ONE_LR_TABLE)
|
|
+ fl_tab[i] = w;
|
|
+#elif defined(FOUR_LR_TABLES)
|
|
+ fl_tab[0][i] = w;
|
|
+ fl_tab[1][i] = upr(w,1);
|
|
+ fl_tab[2][i] = upr(w,2);
|
|
+ fl_tab[3][i] = upr(w,3);
|
|
+#endif
|
|
+ w = bytes2word(FFmul02(b), b, b, FFmul03(b));
|
|
+#if defined(ONE_TABLE)
|
|
+ ft_tab[i] = w;
|
|
+#elif defined(FOUR_TABLES)
|
|
+ ft_tab[0][i] = w;
|
|
+ ft_tab[1][i] = upr(w,1);
|
|
+ ft_tab[2][i] = upr(w,2);
|
|
+ ft_tab[3][i] = upr(w,3);
|
|
+#endif
|
|
+ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
|
|
+
|
|
+ w = bytes2word(b, 0, 0, 0);
|
|
+#if defined(ONE_LR_TABLE)
|
|
+ il_tab[i] = w;
|
|
+#elif defined(FOUR_LR_TABLES)
|
|
+ il_tab[0][i] = w;
|
|
+ il_tab[1][i] = upr(w,1);
|
|
+ il_tab[2][i] = upr(w,2);
|
|
+ il_tab[3][i] = upr(w,3);
|
|
+#endif
|
|
+ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
|
|
+#if defined(ONE_TABLE)
|
|
+ it_tab[i] = w;
|
|
+#elif defined(FOUR_TABLES)
|
|
+ it_tab[0][i] = w;
|
|
+ it_tab[1][i] = upr(w,1);
|
|
+ it_tab[2][i] = upr(w,2);
|
|
+ it_tab[3][i] = upr(w,3);
|
|
+#endif
|
|
+#if defined(ONE_IM_TABLE)
|
|
+ im_tab[b] = w;
|
|
+#elif defined(FOUR_IM_TABLES)
|
|
+ im_tab[0][b] = w;
|
|
+ im_tab[1][b] = upr(w,1);
|
|
+ im_tab[2][b] = upr(w,2);
|
|
+ im_tab[3][b] = upr(w,3);
|
|
+#endif
|
|
+
|
|
+ }
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+#define no_table(x,box,vf,rf,c) bytes2word( \
|
|
+ box[bval(vf(x,0,c),rf(0,c))], \
|
|
+ box[bval(vf(x,1,c),rf(1,c))], \
|
|
+ box[bval(vf(x,2,c),rf(2,c))], \
|
|
+ box[bval(vf(x,3,c),rf(3,c))])
|
|
+
|
|
+#define one_table(x,op,tab,vf,rf,c) \
|
|
+ ( tab[bval(vf(x,0,c),rf(0,c))] \
|
|
+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
|
|
+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
|
|
+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
|
|
+
|
|
+#define four_tables(x,tab,vf,rf,c) \
|
|
+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
|
|
+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
|
|
+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
|
|
+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
|
|
+
|
|
+#define vf1(x,r,c) (x)
|
|
+#define rf1(r,c) (r)
|
|
+#define rf2(r,c) ((r-c)&3)
|
|
+
|
|
+#if defined(FOUR_LR_TABLES)
|
|
+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
|
|
+#elif defined(ONE_LR_TABLE)
|
|
+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
|
|
+#else
|
|
+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
|
|
+#endif
|
|
+
|
|
+#if defined(FOUR_IM_TABLES)
|
|
+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
|
|
+#elif defined(ONE_IM_TABLE)
|
|
+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
|
|
+#else
|
|
+#define inv_mcol(x) \
|
|
+ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
|
|
+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
|
|
+#endif
|
|
+
|
|
+// Subroutine to set the block size (if variable) in bytes, legal
|
|
+// values being 16, 24 and 32.
|
|
+
|
|
+#if defined(AES_BLOCK_SIZE)
|
|
+#define nc (AES_BLOCK_SIZE / 4)
|
|
+#else
|
|
+#define nc (cx->aes_Ncol)
|
|
+
|
|
+void aes_set_blk(aes_context *cx, int n_bytes)
|
|
+{
|
|
+#if !defined(FIXED_TABLES)
|
|
+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
|
|
+#endif
|
|
+
|
|
+ switch(n_bytes) {
|
|
+ case 32: /* bytes */
|
|
+ case 256: /* bits */
|
|
+ nc = 8;
|
|
+ break;
|
|
+ case 24: /* bytes */
|
|
+ case 192: /* bits */
|
|
+ nc = 6;
|
|
+ break;
|
|
+ case 16: /* bytes */
|
|
+ case 128: /* bits */
|
|
+ default:
|
|
+ nc = 4;
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+// Initialise the key schedule from the user supplied key. The key
|
|
+// length is now specified in bytes - 16, 24 or 32 as appropriate.
|
|
+// This corresponds to bit lengths of 128, 192 and 256 bits, and
|
|
+// to Nk values of 4, 6 and 8 respectively.
|
|
+
|
|
+#define mx(t,f) (*t++ = inv_mcol(*f),f++)
|
|
+#define cp(t,f) *t++ = *f++
|
|
+
|
|
+#if AES_BLOCK_SIZE == 16
|
|
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
|
|
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
|
|
+#elif AES_BLOCK_SIZE == 24
|
|
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
|
|
+ cp(d,s); cp(d,s)
|
|
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
|
|
+ mx(d,s); mx(d,s)
|
|
+#elif AES_BLOCK_SIZE == 32
|
|
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
|
|
+ cp(d,s); cp(d,s); cp(d,s); cp(d,s)
|
|
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
|
|
+ mx(d,s); mx(d,s); mx(d,s); mx(d,s)
|
|
+#else
|
|
+
|
|
+#define cpy(d,s) \
|
|
+switch(nc) \
|
|
+{ case 8: cp(d,s); cp(d,s); \
|
|
+ case 6: cp(d,s); cp(d,s); \
|
|
+ case 4: cp(d,s); cp(d,s); \
|
|
+ cp(d,s); cp(d,s); \
|
|
+}
|
|
+
|
|
+#define mix(d,s) \
|
|
+switch(nc) \
|
|
+{ case 8: mx(d,s); mx(d,s); \
|
|
+ case 6: mx(d,s); mx(d,s); \
|
|
+ case 4: mx(d,s); mx(d,s); \
|
|
+ mx(d,s); mx(d,s); \
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
|
|
+{ u_int32_t *kf, *kt, rci;
|
|
+
|
|
+#if !defined(FIXED_TABLES)
|
|
+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
|
|
+#endif
|
|
+
|
|
+ switch(n_bytes) {
|
|
+ case 32: /* bytes */
|
|
+ case 256: /* bits */
|
|
+ cx->aes_Nkey = 8;
|
|
+ break;
|
|
+ case 24: /* bytes */
|
|
+ case 192: /* bits */
|
|
+ cx->aes_Nkey = 6;
|
|
+ break;
|
|
+ case 16: /* bytes */
|
|
+ case 128: /* bits */
|
|
+ default:
|
|
+ cx->aes_Nkey = 4;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
|
|
+
|
|
+ cx->aes_e_key[0] = const_word_in(in_key );
|
|
+ cx->aes_e_key[1] = const_word_in(in_key + 4);
|
|
+ cx->aes_e_key[2] = const_word_in(in_key + 8);
|
|
+ cx->aes_e_key[3] = const_word_in(in_key + 12);
|
|
+
|
|
+ kf = cx->aes_e_key;
|
|
+ kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
|
|
+ rci = 0;
|
|
+
|
|
+ switch(cx->aes_Nkey)
|
|
+ {
|
|
+ case 4: do
|
|
+ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
|
|
+ kf[5] = kf[1] ^ kf[4];
|
|
+ kf[6] = kf[2] ^ kf[5];
|
|
+ kf[7] = kf[3] ^ kf[6];
|
|
+ kf += 4;
|
|
+ }
|
|
+ while(kf < kt);
|
|
+ break;
|
|
+
|
|
+ case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
|
|
+ cx->aes_e_key[5] = const_word_in(in_key + 20);
|
|
+ do
|
|
+ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
|
|
+ kf[ 7] = kf[1] ^ kf[ 6];
|
|
+ kf[ 8] = kf[2] ^ kf[ 7];
|
|
+ kf[ 9] = kf[3] ^ kf[ 8];
|
|
+ kf[10] = kf[4] ^ kf[ 9];
|
|
+ kf[11] = kf[5] ^ kf[10];
|
|
+ kf += 6;
|
|
+ }
|
|
+ while(kf < kt);
|
|
+ break;
|
|
+
|
|
+ case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
|
|
+ cx->aes_e_key[5] = const_word_in(in_key + 20);
|
|
+ cx->aes_e_key[6] = const_word_in(in_key + 24);
|
|
+ cx->aes_e_key[7] = const_word_in(in_key + 28);
|
|
+ do
|
|
+ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
|
|
+ kf[ 9] = kf[1] ^ kf[ 8];
|
|
+ kf[10] = kf[2] ^ kf[ 9];
|
|
+ kf[11] = kf[3] ^ kf[10];
|
|
+ kf[12] = kf[4] ^ ls_box(kf[11],0);
|
|
+ kf[13] = kf[5] ^ kf[12];
|
|
+ kf[14] = kf[6] ^ kf[13];
|
|
+ kf[15] = kf[7] ^ kf[14];
|
|
+ kf += 8;
|
|
+ }
|
|
+ while (kf < kt);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if(!f)
|
|
+ { u_int32_t i;
|
|
+
|
|
+ kt = cx->aes_d_key + nc * cx->aes_Nrnd;
|
|
+ kf = cx->aes_e_key;
|
|
+
|
|
+ cpy(kt, kf); kt -= 2 * nc;
|
|
+
|
|
+ for(i = 1; i < cx->aes_Nrnd; ++i)
|
|
+ {
|
|
+#if defined(ONE_TABLE) || defined(FOUR_TABLES)
|
|
+#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
|
|
+ u_int32_t f2, f4, f8, f9;
|
|
+#endif
|
|
+ mix(kt, kf);
|
|
+#else
|
|
+ cpy(kt, kf);
|
|
+#endif
|
|
+ kt -= 2 * nc;
|
|
+ }
|
|
+
|
|
+ cpy(kt, kf);
|
|
+ }
|
|
+}
|
|
+
|
|
+// y = output word, x = input word, r = row, c = column
|
|
+// for r = 0, 1, 2 and 3 = column accessed for row r
|
|
+
|
|
+#if defined(ARRAYS)
|
|
+#define s(x,c) x[c]
|
|
+#else
|
|
+#define s(x,c) x##c
|
|
+#endif
|
|
+
|
|
+// I am grateful to Frank Yellin for the following constructions
|
|
+// which, given the column (c) of the output state variable that
|
|
+// is being computed, return the input state variables which are
|
|
+// needed for each row (r) of the state
|
|
+
|
|
+// For the fixed block size options, compilers reduce these two
|
|
+// expressions to fixed variable references. For variable block
|
|
+// size code conditional clauses will sometimes be returned
|
|
+
|
|
+#define unused 77 // Sunset Strip
|
|
+
|
|
+#define fwd_var(x,r,c) \
|
|
+ ( r==0 ? \
|
|
+ ( c==0 ? s(x,0) \
|
|
+ : c==1 ? s(x,1) \
|
|
+ : c==2 ? s(x,2) \
|
|
+ : c==3 ? s(x,3) \
|
|
+ : c==4 ? s(x,4) \
|
|
+ : c==5 ? s(x,5) \
|
|
+ : c==6 ? s(x,6) \
|
|
+ : s(x,7)) \
|
|
+ : r==1 ? \
|
|
+ ( c==0 ? s(x,1) \
|
|
+ : c==1 ? s(x,2) \
|
|
+ : c==2 ? s(x,3) \
|
|
+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
|
|
+ : c==4 ? s(x,5) \
|
|
+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \
|
|
+ : c==6 ? s(x,7) \
|
|
+ : s(x,0)) \
|
|
+ : r==2 ? \
|
|
+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
|
|
+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
|
|
+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
|
|
+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
|
|
+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \
|
|
+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \
|
|
+ : c==6 ? s(x,1) \
|
|
+ : s(x,2)) \
|
|
+ : \
|
|
+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
|
|
+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
|
|
+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
|
|
+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
|
|
+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
|
|
+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
|
|
+ : c==6 ? s(x,2) \
|
|
+ : s(x,3)))
|
|
+
|
|
+#define inv_var(x,r,c) \
|
|
+ ( r==0 ? \
|
|
+ ( c==0 ? s(x,0) \
|
|
+ : c==1 ? s(x,1) \
|
|
+ : c==2 ? s(x,2) \
|
|
+ : c==3 ? s(x,3) \
|
|
+ : c==4 ? s(x,4) \
|
|
+ : c==5 ? s(x,5) \
|
|
+ : c==6 ? s(x,6) \
|
|
+ : s(x,7)) \
|
|
+ : r==1 ? \
|
|
+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
|
|
+ : c==1 ? s(x,0) \
|
|
+ : c==2 ? s(x,1) \
|
|
+ : c==3 ? s(x,2) \
|
|
+ : c==4 ? s(x,3) \
|
|
+ : c==5 ? s(x,4) \
|
|
+ : c==6 ? s(x,5) \
|
|
+ : s(x,6)) \
|
|
+ : r==2 ? \
|
|
+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
|
|
+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
|
|
+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
|
|
+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
|
|
+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
|
|
+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
|
|
+ : c==6 ? s(x,3) \
|
|
+ : s(x,4)) \
|
|
+ : \
|
|
+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
|
|
+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
|
|
+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
|
|
+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \
|
|
+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
|
|
+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
|
|
+ : c==6 ? s(x,2) \
|
|
+ : s(x,3)))
|
|
+
|
|
+#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
|
|
+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
|
|
+
|
|
+#if defined(FOUR_TABLES)
|
|
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
|
|
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
|
|
+#elif defined(ONE_TABLE)
|
|
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
|
|
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
|
|
+#else
|
|
+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
|
|
+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
|
|
+#endif
|
|
+
|
|
+#if defined(FOUR_LR_TABLES)
|
|
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
|
|
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
|
|
+#elif defined(ONE_LR_TABLE)
|
|
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
|
|
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
|
|
+#else
|
|
+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
|
|
+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
|
|
+#endif
|
|
+
|
|
+#if AES_BLOCK_SIZE == 16
|
|
+
|
|
+#if defined(ARRAYS)
|
|
+#define locals(y,x) x[4],y[4]
|
|
+#else
|
|
+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
|
|
+// the following defines prevent the compiler requiring the declaration
|
|
+// of generated but unused variables in the fwd_var and inv_var macros
|
|
+#define b04 unused
|
|
+#define b05 unused
|
|
+#define b06 unused
|
|
+#define b07 unused
|
|
+#define b14 unused
|
|
+#define b15 unused
|
|
+#define b16 unused
|
|
+#define b17 unused
|
|
+#endif
|
|
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
|
+ s(y,2) = s(x,2); s(y,3) = s(x,3);
|
|
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
|
|
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
|
|
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
|
|
+
|
|
+#elif AES_BLOCK_SIZE == 24
|
|
+
|
|
+#if defined(ARRAYS)
|
|
+#define locals(y,x) x[6],y[6]
|
|
+#else
|
|
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
|
|
+ y##0,y##1,y##2,y##3,y##4,y##5
|
|
+#define b06 unused
|
|
+#define b07 unused
|
|
+#define b16 unused
|
|
+#define b17 unused
|
|
+#endif
|
|
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
|
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
|
|
+ s(y,4) = s(x,4); s(y,5) = s(x,5);
|
|
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
|
|
+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
|
|
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
|
|
+ so(y,x,3); so(y,x,4); so(y,x,5)
|
|
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
|
|
+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
|
|
+#else
|
|
+
|
|
+#if defined(ARRAYS)
|
|
+#define locals(y,x) x[8],y[8]
|
|
+#else
|
|
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
|
|
+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
|
|
+#endif
|
|
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
|
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
|
|
+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
|
|
+ s(y,6) = s(x,6); s(y,7) = s(x,7);
|
|
+
|
|
+#if AES_BLOCK_SIZE == 32
|
|
+
|
|
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
|
|
+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
|
|
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
|
|
+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
|
|
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
|
|
+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
|
|
+#else
|
|
+
|
|
+#define state_in(y,x,k) \
|
|
+switch(nc) \
|
|
+{ case 8: si(y,x,k,7); si(y,x,k,6); \
|
|
+ case 6: si(y,x,k,5); si(y,x,k,4); \
|
|
+ case 4: si(y,x,k,3); si(y,x,k,2); \
|
|
+ si(y,x,k,1); si(y,x,k,0); \
|
|
+}
|
|
+
|
|
+#define state_out(y,x) \
|
|
+switch(nc) \
|
|
+{ case 8: so(y,x,7); so(y,x,6); \
|
|
+ case 6: so(y,x,5); so(y,x,4); \
|
|
+ case 4: so(y,x,3); so(y,x,2); \
|
|
+ so(y,x,1); so(y,x,0); \
|
|
+}
|
|
+
|
|
+#if defined(FAST_VARIABLE)
|
|
+
|
|
+#define round(rm,y,x,k) \
|
|
+switch(nc) \
|
|
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
|
|
+ rm(y,x,k,5); rm(y,x,k,4); \
|
|
+ rm(y,x,k,3); rm(y,x,k,2); \
|
|
+ rm(y,x,k,1); rm(y,x,k,0); \
|
|
+ break; \
|
|
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
|
|
+ rm(y,x,k,3); rm(y,x,k,2); \
|
|
+ rm(y,x,k,1); rm(y,x,k,0); \
|
|
+ break; \
|
|
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
|
|
+ rm(y,x,k,1); rm(y,x,k,0); \
|
|
+ break; \
|
|
+}
|
|
+#else
|
|
+
|
|
+#define round(rm,y,x,k) \
|
|
+switch(nc) \
|
|
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
|
|
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
|
|
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
|
|
+ rm(y,x,k,1); rm(y,x,k,0); \
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
|
|
+{ u_int32_t locals(b0, b1);
|
|
+ const u_int32_t *kp = cx->aes_e_key;
|
|
+
|
|
+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
|
|
+ u_int32_t f2;
|
|
+#endif
|
|
+
|
|
+ state_in(b0, in_blk, kp); kp += nc;
|
|
+
|
|
+#if defined(UNROLL)
|
|
+
|
|
+ switch(cx->aes_Nrnd)
|
|
+ {
|
|
+ case 14: round(fwd_rnd, b1, b0, kp );
|
|
+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
|
|
+ case 12: round(fwd_rnd, b1, b0, kp );
|
|
+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
|
|
+ case 10: round(fwd_rnd, b1, b0, kp );
|
|
+ round(fwd_rnd, b0, b1, kp + nc);
|
|
+ round(fwd_rnd, b1, b0, kp + 2 * nc);
|
|
+ round(fwd_rnd, b0, b1, kp + 3 * nc);
|
|
+ round(fwd_rnd, b1, b0, kp + 4 * nc);
|
|
+ round(fwd_rnd, b0, b1, kp + 5 * nc);
|
|
+ round(fwd_rnd, b1, b0, kp + 6 * nc);
|
|
+ round(fwd_rnd, b0, b1, kp + 7 * nc);
|
|
+ round(fwd_rnd, b1, b0, kp + 8 * nc);
|
|
+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
|
|
+ }
|
|
+
|
|
+#elif defined(PARTIAL_UNROLL)
|
|
+ { u_int32_t rnd;
|
|
+
|
|
+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
|
|
+ {
|
|
+ round(fwd_rnd, b1, b0, kp);
|
|
+ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
|
|
+ }
|
|
+
|
|
+ round(fwd_rnd, b1, b0, kp);
|
|
+ round(fwd_lrnd, b0, b1, kp + nc);
|
|
+ }
|
|
+#else
|
|
+ { u_int32_t rnd;
|
|
+
|
|
+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
|
|
+ {
|
|
+ round(fwd_rnd, b1, b0, kp);
|
|
+ l_copy(b0, b1); kp += nc;
|
|
+ }
|
|
+
|
|
+ round(fwd_lrnd, b0, b1, kp);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ state_out(out_blk, b0);
|
|
+}
|
|
+
|
|
+void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
|
|
+{ u_int32_t locals(b0, b1);
|
|
+ const u_int32_t *kp = cx->aes_d_key;
|
|
+
|
|
+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
|
|
+ u_int32_t f2, f4, f8, f9;
|
|
+#endif
|
|
+
|
|
+ state_in(b0, in_blk, kp); kp += nc;
|
|
+
|
|
+#if defined(UNROLL)
|
|
+
|
|
+ switch(cx->aes_Nrnd)
|
|
+ {
|
|
+ case 14: round(inv_rnd, b1, b0, kp );
|
|
+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
|
|
+ case 12: round(inv_rnd, b1, b0, kp );
|
|
+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
|
|
+ case 10: round(inv_rnd, b1, b0, kp );
|
|
+ round(inv_rnd, b0, b1, kp + nc);
|
|
+ round(inv_rnd, b1, b0, kp + 2 * nc);
|
|
+ round(inv_rnd, b0, b1, kp + 3 * nc);
|
|
+ round(inv_rnd, b1, b0, kp + 4 * nc);
|
|
+ round(inv_rnd, b0, b1, kp + 5 * nc);
|
|
+ round(inv_rnd, b1, b0, kp + 6 * nc);
|
|
+ round(inv_rnd, b0, b1, kp + 7 * nc);
|
|
+ round(inv_rnd, b1, b0, kp + 8 * nc);
|
|
+ round(inv_lrnd, b0, b1, kp + 9 * nc);
|
|
+ }
|
|
+
|
|
+#elif defined(PARTIAL_UNROLL)
|
|
+ { u_int32_t rnd;
|
|
+
|
|
+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
|
|
+ {
|
|
+ round(inv_rnd, b1, b0, kp);
|
|
+ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
|
|
+ }
|
|
+
|
|
+ round(inv_rnd, b1, b0, kp);
|
|
+ round(inv_lrnd, b0, b1, kp + nc);
|
|
+ }
|
|
+#else
|
|
+ { u_int32_t rnd;
|
|
+
|
|
+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
|
|
+ {
|
|
+ round(inv_rnd, b1, b0, kp);
|
|
+ l_copy(b0, b1); kp += nc;
|
|
+ }
|
|
+
|
|
+ round(inv_lrnd, b0, b1, kp);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ state_out(out_blk, b0);
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/aes/aes_cbc.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,46 @@
|
|
+/*
|
|
+// I retain copyright in this code but I encourage its free use provided
|
|
+// that I don't carry any responsibility for the results. I am especially
|
|
+// happy to see it used in free and open source software. If you do use
|
|
+// it I would appreciate an acknowledgement of its origin in the code or
|
|
+// the product that results and I would also appreciate knowing a little
|
|
+// about the use to which it is being put. I am grateful to Frank Yellin
|
|
+// for some ideas that are used in this implementation.
|
|
+//
|
|
+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
|
|
+//
|
|
+// This is an implementation of the AES encryption algorithm (Rijndael)
|
|
+// designed by Joan Daemen and Vincent Rijmen. This version is designed
|
|
+// to provide both fixed and dynamic block and key lengths and can also
|
|
+// run with either big or little endian internal byte order (see aes.h).
|
|
+// It inputs block and key lengths in bytes with the legal values being
|
|
+// 16, 24 and 32.
|
|
+*
|
|
+*/
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+#include <linux/types.h>
|
|
+#else
|
|
+#include <sys/types.h>
|
|
+#endif
|
|
+#include "crypto/aes_cbc.h"
|
|
+#include "crypto/cbc_generic.h"
|
|
+
|
|
+/* returns bool success */
|
|
+int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
|
|
+ aes_set_key(aes_ctx, key, keysize, 0);
|
|
+ return 1;
|
|
+}
|
|
+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: aes_cbc.c,v $
|
|
+ * Revision 1.2 2004/07/10 07:48:40 mcr
|
|
+ * Moved from linux/crypto/ciphers/aes/aes_cbc.c,v
|
|
+ *
|
|
+ * Revision 1.1 2004/04/06 02:48:12 mcr
|
|
+ * pullup of AES cipher from alg-branch.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,67 @@
|
|
+#ifdef __KERNEL__
|
|
+#include <linux/types.h>
|
|
+#include <linux/kernel.h>
|
|
+#define DEBUG(x)
|
|
+#else
|
|
+#include <stdio.h>
|
|
+#include <sys/types.h>
|
|
+#define DEBUG(x) x
|
|
+#endif
|
|
+
|
|
+#include "crypto/aes.h"
|
|
+#include "crypto/aes_xcbc_mac.h"
|
|
+
|
|
+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
|
|
+{
|
|
+ int ret=1;
|
|
+ aes_block kn[3] = {
|
|
+ { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
|
|
+ { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
|
|
+ { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
|
|
+ };
|
|
+ aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
|
|
+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
|
|
+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
|
|
+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
|
|
+ aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
|
|
+ return ret;
|
|
+}
|
|
+static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
|
|
+ int pos=0;
|
|
+ for (pos=1; pos <= 16; pos++, in++, out++) {
|
|
+ if (pos <= len)
|
|
+ *out ^= *in;
|
|
+ if (pos > len) {
|
|
+ DEBUG(printf("put 0x80 at pos=%d\n", pos));
|
|
+ *out ^= 0x80;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+static void xor_block(aes_block res, const aes_block op) {
|
|
+ res[0] ^= op[0];
|
|
+ res[1] ^= op[1];
|
|
+ res[2] ^= op[2];
|
|
+ res[3] ^= op[3];
|
|
+}
|
|
+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
|
|
+ int ret=ilen;
|
|
+ u_int32_t out[4] = { 0, 0, 0, 0 };
|
|
+ for (; ilen > 16 ; ilen-=16) {
|
|
+ xor_block(out, (const u_int32_t*) &in[0]);
|
|
+ aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
|
|
+ in+=16;
|
|
+ }
|
|
+ do_pad_xor((u_int8_t *)&out, in, ilen);
|
|
+ if (ilen==16) {
|
|
+ DEBUG(printf("using k3\n"));
|
|
+ xor_block(out, ctxm->k3);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ DEBUG(printf("using k2\n"));
|
|
+ xor_block(out, ctxm->k2);
|
|
+ }
|
|
+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
|
|
+ return ret;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/aes/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,296 @@
|
|
+/*
|
|
+ * ipsec_alg AES cipher stubs
|
|
+ *
|
|
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
|
|
+ *
|
|
+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * Fixes by:
|
|
+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
|
|
+ * Fixes list:
|
|
+ * PK: make XCBC comply with latest draft (keylength)
|
|
+ *
|
|
+ */
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+/*
|
|
+ * special case: ipsec core modular with this static algo inside:
|
|
+ * must avoid MODULE magic for this file
|
|
+ */
|
|
+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_AES)
|
|
+#undef MODULE
|
|
+#endif
|
|
+
|
|
+#include <linux/module.h>
|
|
+#include <linux/init.h>
|
|
+
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/string.h>
|
|
+
|
|
+/* Check if __exit is defined, if not null it */
|
|
+#ifndef __exit
|
|
+#define __exit
|
|
+#endif
|
|
+
|
|
+/* Low freeswan header coupling */
|
|
+#include "openswan/ipsec_alg.h"
|
|
+#include "crypto/aes_cbc.h"
|
|
+
|
|
+#define CONFIG_KLIPS_ENC_AES_MAC 1
|
|
+
|
|
+#define AES_CONTEXT_T aes_context
|
|
+static int debug_aes=0;
|
|
+static int test_aes=0;
|
|
+static int excl_aes=0;
|
|
+static int keyminbits=0;
|
|
+static int keymaxbits=0;
|
|
+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
|
|
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
|
|
+#ifdef module_param
|
|
+module_param(debug_aes,int,0600)
|
|
+module_param(test_aes,int,0600)
|
|
+module_param(excl_aes,int,0600)
|
|
+module_param(keyminbits,int,0600)
|
|
+module_param(keymaxbits,int,0600)
|
|
+#else
|
|
+MODULE_PARM(debug_aes, "i");
|
|
+MODULE_PARM(test_aes, "i");
|
|
+MODULE_PARM(excl_aes, "i");
|
|
+MODULE_PARM(keyminbits, "i");
|
|
+MODULE_PARM(keymaxbits, "i");
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#if CONFIG_KLIPS_ENC_AES_MAC
|
|
+#include "crypto/aes_xcbc_mac.h"
|
|
+
|
|
+/*
|
|
+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
|
|
+ * We use 9 for non-modular algorithm and none for modular, thus
|
|
+ * forcing user to specify one on module load. -kravietz
|
|
+ */
|
|
+#ifdef MODULE
|
|
+static int auth_id=0;
|
|
+#else
|
|
+static int auth_id=9;
|
|
+#endif
|
|
+#ifdef module_param
|
|
+module_param(auth_id, int, 0600);
|
|
+#else
|
|
+MODULE_PARM(auth_id, "i");
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#define ESP_AES 12 /* truely _constant_ :) */
|
|
+
|
|
+/* 128, 192 or 256 */
|
|
+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
|
|
+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
|
|
+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
|
|
+
|
|
+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
|
|
+ * -kravietz
|
|
+ */
|
|
+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
|
|
+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
|
|
+
|
|
+static int _aes_set_key(struct ipsec_alg_enc *alg,
|
|
+ __u8 * key_e, const __u8 * key,
|
|
+ size_t keysize)
|
|
+{
|
|
+ int ret;
|
|
+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
|
|
+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
|
|
+ if (debug_aes > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_aes_set_key:"
|
|
+ "ret=%d key_e=%p key=%p keysize=%ld\n",
|
|
+ ret, key_e, key, (unsigned long int) keysize);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e,
|
|
+ __u8 * in, int ilen, const __u8 * iv,
|
|
+ int encrypt)
|
|
+{
|
|
+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
|
|
+ if (debug_aes > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
|
|
+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
|
|
+ key_e, in, ilen, iv, encrypt);
|
|
+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
|
|
+}
|
|
+#if CONFIG_KLIPS_ENC_AES_MAC
|
|
+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
|
|
+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
|
|
+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
|
|
+}
|
|
+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
|
|
+ int ret;
|
|
+ char hash_buf[16];
|
|
+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
|
|
+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
|
|
+ memcpy(hash, hash_buf, hashlen);
|
|
+ return ret;
|
|
+}
|
|
+static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
|
|
+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
|
|
+ ixt_refcnt: ATOMIC_INIT(0),
|
|
+ ixt_name: "aes_mac",
|
|
+ ixt_blocksize: ESP_AES_MAC_BLK_LEN,
|
|
+ ixt_support: {
|
|
+ ias_exttype: IPSEC_ALG_TYPE_AUTH,
|
|
+ ias_id: 0,
|
|
+ ias_keyminbits: ESP_AES_MAC_KEY_SZ*8,
|
|
+ ias_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
|
|
+ },
|
|
+ },
|
|
+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
|
|
+ ixt_module: THIS_MODULE,
|
|
+#endif
|
|
+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
|
|
+ ixt_a_ctx_size: sizeof(aes_context_mac),
|
|
+ ixt_a_hmac_set_key: _aes_mac_set_key,
|
|
+ ixt_a_hmac_hash:_aes_mac_hash,
|
|
+};
|
|
+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
|
|
+static struct ipsec_alg_enc ipsec_alg_AES = {
|
|
+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
|
|
+ ixt_refcnt: ATOMIC_INIT(0),
|
|
+ ixt_name: "aes",
|
|
+ ixt_blocksize: ESP_AES_CBC_BLK_LEN,
|
|
+ ixt_support: {
|
|
+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
|
|
+ ias_id: ESP_AES,
|
|
+ ias_keyminbits: ESP_AES_KEY_SZ_MIN*8,
|
|
+ ias_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
|
|
+ },
|
|
+ },
|
|
+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
|
|
+ ixt_module: THIS_MODULE,
|
|
+#endif
|
|
+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
|
|
+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
|
|
+ ixt_e_set_key: _aes_set_key,
|
|
+ ixt_e_cbc_encrypt:_aes_cbc_encrypt,
|
|
+};
|
|
+
|
|
+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
|
|
+IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
|
|
+#else
|
|
+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
|
|
+#endif
|
|
+{
|
|
+ int ret, test_ret;
|
|
+
|
|
+ if (keyminbits)
|
|
+ ipsec_alg_AES.ixt_common.ixt_support.ias_keyminbits=keyminbits;
|
|
+ if (keymaxbits) {
|
|
+ ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits=keymaxbits;
|
|
+ if (keymaxbits*8>ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits)
|
|
+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
|
|
+ }
|
|
+ if (excl_aes) ipsec_alg_AES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
|
|
+ ret=register_ipsec_alg_enc(&ipsec_alg_AES);
|
|
+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
|
|
+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
|
|
+ ipsec_alg_AES.ixt_common.ixt_name,
|
|
+ ret);
|
|
+ if (ret==0 && test_aes) {
|
|
+ test_ret=ipsec_alg_test(
|
|
+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
|
|
+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
|
|
+ test_aes);
|
|
+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
|
|
+ ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
|
|
+ ipsec_alg_AES.ixt_common.ixt_support.ias_id,
|
|
+ test_ret);
|
|
+ }
|
|
+#if CONFIG_KLIPS_ENC_AES_MAC
|
|
+ if (auth_id!=0){
|
|
+ int ret;
|
|
+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id=auth_id;
|
|
+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
|
|
+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
|
|
+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
|
|
+ ipsec_alg_AES_MAC.ixt_common.ixt_name,
|
|
+ ret);
|
|
+ if (ret==0 && test_aes) {
|
|
+ test_ret=ipsec_alg_test(
|
|
+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
|
|
+ test_aes);
|
|
+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
|
|
+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
|
|
+ test_ret);
|
|
+ }
|
|
+ } else {
|
|
+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
|
|
+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
|
|
+#else
|
|
+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
|
|
+#endif
|
|
+{
|
|
+#if CONFIG_KLIPS_ENC_AES_MAC
|
|
+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
|
|
+#endif /* CONFIG_KLIPS_ENC_AES_MAC */
|
|
+ unregister_ipsec_alg_enc(&ipsec_alg_AES);
|
|
+ return;
|
|
+}
|
|
+#ifdef MODULE_LICENSE
|
|
+MODULE_LICENSE("GPL");
|
|
+#endif
|
|
+
|
|
+#if 0 /* +NOT_YET */
|
|
+#ifndef MODULE
|
|
+/*
|
|
+ * This is intended for static module setups, currently
|
|
+ * doesn't work for modular ipsec.o with static algos inside
|
|
+ */
|
|
+static int setup_keybits(const char *str)
|
|
+{
|
|
+ unsigned aux;
|
|
+ char *end;
|
|
+
|
|
+ aux = simple_strtoul(str,&end,0);
|
|
+ if (aux != 128 && aux != 192 && aux != 256)
|
|
+ return 0;
|
|
+ keyminbits = aux;
|
|
+
|
|
+ if (*end == 0 || *end != ',')
|
|
+ return 1;
|
|
+ str=end+1;
|
|
+ aux = simple_strtoul(str, NULL, 0);
|
|
+ if (aux != 128 && aux != 192 && aux != 256)
|
|
+ return 0;
|
|
+ if (aux >= keyminbits)
|
|
+ keymaxbits = aux;
|
|
+ return 1;
|
|
+}
|
|
+__setup("ipsec_aes_keybits=", setup_keybits);
|
|
+#endif
|
|
+#endif
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,3 @@
|
|
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
|
|
+ tristate ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES
|
|
+fi
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,6 @@
|
|
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
|
|
+ dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
|
|
+ if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
|
|
+ bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
|
|
+ fi
|
|
+fi
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,3 @@
|
|
+#Placeholder
|
|
+source net/ipsec/alg/Config.alg_aes.in
|
|
+source net/ipsec/alg/Config.alg_cryptoapi.in
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/alg/Makefile Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,112 @@
|
|
+# Makefile,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
|
|
+ifeq ($(strip $(KLIPSMODULE)),)
|
|
+FREESWANSRCDIR=.
|
|
+else
|
|
+FREESWANSRCDIR=../../../..
|
|
+endif
|
|
+ifeq ($(strip $(KLIPS_TOP)),)
|
|
+KLIPS_TOP=../../..
|
|
+override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include
|
|
+endif
|
|
+
|
|
+ifeq ($(CONFIG_IPSEC_DEBUG),y)
|
|
+override EXTRA_CFLAGS += -g
|
|
+endif
|
|
+
|
|
+# LIBCRYPTO normally comes as an argument from "parent" Makefile
|
|
+# (this applies both to FS' "make module" and eg. Linux' "make modules"
|
|
+# But make dep doest follow same evaluations, so we need this default:
|
|
+LIBCRYPTO=$(TOPDIR)/lib/libcrypto
|
|
+
|
|
+override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include
|
|
+override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes
|
|
+
|
|
+MOD_LIST_NAME := NET_MISC_MODULES
|
|
+
|
|
+#O_TARGET := static_init.o
|
|
+
|
|
+subdir- :=
|
|
+subdir-n :=
|
|
+subdir-y :=
|
|
+subdir-m :=
|
|
+
|
|
+obj-y := static_init.o
|
|
+
|
|
+ARCH_ASM-y :=
|
|
+ARCH_ASM-$(CONFIG_M586) := i586
|
|
+ARCH_ASM-$(CONFIG_M586TSC) := i586
|
|
+ARCH_ASM-$(CONFIG_M586MMX) := i586
|
|
+ARCH_ASM-$(CONFIG_MK6) := i586
|
|
+ARCH_ASM-$(CONFIG_M686) := i686
|
|
+ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686
|
|
+ARCH_ASM-$(CONFIG_MPENTIUM4) := i686
|
|
+ARCH_ASM-$(CONFIG_MK7) := i686
|
|
+ARCH_ASM-$(CONFIG_MCRUSOE) := i586
|
|
+ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586
|
|
+ARCH_ASM-$(CONFIG_MWINCHIP2) := i586
|
|
+ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586
|
|
+ARCH_ASM-$(CONFIG_USERMODE) := i586
|
|
+
|
|
+ARCH_ASM :=$(ARCH_ASM-y)
|
|
+ifdef NO_ASM
|
|
+ARCH_ASM :=
|
|
+endif
|
|
+
|
|
+# The algorithm makefiles may put dependences, short-circuit them
|
|
+null:
|
|
+
|
|
+makefiles=$(filter-out %.preipsec, $(wildcard Makefile.alg_*))
|
|
+ifneq ($(makefiles),)
|
|
+#include Makefile.alg_aes
|
|
+#include Makefile.alg_aes-opt
|
|
+include $(makefiles)
|
|
+endif
|
|
+
|
|
+# These rules translate from new to old makefile rules
|
|
+# Translate to Rules.make lists.
|
|
+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m))
|
|
+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs))
|
|
+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m))
|
|
+O_OBJS := $(obj-y)
|
|
+M_OBJS := $(obj-m)
|
|
+MIX_OBJS := $(filter $(export-objs), $(active-objs))
|
|
+#OX_OBJS := $(export-objs)
|
|
+SUB_DIRS := $(subdir-y)
|
|
+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
|
|
+MOD_SUB_DIRS := $(subdir-m)
|
|
+
|
|
+
|
|
+static_init_mod.o: $(obj-y)
|
|
+ rm -f $@
|
|
+ $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@
|
|
+
|
|
+perlasm: ../../../crypto/ciphers/des/asm/perlasm
|
|
+ ln -sf $? $@
|
|
+
|
|
+$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
|
|
+$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
|
|
+
|
|
+
|
|
+all_alg_modules: perlasm $(ALG_MODULES)
|
|
+ @echo "ALG_MODULES=$(ALG_MODULES)"
|
|
+
|
|
+
|
|
+#
|
|
+# Construct alg. init. function: call ipsec_ALGO_init() for every static algo
|
|
+# Needed when there are static algos (with static or modular ipsec.o)
|
|
+#
|
|
+static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh
|
|
+ @echo "Re-creating $@"
|
|
+ $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@
|
|
+
|
|
+clean:
|
|
+ @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0
|
|
+ @find . -type l -exec rm -f {} \;
|
|
+ -rm -f perlasm
|
|
+ -rm -rf $(ALG_SUBDIRS)
|
|
+ -rm -f *.o static_init.c
|
|
+
|
|
+ifdef TOPDIR
|
|
+include $(TOPDIR)/Rules.make
|
|
+endif
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,18 @@
|
|
+MOD_AES := ipsec_aes.o
|
|
+
|
|
+ALG_MODULES += $(MOD_AES)
|
|
+ALG_SUBDIRS += libaes
|
|
+
|
|
+obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
|
|
+static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
|
|
+alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
|
|
+
|
|
+AES_OBJS := ipsec_alg_aes.o $(LIBCRYPTO)/libaes/libaes.a
|
|
+
|
|
+
|
|
+$(MOD_AES): $(AES_OBJS)
|
|
+ $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
|
|
+
|
|
+$(LIBCRYPTO)/libaes/libaes.a:
|
|
+ $(MAKE) -C $(LIBCRYPTO)/libaes CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,14 @@
|
|
+MOD_CRYPTOAPI := ipsec_cryptoapi.o
|
|
+
|
|
+ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
|
|
+ALG_MODULES += $(MOD_CRYPTOAPI)
|
|
+obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
|
|
+static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
|
|
+alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
|
|
+else
|
|
+$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
|
|
+endif
|
|
+
|
|
+CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
|
|
+$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
|
|
+ $(LD) -r $(CRYPTOAPI_OBJS) -o $@
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,442 @@
|
|
+/*
|
|
+ * ipsec_alg to linux cryptoapi GLUE
|
|
+ *
|
|
+ * Authors: CODE.ar TEAM
|
|
+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
|
|
+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
|
|
+ * Luciano Ruete <docemeses@softhome.net>
|
|
+ *
|
|
+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * Example usage:
|
|
+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
|
|
+ * modprobe ipsec_cryptoapi
|
|
+ * modprobe ipsec_cryptoapi test=1
|
|
+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
|
|
+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
|
|
+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
|
|
+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
|
|
+ */
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+/*
|
|
+ * special case: ipsec core modular with this static algo inside:
|
|
+ * must avoid MODULE magic for this file
|
|
+ */
|
|
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
|
|
+#undef MODULE
|
|
+#endif
|
|
+
|
|
+#include <linux/module.h>
|
|
+#include <linux/init.h>
|
|
+
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/string.h>
|
|
+
|
|
+/* Check if __exit is defined, if not null it */
|
|
+#ifndef __exit
|
|
+#define __exit
|
|
+#endif
|
|
+
|
|
+/* warn the innocent */
|
|
+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
|
|
+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
|
|
+#define NO_CRYPTOAPI_SUPPORT
|
|
+#endif
|
|
+/* Low freeswan header coupling */
|
|
+#include "openswan/ipsec_alg.h"
|
|
+
|
|
+#include <linux/crypto.h>
|
|
+#ifdef CRYPTO_API_VERSION_CODE
|
|
+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
|
|
+#define NO_CRYPTOAPI_SUPPORT
|
|
+#endif
|
|
+
|
|
+#ifdef NO_CRYPTOAPI_SUPPORT
|
|
+#warning "Building an unusable module :P"
|
|
+/* Catch old CryptoAPI by not allowing module to load */
|
|
+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
|
|
+{
|
|
+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
|
|
+ return -EINVAL;
|
|
+}
|
|
+#else
|
|
+#include <asm/scatterlist.h>
|
|
+#include <asm/pgtable.h>
|
|
+#include <linux/mm.h>
|
|
+
|
|
+#define CIPHERNAME_AES "aes"
|
|
+#define CIPHERNAME_3DES "des3_ede"
|
|
+#define CIPHERNAME_BLOWFISH "blowfish"
|
|
+#define CIPHERNAME_CAST "cast5"
|
|
+#define CIPHERNAME_SERPENT "serpent"
|
|
+#define CIPHERNAME_TWOFISH "twofish"
|
|
+
|
|
+#define ESP_3DES 3
|
|
+#define ESP_AES 12
|
|
+#define ESP_BLOWFISH 7 /* truely _constant_ :) */
|
|
+#define ESP_CAST 6 /* quite constant :) */
|
|
+#define ESP_SERPENT 252 /* from ipsec drafts */
|
|
+#define ESP_TWOFISH 253 /* from ipsec drafts */
|
|
+
|
|
+#define AH_MD5 2
|
|
+#define AH_SHA 3
|
|
+#define DIGESTNAME_MD5 "md5"
|
|
+#define DIGESTNAME_SHA1 "sha1"
|
|
+
|
|
+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
|
|
+static int debug=0;
|
|
+static int test=0;
|
|
+static int excl=0;
|
|
+static int noauto = 0;
|
|
+
|
|
+static int des_ede3[] = {-1, -1};
|
|
+static int aes[] = {-1, -1};
|
|
+static int blowfish[] = {-1, -1};
|
|
+static int cast[] = {-1, -1};
|
|
+static int serpent[] = {-1, -1};
|
|
+static int twofish[] = {-1, -1};
|
|
+
|
|
+#ifdef module_param
|
|
+module_param(debug,int,0600);
|
|
+module_param(test,int,0600);
|
|
+module_param(ebug,int,0600);
|
|
+
|
|
+module_param(noauto,int,0600);
|
|
+module_param(ebug,int,0600);
|
|
+
|
|
+module_param_array(des_ede3,int,NULL,0);
|
|
+module_param(aes,int,NULL,0);
|
|
+module_param(blowfish,int,NULL,0);
|
|
+module_param(cast,int,NULL,0);
|
|
+module_param(serpent,int,NULL,0);
|
|
+module_param(twofish,int,NULL,0);
|
|
+#else
|
|
+MODULE_PARM(debug, "i");
|
|
+MODULE_PARM(test, "i");
|
|
+MODULE_PARM(excl, "i");
|
|
+
|
|
+MODULE_PARM(noauto,"i");
|
|
+
|
|
+MODULE_PARM(des_ede3,"1-2i");
|
|
+MODULE_PARM(aes,"1-2i");
|
|
+MODULE_PARM(blowfish,"1-2i");
|
|
+MODULE_PARM(cast,"1-2i");
|
|
+MODULE_PARM(serpent,"1-2i");
|
|
+MODULE_PARM(twofish,"1-2i");
|
|
+#endif
|
|
+
|
|
+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
|
|
+
|
|
+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
|
|
+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+
|
|
+struct ipsec_alg_capi_cipher {
|
|
+ const char *ciphername; /* cryptoapi's ciphername */
|
|
+ unsigned blocksize;
|
|
+ unsigned short minbits;
|
|
+ unsigned short maxbits;
|
|
+ int *parm; /* lkm param for this cipher */
|
|
+ struct ipsec_alg_enc alg; /* note it's not a pointer */
|
|
+};
|
|
+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
|
|
+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
|
|
+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
|
|
+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
|
|
+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
|
|
+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
|
|
+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
|
|
+ { NULL, 0, 0, 0, NULL, {} }
|
|
+};
|
|
+#ifdef NOT_YET
|
|
+struct ipsec_alg_capi_digest {
|
|
+ const char *digestname; /* cryptoapi's digestname */
|
|
+ struct digest_implementation *di;
|
|
+ struct ipsec_alg_auth alg; /* note it's not a pointer */
|
|
+};
|
|
+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
|
|
+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
|
|
+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
|
|
+ { NULL, NULL, {} }
|
|
+};
|
|
+#endif
|
|
+/*
|
|
+ * "generic" linux cryptoapi setup_cipher() function
|
|
+ */
|
|
+int setup_cipher(const char *ciphername)
|
|
+{
|
|
+ return crypto_alg_available(ciphername, 0);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
|
|
+ * register_ipsec_alg for cointaned ipsec_alg object
|
|
+ */
|
|
+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
|
|
+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
|
|
+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
|
|
+
|
|
+static int
|
|
+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
|
|
+{
|
|
+ int ret;
|
|
+ cptr->alg.ixt_version = IPSEC_ALG_VERSION;
|
|
+ cptr->alg.ixt_module = THIS_MODULE;
|
|
+ atomic_set (& cptr->alg.ixt_refcnt, 0);
|
|
+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
|
|
+
|
|
+ cptr->alg.ixt_blocksize=cptr->blocksize;
|
|
+ cptr->alg.ixt_keyminbits=cptr->minbits;
|
|
+ cptr->alg.ixt_keymaxbits=cptr->maxbits;
|
|
+ cptr->alg.ixt_state = 0;
|
|
+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
|
|
+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
|
|
+ cptr->alg.ixt_e_ctx_size = 0;
|
|
+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
|
|
+ cptr->alg.ixt_e_new_key = _capi_new_key;
|
|
+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
|
|
+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
|
|
+ cptr->alg.ixt_data = cptr;
|
|
+
|
|
+ ret=register_ipsec_alg_enc(&cptr->alg);
|
|
+ printk("setup_ipsec_alg_capi_cipher(): "
|
|
+ "alg_type=%d alg_id=%d name=%s "
|
|
+ "keyminbits=%d keymaxbits=%d, ret=%d\n",
|
|
+ cptr->alg.ixt_alg_type,
|
|
+ cptr->alg.ixt_alg_id,
|
|
+ cptr->alg.ixt_name,
|
|
+ cptr->alg.ixt_keyminbits,
|
|
+ cptr->alg.ixt_keymaxbits,
|
|
+ ret);
|
|
+ return ret;
|
|
+}
|
|
+/*
|
|
+ * called in ipsec_sa_wipe() time, will destroy key contexts
|
|
+ * and do 1 unbind()
|
|
+ */
|
|
+static void
|
|
+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
|
|
+{
|
|
+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
|
|
+
|
|
+ if (debug > 0)
|
|
+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
|
|
+ "name=%s key_e=%p \n",
|
|
+ alg->ixt_name, key_e);
|
|
+ if (!key_e) {
|
|
+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
|
|
+ "name=%s NULL key_e!\n",
|
|
+ alg->ixt_name);
|
|
+ return;
|
|
+ }
|
|
+ crypto_free_tfm(tfm);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * create new key context, need alg->ixt_data to know which
|
|
+ * (of many) cipher inside this module is the target
|
|
+ */
|
|
+static __u8 *
|
|
+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
|
|
+{
|
|
+ struct ipsec_alg_capi_cipher *cptr;
|
|
+ struct crypto_tfm *tfm=NULL;
|
|
+
|
|
+ cptr = alg->ixt_data;
|
|
+ if (!cptr) {
|
|
+ printk(KERN_ERR "_capi_new_key(): "
|
|
+ "NULL ixt_data (?!) for \"%s\" algo\n"
|
|
+ , alg->ixt_name);
|
|
+ goto err;
|
|
+ }
|
|
+ if (debug > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
|
|
+ "name=%s cptr=%p key=%p keysize=%d\n",
|
|
+ alg->ixt_name, cptr, key, keylen);
|
|
+
|
|
+ /*
|
|
+ * alloc tfm
|
|
+ */
|
|
+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
|
|
+ if (!tfm) {
|
|
+ printk(KERN_ERR "_capi_new_key(): "
|
|
+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
|
|
+ , alg->ixt_name, cptr->ciphername);
|
|
+ goto err;
|
|
+ }
|
|
+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
|
|
+ printk(KERN_ERR "_capi_new_key(): "
|
|
+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
|
|
+ , alg->ixt_name, keylen);
|
|
+ crypto_free_tfm(tfm);
|
|
+ tfm=NULL;
|
|
+ }
|
|
+err:
|
|
+ if (debug > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
|
|
+ "name=%s key=%p keylen=%d tfm=%p\n",
|
|
+ alg->ixt_name, key, keylen, tfm);
|
|
+ return (__u8 *) tfm;
|
|
+}
|
|
+/*
|
|
+ * core encryption function: will use cx->ci to call actual cipher's
|
|
+ * cbc function
|
|
+ */
|
|
+static int
|
|
+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
|
|
+ int error =0;
|
|
+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
|
|
+ struct scatterlist sg = {
|
|
+ .page = virt_to_page(in),
|
|
+ .offset = (unsigned long)(in) % PAGE_SIZE,
|
|
+ .length=ilen,
|
|
+ };
|
|
+ if (debug > 1)
|
|
+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
|
|
+ "key_e=%p "
|
|
+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
|
|
+ , key_e
|
|
+ , in, in, ilen, iv, encrypt);
|
|
+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
|
|
+ if (encrypt)
|
|
+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
|
|
+ else
|
|
+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
|
|
+ if (debug > 1)
|
|
+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
|
|
+ "error=%d\n"
|
|
+ , error);
|
|
+ return (error<0)? error : ilen;
|
|
+}
|
|
+/*
|
|
+ * main initialization loop: for each cipher in list, do
|
|
+ * 1) setup cryptoapi cipher else continue
|
|
+ * 2) register ipsec_alg object
|
|
+ */
|
|
+static int
|
|
+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
|
|
+{
|
|
+ struct ipsec_alg_capi_cipher *cptr;
|
|
+ /* foreach cipher in list ... */
|
|
+ for (cptr=clist;cptr->ciphername;cptr++) {
|
|
+ /*
|
|
+ * see if cipher has been disabled (0) or
|
|
+ * if noauto set and not enabled (1)
|
|
+ */
|
|
+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
|
|
+ if (debug>0)
|
|
+ printk(KERN_INFO "setup_cipher_list(): "
|
|
+ "ciphername=%s skipped at user request: "
|
|
+ "noauto=%d parm[0]=%d parm[1]=%d\n"
|
|
+ , cptr->ciphername
|
|
+ , noauto
|
|
+ , cptr->parm[0]
|
|
+ , cptr->parm[1]);
|
|
+ continue;
|
|
+ }
|
|
+ /*
|
|
+ * use a local ci to avoid touching cptr->ci,
|
|
+ * if register ipsec_alg success then bind cipher
|
|
+ */
|
|
+ if( setup_cipher(cptr->ciphername) ) {
|
|
+ if (debug > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:"
|
|
+ "setup_cipher_list():"
|
|
+ "ciphername=%s found\n"
|
|
+ , cptr->ciphername);
|
|
+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
|
|
+
|
|
+
|
|
+ } else {
|
|
+ printk(KERN_ERR "klips_debug:"
|
|
+ "setup_cipher_list():"
|
|
+ "ciphername=%s failed ipsec_alg_register\n"
|
|
+ , cptr->ciphername);
|
|
+ }
|
|
+ } else {
|
|
+ if (debug>0)
|
|
+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
|
|
+ cptr->ciphername);
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+/*
|
|
+ * deregister ipsec_alg objects and unbind ciphers
|
|
+ */
|
|
+static int
|
|
+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
|
|
+{
|
|
+ struct ipsec_alg_capi_cipher *cptr;
|
|
+ /* foreach cipher in list ... */
|
|
+ for (cptr=clist;cptr->ciphername;cptr++) {
|
|
+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
|
|
+ unregister_ipsec_alg_enc(&cptr->alg);
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+/*
|
|
+ * test loop for registered algos
|
|
+ */
|
|
+static int
|
|
+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
|
|
+{
|
|
+ int test_ret;
|
|
+ struct ipsec_alg_capi_cipher *cptr;
|
|
+ /* foreach cipher in list ... */
|
|
+ for (cptr=clist;cptr->ciphername;cptr++) {
|
|
+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
|
|
+ test_ret=ipsec_alg_test(
|
|
+ cptr->alg.ixt_alg_type,
|
|
+ cptr->alg.ixt_alg_id,
|
|
+ test);
|
|
+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
|
|
+ cptr->alg.ixt_alg_type,
|
|
+ cptr->alg.ixt_alg_id,
|
|
+ test_ret);
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
|
|
+{
|
|
+ int ret, test_ret;
|
|
+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
|
|
+ return -EPROTONOSUPPORT;
|
|
+ if (ret==0 && test) {
|
|
+ test_ret=test_cipher_list(alg_capi_carray);
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
|
|
+{
|
|
+ unsetup_cipher_list(alg_capi_carray);
|
|
+ return;
|
|
+}
|
|
+#ifdef MODULE_LICENSE
|
|
+MODULE_LICENSE("GPL");
|
|
+#endif
|
|
+
|
|
+EXPORT_NO_SYMBOLS;
|
|
+#endif /* NO_CRYPTOAPI_SUPPORT */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,18 @@
|
|
+#!/bin/sh
|
|
+cat << EOF
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/list.h>
|
|
+#include "freeswan/ipsec_alg.h"
|
|
+$(for i in $*; do
|
|
+ test -z "$i" && continue
|
|
+ echo "extern int $i(void);"
|
|
+done)
|
|
+void ipsec_alg_static_init(void){
|
|
+ int __attribute__ ((unused)) err=0;
|
|
+$(for i in $*; do
|
|
+ test -z "$i" && continue
|
|
+ echo " if ((err=$i()) < 0)"
|
|
+ echo " printk(KERN_WARNING \"$i() returned %d\", err);"
|
|
+done)
|
|
+}
|
|
+EOF
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/anyaddr.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,148 @@
|
|
+/*
|
|
+ * special addresses
|
|
+ * Copyright (C) 2000 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: anyaddr.c,v 1.10.10.1 2006/11/24 05:55:46 paul Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+/* these are mostly fallbacks for the no-IPv6-support-in-library case */
|
|
+#ifndef IN6ADDR_ANY_INIT
|
|
+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
|
|
+#endif
|
|
+#ifndef IN6ADDR_LOOPBACK_INIT
|
|
+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
|
|
+#endif
|
|
+
|
|
+static struct in6_addr v6any = IN6ADDR_ANY_INIT;
|
|
+static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
|
|
+
|
|
+/*
|
|
+ - anyaddr - initialize to the any-address value
|
|
+ */
|
|
+err_t /* NULL for success, else string literal */
|
|
+anyaddr(af, dst)
|
|
+int af; /* address family */
|
|
+ip_address *dst;
|
|
+{
|
|
+ uint32_t v4any = htonl(INADDR_ANY);
|
|
+
|
|
+ switch (af) {
|
|
+ case AF_INET:
|
|
+ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
|
|
+ break;
|
|
+ default:
|
|
+ return "unknown address family in anyaddr/unspecaddr";
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ - unspecaddr - initialize to the unspecified-address value
|
|
+ */
|
|
+err_t /* NULL for success, else string literal */
|
|
+unspecaddr(af, dst)
|
|
+int af; /* address family */
|
|
+ip_address *dst;
|
|
+{
|
|
+ return anyaddr(af, dst);
|
|
+}
|
|
+
|
|
+/*
|
|
+ - loopbackaddr - initialize to the loopback-address value
|
|
+ */
|
|
+err_t /* NULL for success, else string literal */
|
|
+loopbackaddr(af, dst)
|
|
+int af; /* address family */
|
|
+ip_address *dst;
|
|
+{
|
|
+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
|
|
+
|
|
+ switch (af) {
|
|
+ case AF_INET:
|
|
+ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
|
|
+ break;
|
|
+ default:
|
|
+ return "unknown address family in loopbackaddr";
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ - isanyaddr - test for the any-address value
|
|
+ */
|
|
+int
|
|
+isanyaddr(src)
|
|
+const ip_address *src;
|
|
+{
|
|
+ uint32_t v4any = htonl(INADDR_ANY);
|
|
+ int cmp;
|
|
+
|
|
+ switch (src->u.v4.sin_family) {
|
|
+ case AF_INET:
|
|
+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
|
|
+ break;
|
|
+ case 0:
|
|
+ /* a zeroed structure is considered any address */
|
|
+ return 1;
|
|
+ default:
|
|
+ return 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return (cmp == 0) ? 1 : 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - isunspecaddr - test for the unspecified-address value
|
|
+ */
|
|
+int
|
|
+isunspecaddr(src)
|
|
+const ip_address *src;
|
|
+{
|
|
+ return isanyaddr(src);
|
|
+}
|
|
+
|
|
+/*
|
|
+ - isloopbackaddr - test for the loopback-address value
|
|
+ */
|
|
+int
|
|
+isloopbackaddr(src)
|
|
+const ip_address *src;
|
|
+{
|
|
+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
|
|
+ int cmp;
|
|
+
|
|
+ switch (src->u.v4.sin_family) {
|
|
+ case AF_INET:
|
|
+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
|
|
+ break;
|
|
+ default:
|
|
+ return 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return (cmp == 0) ? 1 : 0;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/datatot.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,234 @@
|
|
+/*
|
|
+ * convert from binary data (e.g. key) to text form
|
|
+ * Copyright (C) 2000 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: datatot.c,v 1.7 2005/04/14 20:48:43 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+static void convert(const char *src, size_t nreal, int format, char *out);
|
|
+
|
|
+/*
|
|
+ - datatot - convert data bytes to text
|
|
+ */
|
|
+size_t /* true length (with NUL) for success */
|
|
+datatot(src, srclen, format, dst, dstlen)
|
|
+const char *src;
|
|
+size_t srclen;
|
|
+int format; /* character indicating what format */
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ size_t inblocksize; /* process this many bytes at a time */
|
|
+ size_t outblocksize; /* producing this many */
|
|
+ size_t breakevery; /* add a _ every this many (0 means don't) */
|
|
+ size_t sincebreak; /* output bytes since last _ */
|
|
+ char breakchar; /* character used to break between groups */
|
|
+ char inblock[10]; /* enough for any format */
|
|
+ char outblock[10]; /* enough for any format */
|
|
+ char fake[1]; /* fake output area for dstlen == 0 */
|
|
+ size_t needed; /* return value */
|
|
+ char *stop; /* where the terminating NUL will go */
|
|
+ size_t ntodo; /* remaining input */
|
|
+ size_t nreal;
|
|
+ char *out;
|
|
+ char *prefix;
|
|
+
|
|
+ breakevery = 0;
|
|
+ breakchar = '_';
|
|
+
|
|
+ switch (format) {
|
|
+ case 0:
|
|
+ case 'h':
|
|
+ format = 'x';
|
|
+ breakevery = 8;
|
|
+ /* FALLTHROUGH */
|
|
+ case 'x':
|
|
+ inblocksize = 1;
|
|
+ outblocksize = 2;
|
|
+ prefix = "0x";
|
|
+ break;
|
|
+ case ':':
|
|
+ format = 'x';
|
|
+ breakevery = 2;
|
|
+ breakchar = ':';
|
|
+ /* FALLTHROUGH */
|
|
+ case 16:
|
|
+ inblocksize = 1;
|
|
+ outblocksize = 2;
|
|
+ prefix = "";
|
|
+ format = 'x';
|
|
+ break;
|
|
+ case 's':
|
|
+ inblocksize = 3;
|
|
+ outblocksize = 4;
|
|
+ prefix = "0s";
|
|
+ break;
|
|
+ case 64: /* beware, equals ' ' */
|
|
+ inblocksize = 3;
|
|
+ outblocksize = 4;
|
|
+ prefix = "";
|
|
+ format = 's';
|
|
+ break;
|
|
+ default:
|
|
+ return 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ user_assert(inblocksize < sizeof(inblock));
|
|
+ user_assert(outblocksize < sizeof(outblock));
|
|
+ user_assert(breakevery % outblocksize == 0);
|
|
+
|
|
+ if (srclen == 0)
|
|
+ return 0;
|
|
+ ntodo = srclen;
|
|
+
|
|
+ if (dstlen == 0) { /* dispose of awkward special case */
|
|
+ dst = fake;
|
|
+ dstlen = 1;
|
|
+ }
|
|
+ stop = dst + dstlen - 1;
|
|
+
|
|
+ nreal = strlen(prefix);
|
|
+ needed = nreal; /* for starters */
|
|
+ if (dstlen <= nreal) { /* prefix won't fit */
|
|
+ strncpy(dst, prefix, dstlen - 1);
|
|
+ dst += dstlen - 1;
|
|
+ } else {
|
|
+ strcpy(dst, prefix);
|
|
+ dst += nreal;
|
|
+ }
|
|
+
|
|
+ user_assert(dst <= stop);
|
|
+ sincebreak = 0;
|
|
+
|
|
+ while (ntodo > 0) {
|
|
+ if (ntodo < inblocksize) { /* incomplete input */
|
|
+ memset(inblock, 0, sizeof(inblock));
|
|
+ memcpy(inblock, src, ntodo);
|
|
+ src = inblock;
|
|
+ nreal = ntodo;
|
|
+ ntodo = inblocksize;
|
|
+ } else
|
|
+ nreal = inblocksize;
|
|
+ out = (outblocksize > stop - dst) ? outblock : dst;
|
|
+
|
|
+ convert(src, nreal, format, out);
|
|
+ needed += outblocksize;
|
|
+ sincebreak += outblocksize;
|
|
+ if (dst < stop) {
|
|
+ if (out != dst) {
|
|
+ user_assert(outblocksize > stop - dst);
|
|
+ memcpy(dst, out, stop - dst);
|
|
+ dst = stop;
|
|
+ } else
|
|
+ dst += outblocksize;
|
|
+ }
|
|
+
|
|
+ src += inblocksize;
|
|
+ ntodo -= inblocksize;
|
|
+ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
|
|
+ if (dst < stop)
|
|
+ *dst++ = breakchar;
|
|
+ needed++;
|
|
+ sincebreak = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ user_assert(dst <= stop);
|
|
+ *dst++ = '\0';
|
|
+ needed++;
|
|
+
|
|
+ return needed;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - convert - convert one input block to one output block
|
|
+ */
|
|
+static void
|
|
+convert(src, nreal, format, out)
|
|
+const char *src;
|
|
+size_t nreal; /* how much of the input block is real */
|
|
+int format;
|
|
+char *out;
|
|
+{
|
|
+ static char hex[] = "0123456789abcdef";
|
|
+ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
+ "abcdefghijklmnopqrstuvwxyz"
|
|
+ "0123456789+/";
|
|
+ unsigned char c;
|
|
+ unsigned char c1, c2, c3;
|
|
+
|
|
+ user_assert(nreal > 0);
|
|
+ switch (format) {
|
|
+ case 'x':
|
|
+ user_assert(nreal == 1);
|
|
+ c = (unsigned char)*src;
|
|
+ *out++ = hex[c >> 4];
|
|
+ *out++ = hex[c & 0xf];
|
|
+ break;
|
|
+ case 's':
|
|
+ c1 = (unsigned char)*src++;
|
|
+ c2 = (unsigned char)*src++;
|
|
+ c3 = (unsigned char)*src++;
|
|
+ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
|
|
+ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
|
|
+ c |= c2 >> 4; /* ...top 4 of c2 */
|
|
+ *out++ = base64[c];
|
|
+ if (nreal == 1)
|
|
+ *out++ = '=';
|
|
+ else {
|
|
+ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
|
|
+ c |= c3 >> 6; /* ...top 2 of c3 */
|
|
+ *out++ = base64[c];
|
|
+ }
|
|
+ if (nreal <= 2)
|
|
+ *out++ = '=';
|
|
+ else
|
|
+ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
|
|
+ break;
|
|
+ default:
|
|
+ user_assert(nreal == 0); /* unknown format */
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ - datatoa - convert data to ASCII
|
|
+ * backward-compatibility synonym for datatot
|
|
+ */
|
|
+size_t /* true length (with NUL) for success */
|
|
+datatoa(src, srclen, format, dst, dstlen)
|
|
+const char *src;
|
|
+size_t srclen;
|
|
+int format; /* character indicating what format */
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ return datatot(src, srclen, format, dst, dstlen);
|
|
+}
|
|
+
|
|
+/*
|
|
+ - bytestoa - convert data bytes to ASCII
|
|
+ * backward-compatibility synonym for datatot
|
|
+ */
|
|
+size_t /* true length (with NUL) for success */
|
|
+bytestoa(src, srclen, format, dst, dstlen)
|
|
+const char *src;
|
|
+size_t srclen;
|
|
+int format; /* character indicating what format */
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ return datatot(src, srclen, format, dst, dstlen);
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,148 @@
|
|
+
|
|
+#
|
|
+# RCSID $Id: defconfig,v 1.28.2.1 2006/10/11 18:14:33 paul Exp $
|
|
+#
|
|
+
|
|
+#
|
|
+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
|
|
+#
|
|
+
|
|
+#
|
|
+# First, lets override stuff already set or not in the kernel config.
|
|
+#
|
|
+# We can't even think about leaving this off...
|
|
+CONFIG_INET=y
|
|
+
|
|
+#
|
|
+# This must be on for subnet protection.
|
|
+CONFIG_IP_FORWARD=y
|
|
+
|
|
+# Shut off IPSEC masquerading if it has been enabled, since it will
|
|
+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
|
|
+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
|
|
+CONFIG_IP_MASQUERADE_IPSEC=n
|
|
+
|
|
+#
|
|
+# Next, lets set the recommended FreeS/WAN configuration.
|
|
+#
|
|
+
|
|
+# To config as static (preferred), 'y'. To config as module, 'm'.
|
|
+CONFIG_KLIPS=m
|
|
+
|
|
+# To do tunnel mode IPSec, this must be enabled.
|
|
+CONFIG_KLIPS_IPIP=y
|
|
+
|
|
+# To enable authentication, say 'y'. (Highly recommended)
|
|
+CONFIG_KLIPS_AH=y
|
|
+
|
|
+# Authentication algorithm(s):
|
|
+CONFIG_KLIPS_AUTH_HMAC_MD5=y
|
|
+CONFIG_KLIPS_AUTH_HMAC_SHA1=y
|
|
+
|
|
+# To enable encryption, say 'y'. (Highly recommended)
|
|
+CONFIG_KLIPS_ESP=y
|
|
+
|
|
+# modular algo extensions (and new ALGOs)
|
|
+CONFIG_KLIPS_ALG=y
|
|
+
|
|
+# Encryption algorithm(s):
|
|
+CONFIG_KLIPS_ENC_3DES=y
|
|
+CONFIG_KLIPS_ENC_AES=y
|
|
+# CONFIG_KLIPS_ENC_NULL=y
|
|
+
|
|
+# Use CryptoAPI for ALG? - by default, no.
|
|
+CONFIG_KLIPS_ENC_CRYPTOAPI=n
|
|
+
|
|
+# IP Compression: new, probably still has minor bugs.
|
|
+CONFIG_KLIPS_IPCOMP=y
|
|
+
|
|
+# To enable userspace-switchable KLIPS debugging, say 'y'.
|
|
+CONFIG_KLIPS_DEBUG=y
|
|
+
|
|
+# NAT Traversal
|
|
+CONFIG_IPSEC_NAT_TRAVERSAL=y
|
|
+
|
|
+#
|
|
+#
|
|
+# $Log: defconfig,v $
|
|
+# Revision 1.28.2.1 2006/10/11 18:14:33 paul
|
|
+# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
|
|
+# per default.
|
|
+#
|
|
+# Revision 1.28 2005/05/11 03:15:42 mcr
|
|
+# adjusted makefiles to sanely build modules properly.
|
|
+#
|
|
+# Revision 1.27 2005/03/20 03:00:05 mcr
|
|
+# default configuration should enable NAT_TRAVERSAL.
|
|
+#
|
|
+# Revision 1.26 2004/07/10 19:11:18 mcr
|
|
+# CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+#
|
|
+# Revision 1.25 2004/07/05 01:03:53 mcr
|
|
+# fix for adding cryptoapi code.
|
|
+# keep it off for now, since UMLs do not have it yet.
|
|
+#
|
|
+# Revision 1.24 2004/04/06 02:49:25 mcr
|
|
+# pullup of algo code from alg-branch.
|
|
+#
|
|
+# Revision 1.23.2.2 2004/04/05 04:30:46 mcr
|
|
+# patches for alg-branch to compile/work with 2.x openswan
|
|
+#
|
|
+# Revision 1.23.2.1 2003/12/22 15:25:52 jjo
|
|
+# . Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+#
|
|
+# Revision 1.23 2003/12/10 01:14:27 mcr
|
|
+# NAT-traversal patches to KLIPS.
|
|
+#
|
|
+# Revision 1.22 2003/02/24 19:37:27 mcr
|
|
+# changed default compilation mode to static.
|
|
+#
|
|
+# Revision 1.21 2002/04/24 07:36:27 mcr
|
|
+# Moved from ./klips/net/ipsec/defconfig,v
|
|
+#
|
|
+# Revision 1.20 2002/04/02 04:07:40 mcr
|
|
+# default build is now 'm'odule for KLIPS
|
|
+#
|
|
+# Revision 1.19 2002/03/08 18:57:17 rgb
|
|
+# Added a blank line at the beginning of the file to make it easier for
|
|
+# other projects to patch ./arch/i386/defconfig, for example
|
|
+# LIDS+grSecurity requested by Jason Pattie.
|
|
+#
|
|
+# Revision 1.18 2000/11/30 17:26:56 rgb
|
|
+# Cleaned out unused options and enabled ipcomp by default.
|
|
+#
|
|
+# Revision 1.17 2000/09/15 11:37:01 rgb
|
|
+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
|
|
+# IPCOMP zlib deflate code.
|
|
+#
|
|
+# Revision 1.16 2000/09/08 19:12:55 rgb
|
|
+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+#
|
|
+# Revision 1.15 2000/05/24 19:37:13 rgb
|
|
+# *** empty log message ***
|
|
+#
|
|
+# Revision 1.14 2000/05/11 21:14:57 henry
|
|
+# just commenting the FOOBAR=y lines out is not enough
|
|
+#
|
|
+# Revision 1.13 2000/05/10 20:17:58 rgb
|
|
+# Comment out netlink defaults, which are no longer needed.
|
|
+#
|
|
+# Revision 1.12 2000/05/10 19:13:38 rgb
|
|
+# Added configure option to shut off no eroute passthrough.
|
|
+#
|
|
+# Revision 1.11 2000/03/16 07:09:46 rgb
|
|
+# Hardcode PF_KEYv2 support.
|
|
+# Disable IPSEC_ICMP by default.
|
|
+# Remove DES config option from defaults file.
|
|
+#
|
|
+# Revision 1.10 2000/01/11 03:09:42 rgb
|
|
+# Added a default of 'y' to PF_KEYv2 keying I/F.
|
|
+#
|
|
+# Revision 1.9 1999/05/08 21:23:12 rgb
|
|
+# Added support for 2.2.x kernels.
|
|
+#
|
|
+# Revision 1.8 1999/04/06 04:54:25 rgb
|
|
+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+# patch shell fixes.
|
|
+#
|
|
+#
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/deflate.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1351 @@
|
|
+/* deflate.c -- compress data using the deflation algorithm
|
|
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * ALGORITHM
|
|
+ *
|
|
+ * The "deflation" process depends on being able to identify portions
|
|
+ * of the input text which are identical to earlier input (within a
|
|
+ * sliding window trailing behind the input currently being processed).
|
|
+ *
|
|
+ * The most straightforward technique turns out to be the fastest for
|
|
+ * most input files: try all possible matches and select the longest.
|
|
+ * The key feature of this algorithm is that insertions into the string
|
|
+ * dictionary are very simple and thus fast, and deletions are avoided
|
|
+ * completely. Insertions are performed at each input character, whereas
|
|
+ * string matches are performed only when the previous match ends. So it
|
|
+ * is preferable to spend more time in matches to allow very fast string
|
|
+ * insertions and avoid deletions. The matching algorithm for small
|
|
+ * strings is inspired from that of Rabin & Karp. A brute force approach
|
|
+ * is used to find longer strings when a small match has been found.
|
|
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
|
|
+ * (by Leonid Broukhis).
|
|
+ * A previous version of this file used a more sophisticated algorithm
|
|
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
|
|
+ * time, but has a larger average cost, uses more memory and is patented.
|
|
+ * However the F&G algorithm may be faster for some highly redundant
|
|
+ * files if the parameter max_chain_length (described below) is too large.
|
|
+ *
|
|
+ * ACKNOWLEDGEMENTS
|
|
+ *
|
|
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
|
|
+ * I found it in 'freeze' written by Leonid Broukhis.
|
|
+ * Thanks to many people for bug reports and testing.
|
|
+ *
|
|
+ * REFERENCES
|
|
+ *
|
|
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
|
|
+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt
|
|
+ *
|
|
+ * A description of the Rabin and Karp algorithm is given in the book
|
|
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
|
|
+ *
|
|
+ * Fiala,E.R., and Greene,D.H.
|
|
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
|
|
+ *
|
|
+ */
|
|
+
|
|
+/* @(#) $Id: deflate.c,v 1.4 2004/07/10 07:48:37 mcr Exp $ */
|
|
+
|
|
+#include "deflate.h"
|
|
+
|
|
+local const char deflate_copyright[] =
|
|
+ " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
|
|
+/*
|
|
+ If you use the zlib library in a product, an acknowledgment is welcome
|
|
+ in the documentation of your product. If for some reason you cannot
|
|
+ include such an acknowledgment, I would appreciate that you keep this
|
|
+ copyright string in the executable of your product.
|
|
+ */
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Function prototypes.
|
|
+ */
|
|
+typedef enum {
|
|
+ need_more, /* block not completed, need more input or more output */
|
|
+ block_done, /* block flush performed */
|
|
+ finish_started, /* finish started, need only more output at next deflate */
|
|
+ finish_done /* finish done, accept no more input or output */
|
|
+} block_state;
|
|
+
|
|
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
|
|
+/* Compression function. Returns the block state after the call. */
|
|
+
|
|
+local void fill_window OF((deflate_state *s));
|
|
+local block_state deflate_stored OF((deflate_state *s, int flush));
|
|
+local block_state deflate_fast OF((deflate_state *s, int flush));
|
|
+local block_state deflate_slow OF((deflate_state *s, int flush));
|
|
+local void lm_init OF((deflate_state *s));
|
|
+local void putShortMSB OF((deflate_state *s, uInt b));
|
|
+local void flush_pending OF((z_streamp strm));
|
|
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
|
|
+#ifdef ASMV
|
|
+ void match_init OF((void)); /* asm code initialization */
|
|
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
|
|
+#else
|
|
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
|
|
+#endif
|
|
+
|
|
+#ifdef DEBUG
|
|
+local void check_match OF((deflate_state *s, IPos start, IPos match,
|
|
+ int length));
|
|
+#endif
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Local data
|
|
+ */
|
|
+
|
|
+#define NIL 0
|
|
+/* Tail of hash chains */
|
|
+
|
|
+#ifndef TOO_FAR
|
|
+# define TOO_FAR 4096
|
|
+#endif
|
|
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
|
|
+
|
|
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
|
+/* Minimum amount of lookahead, except at the end of the input file.
|
|
+ * See deflate.c for comments about the MIN_MATCH+1.
|
|
+ */
|
|
+
|
|
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
|
|
+ * the desired pack level (0..9). The values given below have been tuned to
|
|
+ * exclude worst case performance for pathological files. Better values may be
|
|
+ * found for specific files.
|
|
+ */
|
|
+typedef struct config_s {
|
|
+ ush good_length; /* reduce lazy search above this match length */
|
|
+ ush max_lazy; /* do not perform lazy search above this match length */
|
|
+ ush nice_length; /* quit search above this match length */
|
|
+ ush max_chain;
|
|
+ compress_func func;
|
|
+} config;
|
|
+
|
|
+local const config configuration_table[10] = {
|
|
+/* good lazy nice chain */
|
|
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
|
|
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
|
|
+/* 2 */ {4, 5, 16, 8, deflate_fast},
|
|
+/* 3 */ {4, 6, 32, 32, deflate_fast},
|
|
+
|
|
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
|
|
+/* 5 */ {8, 16, 32, 32, deflate_slow},
|
|
+/* 6 */ {8, 16, 128, 128, deflate_slow},
|
|
+/* 7 */ {8, 32, 128, 256, deflate_slow},
|
|
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
|
|
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
|
|
+
|
|
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
|
|
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
|
|
+ * meaning.
|
|
+ */
|
|
+
|
|
+#define EQUAL 0
|
|
+/* result of memcmp for equal strings */
|
|
+
|
|
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Update a hash value with the given input byte
|
|
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
|
|
+ * input characters, so that a running hash key can be computed from the
|
|
+ * previous key instead of complete recalculation each time.
|
|
+ */
|
|
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
|
|
+
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Insert string str in the dictionary and set match_head to the previous head
|
|
+ * of the hash chain (the most recent string with same hash key). Return
|
|
+ * the previous length of the hash chain.
|
|
+ * If this file is compiled with -DFASTEST, the compression level is forced
|
|
+ * to 1, and no hash chains are maintained.
|
|
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
|
|
+ * input characters and the first MIN_MATCH bytes of str are valid
|
|
+ * (except for the last MIN_MATCH-1 bytes of the input file).
|
|
+ */
|
|
+#ifdef FASTEST
|
|
+#define INSERT_STRING(s, str, match_head) \
|
|
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
|
|
+ match_head = s->head[s->ins_h], \
|
|
+ s->head[s->ins_h] = (Pos)(str))
|
|
+#else
|
|
+#define INSERT_STRING(s, str, match_head) \
|
|
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
|
|
+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
|
|
+ s->head[s->ins_h] = (Pos)(str))
|
|
+#endif
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
|
|
+ * prev[] will be initialized on the fly.
|
|
+ */
|
|
+#define CLEAR_HASH(s) \
|
|
+ s->head[s->hash_size-1] = NIL; \
|
|
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
|
|
+
|
|
+/* ========================================================================= */
|
|
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
|
|
+ z_streamp strm;
|
|
+ int level;
|
|
+ const char *version;
|
|
+ int stream_size;
|
|
+{
|
|
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
|
|
+ Z_DEFAULT_STRATEGY, version, stream_size);
|
|
+ /* To do: ignore strm->next_in if we use it as window */
|
|
+}
|
|
+
|
|
+/* ========================================================================= */
|
|
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
|
+ version, stream_size)
|
|
+ z_streamp strm;
|
|
+ int level;
|
|
+ int method;
|
|
+ int windowBits;
|
|
+ int memLevel;
|
|
+ int strategy;
|
|
+ const char *version;
|
|
+ int stream_size;
|
|
+{
|
|
+ deflate_state *s;
|
|
+ int noheader = 0;
|
|
+ static const char* my_version = ZLIB_VERSION;
|
|
+
|
|
+ ushf *overlay;
|
|
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
|
|
+ * output size for (length,distance) codes is <= 24 bits.
|
|
+ */
|
|
+
|
|
+ if (version == Z_NULL || version[0] != my_version[0] ||
|
|
+ stream_size != sizeof(z_stream)) {
|
|
+ return Z_VERSION_ERROR;
|
|
+ }
|
|
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
|
|
+
|
|
+ strm->msg = Z_NULL;
|
|
+ if (strm->zalloc == Z_NULL) {
|
|
+ return Z_STREAM_ERROR;
|
|
+/* strm->zalloc = zcalloc;
|
|
+ strm->opaque = (voidpf)0;*/
|
|
+ }
|
|
+ if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
|
|
+
|
|
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
|
|
+#ifdef FASTEST
|
|
+ level = 1;
|
|
+#endif
|
|
+
|
|
+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
|
|
+ noheader = 1;
|
|
+ windowBits = -windowBits;
|
|
+ }
|
|
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
|
|
+ windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
|
|
+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
|
|
+ return Z_STREAM_ERROR;
|
|
+ }
|
|
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
|
|
+ if (s == Z_NULL) return Z_MEM_ERROR;
|
|
+ strm->state = (struct internal_state FAR *)s;
|
|
+ s->strm = strm;
|
|
+
|
|
+ s->noheader = noheader;
|
|
+ s->w_bits = windowBits;
|
|
+ s->w_size = 1 << s->w_bits;
|
|
+ s->w_mask = s->w_size - 1;
|
|
+
|
|
+ s->hash_bits = memLevel + 7;
|
|
+ s->hash_size = 1 << s->hash_bits;
|
|
+ s->hash_mask = s->hash_size - 1;
|
|
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
|
|
+
|
|
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
|
|
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
|
|
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
|
|
+
|
|
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
|
|
+
|
|
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
|
|
+ s->pending_buf = (uchf *) overlay;
|
|
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
|
|
+
|
|
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
|
+ s->pending_buf == Z_NULL) {
|
|
+ strm->msg = ERR_MSG(Z_MEM_ERROR);
|
|
+ deflateEnd (strm);
|
|
+ return Z_MEM_ERROR;
|
|
+ }
|
|
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
|
|
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
|
|
+
|
|
+ s->level = level;
|
|
+ s->strategy = strategy;
|
|
+ s->method = (Byte)method;
|
|
+
|
|
+ return deflateReset(strm);
|
|
+}
|
|
+
|
|
+/* ========================================================================= */
|
|
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
|
+ z_streamp strm;
|
|
+ const Bytef *dictionary;
|
|
+ uInt dictLength;
|
|
+{
|
|
+ deflate_state *s;
|
|
+ uInt length = dictLength;
|
|
+ uInt n;
|
|
+ IPos hash_head = 0;
|
|
+
|
|
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
|
|
+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
|
|
+
|
|
+ s = strm->state;
|
|
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
|
|
+
|
|
+ if (length < MIN_MATCH) return Z_OK;
|
|
+ if (length > MAX_DIST(s)) {
|
|
+ length = MAX_DIST(s);
|
|
+#ifndef USE_DICT_HEAD
|
|
+ dictionary += dictLength - length; /* use the tail of the dictionary */
|
|
+#endif
|
|
+ }
|
|
+ zmemcpy(s->window, dictionary, length);
|
|
+ s->strstart = length;
|
|
+ s->block_start = (long)length;
|
|
+
|
|
+ /* Insert all strings in the hash table (except for the last two bytes).
|
|
+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
|
|
+ * call of fill_window.
|
|
+ */
|
|
+ s->ins_h = s->window[0];
|
|
+ UPDATE_HASH(s, s->ins_h, s->window[1]);
|
|
+ for (n = 0; n <= length - MIN_MATCH; n++) {
|
|
+ INSERT_STRING(s, n, hash_head);
|
|
+ }
|
|
+ if (hash_head) hash_head = 0; /* to make compiler happy */
|
|
+ return Z_OK;
|
|
+}
|
|
+
|
|
+/* ========================================================================= */
|
|
+int ZEXPORT deflateReset (strm)
|
|
+ z_streamp strm;
|
|
+{
|
|
+ deflate_state *s;
|
|
+
|
|
+ if (strm == Z_NULL || strm->state == Z_NULL ||
|
|
+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
|
|
+
|
|
+ strm->total_in = strm->total_out = 0;
|
|
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
|
|
+ strm->data_type = Z_UNKNOWN;
|
|
+
|
|
+ s = (deflate_state *)strm->state;
|
|
+ s->pending = 0;
|
|
+ s->pending_out = s->pending_buf;
|
|
+
|
|
+ if (s->noheader < 0) {
|
|
+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
|
|
+ }
|
|
+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
|
|
+ strm->adler = 1;
|
|
+ s->last_flush = Z_NO_FLUSH;
|
|
+
|
|
+ _tr_init(s);
|
|
+ lm_init(s);
|
|
+
|
|
+ return Z_OK;
|
|
+}
|
|
+
|
|
+/* ========================================================================= */
|
|
+int ZEXPORT deflateParams(strm, level, strategy)
|
|
+ z_streamp strm;
|
|
+ int level;
|
|
+ int strategy;
|
|
+{
|
|
+ deflate_state *s;
|
|
+ compress_func func;
|
|
+ int err = Z_OK;
|
|
+
|
|
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
|
+ s = strm->state;
|
|
+
|
|
+ if (level == Z_DEFAULT_COMPRESSION) {
|
|
+ level = 6;
|
|
+ }
|
|
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
|
|
+ return Z_STREAM_ERROR;
|
|
+ }
|
|
+ func = configuration_table[s->level].func;
|
|
+
|
|
+ if (func != configuration_table[level].func && strm->total_in != 0) {
|
|
+ /* Flush the last buffer: */
|
|
+ err = deflate(strm, Z_PARTIAL_FLUSH);
|
|
+ }
|
|
+ if (s->level != level) {
|
|
+ s->level = level;
|
|
+ s->max_lazy_match = configuration_table[level].max_lazy;
|
|
+ s->good_match = configuration_table[level].good_length;
|
|
+ s->nice_match = configuration_table[level].nice_length;
|
|
+ s->max_chain_length = configuration_table[level].max_chain;
|
|
+ }
|
|
+ s->strategy = strategy;
|
|
+ return err;
|
|
+}
|
|
+
|
|
+/* =========================================================================
|
|
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
|
|
+ * IN assertion: the stream state is correct and there is enough room in
|
|
+ * pending_buf.
|
|
+ */
|
|
+local void putShortMSB (s, b)
|
|
+ deflate_state *s;
|
|
+ uInt b;
|
|
+{
|
|
+ put_byte(s, (Byte)(b >> 8));
|
|
+ put_byte(s, (Byte)(b & 0xff));
|
|
+}
|
|
+
|
|
+/* =========================================================================
|
|
+ * Flush as much pending output as possible. All deflate() output goes
|
|
+ * through this function so some applications may wish to modify it
|
|
+ * to avoid allocating a large strm->next_out buffer and copying into it.
|
|
+ * (See also read_buf()).
|
|
+ */
|
|
+local void flush_pending(strm)
|
|
+ z_streamp strm;
|
|
+{
|
|
+ unsigned len = strm->state->pending;
|
|
+
|
|
+ if (len > strm->avail_out) len = strm->avail_out;
|
|
+ if (len == 0) return;
|
|
+
|
|
+ zmemcpy(strm->next_out, strm->state->pending_out, len);
|
|
+ strm->next_out += len;
|
|
+ strm->state->pending_out += len;
|
|
+ strm->total_out += len;
|
|
+ strm->avail_out -= len;
|
|
+ strm->state->pending -= len;
|
|
+ if (strm->state->pending == 0) {
|
|
+ strm->state->pending_out = strm->state->pending_buf;
|
|
+ }
|
|
+}
|
|
+
|
|
+/* ========================================================================= */
|
|
+int ZEXPORT deflate (strm, flush)
|
|
+ z_streamp strm;
|
|
+ int flush;
|
|
+{
|
|
+ int old_flush; /* value of flush param for previous deflate call */
|
|
+ deflate_state *s;
|
|
+
|
|
+ if (strm == Z_NULL || strm->state == Z_NULL ||
|
|
+ flush > Z_FINISH || flush < 0) {
|
|
+ return Z_STREAM_ERROR;
|
|
+ }
|
|
+ s = strm->state;
|
|
+
|
|
+ if (strm->next_out == Z_NULL ||
|
|
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
|
|
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
|
|
+ ERR_RETURN(strm, Z_STREAM_ERROR);
|
|
+ }
|
|
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
|
|
+
|
|
+ s->strm = strm; /* just in case */
|
|
+ old_flush = s->last_flush;
|
|
+ s->last_flush = flush;
|
|
+
|
|
+ /* Write the zlib header */
|
|
+ if (s->status == INIT_STATE) {
|
|
+
|
|
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
|
|
+ uInt level_flags = (s->level-1) >> 1;
|
|
+
|
|
+ if (level_flags > 3) level_flags = 3;
|
|
+ header |= (level_flags << 6);
|
|
+ if (s->strstart != 0) header |= PRESET_DICT;
|
|
+ header += 31 - (header % 31);
|
|
+
|
|
+ s->status = BUSY_STATE;
|
|
+ putShortMSB(s, header);
|
|
+
|
|
+ /* Save the adler32 of the preset dictionary: */
|
|
+ if (s->strstart != 0) {
|
|
+ putShortMSB(s, (uInt)(strm->adler >> 16));
|
|
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
|
|
+ }
|
|
+ strm->adler = 1L;
|
|
+ }
|
|
+
|
|
+ /* Flush as much pending output as possible */
|
|
+ if (s->pending != 0) {
|
|
+ flush_pending(strm);
|
|
+ if (strm->avail_out == 0) {
|
|
+ /* Since avail_out is 0, deflate will be called again with
|
|
+ * more output space, but possibly with both pending and
|
|
+ * avail_in equal to zero. There won't be anything to do,
|
|
+ * but this is not an error situation so make sure we
|
|
+ * return OK instead of BUF_ERROR at next call of deflate:
|
|
+ */
|
|
+ s->last_flush = -1;
|
|
+ return Z_OK;
|
|
+ }
|
|
+
|
|
+ /* Make sure there is something to do and avoid duplicate consecutive
|
|
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
|
|
+ * returning Z_STREAM_END instead of Z_BUFF_ERROR.
|
|
+ */
|
|
+ } else if (strm->avail_in == 0 && flush <= old_flush &&
|
|
+ flush != Z_FINISH) {
|
|
+ ERR_RETURN(strm, Z_BUF_ERROR);
|
|
+ }
|
|
+
|
|
+ /* User must not provide more input after the first FINISH: */
|
|
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
|
|
+ ERR_RETURN(strm, Z_BUF_ERROR);
|
|
+ }
|
|
+
|
|
+ /* Start a new block or continue the current one.
|
|
+ */
|
|
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
|
|
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
|
|
+ block_state bstate;
|
|
+
|
|
+ bstate = (*(configuration_table[s->level].func))(s, flush);
|
|
+
|
|
+ if (bstate == finish_started || bstate == finish_done) {
|
|
+ s->status = FINISH_STATE;
|
|
+ }
|
|
+ if (bstate == need_more || bstate == finish_started) {
|
|
+ if (strm->avail_out == 0) {
|
|
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
|
|
+ }
|
|
+ return Z_OK;
|
|
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
|
|
+ * of deflate should use the same flush parameter to make sure
|
|
+ * that the flush is complete. So we don't have to output an
|
|
+ * empty block here, this will be done at next call. This also
|
|
+ * ensures that for a very small output buffer, we emit at most
|
|
+ * one empty block.
|
|
+ */
|
|
+ }
|
|
+ if (bstate == block_done) {
|
|
+ if (flush == Z_PARTIAL_FLUSH) {
|
|
+ _tr_align(s);
|
|
+ } else { /* FULL_FLUSH or SYNC_FLUSH */
|
|
+ _tr_stored_block(s, (char*)0, 0L, 0);
|
|
+ /* For a full flush, this empty block will be recognized
|
|
+ * as a special marker by inflate_sync().
|
|
+ */
|
|
+ if (flush == Z_FULL_FLUSH) {
|
|
+ CLEAR_HASH(s); /* forget history */
|
|
+ }
|
|
+ }
|
|
+ flush_pending(strm);
|
|
+ if (strm->avail_out == 0) {
|
|
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
|
|
+ return Z_OK;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ Assert(strm->avail_out > 0, "bug2");
|
|
+
|
|
+ if (flush != Z_FINISH) return Z_OK;
|
|
+ if (s->noheader) return Z_STREAM_END;
|
|
+
|
|
+ /* Write the zlib trailer (adler32) */
|
|
+ putShortMSB(s, (uInt)(strm->adler >> 16));
|
|
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
|
|
+ flush_pending(strm);
|
|
+ /* If avail_out is zero, the application will call deflate again
|
|
+ * to flush the rest.
|
|
+ */
|
|
+ s->noheader = -1; /* write the trailer only once! */
|
|
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
|
|
+}
|
|
+
|
|
+/* ========================================================================= */
|
|
+int ZEXPORT deflateEnd (strm)
|
|
+ z_streamp strm;
|
|
+{
|
|
+ int status;
|
|
+
|
|
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
|
+
|
|
+ status = strm->state->status;
|
|
+ if (status != INIT_STATE && status != BUSY_STATE &&
|
|
+ status != FINISH_STATE) {
|
|
+ return Z_STREAM_ERROR;
|
|
+ }
|
|
+
|
|
+ /* Deallocate in reverse order of allocations: */
|
|
+ TRY_FREE(strm, strm->state->pending_buf);
|
|
+ TRY_FREE(strm, strm->state->head);
|
|
+ TRY_FREE(strm, strm->state->prev);
|
|
+ TRY_FREE(strm, strm->state->window);
|
|
+
|
|
+ ZFREE(strm, strm->state);
|
|
+ strm->state = Z_NULL;
|
|
+
|
|
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
|
|
+}
|
|
+
|
|
+/* =========================================================================
|
|
+ * Copy the source state to the destination state.
|
|
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
|
|
+ * doesn't have enough memory anyway to duplicate compression states).
|
|
+ */
|
|
+int ZEXPORT deflateCopy (dest, source)
|
|
+ z_streamp dest;
|
|
+ z_streamp source;
|
|
+{
|
|
+#ifdef MAXSEG_64K
|
|
+ return Z_STREAM_ERROR;
|
|
+#else
|
|
+ deflate_state *ds;
|
|
+ deflate_state *ss;
|
|
+ ushf *overlay;
|
|
+
|
|
+
|
|
+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
|
|
+ return Z_STREAM_ERROR;
|
|
+ }
|
|
+
|
|
+ ss = source->state;
|
|
+
|
|
+ *dest = *source;
|
|
+
|
|
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
|
|
+ if (ds == Z_NULL) return Z_MEM_ERROR;
|
|
+ dest->state = (struct internal_state FAR *) ds;
|
|
+ *ds = *ss;
|
|
+ ds->strm = dest;
|
|
+
|
|
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
|
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
|
|
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
|
|
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
|
|
+ ds->pending_buf = (uchf *) overlay;
|
|
+
|
|
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
|
|
+ ds->pending_buf == Z_NULL) {
|
|
+ deflateEnd (dest);
|
|
+ return Z_MEM_ERROR;
|
|
+ }
|
|
+ /* following zmemcpy do not work for 16-bit MSDOS */
|
|
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
|
|
+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
|
|
+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
|
|
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
|
+
|
|
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
|
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
|
|
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
|
|
+
|
|
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
|
|
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
|
|
+ ds->bl_desc.dyn_tree = ds->bl_tree;
|
|
+
|
|
+ return Z_OK;
|
|
+#endif
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Read a new buffer from the current input stream, update the adler32
|
|
+ * and total number of bytes read. All deflate() input goes through
|
|
+ * this function so some applications may wish to modify it to avoid
|
|
+ * allocating a large strm->next_in buffer and copying from it.
|
|
+ * (See also flush_pending()).
|
|
+ */
|
|
+local int read_buf(strm, buf, size)
|
|
+ z_streamp strm;
|
|
+ Bytef *buf;
|
|
+ unsigned size;
|
|
+{
|
|
+ unsigned len = strm->avail_in;
|
|
+
|
|
+ if (len > size) len = size;
|
|
+ if (len == 0) return 0;
|
|
+
|
|
+ strm->avail_in -= len;
|
|
+
|
|
+ if (!strm->state->noheader) {
|
|
+ strm->adler = adler32(strm->adler, strm->next_in, len);
|
|
+ }
|
|
+ zmemcpy(buf, strm->next_in, len);
|
|
+ strm->next_in += len;
|
|
+ strm->total_in += len;
|
|
+
|
|
+ return (int)len;
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Initialize the "longest match" routines for a new zlib stream
|
|
+ */
|
|
+local void lm_init (s)
|
|
+ deflate_state *s;
|
|
+{
|
|
+ s->window_size = (ulg)2L*s->w_size;
|
|
+
|
|
+ CLEAR_HASH(s);
|
|
+
|
|
+ /* Set the default configuration parameters:
|
|
+ */
|
|
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
|
|
+ s->good_match = configuration_table[s->level].good_length;
|
|
+ s->nice_match = configuration_table[s->level].nice_length;
|
|
+ s->max_chain_length = configuration_table[s->level].max_chain;
|
|
+
|
|
+ s->strstart = 0;
|
|
+ s->block_start = 0L;
|
|
+ s->lookahead = 0;
|
|
+ s->match_length = s->prev_length = MIN_MATCH-1;
|
|
+ s->match_available = 0;
|
|
+ s->ins_h = 0;
|
|
+#ifdef ASMV
|
|
+ match_init(); /* initialize the asm code */
|
|
+#endif
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Set match_start to the longest match starting at the given string and
|
|
+ * return its length. Matches shorter or equal to prev_length are discarded,
|
|
+ * in which case the result is equal to prev_length and match_start is
|
|
+ * garbage.
|
|
+ * IN assertions: cur_match is the head of the hash chain for the current
|
|
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
|
|
+ * OUT assertion: the match length is not greater than s->lookahead.
|
|
+ */
|
|
+#ifndef ASMV
|
|
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
|
|
+ * match.S. The code will be functionally equivalent.
|
|
+ */
|
|
+#ifndef FASTEST
|
|
+local uInt longest_match(s, cur_match)
|
|
+ deflate_state *s;
|
|
+ IPos cur_match; /* current match */
|
|
+{
|
|
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
|
|
+ register Bytef *scan = s->window + s->strstart; /* current string */
|
|
+ register Bytef *match; /* matched string */
|
|
+ register int len; /* length of current match */
|
|
+ int best_len = s->prev_length; /* best match length so far */
|
|
+ int nice_match = s->nice_match; /* stop if match long enough */
|
|
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
|
|
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
|
|
+ /* Stop when cur_match becomes <= limit. To simplify the code,
|
|
+ * we prevent matches with the string of window index 0.
|
|
+ */
|
|
+ Posf *prev = s->prev;
|
|
+ uInt wmask = s->w_mask;
|
|
+
|
|
+#ifdef UNALIGNED_OK
|
|
+ /* Compare two bytes at a time. Note: this is not always beneficial.
|
|
+ * Try with and without -DUNALIGNED_OK to check.
|
|
+ */
|
|
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
|
|
+ register ush scan_start = *(ushf*)scan;
|
|
+ register ush scan_end = *(ushf*)(scan+best_len-1);
|
|
+#else
|
|
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
|
|
+ register Byte scan_end1 = scan[best_len-1];
|
|
+ register Byte scan_end = scan[best_len];
|
|
+#endif
|
|
+
|
|
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
|
|
+ * It is easy to get rid of this optimization if necessary.
|
|
+ */
|
|
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
|
|
+
|
|
+ /* Do not waste too much time if we already have a good match: */
|
|
+ if (s->prev_length >= s->good_match) {
|
|
+ chain_length >>= 2;
|
|
+ }
|
|
+ /* Do not look for matches beyond the end of the input. This is necessary
|
|
+ * to make deflate deterministic.
|
|
+ */
|
|
+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
|
|
+
|
|
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
|
|
+
|
|
+ do {
|
|
+ Assert(cur_match < s->strstart, "no future");
|
|
+ match = s->window + cur_match;
|
|
+
|
|
+ /* Skip to next match if the match length cannot increase
|
|
+ * or if the match length is less than 2:
|
|
+ */
|
|
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
|
|
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
|
|
+ * UNALIGNED_OK if your compiler uses a different size.
|
|
+ */
|
|
+ if (*(ushf*)(match+best_len-1) != scan_end ||
|
|
+ *(ushf*)match != scan_start) continue;
|
|
+
|
|
+ /* It is not necessary to compare scan[2] and match[2] since they are
|
|
+ * always equal when the other bytes match, given that the hash keys
|
|
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
|
|
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
|
|
+ * lookahead only every 4th comparison; the 128th check will be made
|
|
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
|
|
+ * necessary to put more guard bytes at the end of the window, or
|
|
+ * to check more often for insufficient lookahead.
|
|
+ */
|
|
+ Assert(scan[2] == match[2], "scan[2]?");
|
|
+ scan++, match++;
|
|
+ do {
|
|
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
|
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
|
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
|
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
|
|
+ scan < strend);
|
|
+ /* The funny "do {}" generates better code on most compilers */
|
|
+
|
|
+ /* Here, scan <= window+strstart+257 */
|
|
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
|
+ if (*scan == *match) scan++;
|
|
+
|
|
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
|
|
+ scan = strend - (MAX_MATCH-1);
|
|
+
|
|
+#else /* UNALIGNED_OK */
|
|
+
|
|
+ if (match[best_len] != scan_end ||
|
|
+ match[best_len-1] != scan_end1 ||
|
|
+ *match != *scan ||
|
|
+ *++match != scan[1]) continue;
|
|
+
|
|
+ /* The check at best_len-1 can be removed because it will be made
|
|
+ * again later. (This heuristic is not always a win.)
|
|
+ * It is not necessary to compare scan[2] and match[2] since they
|
|
+ * are always equal when the other bytes match, given that
|
|
+ * the hash keys are equal and that HASH_BITS >= 8.
|
|
+ */
|
|
+ scan += 2, match++;
|
|
+ Assert(*scan == *match, "match[2]?");
|
|
+
|
|
+ /* We check for insufficient lookahead only every 8th comparison;
|
|
+ * the 256th check will be made at strstart+258.
|
|
+ */
|
|
+ do {
|
|
+ } while (*++scan == *++match && *++scan == *++match &&
|
|
+ *++scan == *++match && *++scan == *++match &&
|
|
+ *++scan == *++match && *++scan == *++match &&
|
|
+ *++scan == *++match && *++scan == *++match &&
|
|
+ scan < strend);
|
|
+
|
|
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
|
+
|
|
+ len = MAX_MATCH - (int)(strend - scan);
|
|
+ scan = strend - MAX_MATCH;
|
|
+
|
|
+#endif /* UNALIGNED_OK */
|
|
+
|
|
+ if (len > best_len) {
|
|
+ s->match_start = cur_match;
|
|
+ best_len = len;
|
|
+ if (len >= nice_match) break;
|
|
+#ifdef UNALIGNED_OK
|
|
+ scan_end = *(ushf*)(scan+best_len-1);
|
|
+#else
|
|
+ scan_end1 = scan[best_len-1];
|
|
+ scan_end = scan[best_len];
|
|
+#endif
|
|
+ }
|
|
+ } while ((cur_match = prev[cur_match & wmask]) > limit
|
|
+ && --chain_length != 0);
|
|
+
|
|
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
|
|
+ return s->lookahead;
|
|
+}
|
|
+
|
|
+#else /* FASTEST */
|
|
+/* ---------------------------------------------------------------------------
|
|
+ * Optimized version for level == 1 only
|
|
+ */
|
|
+local uInt longest_match(s, cur_match)
|
|
+ deflate_state *s;
|
|
+ IPos cur_match; /* current match */
|
|
+{
|
|
+ register Bytef *scan = s->window + s->strstart; /* current string */
|
|
+ register Bytef *match; /* matched string */
|
|
+ register int len; /* length of current match */
|
|
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
|
|
+
|
|
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
|
|
+ * It is easy to get rid of this optimization if necessary.
|
|
+ */
|
|
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
|
|
+
|
|
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
|
|
+
|
|
+ Assert(cur_match < s->strstart, "no future");
|
|
+
|
|
+ match = s->window + cur_match;
|
|
+
|
|
+ /* Return failure if the match length is less than 2:
|
|
+ */
|
|
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
|
|
+
|
|
+ /* The check at best_len-1 can be removed because it will be made
|
|
+ * again later. (This heuristic is not always a win.)
|
|
+ * It is not necessary to compare scan[2] and match[2] since they
|
|
+ * are always equal when the other bytes match, given that
|
|
+ * the hash keys are equal and that HASH_BITS >= 8.
|
|
+ */
|
|
+ scan += 2, match += 2;
|
|
+ Assert(*scan == *match, "match[2]?");
|
|
+
|
|
+ /* We check for insufficient lookahead only every 8th comparison;
|
|
+ * the 256th check will be made at strstart+258.
|
|
+ */
|
|
+ do {
|
|
+ } while (*++scan == *++match && *++scan == *++match &&
|
|
+ *++scan == *++match && *++scan == *++match &&
|
|
+ *++scan == *++match && *++scan == *++match &&
|
|
+ *++scan == *++match && *++scan == *++match &&
|
|
+ scan < strend);
|
|
+
|
|
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
|
|
+
|
|
+ len = MAX_MATCH - (int)(strend - scan);
|
|
+
|
|
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
|
|
+
|
|
+ s->match_start = cur_match;
|
|
+ return len <= s->lookahead ? len : s->lookahead;
|
|
+}
|
|
+#endif /* FASTEST */
|
|
+#endif /* ASMV */
|
|
+
|
|
+#ifdef DEBUG
|
|
+/* ===========================================================================
|
|
+ * Check that the match at match_start is indeed a match.
|
|
+ */
|
|
+local void check_match(s, start, match, length)
|
|
+ deflate_state *s;
|
|
+ IPos start, match;
|
|
+ int length;
|
|
+{
|
|
+ /* check that the match is indeed a match */
|
|
+ if (zmemcmp(s->window + match,
|
|
+ s->window + start, length) != EQUAL) {
|
|
+ fprintf(stderr, " start %u, match %u, length %d\n",
|
|
+ start, match, length);
|
|
+ do {
|
|
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
|
|
+ } while (--length != 0);
|
|
+ z_error("invalid match");
|
|
+ }
|
|
+ if (z_verbose > 1) {
|
|
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
|
|
+ do { putc(s->window[start++], stderr); } while (--length != 0);
|
|
+ }
|
|
+}
|
|
+#else
|
|
+# define check_match(s, start, match, length)
|
|
+#endif
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Fill the window when the lookahead becomes insufficient.
|
|
+ * Updates strstart and lookahead.
|
|
+ *
|
|
+ * IN assertion: lookahead < MIN_LOOKAHEAD
|
|
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
|
|
+ * At least one byte has been read, or avail_in == 0; reads are
|
|
+ * performed for at least two bytes (required for the zip translate_eol
|
|
+ * option -- not supported here).
|
|
+ */
|
|
+local void fill_window(s)
|
|
+ deflate_state *s;
|
|
+{
|
|
+ register unsigned n, m;
|
|
+ register Posf *p;
|
|
+ unsigned more; /* Amount of free space at the end of the window. */
|
|
+ uInt wsize = s->w_size;
|
|
+
|
|
+ do {
|
|
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
|
|
+
|
|
+ /* Deal with !@#$% 64K limit: */
|
|
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
|
|
+ more = wsize;
|
|
+
|
|
+ } else if (more == (unsigned)(-1)) {
|
|
+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
|
|
+ * and lookahead == 1 (input done one byte at time)
|
|
+ */
|
|
+ more--;
|
|
+
|
|
+ /* If the window is almost full and there is insufficient lookahead,
|
|
+ * move the upper half to the lower one to make room in the upper half.
|
|
+ */
|
|
+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
|
|
+
|
|
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
|
|
+ s->match_start -= wsize;
|
|
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
|
|
+ s->block_start -= (long) wsize;
|
|
+
|
|
+ /* Slide the hash table (could be avoided with 32 bit values
|
|
+ at the expense of memory usage). We slide even when level == 0
|
|
+ to keep the hash table consistent if we switch back to level > 0
|
|
+ later. (Using level 0 permanently is not an optimal usage of
|
|
+ zlib, so we don't care about this pathological case.)
|
|
+ */
|
|
+ n = s->hash_size;
|
|
+ p = &s->head[n];
|
|
+ do {
|
|
+ m = *--p;
|
|
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
|
|
+ } while (--n);
|
|
+
|
|
+ n = wsize;
|
|
+#ifndef FASTEST
|
|
+ p = &s->prev[n];
|
|
+ do {
|
|
+ m = *--p;
|
|
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
|
|
+ /* If n is not on any hash chain, prev[n] is garbage but
|
|
+ * its value will never be used.
|
|
+ */
|
|
+ } while (--n);
|
|
+#endif
|
|
+ more += wsize;
|
|
+ }
|
|
+ if (s->strm->avail_in == 0) return;
|
|
+
|
|
+ /* If there was no sliding:
|
|
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
|
+ * more == window_size - lookahead - strstart
|
|
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
|
|
+ * => more >= window_size - 2*WSIZE + 2
|
|
+ * In the BIG_MEM or MMAP case (not yet supported),
|
|
+ * window_size == input_size + MIN_LOOKAHEAD &&
|
|
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
|
|
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
|
|
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
|
|
+ */
|
|
+ Assert(more >= 2, "more < 2");
|
|
+
|
|
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
|
|
+ s->lookahead += n;
|
|
+
|
|
+ /* Initialize the hash value now that we have some input: */
|
|
+ if (s->lookahead >= MIN_MATCH) {
|
|
+ s->ins_h = s->window[s->strstart];
|
|
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
|
+#if MIN_MATCH != 3
|
|
+ Call UPDATE_HASH() MIN_MATCH-3 more times
|
|
+#endif
|
|
+ }
|
|
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
|
|
+ * but this is not important since only literal bytes will be emitted.
|
|
+ */
|
|
+
|
|
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Flush the current block, with given end-of-file flag.
|
|
+ * IN assertion: strstart is set to the end of the current match.
|
|
+ */
|
|
+#define FLUSH_BLOCK_ONLY(s, eof) { \
|
|
+ _tr_flush_block(s, (s->block_start >= 0L ? \
|
|
+ (charf *)&s->window[(unsigned)s->block_start] : \
|
|
+ (charf *)Z_NULL), \
|
|
+ (ulg)((long)s->strstart - s->block_start), \
|
|
+ (eof)); \
|
|
+ s->block_start = s->strstart; \
|
|
+ flush_pending(s->strm); \
|
|
+ Tracev((stderr,"[FLUSH]")); \
|
|
+}
|
|
+
|
|
+/* Same but force premature exit if necessary. */
|
|
+#define FLUSH_BLOCK(s, eof) { \
|
|
+ FLUSH_BLOCK_ONLY(s, eof); \
|
|
+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Copy without compression as much as possible from the input stream, return
|
|
+ * the current block state.
|
|
+ * This function does not insert new strings in the dictionary since
|
|
+ * uncompressible data is probably not useful. This function is used
|
|
+ * only for the level=0 compression option.
|
|
+ * NOTE: this function should be optimized to avoid extra copying from
|
|
+ * window to pending_buf.
|
|
+ */
|
|
+local block_state deflate_stored(s, flush)
|
|
+ deflate_state *s;
|
|
+ int flush;
|
|
+{
|
|
+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
|
|
+ * to pending_buf_size, and each stored block has a 5 byte header:
|
|
+ */
|
|
+ ulg max_block_size = 0xffff;
|
|
+ ulg max_start;
|
|
+
|
|
+ if (max_block_size > s->pending_buf_size - 5) {
|
|
+ max_block_size = s->pending_buf_size - 5;
|
|
+ }
|
|
+
|
|
+ /* Copy as much as possible from input to output: */
|
|
+ for (;;) {
|
|
+ /* Fill the window as much as possible: */
|
|
+ if (s->lookahead <= 1) {
|
|
+
|
|
+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
|
|
+ s->block_start >= (long)s->w_size, "slide too late");
|
|
+
|
|
+ fill_window(s);
|
|
+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
|
|
+
|
|
+ if (s->lookahead == 0) break; /* flush the current block */
|
|
+ }
|
|
+ Assert(s->block_start >= 0L, "block gone");
|
|
+
|
|
+ s->strstart += s->lookahead;
|
|
+ s->lookahead = 0;
|
|
+
|
|
+ /* Emit a stored block if pending_buf will be full: */
|
|
+ max_start = s->block_start + max_block_size;
|
|
+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
|
|
+ /* strstart == 0 is possible when wraparound on 16-bit machine */
|
|
+ s->lookahead = (uInt)(s->strstart - max_start);
|
|
+ s->strstart = (uInt)max_start;
|
|
+ FLUSH_BLOCK(s, 0);
|
|
+ }
|
|
+ /* Flush if we may have to slide, otherwise block_start may become
|
|
+ * negative and the data will be gone:
|
|
+ */
|
|
+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
|
|
+ FLUSH_BLOCK(s, 0);
|
|
+ }
|
|
+ }
|
|
+ FLUSH_BLOCK(s, flush == Z_FINISH);
|
|
+ return flush == Z_FINISH ? finish_done : block_done;
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Compress as much as possible from the input stream, return the current
|
|
+ * block state.
|
|
+ * This function does not perform lazy evaluation of matches and inserts
|
|
+ * new strings in the dictionary only for unmatched strings or for short
|
|
+ * matches. It is used only for the fast compression options.
|
|
+ */
|
|
+local block_state deflate_fast(s, flush)
|
|
+ deflate_state *s;
|
|
+ int flush;
|
|
+{
|
|
+ IPos hash_head = NIL; /* head of the hash chain */
|
|
+ int bflush; /* set if current block must be flushed */
|
|
+
|
|
+ for (;;) {
|
|
+ /* Make sure that we always have enough lookahead, except
|
|
+ * at the end of the input file. We need MAX_MATCH bytes
|
|
+ * for the next match, plus MIN_MATCH bytes to insert the
|
|
+ * string following the next match.
|
|
+ */
|
|
+ if (s->lookahead < MIN_LOOKAHEAD) {
|
|
+ fill_window(s);
|
|
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
|
|
+ return need_more;
|
|
+ }
|
|
+ if (s->lookahead == 0) break; /* flush the current block */
|
|
+ }
|
|
+
|
|
+ /* Insert the string window[strstart .. strstart+2] in the
|
|
+ * dictionary, and set hash_head to the head of the hash chain:
|
|
+ */
|
|
+ if (s->lookahead >= MIN_MATCH) {
|
|
+ INSERT_STRING(s, s->strstart, hash_head);
|
|
+ }
|
|
+
|
|
+ /* Find the longest match, discarding those <= prev_length.
|
|
+ * At this point we have always match_length < MIN_MATCH
|
|
+ */
|
|
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
|
|
+ /* To simplify the code, we prevent matches with the string
|
|
+ * of window index 0 (in particular we have to avoid a match
|
|
+ * of the string with itself at the start of the input file).
|
|
+ */
|
|
+ if (s->strategy != Z_HUFFMAN_ONLY) {
|
|
+ s->match_length = longest_match (s, hash_head);
|
|
+ }
|
|
+ /* longest_match() sets match_start */
|
|
+ }
|
|
+ if (s->match_length >= MIN_MATCH) {
|
|
+ check_match(s, s->strstart, s->match_start, s->match_length);
|
|
+
|
|
+ _tr_tally_dist(s, s->strstart - s->match_start,
|
|
+ s->match_length - MIN_MATCH, bflush);
|
|
+
|
|
+ s->lookahead -= s->match_length;
|
|
+
|
|
+ /* Insert new strings in the hash table only if the match length
|
|
+ * is not too large. This saves time but degrades compression.
|
|
+ */
|
|
+#ifndef FASTEST
|
|
+ if (s->match_length <= s->max_insert_length &&
|
|
+ s->lookahead >= MIN_MATCH) {
|
|
+ s->match_length--; /* string at strstart already in hash table */
|
|
+ do {
|
|
+ s->strstart++;
|
|
+ INSERT_STRING(s, s->strstart, hash_head);
|
|
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
|
|
+ * always MIN_MATCH bytes ahead.
|
|
+ */
|
|
+ } while (--s->match_length != 0);
|
|
+ s->strstart++;
|
|
+ } else
|
|
+#endif
|
|
+ {
|
|
+ s->strstart += s->match_length;
|
|
+ s->match_length = 0;
|
|
+ s->ins_h = s->window[s->strstart];
|
|
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
|
+#if MIN_MATCH != 3
|
|
+ Call UPDATE_HASH() MIN_MATCH-3 more times
|
|
+#endif
|
|
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
|
|
+ * matter since it will be recomputed at next deflate call.
|
|
+ */
|
|
+ }
|
|
+ } else {
|
|
+ /* No match, output a literal byte */
|
|
+ Tracevv((stderr,"%c", s->window[s->strstart]));
|
|
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
|
|
+ s->lookahead--;
|
|
+ s->strstart++;
|
|
+ }
|
|
+ if (bflush) FLUSH_BLOCK(s, 0);
|
|
+ }
|
|
+ FLUSH_BLOCK(s, flush == Z_FINISH);
|
|
+ return flush == Z_FINISH ? finish_done : block_done;
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Same as above, but achieves better compression. We use a lazy
|
|
+ * evaluation for matches: a match is finally adopted only if there is
|
|
+ * no better match at the next window position.
|
|
+ */
|
|
+local block_state deflate_slow(s, flush)
|
|
+ deflate_state *s;
|
|
+ int flush;
|
|
+{
|
|
+ IPos hash_head = NIL; /* head of hash chain */
|
|
+ int bflush; /* set if current block must be flushed */
|
|
+
|
|
+ /* Process the input block. */
|
|
+ for (;;) {
|
|
+ /* Make sure that we always have enough lookahead, except
|
|
+ * at the end of the input file. We need MAX_MATCH bytes
|
|
+ * for the next match, plus MIN_MATCH bytes to insert the
|
|
+ * string following the next match.
|
|
+ */
|
|
+ if (s->lookahead < MIN_LOOKAHEAD) {
|
|
+ fill_window(s);
|
|
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
|
|
+ return need_more;
|
|
+ }
|
|
+ if (s->lookahead == 0) break; /* flush the current block */
|
|
+ }
|
|
+
|
|
+ /* Insert the string window[strstart .. strstart+2] in the
|
|
+ * dictionary, and set hash_head to the head of the hash chain:
|
|
+ */
|
|
+ if (s->lookahead >= MIN_MATCH) {
|
|
+ INSERT_STRING(s, s->strstart, hash_head);
|
|
+ }
|
|
+
|
|
+ /* Find the longest match, discarding those <= prev_length.
|
|
+ */
|
|
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
|
|
+ s->match_length = MIN_MATCH-1;
|
|
+
|
|
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
|
|
+ s->strstart - hash_head <= MAX_DIST(s)) {
|
|
+ /* To simplify the code, we prevent matches with the string
|
|
+ * of window index 0 (in particular we have to avoid a match
|
|
+ * of the string with itself at the start of the input file).
|
|
+ */
|
|
+ if (s->strategy != Z_HUFFMAN_ONLY) {
|
|
+ s->match_length = longest_match (s, hash_head);
|
|
+ }
|
|
+ /* longest_match() sets match_start */
|
|
+
|
|
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
|
|
+ (s->match_length == MIN_MATCH &&
|
|
+ s->strstart - s->match_start > TOO_FAR))) {
|
|
+
|
|
+ /* If prev_match is also MIN_MATCH, match_start is garbage
|
|
+ * but we will ignore the current match anyway.
|
|
+ */
|
|
+ s->match_length = MIN_MATCH-1;
|
|
+ }
|
|
+ }
|
|
+ /* If there was a match at the previous step and the current
|
|
+ * match is not better, output the previous match:
|
|
+ */
|
|
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
|
|
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
|
|
+ /* Do not insert strings in hash table beyond this. */
|
|
+
|
|
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
|
|
+
|
|
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
|
|
+ s->prev_length - MIN_MATCH, bflush);
|
|
+
|
|
+ /* Insert in hash table all strings up to the end of the match.
|
|
+ * strstart-1 and strstart are already inserted. If there is not
|
|
+ * enough lookahead, the last two strings are not inserted in
|
|
+ * the hash table.
|
|
+ */
|
|
+ s->lookahead -= s->prev_length-1;
|
|
+ s->prev_length -= 2;
|
|
+ do {
|
|
+ if (++s->strstart <= max_insert) {
|
|
+ INSERT_STRING(s, s->strstart, hash_head);
|
|
+ }
|
|
+ } while (--s->prev_length != 0);
|
|
+ s->match_available = 0;
|
|
+ s->match_length = MIN_MATCH-1;
|
|
+ s->strstart++;
|
|
+
|
|
+ if (bflush) FLUSH_BLOCK(s, 0);
|
|
+
|
|
+ } else if (s->match_available) {
|
|
+ /* If there was no match at the previous position, output a
|
|
+ * single literal. If there was a match but the current match
|
|
+ * is longer, truncate the previous match to a single literal.
|
|
+ */
|
|
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
|
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
|
+ if (bflush) {
|
|
+ FLUSH_BLOCK_ONLY(s, 0);
|
|
+ }
|
|
+ s->strstart++;
|
|
+ s->lookahead--;
|
|
+ if (s->strm->avail_out == 0) return need_more;
|
|
+ } else {
|
|
+ /* There is no previous match to compare with, wait for
|
|
+ * the next step to decide.
|
|
+ */
|
|
+ s->match_available = 1;
|
|
+ s->strstart++;
|
|
+ s->lookahead--;
|
|
+ }
|
|
+ }
|
|
+ Assert (flush != Z_NO_FLUSH, "no flush?");
|
|
+ if (s->match_available) {
|
|
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
|
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
|
+ s->match_available = 0;
|
|
+ }
|
|
+ FLUSH_BLOCK(s, flush == Z_FINISH);
|
|
+ return flush == Z_FINISH ? finish_done : block_done;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/deflate.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,318 @@
|
|
+/* deflate.h -- internal compression state
|
|
+ * Copyright (C) 1995-2002 Jean-loup Gailly
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* WARNING: this file should *not* be used by applications. It is
|
|
+ part of the implementation of the compression library and is
|
|
+ subject to change. Applications should only use zlib.h.
|
|
+ */
|
|
+
|
|
+/* @(#) $Id: deflate.h,v 1.5 2004/07/10 07:48:38 mcr Exp $ */
|
|
+
|
|
+#ifndef _DEFLATE_H
|
|
+#define _DEFLATE_H
|
|
+
|
|
+#include "zlib/zutil.h"
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Internal compression state.
|
|
+ */
|
|
+
|
|
+#define LENGTH_CODES 29
|
|
+/* number of length codes, not counting the special END_BLOCK code */
|
|
+
|
|
+#define LITERALS 256
|
|
+/* number of literal bytes 0..255 */
|
|
+
|
|
+#define L_CODES (LITERALS+1+LENGTH_CODES)
|
|
+/* number of Literal or Length codes, including the END_BLOCK code */
|
|
+
|
|
+#define D_CODES 30
|
|
+/* number of distance codes */
|
|
+
|
|
+#define BL_CODES 19
|
|
+/* number of codes used to transfer the bit lengths */
|
|
+
|
|
+#define HEAP_SIZE (2*L_CODES+1)
|
|
+/* maximum heap size */
|
|
+
|
|
+#define MAX_BITS 15
|
|
+/* All codes must not exceed MAX_BITS bits */
|
|
+
|
|
+#define INIT_STATE 42
|
|
+#define BUSY_STATE 113
|
|
+#define FINISH_STATE 666
|
|
+/* Stream status */
|
|
+
|
|
+
|
|
+/* Data structure describing a single value and its code string. */
|
|
+typedef struct ct_data_s {
|
|
+ union {
|
|
+ ush freq; /* frequency count */
|
|
+ ush code; /* bit string */
|
|
+ } fc;
|
|
+ union {
|
|
+ ush dad; /* father node in Huffman tree */
|
|
+ ush len; /* length of bit string */
|
|
+ } dl;
|
|
+} FAR ct_data;
|
|
+
|
|
+#define Freq fc.freq
|
|
+#define Code fc.code
|
|
+#define Dad dl.dad
|
|
+#define Len dl.len
|
|
+
|
|
+typedef struct static_tree_desc_s static_tree_desc;
|
|
+
|
|
+typedef struct tree_desc_s {
|
|
+ ct_data *dyn_tree; /* the dynamic tree */
|
|
+ int max_code; /* largest code with non zero frequency */
|
|
+ static_tree_desc *stat_desc; /* the corresponding static tree */
|
|
+} FAR tree_desc;
|
|
+
|
|
+typedef ush Pos;
|
|
+typedef Pos FAR Posf;
|
|
+typedef unsigned IPos;
|
|
+
|
|
+/* A Pos is an index in the character window. We use short instead of int to
|
|
+ * save space in the various tables. IPos is used only for parameter passing.
|
|
+ */
|
|
+
|
|
+typedef struct internal_state {
|
|
+ z_streamp strm; /* pointer back to this zlib stream */
|
|
+ int status; /* as the name implies */
|
|
+ Bytef *pending_buf; /* output still pending */
|
|
+ ulg pending_buf_size; /* size of pending_buf */
|
|
+ Bytef *pending_out; /* next pending byte to output to the stream */
|
|
+ int pending; /* nb of bytes in the pending buffer */
|
|
+ int noheader; /* suppress zlib header and adler32 */
|
|
+ Byte data_type; /* UNKNOWN, BINARY or ASCII */
|
|
+ Byte method; /* STORED (for zip only) or DEFLATED */
|
|
+ int last_flush; /* value of flush param for previous deflate call */
|
|
+
|
|
+ /* used by deflate.c: */
|
|
+
|
|
+ uInt w_size; /* LZ77 window size (32K by default) */
|
|
+ uInt w_bits; /* log2(w_size) (8..16) */
|
|
+ uInt w_mask; /* w_size - 1 */
|
|
+
|
|
+ Bytef *window;
|
|
+ /* Sliding window. Input bytes are read into the second half of the window,
|
|
+ * and move to the first half later to keep a dictionary of at least wSize
|
|
+ * bytes. With this organization, matches are limited to a distance of
|
|
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
|
|
+ * performed with a length multiple of the block size. Also, it limits
|
|
+ * the window size to 64K, which is quite useful on MSDOS.
|
|
+ * To do: use the user input buffer as sliding window.
|
|
+ */
|
|
+
|
|
+ ulg window_size;
|
|
+ /* Actual size of window: 2*wSize, except when the user input buffer
|
|
+ * is directly used as sliding window.
|
|
+ */
|
|
+
|
|
+ Posf *prev;
|
|
+ /* Link to older string with same hash index. To limit the size of this
|
|
+ * array to 64K, this link is maintained only for the last 32K strings.
|
|
+ * An index in this array is thus a window index modulo 32K.
|
|
+ */
|
|
+
|
|
+ Posf *head; /* Heads of the hash chains or NIL. */
|
|
+
|
|
+ uInt ins_h; /* hash index of string to be inserted */
|
|
+ uInt hash_size; /* number of elements in hash table */
|
|
+ uInt hash_bits; /* log2(hash_size) */
|
|
+ uInt hash_mask; /* hash_size-1 */
|
|
+
|
|
+ uInt hash_shift;
|
|
+ /* Number of bits by which ins_h must be shifted at each input
|
|
+ * step. It must be such that after MIN_MATCH steps, the oldest
|
|
+ * byte no longer takes part in the hash key, that is:
|
|
+ * hash_shift * MIN_MATCH >= hash_bits
|
|
+ */
|
|
+
|
|
+ long block_start;
|
|
+ /* Window position at the beginning of the current output block. Gets
|
|
+ * negative when the window is moved backwards.
|
|
+ */
|
|
+
|
|
+ uInt match_length; /* length of best match */
|
|
+ IPos prev_match; /* previous match */
|
|
+ int match_available; /* set if previous match exists */
|
|
+ uInt strstart; /* start of string to insert */
|
|
+ uInt match_start; /* start of matching string */
|
|
+ uInt lookahead; /* number of valid bytes ahead in window */
|
|
+
|
|
+ uInt prev_length;
|
|
+ /* Length of the best match at previous step. Matches not greater than this
|
|
+ * are discarded. This is used in the lazy match evaluation.
|
|
+ */
|
|
+
|
|
+ uInt max_chain_length;
|
|
+ /* To speed up deflation, hash chains are never searched beyond this
|
|
+ * length. A higher limit improves compression ratio but degrades the
|
|
+ * speed.
|
|
+ */
|
|
+
|
|
+ uInt max_lazy_match;
|
|
+ /* Attempt to find a better match only when the current match is strictly
|
|
+ * smaller than this value. This mechanism is used only for compression
|
|
+ * levels >= 4.
|
|
+ */
|
|
+# define max_insert_length max_lazy_match
|
|
+ /* Insert new strings in the hash table only if the match length is not
|
|
+ * greater than this length. This saves time but degrades compression.
|
|
+ * max_insert_length is used only for compression levels <= 3.
|
|
+ */
|
|
+
|
|
+ int level; /* compression level (1..9) */
|
|
+ int strategy; /* favor or force Huffman coding*/
|
|
+
|
|
+ uInt good_match;
|
|
+ /* Use a faster search when the previous match is longer than this */
|
|
+
|
|
+ int nice_match; /* Stop searching when current match exceeds this */
|
|
+
|
|
+ /* used by trees.c: */
|
|
+ /* Didn't use ct_data typedef below to supress compiler warning */
|
|
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
|
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
|
|
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
|
+
|
|
+ struct tree_desc_s l_desc; /* desc. for literal tree */
|
|
+ struct tree_desc_s d_desc; /* desc. for distance tree */
|
|
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
|
|
+
|
|
+ ush bl_count[MAX_BITS+1];
|
|
+ /* number of codes at each bit length for an optimal tree */
|
|
+
|
|
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
|
|
+ int heap_len; /* number of elements in the heap */
|
|
+ int heap_max; /* element of largest frequency */
|
|
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
|
|
+ * The same heap array is used to build all trees.
|
|
+ */
|
|
+
|
|
+ uch depth[2*L_CODES+1];
|
|
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
|
|
+ */
|
|
+
|
|
+ uchf *l_buf; /* buffer for literals or lengths */
|
|
+
|
|
+ uInt lit_bufsize;
|
|
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
|
|
+ * limiting lit_bufsize to 64K:
|
|
+ * - frequencies can be kept in 16 bit counters
|
|
+ * - if compression is not successful for the first block, all input
|
|
+ * data is still in the window so we can still emit a stored block even
|
|
+ * when input comes from standard input. (This can also be done for
|
|
+ * all blocks if lit_bufsize is not greater than 32K.)
|
|
+ * - if compression is not successful for a file smaller than 64K, we can
|
|
+ * even emit a stored file instead of a stored block (saving 5 bytes).
|
|
+ * This is applicable only for zip (not gzip or zlib).
|
|
+ * - creating new Huffman trees less frequently may not provide fast
|
|
+ * adaptation to changes in the input data statistics. (Take for
|
|
+ * example a binary file with poorly compressible code followed by
|
|
+ * a highly compressible string table.) Smaller buffer sizes give
|
|
+ * fast adaptation but have of course the overhead of transmitting
|
|
+ * trees more frequently.
|
|
+ * - I can't count above 4
|
|
+ */
|
|
+
|
|
+ uInt last_lit; /* running index in l_buf */
|
|
+
|
|
+ ushf *d_buf;
|
|
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
|
|
+ * the same number of elements. To use different lengths, an extra flag
|
|
+ * array would be necessary.
|
|
+ */
|
|
+
|
|
+ ulg opt_len; /* bit length of current block with optimal trees */
|
|
+ ulg static_len; /* bit length of current block with static trees */
|
|
+ uInt matches; /* number of string matches in current block */
|
|
+ int last_eob_len; /* bit length of EOB code for last block */
|
|
+
|
|
+#ifdef DEBUG
|
|
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
|
|
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
|
|
+#endif
|
|
+
|
|
+ ush bi_buf;
|
|
+ /* Output buffer. bits are inserted starting at the bottom (least
|
|
+ * significant bits).
|
|
+ */
|
|
+ int bi_valid;
|
|
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
|
|
+ * are always zero.
|
|
+ */
|
|
+
|
|
+} FAR deflate_state;
|
|
+
|
|
+/* Output a byte on the stream.
|
|
+ * IN assertion: there is enough room in pending_buf.
|
|
+ */
|
|
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
|
|
+
|
|
+
|
|
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
|
+/* Minimum amount of lookahead, except at the end of the input file.
|
|
+ * See deflate.c for comments about the MIN_MATCH+1.
|
|
+ */
|
|
+
|
|
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
|
|
+/* In order to simplify the code, particularly on 16 bit machines, match
|
|
+ * distances are limited to MAX_DIST instead of WSIZE.
|
|
+ */
|
|
+
|
|
+ /* in trees.c */
|
|
+void _tr_init OF((deflate_state *s));
|
|
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
|
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
|
+ int eof));
|
|
+void _tr_align OF((deflate_state *s));
|
|
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
|
+ int eof));
|
|
+
|
|
+#define d_code(dist) \
|
|
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
|
|
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
|
|
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
|
|
+ * used.
|
|
+ */
|
|
+
|
|
+#ifndef DEBUG
|
|
+/* Inline versions of _tr_tally for speed: */
|
|
+
|
|
+#if defined(GEN_TREES_H) || !defined(STDC)
|
|
+ extern uch _length_code[];
|
|
+ extern uch _dist_code[];
|
|
+#else
|
|
+ extern const uch _length_code[];
|
|
+ extern const uch _dist_code[];
|
|
+#endif
|
|
+
|
|
+# define _tr_tally_lit(s, c, flush) \
|
|
+ { uch cc = (c); \
|
|
+ s->d_buf[s->last_lit] = 0; \
|
|
+ s->l_buf[s->last_lit++] = cc; \
|
|
+ s->dyn_ltree[cc].Freq++; \
|
|
+ flush = (s->last_lit == s->lit_bufsize-1); \
|
|
+ }
|
|
+# define _tr_tally_dist(s, distance, length, flush) \
|
|
+ { uch len = (length); \
|
|
+ ush dist = (distance); \
|
|
+ s->d_buf[s->last_lit] = dist; \
|
|
+ s->l_buf[s->last_lit++] = len; \
|
|
+ dist--; \
|
|
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
|
|
+ s->dyn_dtree[d_code(dist)].Freq++; \
|
|
+ flush = (s->last_lit == s->lit_bufsize-1); \
|
|
+ }
|
|
+#else
|
|
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
|
|
+# define _tr_tally_dist(s, distance, length, flush) \
|
|
+ flush = _tr_tally(s, distance, length)
|
|
+#endif
|
|
+
|
|
+#endif /* _DEFLATE_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/COPYRIGHT Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,50 @@
|
|
+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+All rights reserved.
|
|
+
|
|
+This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
|
|
+The implementation was written so as to conform with MIT's libdes.
|
|
+
|
|
+This library is free for commercial and non-commercial use as long as
|
|
+the following conditions are aheared to. The following conditions
|
|
+apply to all code found in this distribution.
|
|
+
|
|
+Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+the code are not to be removed.
|
|
+If this package is used in a product, Eric Young should be given attribution
|
|
+as the author of that the SSL library. This can be in the form of a textual
|
|
+message at program startup or in documentation (online or textual) provided
|
|
+with the package.
|
|
+
|
|
+Redistribution and use in source and binary forms, with or without
|
|
+modification, are permitted provided that the following conditions
|
|
+are met:
|
|
+1. Redistributions of source code must retain the copyright
|
|
+ notice, this list of conditions and the following disclaimer.
|
|
+2. Redistributions in binary form must reproduce the above copyright
|
|
+ notice, this list of conditions and the following disclaimer in the
|
|
+ documentation and/or other materials provided with the distribution.
|
|
+3. All advertising materials mentioning features or use of this software
|
|
+ must display the following acknowledgement:
|
|
+ This product includes software developed by Eric Young (eay@cryptsoft.com)
|
|
+
|
|
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+SUCH DAMAGE.
|
|
+
|
|
+The license and distribution terms for any publically available version or
|
|
+derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+copied and put under another distrubution license
|
|
+[including the GNU Public License.]
|
|
+
|
|
+The reason behind this being stated in this direct manner is past
|
|
+experience in code simply being copied and the attribution removed
|
|
+from it and then being distributed as part of other packages. This
|
|
+implementation was a non-trivial and unpaid effort.
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/INSTALL Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,69 @@
|
|
+Check the CC and CFLAGS lines in the makefile
|
|
+
|
|
+If your C library does not support the times(3) function, change the
|
|
+#define TIMES to
|
|
+#undef TIMES in speed.c
|
|
+If it does, check the HZ value for the times(3) function.
|
|
+If your system does not define CLK_TCK it will be assumed to
|
|
+be 100.0.
|
|
+
|
|
+If possible use gcc v 2.7.?
|
|
+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
|
|
+In recent times, some system compilers give better performace.
|
|
+
|
|
+type 'make'
|
|
+
|
|
+run './destest' to check things are ok.
|
|
+run './rpw' to check the tty code for reading passwords works.
|
|
+run './speed' to see how fast those optimisations make the library run :-)
|
|
+run './des_opts' to determin the best compile time options.
|
|
+
|
|
+The output from des_opts should be put in the makefile options and des_enc.c
|
|
+should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
|
|
+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
|
|
+and then you can use the 'DES_PTR' option.
|
|
+
|
|
+The file options.txt has the options listed for best speed on quite a
|
|
+few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
|
|
+turn on the relevent option in the Makefile
|
|
+
|
|
+There are some special Makefile targets that make life easier.
|
|
+make cc - standard cc build
|
|
+make gcc - standard gcc build
|
|
+make x86-elf - x86 assembler (elf), linux-elf.
|
|
+make x86-out - x86 assembler (a.out), FreeBSD
|
|
+make x86-solaris- x86 assembler
|
|
+make x86-bsdi - x86 assembler (a.out with primative assembler).
|
|
+
|
|
+If at all possible use the assembler (for Windows NT/95, use
|
|
+asm/win32.obj to link with). The x86 assembler is very very fast.
|
|
+
|
|
+A make install will by default install
|
|
+libdes.a in /usr/local/lib/libdes.a
|
|
+des in /usr/local/bin/des
|
|
+des_crypt.man in /usr/local/man/man3/des_crypt.3
|
|
+des.man in /usr/local/man/man1/des.1
|
|
+des.h in /usr/include/des.h
|
|
+
|
|
+des(1) should be compatible with sunOS's but I have been unable to
|
|
+test it.
|
|
+
|
|
+These routines should compile on MSDOS, most 32bit and 64bit version
|
|
+of Unix (BSD and SYSV) and VMS, without modification.
|
|
+The only problems should be #include files that are in the wrong places.
|
|
+
|
|
+These routines can be compiled under MSDOS.
|
|
+I have successfully encrypted files using des(1) under MSDOS and then
|
|
+decrypted the files on a SparcStation.
|
|
+I have been able to compile and test the routines with
|
|
+Microsoft C v 5.1 and Turbo C v 2.0.
|
|
+The code in this library is in no way optimised for the 16bit
|
|
+operation of MSDOS.
|
|
+
|
|
+When building for glibc, ignore all of the above and just unpack into
|
|
+glibc-1.??/des and then gmake as per normal.
|
|
+
|
|
+As a final note on performace. Certain CPUs like sparcs and Alpha often give
|
|
+a %10 speed difference depending on the link order. It is rather anoying
|
|
+when one program reports 'x' DES encrypts a second and another reports
|
|
+'x*0.9' the speed.
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/Makefile Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,63 @@
|
|
+# Makefile for KLIPS kernel code as a module for 2.6 kernels
|
|
+#
|
|
+# Makefile for KLIPS kernel code as a module
|
|
+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
|
|
+# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
|
|
+#
|
|
+# This program is free software; you can redistribute it and/or modify it
|
|
+# under the terms of the GNU General Public License as published by the
|
|
+# Free Software Foundation; either version 2 of the License, or (at your
|
|
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+#
|
|
+# This program is distributed in the hope that it will be useful, but
|
|
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+# for more details.
|
|
+#
|
|
+# RCSID $Id: Makefile.fs2_6,v 1.2.2.1 2005/08/12 16:10:57 ken Exp $
|
|
+#
|
|
+# Note! Dependencies are done automagically by 'make dep', which also
|
|
+# removes any old dependencies. DON'T put your own dependencies here
|
|
+# unless it's something special (ie not a .c file).
|
|
+#
|
|
+
|
|
+obj-$(CONFIG_KLIPS_ENC_3DES) += ipsec_alg_3des.o
|
|
+obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
|
|
+obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
|
|
+obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
|
|
+
|
|
+ifeq ($(strip ${SUBARCH}),)
|
|
+SUBARCH:=${ARCH}
|
|
+endif
|
|
+
|
|
+# the assembly version expects frame pointers, which are
|
|
+# optional in many kernel builds. If you want speed, you should
|
|
+# probably use cryptoapi code instead.
|
|
+USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
|
|
+ifeq (${USEASSEMBLY},i386y)
|
|
+obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
|
|
+else
|
|
+obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
|
|
+endif
|
|
+
|
|
+#
|
|
+# $Log: Makefile.fs2_6,v $
|
|
+# Revision 1.2.2.1 2005/08/12 16:10:57 ken
|
|
+# do not use assembly code with there are no frame pointers
|
|
+#
|
|
+# Revision 1.3 2005/08/12 14:13:59 mcr
|
|
+# do not use assembly code with there are no frame pointers,
|
|
+# as it does not have the right linkages.
|
|
+#
|
|
+# Revision 1.2 2005/04/29 05:13:07 mcr
|
|
+# 3DES algorithm code.
|
|
+#
|
|
+# Revision 1.1 2004/08/17 03:27:30 mcr
|
|
+# klips 2.6 edits.
|
|
+#
|
|
+#
|
|
+# Local Variables:
|
|
+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
|
|
+# End Variables:
|
|
+#
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/README Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,54 @@
|
|
+
|
|
+ libdes, Version 4.01 10-Jan-97
|
|
+
|
|
+ Copyright (c) 1997, Eric Young
|
|
+ All rights reserved.
|
|
+
|
|
+ This program is free software; you can redistribute it and/or modify
|
|
+ it under the terms specified in COPYRIGHT.
|
|
+
|
|
+--
|
|
+The primary ftp site for this library is
|
|
+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
|
|
+libdes is now also shipped with SSLeay. Primary ftp site of
|
|
+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
|
|
+
|
|
+The best way to build this library is to build it as part of SSLeay.
|
|
+
|
|
+This kit builds a DES encryption library and a DES encryption program.
|
|
+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
|
|
+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
|
|
+implementation of crypt(3).
|
|
+It contains support routines to read keys from a terminal,
|
|
+generate a random key, generate a key from an arbitrary length string,
|
|
+read/write encrypted data from/to a file descriptor.
|
|
+
|
|
+The implementation was written so as to conform with the manual entry
|
|
+for the des_crypt(3) library routines from MIT's project Athena.
|
|
+
|
|
+destest should be run after compilation to test the des routines.
|
|
+rpw should be run after compilation to test the read password routines.
|
|
+The des program is a replacement for the sun des command. I believe it
|
|
+conforms to the sun version.
|
|
+
|
|
+The Imakefile is setup for use in the kerberos distribution.
|
|
+
|
|
+These routines are best compiled with gcc or any other good
|
|
+optimising compiler.
|
|
+Just turn you optimiser up to the highest settings and run destest
|
|
+after the build to make sure everything works.
|
|
+
|
|
+I believe these routines are close to the fastest and most portable DES
|
|
+routines that use small lookup tables (4.5k) that are publicly available.
|
|
+The fcrypt routine is faster than ufc's fcrypt (when compiling with
|
|
+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
|
|
+(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
|
|
+[ 10-Jan-97 and a function of an incorrect speed testing program in
|
|
+ ufc which gave much better test figures that reality ].
|
|
+
|
|
+It is worth noting that on sparc and Alpha CPUs, performance of the DES
|
|
+library can vary by upto %10 due to the positioning of files after application
|
|
+linkage.
|
|
+
|
|
+Eric Young (eay@cryptsoft.com)
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/README.freeswan Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,33 @@
|
|
+The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
|
|
+
|
|
+We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
|
|
+on the Alpha, instead of just noting the issue in a comment.
|
|
+
|
|
+We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
|
|
+use it, and its call to sprintf() can cause subtle difficulties when KLIPS
|
|
+is built as a module (depending on details of Linux configuration options).
|
|
+
|
|
+We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
|
|
+it cope better with Linux kernel Makefile stupidities, and took out an
|
|
+explicit CC=gcc (unwise on systems with strange compilers).
|
|
+
|
|
+We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
|
|
+of one function found only in the full libdes (not in libdes-lite), to
|
|
+avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
|
|
+Schultz for spotting this and pointing out the fixes.)
|
|
+
|
|
+We deleted a couple of .obj files in the asm subdirectory, which appear to
|
|
+have been included in the original library by accident.
|
|
+
|
|
+We have added an include of our Makefile.inc file, to permit overriding
|
|
+things like choice of compiler (although the libdes Makefile would
|
|
+probably need some work to make this effective).
|
|
+
|
|
+
|
|
+
|
|
+Note that Eric Young is no longer at the email address listed in these
|
|
+files, and is (alas) no longer working on free crypto software.
|
|
+
|
|
+
|
|
+
|
|
+This file is RCSID $Id: README.freeswan,v 1.12 2004/07/10 08:06:51 mcr Exp $
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/VERSION Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,406 @@
|
|
+Version 4.04
|
|
+ Fixed a few tests in destest. Also added x86 assember for
|
|
+ des_ncbc_encrypt() which is the standard cbc mode function.
|
|
+ This makes a very very large performace difference.
|
|
+ Ariel Glenn ariel@columbia.edu reports that the terminal
|
|
+ 'turn echo off' can return (errno == EINVAL) under solaris
|
|
+ when redirection is used. So I now catch that as well as ENOTTY.
|
|
+
|
|
+
|
|
+Version 4.03
|
|
+ Left a static out of enc_write.c, which caused to buffer to be
|
|
+ continiously malloc()ed. Does anyone use these functions? I keep
|
|
+ on feeling like removing them since I only had these in there
|
|
+ for a version of kerberised login. Anyway, this was pointed out
|
|
+ by Theo de Raadt <deraadt@cvs.openbsd.org>
|
|
+ The 'n' bit ofb code was wrong, it was not shifting the shift
|
|
+ register. It worked correctly for n == 64. Thanks to
|
|
+ Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
|
|
+
|
|
+Version 4.02
|
|
+ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
|
|
+ when checking for weak keys which is wrong :-(, pointed out by
|
|
+ Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
|
|
+
|
|
+Version 4.01
|
|
+ Even faster inner loop in the DES assembler for x86 and a modification
|
|
+ for IP/FP which is faster on x86. Both of these changes are
|
|
+ from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
|
|
+ changes make the assembler run %40 faster on a pentium. This is just
|
|
+ a case of getting the instruction sequence 'just right'.
|
|
+ All credit to 'Svend' :-)
|
|
+ Quite a few special x86 'make' targets.
|
|
+ A libdes-l (lite) distribution.
|
|
+
|
|
+Version 4.00
|
|
+ After a bit of a pause, I'll up the major version number since this
|
|
+ is mostly a performace release. I've added x86 assembler and
|
|
+ added more options for performance. A %28 speedup for gcc
|
|
+ on a pentium and the assembler is a %50 speedup.
|
|
+ MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
|
|
+ Run des_opts to work out which options should be used.
|
|
+ DES_RISC1/DES_RISC2 use alternative inner loops which use
|
|
+ more registers but should give speedups on any CPU that does
|
|
+ dual issue (pentium). DES_UNROLL unrolls the inner loop,
|
|
+ which costs in code size.
|
|
+
|
|
+Version 3.26
|
|
+ I've finally removed one of the shifts in D_ENCRYPT. This
|
|
+ meant I've changed the des_SPtrans table (spr.h), the set_key()
|
|
+ function and some things in des_enc.c. This has definitly
|
|
+ made things faster :-). I've known about this one for some
|
|
+ time but I've been too lazy to follow it up :-).
|
|
+ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
|
|
+ instead of L^=((..)|(..)|(..).. This should save a register at
|
|
+ least.
|
|
+ Assember for x86. The file to replace is des_enc.c, which is replaced
|
|
+ by one of the assembler files found in asm. Look at des/asm/readme
|
|
+ for more info.
|
|
+
|
|
+ /* Modification to fcrypt so it can be compiled to support
|
|
+ HPUX 10.x's long password format, define -DLONGCRYPT to use this.
|
|
+ Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
|
|
+
|
|
+ SIGWINCH case put in des_read_passwd() so the function does not
|
|
+ 'exit' if this function is recieved.
|
|
+
|
|
+Version 3.25 17/07/96
|
|
+ Modified read_pwd.c so that stdin can be read if not a tty.
|
|
+ Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
|
|
+ des_init_random_number_generator() shortened due to VMS linker
|
|
+ limits.
|
|
+ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
|
|
+ 8 byte quantites xored before and after encryption.
|
|
+ des_xcbc_encryption() - the name is funny to preserve the des_
|
|
+ prefix on all functions.
|
|
+
|
|
+Version 3.24 20/04/96
|
|
+ The DES_PTR macro option checked and used by SSLeay configuration
|
|
+
|
|
+Version 3.23 11/04/96
|
|
+ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
|
|
+ it gives a %20 speedup :-)
|
|
+ Fixed the problem with des.pl under perl5. The patches were
|
|
+ sent by Ed Kubaitis (ejk@uiuc.edu).
|
|
+ if fcrypt.c, changed values to handle illegal salt values the way
|
|
+ normal crypt() implementations do. Some programs apparently use
|
|
+ them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
|
|
+
|
|
+Version 3.22 29/11/95
|
|
+ Bug in des(1), an error with the uuencoding stuff when the
|
|
+ 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
|
|
+ for the patch.
|
|
+
|
|
+Version 3.21 22/11/95
|
|
+ After some emailing back and forth with
|
|
+ Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
|
|
+ and in a future version I will probably put in some of the
|
|
+ optimisation he suggested for use with the DES_USE_PTR option.
|
|
+ Extra routines from Mark Murray <mark@grondar.za> for use in
|
|
+ freeBSD. They mostly involve random number generation for use
|
|
+ with kerberos. They involve evil machine specific system calls
|
|
+ etc so I would normally suggest pushing this stuff into the
|
|
+ application and/or using RAND_seed()/RAND_bytes() if you are
|
|
+ using this DES library as part of SSLeay.
|
|
+ Redone the read_pw() function so that it is cleaner and
|
|
+ supports termios, thanks to Sameer Parekh <sameer@c2.org>
|
|
+ for the initial patches for this.
|
|
+ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
|
|
+ done just to make things more consistent.
|
|
+ I have also now added triple DES versions of cfb and ofb.
|
|
+
|
|
+Version 3.20
|
|
+ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
|
|
+ my des_random_seed() function was only copying 4 bytes of the
|
|
+ passed seed into the init structure. It is now fixed to copy 8.
|
|
+ My own suggestion is to used something like MD5 :-)
|
|
+
|
|
+Version 3.19
|
|
+ While looking at my code one day, I though, why do I keep on
|
|
+ calling des_encrypt(in,out,ks,enc) when every function that
|
|
+ calls it has in and out the same. So I dropped the 'out'
|
|
+ parameter, people should not be using this function.
|
|
+
|
|
+Version 3.18 30/08/95
|
|
+ Fixed a few bit with the distribution and the filenames.
|
|
+ 3.17 had been munged via a move to DOS and back again.
|
|
+ NO CODE CHANGES
|
|
+
|
|
+Version 3.17 14/07/95
|
|
+ Fixed ede3 cbc which I had broken in 3.16. I have also
|
|
+ removed some unneeded variables in 7-8 of the routines.
|
|
+
|
|
+Version 3.16 26/06/95
|
|
+ Added des_encrypt2() which does not use IP/FP, used by triple
|
|
+ des routines. Tweaked things a bit elsewhere. %13 speedup on
|
|
+ sparc and %6 on a R4400 for ede3 cbc mode.
|
|
+
|
|
+Version 3.15 06/06/95
|
|
+ Added des_ncbc_encrypt(), it is des_cbc mode except that it is
|
|
+ 'normal' and copies the new iv value back over the top of the
|
|
+ passed parameter.
|
|
+ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
|
|
+ the iv. THIS WILL BREAK EXISTING CODE, but since this function
|
|
+ only new, I feel I can change it, not so with des_cbc_encrypt :-(.
|
|
+ I need to update the documentation.
|
|
+
|
|
+Version 3.14 31/05/95
|
|
+ New release upon the world, as part of my SSL implementation.
|
|
+ New copyright and usage stuff. Basically free for all to use
|
|
+ as long as you say it came from me :-)
|
|
+
|
|
+Version 3.13 31/05/95
|
|
+ A fix in speed.c, if HZ is not defined, I set it to 100.0
|
|
+ which is reasonable for most unixes except SunOS 4.x.
|
|
+ I now have a #ifdef sun but timing for SunOS 4.x looked very
|
|
+ good :-(. At my last job where I used SunOS 4.x, it was
|
|
+ defined to be 60.0 (look at the old INSTALL documentation), at
|
|
+ the last release had it changed to 100.0 since I now work with
|
|
+ Solaris2 and SVR4 boxes.
|
|
+ Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
|
|
+ one out.
|
|
+
|
|
+Version 3.12 08/05/95
|
|
+ As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
|
|
+ my D_ENCRYPT macro in crypt() had an un-necessary variable.
|
|
+ It has been removed.
|
|
+
|
|
+Version 3.11 03/05/95
|
|
+ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
|
|
+ and one iv. It is a standard and I needed it for my SSL code.
|
|
+ It makes more sense to use this for triple DES than
|
|
+ 3cbc_encrypt(). I have also added (or should I say tested :-)
|
|
+ cfb64_encrypt() which is cfb64 but it will encrypt a partial
|
|
+ number of bytes - 3 bytes in 3 bytes out. Again this is for
|
|
+ my SSL library, as a form of encryption to use with SSL
|
|
+ telnet.
|
|
+
|
|
+Version 3.10 22/03/95
|
|
+ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
|
|
+ to cbc3_encrypt, the 2 iv values that were being returned to
|
|
+ be used in the next call were reversed :-(.
|
|
+ Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
|
|
+ this error.
|
|
+
|
|
+Version 3.09 01/02/95
|
|
+ Fixed des_random_key to far more random, it was rather feeble
|
|
+ with regards to picking the initial seed. The problem was
|
|
+ pointed out by Olaf Kirch <okir@monad.swb.de>.
|
|
+
|
|
+Version 3.08 14/12/94
|
|
+ Added Makefile.PL so libdes can be built into perl5.
|
|
+ Changed des_locl.h so RAND is always defined.
|
|
+
|
|
+Version 3.07 05/12/94
|
|
+ Added GNUmake and stuff so the library can be build with
|
|
+ glibc.
|
|
+
|
|
+Version 3.06 30/08/94
|
|
+ Added rpc_enc.c which contains _des_crypt. This is for use in
|
|
+ secure_rpc v 4.0
|
|
+ Finally fixed the cfb_enc problems.
|
|
+ Fixed a few parameter parsing bugs in des (-3 and -b), thanks
|
|
+ to Rob McMillan <R.McMillan@its.gu.edu.au>
|
|
+
|
|
+Version 3.05 21/04/94
|
|
+ for unsigned long l; gcc does not produce ((l>>34) == 0)
|
|
+ This causes bugs in cfb_enc.
|
|
+ Thanks to Hadmut Danisch <danisch@ira.uka.de>
|
|
+
|
|
+Version 3.04 20/04/94
|
|
+ Added a version number to des.c and libdes.a
|
|
+
|
|
+Version 3.03 12/01/94
|
|
+ Fixed a bug in non zero iv in 3cbc_enc.
|
|
+
|
|
+Version 3.02 29/10/93
|
|
+ I now work in a place where there are 6+ architectures and 14+
|
|
+ OS versions :-).
|
|
+ Fixed TERMIO definition so the most sys V boxes will work :-)
|
|
+
|
|
+Release upon comp.sources.misc
|
|
+Version 3.01 08/10/93
|
|
+ Added des_3cbc_encrypt()
|
|
+
|
|
+Version 3.00 07/10/93
|
|
+ Fixed up documentation.
|
|
+ quad_cksum definitely compatible with MIT's now.
|
|
+
|
|
+Version 2.30 24/08/93
|
|
+ Triple DES now defaults to triple cbc but can do triple ecb
|
|
+ with the -b flag.
|
|
+ Fixed some MSDOS uuen/uudecoding problems, thanks to
|
|
+ Added prototypes.
|
|
+
|
|
+Version 2.22 29/06/93
|
|
+ Fixed a bug in des_is_weak_key() which stopped it working :-(
|
|
+ thanks to engineering@MorningStar.Com.
|
|
+
|
|
+Version 2.21 03/06/93
|
|
+ des(1) with no arguments gives quite a bit of help.
|
|
+ Added -c (generate ckecksum) flag to des(1).
|
|
+ Added -3 (triple DES) flag to des(1).
|
|
+ Added cfb and ofb routines to the library.
|
|
+
|
|
+Version 2.20 11/03/93
|
|
+ Added -u (uuencode) flag to des(1).
|
|
+ I have been playing with byte order in quad_cksum to make it
|
|
+ compatible with MIT's version. All I can say is avid this
|
|
+ function if possible since MIT's output is endian dependent.
|
|
+
|
|
+Version 2.12 14/10/92
|
|
+ Added MSDOS specific macro in ecb_encrypt which gives a %70
|
|
+ speed up when the code is compiled with turbo C.
|
|
+
|
|
+Version 2.11 12/10/92
|
|
+ Speedup in set_key (recoding of PC-1)
|
|
+ I now do it in 47 simple operations, down from 60.
|
|
+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
|
|
+ for motivating me to look for a faster system :-)
|
|
+ The speedup is probably less that 1% but it is still 13
|
|
+ instructions less :-).
|
|
+
|
|
+Version 2.10 06/10/92
|
|
+ The code now works on the 64bit ETA10 and CRAY without modifications or
|
|
+ #defines. I believe the code should work on any machine that
|
|
+ defines long, int or short to be 8 bytes long.
|
|
+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
|
|
+ for helping me fix the code to run on 64bit machines (he had
|
|
+ access to an ETA10).
|
|
+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
|
|
+ for testing the routines on a CRAY.
|
|
+ read_password.c has been renamed to read_passwd.c
|
|
+ string_to_key.c has been renamed to string2key.c
|
|
+
|
|
+Version 2.00 14/09/92
|
|
+ Made mods so that the library should work on 64bit CPU's.
|
|
+ Removed all my uchar and ulong defs. To many different
|
|
+ versions of unix define them in their header files in too many
|
|
+ different combinations :-)
|
|
+ IRIX - Sillicon Graphics mods (mostly in read_password.c).
|
|
+ Thanks to Andrew Daviel (advax@erich.triumf.ca)
|
|
+
|
|
+Version 1.99 26/08/92
|
|
+ Fixed a bug or 2 in enc_read.c
|
|
+ Fixed a bug in enc_write.c
|
|
+ Fixed a pseudo bug in fcrypt.c (very obscure).
|
|
+
|
|
+Version 1.98 31/07/92
|
|
+ Support for the ETA10. This is a strange machine that defines
|
|
+ longs and ints as 8 bytes and shorts as 4 bytes.
|
|
+ Since I do evil things with long * that assume that they are 4
|
|
+ bytes. Look in the Makefile for the option to compile for
|
|
+ this machine. quad_cksum appears to have problems but I
|
|
+ will don't have the time to fix it right now, and this is not
|
|
+ a function that uses DES and so will not effect the main uses
|
|
+ of the library.
|
|
+
|
|
+Version 1.97 20/05/92 eay
|
|
+ Fixed the Imakefile and made some changes to des.h to fix some
|
|
+ problems when building this package with Kerberos v 4.
|
|
+
|
|
+Version 1.96 18/05/92 eay
|
|
+ Fixed a small bug in string_to_key() where problems could
|
|
+ occur if des_check_key was set to true and the string
|
|
+ generated a weak key.
|
|
+
|
|
+Patch2 posted to comp.sources.misc
|
|
+Version 1.95 13/05/92 eay
|
|
+ Added an alternative version of the D_ENCRYPT macro in
|
|
+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the
|
|
+ other will be faster. This was inspired by
|
|
+ Dana How <how@isl.stanford.edu>, and her pointers about doing the
|
|
+ *(ulong *)((uchar *)ptr+(value&0xfc))
|
|
+ vs
|
|
+ ptr[value&0x3f]
|
|
+ to stop the C compiler doing a <<2 to convert the long array index.
|
|
+
|
|
+Version 1.94 05/05/92 eay
|
|
+ Fixed an incompatibility between my string_to_key and the MIT
|
|
+ version. When the key is longer than 8 chars, I was wrapping
|
|
+ with a different method. To use the old version, define
|
|
+ OLD_STR_TO_KEY in the makefile. Thanks to
|
|
+ viktor@newsu.shearson.com (Viktor Dukhovni).
|
|
+
|
|
+Version 1.93 28/04/92 eay
|
|
+ Fixed the VMS mods so that echo is now turned off in
|
|
+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
|
|
+ MSDOS support added. The routines can be compiled with
|
|
+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
|
|
+
|
|
+Patch1 posted to comp.sources.misc
|
|
+Version 1.92 13/04/92 eay
|
|
+ Changed D_ENCRYPT so that the rotation of R occurs outside of
|
|
+ the loop. This required rotating all the longs in sp.h (now
|
|
+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
|
|
+ speed.c has been changed so it will work without SIGALRM. If
|
|
+ times(3) is not present it will try to use ftime() instead.
|
|
+
|
|
+Version 1.91 08/04/92 eay
|
|
+ Added -E/-D options to des(1) so it can use string_to_key.
|
|
+ Added SVR4 mods suggested by witr@rwwa.COM
|
|
+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
|
|
+ anyone knows how to turn of tty echo in VMS please tell me or
|
|
+ implement it yourself :-).
|
|
+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
|
|
+ does not like IN/OUT being used.
|
|
+
|
|
+Libdes posted to comp.sources.misc
|
|
+Version 1.9 24/03/92 eay
|
|
+ Now contains a fast small crypt replacement.
|
|
+ Added des(1) command.
|
|
+ Added des_rw_mode so people can use cbc encryption with
|
|
+ enc_read and enc_write.
|
|
+
|
|
+Version 1.8 15/10/91 eay
|
|
+ Bug in cbc_cksum.
|
|
+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
|
|
+ one out.
|
|
+
|
|
+Version 1.7 24/09/91 eay
|
|
+ Fixed set_key :-)
|
|
+ set_key is 4 times faster and takes less space.
|
|
+ There are a few minor changes that could be made.
|
|
+
|
|
+Version 1.6 19/09/1991 eay
|
|
+ Finally go IP and FP finished.
|
|
+ Now I need to fix set_key.
|
|
+ This version is quite a bit faster that 1.51
|
|
+
|
|
+Version 1.52 15/06/1991 eay
|
|
+ 20% speedup in ecb_encrypt by changing the E bit selection
|
|
+ to use 2 32bit words. This also required modification of the
|
|
+ sp table. There is still a way to speedup the IP and IP-1
|
|
+ (hints from outer@sq.com) still working on this one :-(.
|
|
+
|
|
+Version 1.51 07/06/1991 eay
|
|
+ Faster des_encrypt by loop unrolling
|
|
+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
|
|
+
|
|
+Version 1.50 28/05/1991 eay
|
|
+ Optimised the code a bit more for the sparc. I have improved the
|
|
+ speed of the inner des_encrypt by speeding up the initial and
|
|
+ final permutations.
|
|
+
|
|
+Version 1.40 23/10/1990 eay
|
|
+ Fixed des_random_key, it did not produce a random key :-(
|
|
+
|
|
+Version 1.30 2/10/1990 eay
|
|
+ Have made des_quad_cksum the same as MIT's, the full package
|
|
+ should be compatible with MIT's
|
|
+ Have tested on a DECstation 3100
|
|
+ Still need to fix des_set_key (make it faster).
|
|
+ Does des_cbc_encrypts at 70.5k/sec on a 3100.
|
|
+
|
|
+Version 1.20 18/09/1990 eay
|
|
+ Fixed byte order dependencies.
|
|
+ Fixed (I hope) all the word alignment problems.
|
|
+ Speedup in des_ecb_encrypt.
|
|
+
|
|
+Version 1.10 11/09/1990 eay
|
|
+ Added des_enc_read and des_enc_write.
|
|
+ Still need to fix des_quad_cksum.
|
|
+ Still need to document des_enc_read and des_enc_write.
|
|
+
|
|
+Version 1.00 27/08/1990 eay
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/asm/des-586.pl Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,251 @@
|
|
+#!/usr/local/bin/perl
|
|
+#
|
|
+# The inner loop instruction sequence and the IP/FP modifications are from
|
|
+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
|
|
+#
|
|
+
|
|
+push(@INC,"perlasm","../../perlasm");
|
|
+require "x86asm.pl";
|
|
+require "cbc.pl";
|
|
+require "desboth.pl";
|
|
+
|
|
+# base code is in microsft
|
|
+# op dest, source
|
|
+# format.
|
|
+#
|
|
+
|
|
+&asm_init($ARGV[0],"des-586.pl");
|
|
+
|
|
+$L="edi";
|
|
+$R="esi";
|
|
+
|
|
+&external_label("des_SPtrans");
|
|
+&des_encrypt("des_encrypt",1);
|
|
+&des_encrypt("des_encrypt2",0);
|
|
+&des_encrypt3("des_encrypt3",1);
|
|
+&des_encrypt3("des_decrypt3",0);
|
|
+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
|
|
+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
|
|
+
|
|
+&asm_finish();
|
|
+
|
|
+sub des_encrypt
|
|
+ {
|
|
+ local($name,$do_ip)=@_;
|
|
+
|
|
+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
|
|
+
|
|
+ &push("esi");
|
|
+ &push("edi");
|
|
+
|
|
+ &comment("");
|
|
+ &comment("Load the 2 words");
|
|
+ $ks="ebp";
|
|
+
|
|
+ if ($do_ip)
|
|
+ {
|
|
+ &mov($R,&wparam(0));
|
|
+ &xor( "ecx", "ecx" );
|
|
+
|
|
+ &push("ebx");
|
|
+ &push("ebp");
|
|
+
|
|
+ &mov("eax",&DWP(0,$R,"",0));
|
|
+ &mov("ebx",&wparam(2)); # get encrypt flag
|
|
+ &mov($L,&DWP(4,$R,"",0));
|
|
+ &comment("");
|
|
+ &comment("IP");
|
|
+ &IP_new("eax",$L,$R,3);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ &mov("eax",&wparam(0));
|
|
+ &xor( "ecx", "ecx" );
|
|
+
|
|
+ &push("ebx");
|
|
+ &push("ebp");
|
|
+
|
|
+ &mov($R,&DWP(0,"eax","",0));
|
|
+ &mov("ebx",&wparam(2)); # get encrypt flag
|
|
+ &rotl($R,3);
|
|
+ &mov($L,&DWP(4,"eax","",0));
|
|
+ &rotl($L,3);
|
|
+ }
|
|
+
|
|
+ &mov( $ks, &wparam(1) );
|
|
+ &cmp("ebx","0");
|
|
+ &je(&label("start_decrypt"));
|
|
+
|
|
+ for ($i=0; $i<16; $i+=2)
|
|
+ {
|
|
+ &comment("");
|
|
+ &comment("Round $i");
|
|
+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
|
|
+
|
|
+ &comment("");
|
|
+ &comment("Round ".sprintf("%d",$i+1));
|
|
+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
|
|
+ }
|
|
+ &jmp(&label("end"));
|
|
+
|
|
+ &set_label("start_decrypt");
|
|
+
|
|
+ for ($i=15; $i>0; $i-=2)
|
|
+ {
|
|
+ &comment("");
|
|
+ &comment("Round $i");
|
|
+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
|
|
+ &comment("");
|
|
+ &comment("Round ".sprintf("%d",$i-1));
|
|
+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
|
|
+ }
|
|
+
|
|
+ &set_label("end");
|
|
+
|
|
+ if ($do_ip)
|
|
+ {
|
|
+ &comment("");
|
|
+ &comment("FP");
|
|
+ &mov("edx",&wparam(0));
|
|
+ &FP_new($L,$R,"eax",3);
|
|
+
|
|
+ &mov(&DWP(0,"edx","",0),"eax");
|
|
+ &mov(&DWP(4,"edx","",0),$R);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ &comment("");
|
|
+ &comment("Fixup");
|
|
+ &rotr($L,3); # r
|
|
+ &mov("eax",&wparam(0));
|
|
+ &rotr($R,3); # l
|
|
+ &mov(&DWP(0,"eax","",0),$L);
|
|
+ &mov(&DWP(4,"eax","",0),$R);
|
|
+ }
|
|
+
|
|
+ &pop("ebp");
|
|
+ &pop("ebx");
|
|
+ &pop("edi");
|
|
+ &pop("esi");
|
|
+ &ret();
|
|
+
|
|
+ &function_end_B($name);
|
|
+ }
|
|
+
|
|
+sub D_ENCRYPT
|
|
+ {
|
|
+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
|
|
+
|
|
+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
|
|
+ &xor( $tmp1, $tmp1);
|
|
+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
|
|
+ &xor( $u, $R);
|
|
+ &xor( $t, $R);
|
|
+ &and( $u, "0xfcfcfcfc" );
|
|
+ &and( $t, "0xcfcfcfcf" );
|
|
+ &movb( &LB($tmp1), &LB($u) );
|
|
+ &movb( &LB($tmp2), &HB($u) );
|
|
+ &rotr( $t, 4 );
|
|
+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
|
|
+ &movb( &LB($tmp1), &LB($t) );
|
|
+ &xor( $L, $ks);
|
|
+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
|
|
+ &xor( $L, $ks); ######
|
|
+ &movb( &LB($tmp2), &HB($t) );
|
|
+ &shr( $u, 16);
|
|
+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
|
|
+ &xor( $L, $ks); ######
|
|
+ &movb( &LB($tmp1), &HB($u) );
|
|
+ &shr( $t, 16);
|
|
+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
|
|
+ &xor( $L, $ks);
|
|
+ &mov( $ks, &wparam(1) );
|
|
+ &movb( &LB($tmp2), &HB($t) );
|
|
+ &and( $u, "0xff" );
|
|
+ &and( $t, "0xff" );
|
|
+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
|
|
+ &xor( $L, $tmp1);
|
|
+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
|
|
+ &xor( $L, $tmp1);
|
|
+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
|
|
+ &xor( $L, $tmp1);
|
|
+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
|
|
+ &xor( $L, $tmp1);
|
|
+ }
|
|
+
|
|
+sub n2a
|
|
+ {
|
|
+ sprintf("%d",$_[0]);
|
|
+ }
|
|
+
|
|
+# now has a side affect of rotating $a by $shift
|
|
+sub R_PERM_OP
|
|
+ {
|
|
+ local($a,$b,$tt,$shift,$mask,$last)=@_;
|
|
+
|
|
+ &rotl( $a, $shift ) if ($shift != 0);
|
|
+ &mov( $tt, $a );
|
|
+ &xor( $a, $b );
|
|
+ &and( $a, $mask );
|
|
+ if (!$last eq $b)
|
|
+ {
|
|
+ &xor( $b, $a );
|
|
+ &xor( $tt, $a );
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ &xor( $tt, $a );
|
|
+ &xor( $b, $a );
|
|
+ }
|
|
+ &comment("");
|
|
+ }
|
|
+
|
|
+sub IP_new
|
|
+ {
|
|
+ local($l,$r,$tt,$lr)=@_;
|
|
+
|
|
+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
|
|
+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
|
|
+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
|
|
+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
|
|
+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
|
|
+
|
|
+ if ($lr != 3)
|
|
+ {
|
|
+ if (($lr-3) < 0)
|
|
+ { &rotr($tt, 3-$lr); }
|
|
+ else { &rotl($tt, $lr-3); }
|
|
+ }
|
|
+ if ($lr != 2)
|
|
+ {
|
|
+ if (($lr-2) < 0)
|
|
+ { &rotr($r, 2-$lr); }
|
|
+ else { &rotl($r, $lr-2); }
|
|
+ }
|
|
+ }
|
|
+
|
|
+sub FP_new
|
|
+ {
|
|
+ local($l,$r,$tt,$lr)=@_;
|
|
+
|
|
+ if ($lr != 2)
|
|
+ {
|
|
+ if (($lr-2) < 0)
|
|
+ { &rotl($r, 2-$lr); }
|
|
+ else { &rotr($r, $lr-2); }
|
|
+ }
|
|
+ if ($lr != 3)
|
|
+ {
|
|
+ if (($lr-3) < 0)
|
|
+ { &rotl($l, 3-$lr); }
|
|
+ else { &rotr($l, $lr-3); }
|
|
+ }
|
|
+
|
|
+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
|
|
+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
|
|
+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
|
|
+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
|
|
+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
|
|
+ &rotr($tt , 4);
|
|
+ }
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/asm/des686.pl Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,230 @@
|
|
+#!/usr/local/bin/perl
|
|
+
|
|
+$prog="des686.pl";
|
|
+
|
|
+# base code is in microsft
|
|
+# op dest, source
|
|
+# format.
|
|
+#
|
|
+
|
|
+# WILL NOT WORK ANYMORE WITH desboth.pl
|
|
+require "desboth.pl";
|
|
+
|
|
+if ( ($ARGV[0] eq "elf"))
|
|
+ { require "x86unix.pl"; }
|
|
+elsif ( ($ARGV[0] eq "a.out"))
|
|
+ { $aout=1; require "x86unix.pl"; }
|
|
+elsif ( ($ARGV[0] eq "sol"))
|
|
+ { $sol=1; require "x86unix.pl"; }
|
|
+elsif ( ($ARGV[0] eq "cpp"))
|
|
+ { $cpp=1; require "x86unix.pl"; }
|
|
+elsif ( ($ARGV[0] eq "win32"))
|
|
+ { require "x86ms.pl"; }
|
|
+else
|
|
+ {
|
|
+ print STDERR <<"EOF";
|
|
+Pick one target type from
|
|
+ elf - linux, FreeBSD etc
|
|
+ a.out - old linux
|
|
+ sol - x86 solaris
|
|
+ cpp - format so x86unix.cpp can be used
|
|
+ win32 - Windows 95/Windows NT
|
|
+EOF
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+&comment("Don't even think of reading this code");
|
|
+&comment("It was automatically generated by $prog");
|
|
+&comment("Which is a perl program used to generate the x86 assember for");
|
|
+&comment("any of elf, a.out, Win32, or Solaris");
|
|
+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
|
|
+&comment("eric <eay\@cryptsoft.com>");
|
|
+&comment("");
|
|
+
|
|
+&file("dx86xxxx");
|
|
+
|
|
+$L="edi";
|
|
+$R="esi";
|
|
+
|
|
+&des_encrypt("des_encrypt",1);
|
|
+&des_encrypt("des_encrypt2",0);
|
|
+
|
|
+&des_encrypt3("des_encrypt3",1);
|
|
+&des_encrypt3("des_decrypt3",0);
|
|
+
|
|
+&file_end();
|
|
+
|
|
+sub des_encrypt
|
|
+ {
|
|
+ local($name,$do_ip)=@_;
|
|
+
|
|
+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
|
|
+
|
|
+ &comment("");
|
|
+ &comment("Load the 2 words");
|
|
+ &mov("eax",&wparam(0));
|
|
+ &mov($L,&DWP(0,"eax","",0));
|
|
+ &mov($R,&DWP(4,"eax","",0));
|
|
+
|
|
+ $ksp=&wparam(1);
|
|
+
|
|
+ if ($do_ip)
|
|
+ {
|
|
+ &comment("");
|
|
+ &comment("IP");
|
|
+ &IP_new($L,$R,"eax");
|
|
+ }
|
|
+
|
|
+ &comment("");
|
|
+ &comment("fixup rotate");
|
|
+ &rotl($R,3);
|
|
+ &rotl($L,3);
|
|
+ &exch($L,$R);
|
|
+
|
|
+ &comment("");
|
|
+ &comment("load counter, key_schedule and enc flag");
|
|
+ &mov("eax",&wparam(2)); # get encrypt flag
|
|
+ &mov("ebp",&wparam(1)); # get ks
|
|
+ &cmp("eax","0");
|
|
+ &je(&label("start_decrypt"));
|
|
+
|
|
+ # encrypting part
|
|
+
|
|
+ for ($i=0; $i<16; $i+=2)
|
|
+ {
|
|
+ &comment("");
|
|
+ &comment("Round $i");
|
|
+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
|
|
+
|
|
+ &comment("");
|
|
+ &comment("Round ".sprintf("%d",$i+1));
|
|
+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
|
|
+ }
|
|
+ &jmp(&label("end"));
|
|
+
|
|
+ &set_label("start_decrypt");
|
|
+
|
|
+ for ($i=15; $i>0; $i-=2)
|
|
+ {
|
|
+ &comment("");
|
|
+ &comment("Round $i");
|
|
+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
|
|
+ &comment("");
|
|
+ &comment("Round ".sprintf("%d",$i-1));
|
|
+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
|
|
+ }
|
|
+
|
|
+ &set_label("end");
|
|
+
|
|
+ &comment("");
|
|
+ &comment("Fixup");
|
|
+ &rotr($L,3); # r
|
|
+ &rotr($R,3); # l
|
|
+
|
|
+ if ($do_ip)
|
|
+ {
|
|
+ &comment("");
|
|
+ &comment("FP");
|
|
+ &FP_new($R,$L,"eax");
|
|
+ }
|
|
+
|
|
+ &mov("eax",&wparam(0));
|
|
+ &mov(&DWP(0,"eax","",0),$L);
|
|
+ &mov(&DWP(4,"eax","",0),$R);
|
|
+
|
|
+ &function_end($name);
|
|
+ }
|
|
+
|
|
+
|
|
+# The logic is to load R into 2 registers and operate on both at the same time.
|
|
+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
|
|
+# while also masking the other copy and doing a lookup. We then also accumulate the
|
|
+# L value in 2 registers then combine them at the end.
|
|
+sub D_ENCRYPT
|
|
+ {
|
|
+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
|
|
+
|
|
+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
|
|
+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
|
|
+ &xor( $u, $R );
|
|
+ &xor( $t, $R );
|
|
+ &rotr( $t, 4 );
|
|
+
|
|
+ # the numbers at the end of the line are origional instruction order
|
|
+ &mov( $tmp2, $u ); # 1 2
|
|
+ &mov( $tmp1, $t ); # 1 1
|
|
+ &and( $tmp2, "0xfc" ); # 1 4
|
|
+ &and( $tmp1, "0xfc" ); # 1 3
|
|
+ &shr( $t, 8 ); # 1 5
|
|
+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
|
|
+ &shr( $u, 8 ); # 1 6
|
|
+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
|
|
+
|
|
+ &mov( $tmp2, $u ); # 2 2
|
|
+ &xor( $L, $tmp1 ); # 1 9
|
|
+ &and( $tmp2, "0xfc" ); # 2 4
|
|
+ &mov( $tmp1, $t ); # 2 1
|
|
+ &and( $tmp1, "0xfc" ); # 2 3
|
|
+ &shr( $t, 8 ); # 2 5
|
|
+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
|
|
+ &shr( $u, 8 ); # 2 6
|
|
+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
|
|
+ &mov( $tmp2, $u ); # 3 2
|
|
+
|
|
+ &xor( $L, $tmp1 ); # 2 9
|
|
+ &and( $tmp2, "0xfc" ); # 3 4
|
|
+
|
|
+ &mov( $tmp1, $t ); # 3 1
|
|
+ &shr( $u, 8 ); # 3 6
|
|
+ &and( $tmp1, "0xfc" ); # 3 3
|
|
+ &shr( $t, 8 ); # 3 5
|
|
+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
|
|
+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
|
|
+
|
|
+ &and( $t, "0xfc" ); # 4 1
|
|
+ &xor( $L, $tmp1 ); # 3 9
|
|
+
|
|
+ &and( $u, "0xfc" ); # 4 2
|
|
+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
|
|
+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
|
|
+ }
|
|
+
|
|
+sub PERM_OP
|
|
+ {
|
|
+ local($a,$b,$tt,$shift,$mask)=@_;
|
|
+
|
|
+ &mov( $tt, $a );
|
|
+ &shr( $tt, $shift );
|
|
+ &xor( $tt, $b );
|
|
+ &and( $tt, $mask );
|
|
+ &xor( $b, $tt );
|
|
+ &shl( $tt, $shift );
|
|
+ &xor( $a, $tt );
|
|
+ }
|
|
+
|
|
+sub IP_new
|
|
+ {
|
|
+ local($l,$r,$tt)=@_;
|
|
+
|
|
+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
|
|
+ &PERM_OP($l,$r,$tt,16,"0x0000ffff");
|
|
+ &PERM_OP($r,$l,$tt, 2,"0x33333333");
|
|
+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
|
|
+ &PERM_OP($r,$l,$tt, 1,"0x55555555");
|
|
+ }
|
|
+
|
|
+sub FP_new
|
|
+ {
|
|
+ local($l,$r,$tt)=@_;
|
|
+
|
|
+ &PERM_OP($l,$r,$tt, 1,"0x55555555");
|
|
+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
|
|
+ &PERM_OP($l,$r,$tt, 2,"0x33333333");
|
|
+ &PERM_OP($r,$l,$tt,16,"0x0000ffff");
|
|
+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
|
|
+ }
|
|
+
|
|
+sub n2a
|
|
+ {
|
|
+ sprintf("%d",$_[0]);
|
|
+ }
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/asm/desboth.pl Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,79 @@
|
|
+#!/usr/local/bin/perl
|
|
+
|
|
+$L="edi";
|
|
+$R="esi";
|
|
+
|
|
+sub des_encrypt3
|
|
+ {
|
|
+ local($name,$enc)=@_;
|
|
+
|
|
+ &function_begin_B($name,"");
|
|
+ &push("ebx");
|
|
+ &mov("ebx",&wparam(0));
|
|
+
|
|
+ &push("ebp");
|
|
+ &push("esi");
|
|
+
|
|
+ &push("edi");
|
|
+
|
|
+ &comment("");
|
|
+ &comment("Load the data words");
|
|
+ &mov($L,&DWP(0,"ebx","",0));
|
|
+ &mov($R,&DWP(4,"ebx","",0));
|
|
+ &stack_push(3);
|
|
+
|
|
+ &comment("");
|
|
+ &comment("IP");
|
|
+ &IP_new($L,$R,"edx",0);
|
|
+
|
|
+ # put them back
|
|
+
|
|
+ if ($enc)
|
|
+ {
|
|
+ &mov(&DWP(4,"ebx","",0),$R);
|
|
+ &mov("eax",&wparam(1));
|
|
+ &mov(&DWP(0,"ebx","",0),"edx");
|
|
+ &mov("edi",&wparam(2));
|
|
+ &mov("esi",&wparam(3));
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ &mov(&DWP(4,"ebx","",0),$R);
|
|
+ &mov("esi",&wparam(1));
|
|
+ &mov(&DWP(0,"ebx","",0),"edx");
|
|
+ &mov("edi",&wparam(2));
|
|
+ &mov("eax",&wparam(3));
|
|
+ }
|
|
+ &mov(&swtmp(2), (($enc)?"1":"0"));
|
|
+ &mov(&swtmp(1), "eax");
|
|
+ &mov(&swtmp(0), "ebx");
|
|
+ &call("des_encrypt2");
|
|
+ &mov(&swtmp(2), (($enc)?"0":"1"));
|
|
+ &mov(&swtmp(1), "edi");
|
|
+ &mov(&swtmp(0), "ebx");
|
|
+ &call("des_encrypt2");
|
|
+ &mov(&swtmp(2), (($enc)?"1":"0"));
|
|
+ &mov(&swtmp(1), "esi");
|
|
+ &mov(&swtmp(0), "ebx");
|
|
+ &call("des_encrypt2");
|
|
+
|
|
+ &stack_pop(3);
|
|
+ &mov($L,&DWP(0,"ebx","",0));
|
|
+ &mov($R,&DWP(4,"ebx","",0));
|
|
+
|
|
+ &comment("");
|
|
+ &comment("FP");
|
|
+ &FP_new($L,$R,"eax",0);
|
|
+
|
|
+ &mov(&DWP(0,"ebx","",0),"eax");
|
|
+ &mov(&DWP(4,"ebx","",0),$R);
|
|
+
|
|
+ &pop("edi");
|
|
+ &pop("esi");
|
|
+ &pop("ebp");
|
|
+ &pop("ebx");
|
|
+ &ret();
|
|
+ &function_end_B($name);
|
|
+ }
|
|
+
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/asm/readme Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,131 @@
|
|
+First up, let me say I don't like writing in assembler. It is not portable,
|
|
+dependant on the particular CPU architecture release and is generally a pig
|
|
+to debug and get right. Having said that, the x86 architecture is probably
|
|
+the most important for speed due to number of boxes and since
|
|
+it appears to be the worst architecture to to get
|
|
+good C compilers for. So due to this, I have lowered myself to do
|
|
+assembler for the inner DES routines in libdes :-).
|
|
+
|
|
+The file to implement in assembler is des_enc.c. Replace the following
|
|
+4 functions
|
|
+des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
|
|
+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
|
|
+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
|
|
+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
|
|
+
|
|
+They encrypt/decrypt the 64 bits held in 'data' using
|
|
+the 'ks' key schedules. The only difference between the 4 functions is that
|
|
+des_encrypt2() does not perform IP() or FP() on the data (this is an
|
|
+optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
|
|
+perform triple des. The triple DES routines are in here because it does
|
|
+make a big difference to have them located near the des_encrypt2 function
|
|
+at link time..
|
|
+
|
|
+Now as we all know, there are lots of different operating systems running on
|
|
+x86 boxes, and unfortunately they normally try to make sure their assembler
|
|
+formating is not the same as the other peoples.
|
|
+The 4 main formats I know of are
|
|
+Microsoft Windows 95/Windows NT
|
|
+Elf Includes Linux and FreeBSD(?).
|
|
+a.out The older Linux.
|
|
+Solaris Same as Elf but different comments :-(.
|
|
+
|
|
+Now I was not overly keen to write 4 different copies of the same code,
|
|
+so I wrote a few perl routines to output the correct assembler, given
|
|
+a target assembler type. This code is ugly and is just a hack.
|
|
+The libraries are x86unix.pl and x86ms.pl.
|
|
+des586.pl, des686.pl and des-som[23].pl are the programs to actually
|
|
+generate the assembler.
|
|
+
|
|
+So to generate elf assembler
|
|
+perl des-som3.pl elf >dx86-elf.s
|
|
+For Windows 95/NT
|
|
+perl des-som2.pl win32 >win32.asm
|
|
+
|
|
+[ update 4 Jan 1996 ]
|
|
+I have added another way to do things.
|
|
+perl des-som3.pl cpp >dx86-cpp.s
|
|
+generates a file that will be included by dx86unix.cpp when it is compiled.
|
|
+To build for elf, a.out, solaris, bsdi etc,
|
|
+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
|
|
+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
|
|
+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
|
|
+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
|
|
+This was done to cut down the number of files in the distribution.
|
|
+
|
|
+Now the ugly part. I acquired my copy of Intels
|
|
+"Optimization's For Intel's 32-Bit Processors" and found a few interesting
|
|
+things. First, the aim of the exersize is to 'extract' one byte at a time
|
|
+from a word and do an array lookup. This involves getting the byte from
|
|
+the 4 locations in the word and moving it to a new word and doing the lookup.
|
|
+The most obvious way to do this is
|
|
+xor eax, eax # clear word
|
|
+movb al, cl # get low byte
|
|
+xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
|
|
+movb al, ch # get next byte
|
|
+xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
|
|
+shr ecx 16
|
|
+which seems ok. For the pentium, this system appears to be the best.
|
|
+One has to do instruction interleaving to keep both functional units
|
|
+operating, but it is basically very efficient.
|
|
+
|
|
+Now the crunch. When a full register is used after a partial write, eg.
|
|
+mov al, cl
|
|
+xor edi, DWORD PTR 0x100+des_SP[eax]
|
|
+386 - 1 cycle stall
|
|
+486 - 1 cycle stall
|
|
+586 - 0 cycle stall
|
|
+686 - at least 7 cycle stall (page 22 of the above mentioned document).
|
|
+
|
|
+So the technique that produces the best results on a pentium, according to
|
|
+the documentation, will produce hideous results on a pentium pro.
|
|
+
|
|
+To get around this, des686.pl will generate code that is not as fast on
|
|
+a pentium, should be very good on a pentium pro.
|
|
+mov eax, ecx # copy word
|
|
+shr ecx, 8 # line up next byte
|
|
+and eax, 0fch # mask byte
|
|
+xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
|
|
+mov eax, ecx # get word
|
|
+shr ecx 8 # line up next byte
|
|
+and eax, 0fch # mask byte
|
|
+xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
|
|
+
|
|
+Due to the execution units in the pentium, this actually works quite well.
|
|
+For a pentium pro it should be very good. This is the type of output
|
|
+Visual C++ generates.
|
|
+
|
|
+There is a third option. instead of using
|
|
+mov al, ch
|
|
+which is bad on the pentium pro, one may be able to use
|
|
+movzx eax, ch
|
|
+which may not incur the partial write penalty. On the pentium,
|
|
+this instruction takes 4 cycles so is not worth using but on the
|
|
+pentium pro it appears it may be worth while. I need access to one to
|
|
+experiment :-).
|
|
+
|
|
+eric (20 Oct 1996)
|
|
+
|
|
+22 Nov 1996 - I have asked people to run the 2 different version on pentium
|
|
+pros and it appears that the intel documentation is wrong. The
|
|
+mov al,bh is still faster on a pentium pro, so just use the des586.pl
|
|
+install des686.pl
|
|
+
|
|
+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
|
|
+functions into des_enc.c because it does make a massive performance
|
|
+difference on some boxes to have the functions code located close to
|
|
+the des_encrypt2() function.
|
|
+
|
|
+9 Jan 1997 - des-som2.pl is now the correct perl script to use for
|
|
+pentiums. It contains an inner loop from
|
|
+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
|
|
+273,000 per second. He had a previous version at 250,000 and the best
|
|
+I was able to get was 203,000. The content has not changed, this is all
|
|
+due to instruction sequencing (and actual instructions choice) which is able
|
|
+to keep both functional units of the pentium going.
|
|
+We may have lost the ugly register usage restrictions when x86 went 32 bit
|
|
+but for the pentium it has been replaced by evil instruction ordering tricks.
|
|
+
|
|
+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
|
|
+raw DES at 281,000 per second on a pentium 100.
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/cbc_enc.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,135 @@
|
|
+/* crypto/des/cbc_enc.c */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+#include "des/des_locl.h"
|
|
+
|
|
+void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
|
|
+des_cblock (*input);
|
|
+des_cblock (*output);
|
|
+long length;
|
|
+des_key_schedule schedule;
|
|
+des_cblock (*ivec);
|
|
+int enc;
|
|
+ {
|
|
+ register DES_LONG tin0,tin1;
|
|
+ register DES_LONG tout0,tout1,xor0,xor1;
|
|
+ register unsigned char *in,*out;
|
|
+ register long l=length;
|
|
+ DES_LONG tin[2];
|
|
+ unsigned char *iv;
|
|
+
|
|
+ in=(unsigned char *)input;
|
|
+ out=(unsigned char *)output;
|
|
+ iv=(unsigned char *)ivec;
|
|
+
|
|
+ if (enc)
|
|
+ {
|
|
+ c2l(iv,tout0);
|
|
+ c2l(iv,tout1);
|
|
+ for (l-=8; l>=0; l-=8)
|
|
+ {
|
|
+ c2l(in,tin0);
|
|
+ c2l(in,tin1);
|
|
+ tin0^=tout0; tin[0]=tin0;
|
|
+ tin1^=tout1; tin[1]=tin1;
|
|
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
|
|
+ tout0=tin[0]; l2c(tout0,out);
|
|
+ tout1=tin[1]; l2c(tout1,out);
|
|
+ }
|
|
+ if (l != -8)
|
|
+ {
|
|
+ c2ln(in,tin0,tin1,l+8);
|
|
+ tin0^=tout0; tin[0]=tin0;
|
|
+ tin1^=tout1; tin[1]=tin1;
|
|
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
|
|
+ tout0=tin[0]; l2c(tout0,out);
|
|
+ tout1=tin[1]; l2c(tout1,out);
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ c2l(iv,xor0);
|
|
+ c2l(iv,xor1);
|
|
+ for (l-=8; l>=0; l-=8)
|
|
+ {
|
|
+ c2l(in,tin0); tin[0]=tin0;
|
|
+ c2l(in,tin1); tin[1]=tin1;
|
|
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
|
|
+ tout0=tin[0]^xor0;
|
|
+ tout1=tin[1]^xor1;
|
|
+ l2c(tout0,out);
|
|
+ l2c(tout1,out);
|
|
+ xor0=tin0;
|
|
+ xor1=tin1;
|
|
+ }
|
|
+ if (l != -8)
|
|
+ {
|
|
+ c2l(in,tin0); tin[0]=tin0;
|
|
+ c2l(in,tin1); tin[1]=tin1;
|
|
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
|
|
+ tout0=tin[0]^xor0;
|
|
+ tout1=tin[1]^xor1;
|
|
+ l2cn(tout0,tout1,out,l+8);
|
|
+ /* xor0=tin0;
|
|
+ xor1=tin1; */
|
|
+ }
|
|
+ }
|
|
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
|
|
+ tin[0]=tin[1]=0;
|
|
+ }
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/des.doc Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,505 @@
|
|
+The DES library.
|
|
+
|
|
+Please note that this library was originally written to operate with
|
|
+eBones, a version of Kerberos that had had encryption removed when it left
|
|
+the USA and then put back in. As such there are some routines that I will
|
|
+advise not using but they are still in the library for historical reasons.
|
|
+For all calls that have an 'input' and 'output' variables, they can be the
|
|
+same.
|
|
+
|
|
+This library requires the inclusion of 'des.h'.
|
|
+
|
|
+All of the encryption functions take what is called a des_key_schedule as an
|
|
+argument. A des_key_schedule is an expanded form of the des key.
|
|
+A des_key is 8 bytes of odd parity, the type used to hold the key is a
|
|
+des_cblock. A des_cblock is an array of 8 bytes, often in this library
|
|
+description I will refer to input bytes when the function specifies
|
|
+des_cblock's as input or output, this just means that the variable should
|
|
+be a multiple of 8 bytes.
|
|
+
|
|
+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
|
|
+specify decryption. The functions and global variable are as follows:
|
|
+
|
|
+int des_check_key;
|
|
+ DES keys are supposed to be odd parity. If this variable is set to
|
|
+ a non-zero value, des_set_key() will check that the key has odd
|
|
+ parity and is not one of the known weak DES keys. By default this
|
|
+ variable is turned off;
|
|
+
|
|
+void des_set_odd_parity(
|
|
+des_cblock *key );
|
|
+ This function takes a DES key (8 bytes) and sets the parity to odd.
|
|
+
|
|
+int des_is_weak_key(
|
|
+des_cblock *key );
|
|
+ This function returns a non-zero value if the DES key passed is a
|
|
+ weak, DES key. If it is a weak key, don't use it, try a different
|
|
+ one. If you are using 'random' keys, the chances of hitting a weak
|
|
+ key are 1/2^52 so it is probably not worth checking for them.
|
|
+
|
|
+int des_set_key(
|
|
+des_cblock *key,
|
|
+des_key_schedule schedule);
|
|
+ Des_set_key converts an 8 byte DES key into a des_key_schedule.
|
|
+ A des_key_schedule is an expanded form of the key which is used to
|
|
+ perform actual encryption. It can be regenerated from the DES key
|
|
+ so it only needs to be kept when encryption or decryption is about
|
|
+ to occur. Don't save or pass around des_key_schedule's since they
|
|
+ are CPU architecture dependent, DES keys are not. If des_check_key
|
|
+ is non zero, zero is returned if the key has the wrong parity or
|
|
+ the key is a weak key, else 1 is returned.
|
|
+
|
|
+int des_key_sched(
|
|
+des_cblock *key,
|
|
+des_key_schedule schedule);
|
|
+ An alternative name for des_set_key().
|
|
+
|
|
+int des_rw_mode; /* defaults to DES_PCBC_MODE */
|
|
+ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
|
|
+ This specifies the function to use in the enc_read() and enc_write()
|
|
+ functions.
|
|
+
|
|
+void des_encrypt(
|
|
+unsigned long *data,
|
|
+des_key_schedule ks,
|
|
+int enc);
|
|
+ This is the DES encryption function that gets called by just about
|
|
+ every other DES routine in the library. You should not use this
|
|
+ function except to implement 'modes' of DES. I say this because the
|
|
+ functions that call this routine do the conversion from 'char *' to
|
|
+ long, and this needs to be done to make sure 'non-aligned' memory
|
|
+ access do not occur. The characters are loaded 'little endian',
|
|
+ have a look at my source code for more details on how I use this
|
|
+ function.
|
|
+ Data is a pointer to 2 unsigned long's and ks is the
|
|
+ des_key_schedule to use. enc, is non zero specifies encryption,
|
|
+ zero if decryption.
|
|
+
|
|
+void des_encrypt2(
|
|
+unsigned long *data,
|
|
+des_key_schedule ks,
|
|
+int enc);
|
|
+ This functions is the same as des_encrypt() except that the DES
|
|
+ initial permutation (IP) and final permutation (FP) have been left
|
|
+ out. As for des_encrypt(), you should not use this function.
|
|
+ It is used by the routines in my library that implement triple DES.
|
|
+ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
|
|
+ as des_encrypt() des_encrypt() des_encrypt() except faster :-).
|
|
+
|
|
+void des_ecb_encrypt(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+des_key_schedule ks,
|
|
+int enc);
|
|
+ This is the basic Electronic Code Book form of DES, the most basic
|
|
+ form. Input is encrypted into output using the key represented by
|
|
+ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
|
|
+ decryption occurs. Input is 8 bytes long and output is 8 bytes.
|
|
+ (the des_cblock structure is 8 chars).
|
|
+
|
|
+void des_ecb3_encrypt(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+des_key_schedule ks1,
|
|
+des_key_schedule ks2,
|
|
+des_key_schedule ks3,
|
|
+int enc);
|
|
+ This is the 3 key EDE mode of ECB DES. What this means is that
|
|
+ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
|
|
+ then encrypted again with ks3, before being put into output;
|
|
+ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
|
|
+ that only takes 2 des_key_schedules that implements,
|
|
+ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
|
|
+
|
|
+void des_cbc_encrypt(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+long length,
|
|
+des_key_schedule ks,
|
|
+des_cblock *ivec,
|
|
+int enc);
|
|
+ This routine implements DES in Cipher Block Chaining mode.
|
|
+ Input, which should be a multiple of 8 bytes is encrypted
|
|
+ (or decrypted) to output which will also be a multiple of 8 bytes.
|
|
+ The number of bytes is in length (and from what I've said above,
|
|
+ should be a multiple of 8). If length is not a multiple of 8, I'm
|
|
+ not being held responsible :-). ivec is the initialisation vector.
|
|
+ This function does not modify this variable. To correctly implement
|
|
+ cbc mode, you need to do one of 2 things; copy the last 8 bytes of
|
|
+ cipher text for use as the next ivec in your application,
|
|
+ or use des_ncbc_encrypt().
|
|
+ Only this routine has this problem with updating the ivec, all
|
|
+ other routines that are implementing cbc mode update ivec.
|
|
+
|
|
+void des_ncbc_encrypt(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+long length,
|
|
+des_key_schedule sk,
|
|
+des_cblock *ivec,
|
|
+int enc);
|
|
+ For historical reasons, des_cbc_encrypt() did not update the
|
|
+ ivec with the value requires so that subsequent calls to
|
|
+ des_cbc_encrypt() would 'chain'. This was needed so that the same
|
|
+ 'length' values would not need to be used when decrypting.
|
|
+ des_ncbc_encrypt() does the right thing. It is the same as
|
|
+ des_cbc_encrypt accept that ivec is updates with the correct value
|
|
+ to pass in subsequent calls to des_ncbc_encrypt(). I advise using
|
|
+ des_ncbc_encrypt() instead of des_cbc_encrypt();
|
|
+
|
|
+void des_xcbc_encrypt(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+long length,
|
|
+des_key_schedule sk,
|
|
+des_cblock *ivec,
|
|
+des_cblock *inw,
|
|
+des_cblock *outw,
|
|
+int enc);
|
|
+ This is RSA's DESX mode of DES. It uses inw and outw to
|
|
+ 'whiten' the encryption. inw and outw are secret (unlike the iv)
|
|
+ and are as such, part of the key. So the key is sort of 24 bytes.
|
|
+ This is much better than cbc des.
|
|
+
|
|
+void des_3cbc_encrypt(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+long length,
|
|
+des_key_schedule sk1,
|
|
+des_key_schedule sk2,
|
|
+des_cblock *ivec1,
|
|
+des_cblock *ivec2,
|
|
+int enc);
|
|
+ This function is flawed, do not use it. I have left it in the
|
|
+ library because it is used in my des(1) program and will function
|
|
+ correctly when used by des(1). If I removed the function, people
|
|
+ could end up unable to decrypt files.
|
|
+ This routine implements outer triple cbc encryption using 2 ks and
|
|
+ 2 ivec's. Use des_ede2_cbc_encrypt() instead.
|
|
+
|
|
+void des_ede3_cbc_encrypt(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+long length,
|
|
+des_key_schedule ks1,
|
|
+des_key_schedule ks2,
|
|
+des_key_schedule ks3,
|
|
+des_cblock *ivec,
|
|
+int enc);
|
|
+ This function implements inner triple CBC DES encryption with 3
|
|
+ keys. What this means is that each 'DES' operation
|
|
+ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
|
|
+ Again, this is cbc mode so an ivec is requires.
|
|
+ This mode is used by SSL.
|
|
+ There is also a des_ede2_cbc_encrypt() that only uses 2
|
|
+ des_key_schedule's, the first being reused for the final
|
|
+ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
|
|
+ is used by the RSAref library.
|
|
+
|
|
+void des_pcbc_encrypt(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+long length,
|
|
+des_key_schedule ks,
|
|
+des_cblock *ivec,
|
|
+int enc);
|
|
+ This is Propagating Cipher Block Chaining mode of DES. It is used
|
|
+ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
|
|
+
|
|
+void des_cfb_encrypt(
|
|
+unsigned char *in,
|
|
+unsigned char *out,
|
|
+int numbits,
|
|
+long length,
|
|
+des_key_schedule ks,
|
|
+des_cblock *ivec,
|
|
+int enc);
|
|
+ Cipher Feedback Back mode of DES. This implementation 'feeds back'
|
|
+ in numbit blocks. The input (and output) is in multiples of numbits
|
|
+ bits. numbits should to be a multiple of 8 bits. Length is the
|
|
+ number of bytes input. If numbits is not a multiple of 8 bits,
|
|
+ the extra bits in the bytes will be considered padding. So if
|
|
+ numbits is 12, for each 2 input bytes, the 4 high bits of the
|
|
+ second byte will be ignored. So to encode 72 bits when using
|
|
+ a numbits of 12 take 12 bytes. To encode 72 bits when using
|
|
+ numbits of 9 will take 16 bytes. To encode 80 bits when using
|
|
+ numbits of 16 will take 10 bytes. etc, etc. This padding will
|
|
+ apply to both input and output.
|
|
+
|
|
+
|
|
+void des_cfb64_encrypt(
|
|
+unsigned char *in,
|
|
+unsigned char *out,
|
|
+long length,
|
|
+des_key_schedule ks,
|
|
+des_cblock *ivec,
|
|
+int *num,
|
|
+int enc);
|
|
+ This is one of the more useful functions in this DES library, it
|
|
+ implements CFB mode of DES with 64bit feedback. Why is this
|
|
+ useful you ask? Because this routine will allow you to encrypt an
|
|
+ arbitrary number of bytes, no 8 byte padding. Each call to this
|
|
+ routine will encrypt the input bytes to output and then update ivec
|
|
+ and num. num contains 'how far' we are though ivec. If this does
|
|
+ not make much sense, read more about cfb mode of DES :-).
|
|
+
|
|
+void des_ede3_cfb64_encrypt(
|
|
+unsigned char *in,
|
|
+unsigned char *out,
|
|
+long length,
|
|
+des_key_schedule ks1,
|
|
+des_key_schedule ks2,
|
|
+des_key_schedule ks3,
|
|
+des_cblock *ivec,
|
|
+int *num,
|
|
+int enc);
|
|
+ Same as des_cfb64_encrypt() accept that the DES operation is
|
|
+ triple DES. As usual, there is a macro for
|
|
+ des_ede2_cfb64_encrypt() which reuses ks1.
|
|
+
|
|
+void des_ofb_encrypt(
|
|
+unsigned char *in,
|
|
+unsigned char *out,
|
|
+int numbits,
|
|
+long length,
|
|
+des_key_schedule ks,
|
|
+des_cblock *ivec);
|
|
+ This is a implementation of Output Feed Back mode of DES. It is
|
|
+ the same as des_cfb_encrypt() in that numbits is the size of the
|
|
+ units dealt with during input and output (in bits).
|
|
+
|
|
+void des_ofb64_encrypt(
|
|
+unsigned char *in,
|
|
+unsigned char *out,
|
|
+long length,
|
|
+des_key_schedule ks,
|
|
+des_cblock *ivec,
|
|
+int *num);
|
|
+ The same as des_cfb64_encrypt() except that it is Output Feed Back
|
|
+ mode.
|
|
+
|
|
+void des_ede3_ofb64_encrypt(
|
|
+unsigned char *in,
|
|
+unsigned char *out,
|
|
+long length,
|
|
+des_key_schedule ks1,
|
|
+des_key_schedule ks2,
|
|
+des_key_schedule ks3,
|
|
+des_cblock *ivec,
|
|
+int *num);
|
|
+ Same as des_ofb64_encrypt() accept that the DES operation is
|
|
+ triple DES. As usual, there is a macro for
|
|
+ des_ede2_ofb64_encrypt() which reuses ks1.
|
|
+
|
|
+int des_read_pw_string(
|
|
+char *buf,
|
|
+int length,
|
|
+char *prompt,
|
|
+int verify);
|
|
+ This routine is used to get a password from the terminal with echo
|
|
+ turned off. Buf is where the string will end up and length is the
|
|
+ size of buf. Prompt is a string presented to the 'user' and if
|
|
+ verify is set, the key is asked for twice and unless the 2 copies
|
|
+ match, an error is returned. A return code of -1 indicates a
|
|
+ system error, 1 failure due to use interaction, and 0 is success.
|
|
+
|
|
+unsigned long des_cbc_cksum(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+long length,
|
|
+des_key_schedule ks,
|
|
+des_cblock *ivec);
|
|
+ This function produces an 8 byte checksum from input that it puts in
|
|
+ output and returns the last 4 bytes as a long. The checksum is
|
|
+ generated via cbc mode of DES in which only the last 8 byes are
|
|
+ kept. I would recommend not using this function but instead using
|
|
+ the EVP_Digest routines, or at least using MD5 or SHA. This
|
|
+ function is used by Kerberos v4 so that is why it stays in the
|
|
+ library.
|
|
+
|
|
+char *des_fcrypt(
|
|
+const char *buf,
|
|
+const char *salt
|
|
+char *ret);
|
|
+ This is my fast version of the unix crypt(3) function. This version
|
|
+ takes only a small amount of space relative to other fast
|
|
+ crypt() implementations. This is different to the normal crypt
|
|
+ in that the third parameter is the buffer that the return value
|
|
+ is written into. It needs to be at least 14 bytes long. This
|
|
+ function is thread safe, unlike the normal crypt.
|
|
+
|
|
+char *crypt(
|
|
+const char *buf,
|
|
+const char *salt);
|
|
+ This function calls des_fcrypt() with a static array passed as the
|
|
+ third parameter. This emulates the normal non-thread safe semantics
|
|
+ of crypt(3).
|
|
+
|
|
+void des_string_to_key(
|
|
+char *str,
|
|
+des_cblock *key);
|
|
+ This function takes str and converts it into a DES key. I would
|
|
+ recommend using MD5 instead and use the first 8 bytes of output.
|
|
+ When I wrote the first version of these routines back in 1990, MD5
|
|
+ did not exist but I feel these routines are still sound. This
|
|
+ routines is compatible with the one in MIT's libdes.
|
|
+
|
|
+void des_string_to_2keys(
|
|
+char *str,
|
|
+des_cblock *key1,
|
|
+des_cblock *key2);
|
|
+ This function takes str and converts it into 2 DES keys.
|
|
+ I would recommend using MD5 and using the 16 bytes as the 2 keys.
|
|
+ I have nothing against these 2 'string_to_key' routines, it's just
|
|
+ that if you say that your encryption key is generated by using the
|
|
+ 16 bytes of an MD5 hash, every-one knows how you generated your
|
|
+ keys.
|
|
+
|
|
+int des_read_password(
|
|
+des_cblock *key,
|
|
+char *prompt,
|
|
+int verify);
|
|
+ This routine combines des_read_pw_string() with des_string_to_key().
|
|
+
|
|
+int des_read_2passwords(
|
|
+des_cblock *key1,
|
|
+des_cblock *key2,
|
|
+char *prompt,
|
|
+int verify);
|
|
+ This routine combines des_read_pw_string() with des_string_to_2key().
|
|
+
|
|
+void des_random_seed(
|
|
+des_cblock key);
|
|
+ This routine sets a starting point for des_random_key().
|
|
+
|
|
+void des_random_key(
|
|
+des_cblock ret);
|
|
+ This function return a random key. Make sure to 'seed' the random
|
|
+ number generator (with des_random_seed()) before using this function.
|
|
+ I personally now use a MD5 based random number system.
|
|
+
|
|
+int des_enc_read(
|
|
+int fd,
|
|
+char *buf,
|
|
+int len,
|
|
+des_key_schedule ks,
|
|
+des_cblock *iv);
|
|
+ This function will write to a file descriptor the encrypted data
|
|
+ from buf. This data will be preceded by a 4 byte 'byte count' and
|
|
+ will be padded out to 8 bytes. The encryption is either CBC of
|
|
+ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
|
|
+ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
|
|
+ DES_PCBC_MODE.
|
|
+
|
|
+int des_enc_write(
|
|
+int fd,
|
|
+char *buf,
|
|
+int len,
|
|
+des_key_schedule ks,
|
|
+des_cblock *iv);
|
|
+ This routines read stuff written by des_enc_read() and decrypts it.
|
|
+ I have used these routines quite a lot but I don't believe they are
|
|
+ suitable for non-blocking io. If you are after a full
|
|
+ authentication/encryption over networks, have a look at SSL instead.
|
|
+
|
|
+unsigned long des_quad_cksum(
|
|
+des_cblock *input,
|
|
+des_cblock *output,
|
|
+long length,
|
|
+int out_count,
|
|
+des_cblock *seed);
|
|
+ This is a function from Kerberos v4 that is not anything to do with
|
|
+ DES but was needed. It is a cksum that is quicker to generate than
|
|
+ des_cbc_cksum(); I personally would use MD5 routines now.
|
|
+=====
|
|
+Modes of DES
|
|
+Quite a bit of the following information has been taken from
|
|
+ AS 2805.5.2
|
|
+ Australian Standard
|
|
+ Electronic funds transfer - Requirements for interfaces,
|
|
+ Part 5.2: Modes of operation for an n-bit block cipher algorithm
|
|
+ Appendix A
|
|
+
|
|
+There are several different modes in which DES can be used, they are
|
|
+as follows.
|
|
+
|
|
+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
|
|
+- 64 bits are enciphered at a time.
|
|
+- The order of the blocks can be rearranged without detection.
|
|
+- The same plaintext block always produces the same ciphertext block
|
|
+ (for the same key) making it vulnerable to a 'dictionary attack'.
|
|
+- An error will only affect one ciphertext block.
|
|
+
|
|
+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
|
|
+- a multiple of 64 bits are enciphered at a time.
|
|
+- The CBC mode produces the same ciphertext whenever the same
|
|
+ plaintext is encrypted using the same key and starting variable.
|
|
+- The chaining operation makes the ciphertext blocks dependent on the
|
|
+ current and all preceding plaintext blocks and therefore blocks can not
|
|
+ be rearranged.
|
|
+- The use of different starting variables prevents the same plaintext
|
|
+ enciphering to the same ciphertext.
|
|
+- An error will affect the current and the following ciphertext blocks.
|
|
+
|
|
+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
|
|
+- a number of bits (j) <= 64 are enciphered at a time.
|
|
+- The CFB mode produces the same ciphertext whenever the same
|
|
+ plaintext is encrypted using the same key and starting variable.
|
|
+- The chaining operation makes the ciphertext variables dependent on the
|
|
+ current and all preceding variables and therefore j-bit variables are
|
|
+ chained together and can not be rearranged.
|
|
+- The use of different starting variables prevents the same plaintext
|
|
+ enciphering to the same ciphertext.
|
|
+- The strength of the CFB mode depends on the size of k (maximal if
|
|
+ j == k). In my implementation this is always the case.
|
|
+- Selection of a small value for j will require more cycles through
|
|
+ the encipherment algorithm per unit of plaintext and thus cause
|
|
+ greater processing overheads.
|
|
+- Only multiples of j bits can be enciphered.
|
|
+- An error will affect the current and the following ciphertext variables.
|
|
+
|
|
+Output Feedback Mode (OFB) (des_ofb_encrypt())
|
|
+- a number of bits (j) <= 64 are enciphered at a time.
|
|
+- The OFB mode produces the same ciphertext whenever the same
|
|
+ plaintext enciphered using the same key and starting variable. More
|
|
+ over, in the OFB mode the same key stream is produced when the same
|
|
+ key and start variable are used. Consequently, for security reasons
|
|
+ a specific start variable should be used only once for a given key.
|
|
+- The absence of chaining makes the OFB more vulnerable to specific attacks.
|
|
+- The use of different start variables values prevents the same
|
|
+ plaintext enciphering to the same ciphertext, by producing different
|
|
+ key streams.
|
|
+- Selection of a small value for j will require more cycles through
|
|
+ the encipherment algorithm per unit of plaintext and thus cause
|
|
+ greater processing overheads.
|
|
+- Only multiples of j bits can be enciphered.
|
|
+- OFB mode of operation does not extend ciphertext errors in the
|
|
+ resultant plaintext output. Every bit error in the ciphertext causes
|
|
+ only one bit to be in error in the deciphered plaintext.
|
|
+- OFB mode is not self-synchronising. If the two operation of
|
|
+ encipherment and decipherment get out of synchronism, the system needs
|
|
+ to be re-initialised.
|
|
+- Each re-initialisation should use a value of the start variable
|
|
+ different from the start variable values used before with the same
|
|
+ key. The reason for this is that an identical bit stream would be
|
|
+ produced each time from the same parameters. This would be
|
|
+ susceptible to a ' known plaintext' attack.
|
|
+
|
|
+Triple ECB Mode (des_ecb3_encrypt())
|
|
+- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
|
|
+- As for ECB encryption but increases the key length to 168 bits.
|
|
+ There are theoretic attacks that can be used that make the effective
|
|
+ key length 112 bits, but this attack also requires 2^56 blocks of
|
|
+ memory, not very likely, even for the NSA.
|
|
+- If both keys are the same it is equivalent to encrypting once with
|
|
+ just one key.
|
|
+- If the first and last key are the same, the key length is 112 bits.
|
|
+ There are attacks that could reduce the key space to 55 bit's but it
|
|
+ requires 2^56 blocks of memory.
|
|
+- If all 3 keys are the same, this is effectively the same as normal
|
|
+ ecb mode.
|
|
+
|
|
+Triple CBC Mode (des_ede3_cbc_encrypt())
|
|
+- Encrypt with key1, decrypt with key2 and then encrypt with key3.
|
|
+- As for CBC encryption but increases the key length to 168 bits with
|
|
+ the same restrictions as for triple ecb mode.
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/des_enc.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,502 @@
|
|
+/* crypto/des/des_enc.c */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+#include "des/des_locl.h"
|
|
+
|
|
+void des_encrypt(data, ks, enc)
|
|
+DES_LONG *data;
|
|
+des_key_schedule ks;
|
|
+int enc;
|
|
+ {
|
|
+ register DES_LONG l,r,t,u;
|
|
+#ifdef DES_PTR
|
|
+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
|
|
+#endif
|
|
+#ifndef DES_UNROLL
|
|
+ register int i;
|
|
+#endif
|
|
+ register DES_LONG *s;
|
|
+
|
|
+ r=data[0];
|
|
+ l=data[1];
|
|
+
|
|
+ IP(r,l);
|
|
+ /* Things have been modified so that the initial rotate is
|
|
+ * done outside the loop. This required the
|
|
+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
|
|
+ * One perl script later and things have a 5% speed up on a sparc2.
|
|
+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
|
|
+ * for pointing this out. */
|
|
+ /* clear the top bits on machines with 8byte longs */
|
|
+ /* shift left by 2 */
|
|
+ r=ROTATE(r,29)&0xffffffffL;
|
|
+ l=ROTATE(l,29)&0xffffffffL;
|
|
+
|
|
+ s=(DES_LONG *)ks;
|
|
+ /* I don't know if it is worth the effort of loop unrolling the
|
|
+ * inner loop */
|
|
+ if (enc)
|
|
+ {
|
|
+#ifdef DES_UNROLL
|
|
+ D_ENCRYPT(l,r, 0); /* 1 */
|
|
+ D_ENCRYPT(r,l, 2); /* 2 */
|
|
+ D_ENCRYPT(l,r, 4); /* 3 */
|
|
+ D_ENCRYPT(r,l, 6); /* 4 */
|
|
+ D_ENCRYPT(l,r, 8); /* 5 */
|
|
+ D_ENCRYPT(r,l,10); /* 6 */
|
|
+ D_ENCRYPT(l,r,12); /* 7 */
|
|
+ D_ENCRYPT(r,l,14); /* 8 */
|
|
+ D_ENCRYPT(l,r,16); /* 9 */
|
|
+ D_ENCRYPT(r,l,18); /* 10 */
|
|
+ D_ENCRYPT(l,r,20); /* 11 */
|
|
+ D_ENCRYPT(r,l,22); /* 12 */
|
|
+ D_ENCRYPT(l,r,24); /* 13 */
|
|
+ D_ENCRYPT(r,l,26); /* 14 */
|
|
+ D_ENCRYPT(l,r,28); /* 15 */
|
|
+ D_ENCRYPT(r,l,30); /* 16 */
|
|
+#else
|
|
+ for (i=0; i<32; i+=8)
|
|
+ {
|
|
+ D_ENCRYPT(l,r,i+0); /* 1 */
|
|
+ D_ENCRYPT(r,l,i+2); /* 2 */
|
|
+ D_ENCRYPT(l,r,i+4); /* 3 */
|
|
+ D_ENCRYPT(r,l,i+6); /* 4 */
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+#ifdef DES_UNROLL
|
|
+ D_ENCRYPT(l,r,30); /* 16 */
|
|
+ D_ENCRYPT(r,l,28); /* 15 */
|
|
+ D_ENCRYPT(l,r,26); /* 14 */
|
|
+ D_ENCRYPT(r,l,24); /* 13 */
|
|
+ D_ENCRYPT(l,r,22); /* 12 */
|
|
+ D_ENCRYPT(r,l,20); /* 11 */
|
|
+ D_ENCRYPT(l,r,18); /* 10 */
|
|
+ D_ENCRYPT(r,l,16); /* 9 */
|
|
+ D_ENCRYPT(l,r,14); /* 8 */
|
|
+ D_ENCRYPT(r,l,12); /* 7 */
|
|
+ D_ENCRYPT(l,r,10); /* 6 */
|
|
+ D_ENCRYPT(r,l, 8); /* 5 */
|
|
+ D_ENCRYPT(l,r, 6); /* 4 */
|
|
+ D_ENCRYPT(r,l, 4); /* 3 */
|
|
+ D_ENCRYPT(l,r, 2); /* 2 */
|
|
+ D_ENCRYPT(r,l, 0); /* 1 */
|
|
+#else
|
|
+ for (i=30; i>0; i-=8)
|
|
+ {
|
|
+ D_ENCRYPT(l,r,i-0); /* 16 */
|
|
+ D_ENCRYPT(r,l,i-2); /* 15 */
|
|
+ D_ENCRYPT(l,r,i-4); /* 14 */
|
|
+ D_ENCRYPT(r,l,i-6); /* 13 */
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ /* rotate and clear the top bits on machines with 8byte longs */
|
|
+ l=ROTATE(l,3)&0xffffffffL;
|
|
+ r=ROTATE(r,3)&0xffffffffL;
|
|
+
|
|
+ FP(r,l);
|
|
+ data[0]=l;
|
|
+ data[1]=r;
|
|
+ l=r=t=u=0;
|
|
+ }
|
|
+
|
|
+void des_encrypt2(data, ks, enc)
|
|
+DES_LONG *data;
|
|
+des_key_schedule ks;
|
|
+int enc;
|
|
+ {
|
|
+ register DES_LONG l,r,t,u;
|
|
+#ifdef DES_PTR
|
|
+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
|
|
+#endif
|
|
+#ifndef DES_UNROLL
|
|
+ register int i;
|
|
+#endif
|
|
+ register DES_LONG *s;
|
|
+
|
|
+ r=data[0];
|
|
+ l=data[1];
|
|
+
|
|
+ /* Things have been modified so that the initial rotate is
|
|
+ * done outside the loop. This required the
|
|
+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
|
|
+ * One perl script later and things have a 5% speed up on a sparc2.
|
|
+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
|
|
+ * for pointing this out. */
|
|
+ /* clear the top bits on machines with 8byte longs */
|
|
+ r=ROTATE(r,29)&0xffffffffL;
|
|
+ l=ROTATE(l,29)&0xffffffffL;
|
|
+
|
|
+ s=(DES_LONG *)ks;
|
|
+ /* I don't know if it is worth the effort of loop unrolling the
|
|
+ * inner loop */
|
|
+ if (enc)
|
|
+ {
|
|
+#ifdef DES_UNROLL
|
|
+ D_ENCRYPT(l,r, 0); /* 1 */
|
|
+ D_ENCRYPT(r,l, 2); /* 2 */
|
|
+ D_ENCRYPT(l,r, 4); /* 3 */
|
|
+ D_ENCRYPT(r,l, 6); /* 4 */
|
|
+ D_ENCRYPT(l,r, 8); /* 5 */
|
|
+ D_ENCRYPT(r,l,10); /* 6 */
|
|
+ D_ENCRYPT(l,r,12); /* 7 */
|
|
+ D_ENCRYPT(r,l,14); /* 8 */
|
|
+ D_ENCRYPT(l,r,16); /* 9 */
|
|
+ D_ENCRYPT(r,l,18); /* 10 */
|
|
+ D_ENCRYPT(l,r,20); /* 11 */
|
|
+ D_ENCRYPT(r,l,22); /* 12 */
|
|
+ D_ENCRYPT(l,r,24); /* 13 */
|
|
+ D_ENCRYPT(r,l,26); /* 14 */
|
|
+ D_ENCRYPT(l,r,28); /* 15 */
|
|
+ D_ENCRYPT(r,l,30); /* 16 */
|
|
+#else
|
|
+ for (i=0; i<32; i+=8)
|
|
+ {
|
|
+ D_ENCRYPT(l,r,i+0); /* 1 */
|
|
+ D_ENCRYPT(r,l,i+2); /* 2 */
|
|
+ D_ENCRYPT(l,r,i+4); /* 3 */
|
|
+ D_ENCRYPT(r,l,i+6); /* 4 */
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+#ifdef DES_UNROLL
|
|
+ D_ENCRYPT(l,r,30); /* 16 */
|
|
+ D_ENCRYPT(r,l,28); /* 15 */
|
|
+ D_ENCRYPT(l,r,26); /* 14 */
|
|
+ D_ENCRYPT(r,l,24); /* 13 */
|
|
+ D_ENCRYPT(l,r,22); /* 12 */
|
|
+ D_ENCRYPT(r,l,20); /* 11 */
|
|
+ D_ENCRYPT(l,r,18); /* 10 */
|
|
+ D_ENCRYPT(r,l,16); /* 9 */
|
|
+ D_ENCRYPT(l,r,14); /* 8 */
|
|
+ D_ENCRYPT(r,l,12); /* 7 */
|
|
+ D_ENCRYPT(l,r,10); /* 6 */
|
|
+ D_ENCRYPT(r,l, 8); /* 5 */
|
|
+ D_ENCRYPT(l,r, 6); /* 4 */
|
|
+ D_ENCRYPT(r,l, 4); /* 3 */
|
|
+ D_ENCRYPT(l,r, 2); /* 2 */
|
|
+ D_ENCRYPT(r,l, 0); /* 1 */
|
|
+#else
|
|
+ for (i=30; i>0; i-=8)
|
|
+ {
|
|
+ D_ENCRYPT(l,r,i-0); /* 16 */
|
|
+ D_ENCRYPT(r,l,i-2); /* 15 */
|
|
+ D_ENCRYPT(l,r,i-4); /* 14 */
|
|
+ D_ENCRYPT(r,l,i-6); /* 13 */
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+ /* rotate and clear the top bits on machines with 8byte longs */
|
|
+ data[0]=ROTATE(l,3)&0xffffffffL;
|
|
+ data[1]=ROTATE(r,3)&0xffffffffL;
|
|
+ l=r=t=u=0;
|
|
+ }
|
|
+
|
|
+void des_encrypt3(data,ks1,ks2,ks3)
|
|
+DES_LONG *data;
|
|
+des_key_schedule ks1;
|
|
+des_key_schedule ks2;
|
|
+des_key_schedule ks3;
|
|
+ {
|
|
+ register DES_LONG l,r;
|
|
+
|
|
+ l=data[0];
|
|
+ r=data[1];
|
|
+ IP(l,r);
|
|
+ data[0]=l;
|
|
+ data[1]=r;
|
|
+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
|
|
+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
|
|
+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
|
|
+ l=data[0];
|
|
+ r=data[1];
|
|
+ FP(r,l);
|
|
+ data[0]=l;
|
|
+ data[1]=r;
|
|
+ }
|
|
+
|
|
+void des_decrypt3(data,ks1,ks2,ks3)
|
|
+DES_LONG *data;
|
|
+des_key_schedule ks1;
|
|
+des_key_schedule ks2;
|
|
+des_key_schedule ks3;
|
|
+ {
|
|
+ register DES_LONG l,r;
|
|
+
|
|
+ l=data[0];
|
|
+ r=data[1];
|
|
+ IP(l,r);
|
|
+ data[0]=l;
|
|
+ data[1]=r;
|
|
+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
|
|
+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
|
|
+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
|
|
+ l=data[0];
|
|
+ r=data[1];
|
|
+ FP(r,l);
|
|
+ data[0]=l;
|
|
+ data[1]=r;
|
|
+ }
|
|
+
|
|
+#ifndef DES_DEFAULT_OPTIONS
|
|
+
|
|
+void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
|
|
+des_cblock (*input);
|
|
+des_cblock (*output);
|
|
+long length;
|
|
+des_key_schedule schedule;
|
|
+des_cblock (*ivec);
|
|
+int enc;
|
|
+ {
|
|
+ register DES_LONG tin0,tin1;
|
|
+ register DES_LONG tout0,tout1,xor0,xor1;
|
|
+ register unsigned char *in,*out;
|
|
+ register long l=length;
|
|
+ DES_LONG tin[2];
|
|
+ unsigned char *iv;
|
|
+
|
|
+ in=(unsigned char *)input;
|
|
+ out=(unsigned char *)output;
|
|
+ iv=(unsigned char *)ivec;
|
|
+
|
|
+ if (enc)
|
|
+ {
|
|
+ c2l(iv,tout0);
|
|
+ c2l(iv,tout1);
|
|
+ for (l-=8; l>=0; l-=8)
|
|
+ {
|
|
+ c2l(in,tin0);
|
|
+ c2l(in,tin1);
|
|
+ tin0^=tout0; tin[0]=tin0;
|
|
+ tin1^=tout1; tin[1]=tin1;
|
|
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
|
|
+ tout0=tin[0]; l2c(tout0,out);
|
|
+ tout1=tin[1]; l2c(tout1,out);
|
|
+ }
|
|
+ if (l != -8)
|
|
+ {
|
|
+ c2ln(in,tin0,tin1,l+8);
|
|
+ tin0^=tout0; tin[0]=tin0;
|
|
+ tin1^=tout1; tin[1]=tin1;
|
|
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
|
|
+ tout0=tin[0]; l2c(tout0,out);
|
|
+ tout1=tin[1]; l2c(tout1,out);
|
|
+ }
|
|
+ iv=(unsigned char *)ivec;
|
|
+ l2c(tout0,iv);
|
|
+ l2c(tout1,iv);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ c2l(iv,xor0);
|
|
+ c2l(iv,xor1);
|
|
+ for (l-=8; l>=0; l-=8)
|
|
+ {
|
|
+ c2l(in,tin0); tin[0]=tin0;
|
|
+ c2l(in,tin1); tin[1]=tin1;
|
|
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
|
|
+ tout0=tin[0]^xor0;
|
|
+ tout1=tin[1]^xor1;
|
|
+ l2c(tout0,out);
|
|
+ l2c(tout1,out);
|
|
+ xor0=tin0;
|
|
+ xor1=tin1;
|
|
+ }
|
|
+ if (l != -8)
|
|
+ {
|
|
+ c2l(in,tin0); tin[0]=tin0;
|
|
+ c2l(in,tin1); tin[1]=tin1;
|
|
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
|
|
+ tout0=tin[0]^xor0;
|
|
+ tout1=tin[1]^xor1;
|
|
+ l2cn(tout0,tout1,out,l+8);
|
|
+ xor0=tin0;
|
|
+ xor1=tin1;
|
|
+ }
|
|
+
|
|
+ iv=(unsigned char *)ivec;
|
|
+ l2c(xor0,iv);
|
|
+ l2c(xor1,iv);
|
|
+ }
|
|
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
|
|
+ tin[0]=tin[1]=0;
|
|
+ }
|
|
+
|
|
+void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
|
|
+des_cblock (*input);
|
|
+des_cblock (*output);
|
|
+long length;
|
|
+des_key_schedule ks1;
|
|
+des_key_schedule ks2;
|
|
+des_key_schedule ks3;
|
|
+des_cblock (*ivec);
|
|
+int enc;
|
|
+ {
|
|
+ register DES_LONG tin0,tin1;
|
|
+ register DES_LONG tout0,tout1,xor0,xor1;
|
|
+ register unsigned char *in,*out;
|
|
+ register long l=length;
|
|
+ DES_LONG tin[2];
|
|
+ unsigned char *iv;
|
|
+
|
|
+ in=(unsigned char *)input;
|
|
+ out=(unsigned char *)output;
|
|
+ iv=(unsigned char *)ivec;
|
|
+
|
|
+ if (enc)
|
|
+ {
|
|
+ c2l(iv,tout0);
|
|
+ c2l(iv,tout1);
|
|
+ for (l-=8; l>=0; l-=8)
|
|
+ {
|
|
+ c2l(in,tin0);
|
|
+ c2l(in,tin1);
|
|
+ tin0^=tout0;
|
|
+ tin1^=tout1;
|
|
+
|
|
+ tin[0]=tin0;
|
|
+ tin[1]=tin1;
|
|
+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
|
|
+ tout0=tin[0];
|
|
+ tout1=tin[1];
|
|
+
|
|
+ l2c(tout0,out);
|
|
+ l2c(tout1,out);
|
|
+ }
|
|
+ if (l != -8)
|
|
+ {
|
|
+ c2ln(in,tin0,tin1,l+8);
|
|
+ tin0^=tout0;
|
|
+ tin1^=tout1;
|
|
+
|
|
+ tin[0]=tin0;
|
|
+ tin[1]=tin1;
|
|
+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
|
|
+ tout0=tin[0];
|
|
+ tout1=tin[1];
|
|
+
|
|
+ l2c(tout0,out);
|
|
+ l2c(tout1,out);
|
|
+ }
|
|
+ iv=(unsigned char *)ivec;
|
|
+ l2c(tout0,iv);
|
|
+ l2c(tout1,iv);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ register DES_LONG t0,t1;
|
|
+
|
|
+ c2l(iv,xor0);
|
|
+ c2l(iv,xor1);
|
|
+ for (l-=8; l>=0; l-=8)
|
|
+ {
|
|
+ c2l(in,tin0);
|
|
+ c2l(in,tin1);
|
|
+
|
|
+ t0=tin0;
|
|
+ t1=tin1;
|
|
+
|
|
+ tin[0]=tin0;
|
|
+ tin[1]=tin1;
|
|
+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
|
|
+ tout0=tin[0];
|
|
+ tout1=tin[1];
|
|
+
|
|
+ tout0^=xor0;
|
|
+ tout1^=xor1;
|
|
+ l2c(tout0,out);
|
|
+ l2c(tout1,out);
|
|
+ xor0=t0;
|
|
+ xor1=t1;
|
|
+ }
|
|
+ if (l != -8)
|
|
+ {
|
|
+ c2l(in,tin0);
|
|
+ c2l(in,tin1);
|
|
+
|
|
+ t0=tin0;
|
|
+ t1=tin1;
|
|
+
|
|
+ tin[0]=tin0;
|
|
+ tin[1]=tin1;
|
|
+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
|
|
+ tout0=tin[0];
|
|
+ tout1=tin[1];
|
|
+
|
|
+ tout0^=xor0;
|
|
+ tout1^=xor1;
|
|
+ l2cn(tout0,tout1,out,l+8);
|
|
+ xor0=t0;
|
|
+ xor1=t1;
|
|
+ }
|
|
+
|
|
+ iv=(unsigned char *)ivec;
|
|
+ l2c(xor0,iv);
|
|
+ l2c(xor1,iv);
|
|
+ }
|
|
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
|
|
+ tin[0]=tin[1]=0;
|
|
+ }
|
|
+
|
|
+#endif /* DES_DEFAULT_OPTIONS */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/des_opts.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,620 @@
|
|
+/* crypto/des/des_opts.c */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
|
|
+ * This is for machines with 64k code segment size restrictions. */
|
|
+
|
|
+#ifndef MSDOS
|
|
+#define TIMES
|
|
+#endif
|
|
+
|
|
+#include <stdio.h>
|
|
+#ifndef MSDOS
|
|
+#include <unistd.h>
|
|
+#else
|
|
+#include <io.h>
|
|
+extern void exit();
|
|
+#endif
|
|
+#include <signal.h>
|
|
+#ifndef VMS
|
|
+#ifndef _IRIX
|
|
+#include <time.h>
|
|
+#endif
|
|
+#ifdef TIMES
|
|
+#include <sys/types.h>
|
|
+#include <sys/times.h>
|
|
+#endif
|
|
+#else /* VMS */
|
|
+#include <types.h>
|
|
+struct tms {
|
|
+ time_t tms_utime;
|
|
+ time_t tms_stime;
|
|
+ time_t tms_uchild; /* I dunno... */
|
|
+ time_t tms_uchildsys; /* so these names are a guess :-) */
|
|
+ }
|
|
+#endif
|
|
+#ifndef TIMES
|
|
+#include <sys/timeb.h>
|
|
+#endif
|
|
+
|
|
+#ifdef sun
|
|
+#include <limits.h>
|
|
+#include <sys/param.h>
|
|
+#endif
|
|
+
|
|
+#include "des/des_locl.h"
|
|
+#include "des/spr.h"
|
|
+
|
|
+#define DES_DEFAULT_OPTIONS
|
|
+
|
|
+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
|
|
+#define PART1
|
|
+#define PART2
|
|
+#define PART3
|
|
+#define PART4
|
|
+#endif
|
|
+
|
|
+#ifdef PART1
|
|
+
|
|
+#undef DES_UNROLL
|
|
+#undef DES_RISC1
|
|
+#undef DES_RISC2
|
|
+#undef DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#define des_encrypt des_encrypt_u4_cisc_idx
|
|
+#define des_encrypt2 des_encrypt2_u4_cisc_idx
|
|
+#define des_encrypt3 des_encrypt3_u4_cisc_idx
|
|
+#define des_decrypt3 des_decrypt3_u4_cisc_idx
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#define DES_UNROLL
|
|
+#undef DES_RISC1
|
|
+#undef DES_RISC2
|
|
+#undef DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u16_cisc_idx
|
|
+#define des_encrypt2 des_encrypt2_u16_cisc_idx
|
|
+#define des_encrypt3 des_encrypt3_u16_cisc_idx
|
|
+#define des_decrypt3 des_decrypt3_u16_cisc_idx
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#undef DES_UNROLL
|
|
+#define DES_RISC1
|
|
+#undef DES_RISC2
|
|
+#undef DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u4_risc1_idx
|
|
+#define des_encrypt2 des_encrypt2_u4_risc1_idx
|
|
+#define des_encrypt3 des_encrypt3_u4_risc1_idx
|
|
+#define des_decrypt3 des_decrypt3_u4_risc1_idx
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#endif
|
|
+
|
|
+#ifdef PART2
|
|
+
|
|
+#undef DES_UNROLL
|
|
+#undef DES_RISC1
|
|
+#define DES_RISC2
|
|
+#undef DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u4_risc2_idx
|
|
+#define des_encrypt2 des_encrypt2_u4_risc2_idx
|
|
+#define des_encrypt3 des_encrypt3_u4_risc2_idx
|
|
+#define des_decrypt3 des_decrypt3_u4_risc2_idx
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#define DES_UNROLL
|
|
+#define DES_RISC1
|
|
+#undef DES_RISC2
|
|
+#undef DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u16_risc1_idx
|
|
+#define des_encrypt2 des_encrypt2_u16_risc1_idx
|
|
+#define des_encrypt3 des_encrypt3_u16_risc1_idx
|
|
+#define des_decrypt3 des_decrypt3_u16_risc1_idx
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#define DES_UNROLL
|
|
+#undef DES_RISC1
|
|
+#define DES_RISC2
|
|
+#undef DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u16_risc2_idx
|
|
+#define des_encrypt2 des_encrypt2_u16_risc2_idx
|
|
+#define des_encrypt3 des_encrypt3_u16_risc2_idx
|
|
+#define des_decrypt3 des_decrypt3_u16_risc2_idx
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#endif
|
|
+
|
|
+#ifdef PART3
|
|
+
|
|
+#undef DES_UNROLL
|
|
+#undef DES_RISC1
|
|
+#undef DES_RISC2
|
|
+#define DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u4_cisc_ptr
|
|
+#define des_encrypt2 des_encrypt2_u4_cisc_ptr
|
|
+#define des_encrypt3 des_encrypt3_u4_cisc_ptr
|
|
+#define des_decrypt3 des_decrypt3_u4_cisc_ptr
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#define DES_UNROLL
|
|
+#undef DES_RISC1
|
|
+#undef DES_RISC2
|
|
+#define DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u16_cisc_ptr
|
|
+#define des_encrypt2 des_encrypt2_u16_cisc_ptr
|
|
+#define des_encrypt3 des_encrypt3_u16_cisc_ptr
|
|
+#define des_decrypt3 des_decrypt3_u16_cisc_ptr
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#undef DES_UNROLL
|
|
+#define DES_RISC1
|
|
+#undef DES_RISC2
|
|
+#define DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u4_risc1_ptr
|
|
+#define des_encrypt2 des_encrypt2_u4_risc1_ptr
|
|
+#define des_encrypt3 des_encrypt3_u4_risc1_ptr
|
|
+#define des_decrypt3 des_decrypt3_u4_risc1_ptr
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#endif
|
|
+
|
|
+#ifdef PART4
|
|
+
|
|
+#undef DES_UNROLL
|
|
+#undef DES_RISC1
|
|
+#define DES_RISC2
|
|
+#define DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u4_risc2_ptr
|
|
+#define des_encrypt2 des_encrypt2_u4_risc2_ptr
|
|
+#define des_encrypt3 des_encrypt3_u4_risc2_ptr
|
|
+#define des_decrypt3 des_decrypt3_u4_risc2_ptr
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#define DES_UNROLL
|
|
+#define DES_RISC1
|
|
+#undef DES_RISC2
|
|
+#define DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u16_risc1_ptr
|
|
+#define des_encrypt2 des_encrypt2_u16_risc1_ptr
|
|
+#define des_encrypt3 des_encrypt3_u16_risc1_ptr
|
|
+#define des_decrypt3 des_decrypt3_u16_risc1_ptr
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#define DES_UNROLL
|
|
+#undef DES_RISC1
|
|
+#define DES_RISC2
|
|
+#define DES_PTR
|
|
+#undef D_ENCRYPT
|
|
+#undef des_encrypt
|
|
+#undef des_encrypt2
|
|
+#undef des_encrypt3
|
|
+#undef des_decrypt3
|
|
+#define des_encrypt des_encrypt_u16_risc2_ptr
|
|
+#define des_encrypt2 des_encrypt2_u16_risc2_ptr
|
|
+#define des_encrypt3 des_encrypt3_u16_risc2_ptr
|
|
+#define des_decrypt3 des_decrypt3_u16_risc2_ptr
|
|
+#undef HEADER_DES_LOCL_H
|
|
+#include "des_enc.c"
|
|
+
|
|
+#endif
|
|
+
|
|
+/* The following if from times(3) man page. It may need to be changed */
|
|
+#ifndef HZ
|
|
+# ifndef CLK_TCK
|
|
+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
|
|
+# ifndef VMS
|
|
+# define HZ 100.0
|
|
+# else /* VMS */
|
|
+# define HZ 100.0
|
|
+# endif
|
|
+# else /* _BSD_CLK_TCK_ */
|
|
+# define HZ ((double)_BSD_CLK_TCK_)
|
|
+# endif
|
|
+# else /* CLK_TCK */
|
|
+# define HZ ((double)CLK_TCK)
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+#define BUFSIZE ((long)1024)
|
|
+long run=0;
|
|
+
|
|
+#ifndef NOPROTO
|
|
+double Time_F(int s);
|
|
+#else
|
|
+double Time_F();
|
|
+#endif
|
|
+
|
|
+#ifdef SIGALRM
|
|
+#if defined(__STDC__) || defined(sgi)
|
|
+#define SIGRETTYPE void
|
|
+#else
|
|
+#define SIGRETTYPE int
|
|
+#endif
|
|
+
|
|
+#ifndef NOPROTO
|
|
+SIGRETTYPE sig_done(int sig);
|
|
+#else
|
|
+SIGRETTYPE sig_done();
|
|
+#endif
|
|
+
|
|
+SIGRETTYPE sig_done(sig)
|
|
+int sig;
|
|
+ {
|
|
+ signal(SIGALRM,sig_done);
|
|
+ run=0;
|
|
+#ifdef LINT
|
|
+ sig=sig;
|
|
+#endif
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#define START 0
|
|
+#define STOP 1
|
|
+
|
|
+double Time_F(s)
|
|
+int s;
|
|
+ {
|
|
+ double ret;
|
|
+#ifdef TIMES
|
|
+ static struct tms tstart,tend;
|
|
+
|
|
+ if (s == START)
|
|
+ {
|
|
+ times(&tstart);
|
|
+ return(0);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ times(&tend);
|
|
+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
|
|
+ return((ret == 0.0)?1e-6:ret);
|
|
+ }
|
|
+#else /* !times() */
|
|
+ static struct timeb tstart,tend;
|
|
+ long i;
|
|
+
|
|
+ if (s == START)
|
|
+ {
|
|
+ ftime(&tstart);
|
|
+ return(0);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ ftime(&tend);
|
|
+ i=(long)tend.millitm-(long)tstart.millitm;
|
|
+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
|
|
+ return((ret == 0.0)?1e-6:ret);
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+
|
|
+#ifdef SIGALRM
|
|
+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
|
|
+#else
|
|
+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
|
|
+#endif
|
|
+
|
|
+#define time_it(func,name,index) \
|
|
+ print_name(name); \
|
|
+ Time_F(START); \
|
|
+ for (count=0,run=1; COND(cb); count++) \
|
|
+ { \
|
|
+ unsigned long d[2]; \
|
|
+ func(d,&(sch[0]),DES_ENCRYPT); \
|
|
+ } \
|
|
+ tm[index]=Time_F(STOP); \
|
|
+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
|
|
+ tm[index]=((double)COUNT(cb))/tm[index];
|
|
+
|
|
+#define print_it(name,index) \
|
|
+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
|
|
+ tm[index]*8,1.0e6/tm[index]);
|
|
+
|
|
+int main(argc,argv)
|
|
+int argc;
|
|
+char **argv;
|
|
+ {
|
|
+ long count;
|
|
+ static unsigned char buf[BUFSIZE];
|
|
+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
|
|
+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
|
|
+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
|
|
+ des_key_schedule sch,sch2,sch3;
|
|
+ double d,tm[16],max=0;
|
|
+ int rank[16];
|
|
+ char *str[16];
|
|
+ int max_idx=0,i,num=0,j;
|
|
+#ifndef SIGALARM
|
|
+ long ca,cb,cc,cd,ce;
|
|
+#endif
|
|
+
|
|
+ for (i=0; i<12; i++)
|
|
+ {
|
|
+ tm[i]=0.0;
|
|
+ rank[i]=0;
|
|
+ }
|
|
+
|
|
+#ifndef TIMES
|
|
+ fprintf(stderr,"To get the most acurate results, try to run this\n");
|
|
+ fprintf(stderr,"program when this computer is idle.\n");
|
|
+#endif
|
|
+
|
|
+ des_set_key((C_Block *)key,sch);
|
|
+ des_set_key((C_Block *)key2,sch2);
|
|
+ des_set_key((C_Block *)key3,sch3);
|
|
+
|
|
+#ifndef SIGALRM
|
|
+ fprintf(stderr,"First we calculate the approximate speed ...\n");
|
|
+ des_set_key((C_Block *)key,sch);
|
|
+ count=10;
|
|
+ do {
|
|
+ long i;
|
|
+ unsigned long data[2];
|
|
+
|
|
+ count*=2;
|
|
+ Time_F(START);
|
|
+ for (i=count; i; i--)
|
|
+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
|
|
+ d=Time_F(STOP);
|
|
+ } while (d < 3.0);
|
|
+ ca=count;
|
|
+ cb=count*3;
|
|
+ cc=count*3*8/BUFSIZE+1;
|
|
+ cd=count*8/BUFSIZE+1;
|
|
+
|
|
+ ce=count/20+1;
|
|
+#define COND(d) (count != (d))
|
|
+#define COUNT(d) (d)
|
|
+#else
|
|
+#define COND(c) (run)
|
|
+#define COUNT(d) (count)
|
|
+ signal(SIGALRM,sig_done);
|
|
+ alarm(10);
|
|
+#endif
|
|
+
|
|
+#ifdef PART1
|
|
+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
|
|
+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
|
|
+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
|
|
+ num+=3;
|
|
+#endif
|
|
+#ifdef PART2
|
|
+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
|
|
+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
|
|
+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
|
|
+ num+=3;
|
|
+#endif
|
|
+#ifdef PART3
|
|
+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
|
|
+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
|
|
+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
|
|
+ num+=3;
|
|
+#endif
|
|
+#ifdef PART4
|
|
+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
|
|
+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
|
|
+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
|
|
+ num+=3;
|
|
+#endif
|
|
+
|
|
+#ifdef PART1
|
|
+ str[0]=" 4 c i";
|
|
+ print_it("des_encrypt_u4_cisc_idx ",0);
|
|
+ max=tm[0];
|
|
+ max_idx=0;
|
|
+ str[1]="16 c i";
|
|
+ print_it("des_encrypt_u16_cisc_idx ",1);
|
|
+ if (max < tm[1]) { max=tm[1]; max_idx=1; }
|
|
+ str[2]=" 4 r1 i";
|
|
+ print_it("des_encrypt_u4_risc1_idx ",2);
|
|
+ if (max < tm[2]) { max=tm[2]; max_idx=2; }
|
|
+#endif
|
|
+#ifdef PART2
|
|
+ str[3]="16 r1 i";
|
|
+ print_it("des_encrypt_u16_risc1_idx",3);
|
|
+ if (max < tm[3]) { max=tm[3]; max_idx=3; }
|
|
+ str[4]=" 4 r2 i";
|
|
+ print_it("des_encrypt_u4_risc2_idx ",4);
|
|
+ if (max < tm[4]) { max=tm[4]; max_idx=4; }
|
|
+ str[5]="16 r2 i";
|
|
+ print_it("des_encrypt_u16_risc2_idx",5);
|
|
+ if (max < tm[5]) { max=tm[5]; max_idx=5; }
|
|
+#endif
|
|
+#ifdef PART3
|
|
+ str[6]=" 4 c p";
|
|
+ print_it("des_encrypt_u4_cisc_ptr ",6);
|
|
+ if (max < tm[6]) { max=tm[6]; max_idx=6; }
|
|
+ str[7]="16 c p";
|
|
+ print_it("des_encrypt_u16_cisc_ptr ",7);
|
|
+ if (max < tm[7]) { max=tm[7]; max_idx=7; }
|
|
+ str[8]=" 4 r1 p";
|
|
+ print_it("des_encrypt_u4_risc1_ptr ",8);
|
|
+ if (max < tm[8]) { max=tm[8]; max_idx=8; }
|
|
+#endif
|
|
+#ifdef PART4
|
|
+ str[9]="16 r1 p";
|
|
+ print_it("des_encrypt_u16_risc1_ptr",9);
|
|
+ if (max < tm[9]) { max=tm[9]; max_idx=9; }
|
|
+ str[10]=" 4 r2 p";
|
|
+ print_it("des_encrypt_u4_risc2_ptr ",10);
|
|
+ if (max < tm[10]) { max=tm[10]; max_idx=10; }
|
|
+ str[11]="16 r2 p";
|
|
+ print_it("des_encrypt_u16_risc2_ptr",11);
|
|
+ if (max < tm[11]) { max=tm[11]; max_idx=11; }
|
|
+#endif
|
|
+ printf("options des ecb/s\n");
|
|
+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
|
|
+ d=tm[max_idx];
|
|
+ tm[max_idx]= -2.0;
|
|
+ max= -1.0;
|
|
+ for (;;)
|
|
+ {
|
|
+ for (i=0; i<12; i++)
|
|
+ {
|
|
+ if (max < tm[i]) { max=tm[i]; j=i; }
|
|
+ }
|
|
+ if (max < 0.0) break;
|
|
+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
|
|
+ tm[j]= -2.0;
|
|
+ max= -1.0;
|
|
+ }
|
|
+
|
|
+ switch (max_idx)
|
|
+ {
|
|
+ case 0:
|
|
+ printf("-DDES_DEFAULT_OPTIONS\n");
|
|
+ break;
|
|
+ case 1:
|
|
+ printf("-DDES_UNROLL\n");
|
|
+ break;
|
|
+ case 2:
|
|
+ printf("-DDES_RISC1\n");
|
|
+ break;
|
|
+ case 3:
|
|
+ printf("-DDES_UNROLL -DDES_RISC1\n");
|
|
+ break;
|
|
+ case 4:
|
|
+ printf("-DDES_RISC2\n");
|
|
+ break;
|
|
+ case 5:
|
|
+ printf("-DDES_UNROLL -DDES_RISC2\n");
|
|
+ break;
|
|
+ case 6:
|
|
+ printf("-DDES_PTR\n");
|
|
+ break;
|
|
+ case 7:
|
|
+ printf("-DDES_UNROLL -DDES_PTR\n");
|
|
+ break;
|
|
+ case 8:
|
|
+ printf("-DDES_RISC1 -DDES_PTR\n");
|
|
+ break;
|
|
+ case 9:
|
|
+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
|
|
+ break;
|
|
+ case 10:
|
|
+ printf("-DDES_RISC2 -DDES_PTR\n");
|
|
+ break;
|
|
+ case 11:
|
|
+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
|
|
+ break;
|
|
+ }
|
|
+ exit(0);
|
|
+#if defined(LINT) || defined(MSDOS)
|
|
+ return(0);
|
|
+#endif
|
|
+ }
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/dx86unix.S Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,3160 @@
|
|
+/*
|
|
+ * This file was originally generated by Michael Richardson <mcr@freeswan.org>
|
|
+ * via the perl scripts found in the ASM subdir. It remains copyright of
|
|
+ * Eric Young, see the file COPYRIGHT.
|
|
+ *
|
|
+ * This was last done on October 9, 2002.
|
|
+ *
|
|
+ * While this file does not need to go through cpp, we pass it through
|
|
+ * CPP by naming it dx86unix.S instead of dx86unix.s because there is
|
|
+ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
|
|
+ * which may contain stuff that AS doesn't understand instead of
|
|
+ * referencing EXTRA_AFLAGS.
|
|
+ */
|
|
+
|
|
+ .file "dx86unix.S"
|
|
+ .version "01.01"
|
|
+.text
|
|
+ .align 16
|
|
+.globl des_encrypt
|
|
+ .type des_encrypt , @function
|
|
+des_encrypt:
|
|
+ pushl %esi
|
|
+ pushl %edi
|
|
+
|
|
+
|
|
+ movl 12(%esp), %esi
|
|
+ xorl %ecx, %ecx
|
|
+ pushl %ebx
|
|
+ pushl %ebp
|
|
+ movl (%esi), %eax
|
|
+ movl 28(%esp), %ebx
|
|
+ movl 4(%esi), %edi
|
|
+
|
|
+
|
|
+ roll $4, %eax
|
|
+ movl %eax, %esi
|
|
+ xorl %edi, %eax
|
|
+ andl $0xf0f0f0f0, %eax
|
|
+ xorl %eax, %esi
|
|
+ xorl %eax, %edi
|
|
+
|
|
+ roll $20, %edi
|
|
+ movl %edi, %eax
|
|
+ xorl %esi, %edi
|
|
+ andl $0xfff0000f, %edi
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ roll $14, %eax
|
|
+ movl %eax, %edi
|
|
+ xorl %esi, %eax
|
|
+ andl $0x33333333, %eax
|
|
+ xorl %eax, %edi
|
|
+ xorl %eax, %esi
|
|
+
|
|
+ roll $22, %esi
|
|
+ movl %esi, %eax
|
|
+ xorl %edi, %esi
|
|
+ andl $0x03fc03fc, %esi
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edi
|
|
+
|
|
+ roll $9, %eax
|
|
+ movl %eax, %esi
|
|
+ xorl %edi, %eax
|
|
+ andl $0xaaaaaaaa, %eax
|
|
+ xorl %eax, %esi
|
|
+ xorl %eax, %edi
|
|
+
|
|
+.byte 209
|
|
+.byte 199
|
|
+ movl 24(%esp), %ebp
|
|
+ cmpl $0, %ebx
|
|
+ je .L000start_decrypt
|
|
+
|
|
+
|
|
+ movl (%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 4(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 8(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 12(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 16(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 20(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 24(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 28(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 32(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 36(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 40(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 44(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 48(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 52(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 56(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 60(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 64(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 68(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 72(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 76(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 80(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 84(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 88(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 92(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 96(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 100(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 104(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 108(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 112(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 116(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 120(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 124(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ jmp .L001end
|
|
+.L000start_decrypt:
|
|
+
|
|
+
|
|
+ movl 120(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 124(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 112(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 116(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 104(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 108(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 96(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 100(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 88(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 92(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 80(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 84(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 72(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 76(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 64(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 68(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 56(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 60(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 48(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 52(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 40(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 44(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 32(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 36(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 24(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 28(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 16(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 20(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 8(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 12(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl (%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 4(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+.L001end:
|
|
+
|
|
+
|
|
+ movl 20(%esp), %edx
|
|
+.byte 209
|
|
+.byte 206
|
|
+ movl %edi, %eax
|
|
+ xorl %esi, %edi
|
|
+ andl $0xaaaaaaaa, %edi
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ roll $23, %eax
|
|
+ movl %eax, %edi
|
|
+ xorl %esi, %eax
|
|
+ andl $0x03fc03fc, %eax
|
|
+ xorl %eax, %edi
|
|
+ xorl %eax, %esi
|
|
+
|
|
+ roll $10, %edi
|
|
+ movl %edi, %eax
|
|
+ xorl %esi, %edi
|
|
+ andl $0x33333333, %edi
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ roll $18, %esi
|
|
+ movl %esi, %edi
|
|
+ xorl %eax, %esi
|
|
+ andl $0xfff0000f, %esi
|
|
+ xorl %esi, %edi
|
|
+ xorl %esi, %eax
|
|
+
|
|
+ roll $12, %edi
|
|
+ movl %edi, %esi
|
|
+ xorl %eax, %edi
|
|
+ andl $0xf0f0f0f0, %edi
|
|
+ xorl %edi, %esi
|
|
+ xorl %edi, %eax
|
|
+
|
|
+ rorl $4, %eax
|
|
+ movl %eax, (%edx)
|
|
+ movl %esi, 4(%edx)
|
|
+ popl %ebp
|
|
+ popl %ebx
|
|
+ popl %edi
|
|
+ popl %esi
|
|
+ ret
|
|
+.des_encrypt_end:
|
|
+ .size des_encrypt , .des_encrypt_end-des_encrypt
|
|
+.ident "desasm.pl"
|
|
+.text
|
|
+ .align 16
|
|
+.globl des_encrypt2
|
|
+ .type des_encrypt2 , @function
|
|
+des_encrypt2:
|
|
+ pushl %esi
|
|
+ pushl %edi
|
|
+
|
|
+
|
|
+ movl 12(%esp), %eax
|
|
+ xorl %ecx, %ecx
|
|
+ pushl %ebx
|
|
+ pushl %ebp
|
|
+ movl (%eax), %esi
|
|
+ movl 28(%esp), %ebx
|
|
+ roll $3, %esi
|
|
+ movl 4(%eax), %edi
|
|
+ roll $3, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ cmpl $0, %ebx
|
|
+ je .L002start_decrypt
|
|
+
|
|
+
|
|
+ movl (%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 4(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 8(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 12(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 16(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 20(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 24(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 28(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 32(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 36(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 40(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 44(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 48(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 52(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 56(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 60(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 64(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 68(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 72(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 76(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 80(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 84(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 88(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 92(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 96(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 100(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 104(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 108(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 112(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 116(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 120(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 124(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ jmp .L003end
|
|
+.L002start_decrypt:
|
|
+
|
|
+
|
|
+ movl 120(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 124(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 112(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 116(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 104(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 108(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 96(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 100(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 88(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 92(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 80(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 84(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 72(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 76(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 64(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 68(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 56(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 60(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 48(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 52(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 40(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 44(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 32(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 36(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 24(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 28(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl 16(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 20(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+
|
|
+
|
|
+ movl 8(%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 12(%ebp), %edx
|
|
+ xorl %esi, %eax
|
|
+ xorl %esi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %edi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %edi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %edi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %edi
|
|
+
|
|
+
|
|
+ movl (%ebp), %eax
|
|
+ xorl %ebx, %ebx
|
|
+ movl 4(%ebp), %edx
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %edx
|
|
+ andl $0xfcfcfcfc, %eax
|
|
+ andl $0xcfcfcfcf, %edx
|
|
+ movb %al, %bl
|
|
+ movb %ah, %cl
|
|
+ rorl $4, %edx
|
|
+ movl des_SPtrans(%ebx),%ebp
|
|
+ movb %dl, %bl
|
|
+ xorl %ebp, %esi
|
|
+ movl 0x200+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %dh, %cl
|
|
+ shrl $16, %eax
|
|
+ movl 0x100+des_SPtrans(%ebx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movb %ah, %bl
|
|
+ shrl $16, %edx
|
|
+ movl 0x300+des_SPtrans(%ecx),%ebp
|
|
+ xorl %ebp, %esi
|
|
+ movl 24(%esp), %ebp
|
|
+ movb %dh, %cl
|
|
+ andl $0xff, %eax
|
|
+ andl $0xff, %edx
|
|
+ movl 0x600+des_SPtrans(%ebx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x700+des_SPtrans(%ecx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x400+des_SPtrans(%eax),%ebx
|
|
+ xorl %ebx, %esi
|
|
+ movl 0x500+des_SPtrans(%edx),%ebx
|
|
+ xorl %ebx, %esi
|
|
+.L003end:
|
|
+
|
|
+
|
|
+ rorl $3, %edi
|
|
+ movl 20(%esp), %eax
|
|
+ rorl $3, %esi
|
|
+ movl %edi, (%eax)
|
|
+ movl %esi, 4(%eax)
|
|
+ popl %ebp
|
|
+ popl %ebx
|
|
+ popl %edi
|
|
+ popl %esi
|
|
+ ret
|
|
+.des_encrypt2_end:
|
|
+ .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
|
|
+.ident "desasm.pl"
|
|
+.text
|
|
+ .align 16
|
|
+.globl des_encrypt3
|
|
+ .type des_encrypt3 , @function
|
|
+des_encrypt3:
|
|
+ pushl %ebx
|
|
+ movl 8(%esp), %ebx
|
|
+ pushl %ebp
|
|
+ pushl %esi
|
|
+ pushl %edi
|
|
+
|
|
+
|
|
+ movl (%ebx), %edi
|
|
+ movl 4(%ebx), %esi
|
|
+ subl $12, %esp
|
|
+
|
|
+
|
|
+ roll $4, %edi
|
|
+ movl %edi, %edx
|
|
+ xorl %esi, %edi
|
|
+ andl $0xf0f0f0f0, %edi
|
|
+ xorl %edi, %edx
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ roll $20, %esi
|
|
+ movl %esi, %edi
|
|
+ xorl %edx, %esi
|
|
+ andl $0xfff0000f, %esi
|
|
+ xorl %esi, %edi
|
|
+ xorl %esi, %edx
|
|
+
|
|
+ roll $14, %edi
|
|
+ movl %edi, %esi
|
|
+ xorl %edx, %edi
|
|
+ andl $0x33333333, %edi
|
|
+ xorl %edi, %esi
|
|
+ xorl %edi, %edx
|
|
+
|
|
+ roll $22, %edx
|
|
+ movl %edx, %edi
|
|
+ xorl %esi, %edx
|
|
+ andl $0x03fc03fc, %edx
|
|
+ xorl %edx, %edi
|
|
+ xorl %edx, %esi
|
|
+
|
|
+ roll $9, %edi
|
|
+ movl %edi, %edx
|
|
+ xorl %esi, %edi
|
|
+ andl $0xaaaaaaaa, %edi
|
|
+ xorl %edi, %edx
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ rorl $3, %edx
|
|
+ rorl $2, %esi
|
|
+ movl %esi, 4(%ebx)
|
|
+ movl 36(%esp), %eax
|
|
+ movl %edx, (%ebx)
|
|
+ movl 40(%esp), %edi
|
|
+ movl 44(%esp), %esi
|
|
+ movl $1, 8(%esp)
|
|
+ movl %eax, 4(%esp)
|
|
+ movl %ebx, (%esp)
|
|
+ call des_encrypt2
|
|
+ movl $0, 8(%esp)
|
|
+ movl %edi, 4(%esp)
|
|
+ movl %ebx, (%esp)
|
|
+ call des_encrypt2
|
|
+ movl $1, 8(%esp)
|
|
+ movl %esi, 4(%esp)
|
|
+ movl %ebx, (%esp)
|
|
+ call des_encrypt2
|
|
+ addl $12, %esp
|
|
+ movl (%ebx), %edi
|
|
+ movl 4(%ebx), %esi
|
|
+
|
|
+
|
|
+ roll $2, %esi
|
|
+ roll $3, %edi
|
|
+ movl %edi, %eax
|
|
+ xorl %esi, %edi
|
|
+ andl $0xaaaaaaaa, %edi
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ roll $23, %eax
|
|
+ movl %eax, %edi
|
|
+ xorl %esi, %eax
|
|
+ andl $0x03fc03fc, %eax
|
|
+ xorl %eax, %edi
|
|
+ xorl %eax, %esi
|
|
+
|
|
+ roll $10, %edi
|
|
+ movl %edi, %eax
|
|
+ xorl %esi, %edi
|
|
+ andl $0x33333333, %edi
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ roll $18, %esi
|
|
+ movl %esi, %edi
|
|
+ xorl %eax, %esi
|
|
+ andl $0xfff0000f, %esi
|
|
+ xorl %esi, %edi
|
|
+ xorl %esi, %eax
|
|
+
|
|
+ roll $12, %edi
|
|
+ movl %edi, %esi
|
|
+ xorl %eax, %edi
|
|
+ andl $0xf0f0f0f0, %edi
|
|
+ xorl %edi, %esi
|
|
+ xorl %edi, %eax
|
|
+
|
|
+ rorl $4, %eax
|
|
+ movl %eax, (%ebx)
|
|
+ movl %esi, 4(%ebx)
|
|
+ popl %edi
|
|
+ popl %esi
|
|
+ popl %ebp
|
|
+ popl %ebx
|
|
+ ret
|
|
+.des_encrypt3_end:
|
|
+ .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
|
|
+.ident "desasm.pl"
|
|
+.text
|
|
+ .align 16
|
|
+.globl des_decrypt3
|
|
+ .type des_decrypt3 , @function
|
|
+des_decrypt3:
|
|
+ pushl %ebx
|
|
+ movl 8(%esp), %ebx
|
|
+ pushl %ebp
|
|
+ pushl %esi
|
|
+ pushl %edi
|
|
+
|
|
+
|
|
+ movl (%ebx), %edi
|
|
+ movl 4(%ebx), %esi
|
|
+ subl $12, %esp
|
|
+
|
|
+
|
|
+ roll $4, %edi
|
|
+ movl %edi, %edx
|
|
+ xorl %esi, %edi
|
|
+ andl $0xf0f0f0f0, %edi
|
|
+ xorl %edi, %edx
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ roll $20, %esi
|
|
+ movl %esi, %edi
|
|
+ xorl %edx, %esi
|
|
+ andl $0xfff0000f, %esi
|
|
+ xorl %esi, %edi
|
|
+ xorl %esi, %edx
|
|
+
|
|
+ roll $14, %edi
|
|
+ movl %edi, %esi
|
|
+ xorl %edx, %edi
|
|
+ andl $0x33333333, %edi
|
|
+ xorl %edi, %esi
|
|
+ xorl %edi, %edx
|
|
+
|
|
+ roll $22, %edx
|
|
+ movl %edx, %edi
|
|
+ xorl %esi, %edx
|
|
+ andl $0x03fc03fc, %edx
|
|
+ xorl %edx, %edi
|
|
+ xorl %edx, %esi
|
|
+
|
|
+ roll $9, %edi
|
|
+ movl %edi, %edx
|
|
+ xorl %esi, %edi
|
|
+ andl $0xaaaaaaaa, %edi
|
|
+ xorl %edi, %edx
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ rorl $3, %edx
|
|
+ rorl $2, %esi
|
|
+ movl %esi, 4(%ebx)
|
|
+ movl 36(%esp), %esi
|
|
+ movl %edx, (%ebx)
|
|
+ movl 40(%esp), %edi
|
|
+ movl 44(%esp), %eax
|
|
+ movl $0, 8(%esp)
|
|
+ movl %eax, 4(%esp)
|
|
+ movl %ebx, (%esp)
|
|
+ call des_encrypt2
|
|
+ movl $1, 8(%esp)
|
|
+ movl %edi, 4(%esp)
|
|
+ movl %ebx, (%esp)
|
|
+ call des_encrypt2
|
|
+ movl $0, 8(%esp)
|
|
+ movl %esi, 4(%esp)
|
|
+ movl %ebx, (%esp)
|
|
+ call des_encrypt2
|
|
+ addl $12, %esp
|
|
+ movl (%ebx), %edi
|
|
+ movl 4(%ebx), %esi
|
|
+
|
|
+
|
|
+ roll $2, %esi
|
|
+ roll $3, %edi
|
|
+ movl %edi, %eax
|
|
+ xorl %esi, %edi
|
|
+ andl $0xaaaaaaaa, %edi
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ roll $23, %eax
|
|
+ movl %eax, %edi
|
|
+ xorl %esi, %eax
|
|
+ andl $0x03fc03fc, %eax
|
|
+ xorl %eax, %edi
|
|
+ xorl %eax, %esi
|
|
+
|
|
+ roll $10, %edi
|
|
+ movl %edi, %eax
|
|
+ xorl %esi, %edi
|
|
+ andl $0x33333333, %edi
|
|
+ xorl %edi, %eax
|
|
+ xorl %edi, %esi
|
|
+
|
|
+ roll $18, %esi
|
|
+ movl %esi, %edi
|
|
+ xorl %eax, %esi
|
|
+ andl $0xfff0000f, %esi
|
|
+ xorl %esi, %edi
|
|
+ xorl %esi, %eax
|
|
+
|
|
+ roll $12, %edi
|
|
+ movl %edi, %esi
|
|
+ xorl %eax, %edi
|
|
+ andl $0xf0f0f0f0, %edi
|
|
+ xorl %edi, %esi
|
|
+ xorl %edi, %eax
|
|
+
|
|
+ rorl $4, %eax
|
|
+ movl %eax, (%ebx)
|
|
+ movl %esi, 4(%ebx)
|
|
+ popl %edi
|
|
+ popl %esi
|
|
+ popl %ebp
|
|
+ popl %ebx
|
|
+ ret
|
|
+.des_decrypt3_end:
|
|
+ .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
|
|
+.ident "desasm.pl"
|
|
+.text
|
|
+ .align 16
|
|
+.globl des_ncbc_encrypt
|
|
+ .type des_ncbc_encrypt , @function
|
|
+des_ncbc_encrypt:
|
|
+
|
|
+ pushl %ebp
|
|
+ pushl %ebx
|
|
+ pushl %esi
|
|
+ pushl %edi
|
|
+ movl 28(%esp), %ebp
|
|
+
|
|
+ movl 36(%esp), %ebx
|
|
+ movl (%ebx), %esi
|
|
+ movl 4(%ebx), %edi
|
|
+ pushl %edi
|
|
+ pushl %esi
|
|
+ pushl %edi
|
|
+ pushl %esi
|
|
+ movl %esp, %ebx
|
|
+ movl 36(%esp), %esi
|
|
+ movl 40(%esp), %edi
|
|
+
|
|
+ movl 56(%esp), %ecx
|
|
+
|
|
+ pushl %ecx
|
|
+
|
|
+ movl 52(%esp), %eax
|
|
+ pushl %eax
|
|
+ pushl %ebx
|
|
+ cmpl $0, %ecx
|
|
+ jz .L004decrypt
|
|
+ andl $4294967288, %ebp
|
|
+ movl 12(%esp), %eax
|
|
+ movl 16(%esp), %ebx
|
|
+ jz .L005encrypt_finish
|
|
+.L006encrypt_loop:
|
|
+ movl (%esi), %ecx
|
|
+ movl 4(%esi), %edx
|
|
+ xorl %ecx, %eax
|
|
+ xorl %edx, %ebx
|
|
+ movl %eax, 12(%esp)
|
|
+ movl %ebx, 16(%esp)
|
|
+ call des_encrypt
|
|
+ movl 12(%esp), %eax
|
|
+ movl 16(%esp), %ebx
|
|
+ movl %eax, (%edi)
|
|
+ movl %ebx, 4(%edi)
|
|
+ addl $8, %esi
|
|
+ addl $8, %edi
|
|
+ subl $8, %ebp
|
|
+ jnz .L006encrypt_loop
|
|
+.L005encrypt_finish:
|
|
+ movl 56(%esp), %ebp
|
|
+ andl $7, %ebp
|
|
+ jz .L007finish
|
|
+ xorl %ecx, %ecx
|
|
+ xorl %edx, %edx
|
|
+ movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
|
|
+ jmp *%ebp
|
|
+.L009ej7:
|
|
+ movb 6(%esi), %dh
|
|
+ sall $8, %edx
|
|
+.L010ej6:
|
|
+ movb 5(%esi), %dh
|
|
+.L011ej5:
|
|
+ movb 4(%esi), %dl
|
|
+.L012ej4:
|
|
+ movl (%esi), %ecx
|
|
+ jmp .L013ejend
|
|
+.L014ej3:
|
|
+ movb 2(%esi), %ch
|
|
+ sall $8, %ecx
|
|
+.L015ej2:
|
|
+ movb 1(%esi), %ch
|
|
+.L016ej1:
|
|
+ movb (%esi), %cl
|
|
+.L013ejend:
|
|
+ xorl %ecx, %eax
|
|
+ xorl %edx, %ebx
|
|
+ movl %eax, 12(%esp)
|
|
+ movl %ebx, 16(%esp)
|
|
+ call des_encrypt
|
|
+ movl 12(%esp), %eax
|
|
+ movl 16(%esp), %ebx
|
|
+ movl %eax, (%edi)
|
|
+ movl %ebx, 4(%edi)
|
|
+ jmp .L007finish
|
|
+.align 16
|
|
+.L004decrypt:
|
|
+ andl $4294967288, %ebp
|
|
+ movl 20(%esp), %eax
|
|
+ movl 24(%esp), %ebx
|
|
+ jz .L017decrypt_finish
|
|
+.L018decrypt_loop:
|
|
+ movl (%esi), %eax
|
|
+ movl 4(%esi), %ebx
|
|
+ movl %eax, 12(%esp)
|
|
+ movl %ebx, 16(%esp)
|
|
+ call des_encrypt
|
|
+ movl 12(%esp), %eax
|
|
+ movl 16(%esp), %ebx
|
|
+ movl 20(%esp), %ecx
|
|
+ movl 24(%esp), %edx
|
|
+ xorl %eax, %ecx
|
|
+ xorl %ebx, %edx
|
|
+ movl (%esi), %eax
|
|
+ movl 4(%esi), %ebx
|
|
+ movl %ecx, (%edi)
|
|
+ movl %edx, 4(%edi)
|
|
+ movl %eax, 20(%esp)
|
|
+ movl %ebx, 24(%esp)
|
|
+ addl $8, %esi
|
|
+ addl $8, %edi
|
|
+ subl $8, %ebp
|
|
+ jnz .L018decrypt_loop
|
|
+.L017decrypt_finish:
|
|
+ movl 56(%esp), %ebp
|
|
+ andl $7, %ebp
|
|
+ jz .L007finish
|
|
+ movl (%esi), %eax
|
|
+ movl 4(%esi), %ebx
|
|
+ movl %eax, 12(%esp)
|
|
+ movl %ebx, 16(%esp)
|
|
+ call des_encrypt
|
|
+ movl 12(%esp), %eax
|
|
+ movl 16(%esp), %ebx
|
|
+ movl 20(%esp), %ecx
|
|
+ movl 24(%esp), %edx
|
|
+ xorl %eax, %ecx
|
|
+ xorl %ebx, %edx
|
|
+ movl (%esi), %eax
|
|
+ movl 4(%esi), %ebx
|
|
+.L019dj7:
|
|
+ rorl $16, %edx
|
|
+ movb %dl, 6(%edi)
|
|
+ shrl $16, %edx
|
|
+.L020dj6:
|
|
+ movb %dh, 5(%edi)
|
|
+.L021dj5:
|
|
+ movb %dl, 4(%edi)
|
|
+.L022dj4:
|
|
+ movl %ecx, (%edi)
|
|
+ jmp .L023djend
|
|
+.L024dj3:
|
|
+ rorl $16, %ecx
|
|
+ movb %cl, 2(%edi)
|
|
+ sall $16, %ecx
|
|
+.L025dj2:
|
|
+ movb %ch, 1(%esi)
|
|
+.L026dj1:
|
|
+ movb %cl, (%esi)
|
|
+.L023djend:
|
|
+ jmp .L007finish
|
|
+.align 16
|
|
+.L007finish:
|
|
+ movl 64(%esp), %ecx
|
|
+ addl $28, %esp
|
|
+ movl %eax, (%ecx)
|
|
+ movl %ebx, 4(%ecx)
|
|
+ popl %edi
|
|
+ popl %esi
|
|
+ popl %ebx
|
|
+ popl %ebp
|
|
+ ret
|
|
+.align 16
|
|
+.L008cbc_enc_jmp_table:
|
|
+ .long 0
|
|
+ .long .L016ej1
|
|
+ .long .L015ej2
|
|
+ .long .L014ej3
|
|
+ .long .L012ej4
|
|
+ .long .L011ej5
|
|
+ .long .L010ej6
|
|
+ .long .L009ej7
|
|
+.align 16
|
|
+.L027cbc_dec_jmp_table:
|
|
+ .long 0
|
|
+ .long .L026dj1
|
|
+ .long .L025dj2
|
|
+ .long .L024dj3
|
|
+ .long .L022dj4
|
|
+ .long .L021dj5
|
|
+ .long .L020dj6
|
|
+ .long .L019dj7
|
|
+.des_ncbc_encrypt_end:
|
|
+ .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
|
|
+.ident "desasm.pl"
|
|
+.text
|
|
+ .align 16
|
|
+.globl des_ede3_cbc_encrypt
|
|
+ .type des_ede3_cbc_encrypt , @function
|
|
+des_ede3_cbc_encrypt:
|
|
+
|
|
+ pushl %ebp
|
|
+ pushl %ebx
|
|
+ pushl %esi
|
|
+ pushl %edi
|
|
+ movl 28(%esp), %ebp
|
|
+
|
|
+ movl 44(%esp), %ebx
|
|
+ movl (%ebx), %esi
|
|
+ movl 4(%ebx), %edi
|
|
+ pushl %edi
|
|
+ pushl %esi
|
|
+ pushl %edi
|
|
+ pushl %esi
|
|
+ movl %esp, %ebx
|
|
+ movl 36(%esp), %esi
|
|
+ movl 40(%esp), %edi
|
|
+
|
|
+ movl 64(%esp), %ecx
|
|
+
|
|
+ movl 56(%esp), %eax
|
|
+ pushl %eax
|
|
+
|
|
+ movl 56(%esp), %eax
|
|
+ pushl %eax
|
|
+
|
|
+ movl 56(%esp), %eax
|
|
+ pushl %eax
|
|
+ pushl %ebx
|
|
+ cmpl $0, %ecx
|
|
+ jz .L028decrypt
|
|
+ andl $4294967288, %ebp
|
|
+ movl 16(%esp), %eax
|
|
+ movl 20(%esp), %ebx
|
|
+ jz .L029encrypt_finish
|
|
+.L030encrypt_loop:
|
|
+ movl (%esi), %ecx
|
|
+ movl 4(%esi), %edx
|
|
+ xorl %ecx, %eax
|
|
+ xorl %edx, %ebx
|
|
+ movl %eax, 16(%esp)
|
|
+ movl %ebx, 20(%esp)
|
|
+ call des_encrypt3
|
|
+ movl 16(%esp), %eax
|
|
+ movl 20(%esp), %ebx
|
|
+ movl %eax, (%edi)
|
|
+ movl %ebx, 4(%edi)
|
|
+ addl $8, %esi
|
|
+ addl $8, %edi
|
|
+ subl $8, %ebp
|
|
+ jnz .L030encrypt_loop
|
|
+.L029encrypt_finish:
|
|
+ movl 60(%esp), %ebp
|
|
+ andl $7, %ebp
|
|
+ jz .L031finish
|
|
+ xorl %ecx, %ecx
|
|
+ xorl %edx, %edx
|
|
+ movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
|
|
+ jmp *%ebp
|
|
+.L033ej7:
|
|
+ movb 6(%esi), %dh
|
|
+ sall $8, %edx
|
|
+.L034ej6:
|
|
+ movb 5(%esi), %dh
|
|
+.L035ej5:
|
|
+ movb 4(%esi), %dl
|
|
+.L036ej4:
|
|
+ movl (%esi), %ecx
|
|
+ jmp .L037ejend
|
|
+.L038ej3:
|
|
+ movb 2(%esi), %ch
|
|
+ sall $8, %ecx
|
|
+.L039ej2:
|
|
+ movb 1(%esi), %ch
|
|
+.L040ej1:
|
|
+ movb (%esi), %cl
|
|
+.L037ejend:
|
|
+ xorl %ecx, %eax
|
|
+ xorl %edx, %ebx
|
|
+ movl %eax, 16(%esp)
|
|
+ movl %ebx, 20(%esp)
|
|
+ call des_encrypt3
|
|
+ movl 16(%esp), %eax
|
|
+ movl 20(%esp), %ebx
|
|
+ movl %eax, (%edi)
|
|
+ movl %ebx, 4(%edi)
|
|
+ jmp .L031finish
|
|
+.align 16
|
|
+.L028decrypt:
|
|
+ andl $4294967288, %ebp
|
|
+ movl 24(%esp), %eax
|
|
+ movl 28(%esp), %ebx
|
|
+ jz .L041decrypt_finish
|
|
+.L042decrypt_loop:
|
|
+ movl (%esi), %eax
|
|
+ movl 4(%esi), %ebx
|
|
+ movl %eax, 16(%esp)
|
|
+ movl %ebx, 20(%esp)
|
|
+ call des_decrypt3
|
|
+ movl 16(%esp), %eax
|
|
+ movl 20(%esp), %ebx
|
|
+ movl 24(%esp), %ecx
|
|
+ movl 28(%esp), %edx
|
|
+ xorl %eax, %ecx
|
|
+ xorl %ebx, %edx
|
|
+ movl (%esi), %eax
|
|
+ movl 4(%esi), %ebx
|
|
+ movl %ecx, (%edi)
|
|
+ movl %edx, 4(%edi)
|
|
+ movl %eax, 24(%esp)
|
|
+ movl %ebx, 28(%esp)
|
|
+ addl $8, %esi
|
|
+ addl $8, %edi
|
|
+ subl $8, %ebp
|
|
+ jnz .L042decrypt_loop
|
|
+.L041decrypt_finish:
|
|
+ movl 60(%esp), %ebp
|
|
+ andl $7, %ebp
|
|
+ jz .L031finish
|
|
+ movl (%esi), %eax
|
|
+ movl 4(%esi), %ebx
|
|
+ movl %eax, 16(%esp)
|
|
+ movl %ebx, 20(%esp)
|
|
+ call des_decrypt3
|
|
+ movl 16(%esp), %eax
|
|
+ movl 20(%esp), %ebx
|
|
+ movl 24(%esp), %ecx
|
|
+ movl 28(%esp), %edx
|
|
+ xorl %eax, %ecx
|
|
+ xorl %ebx, %edx
|
|
+ movl (%esi), %eax
|
|
+ movl 4(%esi), %ebx
|
|
+.L043dj7:
|
|
+ rorl $16, %edx
|
|
+ movb %dl, 6(%edi)
|
|
+ shrl $16, %edx
|
|
+.L044dj6:
|
|
+ movb %dh, 5(%edi)
|
|
+.L045dj5:
|
|
+ movb %dl, 4(%edi)
|
|
+.L046dj4:
|
|
+ movl %ecx, (%edi)
|
|
+ jmp .L047djend
|
|
+.L048dj3:
|
|
+ rorl $16, %ecx
|
|
+ movb %cl, 2(%edi)
|
|
+ sall $16, %ecx
|
|
+.L049dj2:
|
|
+ movb %ch, 1(%esi)
|
|
+.L050dj1:
|
|
+ movb %cl, (%esi)
|
|
+.L047djend:
|
|
+ jmp .L031finish
|
|
+.align 16
|
|
+.L031finish:
|
|
+ movl 76(%esp), %ecx
|
|
+ addl $32, %esp
|
|
+ movl %eax, (%ecx)
|
|
+ movl %ebx, 4(%ecx)
|
|
+ popl %edi
|
|
+ popl %esi
|
|
+ popl %ebx
|
|
+ popl %ebp
|
|
+ ret
|
|
+.align 16
|
|
+.L032cbc_enc_jmp_table:
|
|
+ .long 0
|
|
+ .long .L040ej1
|
|
+ .long .L039ej2
|
|
+ .long .L038ej3
|
|
+ .long .L036ej4
|
|
+ .long .L035ej5
|
|
+ .long .L034ej6
|
|
+ .long .L033ej7
|
|
+.align 16
|
|
+.L051cbc_dec_jmp_table:
|
|
+ .long 0
|
|
+ .long .L050dj1
|
|
+ .long .L049dj2
|
|
+ .long .L048dj3
|
|
+ .long .L046dj4
|
|
+ .long .L045dj5
|
|
+ .long .L044dj6
|
|
+ .long .L043dj7
|
|
+.des_ede3_cbc_encrypt_end:
|
|
+ .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
|
|
+.ident "desasm.pl"
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/ecb_enc.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,128 @@
|
|
+/* crypto/des/ecb_enc.c */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+#include "des/des_locl.h"
|
|
+#include "des/spr.h"
|
|
+
|
|
+char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
|
|
+char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
|
|
+
|
|
+/* RCSID $Id: ecb_enc.c,v 1.8 2004/08/04 15:57:22 mcr Exp $ */
|
|
+/* This function ifdef'ed out for FreeS/WAN project. */
|
|
+#ifdef notdef
|
|
+char *des_options()
|
|
+ {
|
|
+ static int init=1;
|
|
+ static char buf[32];
|
|
+
|
|
+ if (init)
|
|
+ {
|
|
+ char *ptr,*unroll,*risc,*size;
|
|
+
|
|
+ init=0;
|
|
+#ifdef DES_PTR
|
|
+ ptr="ptr";
|
|
+#else
|
|
+ ptr="idx";
|
|
+#endif
|
|
+#if defined(DES_RISC1) || defined(DES_RISC2)
|
|
+#ifdef DES_RISC1
|
|
+ risc="risc1";
|
|
+#endif
|
|
+#ifdef DES_RISC2
|
|
+ risc="risc2";
|
|
+#endif
|
|
+#else
|
|
+ risc="cisc";
|
|
+#endif
|
|
+#ifdef DES_UNROLL
|
|
+ unroll="16";
|
|
+#else
|
|
+ unroll="4";
|
|
+#endif
|
|
+ if (sizeof(DES_LONG) != sizeof(long))
|
|
+ size="int";
|
|
+ else
|
|
+ size="long";
|
|
+ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
|
|
+ }
|
|
+ return(buf);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+
|
|
+void des_ecb_encrypt(input, output, ks, enc)
|
|
+des_cblock (*input);
|
|
+des_cblock (*output);
|
|
+des_key_schedule ks;
|
|
+int enc;
|
|
+ {
|
|
+ register DES_LONG l;
|
|
+ register unsigned char *in,*out;
|
|
+ DES_LONG ll[2];
|
|
+
|
|
+ in=(unsigned char *)input;
|
|
+ out=(unsigned char *)output;
|
|
+ c2l(in,l); ll[0]=l;
|
|
+ c2l(in,l); ll[1]=l;
|
|
+ des_encrypt(ll,ks,enc);
|
|
+ l=ll[0]; l2c(l,out);
|
|
+ l=ll[1]; l2c(l,out);
|
|
+ l=ll[0]=ll[1]=0;
|
|
+ }
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/ipsec_alg_3des.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,181 @@
|
|
+/*
|
|
+ * ipsec_alg 3DES cipher stubs
|
|
+ *
|
|
+ * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
|
|
+ *
|
|
+ * Adapted from ipsec_alg_aes.c by JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
|
|
+ *
|
|
+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ */
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+/*
|
|
+ * special case: ipsec core modular with this static algo inside:
|
|
+ * must avoid MODULE magic for this file
|
|
+ */
|
|
+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_3DES)
|
|
+#undef MODULE
|
|
+#endif
|
|
+
|
|
+#include <linux/module.h>
|
|
+#include <linux/init.h>
|
|
+
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/string.h>
|
|
+
|
|
+/* Low freeswan header coupling */
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_alg.h"
|
|
+#include "crypto/des.h"
|
|
+#include "openswan/ipsec_alg_3des.h"
|
|
+
|
|
+#define AES_CONTEXT_T aes_context
|
|
+static int debug_3des=0;
|
|
+static int test_3des=0;
|
|
+static int excl_3des=0;
|
|
+
|
|
+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
|
|
+MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
|
|
+#ifdef module_param
|
|
+module_param(debug_3des,int,0600)
|
|
+module_param(test_des,int,0600)
|
|
+module_param(excl_des,int,0600)
|
|
+#else
|
|
+MODULE_PARM(debug_3des, "i");
|
|
+MODULE_PARM(test_des, "i");
|
|
+MODULE_PARM(excl_des, "i");
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
|
|
+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
|
|
+
|
|
+static int _3des_set_key(struct ipsec_alg_enc *alg,
|
|
+ __u8 * key_e, const __u8 * key,
|
|
+ size_t keysize)
|
|
+{
|
|
+ int ret = 0;
|
|
+ TripleDES_context *ctx = (TripleDES_context*)key_e;
|
|
+
|
|
+ if(keysize != 192/8) {
|
|
+ return EINVAL;
|
|
+ }
|
|
+
|
|
+ des_set_key((des_cblock *)(key + DES_KEY_SZ*0), ctx->s1);
|
|
+ des_set_key((des_cblock *)(key + DES_KEY_SZ*1), ctx->s2);
|
|
+ des_set_key((des_cblock *)(key + DES_KEY_SZ*2), ctx->s3);
|
|
+
|
|
+ if (debug_3des > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_3des_set_key:"
|
|
+ "ret=%d key_e=%p key=%p keysize=%ld\n",
|
|
+ ret, key_e, key, (unsigned long int) keysize);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg,
|
|
+ __u8 * key_e,
|
|
+ __u8 * in,
|
|
+ int ilen, const __u8 * iv,
|
|
+ int encrypt)
|
|
+{
|
|
+ TripleDES_context *ctx=(TripleDES_context*)key_e;
|
|
+ des_cblock miv;
|
|
+
|
|
+ memcpy(&miv, iv, sizeof(miv));
|
|
+
|
|
+ if (debug_3des > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
|
|
+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
|
|
+ key_e, in, ilen, iv, encrypt);
|
|
+
|
|
+ des_ede3_cbc_encrypt((des_cblock *)in,
|
|
+ (des_cblock *)in,
|
|
+ ilen,
|
|
+ ctx->s1,
|
|
+ ctx->s2,
|
|
+ ctx->s3,
|
|
+ &miv, encrypt);
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+static struct ipsec_alg_enc ipsec_alg_3DES = {
|
|
+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
|
|
+ ixt_refcnt: ATOMIC_INIT(0),
|
|
+ ixt_name: "3des",
|
|
+ ixt_blocksize: ESP_3DES_CBC_BLK_LEN,
|
|
+ ixt_support: {
|
|
+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
|
|
+ ias_id: ESP_3DES,
|
|
+ ias_keyminbits: ESP_3DES_KEY_SZ*8,
|
|
+ ias_keymaxbits: ESP_3DES_KEY_SZ*8,
|
|
+ },
|
|
+ },
|
|
+#if defined(MODULE_KLIPS_ENC_3DES_MODULE)
|
|
+ ixt_module: THIS_MODULE,
|
|
+#endif
|
|
+ ixt_e_keylen: ESP_3DES_KEY_SZ*8,
|
|
+ ixt_e_ctx_size: sizeof(TripleDES_context),
|
|
+ ixt_e_set_key: _3des_set_key,
|
|
+ ixt_e_cbc_encrypt:_3des_cbc_encrypt,
|
|
+};
|
|
+
|
|
+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
|
|
+IPSEC_ALG_MODULE_INIT_MOD( ipsec_3des_init )
|
|
+#else
|
|
+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_3des_init )
|
|
+#endif
|
|
+{
|
|
+ int ret, test_ret;
|
|
+
|
|
+ if (excl_3des) ipsec_alg_3DES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
|
|
+ ret=register_ipsec_alg_enc(&ipsec_alg_3DES);
|
|
+ printk("ipsec_3des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
|
|
+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
|
|
+ ipsec_alg_3DES.ixt_common.ixt_name,
|
|
+ ret);
|
|
+ if (ret==0 && test_3des) {
|
|
+ test_ret=ipsec_alg_test(
|
|
+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
|
|
+ test_3des);
|
|
+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
|
|
+ ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
|
|
+ test_ret);
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
|
|
+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_3des_fini )
|
|
+#else
|
|
+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_3des_fini )
|
|
+#endif
|
|
+{
|
|
+ unregister_ipsec_alg_enc(&ipsec_alg_3DES);
|
|
+ return;
|
|
+}
|
|
+
|
|
+/* Dual, because 3des code is 4-clause BSD licensed */
|
|
+#ifdef MODULE_LICENSE
|
|
+MODULE_LICENSE("Dual BSD/GPL");
|
|
+#endif
|
|
+
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/des/set_key.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,246 @@
|
|
+/* crypto/des/set_key.c */
|
|
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+/* set_key.c v 1.4 eay 24/9/91
|
|
+ * 1.4 Speed up by 400% :-)
|
|
+ * 1.3 added register declarations.
|
|
+ * 1.2 unrolled make_key_sched a bit more
|
|
+ * 1.1 added norm_expand_bits
|
|
+ * 1.0 First working version
|
|
+ */
|
|
+#include "des/des_locl.h"
|
|
+#include "des/podd.h"
|
|
+#include "des/sk.h"
|
|
+
|
|
+#ifndef NOPROTO
|
|
+static int check_parity(des_cblock (*key));
|
|
+#else
|
|
+static int check_parity();
|
|
+#endif
|
|
+
|
|
+int des_check_key=0;
|
|
+
|
|
+void des_set_odd_parity(key)
|
|
+des_cblock (*key);
|
|
+ {
|
|
+ int i;
|
|
+
|
|
+ for (i=0; i<DES_KEY_SZ; i++)
|
|
+ (*key)[i]=odd_parity[(*key)[i]];
|
|
+ }
|
|
+
|
|
+static int check_parity(key)
|
|
+des_cblock (*key);
|
|
+ {
|
|
+ int i;
|
|
+
|
|
+ for (i=0; i<DES_KEY_SZ; i++)
|
|
+ {
|
|
+ if ((*key)[i] != odd_parity[(*key)[i]])
|
|
+ return(0);
|
|
+ }
|
|
+ return(1);
|
|
+ }
|
|
+
|
|
+/* Weak and semi week keys as take from
|
|
+ * %A D.W. Davies
|
|
+ * %A W.L. Price
|
|
+ * %T Security for Computer Networks
|
|
+ * %I John Wiley & Sons
|
|
+ * %D 1984
|
|
+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
|
|
+ * (and actual cblock values).
|
|
+ */
|
|
+#define NUM_WEAK_KEY 16
|
|
+static des_cblock weak_keys[NUM_WEAK_KEY]={
|
|
+ /* weak keys */
|
|
+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
|
|
+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
|
|
+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
|
|
+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
|
|
+ /* semi-weak keys */
|
|
+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
|
|
+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
|
|
+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
|
|
+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
|
|
+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
|
|
+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
|
|
+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
|
|
+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
|
|
+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
|
|
+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
|
|
+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
|
|
+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
|
|
+
|
|
+int des_is_weak_key(key)
|
|
+des_cblock (*key);
|
|
+ {
|
|
+ int i;
|
|
+
|
|
+ for (i=0; i<NUM_WEAK_KEY; i++)
|
|
+ /* Added == 0 to comparision, I obviously don't run
|
|
+ * this section very often :-(, thanks to
|
|
+ * engineering@MorningStar.Com for the fix
|
|
+ * eay 93/06/29
|
|
+ * Another problem, I was comparing only the first 4
|
|
+ * bytes, 97/03/18 */
|
|
+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
|
|
+ return(0);
|
|
+ }
|
|
+
|
|
+/* NOW DEFINED IN des_local.h
|
|
+ * See ecb_encrypt.c for a pseudo description of these macros.
|
|
+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
|
|
+ * (b)^=(t),\
|
|
+ * (a)=((a)^((t)<<(n))))
|
|
+ */
|
|
+
|
|
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
|
|
+ (a)=(a)^(t)^(t>>(16-(n))))
|
|
+
|
|
+/* return 0 if key parity is odd (correct),
|
|
+ * return -1 if key parity error,
|
|
+ * return -2 if illegal weak key.
|
|
+ */
|
|
+int des_set_key(key, schedule)
|
|
+des_cblock (*key);
|
|
+des_key_schedule schedule;
|
|
+ {
|
|
+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
|
|
+ register DES_LONG c,d,t,s,t2;
|
|
+ register unsigned char *in;
|
|
+ register DES_LONG *k;
|
|
+ register int i;
|
|
+
|
|
+ if (des_check_key)
|
|
+ {
|
|
+ if (!check_parity(key))
|
|
+ return(-1);
|
|
+
|
|
+ if (des_is_weak_key(key))
|
|
+ return(-2);
|
|
+ }
|
|
+
|
|
+ k=(DES_LONG *)schedule;
|
|
+ in=(unsigned char *)key;
|
|
+
|
|
+ c2l(in,c);
|
|
+ c2l(in,d);
|
|
+
|
|
+ /* do PC1 in 60 simple operations */
|
|
+/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
|
|
+ HPERM_OP(c,t,-2, 0xcccc0000L);
|
|
+ HPERM_OP(c,t,-1, 0xaaaa0000L);
|
|
+ HPERM_OP(c,t, 8, 0x00ff0000L);
|
|
+ HPERM_OP(c,t,-1, 0xaaaa0000L);
|
|
+ HPERM_OP(d,t,-8, 0xff000000L);
|
|
+ HPERM_OP(d,t, 8, 0x00ff0000L);
|
|
+ HPERM_OP(d,t, 2, 0x33330000L);
|
|
+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
|
|
+ d=(d>>8)|((c&0xf0000000L)>>4);
|
|
+ c&=0x0fffffffL; */
|
|
+
|
|
+ /* I now do it in 47 simple operations :-)
|
|
+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
|
|
+ * for the inspiration. :-) */
|
|
+ PERM_OP (d,c,t,4,0x0f0f0f0fL);
|
|
+ HPERM_OP(c,t,-2,0xcccc0000L);
|
|
+ HPERM_OP(d,t,-2,0xcccc0000L);
|
|
+ PERM_OP (d,c,t,1,0x55555555L);
|
|
+ PERM_OP (c,d,t,8,0x00ff00ffL);
|
|
+ PERM_OP (d,c,t,1,0x55555555L);
|
|
+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
|
|
+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
|
|
+ c&=0x0fffffffL;
|
|
+
|
|
+ for (i=0; i<ITERATIONS; i++)
|
|
+ {
|
|
+ if (shifts2[i])
|
|
+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
|
|
+ else
|
|
+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
|
|
+ c&=0x0fffffffL;
|
|
+ d&=0x0fffffffL;
|
|
+ /* could be a few less shifts but I am to lazy at this
|
|
+ * point in time to investigate */
|
|
+ s= des_skb[0][ (c )&0x3f ]|
|
|
+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
|
|
+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
|
|
+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
|
|
+ ((c>>22L)&0x38)];
|
|
+ t= des_skb[4][ (d )&0x3f ]|
|
|
+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
|
|
+ des_skb[6][ (d>>15L)&0x3f ]|
|
|
+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
|
|
+
|
|
+ /* table contained 0213 4657 */
|
|
+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
|
|
+ *(k++)=ROTATE(t2,30)&0xffffffffL;
|
|
+
|
|
+ t2=((s>>16L)|(t&0xffff0000L));
|
|
+ *(k++)=ROTATE(t2,26)&0xffffffffL;
|
|
+ }
|
|
+ return(0);
|
|
+ }
|
|
+
|
|
+int des_key_sched(key, schedule)
|
|
+des_cblock (*key);
|
|
+des_key_schedule schedule;
|
|
+ {
|
|
+ return(des_set_key(key,schedule));
|
|
+ }
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/goodmask.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,100 @@
|
|
+/*
|
|
+ * minor utilities for subnet-mask manipulation
|
|
+ * Copyright (C) 1998, 1999 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: goodmask.c,v 1.12 2004/07/10 07:43:47 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+#ifndef ABITS
|
|
+#define ABITS 32 /* bits in an IPv4 address */
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ - goodmask - is this a good (^1*0*$) subnet mask?
|
|
+ * You are not expected to understand this. See Henry S. Warren Jr,
|
|
+ * "Functions realizable with word-parallel logical and two's-complement
|
|
+ * addition instructions", CACM 20.6 (June 1977), p.439.
|
|
+ */
|
|
+int /* predicate */
|
|
+goodmask(mask)
|
|
+struct in_addr mask;
|
|
+{
|
|
+ unsigned long x = ntohl(mask.s_addr);
|
|
+ /* clear rightmost contiguous string of 1-bits */
|
|
+# define CRCS1B(x) (((x|(x-1))+1)&x)
|
|
+# define TOPBIT (1UL << 31)
|
|
+
|
|
+ /* either zero, or has one string of 1-bits which is left-justified */
|
|
+ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
|
|
+ return 1;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - masktobits - how many bits in this mask?
|
|
+ * The algorithm is essentially a binary search, but highly optimized
|
|
+ * for this particular task.
|
|
+ */
|
|
+int /* -1 means !goodmask() */
|
|
+masktobits(mask)
|
|
+struct in_addr mask;
|
|
+{
|
|
+ unsigned long m = ntohl(mask.s_addr);
|
|
+ int masklen;
|
|
+
|
|
+ if (!goodmask(mask))
|
|
+ return -1;
|
|
+
|
|
+ if (m&0x00000001UL)
|
|
+ return 32;
|
|
+ masklen = 0;
|
|
+ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
|
|
+ masklen |= 0x10;
|
|
+ m <<= 16;
|
|
+ }
|
|
+ if (m&(0x00ff0000UL<<1)) {
|
|
+ masklen |= 0x08;
|
|
+ m <<= 8;
|
|
+ }
|
|
+ if (m&(0x0f000000UL<<1)) {
|
|
+ masklen |= 0x04;
|
|
+ m <<= 4;
|
|
+ }
|
|
+ if (m&(0x30000000UL<<1)) {
|
|
+ masklen |= 0x02;
|
|
+ m <<= 2;
|
|
+ }
|
|
+ if (m&(0x40000000UL<<1))
|
|
+ masklen |= 0x01;
|
|
+
|
|
+ return masklen;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - bitstomask - return a mask with this many high bits on
|
|
+ */
|
|
+struct in_addr
|
|
+bitstomask(n)
|
|
+int n;
|
|
+{
|
|
+ struct in_addr result;
|
|
+
|
|
+ if (n > 0 && n <= ABITS)
|
|
+ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
|
|
+ else if (n == 0)
|
|
+ result.s_addr = 0;
|
|
+ else
|
|
+ result.s_addr = 0; /* best error report we can do */
|
|
+ return result;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/infblock.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,403 @@
|
|
+/* infblock.c -- interpret and process block types to last block
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+#include <zlib/zutil.h>
|
|
+#include "infblock.h"
|
|
+#include "inftrees.h"
|
|
+#include "infcodes.h"
|
|
+#include "infutil.h"
|
|
+
|
|
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
|
|
+
|
|
+/* simplify the use of the inflate_huft type with some defines */
|
|
+#define exop word.what.Exop
|
|
+#define bits word.what.Bits
|
|
+
|
|
+/* Table for deflate from PKZIP's appnote.txt. */
|
|
+local const uInt border[] = { /* Order of the bit length code lengths */
|
|
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
|
+
|
|
+/*
|
|
+ Notes beyond the 1.93a appnote.txt:
|
|
+
|
|
+ 1. Distance pointers never point before the beginning of the output
|
|
+ stream.
|
|
+ 2. Distance pointers can point back across blocks, up to 32k away.
|
|
+ 3. There is an implied maximum of 7 bits for the bit length table and
|
|
+ 15 bits for the actual data.
|
|
+ 4. If only one code exists, then it is encoded using one bit. (Zero
|
|
+ would be more efficient, but perhaps a little confusing.) If two
|
|
+ codes exist, they are coded using one bit each (0 and 1).
|
|
+ 5. There is no way of sending zero distance codes--a dummy must be
|
|
+ sent if there are none. (History: a pre 2.0 version of PKZIP would
|
|
+ store blocks with no distance codes, but this was discovered to be
|
|
+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
|
|
+ zero distance codes, which is sent as one code of zero bits in
|
|
+ length.
|
|
+ 6. There are up to 286 literal/length codes. Code 256 represents the
|
|
+ end-of-block. Note however that the static length tree defines
|
|
+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
|
|
+ cannot be used though, since there is no length base or extra bits
|
|
+ defined for them. Similarily, there are up to 30 distance codes.
|
|
+ However, static trees define 32 codes (all 5 bits) to fill out the
|
|
+ Huffman codes, but the last two had better not show up in the data.
|
|
+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
|
|
+ The exception is that a single code would not be complete (see #4).
|
|
+ 8. The five bits following the block type is really the number of
|
|
+ literal codes sent minus 257.
|
|
+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
|
|
+ (1+6+6). Therefore, to output three times the length, you output
|
|
+ three codes (1+1+1), whereas to output four times the same length,
|
|
+ you only need two codes (1+3). Hmm.
|
|
+ 10. In the tree reconstruction algorithm, Code = Code + Increment
|
|
+ only if BitLength(i) is not zero. (Pretty obvious.)
|
|
+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
|
|
+ 12. Note: length code 284 can represent 227-258, but length code 285
|
|
+ really is 258. The last length deserves its own, short code
|
|
+ since it gets used a lot in very redundant files. The length
|
|
+ 258 is special since 258 - 3 (the min match length) is 255.
|
|
+ 13. The literal/length and distance code bit lengths are read as a
|
|
+ single stream of lengths. It is possible (and advantageous) for
|
|
+ a repeat code (16, 17, or 18) to go across the boundary between
|
|
+ the two sets of lengths.
|
|
+ */
|
|
+
|
|
+
|
|
+void inflate_blocks_reset(s, z, c)
|
|
+inflate_blocks_statef *s;
|
|
+z_streamp z;
|
|
+uLongf *c;
|
|
+{
|
|
+ if (c != Z_NULL)
|
|
+ *c = s->check;
|
|
+ if (s->mode == BTREE || s->mode == DTREE)
|
|
+ ZFREE(z, s->sub.trees.blens);
|
|
+ if (s->mode == CODES)
|
|
+ inflate_codes_free(s->sub.decode.codes, z);
|
|
+ s->mode = TYPE;
|
|
+ s->bitk = 0;
|
|
+ s->bitb = 0;
|
|
+ s->read = s->write = s->window;
|
|
+ if (s->checkfn != Z_NULL)
|
|
+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
|
|
+ Tracev((stderr, "inflate: blocks reset\n"));
|
|
+}
|
|
+
|
|
+
|
|
+inflate_blocks_statef *inflate_blocks_new(z, c, w)
|
|
+z_streamp z;
|
|
+check_func c;
|
|
+uInt w;
|
|
+{
|
|
+ inflate_blocks_statef *s;
|
|
+
|
|
+ if ((s = (inflate_blocks_statef *)ZALLOC
|
|
+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
|
|
+ return s;
|
|
+ if ((s->hufts =
|
|
+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
|
|
+ {
|
|
+ ZFREE(z, s);
|
|
+ return Z_NULL;
|
|
+ }
|
|
+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
|
|
+ {
|
|
+ ZFREE(z, s->hufts);
|
|
+ ZFREE(z, s);
|
|
+ return Z_NULL;
|
|
+ }
|
|
+ s->end = s->window + w;
|
|
+ s->checkfn = c;
|
|
+ s->mode = TYPE;
|
|
+ Tracev((stderr, "inflate: blocks allocated\n"));
|
|
+ inflate_blocks_reset(s, z, Z_NULL);
|
|
+ return s;
|
|
+}
|
|
+
|
|
+
|
|
+int inflate_blocks(s, z, r)
|
|
+inflate_blocks_statef *s;
|
|
+z_streamp z;
|
|
+int r;
|
|
+{
|
|
+ uInt t; /* temporary storage */
|
|
+ uLong b; /* bit buffer */
|
|
+ uInt k; /* bits in bit buffer */
|
|
+ Bytef *p; /* input data pointer */
|
|
+ uInt n; /* bytes available there */
|
|
+ Bytef *q; /* output window write pointer */
|
|
+ uInt m; /* bytes to end of window or read pointer */
|
|
+
|
|
+ /* copy input/output information to locals (UPDATE macro restores) */
|
|
+ LOAD
|
|
+
|
|
+ /* process input based on current state */
|
|
+ while (1) switch (s->mode)
|
|
+ {
|
|
+ case TYPE:
|
|
+ NEEDBITS(3)
|
|
+ t = (uInt)b & 7;
|
|
+ s->last = t & 1;
|
|
+ switch (t >> 1)
|
|
+ {
|
|
+ case 0: /* stored */
|
|
+ Tracev((stderr, "inflate: stored block%s\n",
|
|
+ s->last ? " (last)" : ""));
|
|
+ DUMPBITS(3)
|
|
+ t = k & 7; /* go to byte boundary */
|
|
+ DUMPBITS(t)
|
|
+ s->mode = LENS; /* get length of stored block */
|
|
+ break;
|
|
+ case 1: /* fixed */
|
|
+ Tracev((stderr, "inflate: fixed codes block%s\n",
|
|
+ s->last ? " (last)" : ""));
|
|
+ {
|
|
+ uInt bl, bd;
|
|
+ inflate_huft *tl, *td;
|
|
+
|
|
+ inflate_trees_fixed(&bl, &bd, &tl, &td, z);
|
|
+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
|
|
+ if (s->sub.decode.codes == Z_NULL)
|
|
+ {
|
|
+ r = Z_MEM_ERROR;
|
|
+ LEAVE
|
|
+ }
|
|
+ }
|
|
+ DUMPBITS(3)
|
|
+ s->mode = CODES;
|
|
+ break;
|
|
+ case 2: /* dynamic */
|
|
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
|
|
+ s->last ? " (last)" : ""));
|
|
+ DUMPBITS(3)
|
|
+ s->mode = TABLE;
|
|
+ break;
|
|
+ case 3: /* illegal */
|
|
+ DUMPBITS(3)
|
|
+ s->mode = BAD;
|
|
+ z->msg = (char*)"invalid block type";
|
|
+ r = Z_DATA_ERROR;
|
|
+ LEAVE
|
|
+ }
|
|
+ break;
|
|
+ case LENS:
|
|
+ NEEDBITS(32)
|
|
+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
|
|
+ {
|
|
+ s->mode = BAD;
|
|
+ z->msg = (char*)"invalid stored block lengths";
|
|
+ r = Z_DATA_ERROR;
|
|
+ LEAVE
|
|
+ }
|
|
+ s->sub.left = (uInt)b & 0xffff;
|
|
+ b = k = 0; /* dump bits */
|
|
+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
|
|
+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
|
|
+ break;
|
|
+ case STORED:
|
|
+ if (n == 0)
|
|
+ LEAVE
|
|
+ NEEDOUT
|
|
+ t = s->sub.left;
|
|
+ if (t > n) t = n;
|
|
+ if (t > m) t = m;
|
|
+ zmemcpy(q, p, t);
|
|
+ p += t; n -= t;
|
|
+ q += t; m -= t;
|
|
+ if ((s->sub.left -= t) != 0)
|
|
+ break;
|
|
+ Tracev((stderr, "inflate: stored end, %lu total out\n",
|
|
+ z->total_out + (q >= s->read ? q - s->read :
|
|
+ (s->end - s->read) + (q - s->window))));
|
|
+ s->mode = s->last ? DRY : TYPE;
|
|
+ break;
|
|
+ case TABLE:
|
|
+ NEEDBITS(14)
|
|
+ s->sub.trees.table = t = (uInt)b & 0x3fff;
|
|
+#ifndef PKZIP_BUG_WORKAROUND
|
|
+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
|
|
+ {
|
|
+ s->mode = BAD;
|
|
+ z->msg = (char*)"too many length or distance symbols";
|
|
+ r = Z_DATA_ERROR;
|
|
+ LEAVE
|
|
+ }
|
|
+#endif
|
|
+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
|
|
+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
|
|
+ {
|
|
+ r = Z_MEM_ERROR;
|
|
+ LEAVE
|
|
+ }
|
|
+ DUMPBITS(14)
|
|
+ s->sub.trees.index = 0;
|
|
+ Tracev((stderr, "inflate: table sizes ok\n"));
|
|
+ s->mode = BTREE;
|
|
+ case BTREE:
|
|
+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
|
|
+ {
|
|
+ NEEDBITS(3)
|
|
+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
|
|
+ DUMPBITS(3)
|
|
+ }
|
|
+ while (s->sub.trees.index < 19)
|
|
+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
|
|
+ s->sub.trees.bb = 7;
|
|
+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
|
|
+ &s->sub.trees.tb, s->hufts, z);
|
|
+ if (t != Z_OK)
|
|
+ {
|
|
+ r = t;
|
|
+ if (r == Z_DATA_ERROR)
|
|
+ {
|
|
+ ZFREE(z, s->sub.trees.blens);
|
|
+ s->mode = BAD;
|
|
+ }
|
|
+ LEAVE
|
|
+ }
|
|
+ s->sub.trees.index = 0;
|
|
+ Tracev((stderr, "inflate: bits tree ok\n"));
|
|
+ s->mode = DTREE;
|
|
+ case DTREE:
|
|
+ while (t = s->sub.trees.table,
|
|
+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
|
|
+ {
|
|
+ inflate_huft *h;
|
|
+ uInt i, j, c;
|
|
+
|
|
+ t = s->sub.trees.bb;
|
|
+ NEEDBITS(t)
|
|
+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
|
|
+ t = h->bits;
|
|
+ c = h->base;
|
|
+ if (c < 16)
|
|
+ {
|
|
+ DUMPBITS(t)
|
|
+ s->sub.trees.blens[s->sub.trees.index++] = c;
|
|
+ }
|
|
+ else /* c == 16..18 */
|
|
+ {
|
|
+ i = c == 18 ? 7 : c - 14;
|
|
+ j = c == 18 ? 11 : 3;
|
|
+ NEEDBITS(t + i)
|
|
+ DUMPBITS(t)
|
|
+ j += (uInt)b & inflate_mask[i];
|
|
+ DUMPBITS(i)
|
|
+ i = s->sub.trees.index;
|
|
+ t = s->sub.trees.table;
|
|
+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
|
|
+ (c == 16 && i < 1))
|
|
+ {
|
|
+ ZFREE(z, s->sub.trees.blens);
|
|
+ s->mode = BAD;
|
|
+ z->msg = (char*)"invalid bit length repeat";
|
|
+ r = Z_DATA_ERROR;
|
|
+ LEAVE
|
|
+ }
|
|
+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
|
|
+ do {
|
|
+ s->sub.trees.blens[i++] = c;
|
|
+ } while (--j);
|
|
+ s->sub.trees.index = i;
|
|
+ }
|
|
+ }
|
|
+ s->sub.trees.tb = Z_NULL;
|
|
+ {
|
|
+ uInt bl, bd;
|
|
+ inflate_huft *tl, *td;
|
|
+ inflate_codes_statef *c;
|
|
+
|
|
+ bl = 9; /* must be <= 9 for lookahead assumptions */
|
|
+ bd = 6; /* must be <= 9 for lookahead assumptions */
|
|
+ t = s->sub.trees.table;
|
|
+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
|
|
+ s->sub.trees.blens, &bl, &bd, &tl, &td,
|
|
+ s->hufts, z);
|
|
+ if (t != Z_OK)
|
|
+ {
|
|
+ if (t == (uInt)Z_DATA_ERROR)
|
|
+ {
|
|
+ ZFREE(z, s->sub.trees.blens);
|
|
+ s->mode = BAD;
|
|
+ }
|
|
+ r = t;
|
|
+ LEAVE
|
|
+ }
|
|
+ Tracev((stderr, "inflate: trees ok\n"));
|
|
+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
|
|
+ {
|
|
+ r = Z_MEM_ERROR;
|
|
+ LEAVE
|
|
+ }
|
|
+ s->sub.decode.codes = c;
|
|
+ }
|
|
+ ZFREE(z, s->sub.trees.blens);
|
|
+ s->mode = CODES;
|
|
+ case CODES:
|
|
+ UPDATE
|
|
+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
|
|
+ return inflate_flush(s, z, r);
|
|
+ r = Z_OK;
|
|
+ inflate_codes_free(s->sub.decode.codes, z);
|
|
+ LOAD
|
|
+ Tracev((stderr, "inflate: codes end, %lu total out\n",
|
|
+ z->total_out + (q >= s->read ? q - s->read :
|
|
+ (s->end - s->read) + (q - s->window))));
|
|
+ if (!s->last)
|
|
+ {
|
|
+ s->mode = TYPE;
|
|
+ break;
|
|
+ }
|
|
+ s->mode = DRY;
|
|
+ case DRY:
|
|
+ FLUSH
|
|
+ if (s->read != s->write)
|
|
+ LEAVE
|
|
+ s->mode = DONE;
|
|
+ case DONE:
|
|
+ r = Z_STREAM_END;
|
|
+ LEAVE
|
|
+ case BAD:
|
|
+ r = Z_DATA_ERROR;
|
|
+ LEAVE
|
|
+ default:
|
|
+ r = Z_STREAM_ERROR;
|
|
+ LEAVE
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+int inflate_blocks_free(s, z)
|
|
+inflate_blocks_statef *s;
|
|
+z_streamp z;
|
|
+{
|
|
+ inflate_blocks_reset(s, z, Z_NULL);
|
|
+ ZFREE(z, s->window);
|
|
+ ZFREE(z, s->hufts);
|
|
+ ZFREE(z, s);
|
|
+ Tracev((stderr, "inflate: blocks freed\n"));
|
|
+ return Z_OK;
|
|
+}
|
|
+
|
|
+
|
|
+void inflate_set_dictionary(s, d, n)
|
|
+inflate_blocks_statef *s;
|
|
+const Bytef *d;
|
|
+uInt n;
|
|
+{
|
|
+ zmemcpy(s->window, d, n);
|
|
+ s->read = s->write = s->window + n;
|
|
+}
|
|
+
|
|
+
|
|
+/* Returns true if inflate is currently at the end of a block generated
|
|
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
|
|
+ * IN assertion: s != Z_NULL
|
|
+ */
|
|
+int inflate_blocks_sync_point(s)
|
|
+inflate_blocks_statef *s;
|
|
+{
|
|
+ return s->mode == LENS;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/infblock.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,39 @@
|
|
+/* infblock.h -- header to use infblock.c
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* WARNING: this file should *not* be used by applications. It is
|
|
+ part of the implementation of the compression library and is
|
|
+ subject to change. Applications should only use zlib.h.
|
|
+ */
|
|
+
|
|
+struct inflate_blocks_state;
|
|
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
|
|
+
|
|
+extern inflate_blocks_statef * inflate_blocks_new OF((
|
|
+ z_streamp z,
|
|
+ check_func c, /* check function */
|
|
+ uInt w)); /* window size */
|
|
+
|
|
+extern int inflate_blocks OF((
|
|
+ inflate_blocks_statef *,
|
|
+ z_streamp ,
|
|
+ int)); /* initial return code */
|
|
+
|
|
+extern void inflate_blocks_reset OF((
|
|
+ inflate_blocks_statef *,
|
|
+ z_streamp ,
|
|
+ uLongf *)); /* check value on output */
|
|
+
|
|
+extern int inflate_blocks_free OF((
|
|
+ inflate_blocks_statef *,
|
|
+ z_streamp));
|
|
+
|
|
+extern void inflate_set_dictionary OF((
|
|
+ inflate_blocks_statef *s,
|
|
+ const Bytef *d, /* dictionary */
|
|
+ uInt n)); /* dictionary length */
|
|
+
|
|
+extern int inflate_blocks_sync_point OF((
|
|
+ inflate_blocks_statef *s));
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/infcodes.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,251 @@
|
|
+/* infcodes.c -- process literals and length/distance pairs
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+#include <zlib/zutil.h>
|
|
+#include "inftrees.h"
|
|
+#include "infblock.h"
|
|
+#include "infcodes.h"
|
|
+#include "infutil.h"
|
|
+#include "inffast.h"
|
|
+
|
|
+/* simplify the use of the inflate_huft type with some defines */
|
|
+#define exop word.what.Exop
|
|
+#define bits word.what.Bits
|
|
+
|
|
+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
|
|
+ START, /* x: set up for LEN */
|
|
+ LEN, /* i: get length/literal/eob next */
|
|
+ LENEXT, /* i: getting length extra (have base) */
|
|
+ DIST, /* i: get distance next */
|
|
+ DISTEXT, /* i: getting distance extra */
|
|
+ COPY, /* o: copying bytes in window, waiting for space */
|
|
+ LIT, /* o: got literal, waiting for output space */
|
|
+ WASH, /* o: got eob, possibly still output waiting */
|
|
+ END, /* x: got eob and all data flushed */
|
|
+ BADCODE} /* x: got error */
|
|
+inflate_codes_mode;
|
|
+
|
|
+/* inflate codes private state */
|
|
+struct inflate_codes_state {
|
|
+
|
|
+ /* mode */
|
|
+ inflate_codes_mode mode; /* current inflate_codes mode */
|
|
+
|
|
+ /* mode dependent information */
|
|
+ uInt len;
|
|
+ union {
|
|
+ struct {
|
|
+ inflate_huft *tree; /* pointer into tree */
|
|
+ uInt need; /* bits needed */
|
|
+ } code; /* if LEN or DIST, where in tree */
|
|
+ uInt lit; /* if LIT, literal */
|
|
+ struct {
|
|
+ uInt get; /* bits to get for extra */
|
|
+ uInt dist; /* distance back to copy from */
|
|
+ } copy; /* if EXT or COPY, where and how much */
|
|
+ } sub; /* submode */
|
|
+
|
|
+ /* mode independent information */
|
|
+ Byte lbits; /* ltree bits decoded per branch */
|
|
+ Byte dbits; /* dtree bits decoder per branch */
|
|
+ inflate_huft *ltree; /* literal/length/eob tree */
|
|
+ inflate_huft *dtree; /* distance tree */
|
|
+
|
|
+};
|
|
+
|
|
+
|
|
+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
|
|
+uInt bl, bd;
|
|
+inflate_huft *tl;
|
|
+inflate_huft *td; /* need separate declaration for Borland C++ */
|
|
+z_streamp z;
|
|
+{
|
|
+ inflate_codes_statef *c;
|
|
+
|
|
+ if ((c = (inflate_codes_statef *)
|
|
+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
|
|
+ {
|
|
+ c->mode = START;
|
|
+ c->lbits = (Byte)bl;
|
|
+ c->dbits = (Byte)bd;
|
|
+ c->ltree = tl;
|
|
+ c->dtree = td;
|
|
+ Tracev((stderr, "inflate: codes new\n"));
|
|
+ }
|
|
+ return c;
|
|
+}
|
|
+
|
|
+
|
|
+int inflate_codes(s, z, r)
|
|
+inflate_blocks_statef *s;
|
|
+z_streamp z;
|
|
+int r;
|
|
+{
|
|
+ uInt j; /* temporary storage */
|
|
+ inflate_huft *t; /* temporary pointer */
|
|
+ uInt e; /* extra bits or operation */
|
|
+ uLong b; /* bit buffer */
|
|
+ uInt k; /* bits in bit buffer */
|
|
+ Bytef *p; /* input data pointer */
|
|
+ uInt n; /* bytes available there */
|
|
+ Bytef *q; /* output window write pointer */
|
|
+ uInt m; /* bytes to end of window or read pointer */
|
|
+ Bytef *f; /* pointer to copy strings from */
|
|
+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
|
|
+
|
|
+ /* copy input/output information to locals (UPDATE macro restores) */
|
|
+ LOAD
|
|
+
|
|
+ /* process input and output based on current state */
|
|
+ while (1) switch (c->mode)
|
|
+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
|
|
+ case START: /* x: set up for LEN */
|
|
+#ifndef SLOW
|
|
+ if (m >= 258 && n >= 10)
|
|
+ {
|
|
+ UPDATE
|
|
+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
|
|
+ LOAD
|
|
+ if (r != Z_OK)
|
|
+ {
|
|
+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+#endif /* !SLOW */
|
|
+ c->sub.code.need = c->lbits;
|
|
+ c->sub.code.tree = c->ltree;
|
|
+ c->mode = LEN;
|
|
+ case LEN: /* i: get length/literal/eob next */
|
|
+ j = c->sub.code.need;
|
|
+ NEEDBITS(j)
|
|
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
|
|
+ DUMPBITS(t->bits)
|
|
+ e = (uInt)(t->exop);
|
|
+ if (e == 0) /* literal */
|
|
+ {
|
|
+ c->sub.lit = t->base;
|
|
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
|
|
+ "inflate: literal '%c'\n" :
|
|
+ "inflate: literal 0x%02x\n", t->base));
|
|
+ c->mode = LIT;
|
|
+ break;
|
|
+ }
|
|
+ if (e & 16) /* length */
|
|
+ {
|
|
+ c->sub.copy.get = e & 15;
|
|
+ c->len = t->base;
|
|
+ c->mode = LENEXT;
|
|
+ break;
|
|
+ }
|
|
+ if ((e & 64) == 0) /* next table */
|
|
+ {
|
|
+ c->sub.code.need = e;
|
|
+ c->sub.code.tree = t + t->base;
|
|
+ break;
|
|
+ }
|
|
+ if (e & 32) /* end of block */
|
|
+ {
|
|
+ Tracevv((stderr, "inflate: end of block\n"));
|
|
+ c->mode = WASH;
|
|
+ break;
|
|
+ }
|
|
+ c->mode = BADCODE; /* invalid code */
|
|
+ z->msg = (char*)"invalid literal/length code";
|
|
+ r = Z_DATA_ERROR;
|
|
+ LEAVE
|
|
+ case LENEXT: /* i: getting length extra (have base) */
|
|
+ j = c->sub.copy.get;
|
|
+ NEEDBITS(j)
|
|
+ c->len += (uInt)b & inflate_mask[j];
|
|
+ DUMPBITS(j)
|
|
+ c->sub.code.need = c->dbits;
|
|
+ c->sub.code.tree = c->dtree;
|
|
+ Tracevv((stderr, "inflate: length %u\n", c->len));
|
|
+ c->mode = DIST;
|
|
+ case DIST: /* i: get distance next */
|
|
+ j = c->sub.code.need;
|
|
+ NEEDBITS(j)
|
|
+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
|
|
+ DUMPBITS(t->bits)
|
|
+ e = (uInt)(t->exop);
|
|
+ if (e & 16) /* distance */
|
|
+ {
|
|
+ c->sub.copy.get = e & 15;
|
|
+ c->sub.copy.dist = t->base;
|
|
+ c->mode = DISTEXT;
|
|
+ break;
|
|
+ }
|
|
+ if ((e & 64) == 0) /* next table */
|
|
+ {
|
|
+ c->sub.code.need = e;
|
|
+ c->sub.code.tree = t + t->base;
|
|
+ break;
|
|
+ }
|
|
+ c->mode = BADCODE; /* invalid code */
|
|
+ z->msg = (char*)"invalid distance code";
|
|
+ r = Z_DATA_ERROR;
|
|
+ LEAVE
|
|
+ case DISTEXT: /* i: getting distance extra */
|
|
+ j = c->sub.copy.get;
|
|
+ NEEDBITS(j)
|
|
+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
|
|
+ DUMPBITS(j)
|
|
+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
|
|
+ c->mode = COPY;
|
|
+ case COPY: /* o: copying bytes in window, waiting for space */
|
|
+ f = q - c->sub.copy.dist;
|
|
+ while (f < s->window) /* modulo window size-"while" instead */
|
|
+ f += s->end - s->window; /* of "if" handles invalid distances */
|
|
+ while (c->len)
|
|
+ {
|
|
+ NEEDOUT
|
|
+ OUTBYTE(*f++)
|
|
+ if (f == s->end)
|
|
+ f = s->window;
|
|
+ c->len--;
|
|
+ }
|
|
+ c->mode = START;
|
|
+ break;
|
|
+ case LIT: /* o: got literal, waiting for output space */
|
|
+ NEEDOUT
|
|
+ OUTBYTE(c->sub.lit)
|
|
+ c->mode = START;
|
|
+ break;
|
|
+ case WASH: /* o: got eob, possibly more output */
|
|
+ if (k > 7) /* return unused byte, if any */
|
|
+ {
|
|
+ Assert(k < 16, "inflate_codes grabbed too many bytes")
|
|
+ k -= 8;
|
|
+ n++;
|
|
+ p--; /* can always return one */
|
|
+ }
|
|
+ FLUSH
|
|
+ if (s->read != s->write)
|
|
+ LEAVE
|
|
+ c->mode = END;
|
|
+ case END:
|
|
+ r = Z_STREAM_END;
|
|
+ LEAVE
|
|
+ case BADCODE: /* x: got error */
|
|
+ r = Z_DATA_ERROR;
|
|
+ LEAVE
|
|
+ default:
|
|
+ r = Z_STREAM_ERROR;
|
|
+ LEAVE
|
|
+ }
|
|
+#ifdef NEED_DUMMY_RETURN
|
|
+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
|
|
+#endif
|
|
+}
|
|
+
|
|
+
|
|
+void inflate_codes_free(c, z)
|
|
+inflate_codes_statef *c;
|
|
+z_streamp z;
|
|
+{
|
|
+ ZFREE(z, c);
|
|
+ Tracev((stderr, "inflate: codes free\n"));
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/infcodes.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,31 @@
|
|
+/* infcodes.h -- header to use infcodes.c
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* WARNING: this file should *not* be used by applications. It is
|
|
+ part of the implementation of the compression library and is
|
|
+ subject to change. Applications should only use zlib.h.
|
|
+ */
|
|
+
|
|
+#ifndef _INFCODES_H
|
|
+#define _INFCODES_H
|
|
+
|
|
+struct inflate_codes_state;
|
|
+typedef struct inflate_codes_state FAR inflate_codes_statef;
|
|
+
|
|
+extern inflate_codes_statef *inflate_codes_new OF((
|
|
+ uInt, uInt,
|
|
+ inflate_huft *, inflate_huft *,
|
|
+ z_streamp ));
|
|
+
|
|
+extern int inflate_codes OF((
|
|
+ inflate_blocks_statef *,
|
|
+ z_streamp ,
|
|
+ int));
|
|
+
|
|
+extern void inflate_codes_free OF((
|
|
+ inflate_codes_statef *,
|
|
+ z_streamp ));
|
|
+
|
|
+#endif /* _INFCODES_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/inffast.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,183 @@
|
|
+/* inffast.c -- process literals and length/distance pairs fast
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+#include <zlib/zutil.h>
|
|
+#include "inftrees.h"
|
|
+#include "infblock.h"
|
|
+#include "infcodes.h"
|
|
+#include "infutil.h"
|
|
+#include "inffast.h"
|
|
+
|
|
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
|
|
+
|
|
+/* simplify the use of the inflate_huft type with some defines */
|
|
+#define exop word.what.Exop
|
|
+#define bits word.what.Bits
|
|
+
|
|
+/* macros for bit input with no checking and for returning unused bytes */
|
|
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
|
|
+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
|
|
+
|
|
+/* Called with number of bytes left to write in window at least 258
|
|
+ (the maximum string length) and number of input bytes available
|
|
+ at least ten. The ten bytes are six bytes for the longest length/
|
|
+ distance pair plus four bytes for overloading the bit buffer. */
|
|
+
|
|
+int inflate_fast(bl, bd, tl, td, s, z)
|
|
+uInt bl, bd;
|
|
+inflate_huft *tl;
|
|
+inflate_huft *td; /* need separate declaration for Borland C++ */
|
|
+inflate_blocks_statef *s;
|
|
+z_streamp z;
|
|
+{
|
|
+ inflate_huft *t; /* temporary pointer */
|
|
+ uInt e; /* extra bits or operation */
|
|
+ uLong b; /* bit buffer */
|
|
+ uInt k; /* bits in bit buffer */
|
|
+ Bytef *p; /* input data pointer */
|
|
+ uInt n; /* bytes available there */
|
|
+ Bytef *q; /* output window write pointer */
|
|
+ uInt m; /* bytes to end of window or read pointer */
|
|
+ uInt ml; /* mask for literal/length tree */
|
|
+ uInt md; /* mask for distance tree */
|
|
+ uInt c; /* bytes to copy */
|
|
+ uInt d; /* distance back to copy from */
|
|
+ Bytef *r; /* copy source pointer */
|
|
+
|
|
+ /* load input, output, bit values */
|
|
+ LOAD
|
|
+
|
|
+ /* initialize masks */
|
|
+ ml = inflate_mask[bl];
|
|
+ md = inflate_mask[bd];
|
|
+
|
|
+ /* do until not enough input or output space for fast loop */
|
|
+ do { /* assume called with m >= 258 && n >= 10 */
|
|
+ /* get literal/length code */
|
|
+ GRABBITS(20) /* max bits for literal/length code */
|
|
+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
|
|
+ {
|
|
+ DUMPBITS(t->bits)
|
|
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
|
|
+ "inflate: * literal '%c'\n" :
|
|
+ "inflate: * literal 0x%02x\n", t->base));
|
|
+ *q++ = (Byte)t->base;
|
|
+ m--;
|
|
+ continue;
|
|
+ }
|
|
+ do {
|
|
+ DUMPBITS(t->bits)
|
|
+ if (e & 16)
|
|
+ {
|
|
+ /* get extra bits for length */
|
|
+ e &= 15;
|
|
+ c = t->base + ((uInt)b & inflate_mask[e]);
|
|
+ DUMPBITS(e)
|
|
+ Tracevv((stderr, "inflate: * length %u\n", c));
|
|
+
|
|
+ /* decode distance base of block to copy */
|
|
+ GRABBITS(15); /* max bits for distance code */
|
|
+ e = (t = td + ((uInt)b & md))->exop;
|
|
+ do {
|
|
+ DUMPBITS(t->bits)
|
|
+ if (e & 16)
|
|
+ {
|
|
+ /* get extra bits to add to distance base */
|
|
+ e &= 15;
|
|
+ GRABBITS(e) /* get extra bits (up to 13) */
|
|
+ d = t->base + ((uInt)b & inflate_mask[e]);
|
|
+ DUMPBITS(e)
|
|
+ Tracevv((stderr, "inflate: * distance %u\n", d));
|
|
+
|
|
+ /* do the copy */
|
|
+ m -= c;
|
|
+ r = q - d;
|
|
+ if (r < s->window) /* wrap if needed */
|
|
+ {
|
|
+ do {
|
|
+ r += s->end - s->window; /* force pointer in window */
|
|
+ } while (r < s->window); /* covers invalid distances */
|
|
+ e = s->end - r;
|
|
+ if (c > e)
|
|
+ {
|
|
+ c -= e; /* wrapped copy */
|
|
+ do {
|
|
+ *q++ = *r++;
|
|
+ } while (--e);
|
|
+ r = s->window;
|
|
+ do {
|
|
+ *q++ = *r++;
|
|
+ } while (--c);
|
|
+ }
|
|
+ else /* normal copy */
|
|
+ {
|
|
+ *q++ = *r++; c--;
|
|
+ *q++ = *r++; c--;
|
|
+ do {
|
|
+ *q++ = *r++;
|
|
+ } while (--c);
|
|
+ }
|
|
+ }
|
|
+ else /* normal copy */
|
|
+ {
|
|
+ *q++ = *r++; c--;
|
|
+ *q++ = *r++; c--;
|
|
+ do {
|
|
+ *q++ = *r++;
|
|
+ } while (--c);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ else if ((e & 64) == 0)
|
|
+ {
|
|
+ t += t->base;
|
|
+ e = (t += ((uInt)b & inflate_mask[e]))->exop;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ z->msg = (char*)"invalid distance code";
|
|
+ UNGRAB
|
|
+ UPDATE
|
|
+ return Z_DATA_ERROR;
|
|
+ }
|
|
+ } while (1);
|
|
+ break;
|
|
+ }
|
|
+ if ((e & 64) == 0)
|
|
+ {
|
|
+ t += t->base;
|
|
+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
|
|
+ {
|
|
+ DUMPBITS(t->bits)
|
|
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
|
|
+ "inflate: * literal '%c'\n" :
|
|
+ "inflate: * literal 0x%02x\n", t->base));
|
|
+ *q++ = (Byte)t->base;
|
|
+ m--;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ else if (e & 32)
|
|
+ {
|
|
+ Tracevv((stderr, "inflate: * end of block\n"));
|
|
+ UNGRAB
|
|
+ UPDATE
|
|
+ return Z_STREAM_END;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ z->msg = (char*)"invalid literal/length code";
|
|
+ UNGRAB
|
|
+ UPDATE
|
|
+ return Z_DATA_ERROR;
|
|
+ }
|
|
+ } while (1);
|
|
+ } while (m >= 258 && n >= 10);
|
|
+
|
|
+ /* not enough input or output--restore pointers and return */
|
|
+ UNGRAB
|
|
+ UPDATE
|
|
+ return Z_OK;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/inffast.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,22 @@
|
|
+/* inffast.h -- header to use inffast.c
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* WARNING: this file should *not* be used by applications. It is
|
|
+ part of the implementation of the compression library and is
|
|
+ subject to change. Applications should only use zlib.h.
|
|
+ */
|
|
+
|
|
+#ifndef _INFFAST_H
|
|
+#define _INFFAST_H
|
|
+
|
|
+extern int inflate_fast OF((
|
|
+ uInt,
|
|
+ uInt,
|
|
+ inflate_huft *,
|
|
+ inflate_huft *,
|
|
+ inflate_blocks_statef *,
|
|
+ z_streamp ));
|
|
+
|
|
+#endif /* _INFFAST_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/inffixed.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,151 @@
|
|
+/* inffixed.h -- table for decoding fixed codes
|
|
+ * Generated automatically by the maketree.c program
|
|
+ */
|
|
+
|
|
+/* WARNING: this file should *not* be used by applications. It is
|
|
+ part of the implementation of the compression library and is
|
|
+ subject to change. Applications should only use zlib.h.
|
|
+ */
|
|
+
|
|
+local uInt fixed_bl = 9;
|
|
+local uInt fixed_bd = 5;
|
|
+local inflate_huft fixed_tl[] = {
|
|
+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
|
|
+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
|
|
+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
|
|
+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
|
|
+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
|
|
+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
|
|
+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
|
|
+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
|
|
+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
|
|
+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
|
|
+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
|
|
+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
|
|
+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
|
|
+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
|
|
+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
|
|
+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
|
|
+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
|
|
+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
|
|
+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
|
|
+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
|
|
+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
|
|
+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
|
|
+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
|
|
+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
|
|
+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
|
|
+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
|
|
+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
|
|
+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
|
|
+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
|
|
+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
|
|
+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
|
|
+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
|
|
+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
|
|
+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
|
|
+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
|
|
+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
|
|
+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
|
|
+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
|
|
+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
|
|
+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
|
|
+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
|
|
+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
|
|
+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
|
|
+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
|
|
+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
|
|
+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
|
|
+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
|
|
+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
|
|
+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
|
|
+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
|
|
+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
|
|
+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
|
|
+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
|
|
+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
|
|
+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
|
|
+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
|
|
+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
|
|
+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
|
|
+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
|
|
+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
|
|
+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
|
|
+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
|
|
+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
|
|
+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
|
|
+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
|
|
+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
|
|
+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
|
|
+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
|
|
+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
|
|
+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
|
|
+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
|
|
+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
|
|
+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
|
|
+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
|
|
+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
|
|
+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
|
|
+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
|
|
+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
|
|
+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
|
|
+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
|
|
+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
|
|
+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
|
|
+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
|
|
+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
|
|
+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
|
|
+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
|
|
+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
|
|
+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
|
|
+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
|
|
+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
|
|
+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
|
|
+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
|
|
+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
|
|
+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
|
|
+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
|
|
+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
|
|
+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
|
|
+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
|
|
+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
|
|
+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
|
|
+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
|
|
+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
|
|
+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
|
|
+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
|
|
+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
|
|
+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
|
|
+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
|
|
+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
|
|
+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
|
|
+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
|
|
+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
|
|
+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
|
|
+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
|
|
+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
|
|
+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
|
|
+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
|
|
+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
|
|
+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
|
|
+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
|
|
+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
|
|
+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
|
|
+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
|
|
+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
|
|
+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
|
|
+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
|
|
+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
|
|
+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
|
|
+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
|
|
+ };
|
|
+local inflate_huft fixed_td[] = {
|
|
+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
|
|
+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
|
|
+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
|
|
+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
|
|
+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
|
|
+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
|
|
+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
|
|
+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
|
|
+ };
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/inflate.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,368 @@
|
|
+/* inflate.c -- zlib interface to inflate modules
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+#include <zlib/zutil.h>
|
|
+#include "infblock.h"
|
|
+
|
|
+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
|
|
+
|
|
+typedef enum {
|
|
+ METHOD, /* waiting for method byte */
|
|
+ FLAG, /* waiting for flag byte */
|
|
+ DICT4, /* four dictionary check bytes to go */
|
|
+ DICT3, /* three dictionary check bytes to go */
|
|
+ DICT2, /* two dictionary check bytes to go */
|
|
+ DICT1, /* one dictionary check byte to go */
|
|
+ DICT0, /* waiting for inflateSetDictionary */
|
|
+ BLOCKS, /* decompressing blocks */
|
|
+ CHECK4, /* four check bytes to go */
|
|
+ CHECK3, /* three check bytes to go */
|
|
+ CHECK2, /* two check bytes to go */
|
|
+ CHECK1, /* one check byte to go */
|
|
+ DONE, /* finished check, done */
|
|
+ BAD} /* got an error--stay here */
|
|
+inflate_mode;
|
|
+
|
|
+/* inflate private state */
|
|
+struct internal_state {
|
|
+
|
|
+ /* mode */
|
|
+ inflate_mode mode; /* current inflate mode */
|
|
+
|
|
+ /* mode dependent information */
|
|
+ union {
|
|
+ uInt method; /* if FLAGS, method byte */
|
|
+ struct {
|
|
+ uLong was; /* computed check value */
|
|
+ uLong need; /* stream check value */
|
|
+ } check; /* if CHECK, check values to compare */
|
|
+ uInt marker; /* if BAD, inflateSync's marker bytes count */
|
|
+ } sub; /* submode */
|
|
+
|
|
+ /* mode independent information */
|
|
+ int nowrap; /* flag for no wrapper */
|
|
+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
|
|
+ inflate_blocks_statef
|
|
+ *blocks; /* current inflate_blocks state */
|
|
+
|
|
+};
|
|
+
|
|
+
|
|
+int ZEXPORT inflateReset(z)
|
|
+z_streamp z;
|
|
+{
|
|
+ if (z == Z_NULL || z->state == Z_NULL)
|
|
+ return Z_STREAM_ERROR;
|
|
+ z->total_in = z->total_out = 0;
|
|
+ z->msg = Z_NULL;
|
|
+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
|
|
+ inflate_blocks_reset(z->state->blocks, z, Z_NULL);
|
|
+ Tracev((stderr, "inflate: reset\n"));
|
|
+ return Z_OK;
|
|
+}
|
|
+
|
|
+
|
|
+int ZEXPORT inflateEnd(z)
|
|
+z_streamp z;
|
|
+{
|
|
+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
|
|
+ return Z_STREAM_ERROR;
|
|
+ if (z->state->blocks != Z_NULL)
|
|
+ inflate_blocks_free(z->state->blocks, z);
|
|
+ ZFREE(z, z->state);
|
|
+ z->state = Z_NULL;
|
|
+ Tracev((stderr, "inflate: end\n"));
|
|
+ return Z_OK;
|
|
+}
|
|
+
|
|
+
|
|
+int ZEXPORT inflateInit2_(z, w, version, stream_size)
|
|
+z_streamp z;
|
|
+int w;
|
|
+const char *version;
|
|
+int stream_size;
|
|
+{
|
|
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
|
|
+ stream_size != sizeof(z_stream))
|
|
+ return Z_VERSION_ERROR;
|
|
+
|
|
+ /* initialize state */
|
|
+ if (z == Z_NULL)
|
|
+ return Z_STREAM_ERROR;
|
|
+ z->msg = Z_NULL;
|
|
+ if (z->zalloc == Z_NULL)
|
|
+ {
|
|
+ return Z_STREAM_ERROR;
|
|
+/* z->zalloc = zcalloc;
|
|
+ z->opaque = (voidpf)0;
|
|
+*/
|
|
+ }
|
|
+ if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
|
|
+ if ((z->state = (struct internal_state FAR *)
|
|
+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
|
|
+ return Z_MEM_ERROR;
|
|
+ z->state->blocks = Z_NULL;
|
|
+
|
|
+ /* handle undocumented nowrap option (no zlib header or check) */
|
|
+ z->state->nowrap = 0;
|
|
+ if (w < 0)
|
|
+ {
|
|
+ w = - w;
|
|
+ z->state->nowrap = 1;
|
|
+ }
|
|
+
|
|
+ /* set window size */
|
|
+ if (w < 8 || w > 15)
|
|
+ {
|
|
+ inflateEnd(z);
|
|
+ return Z_STREAM_ERROR;
|
|
+ }
|
|
+ z->state->wbits = (uInt)w;
|
|
+
|
|
+ /* create inflate_blocks state */
|
|
+ if ((z->state->blocks =
|
|
+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
|
|
+ == Z_NULL)
|
|
+ {
|
|
+ inflateEnd(z);
|
|
+ return Z_MEM_ERROR;
|
|
+ }
|
|
+ Tracev((stderr, "inflate: allocated\n"));
|
|
+
|
|
+ /* reset state */
|
|
+ inflateReset(z);
|
|
+ return Z_OK;
|
|
+}
|
|
+
|
|
+
|
|
+int ZEXPORT inflateInit_(z, version, stream_size)
|
|
+z_streamp z;
|
|
+const char *version;
|
|
+int stream_size;
|
|
+{
|
|
+ return inflateInit2_(z, DEF_WBITS, version, stream_size);
|
|
+}
|
|
+
|
|
+
|
|
+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
|
|
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
|
|
+
|
|
+int ZEXPORT inflate(z, f)
|
|
+z_streamp z;
|
|
+int f;
|
|
+{
|
|
+ int r;
|
|
+ uInt b;
|
|
+
|
|
+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
|
|
+ return Z_STREAM_ERROR;
|
|
+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
|
|
+ r = Z_BUF_ERROR;
|
|
+ while (1) switch (z->state->mode)
|
|
+ {
|
|
+ case METHOD:
|
|
+ NEEDBYTE
|
|
+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
|
|
+ {
|
|
+ z->state->mode = BAD;
|
|
+ z->msg = (char*)"unknown compression method";
|
|
+ z->state->sub.marker = 5; /* can't try inflateSync */
|
|
+ break;
|
|
+ }
|
|
+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
|
|
+ {
|
|
+ z->state->mode = BAD;
|
|
+ z->msg = (char*)"invalid window size";
|
|
+ z->state->sub.marker = 5; /* can't try inflateSync */
|
|
+ break;
|
|
+ }
|
|
+ z->state->mode = FLAG;
|
|
+ case FLAG:
|
|
+ NEEDBYTE
|
|
+ b = NEXTBYTE;
|
|
+ if (((z->state->sub.method << 8) + b) % 31)
|
|
+ {
|
|
+ z->state->mode = BAD;
|
|
+ z->msg = (char*)"incorrect header check";
|
|
+ z->state->sub.marker = 5; /* can't try inflateSync */
|
|
+ break;
|
|
+ }
|
|
+ Tracev((stderr, "inflate: zlib header ok\n"));
|
|
+ if (!(b & PRESET_DICT))
|
|
+ {
|
|
+ z->state->mode = BLOCKS;
|
|
+ break;
|
|
+ }
|
|
+ z->state->mode = DICT4;
|
|
+ case DICT4:
|
|
+ NEEDBYTE
|
|
+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
|
|
+ z->state->mode = DICT3;
|
|
+ case DICT3:
|
|
+ NEEDBYTE
|
|
+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
|
|
+ z->state->mode = DICT2;
|
|
+ case DICT2:
|
|
+ NEEDBYTE
|
|
+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
|
|
+ z->state->mode = DICT1;
|
|
+ case DICT1:
|
|
+ NEEDBYTE
|
|
+ z->state->sub.check.need += (uLong)NEXTBYTE;
|
|
+ z->adler = z->state->sub.check.need;
|
|
+ z->state->mode = DICT0;
|
|
+ return Z_NEED_DICT;
|
|
+ case DICT0:
|
|
+ z->state->mode = BAD;
|
|
+ z->msg = (char*)"need dictionary";
|
|
+ z->state->sub.marker = 0; /* can try inflateSync */
|
|
+ return Z_STREAM_ERROR;
|
|
+ case BLOCKS:
|
|
+ r = inflate_blocks(z->state->blocks, z, r);
|
|
+ if (r == Z_DATA_ERROR)
|
|
+ {
|
|
+ z->state->mode = BAD;
|
|
+ z->state->sub.marker = 0; /* can try inflateSync */
|
|
+ break;
|
|
+ }
|
|
+ if (r == Z_OK)
|
|
+ r = f;
|
|
+ if (r != Z_STREAM_END)
|
|
+ return r;
|
|
+ r = f;
|
|
+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
|
|
+ if (z->state->nowrap)
|
|
+ {
|
|
+ z->state->mode = DONE;
|
|
+ break;
|
|
+ }
|
|
+ z->state->mode = CHECK4;
|
|
+ case CHECK4:
|
|
+ NEEDBYTE
|
|
+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
|
|
+ z->state->mode = CHECK3;
|
|
+ case CHECK3:
|
|
+ NEEDBYTE
|
|
+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
|
|
+ z->state->mode = CHECK2;
|
|
+ case CHECK2:
|
|
+ NEEDBYTE
|
|
+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
|
|
+ z->state->mode = CHECK1;
|
|
+ case CHECK1:
|
|
+ NEEDBYTE
|
|
+ z->state->sub.check.need += (uLong)NEXTBYTE;
|
|
+
|
|
+ if (z->state->sub.check.was != z->state->sub.check.need)
|
|
+ {
|
|
+ z->state->mode = BAD;
|
|
+ z->msg = (char*)"incorrect data check";
|
|
+ z->state->sub.marker = 5; /* can't try inflateSync */
|
|
+ break;
|
|
+ }
|
|
+ Tracev((stderr, "inflate: zlib check ok\n"));
|
|
+ z->state->mode = DONE;
|
|
+ case DONE:
|
|
+ return Z_STREAM_END;
|
|
+ case BAD:
|
|
+ return Z_DATA_ERROR;
|
|
+ default:
|
|
+ return Z_STREAM_ERROR;
|
|
+ }
|
|
+#ifdef NEED_DUMMY_RETURN
|
|
+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
|
|
+#endif
|
|
+}
|
|
+
|
|
+
|
|
+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
|
|
+z_streamp z;
|
|
+const Bytef *dictionary;
|
|
+uInt dictLength;
|
|
+{
|
|
+ uInt length = dictLength;
|
|
+
|
|
+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
|
|
+ return Z_STREAM_ERROR;
|
|
+
|
|
+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
|
|
+ z->adler = 1L;
|
|
+
|
|
+ if (length >= ((uInt)1<<z->state->wbits))
|
|
+ {
|
|
+ length = (1<<z->state->wbits)-1;
|
|
+ dictionary += dictLength - length;
|
|
+ }
|
|
+ inflate_set_dictionary(z->state->blocks, dictionary, length);
|
|
+ z->state->mode = BLOCKS;
|
|
+ return Z_OK;
|
|
+}
|
|
+
|
|
+
|
|
+int ZEXPORT inflateSync(z)
|
|
+z_streamp z;
|
|
+{
|
|
+ uInt n; /* number of bytes to look at */
|
|
+ Bytef *p; /* pointer to bytes */
|
|
+ uInt m; /* number of marker bytes found in a row */
|
|
+ uLong r, w; /* temporaries to save total_in and total_out */
|
|
+
|
|
+ /* set up */
|
|
+ if (z == Z_NULL || z->state == Z_NULL)
|
|
+ return Z_STREAM_ERROR;
|
|
+ if (z->state->mode != BAD)
|
|
+ {
|
|
+ z->state->mode = BAD;
|
|
+ z->state->sub.marker = 0;
|
|
+ }
|
|
+ if ((n = z->avail_in) == 0)
|
|
+ return Z_BUF_ERROR;
|
|
+ p = z->next_in;
|
|
+ m = z->state->sub.marker;
|
|
+
|
|
+ /* search */
|
|
+ while (n && m < 4)
|
|
+ {
|
|
+ static const Byte mark[4] = {0, 0, 0xff, 0xff};
|
|
+ if (*p == mark[m])
|
|
+ m++;
|
|
+ else if (*p)
|
|
+ m = 0;
|
|
+ else
|
|
+ m = 4 - m;
|
|
+ p++, n--;
|
|
+ }
|
|
+
|
|
+ /* restore */
|
|
+ z->total_in += p - z->next_in;
|
|
+ z->next_in = p;
|
|
+ z->avail_in = n;
|
|
+ z->state->sub.marker = m;
|
|
+
|
|
+ /* return no joy or set up to restart on a new block */
|
|
+ if (m != 4)
|
|
+ return Z_DATA_ERROR;
|
|
+ r = z->total_in; w = z->total_out;
|
|
+ inflateReset(z);
|
|
+ z->total_in = r; z->total_out = w;
|
|
+ z->state->mode = BLOCKS;
|
|
+ return Z_OK;
|
|
+}
|
|
+
|
|
+
|
|
+/* Returns true if inflate is currently at the end of a block generated
|
|
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
|
|
+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
|
|
+ * but removes the length bytes of the resulting empty stored block. When
|
|
+ * decompressing, PPP checks that at the end of input packet, inflate is
|
|
+ * waiting for these length bytes.
|
|
+ */
|
|
+int ZEXPORT inflateSyncPoint(z)
|
|
+z_streamp z;
|
|
+{
|
|
+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
|
|
+ return Z_STREAM_ERROR;
|
|
+ return inflate_blocks_sync_point(z->state->blocks);
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/inftrees.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,454 @@
|
|
+/* inftrees.c -- generate Huffman trees for efficient decoding
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+#include <zlib/zutil.h>
|
|
+#include "inftrees.h"
|
|
+
|
|
+#if !defined(BUILDFIXED) && !defined(STDC)
|
|
+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
|
|
+#endif
|
|
+
|
|
+local const char inflate_copyright[] =
|
|
+ " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
|
|
+/*
|
|
+ If you use the zlib library in a product, an acknowledgment is welcome
|
|
+ in the documentation of your product. If for some reason you cannot
|
|
+ include such an acknowledgment, I would appreciate that you keep this
|
|
+ copyright string in the executable of your product.
|
|
+ */
|
|
+struct internal_state {int dummy;}; /* for buggy compilers */
|
|
+
|
|
+/* simplify the use of the inflate_huft type with some defines */
|
|
+#define exop word.what.Exop
|
|
+#define bits word.what.Bits
|
|
+
|
|
+
|
|
+local int huft_build OF((
|
|
+ uIntf *, /* code lengths in bits */
|
|
+ uInt, /* number of codes */
|
|
+ uInt, /* number of "simple" codes */
|
|
+ const uIntf *, /* list of base values for non-simple codes */
|
|
+ const uIntf *, /* list of extra bits for non-simple codes */
|
|
+ inflate_huft * FAR*,/* result: starting table */
|
|
+ uIntf *, /* maximum lookup bits (returns actual) */
|
|
+ inflate_huft *, /* space for trees */
|
|
+ uInt *, /* hufts used in space */
|
|
+ uIntf * )); /* space for values */
|
|
+
|
|
+/* Tables for deflate from PKZIP's appnote.txt. */
|
|
+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
|
|
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
|
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
|
+ /* see note #13 above about 258 */
|
|
+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
|
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
|
|
+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
|
|
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
|
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
|
+ 8193, 12289, 16385, 24577};
|
|
+local const uInt cpdext[30] = { /* Extra bits for distance codes */
|
|
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
|
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
|
+ 12, 12, 13, 13};
|
|
+
|
|
+/*
|
|
+ Huffman code decoding is performed using a multi-level table lookup.
|
|
+ The fastest way to decode is to simply build a lookup table whose
|
|
+ size is determined by the longest code. However, the time it takes
|
|
+ to build this table can also be a factor if the data being decoded
|
|
+ is not very long. The most common codes are necessarily the
|
|
+ shortest codes, so those codes dominate the decoding time, and hence
|
|
+ the speed. The idea is you can have a shorter table that decodes the
|
|
+ shorter, more probable codes, and then point to subsidiary tables for
|
|
+ the longer codes. The time it costs to decode the longer codes is
|
|
+ then traded against the time it takes to make longer tables.
|
|
+
|
|
+ This results of this trade are in the variables lbits and dbits
|
|
+ below. lbits is the number of bits the first level table for literal/
|
|
+ length codes can decode in one step, and dbits is the same thing for
|
|
+ the distance codes. Subsequent tables are also less than or equal to
|
|
+ those sizes. These values may be adjusted either when all of the
|
|
+ codes are shorter than that, in which case the longest code length in
|
|
+ bits is used, or when the shortest code is *longer* than the requested
|
|
+ table size, in which case the length of the shortest code in bits is
|
|
+ used.
|
|
+
|
|
+ There are two different values for the two tables, since they code a
|
|
+ different number of possibilities each. The literal/length table
|
|
+ codes 286 possible values, or in a flat code, a little over eight
|
|
+ bits. The distance table codes 30 possible values, or a little less
|
|
+ than five bits, flat. The optimum values for speed end up being
|
|
+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
|
|
+ The optimum values may differ though from machine to machine, and
|
|
+ possibly even between compilers. Your mileage may vary.
|
|
+ */
|
|
+
|
|
+
|
|
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
|
|
+#define BMAX 15 /* maximum bit length of any code */
|
|
+
|
|
+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
|
|
+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
|
|
+uInt n; /* number of codes (assumed <= 288) */
|
|
+uInt s; /* number of simple-valued codes (0..s-1) */
|
|
+const uIntf *d; /* list of base values for non-simple codes */
|
|
+const uIntf *e; /* list of extra bits for non-simple codes */
|
|
+inflate_huft * FAR *t; /* result: starting table */
|
|
+uIntf *m; /* maximum lookup bits, returns actual */
|
|
+inflate_huft *hp; /* space for trees */
|
|
+uInt *hn; /* hufts used in space */
|
|
+uIntf *v; /* working area: values in order of bit length */
|
|
+/* Given a list of code lengths and a maximum table size, make a set of
|
|
+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
|
|
+ if the given code set is incomplete (the tables are still built in this
|
|
+ case), or Z_DATA_ERROR if the input is invalid. */
|
|
+{
|
|
+
|
|
+ uInt a; /* counter for codes of length k */
|
|
+ uInt c[BMAX+1]; /* bit length count table */
|
|
+ uInt f; /* i repeats in table every f entries */
|
|
+ int g; /* maximum code length */
|
|
+ int h; /* table level */
|
|
+ register uInt i; /* counter, current code */
|
|
+ register uInt j; /* counter */
|
|
+ register int k; /* number of bits in current code */
|
|
+ int l; /* bits per table (returned in m) */
|
|
+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
|
|
+ register uIntf *p; /* pointer into c[], b[], or v[] */
|
|
+ inflate_huft *q; /* points to current table */
|
|
+ struct inflate_huft_s r; /* table entry for structure assignment */
|
|
+ inflate_huft *u[BMAX]; /* table stack */
|
|
+ register int w; /* bits before this table == (l * h) */
|
|
+ uInt x[BMAX+1]; /* bit offsets, then code stack */
|
|
+ uIntf *xp; /* pointer into x */
|
|
+ int y; /* number of dummy codes added */
|
|
+ uInt z; /* number of entries in current table */
|
|
+
|
|
+
|
|
+ /* Generate counts for each bit length */
|
|
+ p = c;
|
|
+#define C0 *p++ = 0;
|
|
+#define C2 C0 C0 C0 C0
|
|
+#define C4 C2 C2 C2 C2
|
|
+ C4 /* clear c[]--assume BMAX+1 is 16 */
|
|
+ p = b; i = n;
|
|
+ do {
|
|
+ c[*p++]++; /* assume all entries <= BMAX */
|
|
+ } while (--i);
|
|
+ if (c[0] == n) /* null input--all zero length codes */
|
|
+ {
|
|
+ *t = (inflate_huft *)Z_NULL;
|
|
+ *m = 0;
|
|
+ return Z_OK;
|
|
+ }
|
|
+
|
|
+
|
|
+ /* Find minimum and maximum length, bound *m by those */
|
|
+ l = *m;
|
|
+ for (j = 1; j <= BMAX; j++)
|
|
+ if (c[j])
|
|
+ break;
|
|
+ k = j; /* minimum code length */
|
|
+ if ((uInt)l < j)
|
|
+ l = j;
|
|
+ for (i = BMAX; i; i--)
|
|
+ if (c[i])
|
|
+ break;
|
|
+ g = i; /* maximum code length */
|
|
+ if ((uInt)l > i)
|
|
+ l = i;
|
|
+ *m = l;
|
|
+
|
|
+
|
|
+ /* Adjust last length count to fill out codes, if needed */
|
|
+ for (y = 1 << j; j < i; j++, y <<= 1)
|
|
+ if ((y -= c[j]) < 0)
|
|
+ return Z_DATA_ERROR;
|
|
+ if ((y -= c[i]) < 0)
|
|
+ return Z_DATA_ERROR;
|
|
+ c[i] += y;
|
|
+
|
|
+
|
|
+ /* Generate starting offsets into the value table for each length */
|
|
+ x[1] = j = 0;
|
|
+ p = c + 1; xp = x + 2;
|
|
+ while (--i) { /* note that i == g from above */
|
|
+ *xp++ = (j += *p++);
|
|
+ }
|
|
+
|
|
+
|
|
+ /* Make a table of values in order of bit lengths */
|
|
+ p = b; i = 0;
|
|
+ do {
|
|
+ if ((j = *p++) != 0)
|
|
+ v[x[j]++] = i;
|
|
+ } while (++i < n);
|
|
+ n = x[g]; /* set n to length of v */
|
|
+
|
|
+
|
|
+ /* Generate the Huffman codes and for each, make the table entries */
|
|
+ x[0] = i = 0; /* first Huffman code is zero */
|
|
+ p = v; /* grab values in bit order */
|
|
+ h = -1; /* no tables yet--level -1 */
|
|
+ w = -l; /* bits decoded == (l * h) */
|
|
+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
|
|
+ q = (inflate_huft *)Z_NULL; /* ditto */
|
|
+ z = 0; /* ditto */
|
|
+
|
|
+ /* go through the bit lengths (k already is bits in shortest code) */
|
|
+ for (; k <= g; k++)
|
|
+ {
|
|
+ a = c[k];
|
|
+ while (a--)
|
|
+ {
|
|
+ /* here i is the Huffman code of length k bits for value *p */
|
|
+ /* make tables up to required level */
|
|
+ while (k > w + l)
|
|
+ {
|
|
+ h++;
|
|
+ w += l; /* previous table always l bits */
|
|
+
|
|
+ /* compute minimum size table less than or equal to l bits */
|
|
+ z = g - w;
|
|
+ z = z > (uInt)l ? l : z; /* table size upper limit */
|
|
+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
|
|
+ { /* too few codes for k-w bit table */
|
|
+ f -= a + 1; /* deduct codes from patterns left */
|
|
+ xp = c + k;
|
|
+ if (j < z)
|
|
+ while (++j < z) /* try smaller tables up to z bits */
|
|
+ {
|
|
+ if ((f <<= 1) <= *++xp)
|
|
+ break; /* enough codes to use up j bits */
|
|
+ f -= *xp; /* else deduct codes from patterns */
|
|
+ }
|
|
+ }
|
|
+ z = 1 << j; /* table entries for j-bit table */
|
|
+
|
|
+ /* allocate new table */
|
|
+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
|
|
+ return Z_DATA_ERROR; /* overflow of MANY */
|
|
+ u[h] = q = hp + *hn;
|
|
+ *hn += z;
|
|
+
|
|
+ /* connect to last table, if there is one */
|
|
+ if (h)
|
|
+ {
|
|
+ x[h] = i; /* save pattern for backing up */
|
|
+ r.bits = (Byte)l; /* bits to dump before this table */
|
|
+ r.exop = (Byte)j; /* bits in this table */
|
|
+ j = i >> (w - l);
|
|
+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
|
|
+ u[h-1][j] = r; /* connect to last table */
|
|
+ }
|
|
+ else
|
|
+ *t = q; /* first table is returned result */
|
|
+ }
|
|
+
|
|
+ /* set up table entry in r */
|
|
+ r.bits = (Byte)(k - w);
|
|
+ if (p >= v + n)
|
|
+ r.exop = 128 + 64; /* out of values--invalid code */
|
|
+ else if (*p < s)
|
|
+ {
|
|
+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
|
|
+ r.base = *p++; /* simple code is just the value */
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
|
|
+ r.base = d[*p++ - s];
|
|
+ }
|
|
+
|
|
+ /* fill code-like entries with r */
|
|
+ f = 1 << (k - w);
|
|
+ for (j = i >> w; j < z; j += f)
|
|
+ q[j] = r;
|
|
+
|
|
+ /* backwards increment the k-bit code i */
|
|
+ for (j = 1 << (k - 1); i & j; j >>= 1)
|
|
+ i ^= j;
|
|
+ i ^= j;
|
|
+
|
|
+ /* backup over finished tables */
|
|
+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */
|
|
+ while ((i & mask) != x[h])
|
|
+ {
|
|
+ h--; /* don't need to update q */
|
|
+ w -= l;
|
|
+ mask = (1 << w) - 1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ /* Return Z_BUF_ERROR if we were given an incomplete table */
|
|
+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
|
|
+}
|
|
+
|
|
+
|
|
+int inflate_trees_bits(c, bb, tb, hp, z)
|
|
+uIntf *c; /* 19 code lengths */
|
|
+uIntf *bb; /* bits tree desired/actual depth */
|
|
+inflate_huft * FAR *tb; /* bits tree result */
|
|
+inflate_huft *hp; /* space for trees */
|
|
+z_streamp z; /* for messages */
|
|
+{
|
|
+ int r;
|
|
+ uInt hn = 0; /* hufts used in space */
|
|
+ uIntf *v; /* work area for huft_build */
|
|
+
|
|
+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
|
|
+ return Z_MEM_ERROR;
|
|
+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
|
|
+ tb, bb, hp, &hn, v);
|
|
+ if (r == Z_DATA_ERROR)
|
|
+ z->msg = (char*)"oversubscribed dynamic bit lengths tree";
|
|
+ else if (r == Z_BUF_ERROR || *bb == 0)
|
|
+ {
|
|
+ z->msg = (char*)"incomplete dynamic bit lengths tree";
|
|
+ r = Z_DATA_ERROR;
|
|
+ }
|
|
+ ZFREE(z, v);
|
|
+ return r;
|
|
+}
|
|
+
|
|
+
|
|
+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
|
|
+uInt nl; /* number of literal/length codes */
|
|
+uInt nd; /* number of distance codes */
|
|
+uIntf *c; /* that many (total) code lengths */
|
|
+uIntf *bl; /* literal desired/actual bit depth */
|
|
+uIntf *bd; /* distance desired/actual bit depth */
|
|
+inflate_huft * FAR *tl; /* literal/length tree result */
|
|
+inflate_huft * FAR *td; /* distance tree result */
|
|
+inflate_huft *hp; /* space for trees */
|
|
+z_streamp z; /* for messages */
|
|
+{
|
|
+ int r;
|
|
+ uInt hn = 0; /* hufts used in space */
|
|
+ uIntf *v; /* work area for huft_build */
|
|
+
|
|
+ /* allocate work area */
|
|
+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
|
|
+ return Z_MEM_ERROR;
|
|
+
|
|
+ /* build literal/length tree */
|
|
+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
|
|
+ if (r != Z_OK || *bl == 0)
|
|
+ {
|
|
+ if (r == Z_DATA_ERROR)
|
|
+ z->msg = (char*)"oversubscribed literal/length tree";
|
|
+ else if (r != Z_MEM_ERROR)
|
|
+ {
|
|
+ z->msg = (char*)"incomplete literal/length tree";
|
|
+ r = Z_DATA_ERROR;
|
|
+ }
|
|
+ ZFREE(z, v);
|
|
+ return r;
|
|
+ }
|
|
+
|
|
+ /* build distance tree */
|
|
+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
|
|
+ if (r != Z_OK || (*bd == 0 && nl > 257))
|
|
+ {
|
|
+ if (r == Z_DATA_ERROR)
|
|
+ z->msg = (char*)"oversubscribed distance tree";
|
|
+ else if (r == Z_BUF_ERROR) {
|
|
+#ifdef PKZIP_BUG_WORKAROUND
|
|
+ r = Z_OK;
|
|
+ }
|
|
+#else
|
|
+ z->msg = (char*)"incomplete distance tree";
|
|
+ r = Z_DATA_ERROR;
|
|
+ }
|
|
+ else if (r != Z_MEM_ERROR)
|
|
+ {
|
|
+ z->msg = (char*)"empty distance tree with lengths";
|
|
+ r = Z_DATA_ERROR;
|
|
+ }
|
|
+ ZFREE(z, v);
|
|
+ return r;
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ /* done */
|
|
+ ZFREE(z, v);
|
|
+ return Z_OK;
|
|
+}
|
|
+
|
|
+
|
|
+/* build fixed tables only once--keep them here */
|
|
+#ifdef BUILDFIXED
|
|
+local int fixed_built = 0;
|
|
+#define FIXEDH 544 /* number of hufts used by fixed tables */
|
|
+local inflate_huft fixed_mem[FIXEDH];
|
|
+local uInt fixed_bl;
|
|
+local uInt fixed_bd;
|
|
+local inflate_huft *fixed_tl;
|
|
+local inflate_huft *fixed_td;
|
|
+#else
|
|
+#include "inffixed.h"
|
|
+#endif
|
|
+
|
|
+
|
|
+int inflate_trees_fixed(bl, bd, tl, td, z)
|
|
+uIntf *bl; /* literal desired/actual bit depth */
|
|
+uIntf *bd; /* distance desired/actual bit depth */
|
|
+inflate_huft * FAR *tl; /* literal/length tree result */
|
|
+inflate_huft * FAR *td; /* distance tree result */
|
|
+z_streamp z; /* for memory allocation */
|
|
+{
|
|
+#ifdef BUILDFIXED
|
|
+ /* build fixed tables if not already */
|
|
+ if (!fixed_built)
|
|
+ {
|
|
+ int k; /* temporary variable */
|
|
+ uInt f = 0; /* number of hufts used in fixed_mem */
|
|
+ uIntf *c; /* length list for huft_build */
|
|
+ uIntf *v; /* work area for huft_build */
|
|
+
|
|
+ /* allocate memory */
|
|
+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
|
|
+ return Z_MEM_ERROR;
|
|
+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
|
|
+ {
|
|
+ ZFREE(z, c);
|
|
+ return Z_MEM_ERROR;
|
|
+ }
|
|
+
|
|
+ /* literal table */
|
|
+ for (k = 0; k < 144; k++)
|
|
+ c[k] = 8;
|
|
+ for (; k < 256; k++)
|
|
+ c[k] = 9;
|
|
+ for (; k < 280; k++)
|
|
+ c[k] = 7;
|
|
+ for (; k < 288; k++)
|
|
+ c[k] = 8;
|
|
+ fixed_bl = 9;
|
|
+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
|
|
+ fixed_mem, &f, v);
|
|
+
|
|
+ /* distance table */
|
|
+ for (k = 0; k < 30; k++)
|
|
+ c[k] = 5;
|
|
+ fixed_bd = 5;
|
|
+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
|
|
+ fixed_mem, &f, v);
|
|
+
|
|
+ /* done */
|
|
+ ZFREE(z, v);
|
|
+ ZFREE(z, c);
|
|
+ fixed_built = 1;
|
|
+ }
|
|
+#endif
|
|
+ *bl = fixed_bl;
|
|
+ *bd = fixed_bd;
|
|
+ *tl = fixed_tl;
|
|
+ *td = fixed_td;
|
|
+ return Z_OK;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/inftrees.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,63 @@
|
|
+/* inftrees.h -- header to use inftrees.c
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* WARNING: this file should *not* be used by applications. It is
|
|
+ part of the implementation of the compression library and is
|
|
+ subject to change. Applications should only use zlib.h.
|
|
+ */
|
|
+
|
|
+/* Huffman code lookup table entry--this entry is four bytes for machines
|
|
+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
|
|
+
|
|
+#ifndef _INFTREES_H
|
|
+#define _INFTREES_H
|
|
+
|
|
+typedef struct inflate_huft_s FAR inflate_huft;
|
|
+
|
|
+struct inflate_huft_s {
|
|
+ union {
|
|
+ struct {
|
|
+ Byte Exop; /* number of extra bits or operation */
|
|
+ Byte Bits; /* number of bits in this code or subcode */
|
|
+ } what;
|
|
+ uInt pad; /* pad structure to a power of 2 (4 bytes for */
|
|
+ } word; /* 16-bit, 8 bytes for 32-bit int's) */
|
|
+ uInt base; /* literal, length base, distance base,
|
|
+ or table offset */
|
|
+};
|
|
+
|
|
+/* Maximum size of dynamic tree. The maximum found in a long but non-
|
|
+ exhaustive search was 1004 huft structures (850 for length/literals
|
|
+ and 154 for distances, the latter actually the result of an
|
|
+ exhaustive search). The actual maximum is not known, but the
|
|
+ value below is more than safe. */
|
|
+#define MANY 1440
|
|
+
|
|
+extern int inflate_trees_bits OF((
|
|
+ uIntf *, /* 19 code lengths */
|
|
+ uIntf *, /* bits tree desired/actual depth */
|
|
+ inflate_huft * FAR *, /* bits tree result */
|
|
+ inflate_huft *, /* space for trees */
|
|
+ z_streamp)); /* for messages */
|
|
+
|
|
+extern int inflate_trees_dynamic OF((
|
|
+ uInt, /* number of literal/length codes */
|
|
+ uInt, /* number of distance codes */
|
|
+ uIntf *, /* that many (total) code lengths */
|
|
+ uIntf *, /* literal desired/actual bit depth */
|
|
+ uIntf *, /* distance desired/actual bit depth */
|
|
+ inflate_huft * FAR *, /* literal/length tree result */
|
|
+ inflate_huft * FAR *, /* distance tree result */
|
|
+ inflate_huft *, /* space for trees */
|
|
+ z_streamp)); /* for messages */
|
|
+
|
|
+extern int inflate_trees_fixed OF((
|
|
+ uIntf *, /* literal desired/actual bit depth */
|
|
+ uIntf *, /* distance desired/actual bit depth */
|
|
+ inflate_huft * FAR *, /* literal/length tree result */
|
|
+ inflate_huft * FAR *, /* distance tree result */
|
|
+ z_streamp)); /* for memory allocation */
|
|
+
|
|
+#endif /* _INFTREES_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/infutil.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,87 @@
|
|
+/* inflate_util.c -- data and routines common to blocks and codes
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+#include <zlib/zutil.h>
|
|
+#include "infblock.h"
|
|
+#include "inftrees.h"
|
|
+#include "infcodes.h"
|
|
+#include "infutil.h"
|
|
+
|
|
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
|
|
+
|
|
+/* And'ing with mask[n] masks the lower n bits */
|
|
+uInt inflate_mask[17] = {
|
|
+ 0x0000,
|
|
+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
|
+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
|
+};
|
|
+
|
|
+
|
|
+/* copy as much as possible from the sliding window to the output area */
|
|
+int inflate_flush(s, z, r)
|
|
+inflate_blocks_statef *s;
|
|
+z_streamp z;
|
|
+int r;
|
|
+{
|
|
+ uInt n;
|
|
+ Bytef *p;
|
|
+ Bytef *q;
|
|
+
|
|
+ /* local copies of source and destination pointers */
|
|
+ p = z->next_out;
|
|
+ q = s->read;
|
|
+
|
|
+ /* compute number of bytes to copy as far as end of window */
|
|
+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
|
|
+ if (n > z->avail_out) n = z->avail_out;
|
|
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
|
|
+
|
|
+ /* update counters */
|
|
+ z->avail_out -= n;
|
|
+ z->total_out += n;
|
|
+
|
|
+ /* update check information */
|
|
+ if (s->checkfn != Z_NULL)
|
|
+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
|
|
+
|
|
+ /* copy as far as end of window */
|
|
+ zmemcpy(p, q, n);
|
|
+ p += n;
|
|
+ q += n;
|
|
+
|
|
+ /* see if more to copy at beginning of window */
|
|
+ if (q == s->end)
|
|
+ {
|
|
+ /* wrap pointers */
|
|
+ q = s->window;
|
|
+ if (s->write == s->end)
|
|
+ s->write = s->window;
|
|
+
|
|
+ /* compute bytes to copy */
|
|
+ n = (uInt)(s->write - q);
|
|
+ if (n > z->avail_out) n = z->avail_out;
|
|
+ if (n && r == Z_BUF_ERROR) r = Z_OK;
|
|
+
|
|
+ /* update counters */
|
|
+ z->avail_out -= n;
|
|
+ z->total_out += n;
|
|
+
|
|
+ /* update check information */
|
|
+ if (s->checkfn != Z_NULL)
|
|
+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
|
|
+
|
|
+ /* copy */
|
|
+ zmemcpy(p, q, n);
|
|
+ p += n;
|
|
+ q += n;
|
|
+ }
|
|
+
|
|
+ /* update pointers */
|
|
+ z->next_out = p;
|
|
+ s->read = q;
|
|
+
|
|
+ /* done */
|
|
+ return r;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/infutil.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,98 @@
|
|
+/* infutil.h -- types and macros common to blocks and codes
|
|
+ * Copyright (C) 1995-2002 Mark Adler
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* WARNING: this file should *not* be used by applications. It is
|
|
+ part of the implementation of the compression library and is
|
|
+ subject to change. Applications should only use zlib.h.
|
|
+ */
|
|
+
|
|
+#ifndef _INFUTIL_H
|
|
+#define _INFUTIL_H
|
|
+
|
|
+typedef enum {
|
|
+ TYPE, /* get type bits (3, including end bit) */
|
|
+ LENS, /* get lengths for stored */
|
|
+ STORED, /* processing stored block */
|
|
+ TABLE, /* get table lengths */
|
|
+ BTREE, /* get bit lengths tree for a dynamic block */
|
|
+ DTREE, /* get length, distance trees for a dynamic block */
|
|
+ CODES, /* processing fixed or dynamic block */
|
|
+ DRY, /* output remaining window bytes */
|
|
+ DONE, /* finished last block, done */
|
|
+ BAD} /* got a data error--stuck here */
|
|
+inflate_block_mode;
|
|
+
|
|
+/* inflate blocks semi-private state */
|
|
+struct inflate_blocks_state {
|
|
+
|
|
+ /* mode */
|
|
+ inflate_block_mode mode; /* current inflate_block mode */
|
|
+
|
|
+ /* mode dependent information */
|
|
+ union {
|
|
+ uInt left; /* if STORED, bytes left to copy */
|
|
+ struct {
|
|
+ uInt table; /* table lengths (14 bits) */
|
|
+ uInt index; /* index into blens (or border) */
|
|
+ uIntf *blens; /* bit lengths of codes */
|
|
+ uInt bb; /* bit length tree depth */
|
|
+ inflate_huft *tb; /* bit length decoding tree */
|
|
+ } trees; /* if DTREE, decoding info for trees */
|
|
+ struct {
|
|
+ inflate_codes_statef
|
|
+ *codes;
|
|
+ } decode; /* if CODES, current state */
|
|
+ } sub; /* submode */
|
|
+ uInt last; /* true if this block is the last block */
|
|
+
|
|
+ /* mode independent information */
|
|
+ uInt bitk; /* bits in bit buffer */
|
|
+ uLong bitb; /* bit buffer */
|
|
+ inflate_huft *hufts; /* single malloc for tree space */
|
|
+ Bytef *window; /* sliding window */
|
|
+ Bytef *end; /* one byte after sliding window */
|
|
+ Bytef *read; /* window read pointer */
|
|
+ Bytef *write; /* window write pointer */
|
|
+ check_func checkfn; /* check function */
|
|
+ uLong check; /* check on output */
|
|
+
|
|
+};
|
|
+
|
|
+
|
|
+/* defines for inflate input/output */
|
|
+/* update pointers and return */
|
|
+#define UPDBITS {s->bitb=b;s->bitk=k;}
|
|
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
|
|
+#define UPDOUT {s->write=q;}
|
|
+#define UPDATE {UPDBITS UPDIN UPDOUT}
|
|
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
|
|
+/* get bytes and bits */
|
|
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
|
|
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
|
|
+#define NEXTBYTE (n--,*p++)
|
|
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
|
|
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
|
|
+/* output bytes */
|
|
+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
|
|
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
|
|
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
|
|
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
|
|
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
|
|
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
|
|
+/* load local pointers */
|
|
+#define LOAD {LOADIN LOADOUT}
|
|
+
|
|
+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
|
|
+extern uInt inflate_mask[17];
|
|
+
|
|
+/* copy as much as possible from the sliding window to the output area */
|
|
+extern int inflate_flush OF((
|
|
+ inflate_blocks_statef *,
|
|
+ z_streamp ,
|
|
+ int));
|
|
+
|
|
+struct internal_state {int dummy;}; /* for buggy compilers */
|
|
+
|
|
+#endif /* _INFUTIL_H */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/initaddr.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,50 @@
|
|
+/*
|
|
+ * initialize address structure
|
|
+ * Copyright (C) 2000 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: initaddr.c,v 1.6 2004/07/10 07:43:47 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+/*
|
|
+ - initaddr - initialize ip_address from bytes
|
|
+ */
|
|
+err_t /* NULL for success, else string literal */
|
|
+initaddr(src, srclen, af, dst)
|
|
+const unsigned char *src;
|
|
+size_t srclen;
|
|
+int af; /* address family */
|
|
+ip_address *dst;
|
|
+{
|
|
+ switch (af) {
|
|
+ case AF_INET:
|
|
+ if (srclen != 4)
|
|
+ return "IPv4 address must be exactly 4 bytes";
|
|
+ dst->u.v4.sin_family = af;
|
|
+ dst->u.v4.sin_port = 0; /* unused */
|
|
+ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ if (srclen != 16)
|
|
+ return "IPv6 address must be exactly 16 bytes";
|
|
+ dst->u.v6.sin6_family = af;
|
|
+ dst->u.v6.sin6_flowinfo = 0; /* unused */
|
|
+ dst->u.v6.sin6_port = 0; /* unused */
|
|
+ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
|
|
+ break;
|
|
+ default:
|
|
+ return "unknown address family in initaddr";
|
|
+ break;
|
|
+ }
|
|
+ return NULL;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,701 @@
|
|
+/*
|
|
+ * IPCOMP zlib interface code.
|
|
+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
|
|
+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.41.2.5 2006/10/06 21:39:26 paul Exp $";
|
|
+
|
|
+/* SSS */
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h>
|
|
+#include <linux/netdevice.h>
|
|
+#include <linux/ip.h>
|
|
+#include <linux/skbuff.h>
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <asm/uaccess.h>
|
|
+#include <asm/checksum.h>
|
|
+
|
|
+#include <openswan.h>
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#include "openswan/ipcomp.h"
|
|
+#include "zlib/zlib.h"
|
|
+#include "zlib/zutil.h"
|
|
+
|
|
+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int sysctl_ipsec_debug_ipcomp = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+static
|
|
+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
|
|
+
|
|
+static
|
|
+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
|
|
+{
|
|
+ return (voidpf) kmalloc(items*size, GFP_ATOMIC);
|
|
+}
|
|
+
|
|
+static
|
|
+void my_zfree(voidpf opaque, voidpf address)
|
|
+{
|
|
+ kfree(address);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * We use this function because sometimes we want to pass a negative offset
|
|
+ * into skb_put(), this does not work on 64bit platforms because long to
|
|
+ * unsigned int casting.
|
|
+ */
|
|
+static inline unsigned char *
|
|
+safe_skb_put(struct sk_buff *skb, int extend)
|
|
+{
|
|
+ unsigned char *ptr;
|
|
+
|
|
+ if (extend>0) {
|
|
+ // increase the size of the packet
|
|
+ ptr = skb_put(skb, extend);
|
|
+ } else {
|
|
+ // shrink the size of the packet
|
|
+ ptr = skb->tail;
|
|
+ skb_trim (skb, skb->len + extend);
|
|
+ }
|
|
+
|
|
+ return ptr;
|
|
+}
|
|
+
|
|
+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
|
|
+{
|
|
+ struct iphdr *iph;
|
|
+ unsigned int iphlen, pyldsz, cpyldsz;
|
|
+ unsigned char *buffer;
|
|
+ z_stream zs;
|
|
+ int zresult;
|
|
+
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: .\n");
|
|
+
|
|
+ if(skb == NULL) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "passed in NULL skb, returning ERROR.\n");
|
|
+ if(flags != NULL) {
|
|
+ *flags |= IPCOMP_PARMERROR;
|
|
+ }
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ if(ips == NULL) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
|
|
+ if(flags) {
|
|
+ *flags |= IPCOMP_PARMERROR;
|
|
+ }
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ if (flags == NULL) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "passed in NULL flags, returning ERROR.\n");
|
|
+ ipsec_kfree_skb(skb);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+#ifdef NET_21
|
|
+ iph = skb->nh.iph;
|
|
+#else /* NET_21 */
|
|
+ iph = skb->ip_hdr;
|
|
+#endif /* NET_21 */
|
|
+
|
|
+ switch (iph->protocol) {
|
|
+ case IPPROTO_COMP:
|
|
+ case IPPROTO_AH:
|
|
+ case IPPROTO_ESP:
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "skipping compression of packet with ip protocol %d.\n",
|
|
+ iph->protocol);
|
|
+ *flags |= IPCOMP_UNCOMPRESSABLE;
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ /* Don't compress packets already fragmented */
|
|
+ if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "skipping compression of fragmented packet.\n");
|
|
+ *flags |= IPCOMP_UNCOMPRESSABLE;
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ iphlen = iph->ihl << 2;
|
|
+ pyldsz = ntohs(iph->tot_len) - iphlen;
|
|
+
|
|
+ /* Don't compress less than 90 bytes (rfc 2394) */
|
|
+ if (pyldsz < 90) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "skipping compression of tiny packet, len=%d.\n",
|
|
+ pyldsz);
|
|
+ *flags |= IPCOMP_UNCOMPRESSABLE;
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ /* Adaptive decision */
|
|
+ if (ips->ips_comp_adapt_skip) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "skipping compression: ips_comp_adapt_skip=%d.\n",
|
|
+ ips->ips_comp_adapt_skip);
|
|
+ ips->ips_comp_adapt_skip--;
|
|
+ *flags |= IPCOMP_UNCOMPRESSABLE;
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ zs.zalloc = my_zcalloc;
|
|
+ zs.zfree = my_zfree;
|
|
+ zs.opaque = 0;
|
|
+
|
|
+ /* We want to use deflateInit2 because we don't want the adler
|
|
+ header. */
|
|
+ zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
|
|
+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
|
|
+ if (zresult != Z_OK) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_compress: "
|
|
+ "deflateInit2() returned error %d (%s), "
|
|
+ "skipping compression.\n",
|
|
+ zresult,
|
|
+ zs.msg ? zs.msg : zError(zresult));
|
|
+ *flags |= IPCOMP_COMPRESSIONERROR;
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+
|
|
+ /* Max output size. Result should be max this size.
|
|
+ * Implementation specific tweak:
|
|
+ * If it's not at least 32 bytes and 6.25% smaller than
|
|
+ * the original packet, it's probably not worth wasting
|
|
+ * the receiver's CPU cycles decompressing it.
|
|
+ * Your mileage may vary.
|
|
+ */
|
|
+ cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
|
|
+
|
|
+ buffer = kmalloc(cpyldsz, GFP_ATOMIC);
|
|
+ if (!buffer) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_compress: "
|
|
+ "unable to kmalloc(%d, GFP_ATOMIC), "
|
|
+ "skipping compression.\n",
|
|
+ cpyldsz);
|
|
+ *flags |= IPCOMP_COMPRESSIONERROR;
|
|
+ deflateEnd(&zs);
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
|
|
+ __u8 *c;
|
|
+
|
|
+ c = (__u8*)iph + iphlen;
|
|
+ ipsec_dmp_block("compress before", c, pyldsz);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ zs.next_in = (char *) iph + iphlen; /* start of payload */
|
|
+ zs.avail_in = pyldsz;
|
|
+ zs.next_out = buffer; /* start of compressed payload */
|
|
+ zs.avail_out = cpyldsz;
|
|
+
|
|
+ /* Finish compression in one step */
|
|
+ zresult = deflate(&zs, Z_FINISH);
|
|
+
|
|
+ /* Free all dynamically allocated buffers */
|
|
+ deflateEnd(&zs);
|
|
+ if (zresult != Z_STREAM_END) {
|
|
+ *flags |= IPCOMP_UNCOMPRESSABLE;
|
|
+ kfree(buffer);
|
|
+
|
|
+ /* Adjust adaptive counters */
|
|
+ if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "first %d packets didn't compress, "
|
|
+ "skipping next %d\n",
|
|
+ IPCOMP_ADAPT_INITIAL_TRIES,
|
|
+ IPCOMP_ADAPT_INITIAL_SKIP);
|
|
+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
|
|
+ }
|
|
+ else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "next %d packets didn't compress, "
|
|
+ "skipping next %d\n",
|
|
+ IPCOMP_ADAPT_SUBSEQ_TRIES,
|
|
+ IPCOMP_ADAPT_SUBSEQ_SKIP);
|
|
+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
|
|
+ ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
|
|
+ }
|
|
+
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ /* resulting compressed size */
|
|
+ cpyldsz -= zs.avail_out;
|
|
+
|
|
+ /* Insert IPCOMP header */
|
|
+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
|
|
+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
|
|
+ /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
|
|
+ for internal reference only. */
|
|
+ ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_compress: "
|
|
+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
|
|
+ ntohl(ips->ips_said.spi),
|
|
+ ntohl(ips->ips_said.spi) & 0x0000ffff,
|
|
+ ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
|
|
+ pyldsz,
|
|
+ cpyldsz);
|
|
+
|
|
+ /* Update IP header */
|
|
+ iph->protocol = IPPROTO_COMP;
|
|
+ iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
|
|
+#if 1 /* XXX checksum is done by ipsec_tunnel ? */
|
|
+ iph->check = 0;
|
|
+ iph->check = ip_fast_csum((char *) iph, iph->ihl);
|
|
+#endif
|
|
+
|
|
+ /* Copy compressed payload */
|
|
+ memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
|
|
+ buffer,
|
|
+ cpyldsz);
|
|
+ kfree(buffer);
|
|
+
|
|
+ /* Update skb length/tail by "unputting" the shrinkage */
|
|
+ safe_skb_put (skb, cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
|
|
+ __u8 *c;
|
|
+
|
|
+ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
|
|
+ ipsec_dmp_block("compress result", c, cpyldsz);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ ips->ips_comp_adapt_skip = 0;
|
|
+ ips->ips_comp_adapt_tries = 0;
|
|
+
|
|
+ return skb;
|
|
+}
|
|
+
|
|
+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
|
|
+{
|
|
+ struct sk_buff *nskb = NULL;
|
|
+
|
|
+ /* original ip header */
|
|
+ struct iphdr *oiph, *iph;
|
|
+ unsigned int iphlen, pyldsz, cpyldsz;
|
|
+ z_stream zs;
|
|
+ int zresult;
|
|
+
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_decompress: .\n");
|
|
+
|
|
+ if(!skb) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "passed in NULL skb, returning ERROR.\n");
|
|
+ if (flags) *flags |= IPCOMP_PARMERROR;
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ if(!ips && sysctl_ipsec_inbound_policy_check) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
|
|
+ if (flags) *flags |= IPCOMP_PARMERROR;
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ if (!flags) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "passed in NULL flags, returning ERROR.\n");
|
|
+ ipsec_kfree_skb(skb);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+#ifdef NET_21
|
|
+ oiph = skb->nh.iph;
|
|
+#else /* NET_21 */
|
|
+ oiph = skb->ip_hdr;
|
|
+#endif /* NET_21 */
|
|
+
|
|
+ iphlen = oiph->ihl << 2;
|
|
+
|
|
+ if (oiph->protocol != IPPROTO_COMP) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "called with non-IPCOMP packet (protocol=%d),"
|
|
+ "skipping decompression.\n",
|
|
+ oiph->protocol);
|
|
+ *flags |= IPCOMP_PARMERROR;
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
|
|
+ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
|
|
+ != htons(SADB_X_CALG_DEFLATE))
|
|
+ && sysctl_ipsec_inbound_policy_check
|
|
+ && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "called with incompatible IPCOMP packet (flags=%d, "
|
|
+ "cpi=%d), ips-compalg=%d, skipping decompression.\n",
|
|
+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
|
|
+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
|
|
+ ips ? ips->ips_encalg : 0);
|
|
+ *flags |= IPCOMP_PARMERROR;
|
|
+
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ if (ntohs(oiph->frag_off) & ~0x4000) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "called with fragmented IPCOMP packet, "
|
|
+ "skipping decompression.\n");
|
|
+ *flags |= IPCOMP_PARMERROR;
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ /* original compressed payload size */
|
|
+ cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
|
|
+
|
|
+ zs.zalloc = my_zcalloc;
|
|
+ zs.zfree = my_zfree;
|
|
+ zs.opaque = 0;
|
|
+
|
|
+ zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
|
|
+ zs.avail_in = cpyldsz;
|
|
+
|
|
+ /* Maybe we should be a bit conservative about memory
|
|
+ requirements and use inflateInit2 */
|
|
+ /* Beware, that this might make us unable to decompress packets
|
|
+ from other implementations - HINT: check PGPnet source code */
|
|
+ /* We want to use inflateInit2 because we don't want the adler
|
|
+ header. */
|
|
+ zresult = inflateInit2(&zs, -15);
|
|
+ if (zresult != Z_OK) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "inflateInit2() returned error %d (%s), "
|
|
+ "skipping decompression.\n",
|
|
+ zresult,
|
|
+ zs.msg ? zs.msg : zError(zresult));
|
|
+ *flags |= IPCOMP_DECOMPRESSIONERROR;
|
|
+
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ /* We have no way of knowing the exact length of the resulting
|
|
+ decompressed output before we have actually done the decompression.
|
|
+ For now, we guess that the packet will not be bigger than the
|
|
+ attached ipsec device's mtu or 16260, whichever is biggest.
|
|
+ This may be wrong, since the sender's mtu may be bigger yet.
|
|
+ XXX This must be dealt with later XXX
|
|
+ */
|
|
+
|
|
+ /* max payload size */
|
|
+ pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
|
|
+ : (65520 - iphlen);
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_decompress: "
|
|
+ "max payload size: %d\n", pyldsz);
|
|
+
|
|
+ while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
|
|
+ (nskb = skb_copy_ipcomp(skb,
|
|
+ pyldsz - cpyldsz - sizeof(struct ipcomphdr),
|
|
+ GFP_ATOMIC)) == NULL) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
|
|
+ "trying with less payload size.\n",
|
|
+ (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
|
|
+ pyldsz >>=1;
|
|
+ }
|
|
+
|
|
+ if (!nskb) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "unable to allocate memory, dropping packet.\n");
|
|
+ *flags |= IPCOMP_DECOMPRESSIONERROR;
|
|
+ inflateEnd(&zs);
|
|
+
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
|
|
+ __u8 *c;
|
|
+
|
|
+ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
|
|
+ ipsec_dmp_block("decompress before", c, cpyldsz);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+#ifdef NET_21
|
|
+ iph = nskb->nh.iph;
|
|
+#else /* NET_21 */
|
|
+ iph = nskb->ip_hdr;
|
|
+#endif /* NET_21 */
|
|
+ zs.next_out = (char *)iph + iphlen;
|
|
+ zs.avail_out = pyldsz;
|
|
+
|
|
+ zresult = inflate(&zs, Z_SYNC_FLUSH);
|
|
+
|
|
+ /* work around a bug in zlib, which sometimes wants to taste an extra
|
|
+ * byte when being used in the (undocumented) raw deflate mode.
|
|
+ */
|
|
+ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
|
|
+ __u8 zerostuff = 0;
|
|
+
|
|
+ zs.next_in = &zerostuff;
|
|
+ zs.avail_in = 1;
|
|
+ zresult = inflate(&zs, Z_FINISH);
|
|
+ }
|
|
+
|
|
+ inflateEnd(&zs);
|
|
+ if (zresult != Z_STREAM_END) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_error:skb_decompress: "
|
|
+ "inflate() returned error %d (%s), "
|
|
+ "skipping decompression.\n",
|
|
+ zresult,
|
|
+ zs.msg ? zs.msg : zError(zresult));
|
|
+ *flags |= IPCOMP_DECOMPRESSIONERROR;
|
|
+ ipsec_kfree_skb(nskb);
|
|
+
|
|
+ return skb;
|
|
+ }
|
|
+
|
|
+ /* Update IP header */
|
|
+ /* resulting decompressed size */
|
|
+ pyldsz -= zs.avail_out;
|
|
+ iph->tot_len = htons(iphlen + pyldsz);
|
|
+ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_decompress: "
|
|
+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
|
|
+ ips ? ntohl(ips->ips_said.spi) : 0,
|
|
+ ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
|
|
+ ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
|
|
+ cpyldsz,
|
|
+ pyldsz,
|
|
+ iph->protocol);
|
|
+
|
|
+#if 1 /* XXX checksum is done by ipsec_rcv ? */
|
|
+ iph->check = 0;
|
|
+ iph->check = ip_fast_csum((char*) iph, iph->ihl);
|
|
+#endif
|
|
+
|
|
+ /* Update skb length/tail by "unputting" the unused data area */
|
|
+ safe_skb_put(nskb, -zs.avail_out);
|
|
+
|
|
+ ipsec_kfree_skb(skb);
|
|
+
|
|
+ if (iph->protocol == IPPROTO_COMP)
|
|
+ {
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(sysctl_ipsec_debug_ipcomp)
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_decompress: "
|
|
+ "Eh? inner packet is also compressed, dropping.\n");
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ ipsec_kfree_skb(nskb);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
|
|
+ __u8 *c;
|
|
+
|
|
+ c = (__u8*)iph + iphlen;
|
|
+ ipsec_dmp_block("decompress result", c, pyldsz);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ return nskb;
|
|
+}
|
|
+
|
|
+
|
|
+/* this is derived from skb_copy() in linux 2.2.14 */
|
|
+/* May be incompatible with other kernel versions!! */
|
|
+static
|
|
+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
|
|
+{
|
|
+ struct sk_buff *n;
|
|
+ struct iphdr *iph;
|
|
+ unsigned long offset;
|
|
+ unsigned int iphlen;
|
|
+
|
|
+ if(!skb) {
|
|
+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
|
|
+ "klips_debug:skb_copy_ipcomp: "
|
|
+ "passed in NULL skb, returning NULL.\n");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Allocate the copy buffer
|
|
+ */
|
|
+
|
|
+#ifdef NET_21
|
|
+ iph = skb->nh.iph;
|
|
+#else /* NET_21 */
|
|
+ iph = skb->ip_hdr;
|
|
+#endif /* NET_21 */
|
|
+ if (!iph) return NULL;
|
|
+ iphlen = iph->ihl << 2;
|
|
+
|
|
+ n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
|
|
+ if(n==NULL)
|
|
+ return NULL;
|
|
+
|
|
+ /*
|
|
+ * Shift between the two data areas in bytes
|
|
+ */
|
|
+
|
|
+ offset=n->head-skb->head;
|
|
+
|
|
+ /* Set the data pointer */
|
|
+ skb_reserve(n,skb->data-skb->head);
|
|
+ /* Set the tail pointer and length */
|
|
+ safe_skb_put(n,skb->len+data_growth);
|
|
+ /* Copy the bytes up to and including the ip header */
|
|
+ memcpy(n->head,
|
|
+ skb->head,
|
|
+ ((char *)iph - (char *)skb->head) + iphlen);
|
|
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
|
|
+ n->list=NULL;
|
|
+#endif
|
|
+ n->next=NULL;
|
|
+ n->prev=NULL;
|
|
+ n->sk=NULL;
|
|
+ n->dev=skb->dev;
|
|
+ if (skb->h.raw)
|
|
+ n->h.raw=skb->h.raw+offset;
|
|
+ else
|
|
+ n->h.raw=NULL;
|
|
+ n->protocol=skb->protocol;
|
|
+#ifdef NET_21
|
|
+ n->csum = 0;
|
|
+ n->priority=skb->priority;
|
|
+ n->dst=dst_clone(skb->dst);
|
|
+ n->nh.raw=skb->nh.raw+offset;
|
|
+#ifndef NETDEV_23
|
|
+ n->is_clone=0;
|
|
+#endif /* NETDEV_23 */
|
|
+ atomic_set(&n->users, 1);
|
|
+ n->destructor = NULL;
|
|
+#ifdef HAVE_SOCK_SECURITY
|
|
+ n->security=skb->security;
|
|
+#endif
|
|
+ memcpy(n->cb, skb->cb, sizeof(skb->cb));
|
|
+#ifdef CONFIG_IP_FIREWALL
|
|
+ n->fwmark = skb->fwmark;
|
|
+#endif
|
|
+#else /* NET_21 */
|
|
+ n->link3=NULL;
|
|
+ n->when=skb->when;
|
|
+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
|
|
+ n->saddr=skb->saddr;
|
|
+ n->daddr=skb->daddr;
|
|
+ n->raddr=skb->raddr;
|
|
+ n->seq=skb->seq;
|
|
+ n->end_seq=skb->end_seq;
|
|
+ n->ack_seq=skb->ack_seq;
|
|
+ n->acked=skb->acked;
|
|
+ n->free=1;
|
|
+ n->arp=skb->arp;
|
|
+ n->tries=0;
|
|
+ n->lock=0;
|
|
+ n->users=0;
|
|
+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
|
|
+#endif /* NET_21 */
|
|
+ if (skb->mac.raw)
|
|
+ n->mac.raw=skb->mac.raw+offset;
|
|
+ else
|
|
+ n->mac.raw=NULL;
|
|
+#ifndef NETDEV_23
|
|
+ n->used=skb->used;
|
|
+#endif /* !NETDEV_23 */
|
|
+ n->pkt_type=skb->pkt_type;
|
|
+#ifndef NETDEV_23
|
|
+ n->pkt_bridged=skb->pkt_bridged;
|
|
+#endif /* NETDEV_23 */
|
|
+ n->ip_summed=0;
|
|
+#ifdef HAVE_TSTAMP
|
|
+ n->tstamp = skb->tstamp;
|
|
+#else
|
|
+ n->stamp=skb->stamp;
|
|
+#endif
|
|
+#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
|
|
+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
|
|
+ n->shapelatency=skb->shapelatency; /* Latency on frame */
|
|
+ n->shapeclock=skb->shapeclock; /* Time it should go out */
|
|
+ n->shapelen=skb->shapelen; /* Frame length in clocks */
|
|
+ n->shapestamp=skb->shapestamp; /* Stamp for shaper */
|
|
+ n->shapepend=skb->shapepend; /* Pending */
|
|
+#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
|
|
+#endif /* NETDEV_23 */
|
|
+
|
|
+ return n;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,407 @@
|
|
+/*
|
|
+ * processing code for AH
|
|
+ * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+char ipsec_ah_c_version[] = "RCSID $Id: ipsec_ah.c,v 1.12.2.2 2006/10/06 21:39:26 paul Exp $";
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <openswan.h>
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+#include <net/protocol.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#include "openswan/ipsec_xmit.h"
|
|
+
|
|
+#include "openswan/ipsec_auth.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_proto.h"
|
|
+
|
|
+__u32 zeroes[AH_AMAX];
|
|
+
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb)
|
|
+{
|
|
+ int ahminlen;
|
|
+
|
|
+ ahminlen = irs->hard_header_len + sizeof(struct iphdr);
|
|
+
|
|
+ /* take care not to deref this pointer until we check the minlen though */
|
|
+ irs->protostuff.ahstuff.ahp = (struct ahhdr *)skb->h.raw;
|
|
+
|
|
+ if((skb->len < ahminlen+sizeof(struct ahhdr)) ||
|
|
+ (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "runt ah packet of skb->len=%d received from %s, dropped.\n",
|
|
+ skb->len,
|
|
+ irs->ipsaddr_txt);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ return IPSEC_RCV_BADLEN;
|
|
+ }
|
|
+
|
|
+ irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
|
|
+
|
|
+ /* XXX we only support the one 12-byte authenticator for now */
|
|
+ if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "bad authenticator length %ld, expected %lu from %s.\n",
|
|
+ (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
|
|
+ (unsigned long) sizeof(struct ahhdr),
|
|
+ irs->ipsaddr_txt);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ return IPSEC_RCV_BADLEN;
|
|
+ }
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb,
|
|
+ __u32 *replay,
|
|
+ unsigned char **authenticator)
|
|
+{
|
|
+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
|
|
+
|
|
+ *replay = ntohl(ahp->ah_rpl);
|
|
+ *authenticator = ahp->ah_data;
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb)
|
|
+{
|
|
+ struct auth_alg *aa;
|
|
+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
|
|
+ union {
|
|
+ MD5_CTX md5;
|
|
+ SHA1_CTX sha1;
|
|
+ } tctx;
|
|
+ struct iphdr ipo;
|
|
+ int ahhlen;
|
|
+
|
|
+ aa = irs->authfuncs;
|
|
+
|
|
+ /* copy the initialized keying material */
|
|
+ memcpy(&tctx, irs->ictx, irs->ictx_len);
|
|
+
|
|
+ ipo = *irs->ipp;
|
|
+ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
|
|
+ ipo.frag_off = 0;
|
|
+ ipo.ttl = 0;
|
|
+ ipo.check = 0;
|
|
+
|
|
+
|
|
+ /* do the sanitized header */
|
|
+ (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
|
|
+
|
|
+ /* XXX we didn't do the options here! */
|
|
+
|
|
+ /* now do the AH header itself */
|
|
+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
|
|
+ (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN);
|
|
+
|
|
+ /* now, do some zeroes */
|
|
+ (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN);
|
|
+
|
|
+ /* finally, do the packet contents themselves */
|
|
+ (*aa->update)((void*)&tctx,
|
|
+ (caddr_t)skb->h.raw + ahhlen,
|
|
+ skb->len - ahhlen);
|
|
+
|
|
+ (*aa->final)(irs->hash, (void *)&tctx);
|
|
+
|
|
+ memcpy(&tctx, irs->octx, irs->octx_len);
|
|
+
|
|
+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
|
|
+ (*aa->final)(irs->hash, (void *)&tctx);
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
|
|
+{
|
|
+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
|
|
+ struct sk_buff *skb;
|
|
+ int ahhlen;
|
|
+
|
|
+ skb=irs->skb;
|
|
+
|
|
+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
|
|
+
|
|
+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
|
|
+ irs->next_header = ahp->ah_nh;
|
|
+
|
|
+ /*
|
|
+ * move the IP header forward by the size of the AH header, which
|
|
+ * will remove the the AH header from the packet.
|
|
+ */
|
|
+ memmove((void *)(skb->nh.raw + ahhlen),
|
|
+ (void *)(skb->nh.raw), irs->iphlen);
|
|
+
|
|
+ ipsec_rcv_dmp("ah postmove", skb->data, skb->len);
|
|
+
|
|
+ /* skb_pull below, will move up by ahhlen */
|
|
+
|
|
+ /* XXX not clear how this can happen, as the message indicates */
|
|
+ if(skb->len < ahhlen) {
|
|
+ printk(KERN_WARNING
|
|
+ "klips_error:ipsec_rcv: "
|
|
+ "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n",
|
|
+ ahhlen,
|
|
+ (int)(skb->len));
|
|
+ return IPSEC_RCV_DECAPFAIL;
|
|
+ }
|
|
+ skb_pull(skb, ahhlen);
|
|
+
|
|
+ skb->nh.raw = skb->nh.raw + ahhlen;
|
|
+ irs->ipp = skb->nh.iph;
|
|
+
|
|
+ ipsec_rcv_dmp("ah postpull", (void *)skb->nh.iph, skb->len);
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+ struct iphdr ipo;
|
|
+ struct ahhdr *ahp;
|
|
+ __u8 hash[AH_AMAX];
|
|
+ union {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ MD5_CTX md5;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ SHA1_CTX sha1;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ } tctx;
|
|
+ unsigned char *dat = (unsigned char *)ixs->iph;
|
|
+
|
|
+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
|
|
+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
|
|
+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
|
|
+ ahp->ah_rv = 0;
|
|
+ ahp->ah_nh = ixs->iph->protocol;
|
|
+ ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32);
|
|
+ ixs->iph->protocol = IPPROTO_AH;
|
|
+ ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp));
|
|
+
|
|
+ ipo = *ixs->iph;
|
|
+ ipo.tos = 0;
|
|
+ ipo.frag_off = 0;
|
|
+ ipo.ttl = 0;
|
|
+ ipo.check = 0;
|
|
+ ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo));
|
|
+
|
|
+ switch(ixs->ipsp->ips_authalg) {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ case AH_MD5:
|
|
+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
|
|
+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
|
|
+ ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, (unsigned char *)ahp,
|
|
+ sizeof(struct ahhdr) - sizeof(ahp->ah_data));
|
|
+ ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
|
|
+ ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr),
|
|
+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
|
|
+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Final(hash, &tctx.md5);
|
|
+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
|
|
+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
|
|
+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
|
|
+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Final(hash, &tctx.md5);
|
|
+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
|
|
+
|
|
+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
|
|
+
|
|
+ /* paranoid */
|
|
+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
|
|
+ memset((caddr_t)hash, 0, sizeof(*hash));
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ case AH_SHA:
|
|
+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
|
|
+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
|
|
+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data));
|
|
+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
|
|
+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr),
|
|
+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
|
|
+ SHA1Final(hash, &tctx.sha1);
|
|
+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
|
|
+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
|
|
+ SHA1Final(hash, &tctx.sha1);
|
|
+
|
|
+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
|
|
+
|
|
+ /* paranoid */
|
|
+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
|
|
+ memset((caddr_t)hash, 0, sizeof(*hash));
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_AH_BADALG;
|
|
+ }
|
|
+#ifdef NET_21
|
|
+ ixs->skb->h.raw = (unsigned char*)ahp;
|
|
+#endif /* NET_21 */
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+struct xform_functions ah_xform_funcs[]={
|
|
+ { rcv_checks: ipsec_rcv_ah_checks,
|
|
+ rcv_setup_auth: ipsec_rcv_ah_setup_auth,
|
|
+ rcv_calc_auth: ipsec_rcv_ah_authcalc,
|
|
+ rcv_decrypt: ipsec_rcv_ah_decap,
|
|
+
|
|
+ xmit_setup: ipsec_xmit_ah_setup,
|
|
+ xmit_headroom: sizeof(struct ahhdr),
|
|
+ xmit_needtailroom: 0,
|
|
+ },
|
|
+};
|
|
+
|
|
+
|
|
+#ifdef NET_26
|
|
+struct inet_protocol ah_protocol = {
|
|
+ .handler = ipsec_rcv,
|
|
+ .no_policy = 1,
|
|
+};
|
|
+#else
|
|
+struct inet_protocol ah_protocol =
|
|
+{
|
|
+ ipsec_rcv, /* AH handler */
|
|
+ NULL, /* TUNNEL error control */
|
|
+#ifdef NETDEV_25
|
|
+ 1, /* no policy */
|
|
+#else
|
|
+ 0, /* next */
|
|
+ IPPROTO_AH, /* protocol ID */
|
|
+ 0, /* copy */
|
|
+ NULL, /* data */
|
|
+ "AH" /* name */
|
|
+#endif
|
|
+};
|
|
+#endif /* NET_26 */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_ah.c,v $
|
|
+ * Revision 1.12.2.2 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.12.2.1 2006/02/15 05:35:14 paul
|
|
+ * Patch by David McCullough <davidm@snapgear.com>
|
|
+ * If you setup a tunnel without ESP it doesn't work. It used to work in
|
|
+ * an older openswan version but stopped when klips was modified to deal
|
|
+ * with the pulled IP header on the received SKB's.
|
|
+ *
|
|
+ * The code in ipsec_ah.c still thinks the IP header is there and runs the
|
|
+ * hash on the incorrect data.
|
|
+ *
|
|
+ * Revision 1.12 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.11 2005/04/15 19:50:55 mcr
|
|
+ * adjustments to use proper skb fields for data.
|
|
+ *
|
|
+ * Revision 1.10 2004/09/14 00:22:57 mcr
|
|
+ * adjustment of MD5* functions.
|
|
+ *
|
|
+ * Revision 1.9 2004/09/13 02:22:47 mcr
|
|
+ * #define inet_protocol if necessary.
|
|
+ *
|
|
+ * Revision 1.8 2004/09/06 18:35:48 mcr
|
|
+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
|
|
+ * so adjust for that.
|
|
+ *
|
|
+ * Revision 1.7 2004/08/22 05:00:48 mcr
|
|
+ * if we choose to compile the file, we want the contents,
|
|
+ * so don't pull any punches.
|
|
+ *
|
|
+ * Revision 1.6 2004/08/17 03:27:23 mcr
|
|
+ * klips 2.6 edits.
|
|
+ *
|
|
+ * Revision 1.5 2004/08/14 03:28:24 mcr
|
|
+ * fixed log comment to remove warning about embedded comment.
|
|
+ *
|
|
+ * Revision 1.4 2004/08/04 15:57:07 mcr
|
|
+ * moved des .h files to include/des/ *
|
|
+ * included 2.6 protocol specific things
|
|
+ * started at NAT-T support, but it will require a kernel patch.
|
|
+ *
|
|
+ * Revision 1.3 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.2 2004/04/06 02:49:25 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1057 @@
|
|
+/*
|
|
+ * Modular extensions service and registration functions
|
|
+ *
|
|
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
|
|
+ *
|
|
+ * Version: 0.8.1
|
|
+ *
|
|
+ * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ */
|
|
+#define __NO_VERSION__
|
|
+
|
|
+#if defined (MODULE)
|
|
+#include <linux/module.h>
|
|
+#endif
|
|
+
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <linux/socket.h>
|
|
+#include <linux/in.h>
|
|
+#include <linux/types.h>
|
|
+#include <linux/string.h> /* memcmp() */
|
|
+#include <linux/random.h> /* get_random_bytes() */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+#include <openswan.h>
|
|
+#include "openswan/ipsec_sa.h"
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#if defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH)
|
|
+# include "openswan/ipsec_ah.h"
|
|
+#endif /* defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH) */
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+# include "openswan/ipsec_esp.h"
|
|
+#endif /* !CONFIG_KLIPS_ESP */
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+# include "openswan/ipcomp.h"
|
|
+#endif /* CONFIG_KLIPS_COMP */
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_alg.h"
|
|
+#include "openswan/ipsec_proto.h"
|
|
+
|
|
+#if SADB_EALG_MAX < 255
|
|
+#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
|
|
+#endif
|
|
+
|
|
+static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
|
|
+#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
|
|
+static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
|
|
+
|
|
+/* Old gcc's will fail here */
|
|
+#define barf_out(fmt, args...) do { struct ipsec_alg *ixtc = (struct ipsec_alg *)ixt; printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixtc->ixt_name , ## args) \
|
|
+ ; goto out; } while(0)
|
|
+
|
|
+#ifdef NET_26
|
|
+/*
|
|
+ * Must be already protected by lock
|
|
+ */
|
|
+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt)
|
|
+{
|
|
+#ifdef MODULE
|
|
+ if (ixt->ixt_module)
|
|
+ try_module_get(ixt->ixt_module);
|
|
+#endif
|
|
+ atomic_inc(&ixt->ixt_refcnt);
|
|
+}
|
|
+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
|
|
+ atomic_dec(&ixt->ixt_refcnt);
|
|
+#ifdef MODULE
|
|
+ if (ixt->ixt_module)
|
|
+ module_put(ixt->ixt_module);
|
|
+#endif
|
|
+}
|
|
+
|
|
+#else
|
|
+
|
|
+/*
|
|
+ * Must be already protected by lock
|
|
+ */
|
|
+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
|
|
+#ifdef MODULE
|
|
+ if (ixt->ixt_module) {
|
|
+ __MOD_INC_USE_COUNT(ixt->ixt_module);
|
|
+ }
|
|
+#endif
|
|
+ atomic_inc(&ixt->ixt_refcnt);
|
|
+}
|
|
+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
|
|
+ atomic_dec(&ixt->ixt_refcnt);
|
|
+#ifdef MODULE
|
|
+ if (ixt->ixt_module)
|
|
+ __MOD_DEC_USE_COUNT(ixt->ixt_module);
|
|
+#endif
|
|
+}
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * simple hash function, optimized for 0-hash (1 list) special
|
|
+ * case
|
|
+ */
|
|
+#if IPSEC_ALG_HASHSZ > 1
|
|
+static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
|
|
+ return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
|
|
+}
|
|
+#else
|
|
+#define ipsec_alg_hashfn(x,y) (0)
|
|
+#endif
|
|
+
|
|
+/*****************************************************************
|
|
+ *
|
|
+ * INTERNAL table handling: insert, delete, find
|
|
+ *
|
|
+ *****************************************************************/
|
|
+
|
|
+/*
|
|
+ * hash table initialization, called from ipsec_alg_init()
|
|
+ */
|
|
+static void ipsec_alg_hash_init(void) {
|
|
+ struct list_head *head = ipsec_alg_hash_table;
|
|
+ int i = IPSEC_ALG_HASHSZ;
|
|
+ do {
|
|
+ INIT_LIST_HEAD(head);
|
|
+ head++;
|
|
+ i--;
|
|
+ } while (i);
|
|
+}
|
|
+/*
|
|
+ * hash list lookup by {alg_type, alg_id} and table head,
|
|
+ * must be already protected by lock
|
|
+ */
|
|
+static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
|
|
+ struct list_head *p;
|
|
+ struct ipsec_alg *ixt=NULL;
|
|
+ for (p=head->next; p!=head; p=p->next) {
|
|
+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
|
|
+ if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+ ixt=NULL;
|
|
+out:
|
|
+ return ixt;
|
|
+}
|
|
+/*
|
|
+ * inserts (in front) a new entry in hash table,
|
|
+ * called from ipsec_alg_register() when new algorithm is registered.
|
|
+ */
|
|
+static int ipsec_alg_insert(struct ipsec_alg *ixt) {
|
|
+ int ret=-EINVAL;
|
|
+ unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
|
|
+ struct list_head *head= ipsec_alg_hash_table + hashval;
|
|
+ struct ipsec_alg *ixt_cur;
|
|
+
|
|
+ /* new element must be virgin ... */
|
|
+ if (ixt->ixt_list.next != &ixt->ixt_list ||
|
|
+ ixt->ixt_list.prev != &ixt->ixt_list) {
|
|
+ printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
|
|
+ "list head not initialized\n",
|
|
+ ixt->ixt_name);
|
|
+ return ret;
|
|
+ }
|
|
+ write_lock_bh(&ipsec_alg_lock);
|
|
+
|
|
+ ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
|
|
+
|
|
+ /* if previous (current) ipsec_alg found check excl flag of _anyone_ */
|
|
+ if (ixt_cur
|
|
+ && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) {
|
|
+ barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
|
|
+ "Not loaded (ret=%d).\n",
|
|
+ ixt->ixt_alg_type,
|
|
+ ixt->ixt_alg_id, ret=-EEXIST);
|
|
+ }
|
|
+ list_add(&ixt->ixt_list, head);
|
|
+ ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
|
|
+ ret=0;
|
|
+out:
|
|
+ write_unlock_bh(&ipsec_alg_lock);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * deletes an existing entry in hash table,
|
|
+ * called from ipsec_alg_unregister() when algorithm is unregistered.
|
|
+ */
|
|
+static int ipsec_alg_delete(struct ipsec_alg *ixt) {
|
|
+ write_lock_bh(&ipsec_alg_lock);
|
|
+ list_del(&ixt->ixt_list);
|
|
+ write_unlock_bh(&ipsec_alg_lock);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * here @user context (read-only when @kernel bh context)
|
|
+ * -> no bh disabling
|
|
+ *
|
|
+ * called from ipsec_sa_init() -> ipsec_alg_sa_init()
|
|
+ */
|
|
+static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id)
|
|
+{
|
|
+ unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
|
|
+ struct list_head *head= ipsec_alg_hash_table + hashval;
|
|
+ struct ipsec_alg *ixt;
|
|
+
|
|
+ read_lock(&ipsec_alg_lock);
|
|
+ ixt=__ipsec_alg_find(alg_type, alg_id, head);
|
|
+ if (ixt) __ipsec_alg_usage_inc(ixt);
|
|
+ read_unlock(&ipsec_alg_lock);
|
|
+
|
|
+ return ixt;
|
|
+}
|
|
+
|
|
+static void ipsec_alg_put(struct ipsec_alg *ixt) {
|
|
+ __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
|
|
+}
|
|
+
|
|
+/*****************************************************************
|
|
+ *
|
|
+ * INTERFACE for ENC services: key creation, encrypt function
|
|
+ *
|
|
+ *****************************************************************/
|
|
+
|
|
+/*
|
|
+ * main encrypt service entry point
|
|
+ * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
|
|
+ * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
|
|
+ */
|
|
+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat,
|
|
+ int ilen, const __u8 * iv, int encrypt)
|
|
+{
|
|
+ int ret;
|
|
+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ int debug_flag = (encrypt==IPSEC_ALG_ENCRYPT ?
|
|
+ debug_tunnel : debug_rcv);
|
|
+#endif
|
|
+
|
|
+ KLIPS_PRINT(debug_flag,
|
|
+ "klips_debug:ipsec_alg_esp_encrypt: "
|
|
+ "entering with encalg=%d, ixt_e=%p\n",
|
|
+ sa_p->ips_encalg, ixt_e);
|
|
+ if (ixt_e == NULL) {
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ KLIPS_ERROR(debug_flag,
|
|
+ "klips_debug:ipsec_alg_esp_encrypt: "
|
|
+ "NULL ipsec_alg_enc object\n");
|
|
+#endif
|
|
+ return -1;
|
|
+ }
|
|
+ KLIPS_PRINT(debug_flag,
|
|
+ "klips_debug:ipsec_alg_esp_encrypt: "
|
|
+ "calling cbc_encrypt encalg=%d "
|
|
+ "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
|
|
+ sa_p->ips_encalg,
|
|
+ sa_p->ips_key_e, idat, ilen, iv, encrypt);
|
|
+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat,
|
|
+ ilen, iv, encrypt);
|
|
+ KLIPS_PRINT(debug_flag,
|
|
+ "klips_debug:ipsec_alg_esp_encrypt: "
|
|
+ "returned ret=%d\n",
|
|
+ ret);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * encryption key context creation function
|
|
+ * called from pfkey_v2_parser.c:pfkey_ips_init()
|
|
+ */
|
|
+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
|
|
+ int ret=-EINVAL;
|
|
+ int keyminbits, keymaxbits;
|
|
+ caddr_t ekp;
|
|
+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_alg_enc_key_create: "
|
|
+ "entering with encalg=%d ixt_e=%p\n",
|
|
+ sa_p->ips_encalg, ixt_e);
|
|
+ if (!ixt_e) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_alg_enc_key_create: "
|
|
+ "NULL ipsec_alg_enc object\n");
|
|
+ return -EPROTO;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo
|
|
+ */
|
|
+ switch(ixt_e->ixt_common.ixt_support.ias_id) {
|
|
+ case ESP_3DES:
|
|
+ keyminbits=keymaxbits=192;break;
|
|
+ case ESP_DES:
|
|
+ keyminbits=keymaxbits=64;break;
|
|
+ default:
|
|
+ keyminbits=ixt_e->ixt_common.ixt_support.ias_keyminbits;
|
|
+ keymaxbits=ixt_e->ixt_common.ixt_support.ias_keymaxbits;
|
|
+ }
|
|
+ if(sa_p->ips_key_bits_e<keyminbits ||
|
|
+ sa_p->ips_key_bits_e>keymaxbits) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_alg_enc_key_create: "
|
|
+ "incorrect encryption key size for id=%d: %d bits -- "
|
|
+ "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
|
|
+ ixt_e->ixt_common.ixt_support.ias_id,
|
|
+ sa_p->ips_key_bits_e, keyminbits, keymaxbits);
|
|
+ ret=-EINVAL;
|
|
+ goto ixt_out;
|
|
+ }
|
|
+ /* save encryption key pointer */
|
|
+ ekp = sa_p->ips_key_e;
|
|
+
|
|
+
|
|
+ if (ixt_e->ixt_e_new_key) {
|
|
+ sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
|
|
+ ekp, sa_p->ips_key_bits_e/8);
|
|
+ ret = (sa_p->ips_key_e)? 0 : -EINVAL;
|
|
+ } else {
|
|
+ if((sa_p->ips_key_e = (caddr_t)
|
|
+ kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
|
|
+ GFP_ATOMIC)) == NULL) {
|
|
+ ret=-ENOMEM;
|
|
+ goto ixt_out;
|
|
+ }
|
|
+ /* zero-out key_e */
|
|
+ memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
|
|
+
|
|
+ /* I cast here to allow more decoupling in alg module */
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_alg_enc_key_create: about to call:"
|
|
+ "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
|
|
+ (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
|
|
+ ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
|
|
+ }
|
|
+ /* paranoid */
|
|
+ memset(ekp, 0, sa_p->ips_key_bits_e/8);
|
|
+ kfree(ekp);
|
|
+ixt_out:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/***************************************************************
|
|
+ *
|
|
+ * INTERFACE for AUTH services: key creation, hash functions
|
|
+ *
|
|
+ ***************************************************************/
|
|
+
|
|
+/*
|
|
+ * auth key context creation function
|
|
+ * called from pfkey_v2_parser.c:pfkey_ips_init()
|
|
+ */
|
|
+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
|
|
+ int ret=-EINVAL;
|
|
+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
|
|
+ int keyminbits, keymaxbits;
|
|
+ unsigned char *akp;
|
|
+ unsigned int aks;
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_alg_auth_key_create: "
|
|
+ "entering with authalg=%d ixt_a=%p\n",
|
|
+ sa_p->ips_authalg, ixt_a);
|
|
+ if (!ixt_a) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_alg_auth_key_create: "
|
|
+ "NULL ipsec_alg_auth object\n");
|
|
+ return -EPROTO;
|
|
+ }
|
|
+ keyminbits=ixt_a->ixt_common.ixt_support.ias_keyminbits;
|
|
+ keymaxbits=ixt_a->ixt_common.ixt_support.ias_keymaxbits;
|
|
+ if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
|
|
+ "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
|
|
+ sa_p->ips_key_bits_a, keyminbits, keymaxbits);
|
|
+ ret=-EINVAL;
|
|
+ goto ixt_out;
|
|
+ }
|
|
+ /* save auth key pointer */
|
|
+ sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
|
|
+ akp = sa_p->ips_key_a;
|
|
+ aks = sa_p->ips_key_a_size;
|
|
+
|
|
+ /* will hold: 2 ctx and a blocksize buffer: kb */
|
|
+ sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
|
|
+ if((sa_p->ips_key_a =
|
|
+ (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
|
|
+ ret=-ENOMEM;
|
|
+ goto ixt_out;
|
|
+ }
|
|
+ ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
|
|
+ ret=0;
|
|
+ memset(akp, 0, aks);
|
|
+ kfree(akp);
|
|
+
|
|
+ixt_out:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp,
|
|
+ int len, __u8 *hash, int hashlen)
|
|
+{
|
|
+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
|
|
+ if (!ixt_a) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_sa_esp_hash: "
|
|
+ "NULL ipsec_alg_auth object\n");
|
|
+ return -EPROTO;
|
|
+ }
|
|
+ KLIPS_PRINT(debug_tunnel|debug_rcv,
|
|
+ "klips_debug:ipsec_sa_esp_hash: "
|
|
+ "hashing %p (%d bytes) to %p (%d bytes)\n",
|
|
+ espp, len,
|
|
+ hash, hashlen);
|
|
+ ixt_a->ixt_a_hmac_hash(ixt_a,
|
|
+ sa_p->ips_key_a,
|
|
+ espp, len,
|
|
+ hash, hashlen);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/***************************************************************
|
|
+ *
|
|
+ * INTERFACE for module loading,testing, and unloading
|
|
+ *
|
|
+ ***************************************************************/
|
|
+
|
|
+/* validation for registering (enc) module */
|
|
+static int check_enc(struct ipsec_alg_enc *ixt)
|
|
+{
|
|
+ int ret=-EINVAL;
|
|
+ if (ixt->ixt_common.ixt_blocksize==0) /* || ixt->ixt_common.ixt_blocksize%2) need for ESP_NULL */
|
|
+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_common.ixt_blocksize);
|
|
+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0
|
|
+ && ixt->ixt_common.ixt_support.ias_keymaxbits==0
|
|
+ && ixt->ixt_e_keylen==0)
|
|
+ goto zero_key_ok;
|
|
+
|
|
+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
|
|
+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
|
|
+
|
|
+ if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
|
|
+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
|
|
+
|
|
+ if (ixt->ixt_e_keylen==0)
|
|
+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
|
|
+
|
|
+zero_key_ok:
|
|
+ if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
|
|
+ barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
|
|
+ if (ixt->ixt_e_cbc_encrypt==NULL)
|
|
+ barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
|
|
+ ret=0;
|
|
+out:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* validation for registering (auth) module */
|
|
+static int check_auth(struct ipsec_alg_auth *ixt)
|
|
+{
|
|
+ int ret=-EINVAL;
|
|
+ if (ixt->ixt_common.ixt_support.ias_id==0 || ixt->ixt_common.ixt_support.ias_id > SADB_AALG_MAX)
|
|
+ barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n",
|
|
+ ixt->ixt_common.ixt_support.ias_id, SADB_AALG_MAX);
|
|
+
|
|
+ if (ixt->ixt_common.ixt_blocksize==0
|
|
+ || ixt->ixt_common.ixt_blocksize%2)
|
|
+ barf_out(KERN_ERR "invalid blocksize=%d\n",
|
|
+ ixt->ixt_common.ixt_blocksize);
|
|
+
|
|
+ if (ixt->ixt_common.ixt_blocksize>AH_BLKLEN_MAX)
|
|
+ barf_out(KERN_ERR "sorry blocksize=%d > %d. "
|
|
+ "Please increase AH_BLKLEN_MAX and recompile\n",
|
|
+ ixt->ixt_common.ixt_blocksize,
|
|
+ AH_BLKLEN_MAX);
|
|
+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0 && ixt->ixt_common.ixt_support.ias_keymaxbits==0 && ixt->ixt_a_keylen==0)
|
|
+ goto zero_key_ok;
|
|
+ if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
|
|
+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
|
|
+ if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
|
|
+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
|
|
+ if (ixt->ixt_common.ixt_support.ias_keymaxbits!=ixt->ixt_common.ixt_support.ias_keyminbits)
|
|
+ barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
|
|
+ if (ixt->ixt_a_keylen==0)
|
|
+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
|
|
+zero_key_ok:
|
|
+ if (ixt->ixt_a_ctx_size==0)
|
|
+ barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
|
|
+ if (ixt->ixt_a_hmac_set_key==NULL)
|
|
+ barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
|
|
+ if (ixt->ixt_a_hmac_hash==NULL)
|
|
+ barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
|
|
+ ret=0;
|
|
+out:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Generic (enc, auth) registration entry point
|
|
+ */
|
|
+int register_ipsec_alg(struct ipsec_alg *ixt)
|
|
+{
|
|
+ int ret=-EINVAL;
|
|
+ /* Validation */
|
|
+ if (ixt==NULL)
|
|
+ barf_out("NULL ipsec_alg object passed\n");
|
|
+ if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
|
|
+ barf_out("incorrect version: %d.%d.%d-%d, "
|
|
+ "must be %d.%d.%d[-%d]\n",
|
|
+ IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
|
|
+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
|
|
+
|
|
+ switch(ixt->ixt_alg_type) {
|
|
+ case IPSEC_ALG_TYPE_AUTH:
|
|
+ if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
|
|
+ goto out;
|
|
+ break;
|
|
+ case IPSEC_ALG_TYPE_ENCRYPT:
|
|
+ if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
|
|
+ goto out;
|
|
+ /*
|
|
+ * Adapted two lines below:
|
|
+ * ivlen == 0 is possible (NULL enc has blocksize==1)
|
|
+ *
|
|
+ * fixed NULL support by David De Reu <DeReu@tComLabs.com>
|
|
+ */
|
|
+ if (ixt->ixt_support.ias_ivlen == 0
|
|
+ && ixt->ixt_blocksize > 1) {
|
|
+ ixt->ixt_support.ias_ivlen = ixt->ixt_blocksize*8;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);
|
|
+ }
|
|
+ INIT_LIST_HEAD(&ixt->ixt_list);
|
|
+ ret = ipsec_alg_insert(ixt);
|
|
+ if (ret<0)
|
|
+ barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
|
|
+ "Not loaded (ret=%d).\n",
|
|
+ ixt->ixt_support.ias_id, ret);
|
|
+
|
|
+
|
|
+ ret = pfkey_list_insert_supported((struct ipsec_alg_supported *)&ixt->ixt_support
|
|
+ , &(pfkey_supported_list[SADB_SATYPE_ESP]));
|
|
+
|
|
+ if (ret==0) {
|
|
+ ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
|
|
+ /* send register event to userspace */
|
|
+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
|
|
+ } else
|
|
+ printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
|
|
+ "Loading anyway.\n", ret);
|
|
+ ret=0;
|
|
+out:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * unregister ipsec_alg object from own tables, if
|
|
+ * success => calls pfkey_list_remove_supported()
|
|
+ */
|
|
+int unregister_ipsec_alg(struct ipsec_alg *ixt) {
|
|
+ int ret= -EINVAL;
|
|
+ switch(ixt->ixt_alg_type) {
|
|
+ case IPSEC_ALG_TYPE_AUTH:
|
|
+ case IPSEC_ALG_TYPE_ENCRYPT:
|
|
+ break;
|
|
+ default:
|
|
+ /* this is not a typo :) */
|
|
+ barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
|
|
+ ixt->ixt_name);
|
|
+ }
|
|
+
|
|
+ ret=ipsec_alg_delete(ixt);
|
|
+ if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
|
|
+ ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
|
|
+ pfkey_list_remove_supported((struct ipsec_alg_supported *)&ixt->ixt_support
|
|
+ , &(pfkey_supported_list[SADB_SATYPE_ESP]));
|
|
+
|
|
+ /* send register event to userspace */
|
|
+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
|
|
+ }
|
|
+
|
|
+out:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Must be called from user context
|
|
+ * used at module load type for testing algo implementation
|
|
+ */
|
|
+static int ipsec_alg_test_encrypt(int enc_alg, int test) {
|
|
+ int ret;
|
|
+ caddr_t buf = NULL;
|
|
+ int iv_size, keysize, key_e_size;
|
|
+ struct ipsec_alg_enc *ixt_e;
|
|
+ void *tmp_key_e = NULL;
|
|
+ #define BUFSZ 1024
|
|
+ #define MARGIN 0
|
|
+ #define test_enc (buf+MARGIN)
|
|
+ #define test_dec (test_enc+BUFSZ+MARGIN)
|
|
+ #define test_tmp (test_dec+BUFSZ+MARGIN)
|
|
+ #define test_key_e (test_tmp+BUFSZ+MARGIN)
|
|
+ #define test_iv (test_key_e+key_e_size+MARGIN)
|
|
+ #define test_key (test_iv+iv_size+MARGIN)
|
|
+ #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
|
|
+ ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
|
|
+ if (ixt_e==NULL) {
|
|
+ KLIPS_PRINT(1,
|
|
+ "klips_debug: ipsec_alg_test_encrypt: "
|
|
+ "encalg=%d object not found\n",
|
|
+ enc_alg);
|
|
+ ret=-EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+ iv_size=ixt_e->ixt_common.ixt_support.ias_ivlen / 8;
|
|
+ key_e_size=ixt_e->ixt_e_ctx_size;
|
|
+ keysize=ixt_e->ixt_e_keylen;
|
|
+ KLIPS_PRINT(1,
|
|
+ "klips_debug: ipsec_alg_test_encrypt: "
|
|
+ "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
|
|
+ enc_alg, iv_size, key_e_size, keysize);
|
|
+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
|
|
+ ret= -ENOMEM;
|
|
+ goto out;
|
|
+ }
|
|
+ get_random_bytes(test_key, keysize);
|
|
+ get_random_bytes(test_iv, iv_size);
|
|
+ if (ixt_e->ixt_e_new_key) {
|
|
+ tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
|
|
+ ret = tmp_key_e ? 0 : -EINVAL;
|
|
+ } else {
|
|
+ tmp_key_e = test_key_e;
|
|
+ ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
|
|
+ }
|
|
+ if (ret < 0)
|
|
+ goto out;
|
|
+ get_random_bytes(test_enc, BUFSZ);
|
|
+ memcpy(test_tmp, test_enc, BUFSZ);
|
|
+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
|
|
+ printk(KERN_INFO
|
|
+ "klips_info: ipsec_alg_test_encrypt: "
|
|
+ "cbc_encrypt=1 ret=%d\n",
|
|
+ ret);
|
|
+ ret=memcmp(test_enc, test_tmp, BUFSZ);
|
|
+ printk(KERN_INFO
|
|
+ "klips_info: ipsec_alg_test_encrypt: "
|
|
+ "memcmp(enc, tmp) ret=%d: %s\n", ret,
|
|
+ ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
|
|
+ memcpy(test_dec, test_enc, BUFSZ);
|
|
+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
|
|
+ printk(KERN_INFO
|
|
+ "klips_info: ipsec_alg_test_encrypt: "
|
|
+ "cbc_encrypt=0 ret=%d\n", ret);
|
|
+ ret=memcmp(test_dec, test_tmp, BUFSZ);
|
|
+ printk(KERN_INFO
|
|
+ "klips_info: ipsec_alg_test_encrypt: "
|
|
+ "memcmp(dec,tmp) ret=%d: %s\n", ret,
|
|
+ ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
|
|
+ {
|
|
+ /* Shamelessly taken from drivers/md sources O:) */
|
|
+ unsigned long now;
|
|
+ int i, count, max=0;
|
|
+ int encrypt, speed;
|
|
+ for (encrypt=0; encrypt <2;encrypt ++) {
|
|
+ for (i = 0; i < 5; i++) {
|
|
+ now = jiffies;
|
|
+ count = 0;
|
|
+ while (jiffies == now) {
|
|
+ mb();
|
|
+ ixt_e->ixt_e_cbc_encrypt(ixt_e,
|
|
+ tmp_key_e, test_tmp,
|
|
+ BUFSZ, test_iv, encrypt);
|
|
+ mb();
|
|
+ count++;
|
|
+ mb();
|
|
+ }
|
|
+ if (count > max)
|
|
+ max = count;
|
|
+ }
|
|
+ speed = max * (HZ * BUFSZ / 1024);
|
|
+ printk(KERN_INFO
|
|
+ "klips_info: ipsec_alg_test_encrypt: "
|
|
+ "%s %s speed=%d KB/s\n",
|
|
+ ixt_e->ixt_common.ixt_name,
|
|
+ encrypt? "encrypt": "decrypt", speed);
|
|
+ }
|
|
+ }
|
|
+out:
|
|
+ if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
|
|
+ if (buf) kfree(buf);
|
|
+ if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
|
|
+ return ret;
|
|
+ #undef test_enc
|
|
+ #undef test_dec
|
|
+ #undef test_tmp
|
|
+ #undef test_key_e
|
|
+ #undef test_iv
|
|
+ #undef test_key
|
|
+ #undef test_size
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Must be called from user context
|
|
+ * used at module load type for testing algo implementation
|
|
+ */
|
|
+static int ipsec_alg_test_auth(int auth_alg, int test) {
|
|
+ int ret;
|
|
+ caddr_t buf = NULL;
|
|
+ int blocksize, keysize, key_a_size;
|
|
+ struct ipsec_alg_auth *ixt_a;
|
|
+ #define BUFSZ 1024
|
|
+ #define MARGIN 0
|
|
+ #define test_auth (buf+MARGIN)
|
|
+ #define test_key_a (test_auth+BUFSZ+MARGIN)
|
|
+ #define test_key (test_key_a+key_a_size+MARGIN)
|
|
+ #define test_hash (test_key+keysize+MARGIN)
|
|
+ #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
|
|
+ ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
|
|
+ if (ixt_a==NULL) {
|
|
+ KLIPS_PRINT(1,
|
|
+ "klips_debug: ipsec_alg_test_auth: "
|
|
+ "encalg=%d object not found\n",
|
|
+ auth_alg);
|
|
+ ret=-EINVAL;
|
|
+ goto out;
|
|
+ }
|
|
+ blocksize=ixt_a->ixt_common.ixt_blocksize;
|
|
+ key_a_size=ixt_a->ixt_a_ctx_size;
|
|
+ keysize=ixt_a->ixt_a_keylen;
|
|
+ KLIPS_PRINT(1,
|
|
+ "klips_debug: ipsec_alg_test_auth: "
|
|
+ "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
|
|
+ auth_alg, blocksize, key_a_size, keysize);
|
|
+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
|
|
+ ret= -ENOMEM;
|
|
+ goto out;
|
|
+ }
|
|
+ get_random_bytes(test_key, keysize);
|
|
+ ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
|
|
+ if (ret < 0 )
|
|
+ goto out;
|
|
+ get_random_bytes(test_auth, BUFSZ);
|
|
+ ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
|
|
+ printk(KERN_INFO
|
|
+ "klips_info: ipsec_alg_test_auth: "
|
|
+ "ret=%d\n", ret);
|
|
+ {
|
|
+ /* Shamelessly taken from drivers/md sources O:) */
|
|
+ unsigned long now;
|
|
+ int i, count, max=0;
|
|
+ int speed;
|
|
+ for (i = 0; i < 5; i++) {
|
|
+ now = jiffies;
|
|
+ count = 0;
|
|
+ while (jiffies == now) {
|
|
+ mb();
|
|
+ ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
|
|
+ mb();
|
|
+ count++;
|
|
+ mb();
|
|
+ }
|
|
+ if (count > max)
|
|
+ max = count;
|
|
+ }
|
|
+ speed = max * (HZ * BUFSZ / 1024);
|
|
+ printk(KERN_INFO
|
|
+ "klips_info: ipsec_alg_test_auth: "
|
|
+ "%s hash speed=%d KB/s\n",
|
|
+ ixt_a->ixt_common.ixt_name,
|
|
+ speed);
|
|
+ }
|
|
+out:
|
|
+ if (buf) kfree(buf);
|
|
+ if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
|
|
+ return ret;
|
|
+ #undef test_auth
|
|
+ #undef test_key_a
|
|
+ #undef test_key
|
|
+ #undef test_hash
|
|
+ #undef test_size
|
|
+}
|
|
+
|
|
+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
|
|
+ switch(alg_type) {
|
|
+ case IPSEC_ALG_TYPE_ENCRYPT:
|
|
+ return ipsec_alg_test_encrypt(alg_id, test);
|
|
+ break;
|
|
+ case IPSEC_ALG_TYPE_AUTH:
|
|
+ return ipsec_alg_test_auth(alg_id, test);
|
|
+ break;
|
|
+ }
|
|
+ printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
|
|
+ "alg_type=%d alg_id=%d\n",
|
|
+ alg_type, alg_id);
|
|
+ return -EINVAL;
|
|
+}
|
|
+
|
|
+int ipsec_alg_init(void) {
|
|
+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
|
|
+ "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
|
|
+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
|
|
+ SADB_EALG_MAX, SADB_AALG_MAX);
|
|
+ /* Initialize tables */
|
|
+ write_lock_bh(&ipsec_alg_lock);
|
|
+ ipsec_alg_hash_init();
|
|
+ write_unlock_bh(&ipsec_alg_lock);
|
|
+
|
|
+ /* Initialize static algos */
|
|
+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
|
|
+ "calling ipsec_alg_static_init()\n");
|
|
+
|
|
+ /* If we are suppose to use our AES, and don't have
|
|
+ * CryptoAPI enabled...
|
|
+ */
|
|
+#if defined(CONFIG_KLIPS_ENC_AES) && CONFIG_KLIPS_ENC_AES && !defined(CONFIG_KLIPS_ENC_AES_MODULE)
|
|
+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
|
|
+#warning "Using built-in AES rather than CryptoAPI AES"
|
|
+#endif
|
|
+ {
|
|
+ extern int ipsec_aes_init(void);
|
|
+ ipsec_aes_init();
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#if defined(CONFIG_KLIPS_ENC_3DES) && CONFIG_KLIPS_ENC_3DES && !defined(CONFIG_KLIPS_ENC_3DES_MODULE)
|
|
+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
|
|
+#warning "Using built-in 3des rather than CryptoAPI 3des"
|
|
+#endif
|
|
+ {
|
|
+ extern int ipsec_3des_init(void);
|
|
+ ipsec_3des_init();
|
|
+ }
|
|
+#endif
|
|
+#if defined(CONFIG_KLIPS_ENC_NULL) && CONFIG_KLIPS_ENC_NULL && !defined(CONFIG_KLIPS_ENC_NULL_MODULE)
|
|
+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
|
|
+#warning "Using built-in null cipher rather than CryptoAPI null cipher"
|
|
+#endif
|
|
+#warning "Building with null cipher (ESP_NULL), blame on you :-)"
|
|
+ {
|
|
+ extern int ipsec_null_init(void);
|
|
+ ipsec_null_init();
|
|
+ }
|
|
+#endif
|
|
+
|
|
+
|
|
+ /* If we are doing CryptoAPI, then init */
|
|
+#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI && !defined(CONFIG_KLIPS_ENC_CRYPTOAPI_MODULE)
|
|
+ {
|
|
+ extern int ipsec_cryptoapi_init(void);
|
|
+ ipsec_cryptoapi_init();
|
|
+ }
|
|
+#endif
|
|
+
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/**********************************************
|
|
+ *
|
|
+ * INTERFACE for ipsec_sa init and wipe
|
|
+ *
|
|
+ **********************************************/
|
|
+
|
|
+/*
|
|
+ * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
|
|
+ */
|
|
+int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
|
|
+ struct ipsec_alg_enc *ixt_e;
|
|
+ struct ipsec_alg_auth *ixt_a;
|
|
+
|
|
+ /* Only ESP for now ... */
|
|
+ if (sa_p->ips_said.proto != IPPROTO_ESP)
|
|
+ return -EPROTONOSUPPORT;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
|
|
+ "entering for encalg=%d, authalg=%d\n",
|
|
+ sa_p->ips_encalg, sa_p->ips_authalg);
|
|
+
|
|
+ if ((ixt_e=(struct ipsec_alg_enc *)
|
|
+ ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug: ipsec_alg_sa_init() :"
|
|
+ "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
|
|
+ ixt_e, sa_p->ips_encalg);
|
|
+ sa_p->ips_alg_enc=ixt_e;
|
|
+ }
|
|
+
|
|
+ if ((ixt_a=(struct ipsec_alg_auth *)
|
|
+ ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug: ipsec_alg_sa_init() :"
|
|
+ "found ipsec_alg (ixt_a=%p) for auth=%d\n",
|
|
+ ixt_a, sa_p->ips_authalg);
|
|
+ sa_p->ips_alg_auth=ixt_a;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
|
|
+ */
|
|
+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
|
|
+ struct ipsec_alg *ixt;
|
|
+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
|
|
+ "unlinking for encalg=%d\n",
|
|
+ ixt->ixt_support.ias_id);
|
|
+ ipsec_alg_put(ixt);
|
|
+ }
|
|
+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
|
|
+ "unlinking for authalg=%d\n",
|
|
+ ixt->ixt_support.ias_id);
|
|
+ ipsec_alg_put(ixt);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_xform_get_info(char *buffer,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int length IPSEC_PROC_LAST_ARG)
|
|
+{
|
|
+ int len = 0;
|
|
+ off_t begin = 0;
|
|
+ int i;
|
|
+ struct list_head *head;
|
|
+ struct ipsec_alg *ixt;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_tncfg_get_info: "
|
|
+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
|
|
+ buffer,
|
|
+ *start,
|
|
+ (int)offset,
|
|
+ length);
|
|
+
|
|
+ for(i = 0, head = ipsec_alg_hash_table;
|
|
+ i<IPSEC_ALG_HASHSZ;
|
|
+ i++, head++)
|
|
+ {
|
|
+ struct list_head *p;
|
|
+ for (p=head->next; p!=head; p=p->next)
|
|
+ {
|
|
+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
|
|
+ len += ipsec_snprintf(buffer+len, length-len,
|
|
+ "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
|
|
+ ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_support.ias_id,
|
|
+ ixt->ixt_name, ixt->ixt_refcnt);
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len,
|
|
+ "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
|
|
+ ixt->ixt_state, ixt->ixt_blocksize,
|
|
+ ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len,
|
|
+ "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
|
|
+ ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
|
|
+
|
|
+ switch(ixt->ixt_alg_type)
|
|
+ {
|
|
+ case IPSEC_ALG_TYPE_AUTH:
|
|
+ {
|
|
+ struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len,
|
|
+ "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
|
|
+ auth->ixt_a_keylen, auth->ixt_a_ctx_size,
|
|
+ auth->ixt_a_authlen);
|
|
+ break;
|
|
+ }
|
|
+ case IPSEC_ALG_TYPE_ENCRYPT:
|
|
+ {
|
|
+ struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
|
|
+ len += ipsec_snprintf(buffer+len, length-len,
|
|
+ "KEYLEN=%d CTXSIZE=%d ",
|
|
+ enc->ixt_e_keylen, enc->ixt_e_ctx_size);
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "\n");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ len -= (offset - begin); /* Start slop */
|
|
+ if (len > length)
|
|
+ len = length;
|
|
+ return len;
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * As the author of this module, I ONLY ALLOW using it from
|
|
+ * GPL (or same LICENSE TERMS as kernel source) modules.
|
|
+ *
|
|
+ * In respect to hardware crypto engines this means:
|
|
+ * * Closed-source device drivers ARE NOT ALLOWED to use
|
|
+ * this interface.
|
|
+ * * Closed-source VHDL/Verilog firmware running on
|
|
+ * the crypto hardware device IS ALLOWED to use this interface
|
|
+ * via a GPL (or same LICENSE TERMS as kernel source) device driver.
|
|
+ * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * These symbols can only be used from GPL modules
|
|
+ * for now, I'm disabling this because it creates false
|
|
+ * symbol problems for old modutils.
|
|
+ */
|
|
+
|
|
+#ifdef CONFIG_MODULES
|
|
+#ifndef NET_26
|
|
+#if 0
|
|
+#ifndef EXPORT_SYMBOL_GPL
|
|
+#undef EXPORT_SYMBOL_GPL
|
|
+#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
|
|
+#endif
|
|
+#endif
|
|
+EXPORT_SYMBOL(register_ipsec_alg);
|
|
+EXPORT_SYMBOL(unregister_ipsec_alg);
|
|
+EXPORT_SYMBOL(ipsec_alg_test);
|
|
+#endif
|
|
+#endif
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,455 @@
|
|
+/*
|
|
+ * ipsec_alg to linux cryptoapi GLUE
|
|
+ *
|
|
+ * Authors: CODE.ar TEAM
|
|
+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
|
|
+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
|
|
+ * Luciano Ruete <docemeses@softhome.net>
|
|
+ *
|
|
+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * Example usage:
|
|
+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
|
|
+ * modprobe ipsec_cryptoapi
|
|
+ * modprobe ipsec_cryptoapi test=1
|
|
+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
|
|
+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
|
|
+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
|
|
+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
|
|
+ */
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+/*
|
|
+ * special case: ipsec core modular with this static algo inside:
|
|
+ * must avoid MODULE magic for this file
|
|
+ */
|
|
+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_CRYPTOAPI)
|
|
+#undef MODULE
|
|
+#endif
|
|
+
|
|
+#include <linux/module.h>
|
|
+#include <linux/init.h>
|
|
+
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/string.h>
|
|
+
|
|
+/* Check if __exit is defined, if not null it */
|
|
+#ifndef __exit
|
|
+#define __exit
|
|
+#endif
|
|
+
|
|
+/* warn the innocent */
|
|
+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
|
|
+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
|
|
+#define NO_CRYPTOAPI_SUPPORT
|
|
+#endif
|
|
+
|
|
+#include "openswan.h"
|
|
+#include "openswan/ipsec_alg.h"
|
|
+#include "openswan/ipsec_policy.h"
|
|
+
|
|
+#include <linux/crypto.h>
|
|
+#ifdef CRYPTO_API_VERSION_CODE
|
|
+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
|
|
+#define NO_CRYPTOAPI_SUPPORT
|
|
+#endif
|
|
+
|
|
+#ifdef NO_CRYPTOAPI_SUPPORT
|
|
+#warning "Building an unusable module :P"
|
|
+/* Catch old CryptoAPI by not allowing module to load */
|
|
+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
|
|
+{
|
|
+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
|
|
+ return -EINVAL;
|
|
+}
|
|
+#else
|
|
+#include <asm/scatterlist.h>
|
|
+#include <asm/pgtable.h>
|
|
+#include <linux/mm.h>
|
|
+
|
|
+#define CIPHERNAME_AES "aes"
|
|
+#define CIPHERNAME_1DES "des"
|
|
+#define CIPHERNAME_3DES "des3_ede"
|
|
+#define CIPHERNAME_BLOWFISH "blowfish"
|
|
+#define CIPHERNAME_CAST "cast5"
|
|
+#define CIPHERNAME_SERPENT "serpent"
|
|
+#define CIPHERNAME_TWOFISH "twofish"
|
|
+
|
|
+#define ESP_SERPENT 252 /* from ipsec drafts */
|
|
+#define ESP_TWOFISH 253 /* from ipsec drafts */
|
|
+
|
|
+#define DIGESTNAME_MD5 "md5"
|
|
+#define DIGESTNAME_SHA1 "sha1"
|
|
+
|
|
+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
|
|
+static int debug_crypto=0;
|
|
+static int test_crypto=0;
|
|
+static int excl_crypto=0;
|
|
+
|
|
+static int noauto = 0;
|
|
+
|
|
+#ifdef module_param
|
|
+module_param(debug_crypto,int,0600)
|
|
+module_param(test_crypto,int,0600)
|
|
+module_param(excl_crypto,int,0600)
|
|
+
|
|
+module_param(noauto,int,0600)
|
|
+#else
|
|
+MODULE_PARM(debug_crypto, "i");
|
|
+MODULE_PARM(test_crypto, "i");
|
|
+MODULE_PARM(excl_crypto, "i");
|
|
+
|
|
+MODULE_PARM(noauto,"i");
|
|
+#endif
|
|
+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
|
|
+
|
|
+#ifdef CONFIG_KLIPS_ENC_1DES
|
|
+static int des_ede1[] = {-1, -1};
|
|
+#endif
|
|
+static int des_ede3[] = {-1, -1};
|
|
+static int aes[] = {-1, -1};
|
|
+static int blowfish[] = {-1, -1};
|
|
+static int cast[] = {-1, -1};
|
|
+static int serpent[] = {-1, -1};
|
|
+static int twofish[] = {-1, -1};
|
|
+
|
|
+#ifdef CONFIG_KLIPS_ENC_1DES
|
|
+#ifdef module_param
|
|
+module_param_array(des_ede1,int,NULL,0)
|
|
+#else
|
|
+MODULE_PARM(des_ede1,"1-2i");
|
|
+#endif
|
|
+#endif
|
|
+#ifdef module_param
|
|
+module_param_array(des_ede3,int,NULL,0)
|
|
+module_param_array(aes,int,NULL,0)
|
|
+module_param_array(blowfish,int,NULL,0)
|
|
+module_param_array(cast,int,NULL,0)
|
|
+module_param_array(serpent,int,NULL,0)
|
|
+module_param_array(twofish,int,NULL,0)
|
|
+#else
|
|
+MODULE_PARM(des_ede3,"1-2i");
|
|
+MODULE_PARM(aes,"1-2i");
|
|
+MODULE_PARM(blowfish,"1-2i");
|
|
+MODULE_PARM(cast,"1-2i");
|
|
+MODULE_PARM(serpent,"1-2i");
|
|
+MODULE_PARM(twofish,"1-2i");
|
|
+#endif
|
|
+MODULE_PARM_DESC(des_ede1, "0: disable | 1: force_enable | min,max: dontuse");
|
|
+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
|
|
+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
|
|
+
|
|
+struct ipsec_alg_capi_cipher {
|
|
+ const char *ciphername; /* cryptoapi's ciphername */
|
|
+ unsigned blocksize;
|
|
+ unsigned short minbits;
|
|
+ unsigned short maxbits;
|
|
+ int *parm; /* lkm param for this cipher */
|
|
+ struct ipsec_alg_enc alg; /* note it's not a pointer */
|
|
+};
|
|
+
|
|
+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
|
|
+ { CIPHERNAME_AES, 16, 128, 256, aes, { ixt_common:{ ixt_support:{ ias_id: ESP_AES}}}},
|
|
+ { CIPHERNAME_TWOFISH, 16, 128, 256, twofish, { ixt_common:{ ixt_support:{ ias_id: ESP_TWOFISH,}}}},
|
|
+ { CIPHERNAME_SERPENT, 16, 128, 256, serpent, { ixt_common:{ ixt_support:{ ias_id: ESP_SERPENT,}}}},
|
|
+ { CIPHERNAME_CAST, 8, 128, 128, cast , { ixt_common:{ ixt_support:{ ias_id: ESP_CAST,}}}},
|
|
+ { CIPHERNAME_BLOWFISH, 8, 96, 448, blowfish, { ixt_common:{ ixt_support:{ ias_id: ESP_BLOWFISH,}}}},
|
|
+ { CIPHERNAME_3DES, 8, 192, 192, des_ede3, { ixt_common:{ ixt_support:{ ias_id: ESP_3DES,}}}},
|
|
+#ifdef CONFIG_KLIPS_ENC_1DES
|
|
+ { CIPHERNAME_1DES, 8, 64, 64, des_ede1, { ixt_common:{ ixt_support:{ ias_id: ESP_DES,}}}},
|
|
+#endif
|
|
+ { NULL, 0, 0, 0, NULL, {} }
|
|
+};
|
|
+
|
|
+#ifdef NOT_YET
|
|
+struct ipsec_alg_capi_digest {
|
|
+ const char *digestname; /* cryptoapi's digestname */
|
|
+ struct digest_implementation *di;
|
|
+ struct ipsec_alg_auth alg; /* note it's not a pointer */
|
|
+};
|
|
+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
|
|
+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
|
|
+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
|
|
+ { NULL, NULL, {} }
|
|
+};
|
|
+#endif
|
|
+/*
|
|
+ * "generic" linux cryptoapi setup_cipher() function
|
|
+ */
|
|
+int setup_cipher(const char *ciphername)
|
|
+{
|
|
+ return crypto_alg_available(ciphername, 0);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
|
|
+ * register_ipsec_alg for cointaned ipsec_alg object
|
|
+ */
|
|
+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
|
|
+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
|
|
+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
|
|
+
|
|
+static int
|
|
+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
|
|
+{
|
|
+ int ret;
|
|
+ cptr->alg.ixt_common.ixt_version = IPSEC_ALG_VERSION;
|
|
+ cptr->alg.ixt_common.ixt_module = THIS_MODULE;
|
|
+ atomic_set (& cptr->alg.ixt_common.ixt_refcnt, 0);
|
|
+ strncpy (cptr->alg.ixt_common.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_common.ixt_name));
|
|
+
|
|
+ cptr->alg.ixt_common.ixt_blocksize=cptr->blocksize;
|
|
+ cptr->alg.ixt_common.ixt_support.ias_keyminbits=cptr->minbits;
|
|
+ cptr->alg.ixt_common.ixt_support.ias_keymaxbits=cptr->maxbits;
|
|
+ cptr->alg.ixt_common.ixt_state = 0;
|
|
+ if (excl_crypto) cptr->alg.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
|
|
+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_common.ixt_support.ias_keymaxbits/8;
|
|
+ cptr->alg.ixt_e_ctx_size = 0;
|
|
+ cptr->alg.ixt_common.ixt_support.ias_exttype = IPSEC_ALG_TYPE_ENCRYPT;
|
|
+ cptr->alg.ixt_e_new_key = _capi_new_key;
|
|
+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
|
|
+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
|
|
+ cptr->alg.ixt_common.ixt_data = cptr;
|
|
+
|
|
+ ret=register_ipsec_alg_enc(&cptr->alg);
|
|
+ printk(KERN_INFO "KLIPS cryptoapi interface: "
|
|
+ "alg_type=%d alg_id=%d name=%s "
|
|
+ "keyminbits=%d keymaxbits=%d, %s(%d)\n",
|
|
+ cptr->alg.ixt_common.ixt_support.ias_exttype,
|
|
+ cptr->alg.ixt_common.ixt_support.ias_id,
|
|
+ cptr->alg.ixt_common.ixt_name,
|
|
+ cptr->alg.ixt_common.ixt_support.ias_keyminbits,
|
|
+ cptr->alg.ixt_common.ixt_support.ias_keymaxbits,
|
|
+ ret ? "not found" : "found", ret);
|
|
+ return ret;
|
|
+}
|
|
+/*
|
|
+ * called in ipsec_sa_wipe() time, will destroy key contexts
|
|
+ * and do 1 unbind()
|
|
+ */
|
|
+static void
|
|
+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
|
|
+{
|
|
+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
|
|
+
|
|
+ if (debug_crypto > 0)
|
|
+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
|
|
+ "name=%s key_e=%p \n",
|
|
+ alg->ixt_common.ixt_name, key_e);
|
|
+ if (!key_e) {
|
|
+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
|
|
+ "name=%s NULL key_e!\n",
|
|
+ alg->ixt_common.ixt_name);
|
|
+ return;
|
|
+ }
|
|
+ crypto_free_tfm(tfm);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * create new key context, need alg->ixt_data to know which
|
|
+ * (of many) cipher inside this module is the target
|
|
+ */
|
|
+static __u8 *
|
|
+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
|
|
+{
|
|
+ struct ipsec_alg_capi_cipher *cptr;
|
|
+ struct crypto_tfm *tfm=NULL;
|
|
+
|
|
+ cptr = alg->ixt_common.ixt_data;
|
|
+ if (!cptr) {
|
|
+ printk(KERN_ERR "_capi_new_key(): "
|
|
+ "NULL ixt_data (?!) for \"%s\" algo\n"
|
|
+ , alg->ixt_common.ixt_name);
|
|
+ goto err;
|
|
+ }
|
|
+ if (debug_crypto > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
|
|
+ "name=%s cptr=%p key=%p keysize=%d\n",
|
|
+ alg->ixt_common.ixt_name, cptr, key, keylen);
|
|
+
|
|
+ /*
|
|
+ * alloc tfm
|
|
+ */
|
|
+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
|
|
+ if (!tfm) {
|
|
+ printk(KERN_ERR "_capi_new_key(): "
|
|
+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
|
|
+ , alg->ixt_common.ixt_name, cptr->ciphername);
|
|
+ goto err;
|
|
+ }
|
|
+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
|
|
+ printk(KERN_ERR "_capi_new_key(): "
|
|
+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
|
|
+ , alg->ixt_common.ixt_name, keylen);
|
|
+ crypto_free_tfm(tfm);
|
|
+ tfm=NULL;
|
|
+ }
|
|
+err:
|
|
+ if (debug_crypto > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
|
|
+ "name=%s key=%p keylen=%d tfm=%p\n",
|
|
+ alg->ixt_common.ixt_name, key, keylen, tfm);
|
|
+ return (__u8 *) tfm;
|
|
+}
|
|
+/*
|
|
+ * core encryption function: will use cx->ci to call actual cipher's
|
|
+ * cbc function
|
|
+ */
|
|
+static int
|
|
+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
|
|
+ int error =0;
|
|
+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
|
|
+ struct scatterlist sg = {
|
|
+ .page = virt_to_page(in),
|
|
+ .offset = (unsigned long)(in) % PAGE_SIZE,
|
|
+ .length=ilen,
|
|
+ };
|
|
+ if (debug_crypto > 1)
|
|
+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
|
|
+ "key_e=%p "
|
|
+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
|
|
+ , key_e
|
|
+ , in, in, ilen, iv, encrypt);
|
|
+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
|
|
+ if (encrypt)
|
|
+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
|
|
+ else
|
|
+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
|
|
+ if (debug_crypto > 1)
|
|
+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
|
|
+ "error=%d\n"
|
|
+ , error);
|
|
+ return (error<0)? error : ilen;
|
|
+}
|
|
+/*
|
|
+ * main initialization loop: for each cipher in list, do
|
|
+ * 1) setup cryptoapi cipher else continue
|
|
+ * 2) register ipsec_alg object
|
|
+ */
|
|
+static int
|
|
+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
|
|
+{
|
|
+ struct ipsec_alg_capi_cipher *cptr;
|
|
+ /* foreach cipher in list ... */
|
|
+ for (cptr=clist;cptr->ciphername;cptr++) {
|
|
+ /*
|
|
+ * see if cipher has been disabled (0) or
|
|
+ * if noauto set and not enabled (1)
|
|
+ */
|
|
+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
|
|
+ if (debug_crypto>0)
|
|
+ printk(KERN_INFO "setup_cipher_list(): "
|
|
+ "ciphername=%s skipped at user request: "
|
|
+ "noauto=%d parm[0]=%d parm[1]=%d\n"
|
|
+ , cptr->ciphername
|
|
+ , noauto
|
|
+ , cptr->parm[0]
|
|
+ , cptr->parm[1]);
|
|
+ continue;
|
|
+ }
|
|
+ /*
|
|
+ * use a local ci to avoid touching cptr->ci,
|
|
+ * if register ipsec_alg success then bind cipher
|
|
+ */
|
|
+ if(cptr->alg.ixt_common.ixt_support.ias_name == NULL) {
|
|
+ cptr->alg.ixt_common.ixt_support.ias_name = cptr->ciphername;
|
|
+ }
|
|
+
|
|
+ if( setup_cipher(cptr->ciphername) ) {
|
|
+ if (debug_crypto > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:"
|
|
+ "setup_cipher_list():"
|
|
+ "ciphername=%s found\n"
|
|
+ , cptr->ciphername);
|
|
+
|
|
+ if (setup_ipsec_alg_capi_cipher(cptr) != 0) {
|
|
+ printk(KERN_ERR "klips_debug:"
|
|
+ "setup_cipher_list():"
|
|
+ "ciphername=%s failed ipsec_alg_register\n"
|
|
+ , cptr->ciphername);
|
|
+ }
|
|
+ } else {
|
|
+ printk(KERN_INFO "KLIPS: lookup for ciphername=%s: not found \n",
|
|
+ cptr->ciphername);
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+/*
|
|
+ * deregister ipsec_alg objects and unbind ciphers
|
|
+ */
|
|
+static int
|
|
+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
|
|
+{
|
|
+ struct ipsec_alg_capi_cipher *cptr;
|
|
+ /* foreach cipher in list ... */
|
|
+ for (cptr=clist;cptr->ciphername;cptr++) {
|
|
+ if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
|
|
+ unregister_ipsec_alg_enc(&cptr->alg);
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+/*
|
|
+ * test loop for registered algos
|
|
+ */
|
|
+static int
|
|
+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
|
|
+{
|
|
+ int test_ret;
|
|
+ struct ipsec_alg_capi_cipher *cptr;
|
|
+ /* foreach cipher in list ... */
|
|
+ for (cptr=clist;cptr->ciphername;cptr++) {
|
|
+ if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
|
|
+ test_ret=ipsec_alg_test(
|
|
+ cptr->alg.ixt_common.ixt_support.ias_exttype,
|
|
+ cptr->alg.ixt_common.ixt_support.ias_id,
|
|
+ test_crypto);
|
|
+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
|
|
+ cptr->alg.ixt_common.ixt_support.ias_exttype,
|
|
+ cptr->alg.ixt_common.ixt_support.ias_id,
|
|
+ test_ret);
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
|
|
+{
|
|
+ int ret, test_ret;
|
|
+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
|
|
+ return -EPROTONOSUPPORT;
|
|
+ if (ret==0 && test_crypto) {
|
|
+ test_ret=test_cipher_list(alg_capi_carray);
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini )
|
|
+{
|
|
+ unsetup_cipher_list(alg_capi_carray);
|
|
+ return;
|
|
+}
|
|
+#ifdef MODULE_LICENSE
|
|
+MODULE_LICENSE("GPL");
|
|
+#endif
|
|
+
|
|
+#endif /* NO_CRYPTOAPI_SUPPORT */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,607 @@
|
|
+/*
|
|
+ * processing code for ESP
|
|
+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+char ipsec_esp_c_version[] = "RCSID $Id: ipsec_esp.c,v 1.13.2.6 2006/10/06 21:39:26 paul Exp $";
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <openswan.h>
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+#include <net/protocol.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#include "openswan/ipsec_xmit.h"
|
|
+
|
|
+#include "openswan/ipsec_auth.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+#include "openswan/ipsec_esp.h"
|
|
+#endif /* CONFIG_KLIPS_ESP */
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#include "openswan/ipsec_alg.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+#define ESP_DMP(_x,_y,_z) if(debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
|
|
+#else
|
|
+#define ESP_DMP(_x,_y,_z)
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb)
|
|
+{
|
|
+ __u8 proto;
|
|
+ int len; /* packet length */
|
|
+
|
|
+ len = skb->len;
|
|
+ proto = irs->ipp->protocol;
|
|
+
|
|
+ /* XXX this will need to be 8 for IPv6 */
|
|
+ if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
|
|
+ printk("klips_error:ipsec_rcv: "
|
|
+ "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
|
|
+ len - irs->iphlen,
|
|
+ irs->ipsaddr_txt);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ return IPSEC_RCV_BADLEN;
|
|
+ }
|
|
+
|
|
+ if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "runt esp packet of skb->len=%d received from %s, dropped.\n",
|
|
+ skb->len,
|
|
+ irs->ipsaddr_txt);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ return IPSEC_RCV_BADLEN;
|
|
+ }
|
|
+
|
|
+ irs->protostuff.espstuff.espp = (struct esphdr *)skb->h.raw;
|
|
+ irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb,
|
|
+ __u32 *replay,
|
|
+ unsigned char **authenticator)
|
|
+{
|
|
+ struct esphdr *espp = irs->protostuff.espstuff.espp;
|
|
+ //unsigned char *idat = (unsigned char *)espp;
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
|
|
+ irs->ipsaddr_txt,
|
|
+ (__u32)ntohl(espp->esp_rpl),
|
|
+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
|
|
+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
|
|
+ irs->len,
|
|
+ irs->ilen,
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+
|
|
+ *replay = ntohl(espp->esp_rpl);
|
|
+ *authenticator = &(skb->h.raw[irs->ilen]);
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb)
|
|
+{
|
|
+ struct auth_alg *aa;
|
|
+ struct esphdr *espp = irs->protostuff.espstuff.espp;
|
|
+ union {
|
|
+ MD5_CTX md5;
|
|
+ SHA1_CTX sha1;
|
|
+ } tctx;
|
|
+
|
|
+ if (irs->ipsp->ips_alg_auth) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "ipsec_alg hashing proto=%d... ",
|
|
+ irs->said.proto);
|
|
+ if(irs->said.proto == IPPROTO_ESP) {
|
|
+ ipsec_alg_sa_esp_hash(irs->ipsp,
|
|
+ (caddr_t)espp, irs->ilen,
|
|
+ irs->hash, AHHMAC_HASHLEN);
|
|
+ return IPSEC_RCV_OK;
|
|
+ }
|
|
+ return IPSEC_RCV_BADPROTO;
|
|
+ }
|
|
+ aa = irs->authfuncs;
|
|
+
|
|
+ /* copy the initialized keying material */
|
|
+ memcpy(&tctx, irs->ictx, irs->ictx_len);
|
|
+
|
|
+#ifdef HASH_DEBUG
|
|
+ ESP_DMP("ictx", irs->ictx, irs->ictx_len);
|
|
+
|
|
+ ESP_DMP("mac_esp", (caddr_t)espp, irs->ilen);
|
|
+#endif
|
|
+ (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
|
|
+
|
|
+ (*aa->final)(irs->hash, (void *)&tctx);
|
|
+
|
|
+#ifdef HASH_DEBUG
|
|
+ ESP_DMP("hash1", irs->hash, aa->hashlen);
|
|
+#endif
|
|
+
|
|
+ memcpy(&tctx, irs->octx, irs->octx_len);
|
|
+
|
|
+#ifdef HASH_DEBUG
|
|
+ ESP_DMP("octx", irs->octx, irs->octx_len);
|
|
+#endif
|
|
+
|
|
+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
|
|
+ (*aa->final)(irs->hash, (void *)&tctx);
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
|
|
+{
|
|
+ struct ipsec_sa *ipsp = irs->ipsp;
|
|
+ struct esphdr *espp = irs->protostuff.espstuff.espp;
|
|
+ int i;
|
|
+ int pad = 0, padlen;
|
|
+ int badpad = 0;
|
|
+ int esphlen = 0;
|
|
+ __u8 *idat; /* pointer to content to be decrypted/authenticated */
|
|
+ int encaplen = 0;
|
|
+ struct sk_buff *skb;
|
|
+ struct ipsec_alg_enc *ixt_e=NULL;
|
|
+
|
|
+ skb=irs->skb;
|
|
+
|
|
+ idat = skb->h.raw;
|
|
+
|
|
+ /* encaplen is the distance between the end of the IP
|
|
+ * header and the beginning of the ESP header.
|
|
+ * on ESP headers it is zero, but on UDP-encap ESP
|
|
+ * it includes the space for the UDP header.
|
|
+ *
|
|
+ * Note: UDP-encap code has already moved the
|
|
+ * skb->data forward to accomodate this.
|
|
+ */
|
|
+ encaplen = idat - (skb->nh.raw + irs->iphlen);
|
|
+
|
|
+ ixt_e=ipsp->ips_alg_enc;
|
|
+ esphlen = ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "encalg=%d esphlen=%d\n",
|
|
+ ipsp->ips_encalg, esphlen);
|
|
+
|
|
+ idat += esphlen;
|
|
+ irs->ilen -= esphlen;
|
|
+
|
|
+ if (ipsec_alg_esp_encrypt(ipsp,
|
|
+ idat, irs->ilen, espp->esp_iv,
|
|
+ IPSEC_ALG_DECRYPT) <= 0) {
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ KLIPS_ERROR(debug_rcv, "klips_error:ipsec_rcv: "
|
|
+ "got packet with esplen = %d "
|
|
+ "from %s -- should be on "
|
|
+ "ENC(%d) octet boundary, "
|
|
+ "packet dropped\n",
|
|
+ irs->ilen,
|
|
+ irs->ipsaddr_txt,
|
|
+ ipsp->ips_encalg);
|
|
+#endif
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ return IPSEC_RCV_BAD_DECRYPT;
|
|
+ }
|
|
+
|
|
+ ESP_DMP("postdecrypt", idat, irs->ilen);
|
|
+
|
|
+ irs->next_header = idat[irs->ilen - 1];
|
|
+ padlen = idat[irs->ilen - 2];
|
|
+ pad = padlen + 2 + irs->authlen;
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
|
|
+ padlen);
|
|
+
|
|
+ for (i = 1; i <= padlen; i++) {
|
|
+ if((i % 16) == 1) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
|
|
+ "klips_debug: %02x:",
|
|
+ i - 1);
|
|
+ }
|
|
+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
|
|
+ " %02x",
|
|
+ idat[irs->ilen - 2 - padlen + i - 1]);
|
|
+ if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
|
|
+ badpad = 1;
|
|
+ }
|
|
+ if((i % 16) == 0) {
|
|
+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
|
|
+ "\n");
|
|
+ }
|
|
+ }
|
|
+ if((i % 16) != 1) {
|
|
+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
|
|
+ "\n");
|
|
+ }
|
|
+ if(badpad) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "warning, decrypted packet from %s has bad padding\n",
|
|
+ irs->ipsaddr_txt);
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "...may be bad decryption -- not dropped\n");
|
|
+ ipsp->ips_errs.ips_encpad_errs += 1;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "packet decrypted from %s: next_header = %d, padding = %d\n",
|
|
+ irs->ipsaddr_txt,
|
|
+ irs->next_header,
|
|
+ pad - 2 - irs->authlen);
|
|
+
|
|
+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad));
|
|
+
|
|
+ /*
|
|
+ * move the IP header forward by the size of the ESP header, which
|
|
+ * will remove the the ESP header from the packet.
|
|
+ *
|
|
+ * XXX this is really unnecessary, since odds we are in tunnel
|
|
+ * mode, and we will be *removing* this IP header.
|
|
+ *
|
|
+ */
|
|
+ memmove((void *)(idat - irs->iphlen),
|
|
+ (void *)(skb->nh.raw), irs->iphlen);
|
|
+
|
|
+ ESP_DMP("esp postmove", (idat - irs->iphlen),
|
|
+ irs->iphlen + irs->ilen);
|
|
+
|
|
+ /* skb_pull below, will move up by esphlen */
|
|
+
|
|
+ /* XXX not clear how this can happen, as the message indicates */
|
|
+ if(skb->len < esphlen) {
|
|
+ printk(KERN_WARNING
|
|
+ "klips_error:ipsec_rcv: "
|
|
+ "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n",
|
|
+ esphlen, (int)(skb->len));
|
|
+ return IPSEC_RCV_ESP_DECAPFAIL;
|
|
+ }
|
|
+ skb_pull(skb, esphlen);
|
|
+ skb->nh.raw = idat - irs->iphlen;
|
|
+ irs->ipp = skb->nh.iph;
|
|
+
|
|
+ ESP_DMP("esp postpull", skb->data, skb->len);
|
|
+
|
|
+ /* now, trip off the padding from the end */
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "trimming to %d.\n",
|
|
+ irs->len - esphlen - pad);
|
|
+ if(pad + esphlen <= irs->len) {
|
|
+ skb_trim(skb, irs->len - esphlen - pad);
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "bogus packet, size is zero or negative, dropping.\n");
|
|
+ return IPSEC_RCV_DECAPFAIL;
|
|
+ }
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+/*
|
|
+ *
|
|
+ */
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+#ifdef CONFIG_KLIPS_ENC_3DES
|
|
+ __u32 iv[2];
|
|
+#endif
|
|
+ struct esphdr *espp;
|
|
+ int ilen = 0;
|
|
+ int padlen = 0, i;
|
|
+ unsigned char *dat;
|
|
+ unsigned char *idat, *pad;
|
|
+ __u8 hash[AH_AMAX];
|
|
+ union {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ MD5_CTX md5;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ SHA1_CTX sha1;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ } tctx;
|
|
+
|
|
+ dat = (unsigned char *)ixs->iph;
|
|
+
|
|
+ espp = (struct esphdr *)(dat + ixs->iphlen);
|
|
+ espp->esp_spi = ixs->ipsp->ips_said.spi;
|
|
+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
|
|
+
|
|
+ switch(ixs->ipsp->ips_encalg) {
|
|
+#if defined(CONFIG_KLIPS_ENC_3DES)
|
|
+#ifdef CONFIG_KLIPS_ENC_3DES
|
|
+ case ESP_3DES:
|
|
+#endif /* CONFIG_KLIPS_ENC_3DES */
|
|
+ iv[0] = *((__u32*)&(espp->esp_iv) ) =
|
|
+ ((__u32*)(ixs->ipsp->ips_iv))[0];
|
|
+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
|
|
+ ((__u32*)(ixs->ipsp->ips_iv))[1];
|
|
+ break;
|
|
+#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_ESP_BADALG;
|
|
+ }
|
|
+
|
|
+ idat = dat + ixs->iphlen + sizeof(struct esphdr);
|
|
+ ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen);
|
|
+
|
|
+ /* Self-describing padding */
|
|
+ pad = &dat[ixs->skb->len - ixs->tailroom];
|
|
+ padlen = ixs->tailroom - 2 - ixs->authlen;
|
|
+ for (i = 0; i < padlen; i++) {
|
|
+ pad[i] = i + 1;
|
|
+ }
|
|
+ dat[ixs->skb->len - ixs->authlen - 2] = padlen;
|
|
+
|
|
+ dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol;
|
|
+ ixs->iph->protocol = IPPROTO_ESP;
|
|
+
|
|
+ switch(ixs->ipsp->ips_encalg) {
|
|
+#ifdef CONFIG_KLIPS_ENC_3DES
|
|
+ case ESP_3DES:
|
|
+ des_ede3_cbc_encrypt((des_cblock *)idat,
|
|
+ (des_cblock *)idat,
|
|
+ ilen,
|
|
+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
|
|
+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
|
|
+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
|
|
+ (des_cblock *)iv, 1);
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_ENC_3DES */
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_ESP_BADALG;
|
|
+ }
|
|
+
|
|
+ switch(ixs->ipsp->ips_encalg) {
|
|
+#if defined(CONFIG_KLIPS_ENC_3DES)
|
|
+#ifdef CONFIG_KLIPS_ENC_3DES
|
|
+ case ESP_3DES:
|
|
+#endif /* CONFIG_KLIPS_ENC_3DES */
|
|
+ /* XXX update IV with the last 8 octets of the encryption */
|
|
+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
|
|
+ ((__u32*)(ixs->ipsp->ips_iv))[0] =
|
|
+ ((__u32 *)(idat))[(ilen >> 2) - 2];
|
|
+ ((__u32*)(ixs->ipsp->ips_iv))[1] =
|
|
+ ((__u32 *)(idat))[(ilen >> 2) - 1];
|
|
+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
|
|
+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
|
|
+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
|
|
+ break;
|
|
+#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_ESP_BADALG;
|
|
+ }
|
|
+
|
|
+ switch(ixs->ipsp->ips_authalg) {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ case AH_MD5:
|
|
+ ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
|
|
+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
|
|
+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
|
|
+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Final(hash, &tctx.md5);
|
|
+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
|
|
+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
|
|
+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
|
|
+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Final(hash, &tctx.md5);
|
|
+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
|
|
+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
|
|
+
|
|
+ /* paranoid */
|
|
+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
|
|
+ memset((caddr_t)hash, 0, sizeof(*hash));
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ case AH_SHA:
|
|
+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
|
|
+ SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
|
|
+ SHA1Final(hash, &tctx.sha1);
|
|
+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
|
|
+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
|
|
+ SHA1Final(hash, &tctx.sha1);
|
|
+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
|
|
+
|
|
+ /* paranoid */
|
|
+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
|
|
+ memset((caddr_t)hash, 0, sizeof(*hash));
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ case AH_NONE:
|
|
+ break;
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_AH_BADALG;
|
|
+ }
|
|
+
|
|
+ ixs->skb->h.raw = (unsigned char*)espp;
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+
|
|
+struct xform_functions esp_xform_funcs[]={
|
|
+ { rcv_checks: ipsec_rcv_esp_checks,
|
|
+ rcv_setup_auth: ipsec_rcv_esp_decrypt_setup,
|
|
+ rcv_calc_auth: ipsec_rcv_esp_authcalc,
|
|
+ rcv_decrypt: ipsec_rcv_esp_decrypt,
|
|
+
|
|
+ xmit_setup: ipsec_xmit_esp_setup,
|
|
+ xmit_headroom: sizeof(struct esphdr),
|
|
+ xmit_needtailroom: 1,
|
|
+ },
|
|
+};
|
|
+
|
|
+#ifdef NET_26
|
|
+struct inet_protocol esp_protocol = {
|
|
+ .handler = ipsec_rcv,
|
|
+ .no_policy = 1,
|
|
+};
|
|
+#else
|
|
+struct inet_protocol esp_protocol =
|
|
+{
|
|
+ ipsec_rcv, /* ESP handler */
|
|
+ NULL, /* TUNNEL error control */
|
|
+#ifdef NETDEV_25
|
|
+ 1, /* no policy */
|
|
+#else
|
|
+ 0, /* next */
|
|
+ IPPROTO_ESP, /* protocol ID */
|
|
+ 0, /* copy */
|
|
+ NULL, /* data */
|
|
+ "ESP" /* name */
|
|
+#endif
|
|
+};
|
|
+#endif /* NET_26 */
|
|
+
|
|
+#endif /* !CONFIG_KLIPS_ESP */
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_esp.c,v $
|
|
+ * Revision 1.13.2.6 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.13.2.5 2006/08/24 03:02:01 paul
|
|
+ * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
|
|
+ *
|
|
+ * Revision 1.13.2.4 2006/05/06 03:07:38 ken
|
|
+ * Pull in proper padsize->tailroom fix from #public
|
|
+ * Need to do correct math on padlen since padsize is not equal to tailroom
|
|
+ *
|
|
+ * Revision 1.13.2.3 2006/05/05 03:58:04 ken
|
|
+ * ixs->padsize becomes ixs->tailroom
|
|
+ *
|
|
+ * Revision 1.13.2.2 2006/05/01 14:36:03 mcr
|
|
+ * use KLIPS_ERROR for fatal things.
|
|
+ *
|
|
+ * Revision 1.13.2.1 2006/04/20 16:33:06 mcr
|
|
+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
|
|
+ * Fix in-kernel module compilation. Sub-makefiles do not work.
|
|
+ *
|
|
+ * Revision 1.13 2005/05/21 03:19:57 mcr
|
|
+ * hash ctx is not really that interesting most of the time.
|
|
+ *
|
|
+ * Revision 1.12 2005/05/11 01:28:49 mcr
|
|
+ * removed "poor-man"s OOP in favour of proper C structures.
|
|
+ *
|
|
+ * Revision 1.11 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.10 2005/04/17 04:36:14 mcr
|
|
+ * code now deals with ESP and UDP-ESP code.
|
|
+ *
|
|
+ * Revision 1.9 2005/04/15 19:52:30 mcr
|
|
+ * adjustments to use proper skb fields for data.
|
|
+ *
|
|
+ * Revision 1.8 2004/09/14 00:22:57 mcr
|
|
+ * adjustment of MD5* functions.
|
|
+ *
|
|
+ * Revision 1.7 2004/09/13 02:23:01 mcr
|
|
+ * #define inet_protocol if necessary.
|
|
+ *
|
|
+ * Revision 1.6 2004/09/06 18:35:49 mcr
|
|
+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
|
|
+ * so adjust for that.
|
|
+ *
|
|
+ * Revision 1.5 2004/08/17 03:27:23 mcr
|
|
+ * klips 2.6 edits.
|
|
+ *
|
|
+ * Revision 1.4 2004/08/04 15:57:07 mcr
|
|
+ * moved des .h files to include/des/ *
|
|
+ * included 2.6 protocol specific things
|
|
+ * started at NAT-T support, but it will require a kernel patch.
|
|
+ *
|
|
+ * Revision 1.3 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.2 2004/04/06 02:49:25 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,614 @@
|
|
+/*
|
|
+ * @(#) Initialization code.
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * 2001 - 2004 Michael Richardson <mcr@xelerance.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * /proc system code was split out into ipsec_proc.c after rev. 1.70.
|
|
+ *
|
|
+ */
|
|
+
|
|
+char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.104.2.4 2006/10/06 21:39:26 paul Exp $";
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/in.h> /* struct sockaddr_in */
|
|
+#include <linux/skbuff.h>
|
|
+#include <linux/random.h> /* get_random_bytes() */
|
|
+#include <net/protocol.h>
|
|
+
|
|
+#include <openswan.h>
|
|
+
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* 23_SPINLOCK */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* 23_SPINLOCK */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#ifdef CONFIG_PROC_FS
|
|
+# include <linux/proc_fs.h>
|
|
+#endif /* CONFIG_PROC_FS */
|
|
+
|
|
+#ifdef NETLINK_SOCK
|
|
+# include <linux/netlink.h>
|
|
+#else
|
|
+# include <net/netlink.h>
|
|
+#endif
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+
|
|
+#include "openswan/ipsec_life.h"
|
|
+#include "openswan/ipsec_stats.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_esp.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+# include "openswan/ipcomp.h"
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#include "openswan/ipsec_alg.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
|
|
+#include <net/xfrmudp.h>
|
|
+#endif
|
|
+
|
|
+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(HAVE_XFRM4_UDP_REGISTER)
|
|
+#warning "You are trying to build KLIPS2.6 with NAT-T support, but you did not"
|
|
+#error "properly apply the NAT-T patch to your 2.6 kernel source tree."
|
|
+#endif
|
|
+
|
|
+#if !defined(CONFIG_KLIPS_ESP) && !defined(CONFIG_KLIPS_AH)
|
|
+#error "kernel configuration must include ESP or AH"
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * seems to be present in 2.4.10 (Linus), but also in some RH and other
|
|
+ * distro kernels of a lower number.
|
|
+ */
|
|
+#ifdef MODULE_LICENSE
|
|
+MODULE_LICENSE("GPL");
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int debug_eroute = 0;
|
|
+int debug_spi = 0;
|
|
+int debug_netlink = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+struct prng ipsec_prng;
|
|
+
|
|
+
|
|
+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
|
|
+xfrm4_rcv_encap_t klips_old_encap = NULL;
|
|
+#endif
|
|
+
|
|
+extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
|
|
+/*
|
|
+ * the following structure is required so that we receive
|
|
+ * event notifications when network devices are enabled and
|
|
+ * disabled (ifconfig up and down).
|
|
+ */
|
|
+static struct notifier_block ipsec_dev_notifier={
|
|
+ ipsec_device_event,
|
|
+ NULL,
|
|
+ 0
|
|
+};
|
|
+
|
|
+#ifdef CONFIG_SYSCTL
|
|
+extern int ipsec_sysctl_register(void);
|
|
+extern void ipsec_sysctl_unregister(void);
|
|
+#endif
|
|
+
|
|
+#if defined(NET_26) || defined(IPSKB_XFRM_TUNNEL_SIZE)
|
|
+static inline int
|
|
+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
|
|
+{
|
|
+ return inet_add_protocol(prot, protocol);
|
|
+}
|
|
+
|
|
+static inline int
|
|
+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
|
|
+{
|
|
+ return inet_del_protocol(prot, protocol);
|
|
+}
|
|
+
|
|
+#else
|
|
+static inline int
|
|
+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
|
|
+{
|
|
+ inet_add_protocol(prot);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static inline int
|
|
+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
|
|
+{
|
|
+ inet_del_protocol(prot);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+/* void */
|
|
+int
|
|
+ipsec_klips_init(void)
|
|
+{
|
|
+ int error = 0;
|
|
+ unsigned char seed[256];
|
|
+#ifdef CONFIG_KLIPS_ENC_3DES
|
|
+ extern int des_check_key;
|
|
+
|
|
+ /* turn off checking of keys */
|
|
+ des_check_key=0;
|
|
+#endif /* CONFIG_KLIPS_ENC_3DES */
|
|
+
|
|
+ KLIPS_PRINT(1, "klips_info:ipsec_init: "
|
|
+ "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n",
|
|
+ ipsec_version_code());
|
|
+
|
|
+ error |= ipsec_proc_init();
|
|
+
|
|
+#ifdef SPINLOCK
|
|
+ ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
|
|
+#else /* SPINLOCK */
|
|
+ ipsec_sadb.sadb_lock = 0;
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#ifndef SPINLOCK
|
|
+ tdb_lock.lock = 0;
|
|
+ eroute_lock.lock = 0;
|
|
+#endif /* !SPINLOCK */
|
|
+
|
|
+ error |= ipsec_sadb_init();
|
|
+ error |= ipsec_radijinit();
|
|
+
|
|
+ error |= pfkey_init();
|
|
+
|
|
+ error |= register_netdevice_notifier(&ipsec_dev_notifier);
|
|
+
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+ openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP);
|
|
+#endif /* CONFIG_KLIPS_ESP */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_AH
|
|
+ openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH);
|
|
+#endif /* CONFIG_KLIPS_AH */
|
|
+
|
|
+/* we never actually link IPCOMP to the stack */
|
|
+#ifdef IPCOMP_USED_ALONE
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP);
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+#endif
|
|
+
|
|
+ error |= ipsec_tunnel_init_devices();
|
|
+
|
|
+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
|
|
+ /* register our ESP-UDP handler */
|
|
+ if(udp4_register_esp_rcvencap(klips26_rcv_encap
|
|
+ , &klips_old_encap)!=0) {
|
|
+ printk(KERN_ERR "KLIPS: can not register klips_rcv_encap function\n");
|
|
+ }
|
|
+#endif
|
|
+
|
|
+
|
|
+#ifdef CONFIG_SYSCTL
|
|
+ error |= ipsec_sysctl_register();
|
|
+#endif
|
|
+
|
|
+ ipsec_alg_init();
|
|
+
|
|
+ get_random_bytes((void *)seed, sizeof(seed));
|
|
+ prng_init(&ipsec_prng, seed, sizeof(seed));
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+
|
|
+/* void */
|
|
+int
|
|
+ipsec_cleanup(void)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+#ifdef CONFIG_SYSCTL
|
|
+ ipsec_sysctl_unregister();
|
|
+#endif
|
|
+#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
|
|
+ if(udp4_unregister_esp_rcvencap(klips_old_encap) < 0) {
|
|
+ printk(KERN_ERR "KLIPS: can not unregister klips_rcv_encap function\n");
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
|
|
+ "klips_debug:ipsec_cleanup: "
|
|
+ "calling ipsec_tunnel_cleanup_devices.\n");
|
|
+ error |= ipsec_tunnel_cleanup_devices();
|
|
+
|
|
+ KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
|
|
+
|
|
+/* we never actually link IPCOMP to the stack */
|
|
+#ifdef IPCOMP_USED_ALONE
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
|
|
+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
|
|
+ "comp close: can't remove protocol\n");
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+#endif /* IPCOMP_USED_ALONE */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_AH
|
|
+ if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
|
|
+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
|
|
+ "ah close: can't remove protocol\n");
|
|
+#endif /* CONFIG_KLIPS_AH */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+ if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0)
|
|
+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
|
|
+ "esp close: can't remove protocol\n");
|
|
+#endif /* CONFIG_KLIPS_ESP */
|
|
+
|
|
+ error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
|
|
+
|
|
+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
|
|
+ "klips_debug:ipsec_cleanup: "
|
|
+ "calling ipsec_sadb_cleanup.\n");
|
|
+ error |= ipsec_sadb_cleanup(0);
|
|
+ error |= ipsec_sadb_free();
|
|
+
|
|
+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
|
|
+ "klips_debug:ipsec_cleanup: "
|
|
+ "calling ipsec_radijcleanup.\n");
|
|
+ error |= ipsec_radijcleanup();
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
|
|
+ "klips_debug:ipsec_cleanup: "
|
|
+ "calling pfkey_cleanup.\n");
|
|
+ error |= pfkey_cleanup();
|
|
+
|
|
+ ipsec_proc_cleanup();
|
|
+
|
|
+ prng_final(&ipsec_prng);
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+#ifdef MODULE
|
|
+int
|
|
+init_module(void)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ error |= ipsec_klips_init();
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+void
|
|
+cleanup_module(void)
|
|
+{
|
|
+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
|
|
+ "klips_debug:cleanup_module: "
|
|
+ "calling ipsec_cleanup.\n");
|
|
+
|
|
+ ipsec_cleanup();
|
|
+
|
|
+ KLIPS_PRINT(1, "klips_info:cleanup_module: "
|
|
+ "ipsec module unloaded.\n");
|
|
+}
|
|
+#endif /* MODULE */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_init.c,v $
|
|
+ * Revision 1.104.2.4 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.104.2.3 2006/07/31 15:25:20 paul
|
|
+ * Check for NETKEY backport in Debian using IPSKB_XFRM_TUNNEL_SIZE to
|
|
+ * determine wether inet_add_protocol needs the protocol argument.
|
|
+ *
|
|
+ * Revision 1.104.2.2 2006/04/20 16:33:06 mcr
|
|
+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
|
|
+ * Fix in-kernel module compilation. Sub-makefiles do not work.
|
|
+ *
|
|
+ * Revision 1.104.2.1 2005/08/12 01:18:20 ken
|
|
+ * Warn people who don't have NAT-T patch applied, but try and compile NAT-T code
|
|
+ *
|
|
+ * Revision 1.105 2005/08/12 00:56:33 mcr
|
|
+ * add warning for people who didn't apply nat-t patch.
|
|
+ *
|
|
+ * Revision 1.104 2005/07/08 15:51:41 mcr
|
|
+ * removed duplicate NAT-T code.
|
|
+ * if CONFIG_IPSEC_NAT_TRAVERSAL isn't defined, then there is no issue.
|
|
+ *
|
|
+ * Revision 1.103 2005/07/08 03:02:05 paul
|
|
+ * Fixed garbled define that accidentally got commited to the real tree.
|
|
+ *
|
|
+ * Revision 1.102 2005/07/08 02:56:37 paul
|
|
+ * gcc4 fixes that were not commited because vault was down
|
|
+ *
|
|
+ * Revision 1.101 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.100 2005/04/10 22:56:09 mcr
|
|
+ * change to udp.c registration API.
|
|
+ *
|
|
+ * Revision 1.99 2005/04/08 18:26:13 mcr
|
|
+ * register with udp.c, the klips26 encap receive function
|
|
+ *
|
|
+ * Revision 1.98 2004/09/13 02:23:18 mcr
|
|
+ * #define inet_protocol if necessary.
|
|
+ *
|
|
+ * Revision 1.97 2004/09/06 18:35:49 mcr
|
|
+ * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
|
|
+ * so adjust for that.
|
|
+ *
|
|
+ * Revision 1.96 2004/08/17 03:27:23 mcr
|
|
+ * klips 2.6 edits.
|
|
+ *
|
|
+ * Revision 1.95 2004/08/03 18:19:08 mcr
|
|
+ * in 2.6, use "net_device" instead of #define device->net_device.
|
|
+ * this probably breaks 2.0 compiles.
|
|
+ *
|
|
+ * Revision 1.94 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.93 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.92 2004/03/30 15:30:39 ken
|
|
+ * Proper Capitalization
|
|
+ *
|
|
+ * Revision 1.91 2004/03/22 01:51:51 ken
|
|
+ * We are open
|
|
+ *
|
|
+ * Revision 1.90.4.2 2004/04/05 04:30:46 mcr
|
|
+ * patches for alg-branch to compile/work with 2.x openswan
|
|
+ *
|
|
+ * Revision 1.90.4.1 2003/12/22 15:25:52 jjo
|
|
+ * Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.90 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.89.4.1 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.89 2003/07/31 22:47:16 mcr
|
|
+ * preliminary (untested by FS-team) 2.5 patches.
|
|
+ *
|
|
+ * Revision 1.88 2003/06/22 20:05:36 mcr
|
|
+ * clarified why IPCOMP was not being registered, and put a new
|
|
+ * #ifdef in rather than #if 0.
|
|
+ *
|
|
+ * Revision 1.87 2002/09/20 15:40:51 rgb
|
|
+ * Added a lock to the global ipsec_sadb struct for future use.
|
|
+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
|
|
+ * of freeing newly created structures when clearing the reftable upon startup
|
|
+ * to start from a known state.
|
|
+ *
|
|
+ * Revision 1.86 2002/08/15 18:39:15 rgb
|
|
+ * Move ipsec_prng outside debug code.
|
|
+ *
|
|
+ * Revision 1.85 2002/05/14 02:35:29 rgb
|
|
+ * Change reference to tdb to ipsa.
|
|
+ *
|
|
+ * Revision 1.84 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.83 2002/04/24 07:36:28 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_init.c,v
|
|
+ *
|
|
+ * Revision 1.82 2002/04/20 00:12:25 rgb
|
|
+ * Added esp IV CBC attack fix, disabled.
|
|
+ *
|
|
+ * Revision 1.81 2002/04/09 16:13:32 mcr
|
|
+ * switch license to straight GPL.
|
|
+ *
|
|
+ * Revision 1.80 2002/03/24 07:34:08 rgb
|
|
+ * Sanity check for at least one of AH or ESP configured.
|
|
+ *
|
|
+ * Revision 1.79 2002/02/05 22:55:15 mcr
|
|
+ * added MODULE_LICENSE declaration.
|
|
+ * This macro does not appear in all kernel versions (see comment).
|
|
+ *
|
|
+ * Revision 1.78 2002/01/29 17:17:55 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.77 2002/01/29 04:00:51 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.76 2002/01/29 02:13:17 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.75 2001/11/26 09:23:48 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.74 2001/11/22 05:44:11 henry
|
|
+ * new version stuff
|
|
+ *
|
|
+ * Revision 1.71.2.2 2001/10/22 20:51:00 mcr
|
|
+ * explicitely set des_check_key.
|
|
+ *
|
|
+ * Revision 1.71.2.1 2001/09/25 02:19:39 mcr
|
|
+ * /proc manipulation code moved to new ipsec_proc.c
|
|
+ *
|
|
+ * Revision 1.73 2001/11/06 19:47:17 rgb
|
|
+ * Changed lifetime_packets to uint32 from uint64.
|
|
+ *
|
|
+ * Revision 1.72 2001/10/18 04:45:19 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/freeswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.71 2001/09/20 15:32:45 rgb
|
|
+ * Minor pfkey lifetime fixes.
|
|
+ *
|
|
+ * Revision 1.70 2001/07/06 19:51:21 rgb
|
|
+ * Added inbound policy checking code for IPIP SAs.
|
|
+ *
|
|
+ * Revision 1.69 2001/06/14 19:33:26 rgb
|
|
+ * Silence startup message for console, but allow it to be logged.
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.68 2001/05/29 05:14:36 rgb
|
|
+ * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'.
|
|
+ *
|
|
+ * Revision 1.67 2001/05/04 16:34:52 rgb
|
|
+ * Rremove erroneous checking of return codes for proc_net_* in 2.4.
|
|
+ *
|
|
+ * Revision 1.66 2001/05/03 19:40:34 rgb
|
|
+ * Check error return codes in startup and shutdown.
|
|
+ *
|
|
+ * Revision 1.65 2001/02/28 05:03:27 rgb
|
|
+ * Clean up and rationalise startup messages.
|
|
+ *
|
|
+ * Revision 1.64 2001/02/27 22:24:53 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.63 2000/11/29 20:14:06 rgb
|
|
+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
|
|
+ *
|
|
+ * Revision 1.62 2000/11/06 04:31:24 rgb
|
|
+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
|
|
+ * Fixed longlong for pre-2.4 kernels (Svenning).
|
|
+ * Add Svenning's adaptive content compression.
|
|
+ * Disabled registration of ipcomp handler.
|
|
+ *
|
|
+ * Revision 1.61 2000/10/11 13:37:54 rgb
|
|
+ * #ifdef out debug print that causes proc/net/ipsec_version to oops.
|
|
+ *
|
|
+ * Revision 1.60 2000/09/20 03:59:01 rgb
|
|
+ * Change static info functions to DEBUG_NO_STATIC to reveal function names
|
|
+ * in oopsen.
|
|
+ *
|
|
+ * Revision 1.59 2000/09/16 01:06:26 rgb
|
|
+ * Added cast of var to silence compiler warning about long fed to int
|
|
+ * format.
|
|
+ *
|
|
+ * Revision 1.58 2000/09/15 11:37:01 rgb
|
|
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
|
|
+ * IPCOMP zlib deflate code.
|
|
+ *
|
|
+ * Revision 1.57 2000/09/12 03:21:50 rgb
|
|
+ * Moved radij_c_version printing to ipsec_version_get_info().
|
|
+ * Reformatted ipsec_version_get_info().
|
|
+ * Added sysctl_{,un}register() calls.
|
|
+ *
|
|
+ * Revision 1.56 2000/09/08 19:16:50 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
|
|
+ *
|
|
+ * Revision 1.55 2000/08/30 05:19:03 rgb
|
|
+ * Cleaned up no longer used spi_next, netlink register/unregister, other
|
|
+ * minor cleanup.
|
|
+ * Removed cruft replaced by TDB_XFORM_NAME.
|
|
+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
|
|
+ * Moved debug version strings to printk when /proc/net/ipsec_version is
|
|
+ * called.
|
|
+ *
|
|
+ * Revision 1.54 2000/08/20 18:31:05 rgb
|
|
+ * Changed cosmetic alignment in spi_info.
|
|
+ * Changed addtime and usetime to use actual value which is relative
|
|
+ * anyways, as intended. (Momchil)
|
|
+ *
|
|
+ * Revision 1.53 2000/08/18 17:37:03 rgb
|
|
+ * Added an (int) cast to shut up the compiler...
|
|
+ *
|
|
+ * Revision 1.52 2000/08/01 14:51:50 rgb
|
|
+ * Removed _all_ remaining traces of DES.
|
|
+ *
|
|
+ * Revision 1.51 2000/07/25 20:41:22 rgb
|
|
+ * Removed duplicate parameter in spi_getinfo.
|
|
+ *
|
|
+ * Revision 1.50 2000/07/17 03:21:45 rgb
|
|
+ * Removed /proc/net/ipsec_spinew.
|
|
+ *
|
|
+ * Revision 1.49 2000/06/28 05:46:51 rgb
|
|
+ * Renamed ivlen to iv_bits for consistency.
|
|
+ * Changed output of add and use times to be relative to now.
|
|
+ *
|
|
+ * Revision 1.48 2000/05/11 18:26:10 rgb
|
|
+ * Commented out calls to netlink_attach/detach to avoid activating netlink
|
|
+ * in the kenrel config.
|
|
+ *
|
|
+ * Revision 1.47 2000/05/10 22:35:26 rgb
|
|
+ * Comment out most of the startup version information.
|
|
+ *
|
|
+ * Revision 1.46 2000/03/22 16:15:36 rgb
|
|
+ * Fixed renaming of dev_get (MB).
|
|
+ *
|
|
+ * Revision 1.45 2000/03/16 06:40:48 rgb
|
|
+ * Hardcode PF_KEYv2 support.
|
|
+ *
|
|
+ * Revision 1.44 2000/01/22 23:19:20 rgb
|
|
+ * Simplified code to use existing macro TDB_XFORM_NAME().
|
|
+ *
|
|
+ * Revision 1.43 2000/01/21 06:14:04 rgb
|
|
+ * Print individual stats only if non-zero.
|
|
+ * Removed 'bits' from each keylength for brevity.
|
|
+ * Shortened lifetimes legend for brevity.
|
|
+ * Changed wording from 'last_used' to the clearer 'idle'.
|
|
+ *
|
|
+ * Revision 1.42 1999/12/31 14:57:19 rgb
|
|
+ * MB fix for new dummy-less proc_get_info in 2.3.35.
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,256 @@
|
|
+/*
|
|
+ * processing code for IPCOMP
|
|
+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+char ipsec_ipcomp_c_version[] = "RCSID $Id: ipsec_ipcomp.c,v 1.5.2.2 2006/10/06 21:39:26 paul Exp $";
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <openswan.h>
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#include "openswan/ipsec_xmit.h"
|
|
+
|
|
+#include "openswan/ipsec_auth.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+#include "openswan/ipsec_ipcomp.h"
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int debug_ipcomp = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
|
|
+ struct sk_buff *skb)
|
|
+{
|
|
+ int ipcompminlen;
|
|
+
|
|
+ ipcompminlen = sizeof(struct iphdr);
|
|
+
|
|
+ if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "runt comp packet of skb->len=%d received from %s, dropped.\n",
|
|
+ skb->len,
|
|
+ irs->ipsaddr_txt);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ return IPSEC_RCV_BADLEN;
|
|
+ }
|
|
+
|
|
+ irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)skb->h.raw;
|
|
+ irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
|
|
+{
|
|
+ unsigned int flags = 0;
|
|
+ struct ipsec_sa *ipsp = irs->ipsp;
|
|
+ struct sk_buff *skb;
|
|
+
|
|
+ skb=irs->skb;
|
|
+
|
|
+ ipsec_xmit_dmp("ipcomp", skb->h.raw, skb->len);
|
|
+
|
|
+ if(ipsp == NULL) {
|
|
+ return IPSEC_RCV_SAIDNOTFOUND;
|
|
+ }
|
|
+
|
|
+ if(sysctl_ipsec_inbound_policy_check &&
|
|
+ ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
|
|
+ (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */
|
|
+ ))) {
|
|
+ char sa2[SATOT_BUF];
|
|
+ size_t sa_len2 = 0;
|
|
+
|
|
+ sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2));
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "Incoming packet with SA(IPCA):%s does not match policy SA(IPCA):%s cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for SA grouping, dropped.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)",
|
|
+ ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
|
|
+ ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
|
|
+ (__u32)ntohl(irs->said.spi),
|
|
+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
|
|
+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_SAIDNOTFOUND;
|
|
+ }
|
|
+
|
|
+ ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
|
|
+ irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
|
|
+
|
|
+ skb = skb_decompress(skb, ipsp, &flags);
|
|
+ if (!skb || flags) {
|
|
+ spin_unlock(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "skb_decompress() returned error flags=%x, dropped.\n",
|
|
+ flags);
|
|
+ if (irs->stats) {
|
|
+ if (flags)
|
|
+ irs->stats->rx_errors++;
|
|
+ else
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_IPCOMPFAILED;
|
|
+ }
|
|
+
|
|
+ /* make sure we update the pointer */
|
|
+ irs->skb = skb;
|
|
+
|
|
+#ifdef NET_21
|
|
+ irs->ipp = skb->nh.iph;
|
|
+#else /* NET_21 */
|
|
+ irs->ipp = skb->ip_hdr;
|
|
+#endif /* NET_21 */
|
|
+
|
|
+ ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)",
|
|
+ (__u32)ntohl(irs->said.spi),
|
|
+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
|
|
+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
|
|
+ irs->next_header);
|
|
+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+ unsigned int flags = 0;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
|
|
+
|
|
+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
|
|
+
|
|
+#ifdef NET_21
|
|
+ ixs->iph = ixs->skb->nh.iph;
|
|
+#else /* NET_21 */
|
|
+ ixs->iph = ixs->skb->ip_hdr;
|
|
+#endif /* NET_21 */
|
|
+
|
|
+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if (debug_tunnel & DB_TN_CROUT)
|
|
+ {
|
|
+ if (old_tot_len > ntohs(ixs->iph->tot_len))
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_once: "
|
|
+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
|
|
+ old_tot_len, ntohs(ixs->iph->tot_len),
|
|
+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
|
|
+ ntohl(ixs->ipsp->ips_said.spi),
|
|
+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
|
|
+ else
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_once: "
|
|
+ "packet did not compress (flags = %d).\n",
|
|
+ flags);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+struct xform_functions ipcomp_xform_funcs[]={
|
|
+ {rcv_checks: ipsec_rcv_ipcomp_checks,
|
|
+ rcv_decrypt: ipsec_rcv_ipcomp_decomp,
|
|
+ xmit_setup: ipsec_xmit_ipcomp_setup,
|
|
+ xmit_headroom: 0,
|
|
+ xmit_needtailroom: 0,
|
|
+ },
|
|
+};
|
|
+
|
|
+#if 0
|
|
+/* We probably don't want to install a pure IPCOMP protocol handler, but
|
|
+ only want to handle IPCOMP if it is encapsulated inside an ESP payload
|
|
+ (which is already handled) */
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+struct inet_protocol comp_protocol =
|
|
+{
|
|
+ ipsec_rcv, /* COMP handler */
|
|
+ NULL, /* COMP error control */
|
|
+#ifdef NETDEV_25
|
|
+ 1, /* no policy */
|
|
+#else
|
|
+ 0, /* next */
|
|
+ IPPROTO_COMP, /* protocol ID */
|
|
+ 0, /* copy */
|
|
+ NULL, /* data */
|
|
+ "COMP" /* name */
|
|
+#endif
|
|
+};
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+#endif
|
|
+
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,122 @@
|
|
+/*
|
|
+ * processing code for IPIP
|
|
+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+char ipsec_ipip_c_version[] = "RCSID $Id: ipsec_ipip.c,v 1.3.2.3 2006/10/06 21:39:26 paul Exp $";
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <openswan.h>
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#include "openswan/ipsec_xmit.h"
|
|
+
|
|
+#include "openswan/ipsec_auth.h"
|
|
+#include "openswan/ipsec_ipip.h"
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+ ixs->iph->version = 4;
|
|
+
|
|
+ switch(sysctl_ipsec_tos) {
|
|
+ case 0:
|
|
+#ifdef NET_21
|
|
+ ixs->iph->tos = ixs->skb->nh.iph->tos;
|
|
+#else /* NET_21 */
|
|
+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
|
|
+#endif /* NET_21 */
|
|
+ break;
|
|
+ case 1:
|
|
+ ixs->iph->tos = 0;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
|
|
+ ixs->iph->frag_off = 0;
|
|
+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
|
|
+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
|
|
+ ixs->iph->protocol = IPPROTO_IPIP;
|
|
+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
|
|
+
|
|
+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
|
|
+
|
|
+ ixs->newdst = (__u32)ixs->iph->daddr;
|
|
+ ixs->newsrc = (__u32)ixs->iph->saddr;
|
|
+
|
|
+#ifdef NET_21
|
|
+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
|
|
+#endif /* NET_21 */
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+struct xform_functions ipip_xform_funcs[]={
|
|
+ { rcv_checks: NULL,
|
|
+ rcv_setup_auth: NULL,
|
|
+ rcv_calc_auth: NULL,
|
|
+ rcv_decrypt: NULL,
|
|
+
|
|
+ xmit_setup: ipsec_xmit_ipip_setup,
|
|
+ xmit_headroom: sizeof(struct iphdr),
|
|
+ xmit_needtailroom: 0,
|
|
+ },
|
|
+};
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_kern24.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,74 @@
|
|
+/*
|
|
+ * Copyright 2005 (C) Michael Richardson <mcr@xelerance.com>
|
|
+ *
|
|
+ * This is a file of functions which are present in 2.6 kernels,
|
|
+ * but are not available by default in the 2.4 series.
|
|
+ *
|
|
+ * As such this code is usually from the Linux kernel, and is covered by
|
|
+ * GPL.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * $Id: ipsec_kern24.c,v 1.2 2005/05/20 03:19:18 mcr Exp $
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/spinlock.h>
|
|
+
|
|
+/*
|
|
+ * printk rate limiting, lifted from the networking subsystem.
|
|
+ *
|
|
+ * This enforces a rate limit: not more than one kernel message
|
|
+ * every printk_ratelimit_jiffies to make a denial-of-service
|
|
+ * attack impossible.
|
|
+ */
|
|
+static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
|
|
+
|
|
+int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
|
|
+{
|
|
+ static unsigned long toks = 10*5*HZ;
|
|
+ static unsigned long last_msg;
|
|
+ static int missed;
|
|
+ unsigned long flags;
|
|
+ unsigned long now = jiffies;
|
|
+
|
|
+ spin_lock_irqsave(&ratelimit_lock, flags);
|
|
+ toks += now - last_msg;
|
|
+ last_msg = now;
|
|
+ if (toks > (ratelimit_burst * ratelimit_jiffies))
|
|
+ toks = ratelimit_burst * ratelimit_jiffies;
|
|
+ if (toks >= ratelimit_jiffies) {
|
|
+ int lost = missed;
|
|
+ missed = 0;
|
|
+ toks -= ratelimit_jiffies;
|
|
+ spin_unlock_irqrestore(&ratelimit_lock, flags);
|
|
+ if (lost)
|
|
+ printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
|
|
+ return 1;
|
|
+ }
|
|
+ missed++;
|
|
+ spin_unlock_irqrestore(&ratelimit_lock, flags);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* minimum time in jiffies between messages */
|
|
+int printk_ratelimit_jiffies = 5*HZ;
|
|
+
|
|
+/* number of messages we send before ratelimiting */
|
|
+int printk_ratelimit_burst = 10;
|
|
+
|
|
+int printk_ratelimit(void)
|
|
+{
|
|
+ return __printk_ratelimit(printk_ratelimit_jiffies,
|
|
+ printk_ratelimit_burst);
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,273 @@
|
|
+/*
|
|
+ * @(#) lifetime structure utilities
|
|
+ *
|
|
+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * and Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_life.c,v 1.13.10.1 2006/10/06 21:39:26 paul Exp $
|
|
+ *
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * This provides series of utility functions for dealing with lifetime
|
|
+ * structures.
|
|
+ *
|
|
+ * ipsec_check_lifetime - returns -1 hard lifetime exceeded
|
|
+ * 0 soft lifetime exceeded
|
|
+ * 1 everything is okay
|
|
+ * based upon whether or not the count exceeds hard/soft
|
|
+ *
|
|
+ */
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif /* for CONFIG_IP_FORWARD */
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/skbuff.h>
|
|
+#include <openswan.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_life.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_eroute.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+
|
|
+#include "openswan/ipsec_sa.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_ipe4.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_esp.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+#include "openswan/ipcomp.h"
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+
|
|
+
|
|
+enum ipsec_life_alive
|
|
+ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
|
|
+ const char *lifename,
|
|
+ const char *saname,
|
|
+ enum ipsec_life_type ilt,
|
|
+ enum ipsec_direction idir,
|
|
+ struct ipsec_sa *ips)
|
|
+{
|
|
+ __u64 count;
|
|
+ const char *dir;
|
|
+
|
|
+ if(saname == NULL) {
|
|
+ saname = "unknown-SA";
|
|
+ }
|
|
+
|
|
+ if(idir == ipsec_incoming) {
|
|
+ dir = "incoming";
|
|
+ } else {
|
|
+ dir = "outgoing";
|
|
+ }
|
|
+
|
|
+
|
|
+ if(ilt == ipsec_life_timebased) {
|
|
+ count = jiffies/HZ - il64->ipl_count;
|
|
+ } else {
|
|
+ count = il64->ipl_count;
|
|
+ }
|
|
+
|
|
+ if(il64->ipl_hard &&
|
|
+ (count > il64->ipl_hard)) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_lifetime_check: "
|
|
+ "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
|
|
+ "%s packet dropped.\n",
|
|
+ lifename,
|
|
+ IPS_XFORM_NAME(ips),
|
|
+ saname,
|
|
+ dir);
|
|
+
|
|
+ pfkey_expire(ips, 1);
|
|
+ return ipsec_life_harddied;
|
|
+ }
|
|
+
|
|
+ if(il64->ipl_soft &&
|
|
+ (count > il64->ipl_soft)) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_lifetime_check: "
|
|
+ "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
|
|
+ "soft expire message sent up, %s packet still processed.\n",
|
|
+ lifename,
|
|
+ IPS_XFORM_NAME(ips),
|
|
+ saname,
|
|
+ dir);
|
|
+
|
|
+ if(ips->ips_state != SADB_SASTATE_DYING) {
|
|
+ pfkey_expire(ips, 0);
|
|
+ }
|
|
+ ips->ips_state = SADB_SASTATE_DYING;
|
|
+
|
|
+ return ipsec_life_softdied;
|
|
+ }
|
|
+ return ipsec_life_okay;
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * This function takes a buffer (with length), a lifetime name and type,
|
|
+ * and formats a string to represent the current values of the lifetime.
|
|
+ *
|
|
+ * It returns the number of bytes that the format took (or would take,
|
|
+ * if the buffer were large enough: snprintf semantics).
|
|
+ * This is used in /proc routines and in debug output.
|
|
+ */
|
|
+int
|
|
+ipsec_lifetime_format(char *buffer,
|
|
+ int buflen,
|
|
+ char *lifename,
|
|
+ enum ipsec_life_type timebaselife,
|
|
+ struct ipsec_lifetime64 *lifetime)
|
|
+{
|
|
+ int len = 0;
|
|
+ __u64 count;
|
|
+
|
|
+ if(timebaselife == ipsec_life_timebased) {
|
|
+ count = jiffies/HZ - lifetime->ipl_count;
|
|
+ } else {
|
|
+ count = lifetime->ipl_count;
|
|
+ }
|
|
+
|
|
+ if(lifetime->ipl_count > 1 ||
|
|
+ lifetime->ipl_soft ||
|
|
+ lifetime->ipl_hard) {
|
|
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
|
|
+ len = ipsec_snprintf(buffer, buflen,
|
|
+ "%s(%Lu,%Lu,%Lu)",
|
|
+ lifename,
|
|
+ count,
|
|
+ lifetime->ipl_soft,
|
|
+ lifetime->ipl_hard);
|
|
+#else /* XXX high 32 bits are not displayed */
|
|
+ len = ipsec_snprintf(buffer, buflen,
|
|
+ "%s(%lu,%lu,%lu)",
|
|
+ lifename,
|
|
+ (unsigned long)count,
|
|
+ (unsigned long)lifetime->ipl_soft,
|
|
+ (unsigned long)lifetime->ipl_hard);
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ return len;
|
|
+}
|
|
+
|
|
+void
|
|
+ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
|
|
+ __u64 newvalue)
|
|
+{
|
|
+ if(newvalue &&
|
|
+ (!lifetime->ipl_hard ||
|
|
+ (newvalue < lifetime->ipl_hard))) {
|
|
+ lifetime->ipl_hard = newvalue;
|
|
+
|
|
+ if(!lifetime->ipl_soft &&
|
|
+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
|
|
+ lifetime->ipl_soft = lifetime->ipl_hard;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
|
|
+ __u64 newvalue)
|
|
+{
|
|
+ if(newvalue &&
|
|
+ (!lifetime->ipl_soft ||
|
|
+ (newvalue < lifetime->ipl_soft))) {
|
|
+ lifetime->ipl_soft = newvalue;
|
|
+
|
|
+ if(lifetime->ipl_hard &&
|
|
+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
|
|
+ lifetime->ipl_soft = lifetime->ipl_hard;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_life.c,v $
|
|
+ * Revision 1.13.10.1 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.13 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.12 2004/04/23 20:44:35 ken
|
|
+ * Update comments
|
|
+ *
|
|
+ * Revision 1.11 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.10 2004/03/30 11:03:10 paul
|
|
+ * two more occurances of snprintf, found by Sam from a users oops msg.
|
|
+ *
|
|
+ * Revision 1.9 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.8.4.1 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.8 2003/02/06 02:00:10 rgb
|
|
+ * Fixed incorrect debugging text label
|
|
+ *
|
|
+ * Revision 1.7 2002/05/23 07:16:26 rgb
|
|
+ * Fixed absolute/relative reference to lifetime count printout.
|
|
+ *
|
|
+ * Revision 1.6 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.5 2002/04/24 07:36:28 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_life.c,v
|
|
+ *
|
|
+ * Revision 1.4 2002/01/29 17:17:55 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.3 2002/01/29 02:13:17 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:14 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
|
|
+ * lifetime structure created and common functions created.
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1099 @@
|
|
+/*
|
|
+ * IPSEC MAST code.
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+char ipsec_mast_c_version[] = "RCSID $Id: ipsec_mast.c,v 1.7.2.1 2006/10/06 21:39:26 paul Exp $";
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif /* for CONFIG_IP_FORWARD */
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "freeswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/tcp.h> /* struct tcphdr */
|
|
+#include <linux/udp.h> /* struct udphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <freeswan.h>
|
|
+#include <linux/in6.h>
|
|
+#include <net/dst.h>
|
|
+#undef dev_kfree_skb
|
|
+#define dev_kfree_skb(a,b) kfree_skb(a)
|
|
+#define PHYSDEV_TYPE
|
|
+#include <net/icmp.h> /* icmp_send() */
|
|
+#include <net/ip.h>
|
|
+#include <linux/netfilter_ipv4.h>
|
|
+
|
|
+#include <linux/if_arp.h>
|
|
+
|
|
+#include "freeswan/radij.h"
|
|
+#include "freeswan/ipsec_life.h"
|
|
+#include "freeswan/ipsec_xform.h"
|
|
+#include "freeswan/ipsec_eroute.h"
|
|
+#include "freeswan/ipsec_encap.h"
|
|
+#include "freeswan/ipsec_radij.h"
|
|
+#include "freeswan/ipsec_sa.h"
|
|
+#include "freeswan/ipsec_tunnel.h"
|
|
+#include "freeswan/ipsec_mast.h"
|
|
+#include "freeswan/ipsec_ipe4.h"
|
|
+#include "freeswan/ipsec_ah.h"
|
|
+#include "freeswan/ipsec_esp.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "freeswan/ipsec_proto.h"
|
|
+
|
|
+int ipsec_maxdevice_count = -1;
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_open(struct net_device *dev)
|
|
+{
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ /*
|
|
+ * Can't open until attached.
|
|
+ */
|
|
+
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_open: "
|
|
+ "dev = %s, prv->dev = %s\n",
|
|
+ dev->name, prv->dev?prv->dev->name:"NONE");
|
|
+
|
|
+ if (prv->dev == NULL)
|
|
+ return -ENODEV;
|
|
+
|
|
+ KLIPS_INC_USE;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_close(struct net_device *dev)
|
|
+{
|
|
+ KLIPS_DEC_USE;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static inline int ipsec_mast_xmit2(struct sk_buff *skb)
|
|
+{
|
|
+ return ip_send(skb);
|
|
+}
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_mast_send(struct ipsec_xmit_state*ixs)
|
|
+{
|
|
+ /* new route/dst cache code from James Morris */
|
|
+ ixs->skb->dev = ixs->physdev;
|
|
+ /*skb_orphan(ixs->skb);*/
|
|
+ if((ixs->error = ip_route_output(&ixs->route,
|
|
+ ixs->skb->nh.iph->daddr,
|
|
+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
|
|
+ RT_TOS(ixs->skb->nh.iph->tos),
|
|
+ ixs->physdev->iflink /* rgb: should this be 0? */))) {
|
|
+ ixs->stats->tx_errors++;
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
|
|
+ "klips_debug:ipsec_xmit_send: "
|
|
+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
|
|
+ ixs->error,
|
|
+ ixs->route->u.dst.dev->name);
|
|
+ return IPSEC_XMIT_ROUTEERR;
|
|
+ }
|
|
+ if(ixs->dev == ixs->route->u.dst.dev) {
|
|
+ ip_rt_put(ixs->route);
|
|
+ /* This is recursion, drop it. */
|
|
+ ixs->stats->tx_errors++;
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
|
|
+ "klips_debug:ipsec_xmit_send: "
|
|
+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
|
|
+ ixs->dev->name);
|
|
+ return IPSEC_XMIT_RECURSDETECT;
|
|
+ }
|
|
+ dst_release(ixs->skb->dst);
|
|
+ ixs->skb->dst = &ixs->route->u.dst;
|
|
+ ixs->stats->tx_bytes += ixs->skb->len;
|
|
+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
|
|
+ ixs->stats->tx_errors++;
|
|
+ printk(KERN_WARNING
|
|
+ "klips_error:ipsec_xmit_send: "
|
|
+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
|
|
+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
|
|
+ ixs->skb->len);
|
|
+ return IPSEC_XMIT_PUSHPULLERR;
|
|
+ }
|
|
+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
|
|
+#ifdef SKB_RESET_NFCT
|
|
+ nf_conntrack_put(ixs->skb->nfct);
|
|
+ ixs->skb->nfct = NULL;
|
|
+#ifdef CONFIG_NETFILTER_DEBUG
|
|
+ ixs->skb->nf_debug = 0;
|
|
+#endif /* CONFIG_NETFILTER_DEBUG */
|
|
+#endif /* SKB_RESET_NFCT */
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
|
|
+ "klips_debug:ipsec_xmit_send: "
|
|
+ "...done, calling ip_send() on device:%s\n",
|
|
+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
|
|
+ KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
|
|
+ {
|
|
+ int err;
|
|
+
|
|
+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
|
|
+ ipsec_mast_xmit2);
|
|
+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
|
|
+ if(net_ratelimit())
|
|
+ printk(KERN_ERR
|
|
+ "klips_error:ipsec_xmit_send: "
|
|
+ "ip_send() failed, err=%d\n",
|
|
+ -err);
|
|
+ ixs->stats->tx_errors++;
|
|
+ ixs->stats->tx_aborted_errors++;
|
|
+ ixs->skb = NULL;
|
|
+ return IPSEC_XMIT_IPSENDFAILURE;
|
|
+ }
|
|
+ }
|
|
+ ixs->stats->tx_packets++;
|
|
+
|
|
+ ixs->skb = NULL;
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+void
|
|
+ipsec_mast_cleanup(struct ipsec_xmit_state*ixs)
|
|
+{
|
|
+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
|
|
+ netif_wake_queue(ixs->dev);
|
|
+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
|
|
+ ixs->dev->tbusy = 0;
|
|
+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
|
|
+ if(ixs->saved_header) {
|
|
+ kfree(ixs->saved_header);
|
|
+ }
|
|
+ if(ixs->skb) {
|
|
+ dev_kfree_skb(ixs->skb, FREE_WRITE);
|
|
+ }
|
|
+ if(ixs->oskb) {
|
|
+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
|
|
+ }
|
|
+ if (ixs->ips.ips_ident_s.data) {
|
|
+ kfree(ixs->ips.ips_ident_s.data);
|
|
+ }
|
|
+ if (ixs->ips.ips_ident_d.data) {
|
|
+ kfree(ixs->ips.ips_ident_d.data);
|
|
+ }
|
|
+}
|
|
+
|
|
+#if 0
|
|
+/*
|
|
+ * This function assumes it is being called from dev_queue_xmit()
|
|
+ * and that skb is filled properly by that function.
|
|
+ */
|
|
+int
|
|
+ipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev, IPsecSAref_t SAref)
|
|
+{
|
|
+ struct ipsec_xmit_state ixs_mem;
|
|
+ struct ipsec_xmit_state *ixs = &ixs_mem;
|
|
+ enum ipsec_xmit_value stat = IPSEC_XMIT_OK;
|
|
+
|
|
+ /* dev could be a mast device, but should be optional, I think... */
|
|
+ /* SAref is also optional, but one of the two must be present. */
|
|
+ /* I wonder if it could accept no device or saref and guess? */
|
|
+
|
|
+/* ipsec_xmit_sanity_check_dev(ixs); */
|
|
+
|
|
+ ipsec_xmit_sanity_check_skb(ixs);
|
|
+
|
|
+ ipsec_xmit_adjust_hard_header(ixs);
|
|
+
|
|
+ stat = ipsec_xmit_encap_bundle(ixs);
|
|
+ if(stat != IPSEC_XMIT_OK) {
|
|
+ /* SA processing failed */
|
|
+ }
|
|
+
|
|
+ ipsec_xmit_hard_header_restore();
|
|
+}
|
|
+#endif
|
|
+
|
|
+DEBUG_NO_STATIC struct net_device_stats *
|
|
+ipsec_mast_get_stats(struct net_device *dev)
|
|
+{
|
|
+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Revectored calls.
|
|
+ * For each of these calls, a field exists in our private structure.
|
|
+ */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_hard_header(struct sk_buff *skb, struct net_device *dev,
|
|
+ unsigned short type, void *daddr, void *saddr, unsigned len)
|
|
+{
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+ struct net_device *tmp;
|
|
+ int ret;
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+
|
|
+ if(skb == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_hard_header: "
|
|
+ "no skb...\n");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_hard_header: "
|
|
+ "no device...\n");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_hard_header: "
|
|
+ "skb->dev=%s dev=%s.\n",
|
|
+ skb->dev ? skb->dev->name : "NULL",
|
|
+ dev->name);
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_hard_header: "
|
|
+ "no private space associated with dev=%s\n",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+
|
|
+ if(prv->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_hard_header: "
|
|
+ "no physical device associated with dev=%s\n",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ /* check if we have to send a IPv6 packet. It might be a Router
|
|
+ Solicitation, where the building of the packet happens in
|
|
+ reverse order:
|
|
+ 1. ll hdr,
|
|
+ 2. IPv6 hdr,
|
|
+ 3. ICMPv6 hdr
|
|
+ -> skb->nh.raw is still uninitialized when this function is
|
|
+ called!! If this is no IPv6 packet, we can print debugging
|
|
+ messages, otherwise we skip all debugging messages and just
|
|
+ build the ll header */
|
|
+ if(type != ETH_P_IPV6) {
|
|
+ /* execute this only, if we don't have to build the
|
|
+ header for a IPv6 packet */
|
|
+ if(!prv->hard_header) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_hard_header: "
|
|
+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
|
|
+ saddr,
|
|
+ daddr,
|
|
+ len,
|
|
+ type,
|
|
+ dev->name);
|
|
+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->nh.iph->saddr),
|
|
+ (__u32)ntohl(skb->nh.iph->daddr) );
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+#define da ((struct net_device *)(prv->dev))->dev_addr
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_hard_header: "
|
|
+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
|
|
+ saddr,
|
|
+ daddr,
|
|
+ len,
|
|
+ type,
|
|
+ dev->name,
|
|
+ prv->dev->name,
|
|
+ da[0], da[1], da[2], da[3], da[4], da[5]);
|
|
+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->nh.iph->saddr),
|
|
+ (__u32)ntohl(skb->nh.iph->daddr) );
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_mast,
|
|
+ "klips_debug:ipsec_mast_hard_header: "
|
|
+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
|
|
+ }
|
|
+ tmp = skb->dev;
|
|
+ skb->dev = prv->dev;
|
|
+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
|
|
+ skb->dev = tmp;
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_rebuild_header(struct sk_buff *skb)
|
|
+{
|
|
+ struct ipsecpriv *prv = skb->dev->priv;
|
|
+ struct net_device *tmp;
|
|
+ int ret;
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+
|
|
+ if(skb->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_rebuild_header: "
|
|
+ "no device...");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_rebuild_header: "
|
|
+ "no private space associated with dev=%s",
|
|
+ skb->dev->name ? skb->dev->name : "NULL");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+
|
|
+ if(prv->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_rebuild_header: "
|
|
+ "no physical device associated with dev=%s",
|
|
+ skb->dev->name ? skb->dev->name : "NULL");
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(!prv->rebuild_header) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_rebuild_header: "
|
|
+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
|
|
+ skb->dev->name);
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->nh.iph->saddr),
|
|
+ (__u32)ntohl(skb->nh.iph->daddr) );
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast: "
|
|
+ "Revectored rebuild_header dev=%s->%s ",
|
|
+ skb->dev->name, prv->dev->name);
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->nh.iph->saddr),
|
|
+ (__u32)ntohl(skb->nh.iph->daddr) );
|
|
+ tmp = skb->dev;
|
|
+ skb->dev = prv->dev;
|
|
+
|
|
+ ret = prv->rebuild_header(skb);
|
|
+ skb->dev = tmp;
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_set_mac_address(struct net_device *dev, void *addr)
|
|
+{
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_set_mac_address: "
|
|
+ "no device...");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_set_mac_address: "
|
|
+ "no private space associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+
|
|
+ if(prv->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_set_mac_address: "
|
|
+ "no physical device associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(!prv->set_mac_address) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_set_mac_address: "
|
|
+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
|
|
+ dev->name);
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_set_mac_address: "
|
|
+ "Revectored dev=%s->%s addr=0p%p\n",
|
|
+ dev->name, prv->dev->name, addr);
|
|
+ return prv->set_mac_address(prv->dev, addr);
|
|
+
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC void
|
|
+ipsec_mast_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
|
|
+{
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_cache_update: "
|
|
+ "no device...");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_cache_update: "
|
|
+ "no private space associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+
|
|
+ if(prv->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_cache_update: "
|
|
+ "no physical device associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ stats->tx_dropped++;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if(!prv->header_cache_update) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_cache_update: "
|
|
+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
|
|
+ dev->name);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast: "
|
|
+ "Revectored cache_update\n");
|
|
+ prv->header_cache_update(hh, prv->dev, haddr);
|
|
+ return;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_neigh_setup(struct neighbour *n)
|
|
+{
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_neigh_setup:\n");
|
|
+
|
|
+ if (n->nud_state == NUD_NONE) {
|
|
+ n->ops = &arp_broken_ops;
|
|
+ n->output = n->ops->output;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
|
|
+{
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_neigh_setup_dev: "
|
|
+ "setting up %s\n",
|
|
+ dev ? dev->name : "NULL");
|
|
+
|
|
+ if (p->tbl->family == AF_INET) {
|
|
+ p->neigh_setup = ipsec_mast_neigh_setup;
|
|
+ p->ucast_probes = 0;
|
|
+ p->mcast_probes = 0;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * We call the attach routine to attach another device.
|
|
+ */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_attach(struct net_device *dev, struct net_device *physdev)
|
|
+{
|
|
+ int i;
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_attach: "
|
|
+ "no device...");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_attach: "
|
|
+ "no private space associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ prv->dev = physdev;
|
|
+ prv->hard_start_xmit = physdev->hard_start_xmit;
|
|
+ prv->get_stats = physdev->get_stats;
|
|
+
|
|
+ if (physdev->hard_header) {
|
|
+ prv->hard_header = physdev->hard_header;
|
|
+ dev->hard_header = ipsec_mast_hard_header;
|
|
+ } else
|
|
+ dev->hard_header = NULL;
|
|
+
|
|
+ if (physdev->rebuild_header) {
|
|
+ prv->rebuild_header = physdev->rebuild_header;
|
|
+ dev->rebuild_header = ipsec_mast_rebuild_header;
|
|
+ } else
|
|
+ dev->rebuild_header = NULL;
|
|
+
|
|
+ if (physdev->set_mac_address) {
|
|
+ prv->set_mac_address = physdev->set_mac_address;
|
|
+ dev->set_mac_address = ipsec_mast_set_mac_address;
|
|
+ } else
|
|
+ dev->set_mac_address = NULL;
|
|
+
|
|
+ if (physdev->header_cache_update) {
|
|
+ prv->header_cache_update = physdev->header_cache_update;
|
|
+ dev->header_cache_update = ipsec_mast_cache_update;
|
|
+ } else
|
|
+ dev->header_cache_update = NULL;
|
|
+
|
|
+ dev->hard_header_len = physdev->hard_header_len;
|
|
+
|
|
+/* prv->neigh_setup = physdev->neigh_setup; */
|
|
+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
|
|
+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
|
|
+ prv->mtu = physdev->mtu;
|
|
+
|
|
+#ifdef PHYSDEV_TYPE
|
|
+ dev->type = physdev->type; /* ARPHRD_MAST; */
|
|
+#endif /* PHYSDEV_TYPE */
|
|
+
|
|
+ dev->addr_len = physdev->addr_len;
|
|
+ for (i=0; i<dev->addr_len; i++) {
|
|
+ dev->dev_addr[i] = physdev->dev_addr[i];
|
|
+ }
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_mast & DB_MAST_INIT) {
|
|
+ printk(KERN_INFO "klips_debug:ipsec_mast_attach: "
|
|
+ "physical device %s being attached has HW address: %2x",
|
|
+ physdev->name, physdev->dev_addr[0]);
|
|
+ for (i=1; i < physdev->addr_len; i++) {
|
|
+ printk(":%02x", physdev->dev_addr[i]);
|
|
+ }
|
|
+ printk("\n");
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * We call the detach routine to detach the ipsec mast from another device.
|
|
+ */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_detach(struct net_device *dev)
|
|
+{
|
|
+ int i;
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_detach: "
|
|
+ "no device...");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
|
|
+ "klips_debug:ipsec_mast_detach: "
|
|
+ "no private space associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_detach: "
|
|
+ "physical device %s being detached from virtual device %s\n",
|
|
+ prv->dev ? prv->dev->name : "NULL",
|
|
+ dev->name);
|
|
+
|
|
+ prv->dev = NULL;
|
|
+ prv->hard_start_xmit = NULL;
|
|
+ prv->get_stats = NULL;
|
|
+
|
|
+ prv->hard_header = NULL;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->hard_header = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+
|
|
+ prv->rebuild_header = NULL;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->rebuild_header = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+
|
|
+ prv->set_mac_address = NULL;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->set_mac_address = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+
|
|
+ prv->header_cache_update = NULL;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->header_cache_update = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->neigh_setup = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+
|
|
+ dev->hard_header_len = 0;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->mtu = 0;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+ prv->mtu = 0;
|
|
+ for (i=0; i<MAX_ADDR_LEN; i++) {
|
|
+ dev->dev_addr[i] = 0;
|
|
+ }
|
|
+ dev->addr_len = 0;
|
|
+#ifdef PHYSDEV_TYPE
|
|
+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */
|
|
+#endif /* PHYSDEV_TYPE */
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * We call the clear routine to detach all ipsec masts from other devices.
|
|
+ */
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_clear(void)
|
|
+{
|
|
+ int i;
|
|
+ struct net_device *ipsecdev = NULL, *prvdev;
|
|
+ struct ipsecpriv *prv;
|
|
+ char name[9];
|
|
+ int ret;
|
|
+
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_clear: .\n");
|
|
+
|
|
+ for(i = 0; i < IPSEC_NUM_IF; i++) {
|
|
+ sprintf(name, IPSEC_DEV_FORMAT, i);
|
|
+ if((ipsecdev = ipsec_dev_get(name)) != NULL) {
|
|
+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
|
|
+ prvdev = (struct net_device *)(prv->dev);
|
|
+ if(prvdev) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_clear: "
|
|
+ "physical device for device %s is %s\n",
|
|
+ name, prvdev->name);
|
|
+ if((ret = ipsec_mast_detach(ipsecdev))) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_clear: "
|
|
+ "error %d detatching device %s from device %s.\n",
|
|
+ ret, name, prvdev->name);
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_mast_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|
+{
|
|
+ struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+ struct net_device *them; /* physical device */
|
|
+#ifdef CONFIG_IP_ALIAS
|
|
+ char *colon;
|
|
+ char realphysname[IFNAMSIZ];
|
|
+#endif /* CONFIG_IP_ALIAS */
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "device not supplied.\n");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "tncfg service call #%d for dev=%s\n",
|
|
+ cmd,
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ switch (cmd) {
|
|
+ /* attach a virtual ipsec? device to a physical device */
|
|
+ case IPSEC_SET_DEV:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "calling ipsec_mast_attatch...\n");
|
|
+#ifdef CONFIG_IP_ALIAS
|
|
+ /* If this is an IP alias interface, get its real physical name */
|
|
+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
|
|
+ realphysname[IFNAMSIZ-1] = 0;
|
|
+ colon = strchr(realphysname, ':');
|
|
+ if (colon) *colon = 0;
|
|
+ them = ipsec_dev_get(realphysname);
|
|
+#else /* CONFIG_IP_ALIAS */
|
|
+ them = ipsec_dev_get(cf->cf_name);
|
|
+#endif /* CONFIG_IP_ALIAS */
|
|
+
|
|
+ if (them == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "physical device %s requested is null\n",
|
|
+ cf->cf_name);
|
|
+ return -ENXIO;
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ if (them->flags & IFF_UP) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "physical device %s requested is not up.\n",
|
|
+ cf->cf_name);
|
|
+ return -ENXIO;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if (prv && prv->dev) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "virtual device is already connected to %s.\n",
|
|
+ prv->dev->name ? prv->dev->name : "NULL");
|
|
+ return -EBUSY;
|
|
+ }
|
|
+ return ipsec_mast_attach(dev, them);
|
|
+
|
|
+ case IPSEC_DEL_DEV:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "calling ipsec_mast_detatch.\n");
|
|
+ if (! prv->dev) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "physical device not connected.\n");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+ return ipsec_mast_detach(dev);
|
|
+
|
|
+ case IPSEC_CLR_DEV:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "calling ipsec_mast_clear.\n");
|
|
+ return ipsec_mast_clear();
|
|
+
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_ioctl: "
|
|
+ "unknown command %d.\n",
|
|
+ cmd);
|
|
+ return -EOPNOTSUPP;
|
|
+ }
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
|
|
+{
|
|
+ struct net_device *dev = ptr;
|
|
+ struct net_device *ipsec_dev;
|
|
+ struct ipsecpriv *priv;
|
|
+ char name[9];
|
|
+ int i;
|
|
+
|
|
+ if (dev == NULL) {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "dev=NULL for event type %ld.\n",
|
|
+ event);
|
|
+ return(NOTIFY_DONE);
|
|
+ }
|
|
+
|
|
+ /* check for loopback devices */
|
|
+ if (dev && (dev->flags & IFF_LOOPBACK)) {
|
|
+ return(NOTIFY_DONE);
|
|
+ }
|
|
+
|
|
+ switch (event) {
|
|
+ case NETDEV_DOWN:
|
|
+ /* look very carefully at the scope of these compiler
|
|
+ directives before changing anything... -- RGB */
|
|
+
|
|
+ case NETDEV_UNREGISTER:
|
|
+ switch (event) {
|
|
+ case NETDEV_DOWN:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_DOWN dev=%s flags=%x\n",
|
|
+ dev->name,
|
|
+ dev->flags);
|
|
+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
|
|
+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
|
|
+ dev->name);
|
|
+ }
|
|
+ break;
|
|
+ case NETDEV_UNREGISTER:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
|
|
+ dev->name,
|
|
+ dev->flags);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* find the attached physical device and detach it. */
|
|
+ for(i = 0; i < IPSEC_NUM_IF; i++) {
|
|
+ sprintf(name, IPSEC_DEV_FORMAT, i);
|
|
+ ipsec_dev = ipsec_dev_get(name);
|
|
+ if(ipsec_dev) {
|
|
+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
|
|
+ if(priv) {
|
|
+ ;
|
|
+ if(((struct net_device *)(priv->dev)) == dev) {
|
|
+ /* dev_close(ipsec_dev); */
|
|
+ /* return */ ipsec_mast_detach(ipsec_dev);
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "device '%s' has been detached.\n",
|
|
+ ipsec_dev->name);
|
|
+ break;
|
|
+ }
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "device '%s' has no private data space!\n",
|
|
+ ipsec_dev->name);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ case NETDEV_UP:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_UP dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ case NETDEV_REBOOT:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_REBOOT dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ case NETDEV_CHANGE:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_CHANGE dev=%s flags=%x\n",
|
|
+ dev->name,
|
|
+ dev->flags);
|
|
+ break;
|
|
+ case NETDEV_REGISTER:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_REGISTER dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ case NETDEV_CHANGEMTU:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
|
|
+ dev->name,
|
|
+ dev->mtu);
|
|
+ break;
|
|
+ case NETDEV_CHANGEADDR:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_CHANGEADDR dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ case NETDEV_GOING_DOWN:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_GOING_DOWN dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ case NETDEV_CHANGENAME:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "NETDEV_CHANGENAME dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
|
|
+ "klips_debug:ipsec_mast_device_event: "
|
|
+ "event type %ld unrecognised for dev=%s\n",
|
|
+ event,
|
|
+ dev->name);
|
|
+ break;
|
|
+ }
|
|
+ return NOTIFY_DONE;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Called when an ipsec mast device is initialized.
|
|
+ * The ipsec mast device structure is passed to us.
|
|
+ */
|
|
+
|
|
+int
|
|
+ipsec_mast_init(struct net_device *dev)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ KLIPS_PRINT(debug_mast,
|
|
+ "klips_debug:ipsec_mast_init: "
|
|
+ "allocating %lu bytes initialising device: %s\n",
|
|
+ (unsigned long) sizeof(struct ipsecpriv),
|
|
+ dev->name ? dev->name : "NULL");
|
|
+
|
|
+ /* Add our mast functions to the device */
|
|
+ dev->open = ipsec_mast_open;
|
|
+ dev->stop = ipsec_mast_close;
|
|
+ dev->hard_start_xmit = ipsec_mast_start_xmit;
|
|
+ dev->get_stats = ipsec_mast_get_stats;
|
|
+
|
|
+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
|
|
+ if (dev->priv == NULL)
|
|
+ return -ENOMEM;
|
|
+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
|
|
+
|
|
+ for(i = 0; i < sizeof(zeroes); i++) {
|
|
+ ((__u8*)(zeroes))[i] = 0;
|
|
+ }
|
|
+
|
|
+ dev->set_multicast_list = NULL;
|
|
+ dev->do_ioctl = ipsec_mast_ioctl;
|
|
+ dev->hard_header = NULL;
|
|
+ dev->rebuild_header = NULL;
|
|
+ dev->set_mac_address = NULL;
|
|
+ dev->header_cache_update= NULL;
|
|
+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
|
|
+ dev->hard_header_len = 0;
|
|
+ dev->mtu = 0;
|
|
+ dev->addr_len = 0;
|
|
+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */
|
|
+ dev->tx_queue_len = 10; /* Small queue */
|
|
+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
|
|
+
|
|
+ /* New-style flags. */
|
|
+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
|
|
+ dev_init_buffers(dev);
|
|
+
|
|
+ /* We're done. Have I forgotten anything? */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
+/* Module specific interface (but it links with the rest of IPSEC) */
|
|
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
+
|
|
+int
|
|
+ipsec_mast_probe(struct net_device *dev)
|
|
+{
|
|
+ ipsec_mast_init(dev);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_mast_init_devices(void)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* void */
|
|
+int
|
|
+ipsec_mast_cleanup_devices(void)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+ char name[10];
|
|
+ struct net_device *dev_mast;
|
|
+
|
|
+ for(i = 0; i < ipsec_mastdevice_count; i++) {
|
|
+ sprintf(name, MAST_DEV_FORMAT, i);
|
|
+ if((dev_mast = ipsec_dev_get(name)) == NULL) {
|
|
+ break;
|
|
+ }
|
|
+ unregister_netdev(dev_mast);
|
|
+ kfree(dev_mast->priv);
|
|
+ dev_mast->priv=NULL;
|
|
+ }
|
|
+ return error;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_mast.c,v $
|
|
+ * Revision 1.7.2.1 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.7 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.6 2004/12/03 21:25:57 mcr
|
|
+ * compile time fixes for running on 2.6.
|
|
+ * still experimental.
|
|
+ *
|
|
+ * Revision 1.5 2004/08/03 18:19:08 mcr
|
|
+ * in 2.6, use "net_device" instead of #define device->net_device.
|
|
+ * this probably breaks 2.0 compiles.
|
|
+ *
|
|
+ * Revision 1.4 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.3 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.2.4.1 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.2 2003/06/22 20:06:17 mcr
|
|
+ * refactored mast code still had lots of ipsecX junk in it.
|
|
+ *
|
|
+ * Revision 1.1 2003/02/12 19:31:12 rgb
|
|
+ * Refactored from ipsec_tunnel.c
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,453 @@
|
|
+/*
|
|
+ * RCSID $Id: ipsec_md5c.c,v 1.10 2005/04/15 01:25:57 mcr Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
|
|
+ * changes to accomodate it in the kernel by ji.
|
|
+ */
|
|
+
|
|
+#include <asm/byteorder.h>
|
|
+#include <linux/string.h>
|
|
+
|
|
+#include "openswan/ipsec_md5h.h"
|
|
+
|
|
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
|
+ */
|
|
+
|
|
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
|
+rights reserved.
|
|
+
|
|
+License to copy and use this software is granted provided that it
|
|
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
|
+Algorithm" in all material mentioning or referencing this software
|
|
+or this function.
|
|
+
|
|
+License is also granted to make and use derivative works provided
|
|
+that such works are identified as "derived from the RSA Data
|
|
+Security, Inc. MD5 Message-Digest Algorithm" in all material
|
|
+mentioning or referencing the derived work.
|
|
+
|
|
+RSA Data Security, Inc. makes no representations concerning either
|
|
+the merchantability of this software or the suitability of this
|
|
+software for any particular purpose. It is provided "as is"
|
|
+without express or implied warranty of any kind.
|
|
+
|
|
+These notices must be retained in any copies of any part of this
|
|
+documentation and/or software.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Additions by JI
|
|
+ *
|
|
+ * HAVEMEMCOPY is defined if mem* routines are available
|
|
+ *
|
|
+ * HAVEHTON is defined if htons() and htonl() can be used
|
|
+ * for big/little endian conversions
|
|
+ *
|
|
+ */
|
|
+
|
|
+#define HAVEMEMCOPY
|
|
+#ifdef __LITTLE_ENDIAN
|
|
+#define LITTLENDIAN
|
|
+#endif
|
|
+#ifdef __BIG_ENDIAN
|
|
+#define BIGENDIAN
|
|
+#endif
|
|
+
|
|
+/* Constants for MD5Transform routine.
|
|
+ */
|
|
+
|
|
+#define S11 7
|
|
+#define S12 12
|
|
+#define S13 17
|
|
+#define S14 22
|
|
+#define S21 5
|
|
+#define S22 9
|
|
+#define S23 14
|
|
+#define S24 20
|
|
+#define S31 4
|
|
+#define S32 11
|
|
+#define S33 16
|
|
+#define S34 23
|
|
+#define S41 6
|
|
+#define S42 10
|
|
+#define S43 15
|
|
+#define S44 21
|
|
+
|
|
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
|
|
+
|
|
+#ifdef LITTLEENDIAN
|
|
+#define Encode MD5_memcpy
|
|
+#define Decode MD5_memcpy
|
|
+#else
|
|
+static void Encode PROTO_LIST
|
|
+ ((unsigned char *, UINT4 *, unsigned int));
|
|
+static void Decode PROTO_LIST
|
|
+ ((UINT4 *, unsigned char *, unsigned int));
|
|
+#endif
|
|
+
|
|
+#ifdef HAVEMEMCOPY
|
|
+/* no need to include <memory.h> here; <linux/string.h> defines these */
|
|
+#define MD5_memcpy memcpy
|
|
+#define MD5_memset memset
|
|
+#else
|
|
+#ifdef HAVEBCOPY
|
|
+#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
|
|
+#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
|
|
+#else
|
|
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
|
|
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
|
|
+#endif
|
|
+#endif
|
|
+static unsigned char PADDING[64] = {
|
|
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
+};
|
|
+
|
|
+/* F, G, H and I are basic MD5 functions.
|
|
+ */
|
|
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
|
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
|
+#define H(x, y, z) ((x) ^ (y) ^ (z))
|
|
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
|
+
|
|
+/* ROTATE_LEFT rotates x left n bits.
|
|
+ */
|
|
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
|
+
|
|
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
|
+Rotation is separate from addition to prevent recomputation.
|
|
+ */
|
|
+#define FF(a, b, c, d, x, s, ac) { \
|
|
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
+ (a) = ROTATE_LEFT ((a), (s)); \
|
|
+ (a) += (b); \
|
|
+ }
|
|
+#define GG(a, b, c, d, x, s, ac) { \
|
|
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
+ (a) = ROTATE_LEFT ((a), (s)); \
|
|
+ (a) += (b); \
|
|
+ }
|
|
+#define HH(a, b, c, d, x, s, ac) { \
|
|
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
+ (a) = ROTATE_LEFT ((a), (s)); \
|
|
+ (a) += (b); \
|
|
+ }
|
|
+#define II(a, b, c, d, x, s, ac) { \
|
|
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
|
+ (a) = ROTATE_LEFT ((a), (s)); \
|
|
+ (a) += (b); \
|
|
+ }
|
|
+
|
|
+/*
|
|
+ * MD5 initialization. Begins an MD5 operation, writing a new context.
|
|
+ */
|
|
+void osMD5Init(void *vcontext)
|
|
+{
|
|
+ MD5_CTX *context = vcontext;
|
|
+
|
|
+ context->count[0] = context->count[1] = 0;
|
|
+ /* Load magic initialization constants.*/
|
|
+ context->state[0] = 0x67452301;
|
|
+ context->state[1] = 0xefcdab89;
|
|
+ context->state[2] = 0x98badcfe;
|
|
+ context->state[3] = 0x10325476;
|
|
+}
|
|
+
|
|
+/* MD5 block update operation. Continues an MD5 message-digest
|
|
+ operation, processing another message block, and updating the
|
|
+ context.
|
|
+ */
|
|
+void osMD5Update (vcontext, input, inputLen)
|
|
+ void *vcontext;
|
|
+ unsigned char *input; /* input block */
|
|
+ __u32 inputLen; /* length of input block */
|
|
+{
|
|
+ MD5_CTX *context = vcontext;
|
|
+ __u32 i;
|
|
+ unsigned int index, partLen;
|
|
+
|
|
+ /* Compute number of bytes mod 64 */
|
|
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
|
+
|
|
+ /* Update number of bits */
|
|
+ if ((context->count[0] += ((UINT4)inputLen << 3))
|
|
+ < ((UINT4)inputLen << 3))
|
|
+ context->count[1]++;
|
|
+ context->count[1] += ((UINT4)inputLen >> 29);
|
|
+
|
|
+ partLen = 64 - index;
|
|
+
|
|
+ /* Transform as many times as possible.
|
|
+*/
|
|
+ if (inputLen >= partLen) {
|
|
+ MD5_memcpy
|
|
+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
|
|
+ MD5Transform (context->state, context->buffer);
|
|
+
|
|
+ for (i = partLen; i + 63 < inputLen; i += 64)
|
|
+ MD5Transform (context->state, &input[i]);
|
|
+
|
|
+ index = 0;
|
|
+ }
|
|
+ else
|
|
+ i = 0;
|
|
+
|
|
+ /* Buffer remaining input */
|
|
+ MD5_memcpy
|
|
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
|
|
+ inputLen-i);
|
|
+}
|
|
+
|
|
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
|
+ the message digest and zeroizing the context.
|
|
+ */
|
|
+void osMD5Final (digest, vcontext)
|
|
+unsigned char digest[16]; /* message digest */
|
|
+void *vcontext; /* context */
|
|
+{
|
|
+ MD5_CTX *context = vcontext;
|
|
+ unsigned char bits[8];
|
|
+ unsigned int index, padLen;
|
|
+
|
|
+ /* Save number of bits */
|
|
+ Encode (bits, context->count, 8);
|
|
+
|
|
+ /* Pad out to 56 mod 64.
|
|
+*/
|
|
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
|
+ padLen = (index < 56) ? (56 - index) : (120 - index);
|
|
+ osMD5Update (context, PADDING, padLen);
|
|
+
|
|
+ /* Append length (before padding) */
|
|
+ osMD5Update (context, bits, 8);
|
|
+
|
|
+ if (digest != NULL) /* Bill Simpson's padding */
|
|
+ {
|
|
+ /* store state in digest */
|
|
+ Encode (digest, context->state, 16);
|
|
+
|
|
+ /* Zeroize sensitive information.
|
|
+ */
|
|
+ MD5_memset ((POINTER)context, 0, sizeof (*context));
|
|
+ }
|
|
+}
|
|
+
|
|
+/* MD5 basic transformation. Transforms state based on block.
|
|
+ */
|
|
+static void MD5Transform (state, block)
|
|
+UINT4 state[4];
|
|
+unsigned char block[64];
|
|
+{
|
|
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
|
+
|
|
+ Decode (x, block, 64);
|
|
+
|
|
+ /* Round 1 */
|
|
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
|
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
|
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
|
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
|
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
|
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
|
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
|
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
|
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
|
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
|
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
|
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
|
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
|
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
|
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
|
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
|
+
|
|
+ /* Round 2 */
|
|
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
|
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
|
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
|
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
|
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
|
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
|
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
|
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
|
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
|
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
|
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
|
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
|
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
|
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
|
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
|
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
|
+
|
|
+ /* Round 3 */
|
|
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
|
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
|
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
|
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
|
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
|
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
|
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
|
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
|
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
|
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
|
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
|
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
|
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
|
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
|
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
|
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
|
+
|
|
+ /* Round 4 */
|
|
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
|
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
|
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
|
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
|
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
|
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
|
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
|
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
|
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
|
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
|
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
|
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
|
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
|
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
|
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
|
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
|
+
|
|
+ state[0] += a;
|
|
+ state[1] += b;
|
|
+ state[2] += c;
|
|
+ state[3] += d;
|
|
+
|
|
+ /* Zeroize sensitive information.
|
|
+*/
|
|
+ MD5_memset ((POINTER)x, 0, sizeof (x));
|
|
+}
|
|
+
|
|
+#ifndef LITTLEENDIAN
|
|
+
|
|
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
|
|
+ a multiple of 4.
|
|
+ */
|
|
+static void Encode (output, input, len)
|
|
+unsigned char *output;
|
|
+UINT4 *input;
|
|
+unsigned int len;
|
|
+{
|
|
+ unsigned int i, j;
|
|
+
|
|
+ for (i = 0, j = 0; j < len; i++, j += 4) {
|
|
+ output[j] = (unsigned char)(input[i] & 0xff);
|
|
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
|
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
|
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
|
+ }
|
|
+}
|
|
+
|
|
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
|
+ a multiple of 4.
|
|
+ */
|
|
+static void Decode (output, input, len)
|
|
+UINT4 *output;
|
|
+unsigned char *input;
|
|
+unsigned int len;
|
|
+{
|
|
+ unsigned int i, j;
|
|
+
|
|
+ for (i = 0, j = 0; j < len; i++, j += 4)
|
|
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
|
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+#ifndef HAVEMEMCOPY
|
|
+#ifndef HAVEBCOPY
|
|
+/* Note: Replace "for loop" with standard memcpy if possible.
|
|
+ */
|
|
+
|
|
+static void MD5_memcpy (output, input, len)
|
|
+POINTER output;
|
|
+POINTER input;
|
|
+unsigned int len;
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < len; i++)
|
|
+
|
|
+ output[i] = input[i];
|
|
+}
|
|
+
|
|
+/* Note: Replace "for loop" with standard memset if possible.
|
|
+ */
|
|
+
|
|
+static void MD5_memset (output, value, len)
|
|
+POINTER output;
|
|
+int value;
|
|
+unsigned int len;
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < len; i++)
|
|
+ ((char *)output)[i] = (char)value;
|
|
+}
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_md5c.c,v $
|
|
+ * Revision 1.10 2005/04/15 01:25:57 mcr
|
|
+ * minor fix to comments.
|
|
+ *
|
|
+ * Revision 1.9 2004/09/08 17:21:36 ken
|
|
+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
|
|
+ *
|
|
+ * Revision 1.8 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.7 2002/09/10 01:45:14 mcr
|
|
+ * changed type of MD5_CTX and SHA1_CTX to void * so that
|
|
+ * the function prototypes would match, and could be placed
|
|
+ * into a pointer to a function.
|
|
+ *
|
|
+ * Revision 1.6 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.5 2002/04/24 07:36:28 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
|
|
+ *
|
|
+ * Revision 1.4 1999/12/13 13:59:12 rgb
|
|
+ * Quick fix to argument size to Update bugs.
|
|
+ *
|
|
+ * Revision 1.3 1999/05/21 18:09:28 henry
|
|
+ * unnecessary <memory.h> include causes trouble in 2.2
|
|
+ *
|
|
+ * Revision 1.2 1999/04/06 04:54:26 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:48 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.2 1998/04/23 20:54:02 rgb
|
|
+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
|
|
+ * verified.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:08 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:48:53 ji
|
|
+ * Release update only.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1186 @@
|
|
+/*
|
|
+ * @(#) /proc file system interface code.
|
|
+ *
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * 2001 Michael Richardson <mcr@freeswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * Split out from ipsec_init.c version 1.70.
|
|
+ */
|
|
+
|
|
+char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.39.2.4 2006/11/15 22:21:39 paul Exp $";
|
|
+
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_kversion.h"
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/in.h> /* struct sockaddr_in */
|
|
+#include <linux/skbuff.h>
|
|
+#include <asm/uaccess.h> /* copy_from_user */
|
|
+#include <openswan.h>
|
|
+#ifdef SPINLOCK
|
|
+#ifdef SPINLOCK_23
|
|
+#include <linux/spinlock.h> /* *lock* */
|
|
+#else /* SPINLOCK_23 */
|
|
+#include <asm/spinlock.h> /* *lock* */
|
|
+#endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+#ifdef CONFIG_PROC_FS
|
|
+#include <linux/proc_fs.h>
|
|
+#endif /* CONFIG_PROC_FS */
|
|
+#ifdef NETLINK_SOCK
|
|
+#include <linux/netlink.h>
|
|
+#else
|
|
+#include <net/netlink.h>
|
|
+#endif
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+
|
|
+#include "openswan/ipsec_life.h"
|
|
+#include "openswan/ipsec_stats.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_xmit.h"
|
|
+
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_esp.h"
|
|
+#include "openswan/ipsec_kern24.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+#include "openswan/ipcomp.h"
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#ifdef CONFIG_PROC_FS
|
|
+
|
|
+#ifdef IPSEC_PROC_SUBDIRS
|
|
+static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
|
|
+static struct proc_dir_entry *proc_eroute_dir = NULL;
|
|
+static struct proc_dir_entry *proc_spi_dir = NULL;
|
|
+static struct proc_dir_entry *proc_spigrp_dir = NULL;
|
|
+static struct proc_dir_entry *proc_birth_dir = NULL;
|
|
+static struct proc_dir_entry *proc_stats_dir = NULL;
|
|
+#endif
|
|
+
|
|
+struct ipsec_birth_reply ipsec_ipv4_birth_packet;
|
|
+struct ipsec_birth_reply ipsec_ipv6_birth_packet;
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int debug_esp = 0;
|
|
+int debug_ah = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)
|
|
+
|
|
+extern int ipsec_xform_get_info(char *buffer, char **start,
|
|
+ off_t offset, int length IPSEC_PROC_LAST_ARG);
|
|
+
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_eroute_get_info(char *buffer,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int length IPSEC_PROC_LAST_ARG)
|
|
+{
|
|
+ struct wsbuf w = {buffer, length, offset, 0, 0};
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if (debug_radij & DB_RJ_DUMPTREES)
|
|
+ rj_dumptrees(); /* XXXXXXXXX */
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_eroute_get_info: "
|
|
+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
|
|
+ buffer,
|
|
+ *start,
|
|
+ (int)offset,
|
|
+ length);
|
|
+
|
|
+ spin_lock_bh(&eroute_lock);
|
|
+
|
|
+ rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
|
|
+/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
|
|
+
|
|
+ spin_unlock_bh(&eroute_lock);
|
|
+
|
|
+ *start = buffer + (offset - w.begin); /* Start of wanted data */
|
|
+ return w.len - (offset - w.begin);
|
|
+}
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_spi_get_info(char *buffer,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int length IPSEC_PROC_LAST_ARG)
|
|
+{
|
|
+ const int max_content = length > 0? length-1 : 0;
|
|
+ int len = 0;
|
|
+ off_t begin = 0;
|
|
+ int i;
|
|
+ struct ipsec_sa *sa_p;
|
|
+ char sa[SATOT_BUF];
|
|
+ char buf_s[SUBNETTOA_BUF];
|
|
+ char buf_d[SUBNETTOA_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_spi_get_info: "
|
|
+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
|
|
+ buffer,
|
|
+ *start,
|
|
+ (int)offset,
|
|
+ length);
|
|
+
|
|
+ spin_lock_bh(&tdb_lock);
|
|
+
|
|
+ for (i = 0; i < SADB_HASHMOD; i++) {
|
|
+ for (sa_p = ipsec_sadb_hash[i];
|
|
+ sa_p;
|
|
+ sa_p = sa_p->ips_hnext) {
|
|
+ atomic_inc(&sa_p->ips_refcount);
|
|
+ sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
|
|
+ sa_len ? sa : " (error)");
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
|
|
+ IPS_XFORM_NAME(sa_p));
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len, ": dir=%s",
|
|
+ (sa_p->ips_flags & EMT_INBOUND) ?
|
|
+ "in " : "out");
|
|
+
|
|
+ if(sa_p->ips_addr_s) {
|
|
+ addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
|
|
+ 0, buf_s, sizeof(buf_s));
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " src=%s",
|
|
+ buf_s);
|
|
+ }
|
|
+
|
|
+ if((sa_p->ips_said.proto == IPPROTO_IPIP)
|
|
+ && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
|
|
+ subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
|
|
+ sa_p->ips_mask_s.u.v4.sin_addr,
|
|
+ 0,
|
|
+ buf_s,
|
|
+ sizeof(buf_s));
|
|
+
|
|
+ subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
|
|
+ sa_p->ips_mask_d.u.v4.sin_addr,
|
|
+ 0,
|
|
+ buf_d,
|
|
+ sizeof(buf_d));
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
|
|
+ buf_s, buf_d);
|
|
+ }
|
|
+
|
|
+ if(sa_p->ips_iv_bits) {
|
|
+ int j;
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
|
|
+ sa_p->ips_iv_bits);
|
|
+
|
|
+ for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "%02x",
|
|
+ (__u32)((__u8*)(sa_p->ips_iv))[j]);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(sa_p->ips_encalg || sa_p->ips_authalg) {
|
|
+ if(sa_p->ips_replaywin) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
|
|
+ sa_p->ips_replaywin);
|
|
+ }
|
|
+ if(sa_p->ips_errs.ips_replaywin_errs) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
|
|
+ sa_p->ips_errs.ips_replaywin_errs);
|
|
+ }
|
|
+ if(sa_p->ips_replaywin_lastseq) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
|
|
+ sa_p->ips_replaywin_lastseq);
|
|
+ }
|
|
+ if(sa_p->ips_replaywin_bitmap) {
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
|
|
+ sa_p->ips_replaywin_bitmap);
|
|
+#else
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x",
|
|
+ (__u32)(sa_p->ips_replaywin_bitmap >> 32),
|
|
+ (__u32)sa_p->ips_replaywin_bitmap);
|
|
+#endif
|
|
+ }
|
|
+ if(sa_p->ips_replaywin_maxdiff) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
|
|
+ sa_p->ips_replaywin_maxdiff);
|
|
+ }
|
|
+ }
|
|
+ if(sa_p->ips_flags & ~EMT_INBOUND) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
|
|
+ sa_p->ips_flags & ~EMT_INBOUND);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "<");
|
|
+ /* flag printing goes here */
|
|
+ len += ipsec_snprintf(buffer+len, length-len, ">");
|
|
+ }
|
|
+ if(sa_p->ips_auth_bits) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
|
|
+ sa_p->ips_auth_bits);
|
|
+ }
|
|
+ if(sa_p->ips_key_bits_a) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
|
|
+ sa_p->ips_key_bits_a);
|
|
+ }
|
|
+ if(sa_p->ips_errs.ips_auth_errs) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
|
|
+ sa_p->ips_errs.ips_auth_errs);
|
|
+ }
|
|
+ if(sa_p->ips_key_bits_e) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
|
|
+ sa_p->ips_key_bits_e);
|
|
+ }
|
|
+ if(sa_p->ips_errs.ips_encsize_errs) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
|
|
+ sa_p->ips_errs.ips_encsize_errs);
|
|
+ }
|
|
+ if(sa_p->ips_errs.ips_encpad_errs) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
|
|
+ sa_p->ips_errs.ips_encpad_errs);
|
|
+ }
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)=");
|
|
+
|
|
+ len += ipsec_lifetime_format(buffer + len,
|
|
+ length - len,
|
|
+ "alloc",
|
|
+ ipsec_life_countbased,
|
|
+ &sa_p->ips_life.ipl_allocations);
|
|
+
|
|
+ len += ipsec_lifetime_format(buffer + len,
|
|
+ length - len,
|
|
+ "bytes",
|
|
+ ipsec_life_countbased,
|
|
+ &sa_p->ips_life.ipl_bytes);
|
|
+
|
|
+ len += ipsec_lifetime_format(buffer + len,
|
|
+ length - len,
|
|
+ "addtime",
|
|
+ ipsec_life_timebased,
|
|
+ &sa_p->ips_life.ipl_addtime);
|
|
+
|
|
+ len += ipsec_lifetime_format(buffer + len,
|
|
+ length - len,
|
|
+ "usetime",
|
|
+ ipsec_life_timebased,
|
|
+ &sa_p->ips_life.ipl_usetime);
|
|
+
|
|
+ len += ipsec_lifetime_format(buffer + len,
|
|
+ length - len,
|
|
+ "packets",
|
|
+ ipsec_life_countbased,
|
|
+ &sa_p->ips_life.ipl_packets);
|
|
+
|
|
+ if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
|
|
+ jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
|
|
+#else
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
|
|
+ jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
|
|
+#endif
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ if(sa_p->ips_said.proto == IPPROTO_COMP &&
|
|
+ (sa_p->ips_comp_ratio_dbytes ||
|
|
+ sa_p->ips_comp_ratio_cbytes)) {
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
|
|
+ sa_p->ips_comp_ratio_dbytes,
|
|
+ sa_p->ips_comp_ratio_cbytes);
|
|
+#else
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
|
|
+ (unsigned long)sa_p->ips_comp_ratio_dbytes,
|
|
+ (unsigned long)sa_p->ips_comp_ratio_cbytes);
|
|
+#endif
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ {
|
|
+ char *natttype_name;
|
|
+
|
|
+ switch(sa_p->ips_natt_type)
|
|
+ {
|
|
+ case 0:
|
|
+ natttype_name="none";
|
|
+ break;
|
|
+ case ESPINUDP_WITH_NON_IKE:
|
|
+ natttype_name="nonike";
|
|
+ break;
|
|
+ case ESPINUDP_WITH_NON_ESP:
|
|
+ natttype_name="nonesp";
|
|
+ break;
|
|
+ default:
|
|
+ natttype_name = "unknown";
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ len += ipsec_snprintf(buffer + len, length-len, " natencap=%s",
|
|
+ natttype_name);
|
|
+
|
|
+ len += ipsec_snprintf(buffer + len, length-len, " natsport=%d",
|
|
+ sa_p->ips_natt_sport);
|
|
+
|
|
+ len += ipsec_snprintf(buffer + len,length-len, " natdport=%d",
|
|
+ sa_p->ips_natt_dport);
|
|
+ }
|
|
+#else
|
|
+ len += ipsec_snprintf(buffer + len, length-len, " natencap=na");
|
|
+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
|
|
+
|
|
+ len += ipsec_snprintf(buffer + len,length-len, " refcount=%d",
|
|
+ atomic_read(&sa_p->ips_refcount));
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
|
|
+ sa_p->ips_ref);
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_xform) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
|
|
+ (unsigned long)IPsecSAref2table(sa_p->ips_ref),
|
|
+ (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "\n");
|
|
+
|
|
+ atomic_dec(&sa_p->ips_refcount);
|
|
+
|
|
+ if (len >= max_content) {
|
|
+ /* we've done all that can fit -- stop loops */
|
|
+ len = max_content; /* truncate crap */
|
|
+ goto done_spi_i;
|
|
+ } else {
|
|
+ const off_t pos = begin + len; /* file position of end of what we've generated */
|
|
+
|
|
+ if (pos <= offset) {
|
|
+ /* all is before first interesting character:
|
|
+ * discard, but note where we are.
|
|
+ */
|
|
+ len = 0;
|
|
+ begin = pos;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+done_spi_i:
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ return len - (offset - begin);
|
|
+}
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_spigrp_get_info(char *buffer,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int length IPSEC_PROC_LAST_ARG)
|
|
+{
|
|
+ /* Limit of useful snprintf output */
|
|
+ const int max_content = length > 0? length-1 : 0;
|
|
+
|
|
+ int len = 0;
|
|
+ off_t begin = 0;
|
|
+ int i;
|
|
+ struct ipsec_sa *sa_p, *sa_p2;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_spigrp_get_info: "
|
|
+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
|
|
+ buffer,
|
|
+ *start,
|
|
+ (int)offset,
|
|
+ length);
|
|
+
|
|
+ spin_lock_bh(&tdb_lock);
|
|
+
|
|
+ for (i = 0; i < SADB_HASHMOD; i++) {
|
|
+ for (sa_p = ipsec_sadb_hash[i];
|
|
+ sa_p != NULL;
|
|
+ sa_p = sa_p->ips_hnext)
|
|
+ {
|
|
+ atomic_inc(&sa_p->ips_refcount);
|
|
+ if(sa_p->ips_inext == NULL) {
|
|
+ sa_p2 = sa_p;
|
|
+ while(sa_p2 != NULL) {
|
|
+ atomic_inc(&sa_p2->ips_refcount);
|
|
+ sa_len = satot(&sa_p2->ips_said,
|
|
+ 'x', sa, sizeof(sa));
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
|
|
+ sa_len ? sa : " (error)");
|
|
+ atomic_dec(&sa_p2->ips_refcount);
|
|
+ sa_p2 = sa_p2->ips_onext;
|
|
+ }
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "\n");
|
|
+ }
|
|
+
|
|
+ atomic_dec(&sa_p->ips_refcount);
|
|
+
|
|
+ if (len >= max_content) {
|
|
+ /* we've done all that can fit -- stop loops */
|
|
+ len = max_content; /* truncate crap */
|
|
+ goto done_spigrp_i;
|
|
+ } else {
|
|
+ const off_t pos = begin + len;
|
|
+
|
|
+ if (pos <= offset) {
|
|
+ /* all is before first interesting character:
|
|
+ * discard, but note where we are.
|
|
+ */
|
|
+ len = 0;
|
|
+ begin = pos;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+done_spigrp_i:
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ return len - (offset - begin);
|
|
+}
|
|
+
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_tncfg_get_info(char *buffer,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int length IPSEC_PROC_LAST_ARG)
|
|
+{
|
|
+ /* limit of useful snprintf output */
|
|
+ const int max_content = length > 0? length-1 : 0;
|
|
+ int len = 0;
|
|
+ off_t begin = 0;
|
|
+ int i;
|
|
+ char name[9];
|
|
+ struct net_device *dev, *privdev;
|
|
+ struct ipsecpriv *priv;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_tncfg_get_info: "
|
|
+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
|
|
+ buffer,
|
|
+ *start,
|
|
+ (int)offset,
|
|
+ length);
|
|
+
|
|
+ for(i = 0; i < IPSEC_NUM_IF; i++) {
|
|
+ ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i);
|
|
+ dev = __ipsec_dev_get(name);
|
|
+ if(dev) {
|
|
+ priv = (struct ipsecpriv *)(dev->priv);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "%s",
|
|
+ dev->name);
|
|
+ if(priv) {
|
|
+ privdev = (struct net_device *)(priv->dev);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " -> %s",
|
|
+ privdev ? privdev->name : "NULL");
|
|
+ len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d",
|
|
+ dev->mtu,
|
|
+ priv->mtu,
|
|
+ privdev ? privdev->mtu : 0);
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
|
|
+ dev->name);
|
|
+ }
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "\n");
|
|
+
|
|
+ if (len >= max_content) {
|
|
+ /* we've done all that can fit -- stop loop */
|
|
+ len = max_content; /* truncate crap */
|
|
+ break;
|
|
+ } else {
|
|
+ const off_t pos = begin + len;
|
|
+ if (pos <= offset) {
|
|
+ len = 0;
|
|
+ begin = pos;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ len -= (offset - begin); /* Start slop */
|
|
+ if (len > length)
|
|
+ len = length;
|
|
+ return len;
|
|
+}
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_version_get_info(char *buffer,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int length IPSEC_PROC_LAST_ARG)
|
|
+{
|
|
+ int len = 0;
|
|
+ off_t begin = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_version_get_info: "
|
|
+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
|
|
+ buffer,
|
|
+ *start,
|
|
+ (int)offset,
|
|
+ length);
|
|
+
|
|
+ len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n",
|
|
+ ipsec_version_code());
|
|
+#if 0
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_version_get_info: "
|
|
+ "ipsec_init version: %s\n",
|
|
+ ipsec_init_c_version);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_version_get_info: "
|
|
+ "ipsec_tunnel version: %s\n",
|
|
+ ipsec_tunnel_c_version);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_version_get_info: "
|
|
+ "ipsec_netlink version: %s\n",
|
|
+ ipsec_netlink_c_version);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_version_get_info: "
|
|
+ "radij_c_version: %s\n",
|
|
+ radij_c_version);
|
|
+#endif
|
|
+
|
|
+
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ len -= (offset - begin); /* Start slop */
|
|
+ if (len > length)
|
|
+ len = length;
|
|
+ return len;
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+unsigned int natt_available = 1;
|
|
+#else
|
|
+unsigned int natt_available = 0;
|
|
+#endif
|
|
+module_param(natt_available, int, 0444);
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_natt_get_info(char *buffer,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int length IPSEC_PROC_LAST_ARG)
|
|
+{
|
|
+ int len = 0;
|
|
+ off_t begin = 0;
|
|
+
|
|
+ len += ipsec_snprintf(buffer + len,
|
|
+ length-len, "%d\n",
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ 1
|
|
+#else
|
|
+ 0
|
|
+#endif
|
|
+ );
|
|
+
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ len -= (offset - begin); /* Start slop */
|
|
+ if (len > length)
|
|
+ len = length;
|
|
+ return len;
|
|
+}
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_birth_info(char *page,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int count,
|
|
+ int *eof,
|
|
+ void *data)
|
|
+{
|
|
+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
|
|
+ int len;
|
|
+
|
|
+ if(offset >= ibr->packet_template_len) {
|
|
+ if(eof) {
|
|
+ *eof=1;
|
|
+ }
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ len = ibr->packet_template_len;
|
|
+ len -= offset;
|
|
+ if (len > count)
|
|
+ len = count;
|
|
+
|
|
+ memcpy(page + offset, ibr->packet_template+offset, len);
|
|
+
|
|
+ return len;
|
|
+}
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_birth_set(struct file *file, const char *buffer,
|
|
+ unsigned long count, void *data)
|
|
+{
|
|
+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
|
|
+ int len;
|
|
+
|
|
+ KLIPS_INC_USE;
|
|
+ if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
|
|
+ len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
|
|
+ } else {
|
|
+ len = count;
|
|
+ }
|
|
+
|
|
+ if(copy_from_user(ibr->packet_template, buffer, len)) {
|
|
+ KLIPS_DEC_USE;
|
|
+ return -EFAULT;
|
|
+ }
|
|
+ ibr->packet_template_len = len;
|
|
+
|
|
+ KLIPS_DEC_USE;
|
|
+
|
|
+ return len;
|
|
+}
|
|
+
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_klipsdebug_get_info(char *buffer,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int length IPSEC_PROC_LAST_ARG)
|
|
+{
|
|
+ int len = 0;
|
|
+ off_t begin = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
|
|
+ "klips_debug:ipsec_klipsdebug_get_info: "
|
|
+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
|
|
+ buffer,
|
|
+ *start,
|
|
+ (int)offset,
|
|
+ length);
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
|
|
+ len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
|
|
+
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ len -= (offset - begin); /* Start slop */
|
|
+ if (len > length)
|
|
+ len = length;
|
|
+ return len;
|
|
+}
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+IPSEC_PROCFS_DEBUG_NO_STATIC
|
|
+int
|
|
+ipsec_stats_get_int_info(char *buffer,
|
|
+ char **start,
|
|
+ off_t offset,
|
|
+ int length,
|
|
+ int *eof,
|
|
+ void *data)
|
|
+{
|
|
+
|
|
+ const int max_content = length > 0? length-1 : 0;
|
|
+ int len = 0;
|
|
+ int *thing;
|
|
+
|
|
+ thing = (int *)data;
|
|
+
|
|
+ len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing);
|
|
+
|
|
+ if (len >= max_content)
|
|
+ len = max_content; /* truncate crap */
|
|
+
|
|
+ *start = buffer + offset; /* Start of wanted data */
|
|
+ return len > offset? len - offset : 0;
|
|
+
|
|
+}
|
|
+
|
|
+#ifndef PROC_FS_2325
|
|
+struct proc_dir_entry ipsec_eroute =
|
|
+{
|
|
+ 0,
|
|
+ 12, "ipsec_eroute",
|
|
+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
|
|
+ &proc_net_inode_operations,
|
|
+ ipsec_eroute_get_info,
|
|
+ NULL, NULL, NULL, NULL, NULL
|
|
+};
|
|
+
|
|
+struct proc_dir_entry ipsec_spi =
|
|
+{
|
|
+ 0,
|
|
+ 9, "ipsec_spi",
|
|
+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
|
|
+ &proc_net_inode_operations,
|
|
+ ipsec_spi_get_info,
|
|
+ NULL, NULL, NULL, NULL, NULL
|
|
+};
|
|
+
|
|
+struct proc_dir_entry ipsec_spigrp =
|
|
+{
|
|
+ 0,
|
|
+ 12, "ipsec_spigrp",
|
|
+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
|
|
+ &proc_net_inode_operations,
|
|
+ ipsec_spigrp_get_info,
|
|
+ NULL, NULL, NULL, NULL, NULL
|
|
+};
|
|
+
|
|
+struct proc_dir_entry ipsec_tncfg =
|
|
+{
|
|
+ 0,
|
|
+ 11, "ipsec_tncfg",
|
|
+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
|
|
+ &proc_net_inode_operations,
|
|
+ ipsec_tncfg_get_info,
|
|
+ NULL, NULL, NULL, NULL, NULL
|
|
+};
|
|
+
|
|
+struct proc_dir_entry ipsec_version =
|
|
+{
|
|
+ 0,
|
|
+ 13, "ipsec_version",
|
|
+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
|
|
+ &proc_net_inode_operations,
|
|
+ ipsec_version_get_info,
|
|
+ NULL, NULL, NULL, NULL, NULL
|
|
+};
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+struct proc_dir_entry ipsec_klipsdebug =
|
|
+{
|
|
+ 0,
|
|
+ 16, "ipsec_klipsdebug",
|
|
+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
|
|
+ &proc_net_inode_operations,
|
|
+ ipsec_klipsdebug_get_info,
|
|
+ NULL, NULL, NULL, NULL, NULL
|
|
+};
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+#endif /* !PROC_FS_2325 */
|
|
+#endif /* CONFIG_PROC_FS */
|
|
+
|
|
+#if defined(PROC_FS_2325)
|
|
+struct ipsec_proc_list {
|
|
+ char *name;
|
|
+ struct proc_dir_entry **parent;
|
|
+ struct proc_dir_entry **dir;
|
|
+ read_proc_t *readthing;
|
|
+ write_proc_t *writething;
|
|
+ void *data;
|
|
+};
|
|
+static struct ipsec_proc_list proc_items[]={
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL},
|
|
+#endif
|
|
+ {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
|
|
+ {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL},
|
|
+ {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL},
|
|
+ {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL},
|
|
+ {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
|
|
+ {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL},
|
|
+ {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL},
|
|
+ {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
|
|
+ {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
|
|
+ {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL},
|
|
+ {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL},
|
|
+ {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL},
|
|
+ {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
|
|
+ {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
|
|
+ {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL},
|
|
+ {NULL, NULL, NULL, NULL, NULL, NULL}
|
|
+};
|
|
+#endif
|
|
+
|
|
+int
|
|
+ipsec_proc_init()
|
|
+{
|
|
+ int error = 0;
|
|
+#ifdef IPSEC_PROC_SUBDIRS
|
|
+ struct proc_dir_entry *item;
|
|
+#endif
|
|
+
|
|
+ /*
|
|
+ * just complain because pluto won't run without /proc!
|
|
+ */
|
|
+#ifndef CONFIG_PROC_FS
|
|
+#error You must have PROC_FS built in to use KLIPS
|
|
+#endif
|
|
+
|
|
+ /* for 2.0 kernels */
|
|
+#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
|
|
+ error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
|
|
+ error |= proc_register_dynamic(&proc_net, &ipsec_spi);
|
|
+ error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
|
|
+ error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
|
|
+ error |= proc_register_dynamic(&proc_net, &ipsec_version);
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+#endif
|
|
+
|
|
+ /* for 2.2 kernels */
|
|
+#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
|
|
+ error |= proc_register(proc_net, &ipsec_eroute);
|
|
+ error |= proc_register(proc_net, &ipsec_spi);
|
|
+ error |= proc_register(proc_net, &ipsec_spigrp);
|
|
+ error |= proc_register(proc_net, &ipsec_tncfg);
|
|
+ error |= proc_register(proc_net, &ipsec_version);
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ error |= proc_register(proc_net, &ipsec_klipsdebug);
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+#endif
|
|
+
|
|
+ /* for 2.4 kernels */
|
|
+#if defined(PROC_FS_2325)
|
|
+ /* create /proc/net/ipsec */
|
|
+
|
|
+ /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
|
|
+ memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
|
|
+ memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
|
|
+
|
|
+ proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
|
|
+ if(proc_net_ipsec_dir == NULL) {
|
|
+ /* no point in continuing */
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ {
|
|
+ struct ipsec_proc_list *it;
|
|
+
|
|
+ it=proc_items;
|
|
+ while(it->name!=NULL) {
|
|
+ if(it->dir) {
|
|
+ /* make a dir instead */
|
|
+ item = proc_mkdir(it->name, *it->parent);
|
|
+ *it->dir = item;
|
|
+ } else {
|
|
+ item = create_proc_entry(it->name, 0400, *it->parent);
|
|
+ }
|
|
+ if(item) {
|
|
+ item->read_proc = it->readthing;
|
|
+ item->write_proc = it->writething;
|
|
+ item->data = it->data;
|
|
+#ifdef MODULE
|
|
+ item->owner = THIS_MODULE;
|
|
+#endif
|
|
+ } else {
|
|
+ error |= 1;
|
|
+ }
|
|
+ it++;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* now create some symlinks to provide compatibility */
|
|
+ proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
|
|
+ proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all");
|
|
+ proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
|
|
+ proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg");
|
|
+ proc_symlink("ipsec_version",proc_net, "ipsec/version");
|
|
+ proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
|
|
+
|
|
+#endif /* !PROC_FS_2325 */
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+void
|
|
+ipsec_proc_cleanup()
|
|
+{
|
|
+
|
|
+ /* for 2.0 and 2.2 kernels */
|
|
+#if !defined(PROC_FS_2325)
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
|
|
+ printk("klips_debug:ipsec_cleanup: "
|
|
+ "cannot unregister /proc/net/ipsec_klipsdebug\n");
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ if (proc_net_unregister(ipsec_version.low_ino) != 0)
|
|
+ printk("klips_debug:ipsec_cleanup: "
|
|
+ "cannot unregister /proc/net/ipsec_version\n");
|
|
+ if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
|
|
+ printk("klips_debug:ipsec_cleanup: "
|
|
+ "cannot unregister /proc/net/ipsec_eroute\n");
|
|
+ if (proc_net_unregister(ipsec_spi.low_ino) != 0)
|
|
+ printk("klips_debug:ipsec_cleanup: "
|
|
+ "cannot unregister /proc/net/ipsec_spi\n");
|
|
+ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
|
|
+ printk("klips_debug:ipsec_cleanup: "
|
|
+ "cannot unregister /proc/net/ipsec_spigrp\n");
|
|
+ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
|
|
+ printk("klips_debug:ipsec_cleanup: "
|
|
+ "cannot unregister /proc/net/ipsec_tncfg\n");
|
|
+#endif
|
|
+
|
|
+ /* for 2.4 kernels */
|
|
+#if defined(PROC_FS_2325)
|
|
+ {
|
|
+ struct ipsec_proc_list *it;
|
|
+
|
|
+ /* find end of list */
|
|
+ it=proc_items;
|
|
+ while(it->name!=NULL) {
|
|
+ it++;
|
|
+ }
|
|
+ it--;
|
|
+
|
|
+ do {
|
|
+ remove_proc_entry(it->name, *it->parent);
|
|
+ it--;
|
|
+ } while(it >= proc_items);
|
|
+ }
|
|
+
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ remove_proc_entry("ipsec_klipsdebug", proc_net);
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ remove_proc_entry("ipsec_eroute", proc_net);
|
|
+ remove_proc_entry("ipsec_spi", proc_net);
|
|
+ remove_proc_entry("ipsec_spigrp", proc_net);
|
|
+ remove_proc_entry("ipsec_tncfg", proc_net);
|
|
+ remove_proc_entry("ipsec_version", proc_net);
|
|
+ remove_proc_entry("ipsec", proc_net);
|
|
+#endif /* 2.4 kernel */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_proc.c,v $
|
|
+ * Revision 1.39.2.4 2006/11/15 22:21:39 paul
|
|
+ * backport of creating a /sys/ file to test for nat-t capability in kernel.
|
|
+ *
|
|
+ * Revision 1.39.2.3 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.39.2.2 2006/02/13 18:48:12 paul
|
|
+ * Fix by Ankit Desai <ankit@elitecore.com> for module unloading.
|
|
+ *
|
|
+ * Revision 1.39.2.1 2005/09/07 00:45:59 paul
|
|
+ * pull up of mcr's nat-t klips detection patch from head
|
|
+ *
|
|
+ * Revision 1.39 2005/05/20 03:19:18 mcr
|
|
+ * modifications for use on 2.4.30 kernel, with backported
|
|
+ * printk_ratelimit(). all warnings removed.
|
|
+ *
|
|
+ * Revision 1.38 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.37 2005/04/13 22:49:49 mcr
|
|
+ * moved KLIPS specific snprintf() wrapper to seperate file.
|
|
+ *
|
|
+ * Revision 1.36 2005/04/06 17:44:36 mcr
|
|
+ * when NAT-T is compiled out, show encap as "NA"
|
|
+ *
|
|
+ * Revision 1.35 2005/01/26 00:50:35 mcr
|
|
+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
|
|
+ * and make sure that NAT_TRAVERSAL is set as well to match
|
|
+ * userspace compiles of code.
|
|
+ *
|
|
+ * Revision 1.34 2004/12/03 21:25:57 mcr
|
|
+ * compile time fixes for running on 2.6.
|
|
+ * still experimental.
|
|
+ *
|
|
+ * Revision 1.33 2004/08/17 03:27:23 mcr
|
|
+ * klips 2.6 edits.
|
|
+ *
|
|
+ * Revision 1.32 2004/08/03 18:19:08 mcr
|
|
+ * in 2.6, use "net_device" instead of #define device->net_device.
|
|
+ * this probably breaks 2.0 compiles.
|
|
+ *
|
|
+ * Revision 1.31 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.30 2004/04/25 21:23:11 ken
|
|
+ * Pull in dhr's changes from FreeS/WAN 2.06
|
|
+ *
|
|
+ * Revision 1.29 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.28 2004/03/28 20:29:58 paul
|
|
+ * <hugh_> ssize_t, not ssized_t
|
|
+ *
|
|
+ * Revision 1.27 2004/03/28 20:27:20 paul
|
|
+ * Included tested and confirmed fixes mcr made and dhr verified for
|
|
+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
|
|
+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
|
|
+ * dhr. (thanks dhr!)
|
|
+ *
|
|
+ * Revision 1.26 2004/02/09 22:07:06 mcr
|
|
+ * added information about nat-traversal setting to spi-output.
|
|
+ *
|
|
+ * Revision 1.25.4.1 2004/04/05 04:30:46 mcr
|
|
+ * patches for alg-branch to compile/work with 2.x openswan
|
|
+ *
|
|
+ * Revision 1.25 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.24.4.1 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.24 2003/06/20 01:42:21 mcr
|
|
+ * added counters to measure how many ACQUIREs we send to pluto,
|
|
+ * and how many are successfully sent.
|
|
+ *
|
|
+ * Revision 1.23 2003/04/03 17:38:09 rgb
|
|
+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
|
|
+ *
|
|
+ * Revision 1.22 2002/09/20 15:40:57 rgb
|
|
+ * Renamed saref macros for consistency and brevity.
|
|
+ *
|
|
+ * Revision 1.21 2002/09/20 05:01:35 rgb
|
|
+ * Print ref and reftable, refentry seperately.
|
|
+ *
|
|
+ * Revision 1.20 2002/09/19 02:35:39 mcr
|
|
+ * do not define structures needed by /proc/net/ipsec/ if we
|
|
+ * aren't going create that directory.
|
|
+ *
|
|
+ * Revision 1.19 2002/09/10 01:43:25 mcr
|
|
+ * fixed problem in /-* comment.
|
|
+ *
|
|
+ * Revision 1.18 2002/09/03 16:22:11 mcr
|
|
+ * fixed initialization of birth/stuff values - some simple
|
|
+ * screw ups in the code.
|
|
+ * removed debugging that was left in by mistake.
|
|
+ *
|
|
+ * Revision 1.17 2002/09/02 17:54:53 mcr
|
|
+ * changed how the table driven /proc entries are created so that
|
|
+ * making subdirs is now explicit rather than implicit.
|
|
+ *
|
|
+ * Revision 1.16 2002/08/30 01:23:37 mcr
|
|
+ * reorganized /proc creating code to clear up ifdefs,
|
|
+ * make the 2.4 code table driven, and put things into
|
|
+ * /proc/net/ipsec subdir. Symlinks are left for compatibility.
|
|
+ *
|
|
+ * Revision 1.15 2002/08/13 19:01:25 mcr
|
|
+ * patches from kenb to permit compilation of FreeSWAN on ia64.
|
|
+ * des library patched to use proper DES_LONG type for ia64.
|
|
+ *
|
|
+ * Revision 1.14 2002/07/26 08:48:31 rgb
|
|
+ * Added SA ref table code.
|
|
+ *
|
|
+ * Revision 1.13 2002/07/24 18:44:54 rgb
|
|
+ * Type fiddling to tame ia64 compiler.
|
|
+ *
|
|
+ * Revision 1.12 2002/05/27 18:56:07 rgb
|
|
+ * Convert to dynamic ipsec device allocation.
|
|
+ *
|
|
+ * Revision 1.11 2002/05/23 07:14:50 rgb
|
|
+ * Added refcount code.
|
|
+ * Cleaned up %p variants to 0p%p for test suite cleanup.
|
|
+ * Convert "usecount" to "refcount" to remove ambiguity.
|
|
+ *
|
|
+ * Revision 1.10 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.9 2002/04/24 07:36:28 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_proc.c,v
|
|
+ *
|
|
+ * Revision 1.8 2002/01/29 17:17:55 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.7 2002/01/29 04:00:52 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.6 2002/01/29 02:13:17 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.5 2002/01/12 02:54:30 mcr
|
|
+ * beginnings of /proc/net/ipsec dir.
|
|
+ *
|
|
+ * Revision 1.4 2001/12/11 02:21:05 rgb
|
|
+ * Don't include module version here, fixing 2.2 compile bug.
|
|
+ *
|
|
+ * Revision 1.3 2001/12/05 07:19:44 rgb
|
|
+ * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:14 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.74 2001/11/22 05:44:11 henry
|
|
+ * new version stuff
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:19:40 mcr
|
|
+ * /proc manipulation code moved to new ipsec_proc.c
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,889 @@
|
|
+/*
|
|
+ * Interface between the IPSEC code and the radix (radij) tree code
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_radij.c,v 1.73.2.1 2006/10/06 21:39:26 paul Exp $
|
|
+ */
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <openswan.h>
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* 23_SPINLOCK */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* 23_SPINLOCK */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#include "openswan/ipsec_eroute.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */
|
|
+#include "openswan/ipsec_xform.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int debug_radij = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+struct radij_node_head *rnh = NULL;
|
|
+#ifdef SPINLOCK
|
|
+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
|
|
+#else /* SPINLOCK */
|
|
+spinlock_t eroute_lock;
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+int
|
|
+ipsec_radijinit(void)
|
|
+{
|
|
+ maj_keylen = sizeof (struct sockaddr_encap);
|
|
+
|
|
+ rj_init();
|
|
+
|
|
+ if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
|
|
+ return -1;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_radijcleanup(void)
|
|
+{
|
|
+ int error;
|
|
+
|
|
+ spin_lock_bh(&eroute_lock);
|
|
+
|
|
+ error = radijcleanup();
|
|
+
|
|
+ spin_unlock_bh(&eroute_lock);
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_cleareroutes(void)
|
|
+{
|
|
+ int error;
|
|
+
|
|
+ spin_lock_bh(&eroute_lock);
|
|
+
|
|
+ error = radijcleartree();
|
|
+
|
|
+ spin_unlock_bh(&eroute_lock);
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_breakroute(struct sockaddr_encap *eaddr,
|
|
+ struct sockaddr_encap *emask,
|
|
+ struct sk_buff **first,
|
|
+ struct sk_buff **last)
|
|
+{
|
|
+ struct eroute *ro;
|
|
+ struct radij_node *rn;
|
|
+ int error;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+
|
|
+ if (debug_eroute) {
|
|
+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
|
|
+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_breakroute: "
|
|
+ "attempting to delete eroute for %s:%d->%s:%d %d\n",
|
|
+ buf1, ntohs(eaddr->sen_sport),
|
|
+ buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ spin_lock_bh(&eroute_lock);
|
|
+
|
|
+ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
|
|
+ spin_unlock_bh(&eroute_lock);
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_breakroute: "
|
|
+ "node not found, eroute delete failed.\n");
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ spin_unlock_bh(&eroute_lock);
|
|
+
|
|
+ ro = (struct eroute *)rn;
|
|
+
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_breakroute: "
|
|
+ "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
|
|
+ ro,
|
|
+ ro->er_ident_s.data,
|
|
+ ro->er_ident_d.data,
|
|
+ ro->er_first,
|
|
+ ro->er_last);
|
|
+
|
|
+ if (ro->er_ident_s.data != NULL) {
|
|
+ kfree(ro->er_ident_s.data);
|
|
+ }
|
|
+ if (ro->er_ident_d.data != NULL) {
|
|
+ kfree(ro->er_ident_d.data);
|
|
+ }
|
|
+ if (ro->er_first != NULL) {
|
|
+#if 0
|
|
+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
|
|
+ stats->tx_dropped--;
|
|
+#endif
|
|
+ *first = ro->er_first;
|
|
+ }
|
|
+ if (ro->er_last != NULL) {
|
|
+#if 0
|
|
+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
|
|
+ stats->tx_dropped--;
|
|
+#endif
|
|
+ *last = ro->er_last;
|
|
+ }
|
|
+
|
|
+ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
|
|
+ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
|
|
+ memset((caddr_t)rn, 0, sizeof (struct eroute));
|
|
+ kfree(rn);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_makeroute(struct sockaddr_encap *eaddr,
|
|
+ struct sockaddr_encap *emask,
|
|
+ ip_said said,
|
|
+ uint32_t pid,
|
|
+ struct sk_buff *skb,
|
|
+ struct ident *ident_s,
|
|
+ struct ident *ident_d)
|
|
+{
|
|
+ struct eroute *retrt;
|
|
+ int error;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+
|
|
+ if (debug_eroute) {
|
|
+
|
|
+ {
|
|
+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
|
|
+
|
|
+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ sa_len = satot(&said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_makeroute: "
|
|
+ "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
|
|
+ (unsigned long) sizeof(struct eroute),
|
|
+ buf1,
|
|
+ buf2,
|
|
+ sa_len ? sa : " (error)",
|
|
+ pid,
|
|
+ skb,
|
|
+ (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
|
|
+ (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
|
|
+ }
|
|
+ {
|
|
+ char buf1[sizeof(struct sockaddr_encap)*2 + 1],
|
|
+ buf2[sizeof(struct sockaddr_encap)*2 + 1];
|
|
+ int i;
|
|
+ unsigned char *b1 = buf1,
|
|
+ *b2 = buf2,
|
|
+ *ea = (unsigned char *)eaddr,
|
|
+ *em = (unsigned char *)emask;
|
|
+
|
|
+
|
|
+ for (i=0; i<sizeof(struct sockaddr_encap); i++) {
|
|
+ sprintf(b1, "%02x", ea[i]);
|
|
+ sprintf(b2, "%02x", em[i]);
|
|
+ b1+=2;
|
|
+ b2+=2;
|
|
+ }
|
|
+ KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
|
|
+ }
|
|
+
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
|
|
+ if (retrt == NULL) {
|
|
+ printk("klips_error:ipsec_makeroute: "
|
|
+ "not able to allocate kernel memory");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ memset((caddr_t)retrt, 0, sizeof (struct eroute));
|
|
+
|
|
+ retrt->er_eaddr = *eaddr;
|
|
+ retrt->er_emask = *emask;
|
|
+ retrt->er_said = said;
|
|
+ retrt->er_pid = pid;
|
|
+ retrt->er_count = 0;
|
|
+ retrt->er_lasttime = jiffies/HZ;
|
|
+
|
|
+ {
|
|
+ /* this is because gcc 3. doesn't like cast's as lvalues */
|
|
+ struct rjtentry *rje = (struct rjtentry *)&(retrt->er_rjt);
|
|
+ caddr_t er = (caddr_t)&(retrt->er_eaddr);
|
|
+
|
|
+ rje->rd_nodes->rj_key= er;
|
|
+ }
|
|
+
|
|
+ if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
|
|
+ int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
|
|
+
|
|
+ retrt->er_ident_s.type = ident_s->type;
|
|
+ retrt->er_ident_s.id = ident_s->id;
|
|
+ retrt->er_ident_s.len = ident_s->len;
|
|
+ if(data_len) {
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_makeroute: "
|
|
+ "attempting to allocate %u bytes for ident_s.\n",
|
|
+ data_len);
|
|
+ if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
|
|
+ kfree(retrt);
|
|
+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
|
|
+ return ENOMEM;
|
|
+ }
|
|
+ memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
|
|
+ } else {
|
|
+ retrt->er_ident_s.data = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
|
|
+ int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
|
|
+
|
|
+ retrt->er_ident_d.type = ident_d->type;
|
|
+ retrt->er_ident_d.id = ident_d->id;
|
|
+ retrt->er_ident_d.len = ident_d->len;
|
|
+ if(data_len) {
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_makeroute: "
|
|
+ "attempting to allocate %u bytes for ident_d.\n",
|
|
+ data_len);
|
|
+ if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
|
|
+ if (retrt->er_ident_s.data)
|
|
+ kfree(retrt->er_ident_s.data);
|
|
+ kfree(retrt);
|
|
+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
|
|
+ return ENOMEM;
|
|
+ }
|
|
+ memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
|
|
+ } else {
|
|
+ retrt->er_ident_d.data = NULL;
|
|
+ }
|
|
+ }
|
|
+ retrt->er_first = skb;
|
|
+ retrt->er_last = NULL;
|
|
+
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_makeroute: "
|
|
+ "calling rj_addroute now\n");
|
|
+
|
|
+ spin_lock_bh(&eroute_lock);
|
|
+
|
|
+ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
|
|
+ rnh, retrt->er_rjt.rd_nodes);
|
|
+
|
|
+ spin_unlock_bh(&eroute_lock);
|
|
+
|
|
+ if(error) {
|
|
+ sa_len = satot(&said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_makeroute: "
|
|
+ "rj_addroute not able to insert eroute for SA:%s (error:%d)\n",
|
|
+ sa_len ? sa : " (error)", error);
|
|
+ if (retrt->er_ident_s.data)
|
|
+ kfree(retrt->er_ident_s.data);
|
|
+ if (retrt->er_ident_d.data)
|
|
+ kfree(retrt->er_ident_d.data);
|
|
+
|
|
+ kfree(retrt);
|
|
+
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if (debug_eroute) {
|
|
+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
|
|
+/*
|
|
+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+*/
|
|
+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa));
|
|
+
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_makeroute: "
|
|
+ "pid=%05d "
|
|
+ "count=%10d "
|
|
+ "lasttime=%6d "
|
|
+ "%-18s -> %-18s => %s\n",
|
|
+ retrt->er_pid,
|
|
+ retrt->er_count,
|
|
+ (int)(jiffies/HZ - retrt->er_lasttime),
|
|
+ buf1,
|
|
+ buf2,
|
|
+ sa_len ? sa : " (error)");
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_makeroute: "
|
|
+ "succeeded.\n");
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+struct eroute *
|
|
+ipsec_findroute(struct sockaddr_encap *eaddr)
|
|
+{
|
|
+ struct radij_node *rn;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
|
|
+
|
|
+ if (debug_radij & DB_RJ_FINDROUTE) {
|
|
+ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:ipsec_findroute: "
|
|
+ "%s:%d->%s:%d %d\n",
|
|
+ buf1, ntohs(eaddr->sen_sport),
|
|
+ buf2, ntohs(eaddr->sen_dport),
|
|
+ eaddr->sen_proto);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ rn = rj_match((caddr_t)eaddr, rnh);
|
|
+ if(rn) {
|
|
+ KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
|
|
+ "klips_debug:ipsec_findroute: "
|
|
+ "found, points to proto=%d, spi=%x, dst=%x.\n",
|
|
+ ((struct eroute*)rn)->er_said.proto,
|
|
+ ntohl(((struct eroute*)rn)->er_said.spi),
|
|
+ ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr));
|
|
+ }
|
|
+ return (struct eroute *)rn;
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_PROC_FS
|
|
+/** ipsec_rj_walker_procprint: print one line of eroute table output.
|
|
+ *
|
|
+ * Theoretical BUG: if w->length is less than the length
|
|
+ * of some line we should produce, that line will never
|
|
+ * be finished. In effect, the "file" will stop part way
|
|
+ * through that line.
|
|
+ */
|
|
+int
|
|
+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
|
|
+{
|
|
+ struct eroute *ro = (struct eroute *)rn;
|
|
+ struct rjtentry *rd = (struct rjtentry *)rn;
|
|
+ struct wsbuf *w = (struct wsbuf *)w0;
|
|
+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
|
|
+ char buf3[16];
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len, buf_len;
|
|
+ struct sockaddr_encap *key, *mask;
|
|
+
|
|
+ KLIPS_PRINT(debug_radij,
|
|
+ "klips_debug:ipsec_rj_walker_procprint: "
|
|
+ "rn=0p%p, w0=0p%p\n",
|
|
+ rn,
|
|
+ w0);
|
|
+ if (rn->rj_b >= 0) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ key = rd_key(rd);
|
|
+ mask = rd_mask(rd);
|
|
+
|
|
+ if (key == NULL || mask == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ if(key->sen_sport != 0) {
|
|
+ sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
|
|
+ }
|
|
+
|
|
+ buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ if(key->sen_dport != 0) {
|
|
+ sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
|
|
+ }
|
|
+
|
|
+ buf3[0]='\0';
|
|
+ if(key->sen_proto != 0) {
|
|
+ sprintf(buf3, ":%d", key->sen_proto);
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa));
|
|
+ w->len += ipsec_snprintf(w->buffer + w->len,
|
|
+ w->length - w->len,
|
|
+ "%-10d "
|
|
+ "%-18s -> %-18s => %s%s\n",
|
|
+ ro->er_count,
|
|
+ buf1,
|
|
+ buf2,
|
|
+ sa_len ? sa : " (error)",
|
|
+ buf3);
|
|
+
|
|
+ {
|
|
+ /* snprintf can only fill the last character with NUL
|
|
+ * so the maximum useful character is w->length-1.
|
|
+ * However, if w->length == 0, we cannot go back.
|
|
+ * (w->length surely cannot be negative.)
|
|
+ */
|
|
+ int max_content = w->length > 0? w->length-1 : 0;
|
|
+
|
|
+ if (w->len >= max_content) {
|
|
+ /* we've done all that can fit -- stop treewalking */
|
|
+ w->len = max_content; /* truncate crap */
|
|
+ return -ENOBUFS;
|
|
+ } else {
|
|
+ const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
|
|
+
|
|
+ if (pos <= w->offset) {
|
|
+ /* all is before first interesting character:
|
|
+ * discard, but note where we are.
|
|
+ */
|
|
+ w->len = 0;
|
|
+ w->begin = pos;
|
|
+ }
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+#endif /* CONFIG_PROC_FS */
|
|
+
|
|
+int
|
|
+ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
|
|
+{
|
|
+ struct eroute *ro;
|
|
+ struct rjtentry *rd = (struct rjtentry *)rn;
|
|
+ struct radij_node *rn2;
|
|
+ int error;
|
|
+ struct sockaddr_encap *key, *mask;
|
|
+
|
|
+ key = rd_key(rd);
|
|
+ mask = rd_mask(rd);
|
|
+
|
|
+ if(!key || !mask) {
|
|
+ return -ENODATA;
|
|
+ }
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_radij) {
|
|
+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
|
|
+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ KLIPS_PRINT(debug_radij,
|
|
+ "klips_debug:ipsec_rj_walker_delete: "
|
|
+ "deleting: %s -> %s\n",
|
|
+ buf1,
|
|
+ buf2);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ if((error = rj_delete(key, mask, rnh, &rn2))) {
|
|
+ KLIPS_PRINT(debug_radij,
|
|
+ "klips_debug:ipsec_rj_walker_delete: "
|
|
+ "rj_delete failed with error=%d.\n", error);
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ if(rn2 != rn) {
|
|
+ printk("klips_debug:ipsec_rj_walker_delete: "
|
|
+ "tried to delete a different node?!? This should never happen!\n");
|
|
+ }
|
|
+
|
|
+ ro = (struct eroute *)rn;
|
|
+
|
|
+ if (ro->er_ident_s.data)
|
|
+ kfree(ro->er_ident_s.data);
|
|
+ if (ro->er_ident_d.data)
|
|
+ kfree(ro->er_ident_d.data);
|
|
+
|
|
+ memset((caddr_t)rn, 0, sizeof (struct eroute));
|
|
+ kfree(rn);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_radij.c,v $
|
|
+ * Revision 1.73.2.1 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.73 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.72 2004/12/03 21:25:57 mcr
|
|
+ * compile time fixes for running on 2.6.
|
|
+ * still experimental.
|
|
+ *
|
|
+ * Revision 1.71 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.70 2004/04/25 21:10:52 ken
|
|
+ * Pull in dhr's changes from FreeS/WAN 2.06
|
|
+ *
|
|
+ * Revision 1.69 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.68 2004/03/28 20:27:20 paul
|
|
+ * Included tested and confirmed fixes mcr made and dhr verified for
|
|
+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
|
|
+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
|
|
+ * dhr. (thanks dhr!)
|
|
+ *
|
|
+ * Revision 1.67.4.1 2004/04/05 04:30:46 mcr
|
|
+ * patches for alg-branch to compile/work with 2.x openswan
|
|
+ *
|
|
+ * Revision 1.67 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.66.24.2 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.66.24.1 2003/09/21 13:59:56 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.66 2002/10/12 23:11:53 dhr
|
|
+ *
|
|
+ * [KenB + DHR] more 64-bit cleanup
|
|
+ *
|
|
+ * Revision 1.65 2002/09/20 05:01:40 rgb
|
|
+ * Added memory allocation debugging.
|
|
+ *
|
|
+ * Revision 1.64 2002/05/31 01:46:05 mcr
|
|
+ * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute
|
|
+ * as requested in PR#14.
|
|
+ *
|
|
+ * Revision 1.63 2002/05/23 07:14:11 rgb
|
|
+ * Cleaned up %p variants to 0p%p for test suite cleanup.
|
|
+ *
|
|
+ * Revision 1.62 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.61 2002/04/24 07:36:29 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_radij.c,v
|
|
+ *
|
|
+ * Revision 1.60 2002/02/19 23:59:45 rgb
|
|
+ * Removed redundant compiler directives.
|
|
+ *
|
|
+ * Revision 1.59 2002/02/06 04:13:47 mcr
|
|
+ * missing #ifdef CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.58 2002/01/29 17:17:56 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.57 2002/01/29 04:00:52 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.56 2002/01/29 02:13:17 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.55 2001/11/26 09:23:48 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.53.2.1 2001/09/25 02:26:32 mcr
|
|
+ * headers adjusted for new usage.
|
|
+ *
|
|
+ * Revision 1.54 2001/10/18 04:45:20 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/freeswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.53 2001/09/19 17:19:40 rgb
|
|
+ * Debug output bugfix for NetCelo's PF_KEY ident patch.
|
|
+ *
|
|
+ * Revision 1.52 2001/09/19 16:33:37 rgb
|
|
+ * Temporarily disable ident fields to /proc/net/ipsec_eroute.
|
|
+ *
|
|
+ * Revision 1.51 2001/09/15 16:24:04 rgb
|
|
+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
|
|
+ *
|
|
+ * Revision 1.50 2001/09/14 16:58:36 rgb
|
|
+ * Added support for storing the first and last packets through a HOLD.
|
|
+ *
|
|
+ * Revision 1.49 2001/09/08 21:13:32 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.48 2001/06/15 04:12:56 rgb
|
|
+ * Fixed kernel memory allocation error return code polarity bug.
|
|
+ *
|
|
+ * Revision 1.47 2001/06/14 19:35:09 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.46 2001/06/08 08:47:18 rgb
|
|
+ * Fixed for debug disabled.
|
|
+ *
|
|
+ * Revision 1.45 2001/05/27 06:12:11 rgb
|
|
+ * Added structures for pid, packet count and last access time to eroute.
|
|
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
|
|
+ *
|
|
+ * Revision 1.44 2001/05/03 19:41:01 rgb
|
|
+ * Initialise error return variable.
|
|
+ * Use more appropriate return value for ipsec_rj_walker_delete().
|
|
+ *
|
|
+ * Revision 1.43 2001/02/27 22:24:54 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.42 2001/02/27 06:21:57 rgb
|
|
+ * Added findroute success instrumentation.
|
|
+ *
|
|
+ * Revision 1.41 2000/11/06 04:32:08 rgb
|
|
+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
|
|
+ *
|
|
+ * Revision 1.40 2000/09/08 19:12:56 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.39 2000/08/30 05:25:20 rgb
|
|
+ * Correct debug text in ipsec_breakroute() from incorrect
|
|
+ * "ipsec_callback".
|
|
+ *
|
|
+ * Revision 1.38 2000/07/28 14:58:31 rgb
|
|
+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
|
|
+ *
|
|
+ * Revision 1.37 2000/03/16 14:02:50 rgb
|
|
+ * Fixed debug scope to enable compilation with debug off.
|
|
+ *
|
|
+ * Revision 1.36 2000/01/21 06:14:46 rgb
|
|
+ * Added debugging text to ipsec_rj_walker_delete().
|
|
+ * Set return code to negative for consistency.
|
|
+ *
|
|
+ * Revision 1.35 1999/11/23 23:05:24 rgb
|
|
+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
|
|
+ *
|
|
+ * Revision 1.34 1999/11/18 04:13:56 rgb
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
|
|
+ *
|
|
+ * Revision 1.33 1999/11/17 15:53:39 rgb
|
|
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
|
|
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
|
|
+ * klips/net/ipsec/Makefile.
|
|
+ *
|
|
+ * Revision 1.32 1999/10/26 13:58:33 rgb
|
|
+ * Put spinlock flags variable declaration outside the debug compiler
|
|
+ * directive to enable compilation with debug shut off.
|
|
+ *
|
|
+ * Revision 1.31 1999/10/15 22:13:29 rgb
|
|
+ * Clean out cruft.
|
|
+ * Align /proc/net/ipsec_eroute output for easier readability.
|
|
+ * Fix double linefeed in radij debug output.
|
|
+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
|
|
+ *
|
|
+ * Revision 1.30 1999/10/08 18:37:33 rgb
|
|
+ * Fix end-of-line spacing to sate whining PHMs.
|
|
+ *
|
|
+ * Revision 1.29 1999/10/03 18:52:45 rgb
|
|
+ * Spinlock support for 2.0.xx.
|
|
+ * Dumb return code spin_unlock fix.
|
|
+ *
|
|
+ * Revision 1.28 1999/10/01 16:22:24 rgb
|
|
+ * Switch from assignment init. to functional init. of spinlocks.
|
|
+ *
|
|
+ * Revision 1.27 1999/10/01 15:44:53 rgb
|
|
+ * Move spinlock header include to 2.1> scope.
|
|
+ *
|
|
+ * Revision 1.26 1999/10/01 00:01:23 rgb
|
|
+ * Added eroute structure locking.
|
|
+ *
|
|
+ * Revision 1.25 1999/06/10 16:07:30 rgb
|
|
+ * Silence delete eroute on no debug.
|
|
+ *
|
|
+ * Revision 1.24 1999/05/09 03:25:36 rgb
|
|
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
|
|
+ *
|
|
+ * Revision 1.23 1999/05/05 22:02:31 rgb
|
|
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
|
|
+ *
|
|
+ * Revision 1.22 1999/04/29 15:17:23 rgb
|
|
+ * Add return values to init and cleanup functions.
|
|
+ * Add sanity checking for null pointer arguments.
|
|
+ *
|
|
+ * Revision 1.21 1999/04/11 00:28:58 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.20 1999/04/06 04:54:26 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.19 1999/02/17 16:50:35 rgb
|
|
+ * Clean out unused cruft.
|
|
+ * Consolidate for space and speed efficiency.
|
|
+ * Convert DEBUG_IPSEC to KLIPS_PRINT
|
|
+ *
|
|
+ * Revision 1.18 1999/01/22 06:22:06 rgb
|
|
+ * Cruft clean-out.
|
|
+ * 64-bit clean-up.
|
|
+ *
|
|
+ * Revision 1.17 1998/12/02 03:09:39 rgb
|
|
+ * Clean up debug printing conditionals to compile with debugging off.
|
|
+ *
|
|
+ * Revision 1.16 1998/12/01 13:49:39 rgb
|
|
+ * Wrap version info printing in debug switches.
|
|
+ *
|
|
+ * Revision 1.15 1998/11/30 13:22:54 rgb
|
|
+ * Rationalised all the klips kernel file headers. They are much shorter
|
|
+ * now and won't conflict under RH5.2.
|
|
+ *
|
|
+ * Revision 1.14 1998/10/31 06:48:17 rgb
|
|
+ * Fixed up comments in #endif directives.
|
|
+ *
|
|
+ * Revision 1.13 1998/10/27 13:48:09 rgb
|
|
+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
|
|
+ * Fixed less(1) truncated output bug.
|
|
+ * Code clean-up.
|
|
+ *
|
|
+ * Revision 1.12 1998/10/25 02:41:36 rgb
|
|
+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
|
|
+ * argument to be able to transmit more infomation about errors.
|
|
+ * Fix cut-and-paste debug statement identifier.
|
|
+ *
|
|
+ * Revision 1.11 1998/10/22 06:45:39 rgb
|
|
+ * Cleaned up cruft.
|
|
+ * Convert to use satoa for printk.
|
|
+ *
|
|
+ * Revision 1.10 1998/10/19 14:44:28 rgb
|
|
+ * Added inclusion of freeswan.h.
|
|
+ * sa_id structure implemented and used: now includes protocol.
|
|
+ *
|
|
+ * Revision 1.9 1998/10/09 04:30:52 rgb
|
|
+ * Added 'klips_debug' prefix to all klips printk debug statements.
|
|
+ * Deleted old commented out cruft.
|
|
+ *
|
|
+ * Revision 1.8 1998/08/06 17:24:23 rgb
|
|
+ * Fix addrtoa return code bug from stale manpage advice preventing packets
|
|
+ * from being erouted.
|
|
+ *
|
|
+ * Revision 1.7 1998/08/06 07:44:59 rgb
|
|
+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
|
|
+ * ended up in nothing being printed.
|
|
+ *
|
|
+ * Revision 1.6 1998/08/05 22:16:41 rgb
|
|
+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
|
|
+ *
|
|
+ * Revision 1.5 1998/07/29 20:38:44 rgb
|
|
+ * Debug and fix subnettoa and addrtoa output.
|
|
+ *
|
|
+ * Revision 1.4 1998/07/28 00:02:39 rgb
|
|
+ * Converting to exclusive use of addrtoa.
|
|
+ * Fix eroute delete.
|
|
+ *
|
|
+ * Revision 1.3 1998/07/14 18:21:26 rgb
|
|
+ * Add function to clear the eroute table.
|
|
+ *
|
|
+ * Revision 1.2 1998/06/23 02:59:14 rgb
|
|
+ * Added debugging output to eroute add/delete routines.
|
|
+ *
|
|
+ * Revision 1.9 1998/06/18 21:29:06 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
|
|
+ * build scripts happier in presence of symbolic links
|
|
+ *
|
|
+ * Revision 1.8 1998/06/05 02:32:26 rgb
|
|
+ * Fix spi ntoh kernel debug output.
|
|
+ *
|
|
+ * Revision 1.7 1998/05/25 20:30:37 rgb
|
|
+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
|
|
+ *
|
|
+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
|
|
+ * add ipsec_rj_walker_delete.
|
|
+ *
|
|
+ * Revision 1.6 1998/05/21 13:08:57 rgb
|
|
+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
|
|
+ * information is available for printout.
|
|
+ *
|
|
+ * Revision 1.5 1998/05/18 21:35:55 rgb
|
|
+ * Clean up output for numerical consistency and readability. Zero freed
|
|
+ * eroute memory.
|
|
+ *
|
|
+ * Revision 1.4 1998/04/21 21:28:58 rgb
|
|
+ * Rearrange debug switches to change on the fly debug output from user
|
|
+ * space. Only kernel changes checked in at this time. radij.c was also
|
|
+ * changed to temporarily remove buggy debugging code in rj_delete causing
|
|
+ * an OOPS and hence, netlink device open errors.
|
|
+ *
|
|
+ * Revision 1.3 1998/04/14 17:30:39 rgb
|
|
+ * Fix up compiling errors for radij tree memory reclamation.
|
|
+ *
|
|
+ * Revision 1.2 1998/04/12 22:03:23 rgb
|
|
+ * Updated ESP-3DES-HMAC-MD5-96,
|
|
+ * ESP-DES-HMAC-MD5-96,
|
|
+ * AH-HMAC-MD5-96,
|
|
+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
|
|
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
|
|
+ *
|
|
+ * Fixed eroute references in /proc/net/ipsec*.
|
|
+ *
|
|
+ * Started to patch module unloading memory leaks in ipsec_netlink and
|
|
+ * radij tree unloading.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:10 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * No changes.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:39:04 ji
|
|
+ * Minor cleanups.
|
|
+ * Rationalized debugging code.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,2317 @@
|
|
+/*
|
|
+ * receive code
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998-2003 Richard Guy Briggs.
|
|
+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.171.2.11 2007/04/28 20:46:40 paul Exp $";
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+
|
|
+#include <net/tcp.h>
|
|
+#include <net/udp.h>
|
|
+#include <linux/skbuff.h>
|
|
+#include <openswan.h>
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#include "openswan/ipsec_kern24.h"
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+
|
|
+#include "openswan/ipsec_auth.h"
|
|
+
|
|
+#include "openswan/ipsec_esp.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_AH
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#endif /* CONFIG_KLIPS_AH */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+#include "openswan/ipsec_ipcomp.h"
|
|
+#endif /* CONFIG_KLIPS_COMP */
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#include "openswan/ipsec_alg.h"
|
|
+#include "openswan/ipsec_kern24.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int debug_rcv = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+int sysctl_ipsec_inbound_policy_check = 1;
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+#include <linux/udp.h>
|
|
+#endif
|
|
+
|
|
+/* This is a private use protocol, and AT&T should be ashamed. They should have
|
|
+ * used protocol # 59, which is "no next header" instead of 0xFE.
|
|
+ */
|
|
+#ifndef IPPROTO_ATT_HEARTBEAT
|
|
+#define IPPROTO_ATT_HEARTBEAT 0xFE
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * Check-replay-window routine, adapted from the original
|
|
+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
|
|
+ *
|
|
+ * This is a routine that implements a 64 packet window. This is intend-
|
|
+ * ed on being an implementation sample.
|
|
+ */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
|
|
+{
|
|
+ __u32 diff;
|
|
+
|
|
+ if (ipsp->ips_replaywin == 0) /* replay shut off */
|
|
+ return 1;
|
|
+ if (seq == 0)
|
|
+ return 0; /* first == 0 or wrapped */
|
|
+
|
|
+ /* new larger sequence number */
|
|
+ if (seq > ipsp->ips_replaywin_lastseq) {
|
|
+ return 1; /* larger is good */
|
|
+ }
|
|
+ diff = ipsp->ips_replaywin_lastseq - seq;
|
|
+
|
|
+ /* too old or wrapped */ /* if wrapped, kill off SA? */
|
|
+ if (diff >= ipsp->ips_replaywin) {
|
|
+ return 0;
|
|
+ }
|
|
+ /* this packet already seen */
|
|
+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
|
|
+ return 0;
|
|
+ return 1; /* out of order but good */
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
|
|
+{
|
|
+ __u32 diff;
|
|
+
|
|
+ if (ipsp->ips_replaywin == 0) /* replay shut off */
|
|
+ return 1;
|
|
+ if (seq == 0)
|
|
+ return 0; /* first == 0 or wrapped */
|
|
+
|
|
+ /* new larger sequence number */
|
|
+ if (seq > ipsp->ips_replaywin_lastseq) {
|
|
+ diff = seq - ipsp->ips_replaywin_lastseq;
|
|
+
|
|
+ /* In win, set bit for this pkt */
|
|
+ if (diff < ipsp->ips_replaywin)
|
|
+ ipsp->ips_replaywin_bitmap =
|
|
+ (ipsp->ips_replaywin_bitmap << diff) | 1;
|
|
+ else
|
|
+ /* This packet has way larger seq num */
|
|
+ ipsp->ips_replaywin_bitmap = 1;
|
|
+
|
|
+ if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
|
|
+ ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
|
|
+ }
|
|
+ ipsp->ips_replaywin_lastseq = seq;
|
|
+ return 1; /* larger is good */
|
|
+ }
|
|
+ diff = ipsp->ips_replaywin_lastseq - seq;
|
|
+
|
|
+ /* too old or wrapped */ /* if wrapped, kill off SA? */
|
|
+ if (diff >= ipsp->ips_replaywin) {
|
|
+/*
|
|
+ if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
|
|
+ ipsec_sa_delchain(ipsp);
|
|
+ }
|
|
+*/
|
|
+ return 0;
|
|
+ }
|
|
+ /* this packet already seen */
|
|
+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
|
|
+ return 0;
|
|
+ ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */
|
|
+ return 1; /* out of order but good */
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+struct auth_alg ipsec_rcv_md5[]={
|
|
+ {osMD5Init, osMD5Update, osMD5Final, AHMD596_ALEN}
|
|
+};
|
|
+
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+struct auth_alg ipsec_rcv_sha1[]={
|
|
+ {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
|
|
+};
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+
|
|
+/*
|
|
+ * decapsulate a single layer of the system
|
|
+ *
|
|
+ * the following things should be setup to enter this function.
|
|
+ *
|
|
+ * irs->stats == stats structure (or NULL)
|
|
+ * irs->ipp = IP header.
|
|
+ * irs->len = total length of packet
|
|
+ * skb->nh.iph = ipp;
|
|
+ * skb->h.raw = start of payload
|
|
+ * irs->ipsp = NULL.
|
|
+ * irs->iphlen = N/A = is recalculated.
|
|
+ * irs->ilen = 0;
|
|
+ * irs->authlen = 0;
|
|
+ * irs->authfuncs = NULL;
|
|
+ * irs->skb = the skb;
|
|
+ *
|
|
+ * proto_funcs should be from ipsec_esp.c, ipsec_ah.c or ipsec_ipcomp.c.
|
|
+ *
|
|
+ */
|
|
+enum ipsec_rcv_value
|
|
+ipsec_rcv_decap_once(struct ipsec_rcv_state *irs
|
|
+ , struct xform_functions *proto_funcs)
|
|
+{
|
|
+ int iphlen;
|
|
+ __u8 proto;
|
|
+ struct in_addr ipsaddr;
|
|
+ struct in_addr ipdaddr;
|
|
+ int replay = 0; /* replay value in AH or ESP packet */
|
|
+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
|
|
+ struct ipsec_sa *newipsp;
|
|
+ struct iphdr *ipp;
|
|
+ struct sk_buff *skb;
|
|
+ struct ipsec_alg_auth *ixt_a=NULL;
|
|
+
|
|
+ skb = irs->skb;
|
|
+ irs->len = skb->len;
|
|
+ ipp = irs->ipp;
|
|
+ proto = ipp->protocol;
|
|
+ ipsaddr.s_addr = ipp->saddr;
|
|
+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
|
|
+ ipdaddr.s_addr = ipp->daddr;
|
|
+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
|
|
+
|
|
+ iphlen = ipp->ihl << 2;
|
|
+ irs->iphlen=iphlen;
|
|
+ ipp->check = 0; /* we know the sum is good */
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv_decap_once: "
|
|
+ "decap (%d) from %s -> %s\n",
|
|
+ proto, irs->ipsaddr_txt, irs->ipdaddr_txt);
|
|
+
|
|
+ /*
|
|
+ * Find tunnel control block and (indirectly) call the
|
|
+ * appropriate tranform routine. The resulting sk_buf
|
|
+ * is a valid IP packet ready to go through input processing.
|
|
+ */
|
|
+
|
|
+ irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr;
|
|
+ irs->said.dst.u.v4.sin_family = AF_INET;
|
|
+
|
|
+ /* note: rcv_checks set up the said.spi value, if appropriate */
|
|
+ if(proto_funcs->rcv_checks) {
|
|
+ enum ipsec_rcv_value retval =
|
|
+ (*proto_funcs->rcv_checks)(irs, skb);
|
|
+
|
|
+ if(retval < 0) {
|
|
+ return retval;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ irs->said.proto = proto;
|
|
+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
|
|
+ if(irs->sa_len == 0) {
|
|
+ strcpy(irs->sa, "(error)");
|
|
+ }
|
|
+
|
|
+ newipsp = ipsec_sa_getbyid(&irs->said);
|
|
+ if (newipsp == NULL) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_SAIDNOTFOUND;
|
|
+ }
|
|
+
|
|
+ /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having
|
|
+ * incremented the refcount, why in the world would we decrement it
|
|
+ * here? */
|
|
+ /* ipsec_sa_put(irs->ipsp);*/ /* incomplete */
|
|
+
|
|
+ /* If it is in larval state, drop the packet, we cannot process yet. */
|
|
+ if(newipsp->ips_state == SADB_SASTATE_LARVAL) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ ipsec_sa_put(newipsp);
|
|
+ return IPSEC_RCV_SAIDNOTLIVE;
|
|
+ }
|
|
+
|
|
+ if(newipsp->ips_state == SADB_SASTATE_DEAD) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ ipsec_sa_put(newipsp);
|
|
+ return IPSEC_RCV_SAIDNOTLIVE;
|
|
+ }
|
|
+
|
|
+ if(sysctl_ipsec_inbound_policy_check) {
|
|
+ if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)",
|
|
+ irs->ipsaddr_txt);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ ipsec_sa_put(newipsp);
|
|
+ return IPSEC_RCV_FAILEDINBOUND;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)",
|
|
+ irs->ipsaddr_txt);
|
|
+
|
|
+ /*
|
|
+ * at this point, we have looked up a new SA, and we want to make sure that if this
|
|
+ * isn't the first SA in the list, that the previous SA actually points at this one.
|
|
+ */
|
|
+ if(irs->ipsp) {
|
|
+ if(irs->ipsp->ips_inext != newipsp) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ ipsec_sa_put(newipsp);
|
|
+ return IPSEC_RCV_FAILEDINBOUND;
|
|
+ }
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s grouping from previous SA is OK.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s First SA in group.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ }
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ if (proto == IPPROTO_ESP) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "natt_type=%u tdbp->ips_natt_type=%u : %s\n",
|
|
+ irs->natt_type, newipsp->ips_natt_type,
|
|
+ (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad");
|
|
+ if (irs->natt_type != newipsp->ips_natt_type) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s does not agree with expected NAT-T policy.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ ipsec_sa_put(newipsp);
|
|
+ return IPSEC_RCV_FAILEDINBOUND;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ /* okay, SA checks out, so free any previous SA, and record a new one*/
|
|
+
|
|
+ if(irs->ipsp) {
|
|
+ ipsec_sa_put(irs->ipsp);
|
|
+ }
|
|
+ irs->ipsp=newipsp;
|
|
+
|
|
+ /* note that the outer code will free the irs->ipsp
|
|
+ if there is an error */
|
|
+
|
|
+
|
|
+ /* now check the lifetimes */
|
|
+ if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes",
|
|
+ irs->sa, ipsec_life_countbased, ipsec_incoming,
|
|
+ irs->ipsp) == ipsec_life_harddied ||
|
|
+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",
|
|
+ irs->sa, ipsec_life_timebased, ipsec_incoming,
|
|
+ irs->ipsp) == ipsec_life_harddied ||
|
|
+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",
|
|
+ irs->sa, ipsec_life_timebased, ipsec_incoming,
|
|
+ irs->ipsp) == ipsec_life_harddied ||
|
|
+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",
|
|
+ irs->sa, ipsec_life_countbased, ipsec_incoming,
|
|
+ irs->ipsp) == ipsec_life_harddied) {
|
|
+ ipsec_sa_delchain(irs->ipsp);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv_decap_once: "
|
|
+ "decap (%d) failed lifetime check\n",
|
|
+ proto);
|
|
+
|
|
+ return IPSEC_RCV_LIFETIMEFAILED;
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ /*
|
|
+ * This is removed for some reasons:
|
|
+ * 1) it needs to happen *after* authentication.
|
|
+ * 2) do we really care, if it authenticates, if it came
|
|
+ * from the wrong location?
|
|
+ * 3) the NAT_KA messages in IKE will also get to pluto
|
|
+ * and it will figure out that stuff has moved.
|
|
+ * 4) the 2.6 udp-esp encap function does not pass us
|
|
+ * the originating port number, and I can't tell
|
|
+ * if skb->sk is guaranteed to be valid here.
|
|
+ * 2005-04-16: mcr@xelerance.com
|
|
+ */
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ /*
|
|
+ *
|
|
+ * XXX we should ONLY update pluto if the SA passes all checks,
|
|
+ * which we clearly do not now.
|
|
+ */
|
|
+ if ((irs->natt_type) &&
|
|
+ ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) ||
|
|
+ (irs->natt_sport != newipsp->ips_natt_sport)
|
|
+ )) {
|
|
+ struct sockaddr sipaddr;
|
|
+ struct sockaddr_in *psin = (struct sockaddr_in*)(newipsp->ips_addr_s);
|
|
+
|
|
+ /** Advertise NAT-T addr change to pluto **/
|
|
+ sipaddr.sa_family = AF_INET;
|
|
+ ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr;
|
|
+ ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport);
|
|
+ pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport);
|
|
+
|
|
+ /**
|
|
+ * Then allow or block packet depending on
|
|
+ * sysctl_ipsec_inbound_policy_check.
|
|
+ *
|
|
+ * In all cases, pluto will update SA if new mapping is
|
|
+ * accepted.
|
|
+ */
|
|
+ if (sysctl_ipsec_inbound_policy_check) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s, src=%s:%u of pkt does not agree with expected "
|
|
+ "SA source address [%08x:%u] (notifying pluto of change).\n",
|
|
+ irs->sa_len ? irs->sa : " (error)",
|
|
+ irs->ipsaddr_txt, irs->natt_sport,
|
|
+ psin->sin_addr.s_addr,
|
|
+ newipsp->ips_natt_sport);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ ipsec_sa_put(newipsp);
|
|
+ return IPSEC_RCV_FAILEDINBOUND;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+ irs->authfuncs=NULL;
|
|
+
|
|
+ /* authenticate, if required */
|
|
+ if ((ixt_a=irs->ipsp->ips_alg_auth)) {
|
|
+ irs->authlen = AHHMAC_HASHLEN;
|
|
+ irs->authfuncs = NULL;
|
|
+ irs->ictx = NULL;
|
|
+ irs->octx = NULL;
|
|
+ irs->ictx_len = 0;
|
|
+ irs->octx_len = 0;
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "authalg=%d authlen=%d\n",
|
|
+ irs->ipsp->ips_authalg,
|
|
+ irs->authlen);
|
|
+ } else
|
|
+ switch(irs->ipsp->ips_authalg) {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ case AH_MD5:
|
|
+ irs->authlen = AHHMAC_HASHLEN;
|
|
+ irs->authfuncs = ipsec_rcv_md5;
|
|
+ irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
|
|
+ irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
|
|
+ irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
|
|
+ irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ case AH_SHA:
|
|
+ irs->authlen = AHHMAC_HASHLEN;
|
|
+ irs->authfuncs = ipsec_rcv_sha1;
|
|
+ irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
|
|
+ irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
|
|
+ irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
|
|
+ irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ case AH_NONE:
|
|
+ irs->authlen = 0;
|
|
+ irs->authfuncs = NULL;
|
|
+ irs->ictx = NULL;
|
|
+ irs->octx = NULL;
|
|
+ irs->ictx_len = 0;
|
|
+ irs->octx_len = 0;
|
|
+ break;
|
|
+ default:
|
|
+ irs->ipsp->ips_errs.ips_alg_errs += 1;
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ return IPSEC_RCV_BADAUTH;
|
|
+ }
|
|
+
|
|
+ /* ilen counts number of bytes in ESP portion */
|
|
+ irs->ilen = ((skb->data + skb->len) - skb->h.raw) - irs->authlen;
|
|
+ if(irs->ilen <= 0) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "runt %s packet with no data, dropping.\n",
|
|
+ (proto == IPPROTO_ESP ? "esp" : "ah"));
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_BADLEN;
|
|
+ }
|
|
+
|
|
+ if(irs->authfuncs || ixt_a) {
|
|
+ unsigned char *authenticator = NULL;
|
|
+
|
|
+ if(proto_funcs->rcv_setup_auth) {
|
|
+ enum ipsec_rcv_value retval
|
|
+ = (*proto_funcs->rcv_setup_auth)(irs, skb,
|
|
+ &replay,
|
|
+ &authenticator);
|
|
+ if(retval < 0) {
|
|
+ return retval;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(!authenticator) {
|
|
+ irs->ipsp->ips_errs.ips_auth_errs += 1;
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_BADAUTH;
|
|
+ }
|
|
+
|
|
+ if(!ipsec_checkreplaywindow(irs->ipsp, replay)) {
|
|
+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "duplicate frame from %s, packet dropped\n",
|
|
+ irs->ipsaddr_txt);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_REPLAYFAILED;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * verify authenticator
|
|
+ */
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "encalg = %d, authalg = %d.\n",
|
|
+ irs->ipsp->ips_encalg,
|
|
+ irs->ipsp->ips_authalg);
|
|
+
|
|
+ /* calculate authenticator */
|
|
+ if(proto_funcs->rcv_calc_auth == NULL) {
|
|
+ return IPSEC_RCV_BADAUTH;
|
|
+ }
|
|
+ (*proto_funcs->rcv_calc_auth)(irs, skb);
|
|
+
|
|
+ if (memcmp(irs->hash, authenticator, irs->authlen)) {
|
|
+ irs->ipsp->ips_errs.ips_auth_errs += 1;
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
|
|
+ irs->ipsaddr_txt,
|
|
+ ntohl(*(__u32*)&irs->hash[0]),
|
|
+ ntohl(*(__u32*)&irs->hash[4]),
|
|
+ ntohl(*(__u32*)&irs->hash[8]),
|
|
+ ntohl(*(__u32*)authenticator),
|
|
+ ntohl(*((__u32*)authenticator + 1)),
|
|
+ ntohl(*((__u32*)authenticator + 2)));
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_AUTHFAILED;
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "authentication successful.\n");
|
|
+ }
|
|
+
|
|
+ /* Crypto hygiene: clear memory used to calculate autheticator.
|
|
+ * The length varies with the algorithm.
|
|
+ */
|
|
+ memset(irs->hash, 0, irs->authlen);
|
|
+
|
|
+ /* If the sequence number == 0, expire SA, it had rolled */
|
|
+ if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) {
|
|
+ ipsec_sa_delchain(irs->ipsp);
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "replay window counter rolled, expiring SA.\n");
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_REPLAYROLLED;
|
|
+ }
|
|
+
|
|
+ /* now update the replay counter */
|
|
+ if (!ipsec_updatereplaywindow(irs->ipsp, replay)) {
|
|
+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "duplicate frame from %s, packet dropped\n",
|
|
+ irs->ipsaddr_txt);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_REPLAYROLLED;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(proto_funcs->rcv_decrypt) {
|
|
+ enum ipsec_rcv_value retval =
|
|
+ (*proto_funcs->rcv_decrypt)(irs);
|
|
+
|
|
+ if(retval != IPSEC_RCV_OK) {
|
|
+ return retval;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Adjust pointers
|
|
+ */
|
|
+ skb = irs->skb;
|
|
+ irs->len = skb->len;
|
|
+ ipp = irs->ipp = skb->nh.iph;
|
|
+ iphlen = ipp->ihl<<2;
|
|
+ skb->h.raw = skb->nh.raw + iphlen;
|
|
+
|
|
+ /* zero any options that there might be */
|
|
+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
|
|
+
|
|
+ ipsaddr.s_addr = ipp->saddr;
|
|
+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
|
|
+ ipdaddr.s_addr = ipp->daddr;
|
|
+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
|
|
+
|
|
+ /*
|
|
+ * Discard the original ESP/AH header
|
|
+ */
|
|
+ ipp->protocol = irs->next_header;
|
|
+
|
|
+ ipp->check = 0; /* NOTE: this will be included in checksum */
|
|
+ ipp->check = ip_fast_csum((unsigned char *)skb->nh.iph, iphlen >> 2);
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "after <%s%s%s>, SA:%s:\n",
|
|
+ IPS_XFORM_NAME(irs->ipsp),
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
|
|
+
|
|
+ skb->protocol = htons(ETH_P_IP);
|
|
+ skb->ip_summed = 0;
|
|
+
|
|
+ ipsnext = irs->ipsp->ips_inext;
|
|
+ if(sysctl_ipsec_inbound_policy_check) {
|
|
+ if(ipsnext) {
|
|
+ if(
|
|
+ ipp->protocol != IPPROTO_AH
|
|
+ && ipp->protocol != IPPROTO_ESP
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ && ipp->protocol != IPPROTO_COMP
|
|
+ && (ipsnext->ips_said.proto != IPPROTO_COMP
|
|
+ || ipsnext->ips_inext)
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ && ipp->protocol != IPPROTO_IPIP
|
|
+ && ipp->protocol != IPPROTO_ATT_HEARTBEAT /* heartbeats to AT&T SIG/GIG */
|
|
+ ) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "packet with incomplete policy dropped, last successful SA:%s.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ return IPSEC_RCV_FAILEDINBOUND;
|
|
+ }
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s, Another IPSEC header to process.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "No ips_inext from this SA:%s.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ }
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ /* update ipcomp ratio counters, even if no ipcomp packet is present */
|
|
+ if (ipsnext
|
|
+ && ipsnext->ips_said.proto == IPPROTO_COMP
|
|
+ && ipp->protocol != IPPROTO_COMP) {
|
|
+ ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
|
|
+ ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+ irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
|
|
+ irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len;
|
|
+
|
|
+ if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
|
|
+ irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
|
|
+ }
|
|
+ irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
|
|
+ irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
|
|
+
|
|
+#ifdef CONFIG_NETFILTER
|
|
+ if(proto == IPPROTO_ESP || proto == IPPROTO_AH) {
|
|
+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
|
|
+ | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "%s SA sets skb->nfmark=0x%x.\n",
|
|
+ proto == IPPROTO_ESP ? "ESP" : "AH",
|
|
+ (unsigned)skb->nfmark);
|
|
+ }
|
|
+#endif /* CONFIG_NETFILTER */
|
|
+
|
|
+ return IPSEC_RCV_OK;
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * core decapsulation loop for all protocols.
|
|
+ *
|
|
+ * the following things should be setup to enter this function.
|
|
+ *
|
|
+ * irs->stats == stats structure (or NULL)
|
|
+ * irs->ipp = IP header.
|
|
+ * irs->ipsp = NULL.
|
|
+ * irs->ilen = 0;
|
|
+ * irs->authlen = 0;
|
|
+ * irs->authfuncs = NULL;
|
|
+ * irs->skb = skb;
|
|
+ * skb->nh.iph = ipp;
|
|
+ * skb->h.raw = start of payload
|
|
+ *
|
|
+ */
|
|
+int ipsec_rcv_decap(struct ipsec_rcv_state *irs)
|
|
+{
|
|
+ struct ipsec_sa *ipsp = NULL;
|
|
+ struct ipsec_sa* ipsnext = NULL;
|
|
+ struct in_addr ipsaddr;
|
|
+ struct in_addr ipdaddr;
|
|
+ struct iphdr *ipp;
|
|
+ struct sk_buff *skb = NULL;
|
|
+
|
|
+ /* begin decapsulating loop here */
|
|
+
|
|
+ /*
|
|
+ The spinlock is to prevent any other process from
|
|
+ accessing or deleting the ipsec_sa hash table or any of the
|
|
+ ipsec_sa s while we are using and updating them.
|
|
+
|
|
+ This is not optimal, but was relatively straightforward
|
|
+ at the time. A better way to do it has been planned for
|
|
+ more than a year, to lock the hash table and put reference
|
|
+ counts on each ipsec_sa instead. This is not likely to happen
|
|
+ in KLIPS1 unless a volunteer contributes it, but will be
|
|
+ designed into KLIPS2.
|
|
+ */
|
|
+ spin_lock(&tdb_lock);
|
|
+
|
|
+ do {
|
|
+ int decap_stat;
|
|
+ struct xform_functions *proto_funcs;
|
|
+
|
|
+ switch(irs->ipp->protocol) {
|
|
+ case IPPROTO_ESP:
|
|
+ proto_funcs = esp_xform_funcs;
|
|
+ break;
|
|
+
|
|
+#ifdef CONFIG_KLIPS_AH
|
|
+ case IPPROTO_AH:
|
|
+ proto_funcs = ah_xform_funcs;
|
|
+ break;
|
|
+#endif /* !CONFIG_KLIPS_AH */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ case IPPROTO_COMP:
|
|
+ proto_funcs = ipcomp_xform_funcs;
|
|
+ break;
|
|
+#endif /* !CONFIG_KLIPS_IPCOMP */
|
|
+ default:
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ decap_stat = IPSEC_RCV_BADPROTO;
|
|
+ goto rcvleave;
|
|
+ }
|
|
+
|
|
+ decap_stat = ipsec_rcv_decap_once(irs, proto_funcs);
|
|
+
|
|
+ if(decap_stat != IPSEC_RCV_OK) {
|
|
+ spin_unlock(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: decap_once failed: %d\n",
|
|
+ decap_stat);
|
|
+
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ /* end decapsulation loop here */
|
|
+ } while( (irs->ipp->protocol == IPPROTO_ESP )
|
|
+ || (irs->ipp->protocol == IPPROTO_AH )
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ || (irs->ipp->protocol == IPPROTO_COMP)
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ );
|
|
+
|
|
+ /* set up for decap loop */
|
|
+ ipp =irs->ipp;
|
|
+ ipsp =irs->ipsp;
|
|
+ ipsnext = ipsp->ips_inext;
|
|
+ skb = irs->skb;
|
|
+
|
|
+ /* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
|
|
+ * then we can just skip it
|
|
+ */
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) {
|
|
+ ipsp = ipsnext;
|
|
+ ipsnext = ipsp->ips_inext;
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ if ((irs->natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
|
|
+ /**
|
|
+ * NAT-Traversal and Transport Mode:
|
|
+ * we need to correct TCP/UDP checksum
|
|
+ *
|
|
+ * If we've got NAT-OA, we can fix checksum without recalculation.
|
|
+ */
|
|
+ __u32 natt_oa = ipsp->ips_natt_oa ?
|
|
+ ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
|
|
+ __u16 pkt_len = skb->tail - (unsigned char *)ipp;
|
|
+ __u16 data_len = pkt_len - (ipp->ihl << 2);
|
|
+
|
|
+ switch (ipp->protocol) {
|
|
+ case IPPROTO_TCP:
|
|
+ if (data_len >= sizeof(struct tcphdr)) {
|
|
+ struct tcphdr *tcp = skb->h.th;
|
|
+ if (natt_oa) {
|
|
+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NAT-T & TRANSPORT: "
|
|
+ "fix TCP checksum using NAT-OA\n");
|
|
+ tcp->check = csum_fold(
|
|
+ csum_partial((unsigned char *)buff, sizeof(buff),
|
|
+ tcp->check^0xffff));
|
|
+ }
|
|
+ else {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NAT-T & TRANSPORT: recalc TCP checksum\n");
|
|
+ if (pkt_len > (ntohs(ipp->tot_len)))
|
|
+ data_len -= (pkt_len - ntohs(ipp->tot_len));
|
|
+ tcp->check = 0;
|
|
+ tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr,
|
|
+ data_len, IPPROTO_TCP,
|
|
+ csum_partial((unsigned char *)tcp, data_len, 0));
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
|
|
+ }
|
|
+ break;
|
|
+ case IPPROTO_UDP:
|
|
+ if (data_len >= sizeof(struct udphdr)) {
|
|
+ struct udphdr *udp = skb->h.uh;
|
|
+ if (udp->check == 0) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
|
|
+ }
|
|
+ else if (natt_oa) {
|
|
+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NAT-T & TRANSPORT: "
|
|
+ "fix UDP checksum using NAT-OA\n");
|
|
+#ifdef DISABLE_UDP_CHECKSUM
|
|
+ udp->check=0
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NAT-T & TRANSPORT: "
|
|
+ "UDP checksum using NAT-OA disabled at compile time\n");
|
|
+#else
|
|
+ udp->check = csum_fold(
|
|
+ csum_partial((unsigned char *)buff, sizeof(buff),
|
|
+ udp->check^0xffff));
|
|
+#endif
|
|
+ }
|
|
+ else {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NAT-T & TRANSPORT: zero UDP checksum\n");
|
|
+ udp->check = 0;
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ /*
|
|
+ * XXX this needs to be locked from when it was first looked
|
|
+ * up in the decapsulation loop. Perhaps it is better to put
|
|
+ * the IPIP decap inside the loop.
|
|
+ */
|
|
+ if(ipsnext) {
|
|
+ ipsp = ipsnext;
|
|
+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
|
|
+ if((ipp->protocol != IPPROTO_IPIP) &&
|
|
+ (ipp->protocol != IPPROTO_ATT_HEARTBEAT)) { /* AT&T heartbeats to SIG/GIG */
|
|
+ spin_unlock(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s, Hey! How did this get through? Dropped.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ if(sysctl_ipsec_inbound_policy_check) {
|
|
+ struct sockaddr_in *psin = (struct sockaddr_in*)(ipsp->ips_addr_s);
|
|
+ if((ipsnext = ipsp->ips_inext)) {
|
|
+ char sa2[SATOT_BUF];
|
|
+ size_t sa_len2;
|
|
+ sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2));
|
|
+ spin_unlock(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "unexpected SA:%s after IPIP SA:%s\n",
|
|
+ sa_len2 ? sa2 : " (error)",
|
|
+ irs->sa_len ? irs->sa : " (error)");
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ if(ipp->saddr != psin->sin_addr.s_addr) {
|
|
+ spin_unlock(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s, src=%s(%08x) does match expected 0x%08x.\n",
|
|
+ irs->sa_len ? irs->sa : " (error)",
|
|
+ irs->ipsaddr_txt,
|
|
+ ipp->saddr, psin->sin_addr.s_addr);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */
|
|
+ {
|
|
+ /*
|
|
+ * XXX this needs to be locked from when it was first looked
|
|
+ * up in the decapsulation loop. Perhaps it is better to put
|
|
+ * the IPIP decap inside the loop.
|
|
+ */
|
|
+ ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
|
|
+ ipsp->ips_life.ipl_bytes.ipl_last = skb->len;
|
|
+
|
|
+ if(!ipsp->ips_life.ipl_usetime.ipl_count) {
|
|
+ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
|
|
+ }
|
|
+ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
|
|
+ ipsp->ips_life.ipl_packets.ipl_count += 1;
|
|
+
|
|
+ if(skb->len < irs->iphlen) {
|
|
+ spin_unlock(&tdb_lock);
|
|
+ printk(KERN_WARNING "klips_debug:ipsec_rcv: "
|
|
+ "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n",
|
|
+ irs->iphlen,
|
|
+ (int)(skb->len));
|
|
+
|
|
+ goto rcvleave;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * we need to pull up by size of IP header,
|
|
+ * options, but also by any UDP/ESP encap there might
|
|
+ * have been, and this deals with all cases.
|
|
+ */
|
|
+ skb_pull(skb, (skb->h.raw - skb->nh.raw));
|
|
+
|
|
+ /* new L3 header is where L4 payload was */
|
|
+ skb->nh.raw = skb->h.raw;
|
|
+
|
|
+ /* now setup new L4 payload location */
|
|
+ ipp = (struct iphdr *)skb->nh.raw;
|
|
+ skb->h.raw = skb->nh.raw + (ipp->ihl << 2);
|
|
+
|
|
+
|
|
+ /* remove any saved options that we might have,
|
|
+ * since we have a new IP header.
|
|
+ */
|
|
+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
|
|
+
|
|
+#if 0
|
|
+ KLIPS_PRINT(debug_rcv, "csum: %d\n", ip_fast_csum((u8 *)ipp, ipp->ihl));
|
|
+#endif
|
|
+
|
|
+ /* re-do any strings for debugging */
|
|
+ ipsaddr.s_addr = ipp->saddr;
|
|
+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
|
|
+ ipdaddr.s_addr = ipp->daddr;
|
|
+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
|
|
+
|
|
+ skb->protocol = htons(ETH_P_IP);
|
|
+ skb->ip_summed = 0;
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "IPIP tunnel stripped.\n");
|
|
+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
|
|
+ }
|
|
+
|
|
+ if(sysctl_ipsec_inbound_policy_check
|
|
+ /*
|
|
+ Note: "xor" (^) logically replaces "not equal"
|
|
+ (!=) and "bitwise or" (|) logically replaces
|
|
+ "boolean or" (||). This is done to speed up
|
|
+ execution by doing only bitwise operations and
|
|
+ no branch operations
|
|
+ */
|
|
+ && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
|
|
+ ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
|
|
+ | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
|
|
+ ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
|
|
+ {
|
|
+ char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
|
|
+
|
|
+ subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
|
|
+ ipsp->ips_mask_s.u.v4.sin_addr,
|
|
+ 0, sflow_txt, sizeof(sflow_txt));
|
|
+ subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
|
|
+ ipsp->ips_mask_d.u.v4.sin_addr,
|
|
+ 0, dflow_txt, sizeof(dflow_txt));
|
|
+ spin_unlock(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
|
|
+ irs->sa_len ? irs->sa : " (error)",
|
|
+ sflow_txt,
|
|
+ dflow_txt,
|
|
+ irs->ipsaddr_txt,
|
|
+ irs->ipdaddr_txt);
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_dropped++;
|
|
+ }
|
|
+ goto rcvleave;
|
|
+ }
|
|
+#ifdef CONFIG_NETFILTER
|
|
+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
|
|
+ | IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "IPIP SA sets skb->nfmark=0x%x.\n",
|
|
+ (unsigned)skb->nfmark);
|
|
+#endif /* CONFIG_NETFILTER */
|
|
+ }
|
|
+
|
|
+ spin_unlock(&tdb_lock);
|
|
+
|
|
+ if(irs->stats) {
|
|
+ irs->stats->rx_bytes += skb->len;
|
|
+ }
|
|
+ if(skb->dst) {
|
|
+ dst_release(skb->dst);
|
|
+ skb->dst = NULL;
|
|
+ }
|
|
+ skb->pkt_type = PACKET_HOST;
|
|
+ if(irs->hard_header_len &&
|
|
+ (skb->mac.raw != (skb->nh.raw - irs->hard_header_len)) &&
|
|
+ (irs->hard_header_len <= skb_headroom(skb))) {
|
|
+ /* copy back original MAC header */
|
|
+ memmove(skb->nh.raw - irs->hard_header_len,
|
|
+ skb->mac.raw, irs->hard_header_len);
|
|
+ skb->mac.raw = skb->nh.raw - irs->hard_header_len;
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ if(ipp->protocol == IPPROTO_COMP) {
|
|
+ unsigned int flags = 0;
|
|
+
|
|
+ if(sysctl_ipsec_inbound_policy_check) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
|
|
+ if (irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ /*
|
|
+ XXX need a ipsec_sa for updating ratio counters but it is not
|
|
+ following policy anyways so it is not a priority
|
|
+ */
|
|
+ skb = skb_decompress(skb, NULL, &flags);
|
|
+ if (!skb || flags) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "skb_decompress() returned error flags: %d, dropped.\n",
|
|
+ flags);
|
|
+ if (irs->stats) {
|
|
+ irs->stats->rx_errors++;
|
|
+ }
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+ /*
|
|
+ * make sure that data now starts at IP header, since we are going
|
|
+ * to pass this back to ip_input (aka netif_rx). Rules for what the
|
|
+ * pointers wind up a different for 2.6 vs 2.4, so we just fudge it here.
|
|
+ */
|
|
+#ifdef NET_26
|
|
+ skb->data = skb_push(skb, skb->h.raw - skb->nh.raw);
|
|
+#else
|
|
+ skb->data = skb->nh.raw;
|
|
+ {
|
|
+ struct iphdr *iph = skb->nh.iph;
|
|
+ int len = ntohs(iph->tot_len);
|
|
+ skb->len = len;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#ifdef SKB_RESET_NFCT
|
|
+ nf_conntrack_put(skb->nfct);
|
|
+ skb->nfct = NULL;
|
|
+#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
|
|
+ skb->nf_debug = 0;
|
|
+#endif /* CONFIG_NETFILTER_DEBUG */
|
|
+#endif /* SKB_RESET_NFCT */
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "netif_rx() called.\n");
|
|
+ netif_rx(skb);
|
|
+ skb=NULL;
|
|
+
|
|
+ rcvleave:
|
|
+ if(skb) {
|
|
+ ipsec_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+ /* KLIPS_DEC_USE; Artifact from refactor? bug # 454 */
|
|
+ return(0);
|
|
+}
|
|
+
|
|
+struct sk_buff *ipsec_rcv_unclone(struct sk_buff *skb,
|
|
+ struct ipsec_rcv_state *irs)
|
|
+{
|
|
+ /* if skb was cloned (most likely due to a packet sniffer such as
|
|
+ tcpdump being momentarily attached to the interface), make
|
|
+ a copy of our own to modify */
|
|
+ if(skb_cloned(skb)) {
|
|
+ /* include any mac header while copying.. */
|
|
+ if(skb_headroom(skb) < irs->hard_header_len) {
|
|
+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
|
|
+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
|
|
+ irs->hard_header_len,
|
|
+ skb_headroom(skb));
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ skb_push(skb, irs->hard_header_len);
|
|
+ if
|
|
+#ifdef SKB_COW_NEW
|
|
+ (skb_cow(skb, skb_headroom(skb)) != 0)
|
|
+#else /* SKB_COW_NEW */
|
|
+ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
|
|
+#endif /* SKB_COW_NEW */
|
|
+ {
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ if(skb->len < irs->hard_header_len) {
|
|
+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
|
|
+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
|
|
+ irs->hard_header_len,
|
|
+ skb->len);
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ skb_pull(skb, irs->hard_header_len);
|
|
+ }
|
|
+ return skb;
|
|
+
|
|
+rcvleave:
|
|
+ ipsec_kfree_skb(skb);
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+
|
|
+#if !defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
|
|
+/*
|
|
+ * decapsulate a UDP encapsulated ESP packet
|
|
+ */
|
|
+struct sk_buff *ipsec_rcv_natt_decap(struct sk_buff *skb
|
|
+ , struct ipsec_rcv_state *irs
|
|
+ , int *udp_decap_ret_p)
|
|
+{
|
|
+ *udp_decap_ret_p = 0;
|
|
+ if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) {
|
|
+ /**
|
|
+ * Packet comes from udp_queue_rcv_skb so it is already defrag,
|
|
+ * checksum verified, ... (ie safe to use)
|
|
+ *
|
|
+ * If the packet is not for us, return -1 and udp_queue_rcv_skb
|
|
+ * will continue to handle it (do not kfree skb !!).
|
|
+ */
|
|
+
|
|
+#ifndef UDP_OPT_IN_SOCK
|
|
+ struct udp_opt {
|
|
+ __u32 esp_in_udp;
|
|
+ };
|
|
+ struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);
|
|
+#else
|
|
+ struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp);
|
|
+#endif
|
|
+
|
|
+ struct iphdr *ip = (struct iphdr *)skb->nh.iph;
|
|
+ struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
|
|
+ __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
|
|
+ __u32 *udpdata32 = (__u32 *)udpdata;
|
|
+
|
|
+ irs->natt_sport = ntohs(udp->source);
|
|
+ irs->natt_dport = ntohs(udp->dest);
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
|
|
+ tp->esp_in_udp);
|
|
+ KLIPS_IP_PRINT(debug_rcv, ip);
|
|
+
|
|
+ if (udpdata < skb->tail) {
|
|
+ unsigned int len = skb->tail - udpdata;
|
|
+ if ((len==1) && (udpdata[0]==0xff)) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ /* not IPv6 compliant message */
|
|
+ "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
|
|
+ *udp_decap_ret_p = 0;
|
|
+ return NULL;
|
|
+ }
|
|
+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
|
|
+ (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&
|
|
+ (udpdata32[0]==0) && (udpdata32[1]==0) ) {
|
|
+ /* ESP Packet with Non-IKE header */
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "ESPinUDP pkt with Non-IKE - spi=0x%x\n",
|
|
+ ntohl(udpdata32[2]));
|
|
+ irs->natt_type = ESPINUDP_WITH_NON_IKE;
|
|
+ irs->natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
|
|
+ }
|
|
+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
|
|
+ (len > sizeof(struct esphdr)) &&
|
|
+ (udpdata32[0]!=0) ) {
|
|
+ /* ESP Packet without Non-ESP header */
|
|
+ irs->natt_type = ESPINUDP_WITH_NON_ESP;
|
|
+ irs->natt_len = sizeof(struct udphdr);
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
|
|
+ ntohl(udpdata32[0]));
|
|
+ }
|
|
+ else {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "IKE packet - not handled here\n");
|
|
+ *udp_decap_ret_p = -1;
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+ return skb;
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
+int
|
|
+ipsec_rcv(struct sk_buff *skb
|
|
+#ifndef PROTO_HANDLER_SINGLE_PARM
|
|
+ unsigned short xlen
|
|
+#endif /* PROTO_HANDLER_SINGLE_PARM */
|
|
+ )
|
|
+{
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ struct net_device *dev = skb->dev;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ unsigned char protoc;
|
|
+ struct net_device_stats *stats = NULL; /* This device's statistics */
|
|
+ struct net_device *ipsecdev = NULL, *prvdev;
|
|
+ struct ipsecpriv *prv;
|
|
+ struct ipsec_rcv_state nirs, *irs = &nirs;
|
|
+ struct iphdr *ipp;
|
|
+ char name[9];
|
|
+ int i;
|
|
+
|
|
+ /* Don't unlink in the middle of a turnaround */
|
|
+ KLIPS_INC_USE;
|
|
+
|
|
+ memset(&nirs, 0, sizeof(struct ipsec_rcv_state));
|
|
+
|
|
+ if (skb == NULL) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NULL skb passed in.\n");
|
|
+ goto rcvleave;
|
|
+ }
|
|
+
|
|
+ if (skb->data == NULL) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "NULL skb->data passed in, packet is bogus, dropping.\n");
|
|
+ goto rcvleave;
|
|
+ }
|
|
+
|
|
+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
|
|
+ {
|
|
+ /* NET_26 NAT-T is handled by seperate function */
|
|
+ struct sk_buff *nskb;
|
|
+ int udp_decap_ret = 0;
|
|
+
|
|
+ nskb = ipsec_rcv_natt_decap(skb, irs, &udp_decap_ret);
|
|
+ if(nskb == NULL) {
|
|
+ /* return with non-zero, because UDP.c code
|
|
+ * need to send it upstream.
|
|
+ */
|
|
+ if(skb && udp_decap_ret == 0) {
|
|
+ ipsec_kfree_skb(skb);
|
|
+ }
|
|
+ KLIPS_DEC_USE;
|
|
+ return(udp_decap_ret);
|
|
+ }
|
|
+ skb = nskb;
|
|
+ }
|
|
+#endif /* NAT_T */
|
|
+
|
|
+ /* dev->hard_header_len is unreliable and should not be used */
|
|
+ irs->hard_header_len = skb->mac.raw ? (skb->nh.raw - skb->mac.raw) : 0;
|
|
+ if((irs->hard_header_len < 0) || (irs->hard_header_len > skb_headroom(skb)))
|
|
+ irs->hard_header_len = 0;
|
|
+
|
|
+ skb = ipsec_rcv_unclone(skb, irs);
|
|
+ if(skb == NULL) {
|
|
+ goto rcvleave;
|
|
+ }
|
|
+
|
|
+#if IP_FRAGMENT_LINEARIZE
|
|
+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
|
|
+ not assembled automatically to save TCP from having to copy
|
|
+ twice.
|
|
+ */
|
|
+ if (skb_is_nonlinear(skb)) {
|
|
+#ifdef HAVE_NEW_SKB_LINEARIZE
|
|
+ if (skb_linearize_cow(skb) != 0)
|
|
+#else
|
|
+ if (skb_linearize(skb, GFP_ATOMIC) != 0)
|
|
+#endif
|
|
+ {
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ }
|
|
+#endif /* IP_FRAGMENT_LINEARIZE */
|
|
+
|
|
+#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
|
|
+ if (irs->natt_len) {
|
|
+ /**
|
|
+ * Now, we are sure packet is ESPinUDP, and we have a private
|
|
+ * copy that has been linearized, remove natt_len bytes
|
|
+ * from packet and modify protocol to ESP.
|
|
+ */
|
|
+ if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph)
|
|
+ && ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head))
|
|
+ {
|
|
+ unsigned int _len = (unsigned char *)skb->data -
|
|
+ (unsigned char *)skb->nh.iph;
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
|
|
+ _len);
|
|
+ skb_push(skb, _len);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "removing %d bytes from ESPinUDP packet\n", irs->natt_len);
|
|
+ ipp = skb->nh.iph;
|
|
+ irs->iphlen = ipp->ihl << 2;
|
|
+ ipp->tot_len = htons(ntohs(ipp->tot_len) - irs->natt_len);
|
|
+ if (skb->len < irs->iphlen + irs->natt_len) {
|
|
+ printk(KERN_WARNING
|
|
+ "klips_error:ipsec_rcv: "
|
|
+ "ESPinUDP packet is too small (%d < %d+%d). "
|
|
+ "This should never happen, please report.\n",
|
|
+ (int)(skb->len), irs->iphlen, irs->natt_len);
|
|
+ goto rcvleave;
|
|
+ }
|
|
+
|
|
+ /* advance payload pointer to point past the UDP header */
|
|
+ skb->h.raw = skb->h.raw + irs->natt_len;
|
|
+
|
|
+ /* modify protocol */
|
|
+ ipp->protocol = IPPROTO_ESP;
|
|
+
|
|
+ skb->sk = NULL;
|
|
+
|
|
+ KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ ipp = skb->nh.iph;
|
|
+
|
|
+ {
|
|
+ struct in_addr ipsaddr;
|
|
+ struct in_addr ipdaddr;
|
|
+
|
|
+ ipsaddr.s_addr = ipp->saddr;
|
|
+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt
|
|
+ , sizeof(irs->ipsaddr_txt));
|
|
+ ipdaddr.s_addr = ipp->daddr;
|
|
+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt
|
|
+ , sizeof(irs->ipdaddr_txt));
|
|
+ }
|
|
+
|
|
+ irs->iphlen = ipp->ihl << 2;
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "<<< Info -- ");
|
|
+ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
|
|
+ skb->dev->name ? skb->dev->name : "NULL");
|
|
+ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ KLIPS_PRINTMORE(debug_rcv, "\n");
|
|
+
|
|
+ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
|
|
+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
|
|
+ dev ? (dev->name ? dev->name : "NULL") : "NULL");
|
|
+
|
|
+ protoc = ipp->protocol;
|
|
+#ifndef NET_21
|
|
+ if((!protocol) || (protocol->protocol != protoc)) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
|
|
+ }
|
|
+#endif /* !NET_21 */
|
|
+
|
|
+ if( (protoc != IPPROTO_AH) &&
|
|
+#ifdef CONFIG_KLIPS_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
|
|
+ (protoc != IPPROTO_COMP) &&
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ (protoc != IPPROTO_ESP) ) {
|
|
+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
|
|
+ "klips_debug:ipsec_rcv: Why the hell is someone "
|
|
+ "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
|
|
+ protoc);
|
|
+ goto rcvleave;
|
|
+ }
|
|
+
|
|
+ if(skb->dev) {
|
|
+ for(i = 0; i < IPSEC_NUM_IF; i++) {
|
|
+ sprintf(name, IPSEC_DEV_FORMAT, i);
|
|
+ if(!strcmp(name, skb->dev->name)) {
|
|
+ prv = (struct ipsecpriv *)(skb->dev->priv);
|
|
+ if(prv) {
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+ }
|
|
+ ipsecdev = skb->dev;
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
|
|
+ break;
|
|
+ }
|
|
+ if((ipsecdev = __ipsec_dev_get(name)) == NULL) {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_error:ipsec_rcv: "
|
|
+ "device %s does not exist\n",
|
|
+ name);
|
|
+ }
|
|
+ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
|
|
+ prvdev = prv ? (struct net_device *)(prv->dev) : NULL;
|
|
+
|
|
+#if 0
|
|
+ KLIPS_PRINT(debug_rcv && prvdev,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "physical device for device %s is %s\n",
|
|
+ name,
|
|
+ prvdev->name);
|
|
+#endif
|
|
+ if(prvdev && skb->dev &&
|
|
+ !strcmp(prvdev->name, skb->dev->name)) {
|
|
+ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
|
|
+ skb->dev = ipsecdev;
|
|
+ KLIPS_PRINT(debug_rcv && prvdev,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "assigning packet ownership to virtual device %s from physical device %s.\n",
|
|
+ name, prvdev->name);
|
|
+ if(stats) {
|
|
+ stats->rx_packets++;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_rcv,
|
|
+ "klips_debug:ipsec_rcv: "
|
|
+ "device supplied with skb is NULL\n");
|
|
+ }
|
|
+
|
|
+ if(stats == NULL) {
|
|
+ KLIPS_PRINT((debug_rcv),
|
|
+ "klips_error:ipsec_rcv: "
|
|
+ "packet received from physical I/F (%s) not connected to ipsec I/F. Cannot record stats. May not have SA for decoding. Is IPSEC traffic expected on this I/F? Check routing.\n",
|
|
+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
|
|
+ }
|
|
+
|
|
+ KLIPS_IP_PRINT(debug_rcv, ipp);
|
|
+
|
|
+ /* set up for decap loop */
|
|
+ irs->stats= stats;
|
|
+ irs->ipp = ipp;
|
|
+ irs->ipsp = NULL;
|
|
+ irs->ilen = 0;
|
|
+ irs->authlen=0;
|
|
+ irs->authfuncs=NULL;
|
|
+ irs->skb = skb;
|
|
+
|
|
+ ipsec_rcv_decap(irs);
|
|
+ KLIPS_DEC_USE;
|
|
+ return(0);
|
|
+
|
|
+ rcvleave:
|
|
+ if(skb) {
|
|
+ ipsec_kfree_skb(skb);
|
|
+ }
|
|
+ KLIPS_DEC_USE;
|
|
+ return(0);
|
|
+
|
|
+}
|
|
+
|
|
+#ifdef NET_26
|
|
+/*
|
|
+ * this entry point is not a protocol entry point, so the entry
|
|
+ * is a bit different.
|
|
+ *
|
|
+ * skb->iph->tot_len has been byte-swapped, and reduced by the size of
|
|
+ * the IP header (and options).
|
|
+ *
|
|
+ * skb->h.raw has been pulled up the ESP header.
|
|
+ *
|
|
+ * skb->iph->protocol = 50 IPPROTO_ESP;
|
|
+ *
|
|
+ */
|
|
+int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type)
|
|
+{
|
|
+ struct ipsec_rcv_state nirs, *irs = &nirs;
|
|
+ struct iphdr *ipp;
|
|
+
|
|
+ /* Don't unlink in the middle of a turnaround */
|
|
+ KLIPS_INC_USE;
|
|
+
|
|
+ memset(irs, 0, sizeof(*irs));
|
|
+
|
|
+ /* XXX fudge it so that all nat-t stuff comes from ipsec0 */
|
|
+ /* eventually, the SA itself will determine which device
|
|
+ * it comes from
|
|
+ */
|
|
+ {
|
|
+ skb->dev = ipsec_get_device(0);
|
|
+ }
|
|
+
|
|
+ /* set up for decap loop */
|
|
+ irs->hard_header_len = skb->dev->hard_header_len;
|
|
+
|
|
+ skb = ipsec_rcv_unclone(skb, irs);
|
|
+
|
|
+#if IP_FRAGMENT_LINEARIZE
|
|
+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
|
|
+ not assembled automatically to save TCP from having to copy
|
|
+ twice.
|
|
+ */
|
|
+ if (skb_is_nonlinear(skb)) {
|
|
+#ifdef HAVE_NEW_SKB_LINEARIZE
|
|
+ if (skb_linearize_cow(skb) != 0)
|
|
+#else
|
|
+ if (skb_linearize(skb, GFP_ATOMIC) != 0)
|
|
+#endif
|
|
+ {
|
|
+ goto rcvleave;
|
|
+ }
|
|
+ }
|
|
+#endif /* IP_FRAGMENT_LINEARIZE */
|
|
+
|
|
+ ipp = skb->nh.iph;
|
|
+
|
|
+ {
|
|
+ struct in_addr ipsaddr;
|
|
+ struct in_addr ipdaddr;
|
|
+
|
|
+ ipsaddr.s_addr = ipp->saddr;
|
|
+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt
|
|
+ , sizeof(irs->ipsaddr_txt));
|
|
+ ipdaddr.s_addr = ipp->daddr;
|
|
+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt
|
|
+ , sizeof(irs->ipdaddr_txt));
|
|
+ }
|
|
+
|
|
+ irs->iphlen = ipp->ihl << 2;
|
|
+
|
|
+ KLIPS_IP_PRINT(debug_rcv, ipp);
|
|
+
|
|
+ irs->stats= NULL;
|
|
+ irs->ipp = ipp;
|
|
+ irs->ipsp = NULL;
|
|
+ irs->ilen = 0;
|
|
+ irs->authlen=0;
|
|
+ irs->authfuncs=NULL;
|
|
+ irs->skb = skb;
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ switch(encap_type) {
|
|
+ case UDP_ENCAP_ESPINUDP:
|
|
+ irs->natt_type = ESPINUDP_WITH_NON_ESP;
|
|
+ break;
|
|
+
|
|
+ case UDP_ENCAP_ESPINUDP_NON_IKE:
|
|
+ irs->natt_type = ESPINUDP_WITH_NON_IKE;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ if(printk_ratelimit()) {
|
|
+ printk(KERN_INFO "KLIPS received unknown UDP-ESP encap type %u\n",
|
|
+ encap_type);
|
|
+ }
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+#endif
|
|
+ ipsec_rcv_decap(irs);
|
|
+ KLIPS_DEC_USE;
|
|
+ return 0;
|
|
+
|
|
+rcvleave:
|
|
+ if(skb) {
|
|
+ ipsec_kfree_skb(skb);
|
|
+ }
|
|
+ KLIPS_DEC_USE;
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_rcv.c,v $
|
|
+ * Revision 1.171.2.11 2007/04/28 20:46:40 paul
|
|
+ * Added compile time switch for -DDISABLE_UDP_CHECKSUM that seems to be
|
|
+ * breaking IPsec+NAT+Transport mode with NAT-OA. Enabled this per default
|
|
+ * via Makefile.inc's USERCOMPILE flags.
|
|
+ *
|
|
+ * Revision 1.171.2.10 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.171.2.9 2006/07/30 02:09:33 paul
|
|
+ * Author: Bart Trojanowski <bart@xelerance.com>
|
|
+ * This fixes a NATT+ESP bug in rcv path.
|
|
+ *
|
|
+ * We only want to test NATT policy on the ESP packet. Doing so on the
|
|
+ * bundled SA breaks because the next layer does not know anything about
|
|
+ * NATT.
|
|
+ *
|
|
+ * Fix just puts an if(proto == IPPROTO_ESP) around the NATT policy check.
|
|
+ *
|
|
+ * Revision 1.171.2.8 2006/07/29 05:03:04 paul
|
|
+ * Added check for new version of skb_linearize that only takes 1 argument,
|
|
+ * for 2.6.18+ kernels.
|
|
+ *
|
|
+ * Revision 1.171.2.7 2006/04/20 16:33:07 mcr
|
|
+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
|
|
+ * Fix in-kernel module compilation. Sub-makefiles do not work.
|
|
+ *
|
|
+ * Revision 1.171.2.6 2005/12/07 06:07:04 paul
|
|
+ * comment out KLIPS_DEC_USE in ipsec_rcv_decap. Likely an artifact from
|
|
+ * refactoring. http://bugs.xelerance.com/view.php?id=454
|
|
+ *
|
|
+ * Revision 1.171.2.5 2005/10/21 02:22:29 mcr
|
|
+ * pull up of another try at 2.4.x kernel fix
|
|
+ *
|
|
+ * Revision 1.171.2.4 2005/10/21 01:39:56 mcr
|
|
+ * nat-t fix is 2.4/2.6 specific
|
|
+ *
|
|
+ * Revision 1.178 2005/10/21 02:19:34 mcr
|
|
+ * on 2.4 systems, we have to fix up the length as well.
|
|
+ *
|
|
+ * Revision 1.177 2005/10/21 00:18:31 mcr
|
|
+ * nat-t fix is 2.4 specific.
|
|
+ *
|
|
+ * Revision 1.176 2005/10/20 21:06:11 mcr
|
|
+ * possible fix for nat-t problem on 2.4 kernels.
|
|
+ *
|
|
+ * Revision 1.175 2005/10/13 02:49:24 mcr
|
|
+ * tested UDP-encapsulated ESP packets that were not actually ESP,
|
|
+ * (but IKE) were being eaten.
|
|
+ *
|
|
+ * Revision 1.174 2005/10/13 01:25:22 mcr
|
|
+ * UDP-encapsulated ESP packets that were not actually ESP,
|
|
+ * (but IKE) were being eaten.
|
|
+ *
|
|
+ * Revision 1.173 2005/08/31 23:26:11 mcr
|
|
+ * fixes for 2.6.13
|
|
+ *
|
|
+ * Revision 1.172 2005/08/05 08:44:54 mcr
|
|
+ * ipsec_kern24.h (compat code for 2.4) must be include
|
|
+ * explicitely now.
|
|
+ *
|
|
+ * Revision 1.171 2005/07/08 23:56:06 ken
|
|
+ * #ifdef
|
|
+ *
|
|
+ * Revision 1.170 2005/07/08 23:50:05 ken
|
|
+ * Don't attempt to decapsulate if NAT-T isn't available in the code
|
|
+ *
|
|
+ * Revision 1.169 2005/06/06 00:27:31 mcr
|
|
+ * fix for making tcpdump (packet capture) work correctly for
|
|
+ * nat-t received packets.
|
|
+ *
|
|
+ * Revision 1.168 2005/06/04 16:06:06 mcr
|
|
+ * better patch for nat-t rcv-device code.
|
|
+ *
|
|
+ * Revision 1.167 2005/06/03 17:04:46 mcr
|
|
+ * nat-t packets are forced to arrive from ipsec0.
|
|
+ *
|
|
+ * Revision 1.166 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.165 2005/04/20 17:11:32 mcr
|
|
+ * fixed to compile on 2.4.
|
|
+ *
|
|
+ * Revision 1.164 2005/04/18 03:09:50 ken
|
|
+ * Fix typo
|
|
+ *
|
|
+ * Revision 1.163 2005/04/17 05:32:58 mcr
|
|
+ * remove extraneous debugging
|
|
+ * make sure to return success from klips26_encap_rcv().
|
|
+ *
|
|
+ * Revision 1.162 2005/04/17 04:37:01 mcr
|
|
+ * make sure that irs->ipp is still set.
|
|
+ *
|
|
+ * Revision 1.161 2005/04/17 03:51:52 mcr
|
|
+ * removed old comment about removed code.
|
|
+ * added translation from udp.c/2.6 to KLIPS NAT-ESP naming.
|
|
+ * comment about check for origin address/port for incoming NAT-ESP packets.
|
|
+ *
|
|
+ * Revision 1.160 2005/04/15 19:55:58 mcr
|
|
+ * adjustments to use proper skb fields for data.
|
|
+ *
|
|
+ * Revision 1.159 2005/04/10 22:58:20 mcr
|
|
+ * refactoring of receive functions to make it easier to
|
|
+ * call the ESP decap.
|
|
+ *
|
|
+ * Revision 1.158 2005/04/08 18:27:53 mcr
|
|
+ * refactored ipsec_rcv() into ipsec_rcv() and ipsec_rcv_decap().
|
|
+ *
|
|
+ * Revision 1.157 2004/12/28 23:13:09 mcr
|
|
+ * use consistent CONFIG_IPSEC_NAT_TRAVERSAL.
|
|
+ *
|
|
+ * Revision 1.156 2004/12/03 21:34:51 mcr
|
|
+ * mistype of KLIPS_USE_COUNT -> KLIPS_INC_USE;
|
|
+ *
|
|
+ * Revision 1.155 2004/12/03 21:25:57 mcr
|
|
+ * compile time fixes for running on 2.6.
|
|
+ * still experimental.
|
|
+ *
|
|
+ * Revision 1.154 2004/09/08 17:21:36 ken
|
|
+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
|
|
+ *
|
|
+ * Revision 1.153 2004/08/22 20:10:00 mcr
|
|
+ * removed check for incorrect setting of NET_26.
|
|
+ *
|
|
+ * Revision 1.152 2004/08/21 15:22:39 mcr
|
|
+ * added #defines for ATT heartbeat.
|
|
+ *
|
|
+ * Revision 1.151 2004/08/21 02:16:32 ken
|
|
+ * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support
|
|
+ *
|
|
+ * Revision 1.150 2004/08/21 00:44:48 mcr
|
|
+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
|
|
+ *
|
|
+ * Revision 1.149 2004/08/20 21:45:45 mcr
|
|
+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
|
|
+ * be 26sec compatible. But, some defines where changed.
|
|
+ *
|
|
+ * Revision 1.148 2004/08/17 03:27:23 mcr
|
|
+ * klips 2.6 edits.
|
|
+ *
|
|
+ * Revision 1.147 2004/08/05 23:29:27 mcr
|
|
+ * fixed nesting of #ifdef vs {} in ipsec_rcv().
|
|
+ *
|
|
+ * Revision 1.146 2004/08/04 15:57:07 mcr
|
|
+ * moved des .h files to include/des/ *
|
|
+ * included 2.6 protocol specific things
|
|
+ * started at NAT-T support, but it will require a kernel patch.
|
|
+ *
|
|
+ * Revision 1.145 2004/08/03 18:19:08 mcr
|
|
+ * in 2.6, use "net_device" instead of #define device->net_device.
|
|
+ * this probably breaks 2.0 compiles.
|
|
+ *
|
|
+ * Revision 1.144 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.143 2004/05/10 22:27:00 mcr
|
|
+ * fix for ESP-3DES-noauth test case.
|
|
+ *
|
|
+ * Revision 1.142 2004/05/10 22:25:57 mcr
|
|
+ * reformat of calls to ipsec_lifetime_check().
|
|
+ *
|
|
+ * Revision 1.141 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.140 2004/02/03 03:12:53 mcr
|
|
+ * removed erroneously, double patched code.
|
|
+ *
|
|
+ * Revision 1.139 2004/01/05 23:21:29 mcr
|
|
+ * initialize sin_family in ipsec_rcv.c
|
|
+ *
|
|
+ * Revision 1.138 2003/12/24 19:46:52 mcr
|
|
+ * if sock.h patch has not been applied, then define appropriate
|
|
+ * structure so we can use it. This is serious inferior, and
|
|
+ * depends upon the concept that the structure in question is
|
|
+ * smaller than the other members of that union.
|
|
+ * getting rid of differing methods is a better solution.
|
|
+ *
|
|
+ * Revision 1.137 2003/12/22 19:40:57 mcr
|
|
+ * NAT-T patches 0.6c.
|
|
+ *
|
|
+ * Revision 1.136 2003/12/15 18:13:12 mcr
|
|
+ * when compiling with NAT traversal, don't assume that the
|
|
+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
|
|
+ * is set.
|
|
+ *
|
|
+ * Revision 1.135 2003/12/13 19:10:21 mcr
|
|
+ * refactored rcv and xmit code - same as FS 2.05.
|
|
+ *
|
|
+ * Revision 1.134.2.1 2003/12/22 15:25:52 jjo
|
|
+ * Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.134 2003/12/10 01:14:27 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.133 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.132.2.1 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.132 2003/09/02 19:51:48 mcr
|
|
+ * fixes for PR#252.
|
|
+ *
|
|
+ * Revision 1.131 2003/07/31 22:47:16 mcr
|
|
+ * preliminary (untested by FS-team) 2.5 patches.
|
|
+ *
|
|
+ * Revision 1.130 2003/04/03 17:38:25 rgb
|
|
+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
|
|
+ * Clarified logic for non-connected devices.
|
|
+ *
|
|
+ * Revision 1.129 2003/02/06 02:21:34 rgb
|
|
+ *
|
|
+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
|
|
+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
|
|
+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
|
|
+ *
|
|
+ * Revision 1.128 2002/12/13 20:58:03 rgb
|
|
+ * Relegated MCR's recent "_dmp" routine to debug_verbose.
|
|
+ * Cleaned up printing of source and destination addresses in debug output.
|
|
+ *
|
|
+ * Revision 1.127 2002/12/04 16:00:16 rgb
|
|
+ *
|
|
+ * Fixed AH decapsulation pointer update bug and added some comments and
|
|
+ * debugging.
|
|
+ * This bug was caught by west-ah-0[12].
|
|
+ *
|
|
+ * Revision 1.126 2002/11/04 05:03:43 mcr
|
|
+ * fixes for IPCOMP. There were two problems:
|
|
+ * 1) the irs->ipp pointer was not being updated properly after
|
|
+ * the ESP descryption. The meant nothing for IPIP, as the
|
|
+ * later IP header overwrote the earlier one.
|
|
+ * 2) the more serious problem was that skb_decompress will
|
|
+ * usually allocate a new SKB, so we have to make sure that
|
|
+ * it doesn't get lost.
|
|
+ * #2 meant removing the skb argument from the ->decrypt routine
|
|
+ * and moving it to the irs->skb, so it could be value/result.
|
|
+ *
|
|
+ * Revision 1.125 2002/11/01 01:53:35 dhr
|
|
+ *
|
|
+ * fix typo
|
|
+ *
|
|
+ * Revision 1.124 2002/10/31 22:49:01 dhr
|
|
+ *
|
|
+ * - eliminate unused variable "hash"
|
|
+ * - reduce scope of variable "authenticator"
|
|
+ * - add comment on a couple of tricky bits
|
|
+ *
|
|
+ * Revision 1.123 2002/10/31 22:39:56 dhr
|
|
+ *
|
|
+ * use correct type for result of function calls
|
|
+ *
|
|
+ * Revision 1.122 2002/10/31 22:36:25 dhr
|
|
+ *
|
|
+ * simplify complex test
|
|
+ *
|
|
+ * Revision 1.121 2002/10/31 22:34:04 dhr
|
|
+ *
|
|
+ * ipsprev is never used: ditch it
|
|
+ *
|
|
+ * Revision 1.120 2002/10/31 22:30:21 dhr
|
|
+ *
|
|
+ * eliminate redundant assignments
|
|
+ *
|
|
+ * Revision 1.119 2002/10/31 22:27:43 dhr
|
|
+ *
|
|
+ * make whitespace canonical
|
|
+ *
|
|
+ * Revision 1.118 2002/10/30 05:47:17 rgb
|
|
+ * Fixed cut-and-paste error mis-identifying comp runt as ah.
|
|
+ *
|
|
+ * Revision 1.117 2002/10/17 16:37:45 rgb
|
|
+ * Remove compp intermediate variable and in-line its contents
|
|
+ * where used
|
|
+ *
|
|
+ * Revision 1.116 2002/10/12 23:11:53 dhr
|
|
+ *
|
|
+ * [KenB + DHR] more 64-bit cleanup
|
|
+ *
|
|
+ * Revision 1.115 2002/10/07 19:06:58 rgb
|
|
+ * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming.
|
|
+ *
|
|
+ * Revision 1.114 2002/10/07 18:31:31 rgb
|
|
+ * Set saref on incoming packets.
|
|
+ *
|
|
+ * Revision 1.113 2002/09/16 21:28:12 mcr
|
|
+ * adjust hash length for HMAC calculation - must look at whether
|
|
+ * it is MD5 or SHA1.
|
|
+ *
|
|
+ * Revision 1.112 2002/09/16 21:19:15 mcr
|
|
+ * fixes for west-ah-icmp-01 - length of AH header must be
|
|
+ * calculated properly, and next_header field properly copied.
|
|
+ *
|
|
+ * Revision 1.111 2002/09/10 02:45:56 mcr
|
|
+ * re-factored the ipsec_rcv function into several functions,
|
|
+ * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP.
|
|
+ * In addition, the MD5 and SHA1 functions are replaced with pointers.
|
|
+ *
|
|
+ * Revision 1.110 2002/08/30 06:34:33 rgb
|
|
+ * Fix scope of shift in AH header length check.
|
|
+ *
|
|
+ * Revision 1.109 2002/08/27 16:49:20 rgb
|
|
+ * Fixed ESP short packet DOS (and AH and IPCOMP).
|
|
+ *
|
|
+ * Revision 1.108 2002/07/24 18:44:54 rgb
|
|
+ * Type fiddling to tame ia64 compiler.
|
|
+ *
|
|
+ * Revision 1.107 2002/05/27 18:58:18 rgb
|
|
+ * Convert to dynamic ipsec device allocation.
|
|
+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
|
|
+ *
|
|
+ * Revision 1.106 2002/05/23 07:15:21 rgb
|
|
+ * Pointer clean-up.
|
|
+ * Added refcount code.
|
|
+ *
|
|
+ * Revision 1.105 2002/05/14 02:35:06 rgb
|
|
+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
|
|
+ * ipsec_sa or ipsec_sa.
|
|
+ * Change references to _TDB to _IPSA.
|
|
+ *
|
|
+ * Revision 1.104 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.103 2002/04/24 07:36:30 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_rcv.c,v
|
|
+ *
|
|
+ * Revision 1.102 2002/01/29 17:17:56 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.101 2002/01/29 04:00:52 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.100 2002/01/29 02:13:17 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.99 2002/01/28 21:40:59 mcr
|
|
+ * should use #if to test boolean option rather than #ifdef.
|
|
+ *
|
|
+ * Revision 1.98 2002/01/20 20:19:36 mcr
|
|
+ * renamed option to IP_FRAGMENT_LINEARIZE.
|
|
+ *
|
|
+ * Revision 1.97 2002/01/12 02:55:36 mcr
|
|
+ * fix for post-2.4.4 to linearize skb's when ESP packet
|
|
+ * was assembled from fragments.
|
|
+ *
|
|
+ * Revision 1.96 2001/11/26 09:23:49 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.93.2.2 2001/10/22 20:54:07 mcr
|
|
+ * include des.h, removed phony prototypes and fixed calling
|
|
+ * conventions to match real prototypes.
|
|
+ *
|
|
+ * Revision 1.93.2.1 2001/09/25 02:22:22 mcr
|
|
+ * struct tdb -> struct ipsec_sa.
|
|
+ * lifetime checks moved to ipsec_life.c
|
|
+ * some sa(tdb) manipulation functions renamed.
|
|
+ *
|
|
+ * Revision 1.95 2001/11/06 19:49:07 rgb
|
|
+ * Added variable descriptions.
|
|
+ * Removed unauthenticated sequence==0 check to prevent DoS.
|
|
+ *
|
|
+ * Revision 1.94 2001/10/18 04:45:20 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/freeswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.93 2001/09/07 22:17:24 rgb
|
|
+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
|
|
+ * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
|
|
+ *
|
|
+ * Revision 1.92 2001/08/27 19:44:41 rgb
|
|
+ * Fix error in comment.
|
|
+ *
|
|
+ * Revision 1.91 2001/07/20 19:31:48 dhr
|
|
+ * [DHR] fix source and destination subnets of policy in diagnostic
|
|
+ *
|
|
+ * Revision 1.90 2001/07/06 19:51:09 rgb
|
|
+ * Added inbound policy checking code for IPIP SAs.
|
|
+ * Renamed unused function argument for ease and intuitive naming.
|
|
+ *
|
|
+ * Revision 1.89 2001/06/22 19:35:23 rgb
|
|
+ * Disable ipcomp processing if we are handed a ipcomp packet with no esp
|
|
+ * or ah header.
|
|
+ * Print protocol if we are handed a non-ipsec packet.
|
|
+ *
|
|
+ * Revision 1.88 2001/06/20 06:30:47 rgb
|
|
+ * Fixed transport mode IPCOMP policy check bug.
|
|
+ *
|
|
+ * Revision 1.87 2001/06/13 20:58:40 rgb
|
|
+ * Added parentheses around assignment used as truth value to silence
|
|
+ * compiler.
|
|
+ *
|
|
+ * Revision 1.86 2001/06/07 22:25:23 rgb
|
|
+ * Added a source address policy check for tunnel mode. It still does
|
|
+ * not check client addresses and masks.
|
|
+ * Only decapsulate IPIP if it is expected.
|
|
+ *
|
|
+ * Revision 1.85 2001/05/30 08:14:02 rgb
|
|
+ * Removed vestiges of esp-null transforms.
|
|
+ *
|
|
+ * Revision 1.84 2001/05/27 06:12:11 rgb
|
|
+ * Added structures for pid, packet count and last access time to eroute.
|
|
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
|
|
+ *
|
|
+ * Revision 1.83 2001/05/04 16:45:47 rgb
|
|
+ * Remove unneeded code. ipp is not used after this point.
|
|
+ *
|
|
+ * Revision 1.82 2001/05/04 16:36:00 rgb
|
|
+ * Fix skb_cow() call for 2.4.4. (SS)
|
|
+ *
|
|
+ * Revision 1.81 2001/05/02 14:46:53 rgb
|
|
+ * Fix typo for compiler directive to pull IPH back.
|
|
+ *
|
|
+ * Revision 1.80 2001/04/30 19:46:34 rgb
|
|
+ * Update for 2.4.4. We now receive the skb with skb->data pointing to
|
|
+ * h.raw.
|
|
+ *
|
|
+ * Revision 1.79 2001/04/23 15:01:15 rgb
|
|
+ * Added spin_lock() check to prevent double-locking for multiple
|
|
+ * transforms and hence kernel lock-ups with SMP kernels.
|
|
+ * Minor spin_unlock() adjustments to unlock before non-dependant prints
|
|
+ * and IPSEC device stats updates.
|
|
+ *
|
|
+ * Revision 1.78 2001/04/21 23:04:24 rgb
|
|
+ * Check if soft expire has already been sent before sending another to
|
|
+ * prevent ACQUIRE flooding.
|
|
+ *
|
|
+ * Revision 1.77 2001/03/16 07:35:20 rgb
|
|
+ * Ditch extra #if 1 around now permanent policy checking code.
|
|
+ *
|
|
+ * Revision 1.76 2001/02/27 22:24:54 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.75 2001/02/19 22:28:30 rgb
|
|
+ * Minor change to virtual device discovery code to assert which I/F has
|
|
+ * been found.
|
|
+ *
|
|
+ * Revision 1.74 2000/11/25 03:50:36 rgb
|
|
+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
|
|
+ *
|
|
+ * Revision 1.73 2000/11/09 20:52:15 rgb
|
|
+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
|
|
+ * include ipcomp and prevent races, renaming some tdb variables that got
|
|
+ * forgotten, moving some unlocks to include tdbs and adding a missing
|
|
+ * unlock. Thanks to Svenning for some of these.
|
|
+ *
|
|
+ * Revision 1.72 2000/11/09 20:11:22 rgb
|
|
+ * Minor shuffles to fix non-standard kernel config option selection.
|
|
+ *
|
|
+ * Revision 1.71 2000/11/06 04:36:18 rgb
|
|
+ * Ditched spin_lock_irqsave in favour of spin_lock.
|
|
+ * Minor initial protocol check rewrite.
|
|
+ * Clean up debug printing.
|
|
+ * Clean up tdb handling on ipcomp.
|
|
+ * Fixed transport mode null pointer de-reference without ipcomp.
|
|
+ * Add Svenning's adaptive content compression.
|
|
+ * Disabled registration of ipcomp handler.
|
|
+ *
|
|
+ * Revision 1.70 2000/10/30 23:41:43 henry
|
|
+ * Hans-Joerg Hoexer's null-pointer fix
|
|
+ *
|
|
+ * Revision 1.69 2000/10/10 18:54:16 rgb
|
|
+ * Added a fix for incoming policy check with ipcomp enabled but
|
|
+ * uncompressible.
|
|
+ *
|
|
+ * Revision 1.68 2000/09/22 17:53:12 rgb
|
|
+ * Fixed ipcomp tdb pointers update for policy checking.
|
|
+ *
|
|
+ * Revision 1.67 2000/09/21 03:40:58 rgb
|
|
+ * Added more debugging to try and track down the cpi outward copy problem.
|
|
+ *
|
|
+ * Revision 1.66 2000/09/20 04:00:10 rgb
|
|
+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for
|
|
+ * debugging oopsen.
|
|
+ *
|
|
+ * Revision 1.65 2000/09/19 07:07:16 rgb
|
|
+ * Added debugging to inbound policy check for ipcomp.
|
|
+ * Added missing spin_unlocks (thanks Svenning!).
|
|
+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
|
|
+ * Protect ipcomp policy check following ipip decap with sysctl switch.
|
|
+ *
|
|
+ * Revision 1.64 2000/09/18 21:27:29 rgb
|
|
+ * 2.0 fixes.
|
|
+ *
|
|
+ * Revision 1.63 2000/09/18 02:35:50 rgb
|
|
+ * Added policy checking to ipcomp and re-enabled policy checking by
|
|
+ * default.
|
|
+ * Optimised satoa calls.
|
|
+ *
|
|
+ * Revision 1.62 2000/09/17 21:02:32 rgb
|
|
+ * Clean up debugging, removing slow timestamp debug code.
|
|
+ *
|
|
+ * Revision 1.61 2000/09/16 01:07:55 rgb
|
|
+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
|
|
+ *
|
|
+ * Revision 1.60 2000/09/15 11:37:01 rgb
|
|
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
|
|
+ * IPCOMP zlib deflate code.
|
|
+ *
|
|
+ * Revision 1.59 2000/09/15 04:56:20 rgb
|
|
+ * Remove redundant satoa() call, reformat comment.
|
|
+ *
|
|
+ * Revision 1.58 2000/09/13 08:00:52 rgb
|
|
+ * Flick on inbound policy checking.
|
|
+ *
|
|
+ * Revision 1.57 2000/09/12 03:22:19 rgb
|
|
+ * Converted inbound_policy_check to sysctl.
|
|
+ * Re-enabled policy backcheck.
|
|
+ * Moved policy checks to top and within tdb lock.
|
|
+ *
|
|
+ * Revision 1.56 2000/09/08 19:12:56 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.55 2000/08/28 18:15:46 rgb
|
|
+ * Added MB's nf-debug reset patch.
|
|
+ *
|
|
+ * Revision 1.54 2000/08/27 01:41:26 rgb
|
|
+ * More minor tweaks to the bad padding debug code.
|
|
+ *
|
|
+ * Revision 1.53 2000/08/24 16:54:16 rgb
|
|
+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
|
|
+ * info.
|
|
+ * Tidied up device reporting at the start of ipsec_rcv.
|
|
+ * Tidied up bad padding debugging and processing.
|
|
+ *
|
|
+ * Revision 1.52 2000/08/20 21:36:03 rgb
|
|
+ * Activated pfkey_expire() calls.
|
|
+ * Added a hard/soft expiry parameter to pfkey_expire().
|
|
+ * Added sanity checking to avoid propagating zero or smaller-length skbs
|
|
+ * from a bogus decryption.
|
|
+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
|
|
+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
|
|
+ *
|
|
+ * Revision 1.51 2000/08/18 21:23:30 rgb
|
|
+ * Improve bad padding warning so that the printk buffer doesn't get
|
|
+ * trampled.
|
|
+ *
|
|
+ * Revision 1.50 2000/08/01 14:51:51 rgb
|
|
+ * Removed _all_ remaining traces of DES.
|
|
+ *
|
|
+ * Revision 1.49 2000/07/28 13:50:53 rgb
|
|
+ * Changed enet_statistics to net_device_stats and added back compatibility
|
|
+ * for pre-2.1.19.
|
|
+ *
|
|
+ * Revision 1.48 2000/05/10 19:14:40 rgb
|
|
+ * Only check usetime against soft and hard limits if the tdb has been
|
|
+ * used.
|
|
+ * Cast output of ntohl so that the broken prototype doesn't make our
|
|
+ * compile noisy.
|
|
+ *
|
|
+ * Revision 1.47 2000/05/09 17:45:43 rgb
|
|
+ * Fix replay bitmap corruption bug upon receipt of bogus packet
|
|
+ * with correct SPI. This was a DoS.
|
|
+ *
|
|
+ * Revision 1.46 2000/03/27 02:31:58 rgb
|
|
+ * Fixed authentication failure printout bug.
|
|
+ *
|
|
+ * Revision 1.45 2000/03/22 16:15:37 rgb
|
|
+ * Fixed renaming of dev_get (MB).
|
|
+ *
|
|
+ * Revision 1.44 2000/03/16 08:17:24 rgb
|
|
+ * Hardcode PF_KEYv2 support.
|
|
+ * Fixed minor bug checking AH header length.
|
|
+ *
|
|
+ * Revision 1.43 2000/03/14 12:26:59 rgb
|
|
+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
|
|
+ *
|
|
+ * Revision 1.42 2000/01/26 10:04:04 rgb
|
|
+ * Fixed inbound policy checking on transport mode bug.
|
|
+ * Fixed noisy 2.0 printk arguments.
|
|
+ *
|
|
+ * Revision 1.41 2000/01/24 20:58:02 rgb
|
|
+ * Improve debugging/reporting support for (disabled) inbound
|
|
+ * policy checking.
|
|
+ *
|
|
+ * Revision 1.40 2000/01/22 23:20:10 rgb
|
|
+ * Fixed up inboud policy checking code.
|
|
+ * Cleaned out unused crud.
|
|
+ *
|
|
+ * Revision 1.39 2000/01/21 06:15:29 rgb
|
|
+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
|
|
+ * Fixed cut-and-paste debug_tunnel to debug_rcv.
|
|
+ * Added inbound policy checking code, disabled.
|
|
+ * Simplified output code by updating ipp to post-IPIP decapsulation.
|
|
+ *
|
|
+ * elided pre-2000 comments. Use "cvs log"
|
|
+ *
|
|
+ *
|
|
+ * Local Variables:
|
|
+ * c-set-style: linux
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1870 @@
|
|
+/*
|
|
+ * Common routines for IPsec SA maintenance routines.
|
|
+ *
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_sa.c,v 1.30.2.2 2006/10/06 21:39:26 paul Exp $
|
|
+ *
|
|
+ * This is the file formerly known as "ipsec_xform.h"
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/vmalloc.h> /* vmalloc() */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <openswan.h>
|
|
+#ifdef SPINLOCK
|
|
+#ifdef SPINLOCK_23
|
|
+#include <linux/spinlock.h> /* *lock* */
|
|
+#else /* SPINLOCK_23 */
|
|
+#include <asm/spinlock.h> /* *lock* */
|
|
+#endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+
|
|
+#include "openswan/ipsec_stats.h"
|
|
+#include "openswan/ipsec_life.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_ipe4.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_esp.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#include "openswan/ipsec_alg.h"
|
|
+
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int debug_xform = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
|
|
+
|
|
+struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
|
|
+#ifdef SPINLOCK
|
|
+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
|
|
+#else /* SPINLOCK */
|
|
+spinlock_t tdb_lock;
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+struct ipsec_sadb ipsec_sadb;
|
|
+
|
|
+#if IPSEC_SA_REF_CODE
|
|
+
|
|
+/* the sub table must be narrower (or equal) in bits than the variable type
|
|
+ in the main table to count the number of unused entries in it. */
|
|
+typedef struct {
|
|
+ int testSizeOf_refSubTable :
|
|
+ ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
|
|
+} dummy;
|
|
+
|
|
+
|
|
+/* The field where the saref will be hosted in the skb must be wide enough to
|
|
+ accomodate the information it needs to store. */
|
|
+typedef struct {
|
|
+ int testSizeOf_refField :
|
|
+ (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
|
|
+} dummy2;
|
|
+
|
|
+
|
|
+#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
|
|
+
|
|
+
|
|
+void
|
|
+ipsec_SAtest(void)
|
|
+{
|
|
+ IPsecSAref_t SAref = 258;
|
|
+ struct ipsec_sa ips;
|
|
+ ips.ips_ref = 772;
|
|
+
|
|
+ printk("klips_debug:ipsec_SAtest: "
|
|
+ "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
|
|
+ "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
|
|
+ "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
|
|
+ "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
|
|
+ "IPSEC_SA_REF_TABLE_MASK=%x\n"
|
|
+ "IPSEC_SA_REF_ENTRY_MASK=%x\n"
|
|
+ "IPsecSAref2table(%d)=%u\n"
|
|
+ "IPsecSAref2entry(%d)=%u\n"
|
|
+ "IPsecSAref2NFmark(%d)=%u\n"
|
|
+ "IPsecSAref2SA(%d)=%p\n"
|
|
+ "IPsecSA2SAref(%p)=%d\n"
|
|
+ ,
|
|
+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
|
|
+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
|
|
+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
|
|
+ (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH,
|
|
+ IPSEC_SA_REF_TABLE_MASK,
|
|
+ IPSEC_SA_REF_ENTRY_MASK,
|
|
+ SAref, IPsecSAref2table(SAref),
|
|
+ SAref, IPsecSAref2entry(SAref),
|
|
+ SAref, IPsecSAref2NFmark(SAref),
|
|
+ SAref, IPsecSAref2SA(SAref),
|
|
+ (&ips), IPsecSA2SAref((&ips))
|
|
+ );
|
|
+ return;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_SAref_recycle(void)
|
|
+{
|
|
+ int table;
|
|
+ int entry;
|
|
+ int error = 0;
|
|
+
|
|
+ ipsec_sadb.refFreeListHead = -1;
|
|
+ ipsec_sadb.refFreeListTail = -1;
|
|
+
|
|
+ if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_recycle: "
|
|
+ "end of table reached, continuing at start..\n");
|
|
+ ipsec_sadb.refFreeListCont = 0;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_recycle: "
|
|
+ "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
|
|
+ ipsec_sadb.refFreeListCont,
|
|
+ (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
|
|
+ IPsecSAref2table(ipsec_sadb.refFreeListCont),
|
|
+ IPsecSAref2entry(ipsec_sadb.refFreeListCont));
|
|
+
|
|
+ for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
|
|
+ table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
|
|
+ table++) {
|
|
+ if(ipsec_sadb.refTable[table] == NULL) {
|
|
+ error = ipsec_SArefSubTable_alloc(table);
|
|
+ if(error) {
|
|
+ return error;
|
|
+ }
|
|
+ }
|
|
+ for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
|
|
+ entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
|
|
+ entry++) {
|
|
+ if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
|
|
+ ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
|
|
+ if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
|
|
+ ipsec_sadb.refFreeListHead = 0;
|
|
+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_recycle: "
|
|
+ "SArefFreeList refilled.\n");
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(ipsec_sadb.refFreeListTail == -1) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_recycle: "
|
|
+ "out of room in the SArefTable.\n");
|
|
+
|
|
+ return(-ENOSPC);
|
|
+ }
|
|
+
|
|
+ ipsec_sadb.refFreeListHead = 0;
|
|
+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_recycle: "
|
|
+ "SArefFreeList partly refilled to %d of %d.\n",
|
|
+ ipsec_sadb.refFreeListTail,
|
|
+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_SArefSubTable_alloc(unsigned table)
|
|
+{
|
|
+ unsigned entry;
|
|
+ struct IPsecSArefSubTable* SArefsub;
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SArefSubTable_alloc: "
|
|
+ "allocating %lu bytes for table %u of %u.\n",
|
|
+ (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
|
|
+ table,
|
|
+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
|
|
+
|
|
+ /* allocate another sub-table */
|
|
+ SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
|
|
+ if(SArefsub == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SArefSubTable_alloc: "
|
|
+ "error allocating memory for table %u of %u!\n",
|
|
+ table,
|
|
+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ /* add this sub-table to the main table */
|
|
+ ipsec_sadb.refTable[table] = SArefsub;
|
|
+
|
|
+ /* initialise each element to NULL */
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SArefSubTable_alloc: "
|
|
+ "initialising %u elements (2 ^ %u) of table %u.\n",
|
|
+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
|
|
+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
|
|
+ table);
|
|
+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
|
|
+ SArefsub->entry[entry] = NULL;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#endif /* IPSEC_SA_REF_CODE */
|
|
+
|
|
+int
|
|
+ipsec_saref_freelist_init(void)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_saref_freelist_init: "
|
|
+ "initialising %u elements of FreeList.\n",
|
|
+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
|
|
+
|
|
+ for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
|
|
+ ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
|
|
+ }
|
|
+ ipsec_sadb.refFreeListHead = -1;
|
|
+ ipsec_sadb.refFreeListCont = 0;
|
|
+ ipsec_sadb.refFreeListTail = -1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_sadb_init(void)
|
|
+{
|
|
+ int error = 0;
|
|
+ unsigned i;
|
|
+
|
|
+ for(i = 0; i < SADB_HASHMOD; i++) {
|
|
+ ipsec_sadb_hash[i] = NULL;
|
|
+ }
|
|
+ /* parts above are for the old style SADB hash table */
|
|
+
|
|
+
|
|
+#if IPSEC_SA_REF_CODE
|
|
+ /* initialise SA reference table */
|
|
+
|
|
+ /* initialise the main table */
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_init: "
|
|
+ "initialising main table of size %u (2 ^ %u).\n",
|
|
+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
|
|
+ IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
|
|
+ {
|
|
+ unsigned table;
|
|
+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
|
|
+ ipsec_sadb.refTable[table] = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* allocate the first sub-table */
|
|
+ error = ipsec_SArefSubTable_alloc(0);
|
|
+ if(error) {
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ error = ipsec_saref_freelist_init();
|
|
+#endif /* IPSEC_SA_REF_CODE */
|
|
+ return error;
|
|
+}
|
|
+
|
|
+#if IPSEC_SA_REF_CODE
|
|
+IPsecSAref_t
|
|
+ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
|
|
+{
|
|
+ IPsecSAref_t SAref;
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_alloc: "
|
|
+ "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
|
|
+ ipsec_sadb.refFreeListHead,
|
|
+ ipsec_sadb.refFreeListCont,
|
|
+ ipsec_sadb.refFreeListTail,
|
|
+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
|
|
+
|
|
+ if(ipsec_sadb.refFreeListHead == -1) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_alloc: "
|
|
+ "FreeList empty, recycling...\n");
|
|
+ *error = ipsec_SAref_recycle();
|
|
+ if(*error) {
|
|
+ return IPSEC_SAREF_NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
|
|
+ if(SAref == IPSEC_SAREF_NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_alloc: "
|
|
+ "unexpected error, refFreeListHead = %d points to invalid entry.\n",
|
|
+ ipsec_sadb.refFreeListHead);
|
|
+ *error = -ESPIPE;
|
|
+ return IPSEC_SAREF_NULL;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_alloc: "
|
|
+ "allocating SAref=%d, table=%u, entry=%u of %u.\n",
|
|
+ SAref,
|
|
+ IPsecSAref2table(SAref),
|
|
+ IPsecSAref2entry(SAref),
|
|
+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
|
|
+
|
|
+ ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
|
|
+ ipsec_sadb.refFreeListHead++;
|
|
+ if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_SAref_alloc: "
|
|
+ "last FreeList entry allocated, resetting list head to empty.\n");
|
|
+ ipsec_sadb.refFreeListHead = -1;
|
|
+ }
|
|
+
|
|
+ return SAref;
|
|
+}
|
|
+#endif /* IPSEC_SA_REF_CODE */
|
|
+
|
|
+int
|
|
+ipsec_sa_print(struct ipsec_sa *ips)
|
|
+{
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+ printk(KERN_INFO "klips_debug: SA:");
|
|
+ if(ips == NULL) {
|
|
+ printk("NULL\n");
|
|
+ return -ENOENT;
|
|
+ }
|
|
+ printk(" ref=%d", ips->ips_ref);
|
|
+ printk(" refcount=%d", atomic_read(&ips->ips_refcount));
|
|
+ if(ips->ips_hnext != NULL) {
|
|
+ printk(" hnext=0p%p", ips->ips_hnext);
|
|
+ }
|
|
+ if(ips->ips_inext != NULL) {
|
|
+ printk(" inext=0p%p", ips->ips_inext);
|
|
+ }
|
|
+ if(ips->ips_onext != NULL) {
|
|
+ printk(" onext=0p%p", ips->ips_onext);
|
|
+ }
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+ printk(" said=%s", sa_len ? sa : " (error)");
|
|
+ if(ips->ips_seq) {
|
|
+ printk(" seq=%u", ips->ips_seq);
|
|
+ }
|
|
+ if(ips->ips_pid) {
|
|
+ printk(" pid=%u", ips->ips_pid);
|
|
+ }
|
|
+ if(ips->ips_authalg) {
|
|
+ printk(" authalg=%u", ips->ips_authalg);
|
|
+ }
|
|
+ if(ips->ips_encalg) {
|
|
+ printk(" encalg=%u", ips->ips_encalg);
|
|
+ }
|
|
+ printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
|
|
+ if(ips->ips_replaywin) {
|
|
+ printk(" ooowin=%u", ips->ips_replaywin);
|
|
+ }
|
|
+ if(ips->ips_flags) {
|
|
+ printk(" flags=%u", ips->ips_flags);
|
|
+ }
|
|
+ if(ips->ips_addr_s) {
|
|
+ char buf[SUBNETTOA_BUF];
|
|
+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
|
|
+ 0, buf, sizeof(buf));
|
|
+ printk(" src=%s", buf);
|
|
+ }
|
|
+ if(ips->ips_addr_d) {
|
|
+ char buf[SUBNETTOA_BUF];
|
|
+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
|
|
+ 0, buf, sizeof(buf));
|
|
+ printk(" dst=%s", buf);
|
|
+ }
|
|
+ if(ips->ips_addr_p) {
|
|
+ char buf[SUBNETTOA_BUF];
|
|
+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
|
|
+ 0, buf, sizeof(buf));
|
|
+ printk(" proxy=%s", buf);
|
|
+ }
|
|
+ if(ips->ips_key_bits_a) {
|
|
+ printk(" key_bits_a=%u", ips->ips_key_bits_a);
|
|
+ }
|
|
+ if(ips->ips_key_bits_e) {
|
|
+ printk(" key_bits_e=%u", ips->ips_key_bits_e);
|
|
+ }
|
|
+
|
|
+ printk("\n");
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+struct ipsec_sa*
|
|
+ipsec_sa_alloc(int*error) /* pass in error var by pointer */
|
|
+{
|
|
+ struct ipsec_sa* ips;
|
|
+
|
|
+ if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_alloc: "
|
|
+ "memory allocation error\n");
|
|
+ *error = -ENOMEM;
|
|
+ return NULL;
|
|
+ }
|
|
+ memset((caddr_t)ips, 0, sizeof(*ips));
|
|
+#if IPSEC_SA_REF_CODE
|
|
+ ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_alloc: "
|
|
+ "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
|
|
+ (unsigned long) sizeof(*ips),
|
|
+ ips,
|
|
+ ips->ips_ref);
|
|
+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
|
|
+ kfree(ips);
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_alloc: "
|
|
+ "SAref allocation error\n");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ atomic_inc(&ips->ips_refcount);
|
|
+ IPsecSAref2SA(ips->ips_ref) = ips;
|
|
+#endif /* IPSEC_SA_REF_CODE */
|
|
+
|
|
+ *error = 0;
|
|
+ return(ips);
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_sa_free(struct ipsec_sa* ips)
|
|
+{
|
|
+ return ipsec_sa_wipe(ips);
|
|
+}
|
|
+
|
|
+struct ipsec_sa *
|
|
+ipsec_sa_getbyid(ip_said *said)
|
|
+{
|
|
+ int hashval;
|
|
+ struct ipsec_sa *ips;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+ if(said == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_error:ipsec_sa_getbyid: "
|
|
+ "null pointer passed in!\n");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ sa_len = satot(said, 0, sa, sizeof(sa));
|
|
+
|
|
+ hashval = IPS_HASH(said);
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_getbyid: "
|
|
+ "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
|
|
+ hashval,
|
|
+ sa_len ? sa : " (error)");
|
|
+
|
|
+ if((ips = ipsec_sadb_hash[hashval]) == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_getbyid: "
|
|
+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
|
|
+ hashval,
|
|
+ sa_len ? sa : " (error)");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ for (; ips; ips = ips->ips_hnext) {
|
|
+ if ((ips->ips_said.spi == said->spi) &&
|
|
+ (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
|
|
+ (ips->ips_said.proto == said->proto)) {
|
|
+ atomic_inc(&ips->ips_refcount);
|
|
+ return ips;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_getbyid: "
|
|
+ "no entry in linked list for hash=%d of SA:%s.\n",
|
|
+ hashval,
|
|
+ sa_len ? sa : " (error)");
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_sa_put(struct ipsec_sa *ips)
|
|
+{
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+ if(ips == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_error:ipsec_sa_put: "
|
|
+ "null pointer passed in!\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_put: "
|
|
+ "ipsec_sa SA:%s, ref:%d reference count decremented.\n",
|
|
+ sa_len ? sa : " (error)",
|
|
+ ips->ips_ref);
|
|
+
|
|
+ atomic_dec(&ips->ips_refcount);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
|
|
+*/
|
|
+int
|
|
+ipsec_sa_add(struct ipsec_sa *ips)
|
|
+{
|
|
+ int error = 0;
|
|
+ unsigned int hashval;
|
|
+
|
|
+ if(ips == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_error:ipsec_sa_add: "
|
|
+ "null pointer passed in!\n");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+ hashval = IPS_HASH(&ips->ips_said);
|
|
+
|
|
+ atomic_inc(&ips->ips_refcount);
|
|
+ spin_lock_bh(&tdb_lock);
|
|
+
|
|
+ ips->ips_hnext = ipsec_sadb_hash[hashval];
|
|
+ ipsec_sadb_hash[hashval] = ips;
|
|
+
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+/*
|
|
+ The ipsec_sa table better be locked before it is handed in, or races might happen
|
|
+*/
|
|
+int
|
|
+ipsec_sa_del(struct ipsec_sa *ips)
|
|
+{
|
|
+ unsigned int hashval;
|
|
+ struct ipsec_sa *ipstp;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+ if(ips == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_error:ipsec_sa_del: "
|
|
+ "null pointer passed in!\n");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+ if(ips->ips_inext || ips->ips_onext) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_error:ipsec_sa_del: "
|
|
+ "SA:%s still linked!\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ return -EMLINK;
|
|
+ }
|
|
+
|
|
+ hashval = IPS_HASH(&ips->ips_said);
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_del: "
|
|
+ "deleting SA:%s, hashval=%d.\n",
|
|
+ sa_len ? sa : " (error)",
|
|
+ hashval);
|
|
+ if(ipsec_sadb_hash[hashval] == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_del: "
|
|
+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
|
|
+ hashval,
|
|
+ sa_len ? sa : " (error)");
|
|
+ return -ENOENT;
|
|
+ }
|
|
+
|
|
+ if (ips == ipsec_sadb_hash[hashval]) {
|
|
+ ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
|
|
+ ips->ips_hnext = NULL;
|
|
+ atomic_dec(&ips->ips_refcount);
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_del: "
|
|
+ "successfully deleted first ipsec_sa in chain.\n");
|
|
+ return 0;
|
|
+ } else {
|
|
+ for (ipstp = ipsec_sadb_hash[hashval];
|
|
+ ipstp;
|
|
+ ipstp = ipstp->ips_hnext) {
|
|
+ if (ipstp->ips_hnext == ips) {
|
|
+ ipstp->ips_hnext = ips->ips_hnext;
|
|
+ ips->ips_hnext = NULL;
|
|
+ atomic_dec(&ips->ips_refcount);
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_del: "
|
|
+ "successfully deleted link in ipsec_sa chain.\n");
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_del: "
|
|
+ "no entries in linked list for hash=%d of SA:%s.\n",
|
|
+ hashval,
|
|
+ sa_len ? sa : " (error)");
|
|
+ return -ENOENT;
|
|
+}
|
|
+
|
|
+/*
|
|
+ The ipsec_sa table better be locked before it is handed in, or races
|
|
+ might happen
|
|
+*/
|
|
+int
|
|
+ipsec_sa_delchain(struct ipsec_sa *ips)
|
|
+{
|
|
+ struct ipsec_sa *ipsdel;
|
|
+ int error = 0;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+ if(ips == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_error:ipsec_sa_delchain: "
|
|
+ "null pointer passed in!\n");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_delchain: "
|
|
+ "passed SA:%s\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ while(ips->ips_onext != NULL) {
|
|
+ ips = ips->ips_onext;
|
|
+ }
|
|
+
|
|
+ while(ips) {
|
|
+ /* XXX send a pfkey message up to advise of deleted ipsec_sa */
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_delchain: "
|
|
+ "unlinking and delting SA:%s",
|
|
+ sa_len ? sa : " (error)");
|
|
+ ipsdel = ips;
|
|
+ ips = ips->ips_inext;
|
|
+ if(ips != NULL) {
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ", inext=%s",
|
|
+ sa_len ? sa : " (error)");
|
|
+ atomic_dec(&ipsdel->ips_refcount);
|
|
+ ipsdel->ips_inext = NULL;
|
|
+ atomic_dec(&ips->ips_refcount);
|
|
+ ips->ips_onext = NULL;
|
|
+ }
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ".\n");
|
|
+ if((error = ipsec_sa_del(ipsdel))) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_delchain: "
|
|
+ "ipsec_sa_del returned error %d.\n", -error);
|
|
+ return error;
|
|
+ }
|
|
+ if((error = ipsec_sa_wipe(ipsdel))) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_delchain: "
|
|
+ "ipsec_sa_wipe returned error %d.\n", -error);
|
|
+ return error;
|
|
+ }
|
|
+ }
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_sadb_cleanup(__u8 proto)
|
|
+{
|
|
+ unsigned i;
|
|
+ int error = 0;
|
|
+ struct ipsec_sa *ips, **ipsprev, *ipsdel;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_cleanup: "
|
|
+ "cleaning up proto=%d.\n",
|
|
+ proto);
|
|
+
|
|
+ spin_lock_bh(&tdb_lock);
|
|
+
|
|
+ for (i = 0; i < SADB_HASHMOD; i++) {
|
|
+ ipsprev = &(ipsec_sadb_hash[i]);
|
|
+ ips = ipsec_sadb_hash[i];
|
|
+ if(ips != NULL) {
|
|
+ atomic_inc(&ips->ips_refcount);
|
|
+ }
|
|
+ for(; ips != NULL;) {
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_cleanup: "
|
|
+ "checking SA:%s, hash=%d, ref=%d",
|
|
+ sa_len ? sa : " (error)",
|
|
+ i,
|
|
+ ips->ips_ref);
|
|
+ ipsdel = ips;
|
|
+ ips = ipsdel->ips_hnext;
|
|
+ if(ips != NULL) {
|
|
+ atomic_inc(&ips->ips_refcount);
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ", hnext=%s",
|
|
+ sa_len ? sa : " (error)");
|
|
+ }
|
|
+ if(*ipsprev != NULL) {
|
|
+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ", *ipsprev=%s",
|
|
+ sa_len ? sa : " (error)");
|
|
+ if((*ipsprev)->ips_hnext) {
|
|
+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ", *ipsprev->ips_hnext=%s",
|
|
+ sa_len ? sa : " (error)");
|
|
+ }
|
|
+ }
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ".\n");
|
|
+ if(proto == 0 || (proto == ipsdel->ips_said.proto)) {
|
|
+ sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_cleanup: "
|
|
+ "deleting SA chain:%s.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ if((error = ipsec_sa_delchain(ipsdel))) {
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ ipsprev = &(ipsec_sadb_hash[i]);
|
|
+ ips = ipsec_sadb_hash[i];
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_cleanup: "
|
|
+ "deleted SA chain:%s",
|
|
+ sa_len ? sa : " (error)");
|
|
+ if(ips != NULL) {
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ", ipsec_sadb_hash[%d]=%s",
|
|
+ i,
|
|
+ sa_len ? sa : " (error)");
|
|
+ }
|
|
+ if(*ipsprev != NULL) {
|
|
+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ", *ipsprev=%s",
|
|
+ sa_len ? sa : " (error)");
|
|
+ if((*ipsprev)->ips_hnext != NULL) {
|
|
+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ", *ipsprev->ips_hnext=%s",
|
|
+ sa_len ? sa : " (error)");
|
|
+ }
|
|
+ }
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ ".\n");
|
|
+ } else {
|
|
+ ipsprev = &ipsdel;
|
|
+ }
|
|
+ if(ipsdel != NULL) {
|
|
+ ipsec_sa_put(ipsdel);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ errlab:
|
|
+
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+
|
|
+
|
|
+#if IPSEC_SA_REF_CODE
|
|
+ /* clean up SA reference table */
|
|
+
|
|
+ /* go through the ref table and clean out all the SAs */
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_cleanup: "
|
|
+ "removing SAref entries and tables.");
|
|
+ {
|
|
+ unsigned table, entry;
|
|
+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_cleanup: "
|
|
+ "cleaning SAref table=%u.\n",
|
|
+ table);
|
|
+ if(ipsec_sadb.refTable[table] == NULL) {
|
|
+ printk("\n");
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_cleanup: "
|
|
+ "cleaned %u used refTables.\n",
|
|
+ table);
|
|
+ break;
|
|
+ }
|
|
+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
|
|
+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
|
|
+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
|
|
+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#endif /* IPSEC_SA_REF_CODE */
|
|
+
|
|
+ return(error);
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_sadb_free(void)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_free: "
|
|
+ "freeing SArefTable memory.\n");
|
|
+
|
|
+ /* clean up SA reference table */
|
|
+
|
|
+ /* go through the ref table and clean out all the SAs if any are
|
|
+ left and free table memory */
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_free: "
|
|
+ "removing SAref entries and tables.\n");
|
|
+ {
|
|
+ unsigned table, entry;
|
|
+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_free: "
|
|
+ "removing SAref table=%u.\n",
|
|
+ table);
|
|
+ if(ipsec_sadb.refTable[table] == NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sadb_free: "
|
|
+ "removed %u used refTables.\n",
|
|
+ table);
|
|
+ break;
|
|
+ }
|
|
+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
|
|
+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
|
|
+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
|
|
+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
|
|
+ }
|
|
+ }
|
|
+ vfree(ipsec_sadb.refTable[table]);
|
|
+ ipsec_sadb.refTable[table] = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return(error);
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_sa_wipe(struct ipsec_sa *ips)
|
|
+{
|
|
+ if(ips == NULL) {
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ /* if(atomic_dec_and_test(ips)) {
|
|
+ }; */
|
|
+
|
|
+#if IPSEC_SA_REF_CODE
|
|
+ /* remove me from the SArefTable */
|
|
+ {
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_wipe: "
|
|
+ "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
|
|
+ sa_len ? sa : " (error)",
|
|
+ ips,
|
|
+ ips->ips_ref,
|
|
+ IPsecSAref2table(IPsecSA2SAref(ips)),
|
|
+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
|
|
+ IPsecSAref2entry(IPsecSA2SAref(ips)));
|
|
+ }
|
|
+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
|
|
+ KLIPS_PRINT(debug_xform,
|
|
+ "klips_debug:ipsec_sa_wipe: "
|
|
+ "why does this SA not have a valid SAref?.\n");
|
|
+ }
|
|
+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
|
|
+ ips->ips_ref = IPSEC_SAREF_NULL;
|
|
+ ipsec_sa_put(ips);
|
|
+#endif /* IPSEC_SA_REF_CODE */
|
|
+
|
|
+ /* paranoid clean up */
|
|
+ if(ips->ips_addr_s != NULL) {
|
|
+ memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
|
|
+ kfree(ips->ips_addr_s);
|
|
+ }
|
|
+ ips->ips_addr_s = NULL;
|
|
+
|
|
+ if(ips->ips_addr_d != NULL) {
|
|
+ memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
|
|
+ kfree(ips->ips_addr_d);
|
|
+ }
|
|
+ ips->ips_addr_d = NULL;
|
|
+
|
|
+ if(ips->ips_addr_p != NULL) {
|
|
+ memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
|
|
+ kfree(ips->ips_addr_p);
|
|
+ }
|
|
+ ips->ips_addr_p = NULL;
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ if(ips->ips_natt_oa) {
|
|
+ memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
|
|
+ kfree(ips->ips_natt_oa);
|
|
+ }
|
|
+ ips->ips_natt_oa = NULL;
|
|
+#endif
|
|
+
|
|
+ if(ips->ips_key_a != NULL) {
|
|
+ memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
|
|
+ kfree(ips->ips_key_a);
|
|
+ }
|
|
+ ips->ips_key_a = NULL;
|
|
+
|
|
+ if(ips->ips_key_e != NULL) {
|
|
+ if (ips->ips_alg_enc &&
|
|
+ ips->ips_alg_enc->ixt_e_destroy_key)
|
|
+ {
|
|
+ ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
|
|
+ ips->ips_key_e);
|
|
+ } else
|
|
+ {
|
|
+ memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
|
|
+ kfree(ips->ips_key_e);
|
|
+ }
|
|
+ }
|
|
+ ips->ips_key_e = NULL;
|
|
+
|
|
+ if(ips->ips_iv != NULL) {
|
|
+ memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
|
|
+ kfree(ips->ips_iv);
|
|
+ }
|
|
+ ips->ips_iv = NULL;
|
|
+
|
|
+ if(ips->ips_ident_s.data != NULL) {
|
|
+ memset((caddr_t)(ips->ips_ident_s.data),
|
|
+ 0,
|
|
+ ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
|
|
+ kfree(ips->ips_ident_s.data);
|
|
+ }
|
|
+ ips->ips_ident_s.data = NULL;
|
|
+
|
|
+ if(ips->ips_ident_d.data != NULL) {
|
|
+ memset((caddr_t)(ips->ips_ident_d.data),
|
|
+ 0,
|
|
+ ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
|
|
+ kfree(ips->ips_ident_d.data);
|
|
+ }
|
|
+ ips->ips_ident_d.data = NULL;
|
|
+
|
|
+ if (ips->ips_alg_enc||ips->ips_alg_auth) {
|
|
+ ipsec_alg_sa_wipe(ips);
|
|
+ }
|
|
+
|
|
+ memset((caddr_t)ips, 0, sizeof(*ips));
|
|
+ kfree(ips);
|
|
+ ips = NULL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+extern int sysctl_ipsec_debug_verbose;
|
|
+
|
|
+int ipsec_sa_init(struct ipsec_sa *ipsp)
|
|
+{
|
|
+ int i;
|
|
+ int error = 0;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+ char ipaddr_txt[ADDRTOA_BUF];
|
|
+ char ipaddr2_txt[ADDRTOA_BUF];
|
|
+#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
|
|
+ unsigned char kb[AHMD596_BLKLEN];
|
|
+#endif
|
|
+ struct ipsec_alg_enc *ixt_e = NULL;
|
|
+ struct ipsec_alg_auth *ixt_a = NULL;
|
|
+
|
|
+ if(ipsp == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "ipsp is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&ipsp->ips_said, 0, sa, sizeof(sa));
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "(pfkey defined) called for SA:%s\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "calling init routine of %s%s%s\n",
|
|
+ IPS_XFORM_NAME(ipsp));
|
|
+
|
|
+ switch(ipsp->ips_said.proto) {
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPIP
|
|
+ case IPPROTO_IPIP: {
|
|
+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
|
|
+ 0,
|
|
+ ipaddr_txt, sizeof(ipaddr_txt));
|
|
+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
|
|
+ 0,
|
|
+ ipaddr2_txt, sizeof(ipaddr_txt));
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
|
|
+ ipaddr_txt,
|
|
+ ipaddr2_txt);
|
|
+ }
|
|
+ break;
|
|
+#endif /* !CONFIG_KLIPS_IPIP */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_AH
|
|
+ case IPPROTO_AH:
|
|
+ switch(ipsp->ips_authalg) {
|
|
+# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ case AH_MD5: {
|
|
+ unsigned char *akp;
|
|
+ unsigned int aks;
|
|
+ MD5_CTX *ictx;
|
|
+ MD5_CTX *octx;
|
|
+
|
|
+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
|
|
+ ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+# if KLIPS_DIVULGE_HMAC_KEY
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
|
|
+# endif /* KLIPS_DIVULGE_HMAC_KEY */
|
|
+
|
|
+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
|
|
+
|
|
+ /* save the pointer to the key material */
|
|
+ akp = ipsp->ips_key_a;
|
|
+ aks = ipsp->ips_key_a_size;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "allocating %lu bytes for md5_ctx.\n",
|
|
+ (unsigned long) sizeof(struct md5_ctx));
|
|
+ if((ipsp->ips_key_a = (caddr_t)
|
|
+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
|
|
+ ipsp->ips_key_a = akp;
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
|
|
+
|
|
+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
|
|
+ kb[i] = akp[i] ^ HMAC_IPAD;
|
|
+ }
|
|
+ for (; i < AHMD596_BLKLEN; i++) {
|
|
+ kb[i] = HMAC_IPAD;
|
|
+ }
|
|
+
|
|
+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
|
|
+ osMD5Init(ictx);
|
|
+ osMD5Update(ictx, kb, AHMD596_BLKLEN);
|
|
+
|
|
+ for (i = 0; i < AHMD596_BLKLEN; i++) {
|
|
+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
|
|
+ }
|
|
+
|
|
+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
|
|
+ osMD5Init(octx);
|
|
+ osMD5Update(octx, kb, AHMD596_BLKLEN);
|
|
+
|
|
+# if KLIPS_DIVULGE_HMAC_KEY
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
|
|
+ ((__u32*)ictx)[0],
|
|
+ ((__u32*)ictx)[1],
|
|
+ ((__u32*)ictx)[2],
|
|
+ ((__u32*)ictx)[3],
|
|
+ ((__u32*)octx)[0],
|
|
+ ((__u32*)octx)[1],
|
|
+ ((__u32*)octx)[2],
|
|
+ ((__u32*)octx)[3] );
|
|
+# endif /* KLIPS_DIVULGE_HMAC_KEY */
|
|
+
|
|
+ /* zero key buffer -- paranoid */
|
|
+ memset(akp, 0, aks);
|
|
+ kfree(akp);
|
|
+ }
|
|
+ break;
|
|
+# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ case AH_SHA: {
|
|
+ unsigned char *akp;
|
|
+ unsigned int aks;
|
|
+ SHA1_CTX *ictx;
|
|
+ SHA1_CTX *octx;
|
|
+
|
|
+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
|
|
+ ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+# if KLIPS_DIVULGE_HMAC_KEY
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
|
|
+# endif /* KLIPS_DIVULGE_HMAC_KEY */
|
|
+
|
|
+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
|
|
+
|
|
+ /* save the pointer to the key material */
|
|
+ akp = ipsp->ips_key_a;
|
|
+ aks = ipsp->ips_key_a_size;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "allocating %lu bytes for sha1_ctx.\n",
|
|
+ (unsigned long) sizeof(struct sha1_ctx));
|
|
+ if((ipsp->ips_key_a = (caddr_t)
|
|
+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
|
|
+ ipsp->ips_key_a = akp;
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
|
|
+
|
|
+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
|
|
+ kb[i] = akp[i] ^ HMAC_IPAD;
|
|
+ }
|
|
+ for (; i < AHMD596_BLKLEN; i++) {
|
|
+ kb[i] = HMAC_IPAD;
|
|
+ }
|
|
+
|
|
+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
|
|
+ SHA1Init(ictx);
|
|
+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
|
|
+
|
|
+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
|
|
+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
|
|
+ }
|
|
+
|
|
+ octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
|
|
+ SHA1Init(octx);
|
|
+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
|
|
+
|
|
+# if KLIPS_DIVULGE_HMAC_KEY
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
|
|
+ ((__u32*)ictx)[0],
|
|
+ ((__u32*)ictx)[1],
|
|
+ ((__u32*)ictx)[2],
|
|
+ ((__u32*)ictx)[3],
|
|
+ ((__u32*)octx)[0],
|
|
+ ((__u32*)octx)[1],
|
|
+ ((__u32*)octx)[2],
|
|
+ ((__u32*)octx)[3] );
|
|
+# endif /* KLIPS_DIVULGE_HMAC_KEY */
|
|
+ /* zero key buffer -- paranoid */
|
|
+ memset(akp, 0, aks);
|
|
+ kfree(akp);
|
|
+ }
|
|
+ break;
|
|
+# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "authalg=%d support not available in the kernel",
|
|
+ ipsp->ips_authalg);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AH */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+ case IPPROTO_ESP:
|
|
+ {
|
|
+#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
|
|
+ unsigned char *akp;
|
|
+ unsigned int aks;
|
|
+#endif
|
|
+
|
|
+ ipsec_alg_sa_init(ipsp);
|
|
+ ixt_e=ipsp->ips_alg_enc;
|
|
+
|
|
+ if (ixt_e == NULL) {
|
|
+ if(printk_ratelimit()) {
|
|
+ printk(KERN_INFO
|
|
+ "ipsec_sa_init: "
|
|
+ "encalg=%d support not available in the kernel",
|
|
+ ipsp->ips_encalg);
|
|
+ }
|
|
+ SENDERR(ENOENT);
|
|
+ }
|
|
+
|
|
+ ipsp->ips_iv_size = ixt_e->ixt_common.ixt_support.ias_ivlen/8;
|
|
+
|
|
+ /* Create IV */
|
|
+ if (ipsp->ips_iv_size) {
|
|
+ if((ipsp->ips_iv = (caddr_t)
|
|
+ kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) {
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ prng_bytes(&ipsec_prng,
|
|
+ (char *)ipsp->ips_iv,
|
|
+ ipsp->ips_iv_size);
|
|
+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
|
|
+ }
|
|
+
|
|
+ if ((error=ipsec_alg_enc_key_create(ipsp)) < 0)
|
|
+ SENDERR(-error);
|
|
+
|
|
+ if ((ixt_a=ipsp->ips_alg_auth)) {
|
|
+ if ((error=ipsec_alg_auth_key_create(ipsp)) < 0)
|
|
+ SENDERR(-error);
|
|
+ } else
|
|
+
|
|
+ switch(ipsp->ips_authalg) {
|
|
+# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ case AH_MD5: {
|
|
+ MD5_CTX *ictx;
|
|
+ MD5_CTX *octx;
|
|
+
|
|
+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
|
|
+ ipsp->ips_key_bits_a,
|
|
+ AHMD596_KLEN * 8);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+# if KLIPS_DIVULGE_HMAC_KEY
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
|
|
+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
|
|
+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
|
|
+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
|
|
+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
|
|
+# endif /* KLIPS_DIVULGE_HMAC_KEY */
|
|
+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
|
|
+
|
|
+ /* save the pointer to the key material */
|
|
+ akp = ipsp->ips_key_a;
|
|
+ aks = ipsp->ips_key_a_size;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "allocating %lu bytes for md5_ctx.\n",
|
|
+ (unsigned long) sizeof(struct md5_ctx));
|
|
+ if((ipsp->ips_key_a = (caddr_t)
|
|
+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
|
|
+ ipsp->ips_key_a = akp;
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
|
|
+
|
|
+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
|
|
+ kb[i] = akp[i] ^ HMAC_IPAD;
|
|
+ }
|
|
+ for (; i < AHMD596_BLKLEN; i++) {
|
|
+ kb[i] = HMAC_IPAD;
|
|
+ }
|
|
+
|
|
+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
|
|
+ osMD5Init(ictx);
|
|
+ osMD5Update(ictx, kb, AHMD596_BLKLEN);
|
|
+
|
|
+ for (i = 0; i < AHMD596_BLKLEN; i++) {
|
|
+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
|
|
+ }
|
|
+
|
|
+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
|
|
+ osMD5Init(octx);
|
|
+ osMD5Update(octx, kb, AHMD596_BLKLEN);
|
|
+
|
|
+# if KLIPS_DIVULGE_HMAC_KEY
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
|
|
+ ((__u32*)ictx)[0],
|
|
+ ((__u32*)ictx)[1],
|
|
+ ((__u32*)ictx)[2],
|
|
+ ((__u32*)ictx)[3],
|
|
+ ((__u32*)octx)[0],
|
|
+ ((__u32*)octx)[1],
|
|
+ ((__u32*)octx)[2],
|
|
+ ((__u32*)octx)[3] );
|
|
+# endif /* KLIPS_DIVULGE_HMAC_KEY */
|
|
+ /* paranoid */
|
|
+ memset(akp, 0, aks);
|
|
+ kfree(akp);
|
|
+ break;
|
|
+ }
|
|
+# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ case AH_SHA: {
|
|
+ SHA1_CTX *ictx;
|
|
+ SHA1_CTX *octx;
|
|
+
|
|
+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
|
|
+ ipsp->ips_key_bits_a,
|
|
+ AHSHA196_KLEN * 8);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+# if KLIPS_DIVULGE_HMAC_KEY
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
|
|
+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
|
|
+# endif /* KLIPS_DIVULGE_HMAC_KEY */
|
|
+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
|
|
+
|
|
+ /* save the pointer to the key material */
|
|
+ akp = ipsp->ips_key_a;
|
|
+ aks = ipsp->ips_key_a_size;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "allocating %lu bytes for sha1_ctx.\n",
|
|
+ (unsigned long) sizeof(struct sha1_ctx));
|
|
+ if((ipsp->ips_key_a = (caddr_t)
|
|
+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
|
|
+ ipsp->ips_key_a = akp;
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
|
|
+
|
|
+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
|
|
+ kb[i] = akp[i] ^ HMAC_IPAD;
|
|
+ }
|
|
+ for (; i < AHMD596_BLKLEN; i++) {
|
|
+ kb[i] = HMAC_IPAD;
|
|
+ }
|
|
+
|
|
+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
|
|
+ SHA1Init(ictx);
|
|
+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
|
|
+
|
|
+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
|
|
+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
|
|
+ }
|
|
+
|
|
+ octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
|
|
+ SHA1Init(octx);
|
|
+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
|
|
+
|
|
+# if KLIPS_DIVULGE_HMAC_KEY
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "ipsec_sa_init: "
|
|
+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
|
|
+ ((__u32*)ictx)[0],
|
|
+ ((__u32*)ictx)[1],
|
|
+ ((__u32*)ictx)[2],
|
|
+ ((__u32*)ictx)[3],
|
|
+ ((__u32*)octx)[0],
|
|
+ ((__u32*)octx)[1],
|
|
+ ((__u32*)octx)[2],
|
|
+ ((__u32*)octx)[3] );
|
|
+# endif /* KLIPS_DIVULGE_HMAC_KEY */
|
|
+ memset(akp, 0, aks);
|
|
+ kfree(akp);
|
|
+ break;
|
|
+ }
|
|
+# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ case AH_NONE:
|
|
+ break;
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "ipsec_sa_init: "
|
|
+ "authalg=%d support not available in the kernel.\n",
|
|
+ ipsp->ips_authalg);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+#endif /* !CONFIG_KLIPS_ESP */
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ case IPPROTO_COMP:
|
|
+ ipsp->ips_comp_adapt_tries = 0;
|
|
+ ipsp->ips_comp_adapt_skip = 0;
|
|
+ ipsp->ips_comp_ratio_cbytes = 0;
|
|
+ ipsp->ips_comp_ratio_dbytes = 0;
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ default:
|
|
+ printk(KERN_ERR "KLIPS sa initialization: "
|
|
+ "proto=%d unknown.\n",
|
|
+ ipsp->ips_said.proto);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ return(error);
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_sa.c,v $
|
|
+ * Revision 1.30.2.2 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.30.2.1 2006/04/20 16:33:07 mcr
|
|
+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
|
|
+ * Fix in-kernel module compilation. Sub-makefiles do not work.
|
|
+ *
|
|
+ * Revision 1.30 2005/05/24 01:02:35 mcr
|
|
+ * some refactoring/simplification of situation where alg
|
|
+ * is not found.
|
|
+ *
|
|
+ * Revision 1.29 2005/05/18 19:13:28 mcr
|
|
+ * rename debug messages. make sure that algo not found is not
|
|
+ * a debug message.
|
|
+ *
|
|
+ * Revision 1.28 2005/05/11 01:30:20 mcr
|
|
+ * removed "poor-man"s OOP in favour of proper C structures.
|
|
+ *
|
|
+ * Revision 1.27 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.26 2005/04/14 20:56:24 mcr
|
|
+ * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
|
|
+ *
|
|
+ * Revision 1.25 2004/08/22 20:12:16 mcr
|
|
+ * one more KLIPS_NAT->IPSEC_NAT.
|
|
+ *
|
|
+ * Revision 1.24 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.23 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.22.2.1 2003/12/22 15:25:52 jjo
|
|
+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.22 2003/12/10 01:14:27 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.21 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.20.4.1 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.20 2003/02/06 01:50:34 rgb
|
|
+ * Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0.
|
|
+ *
|
|
+ * Revision 1.19 2003/01/30 02:32:22 rgb
|
|
+ *
|
|
+ * Rename SAref table macro names for clarity.
|
|
+ * Transmit error code through to caller from callee for better diagnosis of problems.
|
|
+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
|
|
+ *
|
|
+ * Revision 1.18 2002/10/12 23:11:53 dhr
|
|
+ *
|
|
+ * [KenB + DHR] more 64-bit cleanup
|
|
+ *
|
|
+ * Revision 1.17 2002/10/07 18:31:43 rgb
|
|
+ * Move field width sanity checks to ipsec_sa.c
|
|
+ *
|
|
+ * Revision 1.16 2002/09/20 15:41:02 rgb
|
|
+ * Re-wrote most of the SAref code to eliminate Entry pointers.
|
|
+ * Added SAref code compiler directive switch.
|
|
+ * Added a saref test function for testing macros.
|
|
+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
|
|
+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
|
|
+ * of freeing newly created structures when clearing the reftable upon startup
|
|
+ * to start from a known state.
|
|
+ * Place all ipsec sadb globals into one struct.
|
|
+ * Rework saref freelist.
|
|
+ * Added memory allocation debugging.
|
|
+ *
|
|
+ * Revision 1.15 2002/09/20 05:01:44 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.14 2002/08/13 19:01:25 mcr
|
|
+ * patches from kenb to permit compilation of FreeSWAN on ia64.
|
|
+ * des library patched to use proper DES_LONG type for ia64.
|
|
+ *
|
|
+ * Revision 1.13 2002/07/29 03:06:20 mcr
|
|
+ * get rid of variable not used warnings.
|
|
+ *
|
|
+ * Revision 1.12 2002/07/26 08:48:31 rgb
|
|
+ * Added SA ref table code.
|
|
+ *
|
|
+ * Revision 1.11 2002/06/04 16:48:49 rgb
|
|
+ * Tidied up pointer code for processor independance.
|
|
+ *
|
|
+ * Revision 1.10 2002/05/23 07:16:17 rgb
|
|
+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
|
|
+ * Pointer clean-up.
|
|
+ * Added refcount code.
|
|
+ * Convert "usecount" to "refcount" to remove ambiguity.
|
|
+ *
|
|
+ * Revision 1.9 2002/05/14 02:34:49 rgb
|
|
+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
|
|
+ * with "put" usage in the kernel.
|
|
+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
|
|
+ * ipsec_sa or ipsec_sa.
|
|
+ * Added some preliminary refcount code.
|
|
+ *
|
|
+ * Revision 1.8 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.7 2002/04/24 07:36:30 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_sa.c,v
|
|
+ *
|
|
+ * Revision 1.6 2002/04/20 00:12:25 rgb
|
|
+ * Added esp IV CBC attack fix, disabled.
|
|
+ *
|
|
+ * Revision 1.5 2002/01/29 17:17:56 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.4 2002/01/29 04:00:52 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.3 2002/01/29 02:13:18 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.2 2001/11/26 09:16:15 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.1.2.2 2001/10/22 21:05:41 mcr
|
|
+ * removed phony prototype for des_set_key.
|
|
+ *
|
|
+ * Revision 1.1.2.1 2001/09/25 02:24:57 mcr
|
|
+ * struct tdb -> struct ipsec_sa.
|
|
+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
|
|
+ * ipsec_xform.c removed. header file still contains useful things.
|
|
+ *
|
|
+ *
|
|
+ *
|
|
+ * CLONED from ipsec_xform.c:
|
|
+ * Revision 1.53 2001/09/08 21:13:34 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.52 2001/06/14 19:35:11 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.51 2001/05/30 08:14:03 rgb
|
|
+ * Removed vestiges of esp-null transforms.
|
|
+ *
|
|
+ * Revision 1.50 2001/05/03 19:43:18 rgb
|
|
+ * Initialise error return variable.
|
|
+ * Update SENDERR macro.
|
|
+ * Fix sign of error return code for ipsec_tdbcleanup().
|
|
+ * Use more appropriate return code for ipsec_tdbwipe().
|
|
+ *
|
|
+ * Revision 1.49 2001/04/19 18:56:17 rgb
|
|
+ * Fixed tdb table locking comments.
|
|
+ *
|
|
+ * Revision 1.48 2001/02/27 22:24:55 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.47 2000/11/06 04:32:08 rgb
|
|
+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
|
|
+ *
|
|
+ * Revision 1.46 2000/09/20 16:21:57 rgb
|
|
+ * Cleaned up ident string alloc/free.
|
|
+ *
|
|
+ * Revision 1.45 2000/09/08 19:16:51 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
|
|
+ *
|
|
+ * Revision 1.44 2000/08/30 05:29:04 rgb
|
|
+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
|
|
+ *
|
|
+ * Revision 1.43 2000/08/18 21:30:41 rgb
|
|
+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
|
|
+ *
|
|
+ * Revision 1.42 2000/08/01 14:51:51 rgb
|
|
+ * Removed _all_ remaining traces of DES.
|
|
+ *
|
|
+ * Revision 1.41 2000/07/28 14:58:31 rgb
|
|
+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
|
|
+ *
|
|
+ * Revision 1.40 2000/06/28 05:50:11 rgb
|
|
+ * Actually set iv_bits.
|
|
+ *
|
|
+ * Revision 1.39 2000/05/10 23:11:09 rgb
|
|
+ * Added netlink debugging output.
|
|
+ * Added a cast to quiet down the ntohl bug.
|
|
+ *
|
|
+ * Revision 1.38 2000/05/10 19:18:42 rgb
|
|
+ * Cast output of ntohl so that the broken prototype doesn't make our
|
|
+ * compile noisy.
|
|
+ *
|
|
+ * Revision 1.37 2000/03/16 14:04:59 rgb
|
|
+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
|
|
+ *
|
|
+ * Revision 1.36 2000/01/26 10:11:28 rgb
|
|
+ * Fixed spacing in error text causing run-in words.
|
|
+ *
|
|
+ * Revision 1.35 2000/01/21 06:17:16 rgb
|
|
+ * Tidied up compiler directive indentation for readability.
|
|
+ * Added ictx,octx vars for simplification.(kravietz)
|
|
+ * Added macros for HMAC padding magic numbers.(kravietz)
|
|
+ * Fixed missing key length reporting bug.
|
|
+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
|
|
+ *
|
|
+ * Revision 1.34 1999/12/08 00:04:19 rgb
|
|
+ * Fixed SA direction overwriting bug for netlink users.
|
|
+ *
|
|
+ * Revision 1.33 1999/12/01 22:16:44 rgb
|
|
+ * Minor formatting changes in ESP MD5 initialisation.
|
|
+ *
|
|
+ * Revision 1.32 1999/11/25 09:06:36 rgb
|
|
+ * Fixed error return messages, should be returning negative numbers.
|
|
+ * Implemented SENDERR macro for propagating error codes.
|
|
+ * Added debug message and separate error code for algorithms not compiled
|
|
+ * in.
|
|
+ *
|
|
+ * Revision 1.31 1999/11/23 23:06:26 rgb
|
|
+ * Sort out pfkey and freeswan headers, putting them in a library path.
|
|
+ *
|
|
+ * Revision 1.30 1999/11/18 04:09:20 rgb
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ *
|
|
+ * Revision 1.29 1999/11/17 15:53:40 rgb
|
|
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
|
|
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
|
|
+ * klips/net/ipsec/Makefile.
|
|
+ *
|
|
+ * Revision 1.28 1999/10/18 20:04:01 rgb
|
|
+ * Clean-out unused cruft.
|
|
+ *
|
|
+ * Revision 1.27 1999/10/03 19:01:03 rgb
|
|
+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
|
|
+ *
|
|
+ * Revision 1.26 1999/10/01 16:22:24 rgb
|
|
+ * Switch from assignment init. to functional init. of spinlocks.
|
|
+ *
|
|
+ * Revision 1.25 1999/10/01 15:44:54 rgb
|
|
+ * Move spinlock header include to 2.1> scope.
|
|
+ *
|
|
+ * Revision 1.24 1999/10/01 00:03:46 rgb
|
|
+ * Added tdb structure locking.
|
|
+ * Minor formatting changes.
|
|
+ * Add function to initialize tdb hash table.
|
|
+ *
|
|
+ * Revision 1.23 1999/05/25 22:42:12 rgb
|
|
+ * Add deltdbchain() debugging.
|
|
+ *
|
|
+ * Revision 1.22 1999/05/25 21:24:31 rgb
|
|
+ * Add debugging statements to deltdbchain().
|
|
+ *
|
|
+ * Revision 1.21 1999/05/25 03:51:48 rgb
|
|
+ * Refix error return code.
|
|
+ *
|
|
+ * Revision 1.20 1999/05/25 03:34:07 rgb
|
|
+ * Fix error return for flush.
|
|
+ *
|
|
+ * Revision 1.19 1999/05/09 03:25:37 rgb
|
|
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
|
|
+ *
|
|
+ * Revision 1.18 1999/05/05 22:02:32 rgb
|
|
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
|
|
+ *
|
|
+ * Revision 1.17 1999/04/29 15:20:16 rgb
|
|
+ * Change gettdb parameter to a pointer to reduce stack loading and
|
|
+ * facilitate parameter sanity checking.
|
|
+ * Add sanity checking for null pointer arguments.
|
|
+ * Add debugging instrumentation.
|
|
+ * Add function deltdbchain() which will take care of unlinking,
|
|
+ * zeroing and deleting a chain of tdbs.
|
|
+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
|
|
+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
|
|
+ * structures.
|
|
+ *
|
|
+ * Revision 1.16 1999/04/16 15:36:29 rgb
|
|
+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
|
|
+ *
|
|
+ * Revision 1.15 1999/04/11 00:29:01 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.14 1999/04/06 04:54:28 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.13 1999/02/19 18:23:01 rgb
|
|
+ * Nix debug off compile warning.
|
|
+ *
|
|
+ * Revision 1.12 1999/02/17 16:52:16 rgb
|
|
+ * Consolidate satoa()s for space and speed efficiency.
|
|
+ * Convert DEBUG_IPSEC to KLIPS_PRINT
|
|
+ * Clean out unused cruft.
|
|
+ * Ditch NET_IPIP dependancy.
|
|
+ * Loop for 3des key setting.
|
|
+ *
|
|
+ * Revision 1.11 1999/01/26 02:09:05 rgb
|
|
+ * Remove ah/esp/IPIP switching on include files.
|
|
+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
|
|
+ * Removed dead code.
|
|
+ * Clean up debug code when switched off.
|
|
+ * Remove references to INET_GET_PROTOCOL.
|
|
+ * Added code exclusion macros to reduce code from unused algorithms.
|
|
+ *
|
|
+ * Revision 1.10 1999/01/22 06:28:55 rgb
|
|
+ * Cruft clean-out.
|
|
+ * Put random IV generation in kernel.
|
|
+ * Added algorithm switch code.
|
|
+ * Enhanced debugging.
|
|
+ * 64-bit clean-up.
|
|
+ *
|
|
+ * Revision 1.9 1998/11/30 13:22:55 rgb
|
|
+ * Rationalised all the klips kernel file headers. They are much shorter
|
|
+ * now and won't conflict under RH5.2.
|
|
+ *
|
|
+ * Revision 1.8 1998/11/25 04:59:06 rgb
|
|
+ * Add conditionals for no IPIP tunnel code.
|
|
+ * Delete commented out code.
|
|
+ *
|
|
+ * Revision 1.7 1998/10/31 06:50:41 rgb
|
|
+ * Convert xform ASCII names to no spaces.
|
|
+ * Fixed up comments in #endif directives.
|
|
+ *
|
|
+ * Revision 1.6 1998/10/19 14:44:28 rgb
|
|
+ * Added inclusion of freeswan.h.
|
|
+ * sa_id structure implemented and used: now includes protocol.
|
|
+ *
|
|
+ * Revision 1.5 1998/10/09 04:32:19 rgb
|
|
+ * Added 'klips_debug' prefix to all klips printk debug statements.
|
|
+ *
|
|
+ * Revision 1.4 1998/08/12 00:11:31 rgb
|
|
+ * Added new xform functions to the xform table.
|
|
+ * Fixed minor debug output spelling error.
|
|
+ *
|
|
+ * Revision 1.3 1998/07/09 17:45:31 rgb
|
|
+ * Clarify algorithm not available message.
|
|
+ *
|
|
+ * Revision 1.2 1998/06/23 03:00:51 rgb
|
|
+ * Check for presence of IPIP protocol if it is setup one way (we don't
|
|
+ * know what has been set up the other way and can only assume it will be
|
|
+ * symmetrical with the exception of keys).
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:51 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.3 1998/06/11 05:54:59 rgb
|
|
+ * Added transform version string pointer to xformsw initialisations.
|
|
+ *
|
|
+ * Revision 1.2 1998/04/21 21:28:57 rgb
|
|
+ * Rearrange debug switches to change on the fly debug output from user
|
|
+ * space. Only kernel changes checked in at this time. radij.c was also
|
|
+ * changed to temporarily remove buggy debugging code in rj_delete causing
|
|
+ * an OOPS and hence, netlink device open errors.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:13 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.5 1997/06/03 04:24:48 ji
|
|
+ * Added ESP-3DES-MD5-96
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * Added new transforms.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:39:04 ji
|
|
+ * Minor cleanups.
|
|
+ * Rationalized debugging code.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,219 @@
|
|
+/*
|
|
+ * RCSID $Id: ipsec_sha1.c,v 1.9 2004/04/06 02:49:26 mcr Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * The rest of the code is derived from sha1.c by Steve Reid, which is
|
|
+ * public domain.
|
|
+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
|
|
+ */
|
|
+
|
|
+#include <asm/byteorder.h>
|
|
+#include <linux/string.h>
|
|
+
|
|
+#include "openswan/ipsec_sha1.h"
|
|
+
|
|
+#if defined(rol)
|
|
+#undef rol
|
|
+#endif
|
|
+
|
|
+#define SHA1HANDSOFF
|
|
+
|
|
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
|
+
|
|
+/* blk0() and blk() perform the initial expand. */
|
|
+/* I got the idea of expanding during the round function from SSLeay */
|
|
+#ifdef __LITTLE_ENDIAN
|
|
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|
|
+ |(rol(block->l[i],8)&0x00FF00FF))
|
|
+#else
|
|
+#define blk0(i) block->l[i]
|
|
+#endif
|
|
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
|
|
+ ^block->l[(i+2)&15]^block->l[i&15],1))
|
|
+
|
|
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
|
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
|
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
|
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
|
|
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
|
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
|
+
|
|
+
|
|
+/* Hash a single 512-bit block. This is the core of the algorithm. */
|
|
+
|
|
+void SHA1Transform(__u32 state[5], __u8 buffer[64])
|
|
+{
|
|
+__u32 a, b, c, d, e;
|
|
+typedef union {
|
|
+ unsigned char c[64];
|
|
+ __u32 l[16];
|
|
+} CHAR64LONG16;
|
|
+CHAR64LONG16* block;
|
|
+#ifdef SHA1HANDSOFF
|
|
+static unsigned char workspace[64];
|
|
+ block = (CHAR64LONG16*)workspace;
|
|
+ memcpy(block, buffer, 64);
|
|
+#else
|
|
+ block = (CHAR64LONG16*)buffer;
|
|
+#endif
|
|
+ /* Copy context->state[] to working vars */
|
|
+ a = state[0];
|
|
+ b = state[1];
|
|
+ c = state[2];
|
|
+ d = state[3];
|
|
+ e = state[4];
|
|
+ /* 4 rounds of 20 operations each. Loop unrolled. */
|
|
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
|
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
|
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
|
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
|
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
|
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
|
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
|
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
|
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
|
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
|
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
|
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
|
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
|
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
|
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
|
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
|
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
|
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
|
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
|
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
|
+ /* Add the working vars back into context.state[] */
|
|
+ state[0] += a;
|
|
+ state[1] += b;
|
|
+ state[2] += c;
|
|
+ state[3] += d;
|
|
+ state[4] += e;
|
|
+ /* Wipe variables */
|
|
+ a = b = c = d = e = 0;
|
|
+}
|
|
+
|
|
+
|
|
+/* SHA1Init - Initialize new context */
|
|
+
|
|
+void SHA1Init(void *vcontext)
|
|
+{
|
|
+ SHA1_CTX* context = vcontext;
|
|
+
|
|
+ /* SHA1 initialization constants */
|
|
+ context->state[0] = 0x67452301;
|
|
+ context->state[1] = 0xEFCDAB89;
|
|
+ context->state[2] = 0x98BADCFE;
|
|
+ context->state[3] = 0x10325476;
|
|
+ context->state[4] = 0xC3D2E1F0;
|
|
+ context->count[0] = context->count[1] = 0;
|
|
+}
|
|
+
|
|
+
|
|
+/* Run your data through this. */
|
|
+
|
|
+void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
|
|
+{
|
|
+ SHA1_CTX* context = vcontext;
|
|
+ __u32 i, j;
|
|
+
|
|
+ j = context->count[0];
|
|
+ if ((context->count[0] += len << 3) < j)
|
|
+ context->count[1]++;
|
|
+ context->count[1] += (len>>29);
|
|
+ j = (j >> 3) & 63;
|
|
+ if ((j + len) > 63) {
|
|
+ memcpy(&context->buffer[j], data, (i = 64-j));
|
|
+ SHA1Transform(context->state, context->buffer);
|
|
+ for ( ; i + 63 < len; i += 64) {
|
|
+ SHA1Transform(context->state, &data[i]);
|
|
+ }
|
|
+ j = 0;
|
|
+ }
|
|
+ else i = 0;
|
|
+ memcpy(&context->buffer[j], &data[i], len - i);
|
|
+}
|
|
+
|
|
+
|
|
+/* Add padding and return the message digest. */
|
|
+
|
|
+void SHA1Final(unsigned char digest[20], void *vcontext)
|
|
+{
|
|
+ __u32 i, j;
|
|
+ unsigned char finalcount[8];
|
|
+ SHA1_CTX* context = vcontext;
|
|
+
|
|
+ for (i = 0; i < 8; i++) {
|
|
+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
|
|
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
|
+ }
|
|
+ SHA1Update(context, (unsigned char *)"\200", 1);
|
|
+ while ((context->count[0] & 504) != 448) {
|
|
+ SHA1Update(context, (unsigned char *)"\0", 1);
|
|
+ }
|
|
+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
|
|
+ for (i = 0; i < 20; i++) {
|
|
+ digest[i] = (unsigned char)
|
|
+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
|
+ }
|
|
+ /* Wipe variables */
|
|
+ i = j = 0;
|
|
+ memset(context->buffer, 0, 64);
|
|
+ memset(context->state, 0, 20);
|
|
+ memset(context->count, 0, 8);
|
|
+ memset(&finalcount, 0, 8);
|
|
+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
|
|
+ SHA1Transform(context->state, context->buffer);
|
|
+#endif
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_sha1.c,v $
|
|
+ * Revision 1.9 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.8 2002/09/10 01:45:14 mcr
|
|
+ * changed type of MD5_CTX and SHA1_CTX to void * so that
|
|
+ * the function prototypes would match, and could be placed
|
|
+ * into a pointer to a function.
|
|
+ *
|
|
+ * Revision 1.7 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.6 2002/04/24 07:36:30 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_sha1.c,v
|
|
+ *
|
|
+ * Revision 1.5 1999/12/13 13:59:13 rgb
|
|
+ * Quick fix to argument size to Update bugs.
|
|
+ *
|
|
+ * Revision 1.4 1999/04/11 00:29:00 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.3 1999/04/06 04:54:27 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.2 1999/01/22 06:55:50 rgb
|
|
+ * 64-bit clean-up.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:50 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.2 1998/04/23 20:54:04 rgb
|
|
+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
|
|
+ * verified.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:11 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * New transform
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_snprintf.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,135 @@
|
|
+/*
|
|
+ * @(#) ipsec_snprintf() function
|
|
+ *
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ * 2001 Michael Richardson <mcr@freeswan.org>
|
|
+ * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * Split out from ipsec_proc.c.
|
|
+ */
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_kversion.h"
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+
|
|
+#include "openswan/ipsec_life.h"
|
|
+#include "openswan/ipsec_stats.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_xmit.h"
|
|
+
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_esp.h"
|
|
+#include "openswan/ipsec_kern24.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+#include "openswan/ipcomp.h"
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+/* ipsec_snprintf: like snprintf except
|
|
+ * - size is signed and a negative value is treated as if it were 0
|
|
+ * - the returned result is never negative --
|
|
+ * an error generates a "?" or null output (depending on space).
|
|
+ * (Our callers are too lazy to check for an error return.)
|
|
+ *
|
|
+ * @param buf String buffer
|
|
+ * @param size Size of the string
|
|
+ * @param fmt printf string
|
|
+ * @param ... Variables to be displayed in fmt
|
|
+ * @return int Return code
|
|
+ */
|
|
+int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
|
|
+{
|
|
+ va_list args;
|
|
+ int i;
|
|
+ size_t possize = size < 0? 0 : size;
|
|
+ va_start(args, fmt);
|
|
+ i = vsnprintf(buf,possize,fmt,args);
|
|
+ va_end(args);
|
|
+ if (i < 0) {
|
|
+ /* create empty output in place of error */
|
|
+ i = 0;
|
|
+ if (size > 0) {
|
|
+ *buf = '\0';
|
|
+ }
|
|
+ }
|
|
+ return i;
|
|
+}
|
|
+
|
|
+
|
|
+void ipsec_dmp_block(char *s, caddr_t bb, int len)
|
|
+{
|
|
+ int i;
|
|
+ unsigned char *b = bb;
|
|
+
|
|
+ printk(KERN_INFO "klips_dmp: "
|
|
+ "at %s, len=%d:\n", s, len);
|
|
+
|
|
+ for(i = 0; i < len; i++ /*, c++*/) {
|
|
+ if(!(i % 16)) {
|
|
+ printk(KERN_INFO
|
|
+ "klips_debug: @%03x:",
|
|
+ i);
|
|
+ }
|
|
+ printk(" %02x", b[i]);
|
|
+ if(!((i + 1) % 16)) {
|
|
+ printk("\n");
|
|
+ }
|
|
+ }
|
|
+ if(i % 16) {
|
|
+ printk("\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ *
|
|
+ * $Log: ipsec_snprintf.c,v $
|
|
+ * Revision 1.3.2.1 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.3 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.2 2005/04/15 00:32:01 mcr
|
|
+ * added ipsec_dmp_block routine.
|
|
+ *
|
|
+ *
|
|
+ * Local Variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,2878 @@
|
|
+/*
|
|
+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+char ipsec_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.232.2.5 2006/10/06 21:39:26 paul Exp $";
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif /* for CONFIG_IP_FORWARD */
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <net/tcp.h>
|
|
+#include <net/udp.h>
|
|
+#include <linux/skbuff.h>
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+
|
|
+#include <openswan.h>
|
|
+
|
|
+#ifdef NET_21
|
|
+# include <linux/in6.h>
|
|
+# define ip_chk_addr inet_addr_type
|
|
+# define IS_MYADDR RTN_LOCAL
|
|
+# include <net/dst.h>
|
|
+# undef dev_kfree_skb
|
|
+# define dev_kfree_skb(a,b) kfree_skb(a)
|
|
+# define PHYSDEV_TYPE
|
|
+#endif /* NET_21 */
|
|
+
|
|
+#include <net/icmp.h> /* icmp_send() */
|
|
+#include <net/ip.h>
|
|
+#ifdef NETDEV_23
|
|
+# include <linux/netfilter_ipv4.h>
|
|
+#endif /* NETDEV_23 */
|
|
+
|
|
+#include <linux/if_arp.h>
|
|
+#include <net/arp.h>
|
|
+
|
|
+#include "openswan/ipsec_kversion.h"
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_life.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_eroute.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_xmit.h"
|
|
+#include "openswan/ipsec_ipe4.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_esp.h"
|
|
+#include "openswan/ipsec_kern24.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+#include <linux/udp.h>
|
|
+#endif
|
|
+
|
|
+static __u32 zeroes[64];
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int debug_tunnel = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_open(struct net_device *dev)
|
|
+{
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ /*
|
|
+ * Can't open until attached.
|
|
+ */
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_open: "
|
|
+ "dev = %s, prv->dev = %s\n",
|
|
+ dev->name, prv->dev?prv->dev->name:"NONE");
|
|
+
|
|
+ if (prv->dev == NULL)
|
|
+ return -ENODEV;
|
|
+
|
|
+ KLIPS_INC_USE;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_close(struct net_device *dev)
|
|
+{
|
|
+ KLIPS_DEC_USE;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#ifdef NETDEV_23
|
|
+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
|
|
+{
|
|
+#ifdef NETDEV_25 /* 2.6 kernels */
|
|
+ return dst_output(skb);
|
|
+#else
|
|
+ return ip_send(skb);
|
|
+#endif
|
|
+}
|
|
+#endif /* NETDEV_23 */
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+ /* ixs->physdev->hard_header_len is unreliable and should not be used */
|
|
+ ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data;
|
|
+
|
|
+ if(ixs->hard_header_len < 0) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_error:ipsec_xmit_strip_hard_header: "
|
|
+ "Negative hard_header_len (%d)?!\n", ixs->hard_header_len);
|
|
+ ixs->stats->tx_dropped++;
|
|
+ return IPSEC_XMIT_BADHHLEN;
|
|
+ }
|
|
+
|
|
+ /* while ixs->physdev->hard_header_len is unreliable and
|
|
+ * should not be trusted, it accurate and required for ATM, GRE and
|
|
+ * some other interfaces to work. Thanks to Willy Tarreau
|
|
+ * <willy@w.ods.org>.
|
|
+ */
|
|
+ if(ixs->hard_header_len == 0) { /* no hard header present */
|
|
+ ixs->hard_header_stripped = 1;
|
|
+ ixs->hard_header_len = ixs->physdev->hard_header_len;
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if (debug_tunnel & DB_TN_XMIT) {
|
|
+ int i;
|
|
+ char c;
|
|
+
|
|
+ printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: "
|
|
+ ">>> skb->len=%ld hard_header_len:%d",
|
|
+ (unsigned long int)ixs->skb->len, ixs->hard_header_len);
|
|
+ c = ' ';
|
|
+ for (i=0; i < ixs->hard_header_len; i++) {
|
|
+ printk("%c%02x", c, ixs->skb->data[i]);
|
|
+ c = ':';
|
|
+ }
|
|
+ printk(" \n");
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_strip_hard_header: "
|
|
+ "Original head,tailroom: %d,%d\n",
|
|
+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+ unsigned int bypass;
|
|
+
|
|
+ bypass = FALSE;
|
|
+
|
|
+ /*
|
|
+ * First things first -- look us up in the erouting tables.
|
|
+ */
|
|
+ ixs->matcher.sen_len = sizeof (struct sockaddr_encap);
|
|
+ ixs->matcher.sen_family = AF_ENCAP;
|
|
+ ixs->matcher.sen_type = SENT_IP4;
|
|
+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
|
|
+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
|
|
+ ixs->matcher.sen_proto = ixs->iph->protocol;
|
|
+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
|
|
+
|
|
+ /*
|
|
+ * The spinlock is to prevent any other process from accessing or deleting
|
|
+ * the eroute while we are using and updating it.
|
|
+ */
|
|
+ spin_lock(&eroute_lock);
|
|
+
|
|
+ ixs->eroute = ipsec_findroute(&ixs->matcher);
|
|
+
|
|
+ if(ixs->iph->protocol == IPPROTO_UDP) {
|
|
+ struct udphdr *t = NULL;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:udp port check: "
|
|
+ "fragoff: %d len: %d>%ld \n",
|
|
+ ntohs(ixs->iph->frag_off) & IP_OFFSET,
|
|
+ (ixs->skb->len - ixs->hard_header_len),
|
|
+ (unsigned long int) ((ixs->iph->ihl << 2) + sizeof(struct udphdr)));
|
|
+
|
|
+ if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
|
|
+ ((ixs->skb->len - ixs->hard_header_len) >=
|
|
+ ((ixs->iph->ihl << 2) + sizeof(struct udphdr))))
|
|
+ {
|
|
+ t =((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:udp port in packet: "
|
|
+ "port %d -> %d\n",
|
|
+ ntohs(t->source), ntohs(t->dest));
|
|
+ }
|
|
+
|
|
+ ixs->sport=0; ixs->dport=0;
|
|
+
|
|
+ if(ixs->skb->sk) {
|
|
+#ifdef NET_26
|
|
+ struct udp_sock *us;
|
|
+
|
|
+ us = (struct udp_sock *)ixs->skb->sk;
|
|
+
|
|
+ ixs->sport = ntohs(us->inet.sport);
|
|
+ ixs->dport = ntohs(us->inet.dport);
|
|
+#else
|
|
+ ixs->sport = ntohs(ixs->skb->sk->sport);
|
|
+ ixs->dport = ntohs(ixs->skb->sk->dport);
|
|
+#endif
|
|
+
|
|
+ }
|
|
+
|
|
+ if(t != NULL) {
|
|
+ if(ixs->sport == 0) {
|
|
+ ixs->sport = ntohs(t->source);
|
|
+ }
|
|
+ if(ixs->dport == 0) {
|
|
+ ixs->dport = ntohs(t->dest);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * practically identical to above, but let's be careful about
|
|
+ * tcp vs udp headers
|
|
+ */
|
|
+ if(ixs->iph->protocol == IPPROTO_TCP) {
|
|
+ struct tcphdr *t = NULL;
|
|
+
|
|
+ if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
|
|
+ ((ixs->skb->len - ixs->hard_header_len) >=
|
|
+ ((ixs->iph->ihl << 2) + sizeof(struct tcphdr)))) {
|
|
+ t =((struct tcphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
|
|
+ }
|
|
+
|
|
+ ixs->sport=0; ixs->dport=0;
|
|
+
|
|
+ if(ixs->skb->sk) {
|
|
+#ifdef NET_26
|
|
+#ifdef HAVE_INET_SK_SPORT
|
|
+ ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
|
|
+ ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
|
|
+#else
|
|
+ struct tcp_tw_bucket *tw;
|
|
+
|
|
+ tw = (struct tcp_tw_bucket *)ixs->skb->sk;
|
|
+
|
|
+ ixs->sport = ntohs(tw->tw_sport);
|
|
+ ixs->dport = ntohs(tw->tw_dport);
|
|
+#endif
|
|
+#else
|
|
+ ixs->sport = ntohs(ixs->skb->sk->sport);
|
|
+ ixs->dport = ntohs(ixs->skb->sk->dport);
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ if(t != NULL) {
|
|
+ if(ixs->sport == 0) {
|
|
+ ixs->sport = ntohs(t->source);
|
|
+ }
|
|
+ if(ixs->dport == 0) {
|
|
+ ixs->dport = ntohs(t->dest);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* default to a %drop eroute */
|
|
+ ixs->outgoing_said.proto = IPPROTO_INT;
|
|
+ ixs->outgoing_said.spi = htonl(SPI_DROP);
|
|
+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "checking for local udp/500 IKE packet "
|
|
+ "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
|
|
+ ntohl((unsigned int)ixs->iph->saddr),
|
|
+ ixs->eroute,
|
|
+ ntohl((unsigned int)ixs->iph->daddr),
|
|
+ ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0,
|
|
+ ixs->iph->protocol,
|
|
+ ixs->sport,
|
|
+ ixs->dport);
|
|
+
|
|
+ /*
|
|
+ * cheat for now...are we udp/500? If so, let it through
|
|
+ * without interference since it is most likely an IKE packet.
|
|
+ */
|
|
+
|
|
+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
|
|
+ && (ixs->eroute==NULL
|
|
+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
|
|
+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
|
|
+ && (ixs->iph->protocol == IPPROTO_UDP &&
|
|
+ (ixs->sport == 500 || ixs->sport == 4500))) {
|
|
+ /* Whatever the eroute, this is an IKE message
|
|
+ * from us (i.e. not being forwarded).
|
|
+ * Furthermore, if there is a tunnel eroute,
|
|
+ * the destination is the peer for this eroute.
|
|
+ * So %pass the packet: modify the default %drop.
|
|
+ */
|
|
+
|
|
+ ixs->outgoing_said.spi = htonl(SPI_PASS);
|
|
+ if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
|
|
+ }
|
|
+ bypass = TRUE;
|
|
+ }
|
|
+
|
|
+#ifdef KLIPS_EXCEPT_DNS53
|
|
+ /*
|
|
+ *
|
|
+ * if we are udp/53 or tcp/53, also let it through a %trap or %hold,
|
|
+ * since it is DNS, but *also* follow the %trap.
|
|
+ *
|
|
+ * we do not do this for tunnels, only %trap's and %hold's.
|
|
+ *
|
|
+ */
|
|
+
|
|
+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
|
|
+ && (ixs->eroute==NULL
|
|
+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
|
|
+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
|
|
+ && ((ixs->iph->protocol == IPPROTO_UDP
|
|
+ || ixs->iph->protocol == IPPROTO_TCP)
|
|
+ && ixs->dport == 53)) {
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "possible DNS packet\n");
|
|
+
|
|
+ if(ixs->eroute)
|
|
+ {
|
|
+ if(ixs->eroute->er_said.spi == htonl(SPI_TRAP)
|
|
+ || ixs->eroute->er_said.spi == htonl(SPI_HOLD))
|
|
+ {
|
|
+ ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
|
|
+ bypass = TRUE;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
|
|
+ bypass = TRUE;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "bypass = %d\n", bypass);
|
|
+
|
|
+ if(bypass
|
|
+ && !(ixs->skb->sk)
|
|
+ && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0))
|
|
+ {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "local port 53 (probably DNS) passthrough:"
|
|
+ "base fragment, rest of fragments will "
|
|
+ "probably get filtered.\n");
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if (bypass==FALSE && ixs->eroute) {
|
|
+ ixs->eroute->er_count++;
|
|
+ ixs->eroute->er_lasttime = jiffies/HZ;
|
|
+ if(ixs->eroute->er_said.proto==IPPROTO_INT
|
|
+ && ixs->eroute->er_said.spi==htonl(SPI_HOLD))
|
|
+ {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "shunt SA of HOLD: skb stored in HOLD.\n");
|
|
+ if(ixs->eroute->er_last != NULL) {
|
|
+ kfree_skb(ixs->eroute->er_last);
|
|
+ }
|
|
+ ixs->eroute->er_last = ixs->skb;
|
|
+ ixs->skb = NULL;
|
|
+ ixs->stats->tx_dropped++;
|
|
+ spin_unlock(&eroute_lock);
|
|
+ return IPSEC_XMIT_STOLEN;
|
|
+ }
|
|
+ ixs->outgoing_said = ixs->eroute->er_said;
|
|
+ ixs->eroute_pid = ixs->eroute->er_pid;
|
|
+
|
|
+ /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
|
|
+ if(ixs->outgoing_said.proto==IPPROTO_INT
|
|
+ && (ixs->outgoing_said.spi==htonl(SPI_TRAP)
|
|
+ || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
|
|
+ int len;
|
|
+
|
|
+ ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type;
|
|
+ ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id;
|
|
+ ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len;
|
|
+ if (ixs->ips.ips_ident_s.len)
|
|
+ {
|
|
+ len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
|
|
+ len);
|
|
+ if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
|
|
+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "Failed, tried to allocate %d bytes for source ident.\n",
|
|
+ len);
|
|
+ ixs->stats->tx_dropped++;
|
|
+ spin_unlock(&eroute_lock);
|
|
+ return IPSEC_XMIT_ERRMEMALLOC;
|
|
+ }
|
|
+ memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len);
|
|
+ }
|
|
+ ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type;
|
|
+ ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id;
|
|
+ ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len;
|
|
+ if (ixs->ips.ips_ident_d.len)
|
|
+ {
|
|
+ len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
|
|
+ len);
|
|
+ if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
|
|
+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
|
|
+ "Failed, tried to allocate %d bytes for dest ident.\n",
|
|
+ len);
|
|
+ ixs->stats->tx_dropped++;
|
|
+ spin_unlock(&eroute_lock);
|
|
+ return IPSEC_XMIT_ERRMEMALLOC;
|
|
+ }
|
|
+ memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ spin_unlock(&eroute_lock);
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs)
|
|
+{
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_restore_hard_header: "
|
|
+ "After recursive xforms -- head,tailroom: %d,%d\n",
|
|
+ skb_headroom(ixs->skb),
|
|
+ skb_tailroom(ixs->skb));
|
|
+
|
|
+ if(ixs->saved_header) {
|
|
+ if(skb_headroom(ixs->skb) < ixs->hard_header_len) {
|
|
+ printk(KERN_WARNING
|
|
+ "klips_error:ipsec_xmit_restore_hard_header: "
|
|
+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
|
|
+ ixs->hard_header_len,
|
|
+ skb_headroom(ixs->skb));
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_PUSHPULLERR;
|
|
+
|
|
+ }
|
|
+ skb_push(ixs->skb, ixs->hard_header_len);
|
|
+ {
|
|
+ int i;
|
|
+ for (i = 0; i < ixs->hard_header_len; i++) {
|
|
+ ixs->skb->data[i] = ixs->saved_header[i];
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ if (ixs->natt_type && ixs->natt_head) {
|
|
+ struct iphdr *ipp = ixs->skb->nh.iph;
|
|
+ struct udphdr *udp;
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
|
|
+ ixs->natt_type, ixs->natt_head);
|
|
+
|
|
+ ixs->iphlen = ipp->ihl << 2;
|
|
+ ipp->tot_len =
|
|
+ htons(ntohs(ipp->tot_len) + ixs->natt_head);
|
|
+ if(skb_tailroom(ixs->skb) < ixs->natt_head) {
|
|
+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
|
|
+ "tried to skb_put %d, %d available. "
|
|
+ "This should never happen, please report.\n",
|
|
+ ixs->natt_head,
|
|
+ skb_tailroom(ixs->skb));
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_ESPUDP;
|
|
+ }
|
|
+ skb_put(ixs->skb, ixs->natt_head);
|
|
+
|
|
+ udp = (struct udphdr *)((char *)ipp + ixs->iphlen);
|
|
+
|
|
+ /* move ESP hdr after UDP hdr */
|
|
+ memmove((void *)((char *)udp + ixs->natt_head),
|
|
+ (void *)(udp),
|
|
+ ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head);
|
|
+
|
|
+ /* clear UDP & Non-IKE Markers (if any) */
|
|
+ memset(udp, 0, ixs->natt_head);
|
|
+
|
|
+ /* fill UDP with usefull informations ;-) */
|
|
+ udp->source = htons(ixs->natt_sport);
|
|
+ udp->dest = htons(ixs->natt_dport);
|
|
+ udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen);
|
|
+
|
|
+ /* set protocol */
|
|
+ ipp->protocol = IPPROTO_UDP;
|
|
+
|
|
+ /* fix IP checksum */
|
|
+ ipp->check = 0;
|
|
+ ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
|
|
+ }
|
|
+#endif
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_restore_hard_header: "
|
|
+ "With hard_header, final head,tailroom: %d,%d\n",
|
|
+ skb_headroom(ixs->skb),
|
|
+ skb_tailroom(ixs->skb));
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_tunnel_send(struct ipsec_xmit_state*ixs)
|
|
+{
|
|
+#ifdef NETDEV_25
|
|
+ struct flowi fl;
|
|
+#endif
|
|
+
|
|
+#ifdef NET_21 /* 2.2 and 2.4 kernels */
|
|
+ /* new route/dst cache code from James Morris */
|
|
+ ixs->skb->dev = ixs->physdev;
|
|
+#ifdef NETDEV_25
|
|
+ memset (&fl, 0x0, sizeof (struct flowi));
|
|
+ fl.oif = ixs->physdev->iflink;
|
|
+ fl.nl_u.ip4_u.daddr = ixs->skb->nh.iph->daddr;
|
|
+ fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ixs->skb->nh.iph->saddr;
|
|
+ fl.nl_u.ip4_u.tos = RT_TOS(ixs->skb->nh.iph->tos);
|
|
+ fl.proto = ixs->skb->nh.iph->protocol;
|
|
+ if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) {
|
|
+#else
|
|
+ /*skb_orphan(ixs->skb);*/
|
|
+ if((ixs->error = ip_route_output(&ixs->route,
|
|
+ ixs->skb->nh.iph->daddr,
|
|
+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
|
|
+ RT_TOS(ixs->skb->nh.iph->tos),
|
|
+ /* mcr->rgb: should this be 0 instead? */
|
|
+ ixs->physdev->iflink))) {
|
|
+#endif
|
|
+ ixs->stats->tx_errors++;
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_send: "
|
|
+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
|
|
+ ixs->error,
|
|
+ ixs->route->u.dst.dev->name);
|
|
+ return IPSEC_XMIT_ROUTEERR;
|
|
+ }
|
|
+ if(ixs->dev == ixs->route->u.dst.dev) {
|
|
+ ip_rt_put(ixs->route);
|
|
+ /* This is recursion, drop it. */
|
|
+ ixs->stats->tx_errors++;
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_send: "
|
|
+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
|
|
+ ixs->dev->name);
|
|
+ return IPSEC_XMIT_RECURSDETECT;
|
|
+ }
|
|
+ dst_release(ixs->skb->dst);
|
|
+ ixs->skb->dst = &ixs->route->u.dst;
|
|
+ ixs->stats->tx_bytes += ixs->skb->len;
|
|
+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
|
|
+ ixs->stats->tx_errors++;
|
|
+ printk(KERN_WARNING
|
|
+ "klips_error:ipsec_xmit_send: "
|
|
+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
|
|
+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
|
|
+ ixs->skb->len);
|
|
+ return IPSEC_XMIT_PUSHPULLERR;
|
|
+ }
|
|
+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
|
|
+#ifdef SKB_RESET_NFCT
|
|
+ if(!ixs->pass) {
|
|
+ nf_conntrack_put(ixs->skb->nfct);
|
|
+ ixs->skb->nfct = NULL;
|
|
+ }
|
|
+#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
|
|
+ ixs->skb->nf_debug = 0;
|
|
+#endif /* CONFIG_NETFILTER_DEBUG */
|
|
+#endif /* SKB_RESET_NFCT */
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_send: "
|
|
+ "...done, calling ip_send() on device:%s\n",
|
|
+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
|
|
+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->skb->nh.iph);
|
|
+#ifdef NETDEV_23 /* 2.4 kernels */
|
|
+ {
|
|
+ int err;
|
|
+
|
|
+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
|
|
+ ipsec_tunnel_xmit2);
|
|
+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
|
|
+ if(net_ratelimit())
|
|
+ printk(KERN_ERR
|
|
+ "klips_error:ipsec_xmit_send: "
|
|
+ "ip_send() failed, err=%d\n",
|
|
+ -err);
|
|
+ ixs->stats->tx_errors++;
|
|
+ ixs->stats->tx_aborted_errors++;
|
|
+ ixs->skb = NULL;
|
|
+ return IPSEC_XMIT_IPSENDFAILURE;
|
|
+ }
|
|
+ }
|
|
+#else /* NETDEV_23 */ /* 2.2 kernels */
|
|
+ ip_send(ixs->skb);
|
|
+#endif /* NETDEV_23 */
|
|
+#else /* NET_21 */ /* 2.0 kernels */
|
|
+ ixs->skb->arp = 1;
|
|
+ /* ISDN/ASYNC PPP from Matjaz Godec. */
|
|
+ /* skb->protocol = htons(ETH_P_IP); */
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_send: "
|
|
+ "...done, calling dev_queue_xmit() or ip_fragment().\n");
|
|
+ IP_SEND(ixs->skb, ixs->physdev);
|
|
+#endif /* NET_21 */
|
|
+ ixs->stats->tx_packets++;
|
|
+
|
|
+ ixs->skb = NULL;
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+void
|
|
+ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs)
|
|
+{
|
|
+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
|
|
+ netif_wake_queue(ixs->dev);
|
|
+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
|
|
+ ixs->dev->tbusy = 0;
|
|
+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
|
|
+ if(ixs->saved_header) {
|
|
+ kfree(ixs->saved_header);
|
|
+ }
|
|
+ if(ixs->skb) {
|
|
+ dev_kfree_skb(ixs->skb, FREE_WRITE);
|
|
+ }
|
|
+ if(ixs->oskb) {
|
|
+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
|
|
+ }
|
|
+ if (ixs->ips.ips_ident_s.data) {
|
|
+ kfree(ixs->ips.ips_ident_s.data);
|
|
+ }
|
|
+ if (ixs->ips.ips_ident_d.data) {
|
|
+ kfree(ixs->ips.ips_ident_d.data);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * This function assumes it is being called from dev_queue_xmit()
|
|
+ * and that skb is filled properly by that function.
|
|
+ */
|
|
+int
|
|
+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
+{
|
|
+ struct ipsec_xmit_state ixs_mem;
|
|
+ struct ipsec_xmit_state *ixs = &ixs_mem;
|
|
+ enum ipsec_xmit_value stat;
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ ixs->natt_type = 0, ixs->natt_head = 0;
|
|
+ ixs->natt_sport = 0, ixs->natt_dport = 0;
|
|
+#endif
|
|
+
|
|
+ memset((caddr_t)ixs, 0, sizeof(*ixs));
|
|
+ ixs->oskb = NULL;
|
|
+ ixs->saved_header = NULL; /* saved copy of the hard header */
|
|
+ ixs->route = NULL;
|
|
+ memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips));
|
|
+ ixs->dev = dev;
|
|
+ ixs->skb = skb;
|
|
+
|
|
+ stat = ipsec_xmit_sanity_check_dev(ixs);
|
|
+ if(stat != IPSEC_XMIT_OK) {
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ stat = ipsec_xmit_sanity_check_skb(ixs);
|
|
+ if(stat != IPSEC_XMIT_OK) {
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ stat = ipsec_tunnel_strip_hard_header(ixs);
|
|
+ if(stat != IPSEC_XMIT_OK) {
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ stat = ipsec_tunnel_SAlookup(ixs);
|
|
+ if(stat != IPSEC_XMIT_OK) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n",
|
|
+ stat);
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ ixs->innersrc = ixs->iph->saddr;
|
|
+ /* start encapsulation loop here XXX */
|
|
+ do {
|
|
+ stat = ipsec_xmit_encap_bundle(ixs);
|
|
+ if(stat != IPSEC_XMIT_OK) {
|
|
+ if(stat == IPSEC_XMIT_PASS) {
|
|
+ goto bypass;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n",
|
|
+ stat);
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
|
|
+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
|
|
+ ixs->matcher.sen_proto = ixs->iph->protocol;
|
|
+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
|
|
+
|
|
+ spin_lock(&eroute_lock);
|
|
+ ixs->eroute = ipsec_findroute(&ixs->matcher);
|
|
+ if(ixs->eroute) {
|
|
+ ixs->outgoing_said = ixs->eroute->er_said;
|
|
+ ixs->eroute_pid = ixs->eroute->er_pid;
|
|
+ ixs->eroute->er_count++;
|
|
+ ixs->eroute->er_lasttime = jiffies/HZ;
|
|
+ }
|
|
+ spin_unlock(&eroute_lock);
|
|
+
|
|
+ KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
|
|
+ /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */
|
|
+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
|
|
+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
|
|
+ ixs->eroute,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "We are recursing here.\n");
|
|
+
|
|
+ } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/
|
|
+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
|
|
+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
|
|
+ ixs->eroute);
|
|
+
|
|
+ stat = ipsec_tunnel_restore_hard_header(ixs);
|
|
+ if(stat != IPSEC_XMIT_OK) {
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ bypass:
|
|
+ stat = ipsec_tunnel_send(ixs);
|
|
+
|
|
+ cleanup:
|
|
+ ipsec_tunnel_cleanup(ixs);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC struct net_device_stats *
|
|
+ipsec_tunnel_get_stats(struct net_device *dev)
|
|
+{
|
|
+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Revectored calls.
|
|
+ * For each of these calls, a field exists in our private structure.
|
|
+ */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_hard_header(struct sk_buff *skb, struct net_device *dev,
|
|
+ unsigned short type, void *daddr, void *saddr, unsigned len)
|
|
+{
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+ struct net_device *tmp;
|
|
+ int ret;
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+
|
|
+ if(skb == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_hard_header: "
|
|
+ "no skb...\n");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_hard_header: "
|
|
+ "no device...\n");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_hard_header: "
|
|
+ "skb->dev=%s dev=%s.\n",
|
|
+ skb->dev ? skb->dev->name : "NULL",
|
|
+ dev->name);
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_hard_header: "
|
|
+ "no private space associated with dev=%s\n",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+
|
|
+ if(prv->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_hard_header: "
|
|
+ "no physical device associated with dev=%s\n",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ /* check if we have to send a IPv6 packet. It might be a Router
|
|
+ Solicitation, where the building of the packet happens in
|
|
+ reverse order:
|
|
+ 1. ll hdr,
|
|
+ 2. IPv6 hdr,
|
|
+ 3. ICMPv6 hdr
|
|
+ -> skb->nh.raw is still uninitialized when this function is
|
|
+ called!! If this is no IPv6 packet, we can print debugging
|
|
+ messages, otherwise we skip all debugging messages and just
|
|
+ build the ll header */
|
|
+ if(type != ETH_P_IPV6) {
|
|
+ /* execute this only, if we don't have to build the
|
|
+ header for a IPv6 packet */
|
|
+ if(!prv->hard_header) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_hard_header: "
|
|
+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
|
|
+ saddr,
|
|
+ daddr,
|
|
+ len,
|
|
+ type,
|
|
+ dev->name);
|
|
+#ifdef NET_21
|
|
+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->nh.iph->saddr),
|
|
+ (__u32)ntohl(skb->nh.iph->daddr) );
|
|
+#else /* NET_21 */
|
|
+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->ip_hdr->saddr),
|
|
+ (__u32)ntohl(skb->ip_hdr->daddr) );
|
|
+#endif /* NET_21 */
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+#define da ((struct net_device *)(prv->dev))->dev_addr
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_hard_header: "
|
|
+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
|
|
+ saddr,
|
|
+ daddr,
|
|
+ len,
|
|
+ type,
|
|
+ dev->name,
|
|
+ prv->dev->name,
|
|
+ da[0], da[1], da[2], da[3], da[4], da[5]);
|
|
+#ifdef NET_21
|
|
+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->nh.iph->saddr),
|
|
+ (__u32)ntohl(skb->nh.iph->daddr) );
|
|
+#else /* NET_21 */
|
|
+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->ip_hdr->saddr),
|
|
+ (__u32)ntohl(skb->ip_hdr->daddr) );
|
|
+#endif /* NET_21 */
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_hard_header: "
|
|
+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
|
|
+ }
|
|
+ tmp = skb->dev;
|
|
+ skb->dev = prv->dev;
|
|
+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
|
|
+ skb->dev = tmp;
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+#ifdef NET_21
|
|
+ipsec_tunnel_rebuild_header(struct sk_buff *skb)
|
|
+#else /* NET_21 */
|
|
+ipsec_tunnel_rebuild_header(void *buff, struct net_device *dev,
|
|
+ unsigned long raddr, struct sk_buff *skb)
|
|
+#endif /* NET_21 */
|
|
+{
|
|
+ struct ipsecpriv *prv = skb->dev->priv;
|
|
+ struct net_device *tmp;
|
|
+ int ret;
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+
|
|
+ if(skb->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_rebuild_header: "
|
|
+ "no device...");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_rebuild_header: "
|
|
+ "no private space associated with dev=%s",
|
|
+ skb->dev->name ? skb->dev->name : "NULL");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+
|
|
+ if(prv->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_rebuild_header: "
|
|
+ "no physical device associated with dev=%s",
|
|
+ skb->dev->name ? skb->dev->name : "NULL");
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(!prv->rebuild_header) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_rebuild_header: "
|
|
+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
|
|
+ skb->dev->name);
|
|
+#ifdef NET_21
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->nh.iph->saddr),
|
|
+ (__u32)ntohl(skb->nh.iph->daddr) );
|
|
+#else /* NET_21 */
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->ip_hdr->saddr),
|
|
+ (__u32)ntohl(skb->ip_hdr->daddr) );
|
|
+#endif /* NET_21 */
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel: "
|
|
+ "Revectored rebuild_header dev=%s->%s ",
|
|
+ skb->dev->name, prv->dev->name);
|
|
+#ifdef NET_21
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->nh.iph->saddr),
|
|
+ (__u32)ntohl(skb->nh.iph->daddr) );
|
|
+#else /* NET_21 */
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "ip=%08x->%08x\n",
|
|
+ (__u32)ntohl(skb->ip_hdr->saddr),
|
|
+ (__u32)ntohl(skb->ip_hdr->daddr) );
|
|
+#endif /* NET_21 */
|
|
+ tmp = skb->dev;
|
|
+ skb->dev = prv->dev;
|
|
+
|
|
+#ifdef NET_21
|
|
+ ret = prv->rebuild_header(skb);
|
|
+#else /* NET_21 */
|
|
+ ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
|
|
+#endif /* NET_21 */
|
|
+ skb->dev = tmp;
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_set_mac_address(struct net_device *dev, void *addr)
|
|
+{
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_set_mac_address: "
|
|
+ "no device...");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_set_mac_address: "
|
|
+ "no private space associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+
|
|
+ if(prv->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_set_mac_address: "
|
|
+ "no physical device associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ stats->tx_dropped++;
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(!prv->set_mac_address) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_set_mac_address: "
|
|
+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
|
|
+ dev->name);
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_set_mac_address: "
|
|
+ "Revectored dev=%s->%s addr=0p%p\n",
|
|
+ dev->name, prv->dev->name, addr);
|
|
+ return prv->set_mac_address(prv->dev, addr);
|
|
+
|
|
+}
|
|
+
|
|
+#ifndef NET_21
|
|
+DEBUG_NO_STATIC void
|
|
+ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct net_device *dev,
|
|
+ unsigned short htype, __u32 daddr)
|
|
+{
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_cache_bind: "
|
|
+ "no device...");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_cache_bind: "
|
|
+ "no private space associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+
|
|
+ if(prv->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_cache_bind: "
|
|
+ "no physical device associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ stats->tx_dropped++;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if(!prv->header_cache_bind) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_cache_bind: "
|
|
+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
|
|
+ dev->name);
|
|
+ stats->tx_dropped++;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_cache_bind: "
|
|
+ "Revectored \n");
|
|
+ prv->header_cache_bind(hhp, prv->dev, htype, daddr);
|
|
+ return;
|
|
+}
|
|
+#endif /* !NET_21 */
|
|
+
|
|
+
|
|
+DEBUG_NO_STATIC void
|
|
+ipsec_tunnel_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
|
|
+{
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ struct net_device_stats *stats; /* This device's statistics */
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_cache_update: "
|
|
+ "no device...");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_cache_update: "
|
|
+ "no private space associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ stats = (struct net_device_stats *) &(prv->mystats);
|
|
+
|
|
+ if(prv->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_cache_update: "
|
|
+ "no physical device associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ stats->tx_dropped++;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if(!prv->header_cache_update) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_cache_update: "
|
|
+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
|
|
+ dev->name);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel: "
|
|
+ "Revectored cache_update\n");
|
|
+ prv->header_cache_update(hh, prv->dev, haddr);
|
|
+ return;
|
|
+}
|
|
+
|
|
+#ifdef NET_21
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_neigh_setup(struct neighbour *n)
|
|
+{
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_neigh_setup:\n");
|
|
+
|
|
+ if (n->nud_state == NUD_NONE) {
|
|
+ n->ops = &arp_broken_ops;
|
|
+ n->output = n->ops->output;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
|
|
+{
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_neigh_setup_dev: "
|
|
+ "setting up %s\n",
|
|
+ dev ? dev->name : "NULL");
|
|
+
|
|
+ if (p->tbl->family == AF_INET) {
|
|
+ p->neigh_setup = ipsec_tunnel_neigh_setup;
|
|
+ p->ucast_probes = 0;
|
|
+ p->mcast_probes = 0;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+#endif /* NET_21 */
|
|
+
|
|
+/*
|
|
+ * We call the attach routine to attach another device.
|
|
+ */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_attach(struct net_device *dev, struct net_device *physdev)
|
|
+{
|
|
+ int i;
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_attach: "
|
|
+ "no device...");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_attach: "
|
|
+ "no private space associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ prv->dev = physdev;
|
|
+ prv->hard_start_xmit = physdev->hard_start_xmit;
|
|
+ prv->get_stats = physdev->get_stats;
|
|
+
|
|
+ if (physdev->hard_header) {
|
|
+ prv->hard_header = physdev->hard_header;
|
|
+ dev->hard_header = ipsec_tunnel_hard_header;
|
|
+ } else
|
|
+ dev->hard_header = NULL;
|
|
+
|
|
+ if (physdev->rebuild_header) {
|
|
+ prv->rebuild_header = physdev->rebuild_header;
|
|
+ dev->rebuild_header = ipsec_tunnel_rebuild_header;
|
|
+ } else
|
|
+ dev->rebuild_header = NULL;
|
|
+
|
|
+ if (physdev->set_mac_address) {
|
|
+ prv->set_mac_address = physdev->set_mac_address;
|
|
+ dev->set_mac_address = ipsec_tunnel_set_mac_address;
|
|
+ } else
|
|
+ dev->set_mac_address = NULL;
|
|
+
|
|
+#ifndef NET_21
|
|
+ if (physdev->header_cache_bind) {
|
|
+ prv->header_cache_bind = physdev->header_cache_bind;
|
|
+ dev->header_cache_bind = ipsec_tunnel_cache_bind;
|
|
+ } else
|
|
+ dev->header_cache_bind = NULL;
|
|
+#endif /* !NET_21 */
|
|
+
|
|
+ if (physdev->header_cache_update) {
|
|
+ prv->header_cache_update = physdev->header_cache_update;
|
|
+ dev->header_cache_update = ipsec_tunnel_cache_update;
|
|
+ } else
|
|
+ dev->header_cache_update = NULL;
|
|
+
|
|
+ dev->hard_header_len = physdev->hard_header_len;
|
|
+
|
|
+#ifdef NET_21
|
|
+/* prv->neigh_setup = physdev->neigh_setup; */
|
|
+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
|
|
+#endif /* NET_21 */
|
|
+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
|
|
+ prv->mtu = physdev->mtu;
|
|
+
|
|
+#ifdef PHYSDEV_TYPE
|
|
+ dev->type = physdev->type; /* ARPHRD_TUNNEL; */
|
|
+#endif /* PHYSDEV_TYPE */
|
|
+
|
|
+ dev->addr_len = physdev->addr_len;
|
|
+ for (i=0; i<dev->addr_len; i++) {
|
|
+ dev->dev_addr[i] = physdev->dev_addr[i];
|
|
+ }
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_tunnel & DB_TN_INIT) {
|
|
+ printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
|
|
+ "physical device %s being attached has HW address: %2x",
|
|
+ physdev->name, physdev->dev_addr[0]);
|
|
+ for (i=1; i < physdev->addr_len; i++) {
|
|
+ printk(":%02x", physdev->dev_addr[i]);
|
|
+ }
|
|
+ printk("\n");
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * We call the detach routine to detach the ipsec tunnel from another device.
|
|
+ */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_detach(struct net_device *dev)
|
|
+{
|
|
+ int i;
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_detach: "
|
|
+ "no device...");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ if(prv == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
|
|
+ "klips_debug:ipsec_tunnel_detach: "
|
|
+ "no private space associated with dev=%s",
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_detach: "
|
|
+ "physical device %s being detached from virtual device %s\n",
|
|
+ prv->dev ? prv->dev->name : "NULL",
|
|
+ dev->name);
|
|
+
|
|
+ ipsec_dev_put(prv->dev);
|
|
+ prv->dev = NULL;
|
|
+ prv->hard_start_xmit = NULL;
|
|
+ prv->get_stats = NULL;
|
|
+
|
|
+ prv->hard_header = NULL;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->hard_header = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+
|
|
+ prv->rebuild_header = NULL;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->rebuild_header = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+
|
|
+ prv->set_mac_address = NULL;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->set_mac_address = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+
|
|
+#ifndef NET_21
|
|
+ prv->header_cache_bind = NULL;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->header_cache_bind = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+#endif /* !NET_21 */
|
|
+
|
|
+ prv->header_cache_update = NULL;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->header_cache_update = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+
|
|
+#ifdef NET_21
|
|
+/* prv->neigh_setup = NULL; */
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->neigh_setup = NULL;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+#endif /* NET_21 */
|
|
+ dev->hard_header_len = 0;
|
|
+#ifdef DETACH_AND_DOWN
|
|
+ dev->mtu = 0;
|
|
+#endif /* DETACH_AND_DOWN */
|
|
+ prv->mtu = 0;
|
|
+ for (i=0; i<MAX_ADDR_LEN; i++) {
|
|
+ dev->dev_addr[i] = 0;
|
|
+ }
|
|
+ dev->addr_len = 0;
|
|
+#ifdef PHYSDEV_TYPE
|
|
+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
|
|
+#endif /* PHYSDEV_TYPE */
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * We call the clear routine to detach all ipsec tunnels from other devices.
|
|
+ */
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_clear(void)
|
|
+{
|
|
+ int i;
|
|
+ struct net_device *ipsecdev = NULL, *prvdev;
|
|
+ struct ipsecpriv *prv;
|
|
+ int ret;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_clear: .\n");
|
|
+
|
|
+ for(i = 0; i < IPSEC_NUM_IF; i++) {
|
|
+ ipsecdev = ipsecdevices[i];
|
|
+ if(ipsecdev != NULL) {
|
|
+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
|
|
+ prvdev = (struct net_device *)(prv->dev);
|
|
+ if(prvdev) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_clear: "
|
|
+ "physical device for device %s is %s\n",
|
|
+ ipsecdev->name, prvdev->name);
|
|
+ if((ret = ipsec_tunnel_detach(ipsecdev))) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_clear: "
|
|
+ "error %d detatching device %s from device %s.\n",
|
|
+ ret, ipsecdev->name, prvdev->name);
|
|
+ return ret;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+ipsec_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|
+{
|
|
+ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
|
|
+ struct ipsecpriv *prv = dev->priv;
|
|
+ struct net_device *them; /* physical device */
|
|
+#ifdef CONFIG_IP_ALIAS
|
|
+ char *colon;
|
|
+ char realphysname[IFNAMSIZ];
|
|
+#endif /* CONFIG_IP_ALIAS */
|
|
+
|
|
+ if(dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "device not supplied.\n");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "tncfg service call #%d for dev=%s\n",
|
|
+ cmd,
|
|
+ dev->name ? dev->name : "NULL");
|
|
+ switch (cmd) {
|
|
+ /* attach a virtual ipsec? device to a physical device */
|
|
+ case IPSEC_SET_DEV:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "calling ipsec_tunnel_attatch...\n");
|
|
+#ifdef CONFIG_IP_ALIAS
|
|
+ /* If this is an IP alias interface, get its real physical name */
|
|
+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
|
|
+ realphysname[IFNAMSIZ-1] = 0;
|
|
+ colon = strchr(realphysname, ':');
|
|
+ if (colon) *colon = 0;
|
|
+ them = ipsec_dev_get(realphysname);
|
|
+#else /* CONFIG_IP_ALIAS */
|
|
+ them = ipsec_dev_get(cf->cf_name);
|
|
+#endif /* CONFIG_IP_ALIAS */
|
|
+
|
|
+ if (them == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "physical device %s requested is null\n",
|
|
+ cf->cf_name);
|
|
+ return -ENXIO;
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ if (them->flags & IFF_UP) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "physical device %s requested is not up.\n",
|
|
+ cf->cf_name);
|
|
+ ipsec_dev_put(them);
|
|
+ return -ENXIO;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if (prv && prv->dev) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "virtual device is already connected to %s.\n",
|
|
+ prv->dev->name ? prv->dev->name : "NULL");
|
|
+ ipsec_dev_put(them);
|
|
+ return -EBUSY;
|
|
+ }
|
|
+ return ipsec_tunnel_attach(dev, them);
|
|
+
|
|
+ case IPSEC_DEL_DEV:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "calling ipsec_tunnel_detatch.\n");
|
|
+ if (! prv->dev) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "physical device not connected.\n");
|
|
+ return -ENODEV;
|
|
+ }
|
|
+ return ipsec_tunnel_detach(dev);
|
|
+
|
|
+ case IPSEC_CLR_DEV:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "calling ipsec_tunnel_clear.\n");
|
|
+ return ipsec_tunnel_clear();
|
|
+
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_ioctl: "
|
|
+ "unknown command %d.\n",
|
|
+ cmd);
|
|
+ return -EOPNOTSUPP;
|
|
+ }
|
|
+}
|
|
+
|
|
+struct net_device *ipsec_get_device(int inst)
|
|
+{
|
|
+ struct net_device *ipsec_dev;
|
|
+
|
|
+ ipsec_dev = NULL;
|
|
+
|
|
+ if(inst < IPSEC_NUM_IF) {
|
|
+ ipsec_dev = ipsecdevices[inst];
|
|
+ }
|
|
+
|
|
+ return ipsec_dev;
|
|
+}
|
|
+
|
|
+int
|
|
+ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
|
|
+{
|
|
+ struct net_device *dev = ptr;
|
|
+ struct net_device *ipsec_dev;
|
|
+ struct ipsecpriv *priv;
|
|
+ int i;
|
|
+
|
|
+ if (dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "dev=NULL for event type %ld.\n",
|
|
+ event);
|
|
+ return(NOTIFY_DONE);
|
|
+ }
|
|
+
|
|
+ /* check for loopback devices */
|
|
+ if (dev && (dev->flags & IFF_LOOPBACK)) {
|
|
+ return(NOTIFY_DONE);
|
|
+ }
|
|
+
|
|
+ switch (event) {
|
|
+ case NETDEV_DOWN:
|
|
+ /* look very carefully at the scope of these compiler
|
|
+ directives before changing anything... -- RGB */
|
|
+#ifdef NET_21
|
|
+ case NETDEV_UNREGISTER:
|
|
+ switch (event) {
|
|
+ case NETDEV_DOWN:
|
|
+#endif /* NET_21 */
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_DOWN dev=%s flags=%x\n",
|
|
+ dev->name,
|
|
+ dev->flags);
|
|
+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
|
|
+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
|
|
+ dev->name);
|
|
+ }
|
|
+#ifdef NET_21
|
|
+ break;
|
|
+ case NETDEV_UNREGISTER:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
|
|
+ dev->name,
|
|
+ dev->flags);
|
|
+ break;
|
|
+ }
|
|
+#endif /* NET_21 */
|
|
+
|
|
+ /* find the attached physical device and detach it. */
|
|
+ for(i = 0; i < IPSEC_NUM_IF; i++) {
|
|
+ ipsec_dev = ipsecdevices[i];
|
|
+
|
|
+ if(ipsec_dev) {
|
|
+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
|
|
+ if(priv) {
|
|
+ ;
|
|
+ if(((struct net_device *)(priv->dev)) == dev) {
|
|
+ /* dev_close(ipsec_dev); */
|
|
+ /* return */ ipsec_tunnel_detach(ipsec_dev);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "device '%s' has been detached.\n",
|
|
+ ipsec_dev->name);
|
|
+ break;
|
|
+ }
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "device '%s' has no private data space!\n",
|
|
+ ipsec_dev->name);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ case NETDEV_UP:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_UP dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+#ifdef NET_21
|
|
+ case NETDEV_REBOOT:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_REBOOT dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ case NETDEV_CHANGE:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_CHANGE dev=%s flags=%x\n",
|
|
+ dev->name,
|
|
+ dev->flags);
|
|
+ break;
|
|
+ case NETDEV_REGISTER:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_REGISTER dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ case NETDEV_CHANGEMTU:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
|
|
+ dev->name,
|
|
+ dev->mtu);
|
|
+ break;
|
|
+ case NETDEV_CHANGEADDR:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_CHANGEADDR dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ case NETDEV_GOING_DOWN:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_GOING_DOWN dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+ case NETDEV_CHANGENAME:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "NETDEV_CHANGENAME dev=%s\n",
|
|
+ dev->name);
|
|
+ break;
|
|
+#endif /* NET_21 */
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_device_event: "
|
|
+ "event type %ld unrecognised for dev=%s\n",
|
|
+ event,
|
|
+ dev->name);
|
|
+ break;
|
|
+ }
|
|
+ return NOTIFY_DONE;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Called when an ipsec tunnel device is initialized.
|
|
+ * The ipsec tunnel device structure is passed to us.
|
|
+ */
|
|
+
|
|
+int
|
|
+ipsec_tunnel_init(struct net_device *dev)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_init: "
|
|
+ "allocating %lu bytes initialising device: %s\n",
|
|
+ (unsigned long) sizeof(struct ipsecpriv),
|
|
+ dev->name ? dev->name : "NULL");
|
|
+
|
|
+ /* Add our tunnel functions to the device */
|
|
+ dev->open = ipsec_tunnel_open;
|
|
+ dev->stop = ipsec_tunnel_close;
|
|
+ dev->hard_start_xmit = ipsec_tunnel_start_xmit;
|
|
+ dev->get_stats = ipsec_tunnel_get_stats;
|
|
+
|
|
+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
|
|
+ if (dev->priv == NULL)
|
|
+ return -ENOMEM;
|
|
+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
|
|
+
|
|
+ for(i = 0; i < sizeof(zeroes); i++) {
|
|
+ ((__u8*)(zeroes))[i] = 0;
|
|
+ }
|
|
+
|
|
+#ifndef NET_21
|
|
+ /* Initialize the tunnel device structure */
|
|
+ for (i = 0; i < DEV_NUMBUFFS; i++)
|
|
+ skb_queue_head_init(&dev->buffs[i]);
|
|
+#endif /* !NET_21 */
|
|
+
|
|
+ dev->set_multicast_list = NULL;
|
|
+ dev->do_ioctl = ipsec_tunnel_ioctl;
|
|
+ dev->hard_header = NULL;
|
|
+ dev->rebuild_header = NULL;
|
|
+ dev->set_mac_address = NULL;
|
|
+#ifndef NET_21
|
|
+ dev->header_cache_bind = NULL;
|
|
+#endif /* !NET_21 */
|
|
+ dev->header_cache_update= NULL;
|
|
+
|
|
+#ifdef NET_21
|
|
+/* prv->neigh_setup = NULL; */
|
|
+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
|
|
+#endif /* NET_21 */
|
|
+ dev->hard_header_len = 0;
|
|
+ dev->mtu = 0;
|
|
+ dev->addr_len = 0;
|
|
+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
|
|
+ dev->tx_queue_len = 10; /* Small queue */
|
|
+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
|
|
+
|
|
+ /* New-style flags. */
|
|
+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
|
|
+
|
|
+#if 0
|
|
+#ifdef NET_21
|
|
+ dev_init_buffers(dev);
|
|
+#else /* NET_21 */
|
|
+ dev->family = AF_INET;
|
|
+ dev->pa_addr = 0;
|
|
+ dev->pa_brdaddr = 0;
|
|
+ dev->pa_mask = 0;
|
|
+ dev->pa_alen = 4;
|
|
+#endif /* NET_21 */
|
|
+#endif
|
|
+
|
|
+ /* We're done. Have I forgotten anything? */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
+/* Module specific interface (but it links with the rest of IPSEC) */
|
|
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
+
|
|
+int
|
|
+ipsec_tunnel_probe(struct net_device *dev)
|
|
+{
|
|
+ ipsec_tunnel_init(dev);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+struct net_device *ipsecdevices[IPSEC_NUM_IF];
|
|
+
|
|
+int
|
|
+ipsec_tunnel_init_devices(void)
|
|
+{
|
|
+ int i;
|
|
+ char name[IFNAMSIZ];
|
|
+ struct net_device *dev_ipsec;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_init_devices: "
|
|
+ "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
|
|
+ IPSEC_NUM_IF,
|
|
+ (unsigned long) (sizeof(struct net_device) + IFNAMSIZ),
|
|
+ IFNAMSIZ);
|
|
+
|
|
+ for(i = 0; i < IPSEC_NUM_IF; i++) {
|
|
+ sprintf(name, IPSEC_DEV_FORMAT, i);
|
|
+ dev_ipsec = (struct net_device*)kmalloc(sizeof(struct net_device), GFP_KERNEL);
|
|
+ if (dev_ipsec == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_init_devices: "
|
|
+ "failed to allocate memory for device %s, quitting device init.\n",
|
|
+ name);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ memset((caddr_t)dev_ipsec, 0, sizeof(struct net_device));
|
|
+#ifdef NETDEV_23
|
|
+ strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
|
|
+#else /* NETDEV_23 */
|
|
+ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
|
|
+ if (dev_ipsec->name == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_init_devices: "
|
|
+ "failed to allocate memory for device %s name, quitting device init.\n",
|
|
+ name);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ);
|
|
+ strncpy(dev_ipsec->name, name, IFNAMSIZ);
|
|
+#endif /* NETDEV_23 */
|
|
+ dev_ipsec->next = NULL;
|
|
+ dev_ipsec->init = &ipsec_tunnel_probe;
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_init_devices: "
|
|
+ "registering device %s\n",
|
|
+ dev_ipsec->name);
|
|
+
|
|
+ /* reference and hold the device reference */
|
|
+ dev_hold(dev_ipsec);
|
|
+ ipsecdevices[i]=dev_ipsec;
|
|
+
|
|
+ if (register_netdev(dev_ipsec) != 0) {
|
|
+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_init_devices: "
|
|
+ "registering device %s failed, quitting device init.\n",
|
|
+ dev_ipsec->name);
|
|
+ return -EIO;
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
|
|
+ "klips_debug:ipsec_tunnel_init_devices: "
|
|
+ "registering device %s succeeded, continuing...\n",
|
|
+ dev_ipsec->name);
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* void */
|
|
+int
|
|
+ipsec_tunnel_cleanup_devices(void)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+ struct net_device *dev_ipsec;
|
|
+
|
|
+ for(i = 0; i < IPSEC_NUM_IF; i++) {
|
|
+ dev_ipsec = ipsecdevices[i];
|
|
+ if(dev_ipsec == NULL) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /* release reference */
|
|
+ ipsecdevices[i]=NULL;
|
|
+ ipsec_dev_put(dev_ipsec);
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
|
|
+ dev_ipsec->name,
|
|
+ atomic_read(&dev_ipsec->refcnt));
|
|
+ unregister_netdev(dev_ipsec);
|
|
+ KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", dev_ipsec->name);
|
|
+#ifndef NETDEV_23
|
|
+ kfree(dev_ipsec->name);
|
|
+ dev_ipsec->name=NULL;
|
|
+#endif /* !NETDEV_23 */
|
|
+ kfree(dev_ipsec->priv);
|
|
+ dev_ipsec->priv=NULL;
|
|
+ }
|
|
+ return error;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_tunnel.c,v $
|
|
+ * Revision 1.232.2.5 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.232.2.4 2006/03/28 20:58:19 ken
|
|
+ * Fix for KLIPS on 2.6.16 - need to include <net/arp.h> now
|
|
+ *
|
|
+ * Revision 1.232.2.3 2006/02/15 05:14:12 paul
|
|
+ * 568: uninitialized struct in ipsec_tunnel.c coud break routing under 2.6 kernels
|
|
+ * ipsec_tunnel_send() calls the entry point function of routing subsystem
|
|
+ * (ip_route_output_key()) using a not fully initialized struct of type
|
|
+ * struct flowi.
|
|
+ * This will cause a failure in routing packets through an ipsec interface
|
|
+ * when patches for multipath routing from http://www.ssi.bg/~ja/
|
|
+ * are applied.
|
|
+ *
|
|
+ * Revision 1.232.2.2 2005/11/22 04:11:52 ken
|
|
+ * Backport fixes for 2.6.14 kernels from HEAD
|
|
+ *
|
|
+ * Revision 1.232.2.1 2005/09/21 22:57:43 paul
|
|
+ * pulled up compile fix for 2.6.13
|
|
+ *
|
|
+ * Revision 1.232 2005/06/04 16:06:06 mcr
|
|
+ * better patch for nat-t rcv-device code.
|
|
+ *
|
|
+ * Revision 1.231 2005/05/21 03:28:51 mcr
|
|
+ * make sure that port-500 hole is used for port-4500 as well.
|
|
+ *
|
|
+ * Revision 1.230 2005/05/11 01:42:04 mcr
|
|
+ * removal of debugging showed useless/wrong variables used.
|
|
+ *
|
|
+ * Revision 1.229 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.228 2005/01/26 00:50:35 mcr
|
|
+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
|
|
+ * and make sure that NAT_TRAVERSAL is set as well to match
|
|
+ * userspace compiles of code.
|
|
+ *
|
|
+ * Revision 1.227 2004/12/10 21:16:08 ken
|
|
+ * 64bit fixes from Opteron port of KLIPS 2.6
|
|
+ *
|
|
+ * Revision 1.226 2004/12/04 07:11:23 mcr
|
|
+ * fix for snmp SIOCPRIVATE use of snmpd.
|
|
+ * http://bugs.xelerance.com/view.php?id=144
|
|
+ *
|
|
+ * Revision 1.225 2004/12/03 21:25:57 mcr
|
|
+ * compile time fixes for running on 2.6.
|
|
+ * still experimental.
|
|
+ *
|
|
+ * Revision 1.224 2004/08/14 03:28:24 mcr
|
|
+ * fixed log comment to remove warning about embedded comment.
|
|
+ *
|
|
+ * Revision 1.223 2004/08/04 15:57:07 mcr
|
|
+ * moved des .h files to include/des/ *
|
|
+ * included 2.6 protocol specific things
|
|
+ * started at NAT-T support, but it will require a kernel patch.
|
|
+ *
|
|
+ * Revision 1.222 2004/08/03 18:19:08 mcr
|
|
+ * in 2.6, use "net_device" instead of #define device->net_device.
|
|
+ * this probably breaks 2.0 compiles.
|
|
+ *
|
|
+ * Revision 1.221 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.220 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.219 2004/02/03 03:13:17 mcr
|
|
+ * minor edits for readability, and error reporting.
|
|
+ *
|
|
+ * Revision 1.218 2004/01/27 20:29:20 mcr
|
|
+ * fix for unregister_netdev() problem for underlying eth0.
|
|
+ *
|
|
+ * Revision 1.217 2003/12/10 01:14:27 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.216 2003/12/04 23:01:17 mcr
|
|
+ * removed ipsec_netlink.h
|
|
+ *
|
|
+ * Revision 1.215 2003/12/04 16:35:16 ken
|
|
+ * Fix for ATM devices where physdev->hard_header_len *is* correct
|
|
+ *
|
|
+ * Revision 1.214 2003/11/25 23:52:37 mcr
|
|
+ * fix typo in patch - ixs-> needed.
|
|
+ *
|
|
+ * Revision 1.213 2003/11/24 18:25:49 mcr
|
|
+ * patch from willy@w.ods.org to fix problems with ATM interfaces.
|
|
+ *
|
|
+ * Revision 1.212 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.211.2.2 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.211.2.1 2003/09/21 13:59:56 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.211 2003/09/10 16:46:30 mcr
|
|
+ * patches for 2.4 backport/2.6 existence.
|
|
+ *
|
|
+ * Revision 1.210 2003/07/31 22:47:16 mcr
|
|
+ * preliminary (untested by FS-team) 2.5 patches.
|
|
+ *
|
|
+ * Revision 1.209 2003/06/22 21:28:43 mcr
|
|
+ * inability to unload module was caused by calls to dev_get
|
|
+ * (ipsec_dev_get), to gather a device from a name. There is
|
|
+ * simply no reason to look the devices up - they should be kept
|
|
+ * in a nice array, ready for use.
|
|
+ *
|
|
+ * Revision 1.208 2003/06/22 21:25:07 mcr
|
|
+ * all staticly counted ipsecXXX device support removed.
|
|
+ *
|
|
+ * Revision 1.207 2003/04/02 20:15:37 mcr
|
|
+ * fix for PR#204 - do not clear connection tracking info if we
|
|
+ * the packet is being sent in the clear.
|
|
+ *
|
|
+ * Revision 1.206 2003/02/12 19:32:51 rgb
|
|
+ * Refactored file to:
|
|
+ * ipsec_xmit.c
|
|
+ * ipsec_xmit.h
|
|
+ * ipsec_mast.c
|
|
+ *
|
|
+ * Revision 1.205 2003/02/06 17:47:00 rgb
|
|
+ *
|
|
+ * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code.
|
|
+ * Refactor ipsec_tunnel_start_xmit() further into:
|
|
+ * ipsec_xmit_sanity_check_dev()
|
|
+ * ipsec_xmit_sanity_check_skb()
|
|
+ * ipsec_xmit_strip_hard_header()
|
|
+ * ipsec_xmit_restore_hard_header()
|
|
+ * ipsec_xmit_send()
|
|
+ * ipsec_xmit_cleanup()
|
|
+ * and start a skeletal ipsec_mast_start_xmit() .
|
|
+ *
|
|
+ * Revision 1.204 2003/02/06 06:43:46 rgb
|
|
+ *
|
|
+ * Refactor ipsec_tunnel_start_xmit, bringing out:
|
|
+ * ipsec_xmit_SAlookup
|
|
+ * ipsec_xmit_encap_once
|
|
+ * ipsec_xmit_encap_bundle
|
|
+ *
|
|
+ * Revision 1.203 2003/02/06 02:21:34 rgb
|
|
+ *
|
|
+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
|
|
+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
|
|
+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
|
|
+ *
|
|
+ * Revision 1.202 2003/01/03 07:38:01 rgb
|
|
+ *
|
|
+ * Start to refactor ipsec_tunnel_start_xmit() by putting local variables
|
|
+ * into struct ipsec_xmit_state and renaming a few variables to give more
|
|
+ * unique or searchable names.
|
|
+ *
|
|
+ * Revision 1.201 2003/01/03 00:31:28 rgb
|
|
+ *
|
|
+ * Clean up memset usage, including fixing 2 places where keys were not
|
|
+ * properly wiped.
|
|
+ *
|
|
+ * Revision 1.200 2002/12/06 02:24:02 mcr
|
|
+ * patches for compiling against SUSE 8.1 kernels. Requires
|
|
+ * an additional -DSUSE_LINUX_2_4_19_IS_STUPID.
|
|
+ *
|
|
+ * Revision 1.199 2002/10/12 23:11:53 dhr
|
|
+ *
|
|
+ * [KenB + DHR] more 64-bit cleanup
|
|
+ *
|
|
+ * Revision 1.198 2002/10/05 05:02:58 dhr
|
|
+ *
|
|
+ * C labels go on statements
|
|
+ *
|
|
+ * Revision 1.197 2002/09/20 05:01:50 rgb
|
|
+ * Added compiler directive to switch on IP options and fix IP options bug.
|
|
+ * Make ip->ihl treatment consistent using shifts rather than multiplications.
|
|
+ * Check for large enough packet before accessing udp header for IKE bypass.
|
|
+ * Added memory allocation debugging.
|
|
+ * Fixed potential memory allocation failure-induced oops.
|
|
+ *
|
|
+ * Revision 1.196 2002/07/24 18:44:54 rgb
|
|
+ * Type fiddling to tame ia64 compiler.
|
|
+ *
|
|
+ * Revision 1.195 2002/07/23 03:36:07 rgb
|
|
+ * Fixed 2.2 device initialisation hang.
|
|
+ *
|
|
+ * Revision 1.194 2002/05/27 21:40:34 rgb
|
|
+ * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2.
|
|
+ * Cleaned up intermediate step to dynamic device allocation.
|
|
+ *
|
|
+ * Revision 1.193 2002/05/27 19:31:36 rgb
|
|
+ * Convert to dynamic ipsec device allocation.
|
|
+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
|
|
+ *
|
|
+ * Revision 1.192 2002/05/23 07:14:28 rgb
|
|
+ * Added refcount code.
|
|
+ * Cleaned up %p variants to 0p%p for test suite cleanup.
|
|
+ *
|
|
+ * Revision 1.191 2002/05/14 02:34:37 rgb
|
|
+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
|
|
+ * ipsec_sa or ipsec_sa.
|
|
+ *
|
|
+ * Revision 1.190 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.189 2002/04/24 07:36:32 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v
|
|
+ *
|
|
+ * Revision 1.188 2002/04/20 00:12:25 rgb
|
|
+ * Added esp IV CBC attack fix, disabled.
|
|
+ *
|
|
+ * Revision 1.187 2002/03/23 19:55:17 rgb
|
|
+ * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if
|
|
+ * iptraf or another pcap app is running.
|
|
+ *
|
|
+ * Revision 1.186 2002/03/19 03:26:22 rgb
|
|
+ * Applied DHR's tunnel patch to streamline IKE/specialSA processing.
|
|
+ *
|
|
+ * Revision 1.185 2002/02/20 04:13:05 rgb
|
|
+ * Send back ICMP_PKT_FILTERED upon %reject.
|
|
+ *
|
|
+ * Revision 1.184 2002/01/29 17:17:56 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.183 2002/01/29 04:00:53 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.182 2002/01/29 02:13:18 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.181 2002/01/07 20:00:33 rgb
|
|
+ * Added IKE destination port debugging.
|
|
+ *
|
|
+ * Revision 1.180 2001/12/21 21:49:54 rgb
|
|
+ * Fixed bug as a result of moving IKE bypass above %trap/%hold code.
|
|
+ *
|
|
+ * Revision 1.179 2001/12/19 21:08:14 rgb
|
|
+ * Added transport protocol ports to ipsec_print_ip().
|
|
+ * Update eroute info for non-SA targets.
|
|
+ * Added obey DF code disabled.
|
|
+ * Fixed formatting bugs in ipsec_tunnel_hard_header().
|
|
+ *
|
|
+ * Revision 1.178 2001/12/05 09:36:10 rgb
|
|
+ * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid
|
|
+ * IKE packets being stolen by the %hold (and returned to the sending KMd
|
|
+ * in an ACQUIRE, ironically ;-).
|
|
+ *
|
|
+ * Revision 1.177 2001/11/26 09:23:50 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.170.2.1 2001/09/25 02:28:27 mcr
|
|
+ * struct tdb -> struct ipsec_sa.
|
|
+ * lifetime checks moved to common routines.
|
|
+ * cleaned up includes.
|
|
+ *
|
|
+ * Revision 1.170.2.2 2001/10/22 21:08:01 mcr
|
|
+ * include des.h, removed phony prototypes and fixed calling
|
|
+ * conventions to match real prototypes.
|
|
+ *
|
|
+ * Revision 1.176 2001/11/09 18:32:31 rgb
|
|
+ * Added Hans Schultz' fragmented UDP/500 IKE socket port selector.
|
|
+ *
|
|
+ * Revision 1.175 2001/11/06 20:47:00 rgb
|
|
+ * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling.
|
|
+ *
|
|
+ * Revision 1.174 2001/11/06 19:50:43 rgb
|
|
+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
|
|
+ * use also by pfkey_v2_parser.c
|
|
+ *
|
|
+ * Revision 1.173 2001/10/29 21:53:44 henry
|
|
+ * tone down the device-down message slightly, until we can make it smarter
|
|
+ *
|
|
+ * Revision 1.172 2001/10/26 04:59:37 rgb
|
|
+ * Added a critical level syslog message if an ipsec device goes down.
|
|
+ *
|
|
+ * Revision 1.171 2001/10/18 04:45:21 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/freeswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.170 2001/09/25 00:09:50 rgb
|
|
+ * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a
|
|
+ * HOLD.
|
|
+ *
|
|
+ * Revision 1.169 2001/09/15 16:24:05 rgb
|
|
+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
|
|
+ *
|
|
+ * Revision 1.168 2001/09/14 16:58:37 rgb
|
|
+ * Added support for storing the first and last packets through a HOLD.
|
|
+ *
|
|
+ * Revision 1.167 2001/09/08 21:13:33 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.166 2001/08/27 19:47:59 rgb
|
|
+ * Clear tdb before usage.
|
|
+ * Added comment: clear IF before calling routing?
|
|
+ *
|
|
+ * Revision 1.165 2001/07/03 01:23:53 rgb
|
|
+ * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len >
|
|
+ * emtu, and don't drop.
|
|
+ *
|
|
+ * Revision 1.164 2001/06/14 19:35:10 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.163 2001/06/06 20:28:51 rgb
|
|
+ * Added sanity checks for NULL skbs and devices.
|
|
+ * Added more debugging output to various functions.
|
|
+ * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach().
|
|
+ * Renamed ipsec_tunnel_attach() virtual and physical device arguments.
|
|
+ * Corrected neigh_setup() device function assignment.
|
|
+ * Keep valid pointers to ipsec_tunnel_*() on detach.
|
|
+ * Set dev->type to the originally-initiallised value.
|
|
+ *
|
|
+ * Revision 1.162 2001/06/01 07:28:04 rgb
|
|
+ * Added sanity checks for detached devices. Don't down virtual devices
|
|
+ * to prevent packets going out in the clear if the detached device comes
|
|
+ * back up.
|
|
+ *
|
|
+ * Revision 1.161 2001/05/30 08:14:52 rgb
|
|
+ * Removed vestiges of esp-null transforms.
|
|
+ * NetDev Notifier instrumentation to track down disappearing devices.
|
|
+ *
|
|
+ * Revision 1.160 2001/05/29 05:15:12 rgb
|
|
+ * Added SS' PMTU patch which notifies sender if packet doesn't fit
|
|
+ * physical MTU (if it wasn't ICMP) and then drops it.
|
|
+ *
|
|
+ * Revision 1.159 2001/05/27 06:12:12 rgb
|
|
+ * Added structures for pid, packet count and last access time to eroute.
|
|
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
|
|
+ *
|
|
+ * Revision 1.158 2001/05/24 05:39:33 rgb
|
|
+ * Applied source zeroing to 2.2 ip_route_output() call as well to enable
|
|
+ * PASS eroutes for opportunism.
|
|
+ *
|
|
+ * Revision 1.157 2001/05/23 22:35:28 rgb
|
|
+ * 2.4 source override simplification.
|
|
+ *
|
|
+ * Revision 1.156 2001/05/23 21:41:31 rgb
|
|
+ * Added error return code printing on ip_route_output().
|
|
+ *
|
|
+ * Revision 1.155 2001/05/23 05:09:13 rgb
|
|
+ * Fixed incorrect ip_route_output() failure message.
|
|
+ *
|
|
+ * Revision 1.154 2001/05/21 14:53:31 rgb
|
|
+ * Added debug statement for case when ip_route_output() fails, causing
|
|
+ * packet to be dropped, but log looked ok.
|
|
+ *
|
|
+ * Revision 1.153 2001/05/19 02:37:54 rgb
|
|
+ * Fixed missing comment termination.
|
|
+ *
|
|
+ * Revision 1.152 2001/05/19 02:35:50 rgb
|
|
+ * Debug code optimisation for non-debug speed.
|
|
+ * Kernel version compiler define comments.
|
|
+ * 2.2 and 2.4 kernel ip_send device and ip debug output added.
|
|
+ *
|
|
+ * Revision 1.151 2001/05/18 16:17:35 rgb
|
|
+ * Changed reference from "magic" to "shunt" SAs.
|
|
+ *
|
|
+ * Revision 1.150 2001/05/18 16:12:19 rgb
|
|
+ * Changed UDP/500 bypass test from 3 nested ifs to one anded if.
|
|
+ *
|
|
+ * Revision 1.149 2001/05/16 04:39:33 rgb
|
|
+ * Add default == eroute.dest to IKE bypass conditions for magic eroutes.
|
|
+ *
|
|
+ * Revision 1.148 2001/05/05 03:31:41 rgb
|
|
+ * IP frag debugging updates and enhancements.
|
|
+ *
|
|
+ * Revision 1.147 2001/05/03 19:41:40 rgb
|
|
+ * Added SS' skb_cow fix for 2.4.4.
|
|
+ *
|
|
+ * Revision 1.146 2001/04/30 19:28:16 rgb
|
|
+ * Update for 2.4.4. ip_select_ident() now has 3 args.
|
|
+ *
|
|
+ * Revision 1.145 2001/04/23 14:56:10 rgb
|
|
+ * Added spin_lock() check to prevent double-locking for multiple
|
|
+ * transforms and hence kernel lock-ups with SMP kernels.
|
|
+ *
|
|
+ * Revision 1.144 2001/04/21 23:04:45 rgb
|
|
+ * Define out skb->used for 2.4 kernels.
|
|
+ * Check if soft expire has already been sent before sending another to
|
|
+ * prevent ACQUIRE flooding.
|
|
+ *
|
|
+ * Revision 1.143 2001/03/16 07:37:21 rgb
|
|
+ * Added comments to all #endifs.
|
|
+ *
|
|
+ * Revision 1.142 2001/02/28 05:03:27 rgb
|
|
+ * Clean up and rationalise startup messages.
|
|
+ *
|
|
+ * Revision 1.141 2001/02/27 22:24:54 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.140 2001/02/27 06:40:12 rgb
|
|
+ * Fixed TRAP->HOLD eroute byte order.
|
|
+ *
|
|
+ * Revision 1.139 2001/02/26 20:38:59 rgb
|
|
+ * Added compiler defines for 2.4.x-specific code.
|
|
+ *
|
|
+ * Revision 1.138 2001/02/26 19:57:27 rgb
|
|
+ * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
|
|
+ * of the new SPD and to support opportunistic.
|
|
+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
|
|
+ *
|
|
+ * Revision 1.137 2001/02/19 22:29:49 rgb
|
|
+ * Fixes for presence of active ipv6 segments which share ipsec physical
|
|
+ * device (gg).
|
|
+ *
|
|
+ * Revision 1.136 2001/01/29 22:30:38 rgb
|
|
+ * Fixed minor acquire debug printing bug.
|
|
+ *
|
|
+ * Revision 1.135 2001/01/29 22:19:45 rgb
|
|
+ * Zero source address for 2.4 bypass route lookup.
|
|
+ *
|
|
+ * Revision 1.134 2001/01/23 20:19:49 rgb
|
|
+ * 2.4 fix to remove removed is_clone member.
|
|
+ *
|
|
+ * Revision 1.133 2000/12/09 22:08:35 rgb
|
|
+ * Fix NET_23 bug, should be NETDEV_23.
|
|
+ *
|
|
+ * Revision 1.132 2000/12/01 06:54:50 rgb
|
|
+ * Fix for new 2.4 IP TTL default variable name.
|
|
+ *
|
|
+ * Revision 1.131 2000/11/09 20:52:15 rgb
|
|
+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
|
|
+ * include ipcomp and prevent races, renaming some tdb variables that got
|
|
+ * forgotten, moving some unlocks to include tdbs and adding a missing
|
|
+ * unlock. Thanks to Svenning for some of these.
|
|
+ *
|
|
+ * Revision 1.130 2000/11/09 20:11:22 rgb
|
|
+ * Minor shuffles to fix non-standard kernel config option selection.
|
|
+ *
|
|
+ * Revision 1.129 2000/11/06 04:32:49 rgb
|
|
+ * Clean up debug printing.
|
|
+ * Copy skb->protocol for all kernel versions.
|
|
+ * Ditched spin_lock_irqsave in favour of spin_lock.
|
|
+ * Disabled TTL decrement, done in ip_forward.
|
|
+ * Added debug printing before pfkey_acquire().
|
|
+ * Fixed printk-deltdbchain-spin_lock races (Svenning).
|
|
+ * Use defaultTTL for 2.1+ kernels.
|
|
+ * Add Svenning's adaptive content compression.
|
|
+ * Fix up debug display arguments.
|
|
+ *
|
|
+ * Revision 1.128 2000/09/28 00:58:57 rgb
|
|
+ * Moved the IKE passthrough check after the eroute lookup so we can pass
|
|
+ * IKE through intermediate tunnels.
|
|
+ *
|
|
+ * Revision 1.127 2000/09/22 17:52:11 rgb
|
|
+ * Fixed misleading ipcomp debug output.
|
|
+ *
|
|
+ * Revision 1.126 2000/09/22 04:22:56 rgb
|
|
+ * Fixed dumb spi->cpi conversion error.
|
|
+ *
|
|
+ * Revision 1.125 2000/09/21 04:34:48 rgb
|
|
+ * A few debug-specific things should be hidden under
|
|
+ * CONFIG_IPSEC_DEBUG.(MB)
|
|
+ * Improved ip_send() error handling.(MB)
|
|
+ *
|
|
+ * Revision 1.124 2000/09/21 03:40:58 rgb
|
|
+ * Added more debugging to try and track down the cpi outward copy problem.
|
|
+ *
|
|
+ * Revision 1.123 2000/09/19 07:08:49 rgb
|
|
+ * Added debugging to outgoing compression report.
|
|
+ *
|
|
+ * Revision 1.122 2000/09/18 19:21:26 henry
|
|
+ * RGB-supplied fix for RH5.2 problem
|
|
+ *
|
|
+ * Revision 1.121 2000/09/17 21:05:09 rgb
|
|
+ * Added tdb to skb_compress call to write in cpi.
|
|
+ *
|
|
+ * Revision 1.120 2000/09/17 16:57:16 rgb
|
|
+ * Added Svenning's patch to remove restriction of ipcomp to innermost
|
|
+ * transform.
|
|
+ *
|
|
+ * Revision 1.119 2000/09/15 11:37:01 rgb
|
|
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
|
|
+ * IPCOMP zlib deflate code.
|
|
+ *
|
|
+ * Revision 1.118 2000/09/15 04:57:16 rgb
|
|
+ * Moved debug output after sanity check.
|
|
+ * Added tos copy sysctl.
|
|
+ *
|
|
+ * Revision 1.117 2000/09/12 03:22:51 rgb
|
|
+ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
|
|
+ * sysctl.
|
|
+ *
|
|
+ * Revision 1.116 2000/09/08 19:18:19 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ * Added outgoing opportunistic hook, ifdef'ed out.
|
|
+ *
|
|
+ * Revision 1.115 2000/08/30 05:27:29 rgb
|
|
+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
|
|
+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
|
|
+ *
|
|
+ * Revision 1.114 2000/08/28 18:15:46 rgb
|
|
+ * Added MB's nf-debug reset patch.
|
|
+ *
|
|
+ * Revision 1.113 2000/08/27 02:26:40 rgb
|
|
+ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
|
|
+ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
|
|
+ *
|
|
+ * Revision 1.112 2000/08/20 21:37:33 rgb
|
|
+ * Activated pfkey_expire() calls.
|
|
+ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
|
|
+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
|
|
+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
|
|
+ *
|
|
+ * Revision 1.111 2000/08/01 14:51:51 rgb
|
|
+ * Removed _all_ remaining traces of DES.
|
|
+ *
|
|
+ * Revision 1.110 2000/07/28 14:58:31 rgb
|
|
+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
|
|
+ *
|
|
+ * Revision 1.109 2000/07/28 13:50:54 rgb
|
|
+ * Changed enet_statistics to net_device_stats and added back compatibility
|
|
+ * for pre-2.1.19.
|
|
+ *
|
|
+ * Revision 1.108 2000/05/16 03:03:11 rgb
|
|
+ * Updates for 2.3.99pre8 from MB.
|
|
+ *
|
|
+ * Revision 1.107 2000/05/10 23:08:21 rgb
|
|
+ * Print a debug warning about bogus packets received by the outgoing
|
|
+ * processing machinery only when klipsdebug is not set to none.
|
|
+ * Comment out the device initialisation informational messages.
|
|
+ *
|
|
+ * Revision 1.106 2000/05/10 19:17:14 rgb
|
|
+ * Define an IP_SEND macro, intending to have all packet passthroughs
|
|
+ * use fragmentation. This didn't quite work, but is a step in the
|
|
+ * right direction.
|
|
+ * Added buffer allocation debugging statements.
|
|
+ * Added configure option to shut off no eroute passthrough.
|
|
+ * Only check usetime against soft and hard limits if the tdb has been
|
|
+ * used.
|
|
+ * Cast output of ntohl so that the broken prototype doesn't make our
|
|
+ * compile noisy.
|
|
+ *
|
|
+ * Revision 1.105 2000/03/22 16:15:37 rgb
|
|
+ * Fixed renaming of dev_get (MB).
|
|
+ *
|
|
+ * Revision 1.104 2000/03/16 14:04:15 rgb
|
|
+ * Indented headers for readability.
|
|
+ * Fixed debug scope to enable compilation with debug off.
|
|
+ * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
|
|
+ *
|
|
+ * Revision 1.103 2000/03/16 07:11:07 rgb
|
|
+ * Hardcode PF_KEYv2 support.
|
|
+ * Fixed bug which allowed UDP/500 packet from another machine
|
|
+ * through in the clear.
|
|
+ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
|
|
+ *
|
|
+ * Revision 1.102 2000/03/14 12:26:59 rgb
|
|
+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
|
|
+ *
|
|
+ * Revision 1.101 2000/02/14 21:05:22 rgb
|
|
+ * Added MB's netif_queue fix for kernels 2.3.43+.
|
|
+ *
|
|
+ * Revision 1.100 2000/01/26 10:04:57 rgb
|
|
+ * Fixed noisy 2.0 printk arguments.
|
|
+ *
|
|
+ * Revision 1.99 2000/01/21 06:16:25 rgb
|
|
+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
|
|
+ * Switched to AF_ENCAP macro.
|
|
+ * Shortened debug output per packet and re-arranging debug_tunnel
|
|
+ * bitmap flags, while retaining necessary information to avoid
|
|
+ * trampling the kernel print ring buffer.
|
|
+ * Reformatted recursion switch code.
|
|
+ * Changed all references to tdb_proto to tdb_said.proto for clarity.
|
|
+ *
|
|
+ * Revision 1.98 2000/01/13 08:09:31 rgb
|
|
+ * Shuffled debug_tunnel switches to focus output.
|
|
+ * Fixed outgoing recursion bug, limiting to recursing only if the remote
|
|
+ * SG changes and if it is valid, ie. not passthrough.
|
|
+ * Clarified a number of debug messages.
|
|
+ *
|
|
+ * Revision 1.97 2000/01/10 16:37:16 rgb
|
|
+ * MB support for new ip_select_ident() upon disappearance of
|
|
+ * ip_id_count in 2.3.36+.
|
|
+ *
|
|
+ * Revision 1.96 1999/12/31 14:59:08 rgb
|
|
+ * MB fix to use new skb_copy_expand in kernel 2.3.35.
|
|
+ *
|
|
+ * Revision 1.95 1999/12/29 21:15:44 rgb
|
|
+ * Fix tncfg to aliased device bug.
|
|
+ *
|
|
+ * Revision 1.94 1999/12/22 04:26:06 rgb
|
|
+ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
|
|
+ * debugging by providing external labels to all functions with debugging
|
|
+ * turned on.
|
|
+ *
|
|
+ * Revision 1.93 1999/12/13 13:30:14 rgb
|
|
+ * Changed MTU reports and HW address reporting back to debug only.
|
|
+ *
|
|
+ * Revision 1.92 1999/12/07 18:57:56 rgb
|
|
+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
|
|
+ *
|
|
+ * Revision 1.91 1999/12/01 22:15:36 rgb
|
|
+ * Add checks for LARVAL and DEAD SAs.
|
|
+ * Change state of SA from MATURE to DYING when a soft lifetime is
|
|
+ * reached and print debug warning.
|
|
+ *
|
|
+ * Revision 1.90 1999/11/23 23:04:04 rgb
|
|
+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
|
|
+ * Sort out pfkey and freeswan headers, putting them in a library path.
|
|
+ *
|
|
+ * Revision 1.89 1999/11/18 18:50:59 rgb
|
|
+ * Changed all device registrations for static linking to
|
|
+ * dynamic to reduce the number and size of patches.
|
|
+ *
|
|
+ * Revision 1.88 1999/11/18 04:09:19 rgb
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ *
|
|
+ * Revision 1.87 1999/11/17 15:53:40 rgb
|
|
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
|
|
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
|
|
+ * klips/net/ipsec/Makefile.
|
|
+ *
|
|
+ * Revision 1.86 1999/10/16 18:25:37 rgb
|
|
+ * Moved SA lifetime expiry checks before packet processing.
|
|
+ * Expire SA on replay counter rollover.
|
|
+ *
|
|
+ * Revision 1.85 1999/10/16 04:24:31 rgb
|
|
+ * Add stats for time since last packet.
|
|
+ *
|
|
+ * Revision 1.84 1999/10/16 00:30:47 rgb
|
|
+ * Added SA lifetime counting.
|
|
+ *
|
|
+ * Revision 1.83 1999/10/15 22:15:57 rgb
|
|
+ * Clean out cruft.
|
|
+ * Add debugging.
|
|
+ *
|
|
+ * Revision 1.82 1999/10/08 18:26:19 rgb
|
|
+ * Fix 2.0.3x outgoing fragmented packet memory leak.
|
|
+ *
|
|
+ * Revision 1.81 1999/10/05 02:38:54 rgb
|
|
+ * Lower the default mtu of virtual devices to 16260.
|
|
+ *
|
|
+ * Revision 1.80 1999/10/03 18:56:41 rgb
|
|
+ * Spinlock support for 2.3.xx.
|
|
+ * Don't forget to undo spinlocks on error!
|
|
+ * Check for valid eroute before copying the structure.
|
|
+ *
|
|
+ * Revision 1.79 1999/10/01 15:44:53 rgb
|
|
+ * Move spinlock header include to 2.1> scope.
|
|
+ *
|
|
+ * Revision 1.78 1999/10/01 00:02:43 rgb
|
|
+ * Added tdb structure locking.
|
|
+ * Added eroute structure locking.
|
|
+ *
|
|
+ * Revision 1.77 1999/09/30 02:52:29 rgb
|
|
+ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
|
|
+ *
|
|
+ * Revision 1.76 1999/09/25 19:31:27 rgb
|
|
+ * Refine MSS hack to affect SYN, but not SYN+ACK packets.
|
|
+ *
|
|
+ * Revision 1.75 1999/09/24 22:52:38 rgb
|
|
+ * Fix two things broken in 2.0.38 by trying to fix network notifiers.
|
|
+ *
|
|
+ * Revision 1.74 1999/09/24 00:30:37 rgb
|
|
+ * Add test for changed source as well as destination to check for
|
|
+ * recursion.
|
|
+ *
|
|
+ * Revision 1.73 1999/09/23 20:52:24 rgb
|
|
+ * Add James Morris' MSS hack patch, disabled.
|
|
+ *
|
|
+ * Revision 1.72 1999/09/23 20:22:40 rgb
|
|
+ * Enable, tidy and fix network notifier code.
|
|
+ *
|
|
+ * Revision 1.71 1999/09/23 18:09:05 rgb
|
|
+ * Clean up 2.2.x fragmenting traces.
|
|
+ * Disable dev->type switching, forcing ARPHRD_TUNNEL.
|
|
+ *
|
|
+ * Revision 1.70 1999/09/22 14:14:24 rgb
|
|
+ * Add sanity checks for revectored calls to prevent calling a downed I/F.
|
|
+ *
|
|
+ * Revision 1.69 1999/09/21 15:00:57 rgb
|
|
+ * Add Marc Boucher's packet size check.
|
|
+ * Flesh out network device notifier code.
|
|
+ *
|
|
+ * Revision 1.68 1999/09/18 11:39:57 rgb
|
|
+ * Start to add (disabled) netdevice notifier code.
|
|
+ *
|
|
+ * Revision 1.67 1999/09/17 23:44:40 rgb
|
|
+ * Add a comment warning potential code hackers to stay away from mac.raw.
|
|
+ *
|
|
+ * Revision 1.66 1999/09/17 18:04:02 rgb
|
|
+ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
|
|
+ * Ditch TTL decrement in 2.2 (MB).
|
|
+ *
|
|
+ * Revision 1.65 1999/09/15 23:15:35 henry
|
|
+ * Marc Boucher's PPP fixes
|
|
+ *
|
|
+ * Revision 1.64 1999/09/07 13:40:53 rgb
|
|
+ * Ditch unreliable references to skb->mac.raw.
|
|
+ *
|
|
+ * Revision 1.63 1999/08/28 11:33:09 rgb
|
|
+ * Check for null skb->mac pointer.
|
|
+ *
|
|
+ * Revision 1.62 1999/08/28 02:02:30 rgb
|
|
+ * Add Marc Boucher's fix for properly dealing with skb->sk.
|
|
+ *
|
|
+ * Revision 1.61 1999/08/27 05:23:05 rgb
|
|
+ * Clean up skb->data/raw/nh/h manipulation.
|
|
+ * Add Marc Boucher's mods to aid tcpdump.
|
|
+ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
|
|
+ * Re-order hard_header stripping -- might be able to remove it...
|
|
+ *
|
|
+ * Revision 1.60 1999/08/26 20:01:02 rgb
|
|
+ * Tidy up compiler directives and macros.
|
|
+ * Re-enable ICMP for tunnels where inner_dst != outer_dst.
|
|
+ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
|
|
+ *
|
|
+ * Revision 1.59 1999/08/25 15:44:41 rgb
|
|
+ * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
|
|
+ *
|
|
+ * Revision 1.58 1999/08/25 15:00:54 rgb
|
|
+ * Add dst cache code for 2.2.xx.
|
|
+ * Add sanity check for skb packet header pointers.
|
|
+ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
|
|
+ * *_rebuild_header.
|
|
+ * Add neigh_* cache code.
|
|
+ * Change dev->type back to ARPHRD_TUNNEL.
|
|
+ *
|
|
+ * Revision 1.57 1999/08/17 21:50:23 rgb
|
|
+ * Fixed minor debug output bugs.
|
|
+ * Regrouped error recovery exit code.
|
|
+ * Added compiler directives to remove unwanted code and symbols.
|
|
+ * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
|
|
+ * Add debugging code for output function addresses.
|
|
+ * Fix minor bug in (possibly unused) header_cache_bind function.
|
|
+ * Add device neighbour caching code.
|
|
+ * Change dev->type from ARPHRD_TUNNEL to physdev->type.
|
|
+ *
|
|
+ * Revision 1.56 1999/08/03 17:22:56 rgb
|
|
+ * Debug output clarification using KERN_* macros. Other inactive changes
|
|
+ * added.
|
|
+ *
|
|
+ * Revision 1.55 1999/08/03 16:58:46 rgb
|
|
+ * Fix skb_copy_expand size bug. Was getting incorrect size.
|
|
+ *
|
|
+ * Revision 1.54 1999/07/14 19:32:38 rgb
|
|
+ * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
|
|
+ *
|
|
+ * Revision 1.53 1999/06/10 15:44:02 rgb
|
|
+ * Minor reformatting and clean-up.
|
|
+ *
|
|
+ * Revision 1.52 1999/05/09 03:25:36 rgb
|
|
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
|
|
+ *
|
|
+ * Revision 1.51 1999/05/08 21:24:59 rgb
|
|
+ * Add casting to silence the 2.2.x compile.
|
|
+ *
|
|
+ * Revision 1.50 1999/05/05 22:02:32 rgb
|
|
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
|
|
+ *
|
|
+ * Revision 1.49 1999/04/29 15:18:52 rgb
|
|
+ * Change gettdb parameter to a pointer to reduce stack loading and
|
|
+ * facilitate parameter sanity checking.
|
|
+ * Fix undetected bug that might have tried to access a null pointer.
|
|
+ * Eliminate unnessessary usage of tdb_xform member to further switch
|
|
+ * away from the transform switch to the algorithm switch.
|
|
+ * Add return values to init and cleanup functions.
|
|
+ *
|
|
+ * Revision 1.48 1999/04/16 15:38:00 rgb
|
|
+ * Minor rearrangement of freeing code to avoid memory leaks with impossible or
|
|
+ * rare situations.
|
|
+ *
|
|
+ * Revision 1.47 1999/04/15 15:37:25 rgb
|
|
+ * Forward check changes from POST1_00 branch.
|
|
+ *
|
|
+ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb
|
|
+ * Ditch 'things I wish I had known before...'.
|
|
+ *
|
|
+ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb
|
|
+ * Free skb after fragmentation.
|
|
+ * Use stats more effectively.
|
|
+ * Add I/F to mtu notch-down reporting.
|
|
+ *
|
|
+ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb
|
|
+ * Backcheck from HEAD, pre1.0.
|
|
+ *
|
|
+ * Revision 1.46 1999/04/11 00:29:00 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.45 1999/04/07 15:42:01 rgb
|
|
+ * Fix mtu/ping bug AGAIN!
|
|
+ *
|
|
+ * Revision 1.44 1999/04/06 04:54:27 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.43 1999/04/04 03:57:07 rgb
|
|
+ * ip_fragment() doesn't free the supplied skb. Freed.
|
|
+ *
|
|
+ * Revision 1.42 1999/04/01 23:27:15 rgb
|
|
+ * Preload size of virtual mtu.
|
|
+ *
|
|
+ * Revision 1.41 1999/04/01 09:31:23 rgb
|
|
+ * Invert meaning of ICMP PMTUD config option and clarify.
|
|
+ * Code clean-up.
|
|
+ *
|
|
+ * Revision 1.40 1999/04/01 04:37:17 rgb
|
|
+ * SSH stalling bug fix.
|
|
+ *
|
|
+ * Revision 1.39 1999/03/31 23:44:28 rgb
|
|
+ * Don't send ICMP on DF and frag_off.
|
|
+ *
|
|
+ * Revision 1.38 1999/03/31 15:20:10 rgb
|
|
+ * Quiet down debugging.
|
|
+ *
|
|
+ * Revision 1.37 1999/03/31 08:30:31 rgb
|
|
+ * Add switch to shut off ICMP PMTUD packets.
|
|
+ *
|
|
+ * Revision 1.36 1999/03/31 05:44:47 rgb
|
|
+ * Keep PMTU reduction private.
|
|
+ *
|
|
+ * Revision 1.35 1999/03/27 15:13:02 rgb
|
|
+ * PMTU/fragmentation bug fix.
|
|
+ *
|
|
+ * Revision 1.34 1999/03/17 21:19:26 rgb
|
|
+ * Fix kmalloc nonatomic bug.
|
|
+ *
|
|
+ * Revision 1.33 1999/03/17 15:38:42 rgb
|
|
+ * Code clean-up.
|
|
+ * ESP_NULL IV bug fix.
|
|
+ *
|
|
+ * Revision 1.32 1999/03/01 20:44:25 rgb
|
|
+ * Code clean-up.
|
|
+ * Memory leak bug fix.
|
|
+ *
|
|
+ * Revision 1.31 1999/02/27 00:02:09 rgb
|
|
+ * Tune to report the MTU reduction once, rather than after every recursion
|
|
+ * through the encapsulating code, preventing tcp stream stalling.
|
|
+ *
|
|
+ * Revision 1.30 1999/02/24 20:21:01 rgb
|
|
+ * Reformat debug printk's.
|
|
+ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
|
|
+ * Clean-up.
|
|
+ *
|
|
+ * Revision 1.29 1999/02/22 17:08:14 rgb
|
|
+ * Fix recursive encapsulation code.
|
|
+ *
|
|
+ * Revision 1.28 1999/02/19 18:27:02 rgb
|
|
+ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
|
|
+ *
|
|
+ * Revision 1.27 1999/02/17 16:51:37 rgb
|
|
+ * Clean out unused cruft.
|
|
+ * Temporarily tone down volume of debug output.
|
|
+ * Temporarily shut off fragment rejection.
|
|
+ * Disabled temporary failed recursive encapsulation loop.
|
|
+ *
|
|
+ * Revision 1.26 1999/02/12 21:21:26 rgb
|
|
+ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
|
|
+ *
|
|
+ * Revision 1.25 1999/02/11 19:38:27 rgb
|
|
+ * More clean-up.
|
|
+ * Add sanity checking for skb_copy_expand() to prevent kernel panics on
|
|
+ * skb_put() values out of range.
|
|
+ * Fix head/tailroom calculation causing skb_put() out-of-range values.
|
|
+ * Fix return values to prevent 'nonatomic alloc_skb' warnings.
|
|
+ * Allocate new skb iff needed.
|
|
+ * Added more debug statements.
|
|
+ * Make headroom depend on structure, not hard-coded values.
|
|
+ *
|
|
+ * Revision 1.24 1999/02/10 23:20:33 rgb
|
|
+ * Shut up annoying 'statement has no effect' compiler warnings with
|
|
+ * debugging compiled out.
|
|
+ *
|
|
+ * Revision 1.23 1999/02/10 22:36:30 rgb
|
|
+ * Clean-up obsolete, unused and messy code.
|
|
+ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
|
|
+ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
|
|
+ * original ipsec_tunnel_start_xmit.
|
|
+ * Send all packet with different inner and outer destinations directly to
|
|
+ * the attached physical device, rather than back through ip_forward,
|
|
+ * preventing disappearing routes problems.
|
|
+ * Do sanity checking before investing too much CPU in allocating new
|
|
+ * structures.
|
|
+ * Fail on IP header options: We cannot process them yet.
|
|
+ * Add some helpful comments.
|
|
+ * Use virtual device for parameters instead of physical device.
|
|
+ *
|
|
+ * Revision 1.22 1999/02/10 03:03:02 rgb
|
|
+ * Duh. Fixed the TTL bug: forgot to update the checksum.
|
|
+ *
|
|
+ * Revision 1.21 1999/02/09 23:17:53 rgb
|
|
+ * Add structure members to ipsec_print_ip debug function.
|
|
+ * Temporarily fix TTL bug preventing tunnel mode from functioning.
|
|
+ *
|
|
+ * Revision 1.20 1999/02/09 00:14:25 rgb
|
|
+ * Add KLIPSPRINT macro. (Not used yet, though.)
|
|
+ * Delete old ip_tunnel code (BADCODE).
|
|
+ * Decrement TTL in outgoing packet.
|
|
+ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
|
|
+ * Delete ethernet only feature and fix hard-coded hard_header_len.
|
|
+ *
|
|
+ * Revision 1.19 1999/01/29 17:56:22 rgb
|
|
+ * 64-bit re-fix submitted by Peter Onion.
|
|
+ *
|
|
+ * Revision 1.18 1999/01/28 22:43:24 rgb
|
|
+ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
|
|
+ *
|
|
+ * Revision 1.17 1999/01/26 02:08:16 rgb
|
|
+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
|
|
+ * Removed dead code.
|
|
+ *
|
|
+ * Revision 1.16 1999/01/22 06:25:26 rgb
|
|
+ * Cruft clean-out.
|
|
+ * Added algorithm switch code.
|
|
+ * 64-bit clean-up.
|
|
+ * Passthrough on IPIP protocol, spi 0x0 fix.
|
|
+ * Enhanced debugging.
|
|
+ *
|
|
+ * Revision 1.15 1998/12/01 13:22:04 rgb
|
|
+ * Added support for debug printing of version info.
|
|
+ *
|
|
+ * Revision 1.14 1998/11/30 13:22:55 rgb
|
|
+ * Rationalised all the klips kernel file headers. They are much shorter
|
|
+ * now and won't conflict under RH5.2.
|
|
+ *
|
|
+ * Revision 1.13 1998/11/17 21:13:52 rgb
|
|
+ * Put IKE port bypass debug output in user-switched debug statements.
|
|
+ *
|
|
+ * Revision 1.12 1998/11/13 13:20:25 rgb
|
|
+ * Fixed ntohs bug in udp/500 hole for IKE.
|
|
+ *
|
|
+ * Revision 1.11 1998/11/10 08:01:19 rgb
|
|
+ * Kill tcp/500 hole, keep udp/500 hole.
|
|
+ *
|
|
+ * Revision 1.10 1998/11/09 21:29:26 rgb
|
|
+ * If no eroute is found, discard packet and incr. tx_error.
|
|
+ *
|
|
+ * Revision 1.9 1998/10/31 06:50:00 rgb
|
|
+ * Add tcp/udp/500 bypass.
|
|
+ * Fixed up comments in #endif directives.
|
|
+ *
|
|
+ * Revision 1.8 1998/10/27 00:34:31 rgb
|
|
+ * Reformat debug output of IP headers.
|
|
+ * Newlines added before calls to ipsec_print_ip.
|
|
+ *
|
|
+ * Revision 1.7 1998/10/19 14:44:28 rgb
|
|
+ * Added inclusion of freeswan.h.
|
|
+ * sa_id structure implemented and used: now includes protocol.
|
|
+ *
|
|
+ * Revision 1.6 1998/10/09 04:31:35 rgb
|
|
+ * Added 'klips_debug' prefix to all klips printk debug statements.
|
|
+ *
|
|
+ * Revision 1.5 1998/08/28 03:09:51 rgb
|
|
+ * Prevent kernel log spam with default route through ipsec.
|
|
+ *
|
|
+ * Revision 1.4 1998/08/05 22:23:09 rgb
|
|
+ * Change setdev return code to ENXIO for a non-existant physical device.
|
|
+ *
|
|
+ * Revision 1.3 1998/07/29 20:41:11 rgb
|
|
+ * Add ipsec_tunnel_clear to clear all tunnel attachments.
|
|
+ *
|
|
+ * Revision 1.2 1998/06/25 20:00:33 rgb
|
|
+ * Clean up #endif comments.
|
|
+ * Rename dev_ipsec to dev_ipsec0 for consistency.
|
|
+ * Document ipsec device fields.
|
|
+ * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
|
|
+ * Get debugging report for *every* ipsec device initialisation.
|
|
+ * Comment out redundant code.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:50 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.8 1998/06/14 23:49:40 rgb
|
|
+ * Clarify version reporting on module loading.
|
|
+ *
|
|
+ * Revision 1.7 1998/05/27 23:19:20 rgb
|
|
+ * Added version reporting.
|
|
+ *
|
|
+ * Revision 1.6 1998/05/18 21:56:23 rgb
|
|
+ * Clean up for numerical consistency of output and cleaning up debug code.
|
|
+ *
|
|
+ * Revision 1.5 1998/05/12 02:44:23 rgb
|
|
+ * Clarifying 'no e-route to host' message.
|
|
+ *
|
|
+ * Revision 1.4 1998/04/30 15:34:35 rgb
|
|
+ * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
|
|
+ *
|
|
+ * Revision 1.3 1998/04/21 21:28:54 rgb
|
|
+ * Rearrange debug switches to change on the fly debug output from user
|
|
+ * space. Only kernel changes checked in at this time. radij.c was also
|
|
+ * changed to temporarily remove buggy debugging code in rj_delete causing
|
|
+ * an OOPS and hence, netlink device open errors.
|
|
+ *
|
|
+ * Revision 1.2 1998/04/12 22:03:24 rgb
|
|
+ * Updated ESP-3DES-HMAC-MD5-96,
|
|
+ * ESP-DES-HMAC-MD5-96,
|
|
+ * AH-HMAC-MD5-96,
|
|
+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
|
|
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
|
|
+ *
|
|
+ * Fixed eroute references in /proc/net/ipsec*.
|
|
+ *
|
|
+ * Started to patch module unloading memory leaks in ipsec_netlink and
|
|
+ * radij tree unloading.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:12 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.5 1997/06/03 04:24:48 ji
|
|
+ * Added transport mode.
|
|
+ * Changed the way routing is done.
|
|
+ * Lots of bug fixes.
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * No changes.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:39:04 ji
|
|
+ * Minor cleanups.
|
|
+ * Rationalized debugging code.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ * Local Variables:
|
|
+ * c-style: linux
|
|
+ * End:
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,360 @@
|
|
+/*
|
|
+ * Common routines for IPSEC transformations.
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: ipsec_xform.c,v 1.65.2.1 2006/10/06 21:39:26 paul Exp $
|
|
+ */
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "freeswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <linux/random.h> /* get_random_bytes() */
|
|
+#include <freeswan.h>
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#include "freeswan/radij.h"
|
|
+#include "freeswan/ipsec_encap.h"
|
|
+#include "freeswan/ipsec_radij.h"
|
|
+#include "freeswan/ipsec_xform.h"
|
|
+#include "freeswan/ipsec_ipe4.h"
|
|
+#include "freeswan/ipsec_ah.h"
|
|
+#include "freeswan/ipsec_esp.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int debug_xform = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+#ifdef SPINLOCK
|
|
+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
|
|
+#else /* SPINLOCK */
|
|
+spinlock_t tdb_lock;
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_xform.c,v $
|
|
+ * Revision 1.65.2.1 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.65 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.64 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.63 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.62.30.1 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.62 2002/05/14 02:34:21 rgb
|
|
+ * Delete stale code.
|
|
+ *
|
|
+ * Revision 1.61 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.60 2002/04/24 07:36:33 mcr
|
|
+ * Moved from ./klips/net/ipsec/ipsec_xform.c,v
|
|
+ *
|
|
+ * Revision 1.59 2002/03/29 15:01:36 rgb
|
|
+ * Delete decommissioned code.
|
|
+ *
|
|
+ * Revision 1.58 2002/01/29 17:17:57 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.57 2002/01/29 04:00:53 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.56 2001/11/27 05:17:22 mcr
|
|
+ * turn off the worst of the per-packet debugging.
|
|
+ *
|
|
+ * Revision 1.55 2001/11/26 09:23:50 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.54 2001/10/18 04:45:21 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/freeswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.53 2001/09/08 21:13:34 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.52 2001/06/14 19:35:11 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.51 2001/05/30 08:14:03 rgb
|
|
+ * Removed vestiges of esp-null transforms.
|
|
+ *
|
|
+ * Revision 1.50 2001/05/03 19:43:18 rgb
|
|
+ * Initialise error return variable.
|
|
+ * Update SENDERR macro.
|
|
+ * Fix sign of error return code for ipsec_tdbcleanup().
|
|
+ * Use more appropriate return code for ipsec_tdbwipe().
|
|
+ *
|
|
+ * Revision 1.49 2001/04/19 18:56:17 rgb
|
|
+ * Fixed tdb table locking comments.
|
|
+ *
|
|
+ * Revision 1.48 2001/02/27 22:24:55 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.47 2000/11/06 04:32:08 rgb
|
|
+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
|
|
+ *
|
|
+ * Revision 1.46 2000/09/20 16:21:57 rgb
|
|
+ * Cleaned up ident string alloc/free.
|
|
+ *
|
|
+ * Revision 1.45 2000/09/08 19:16:51 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
|
|
+ *
|
|
+ * Revision 1.44 2000/08/30 05:29:04 rgb
|
|
+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
|
|
+ *
|
|
+ * Revision 1.43 2000/08/18 21:30:41 rgb
|
|
+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
|
|
+ *
|
|
+ * Revision 1.42 2000/08/01 14:51:51 rgb
|
|
+ * Removed _all_ remaining traces of DES.
|
|
+ *
|
|
+ * Revision 1.41 2000/07/28 14:58:31 rgb
|
|
+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
|
|
+ *
|
|
+ * Revision 1.40 2000/06/28 05:50:11 rgb
|
|
+ * Actually set iv_bits.
|
|
+ *
|
|
+ * Revision 1.39 2000/05/10 23:11:09 rgb
|
|
+ * Added netlink debugging output.
|
|
+ * Added a cast to quiet down the ntohl bug.
|
|
+ *
|
|
+ * Revision 1.38 2000/05/10 19:18:42 rgb
|
|
+ * Cast output of ntohl so that the broken prototype doesn't make our
|
|
+ * compile noisy.
|
|
+ *
|
|
+ * Revision 1.37 2000/03/16 14:04:59 rgb
|
|
+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
|
|
+ *
|
|
+ * Revision 1.36 2000/01/26 10:11:28 rgb
|
|
+ * Fixed spacing in error text causing run-in words.
|
|
+ *
|
|
+ * Revision 1.35 2000/01/21 06:17:16 rgb
|
|
+ * Tidied up compiler directive indentation for readability.
|
|
+ * Added ictx,octx vars for simplification.(kravietz)
|
|
+ * Added macros for HMAC padding magic numbers.(kravietz)
|
|
+ * Fixed missing key length reporting bug.
|
|
+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
|
|
+ *
|
|
+ * Revision 1.34 1999/12/08 00:04:19 rgb
|
|
+ * Fixed SA direction overwriting bug for netlink users.
|
|
+ *
|
|
+ * Revision 1.33 1999/12/01 22:16:44 rgb
|
|
+ * Minor formatting changes in ESP MD5 initialisation.
|
|
+ *
|
|
+ * Revision 1.32 1999/11/25 09:06:36 rgb
|
|
+ * Fixed error return messages, should be returning negative numbers.
|
|
+ * Implemented SENDERR macro for propagating error codes.
|
|
+ * Added debug message and separate error code for algorithms not compiled
|
|
+ * in.
|
|
+ *
|
|
+ * Revision 1.31 1999/11/23 23:06:26 rgb
|
|
+ * Sort out pfkey and freeswan headers, putting them in a library path.
|
|
+ *
|
|
+ * Revision 1.30 1999/11/18 04:09:20 rgb
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ *
|
|
+ * Revision 1.29 1999/11/17 15:53:40 rgb
|
|
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
|
|
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
|
|
+ * klips/net/ipsec/Makefile.
|
|
+ *
|
|
+ * Revision 1.28 1999/10/18 20:04:01 rgb
|
|
+ * Clean-out unused cruft.
|
|
+ *
|
|
+ * Revision 1.27 1999/10/03 19:01:03 rgb
|
|
+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
|
|
+ *
|
|
+ * Revision 1.26 1999/10/01 16:22:24 rgb
|
|
+ * Switch from assignment init. to functional init. of spinlocks.
|
|
+ *
|
|
+ * Revision 1.25 1999/10/01 15:44:54 rgb
|
|
+ * Move spinlock header include to 2.1> scope.
|
|
+ *
|
|
+ * Revision 1.24 1999/10/01 00:03:46 rgb
|
|
+ * Added tdb structure locking.
|
|
+ * Minor formatting changes.
|
|
+ * Add function to initialize tdb hash table.
|
|
+ *
|
|
+ * Revision 1.23 1999/05/25 22:42:12 rgb
|
|
+ * Add deltdbchain() debugging.
|
|
+ *
|
|
+ * Revision 1.22 1999/05/25 21:24:31 rgb
|
|
+ * Add debugging statements to deltdbchain().
|
|
+ *
|
|
+ * Revision 1.21 1999/05/25 03:51:48 rgb
|
|
+ * Refix error return code.
|
|
+ *
|
|
+ * Revision 1.20 1999/05/25 03:34:07 rgb
|
|
+ * Fix error return for flush.
|
|
+ *
|
|
+ * Revision 1.19 1999/05/09 03:25:37 rgb
|
|
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
|
|
+ *
|
|
+ * Revision 1.18 1999/05/05 22:02:32 rgb
|
|
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
|
|
+ *
|
|
+ * Revision 1.17 1999/04/29 15:20:16 rgb
|
|
+ * Change gettdb parameter to a pointer to reduce stack loading and
|
|
+ * facilitate parameter sanity checking.
|
|
+ * Add sanity checking for null pointer arguments.
|
|
+ * Add debugging instrumentation.
|
|
+ * Add function deltdbchain() which will take care of unlinking,
|
|
+ * zeroing and deleting a chain of tdbs.
|
|
+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
|
|
+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
|
|
+ * structures.
|
|
+ *
|
|
+ * Revision 1.16 1999/04/16 15:36:29 rgb
|
|
+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
|
|
+ *
|
|
+ * Revision 1.15 1999/04/11 00:29:01 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.14 1999/04/06 04:54:28 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.13 1999/02/19 18:23:01 rgb
|
|
+ * Nix debug off compile warning.
|
|
+ *
|
|
+ * Revision 1.12 1999/02/17 16:52:16 rgb
|
|
+ * Consolidate satoa()s for space and speed efficiency.
|
|
+ * Convert DEBUG_IPSEC to KLIPS_PRINT
|
|
+ * Clean out unused cruft.
|
|
+ * Ditch NET_IPIP dependancy.
|
|
+ * Loop for 3des key setting.
|
|
+ *
|
|
+ * Revision 1.11 1999/01/26 02:09:05 rgb
|
|
+ * Remove ah/esp/IPIP switching on include files.
|
|
+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
|
|
+ * Removed dead code.
|
|
+ * Clean up debug code when switched off.
|
|
+ * Remove references to INET_GET_PROTOCOL.
|
|
+ * Added code exclusion macros to reduce code from unused algorithms.
|
|
+ *
|
|
+ * Revision 1.10 1999/01/22 06:28:55 rgb
|
|
+ * Cruft clean-out.
|
|
+ * Put random IV generation in kernel.
|
|
+ * Added algorithm switch code.
|
|
+ * Enhanced debugging.
|
|
+ * 64-bit clean-up.
|
|
+ *
|
|
+ * Revision 1.9 1998/11/30 13:22:55 rgb
|
|
+ * Rationalised all the klips kernel file headers. They are much shorter
|
|
+ * now and won't conflict under RH5.2.
|
|
+ *
|
|
+ * Revision 1.8 1998/11/25 04:59:06 rgb
|
|
+ * Add conditionals for no IPIP tunnel code.
|
|
+ * Delete commented out code.
|
|
+ *
|
|
+ * Revision 1.7 1998/10/31 06:50:41 rgb
|
|
+ * Convert xform ASCII names to no spaces.
|
|
+ * Fixed up comments in #endif directives.
|
|
+ *
|
|
+ * Revision 1.6 1998/10/19 14:44:28 rgb
|
|
+ * Added inclusion of freeswan.h.
|
|
+ * sa_id structure implemented and used: now includes protocol.
|
|
+ *
|
|
+ * Revision 1.5 1998/10/09 04:32:19 rgb
|
|
+ * Added 'klips_debug' prefix to all klips printk debug statements.
|
|
+ *
|
|
+ * Revision 1.4 1998/08/12 00:11:31 rgb
|
|
+ * Added new xform functions to the xform table.
|
|
+ * Fixed minor debug output spelling error.
|
|
+ *
|
|
+ * Revision 1.3 1998/07/09 17:45:31 rgb
|
|
+ * Clarify algorithm not available message.
|
|
+ *
|
|
+ * Revision 1.2 1998/06/23 03:00:51 rgb
|
|
+ * Check for presence of IPIP protocol if it is setup one way (we don't
|
|
+ * know what has been set up the other way and can only assume it will be
|
|
+ * symmetrical with the exception of keys).
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:27:51 henry
|
|
+ * move sources from klips/src to klips/net/ipsec, to keep stupid
|
|
+ * kernel-build scripts happier in the presence of symlinks
|
|
+ *
|
|
+ * Revision 1.3 1998/06/11 05:54:59 rgb
|
|
+ * Added transform version string pointer to xformsw initialisations.
|
|
+ *
|
|
+ * Revision 1.2 1998/04/21 21:28:57 rgb
|
|
+ * Rearrange debug switches to change on the fly debug output from user
|
|
+ * space. Only kernel changes checked in at this time. radij.c was also
|
|
+ * changed to temporarily remove buggy debugging code in rj_delete causing
|
|
+ * an OOPS and hence, netlink device open errors.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:13 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.5 1997/06/03 04:24:48 ji
|
|
+ * Added ESP-3DES-MD5-96
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * Added new transforms.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:39:04 ji
|
|
+ * Minor cleanups.
|
|
+ * Rationalized debugging code.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1855 @@
|
|
+/*
|
|
+ * IPSEC Transmit code.
|
|
+ * Copyright (C) 1996, 1997 John Ioannidis.
|
|
+ * Copyright (C) 1998-2003 Richard Guy Briggs.
|
|
+ * Copyright (C) 2004-2005 Michael Richardson <mcr@xelerance.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+char ipsec_xmit_c_version[] = "RCSID $Id: ipsec_xmit.c,v 1.20.2.9 2007/07/06 17:18:43 paul Exp $";
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif /* for CONFIG_IP_FORWARD */
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/tcp.h> /* struct tcphdr */
|
|
+#include <linux/udp.h> /* struct udphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#include <asm/uaccess.h>
|
|
+#include <asm/checksum.h>
|
|
+#include <openswan.h>
|
|
+#ifdef NET_21
|
|
+# define MSS_HACK_ /* experimental */
|
|
+# include <linux/in6.h>
|
|
+# include <net/dst.h>
|
|
+# define proto_priv cb
|
|
+#endif /* NET_21 */
|
|
+
|
|
+#include <net/icmp.h> /* icmp_send() */
|
|
+#include <net/ip.h>
|
|
+#ifdef NETDEV_23
|
|
+# include <linux/netfilter_ipv4.h>
|
|
+#endif /* NETDEV_23 */
|
|
+
|
|
+#include <linux/if_arp.h>
|
|
+#ifdef MSS_HACK
|
|
+# include <net/tcp.h> /* TCP options */
|
|
+#endif /* MSS_HACK */
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_life.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_eroute.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xmit.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_ipe4.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_esp.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+#include "openswan/ipcomp.h"
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#include "openswan/ipsec_alg.h"
|
|
+
|
|
+
|
|
+/*
|
|
+ * Stupid kernel API differences in APIs. Not only do some
|
|
+ * kernels not have ip_select_ident, but some have differing APIs,
|
|
+ * and SuSE has one with one parameter, but no way of checking to
|
|
+ * see what is really what.
|
|
+ */
|
|
+
|
|
+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
|
|
+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
|
|
+#else
|
|
+
|
|
+/* simplest case, nothing */
|
|
+#if !defined(IP_SELECT_IDENT)
|
|
+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
|
|
+#endif
|
|
+
|
|
+/* kernels > 2.3.37-ish */
|
|
+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
|
|
+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
|
|
+#endif
|
|
+
|
|
+/* kernels > 2.4.2 */
|
|
+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
|
|
+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
|
|
+#endif
|
|
+
|
|
+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
|
|
+
|
|
+
|
|
+
|
|
+#if defined(CONFIG_KLIPS_AH)
|
|
+static __u32 zeroes[64];
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int sysctl_ipsec_debug_verbose = 0;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+int ipsec_xmit_trap_count = 0;
|
|
+int ipsec_xmit_trap_sendcount = 0;
|
|
+
|
|
+int sysctl_ipsec_icmp = 0;
|
|
+int sysctl_ipsec_tos = 0;
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+#define dmp(_x,_y,_z) if(debug_tunnel) ipsec_dmp_block(_x,_y,_z)
|
|
+#else /* CONFIG_KLIPS_DEBUG */
|
|
+#define dmp(_x, _y, _z)
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+
|
|
+#if !defined(SKB_COPY_EXPAND) || defined(KLIPS_UNIT_TESTS)
|
|
+/*
|
|
+ * This is mostly skbuff.c:skb_copy().
|
|
+ */
|
|
+struct sk_buff *
|
|
+skb_copy_expand(const struct sk_buff *skb, int headroom,
|
|
+ int tailroom, int priority)
|
|
+{
|
|
+ struct sk_buff *n;
|
|
+ unsigned long offset;
|
|
+
|
|
+ /*
|
|
+ * Do sanity checking
|
|
+ */
|
|
+ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
|
|
+ printk(KERN_WARNING
|
|
+ "klips_error:skb_copy_expand: "
|
|
+ "Illegal negative head,tailroom %d,%d\n",
|
|
+ headroom,
|
|
+ tailroom);
|
|
+ return NULL;
|
|
+ }
|
|
+ /*
|
|
+ * Allocate the copy buffer
|
|
+ */
|
|
+
|
|
+#ifndef NET_21
|
|
+ IS_SKB(skb);
|
|
+#endif /* !NET_21 */
|
|
+
|
|
+
|
|
+ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:skb_copy_expand: "
|
|
+ "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
|
|
+ skb->end - skb->head + headroom + tailroom,
|
|
+ skb->head,
|
|
+ skb->data,
|
|
+ skb->tail,
|
|
+ skb->end,
|
|
+ skb->end - skb->head,
|
|
+ skb->tail - skb->data);
|
|
+
|
|
+ if(n==NULL)
|
|
+ return NULL;
|
|
+
|
|
+ /*
|
|
+ * Shift between the two data areas in bytes
|
|
+ */
|
|
+
|
|
+ /* Set the data pointer */
|
|
+ skb_reserve(n,skb->data-skb->head+headroom);
|
|
+ /* Set the tail pointer and length */
|
|
+ if(skb_tailroom(n) < skb->len) {
|
|
+ printk(KERN_WARNING "klips_error:skb_copy_expand: "
|
|
+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
|
|
+ (unsigned long int)skb->len,
|
|
+ skb_tailroom(n));
|
|
+ ipsec_kfree_skb(n);
|
|
+ return NULL;
|
|
+ }
|
|
+ skb_put(n,skb->len);
|
|
+
|
|
+ offset=n->head + headroom - skb->head;
|
|
+
|
|
+ /* Copy the bytes */
|
|
+ memcpy(n->head + headroom, skb->head,skb->end-skb->head);
|
|
+#ifdef NET_21
|
|
+ n->csum=skb->csum;
|
|
+ n->priority=skb->priority;
|
|
+ n->dst=dst_clone(skb->dst);
|
|
+ if(skb->nh.raw)
|
|
+ n->nh.raw=skb->nh.raw+offset;
|
|
+#ifndef NETDEV_23
|
|
+ n->is_clone=0;
|
|
+#endif /* NETDEV_23 */
|
|
+ atomic_set(&n->users, 1);
|
|
+ n->destructor = NULL;
|
|
+#ifdef HAVE_SOCK_SECURITY
|
|
+ n->security=skb->security;
|
|
+#endif
|
|
+#else /* NET_21 */
|
|
+ n->link3=NULL;
|
|
+ n->when=skb->when;
|
|
+ if(skb->ip_hdr)
|
|
+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
|
|
+ n->saddr=skb->saddr;
|
|
+ n->daddr=skb->daddr;
|
|
+ n->raddr=skb->raddr;
|
|
+ n->seq=skb->seq;
|
|
+ n->end_seq=skb->end_seq;
|
|
+ n->ack_seq=skb->ack_seq;
|
|
+ n->acked=skb->acked;
|
|
+ n->free=1;
|
|
+ n->arp=skb->arp;
|
|
+ n->tries=0;
|
|
+ n->lock=0;
|
|
+ n->users=0;
|
|
+#endif /* NET_21 */
|
|
+ n->protocol=skb->protocol;
|
|
+ n->list=NULL;
|
|
+ n->sk=NULL;
|
|
+ n->dev=skb->dev;
|
|
+ if(skb->h.raw)
|
|
+ n->h.raw=skb->h.raw+offset;
|
|
+ if(skb->mac.raw)
|
|
+ n->mac.raw=skb->mac.raw+offset;
|
|
+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
|
|
+#ifndef NETDEV_23
|
|
+ n->used=skb->used;
|
|
+#endif /* !NETDEV_23 */
|
|
+ n->pkt_type=skb->pkt_type;
|
|
+ n->stamp=skb->stamp;
|
|
+
|
|
+#ifndef NET_21
|
|
+ IS_SKB(n);
|
|
+#endif /* !NET_21 */
|
|
+ return n;
|
|
+}
|
|
+#endif /* !SKB_COPY_EXPAND */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+void
|
|
+ipsec_print_ip(struct iphdr *ip)
|
|
+{
|
|
+ char buf[ADDRTOA_BUF];
|
|
+
|
|
+ printk(KERN_INFO "klips_debug: IP:");
|
|
+ printk(" ihl:%d", ip->ihl << 2);
|
|
+ printk(" ver:%d", ip->version);
|
|
+ printk(" tos:%d", ip->tos);
|
|
+ printk(" tlen:%d", ntohs(ip->tot_len));
|
|
+ printk(" id:%d", ntohs(ip->id));
|
|
+ printk(" %s%s%sfrag_off:%d",
|
|
+ ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
|
|
+ ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
|
|
+ ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
|
|
+ (ntohs(ip->frag_off) & IP_OFFSET) << 3);
|
|
+ printk(" ttl:%d", ip->ttl);
|
|
+ printk(" proto:%d", ip->protocol);
|
|
+ if(ip->protocol == IPPROTO_UDP)
|
|
+ printk(" (UDP)");
|
|
+ if(ip->protocol == IPPROTO_TCP)
|
|
+ printk(" (TCP)");
|
|
+ if(ip->protocol == IPPROTO_ICMP)
|
|
+ printk(" (ICMP)");
|
|
+ if(ip->protocol == IPPROTO_ESP)
|
|
+ printk(" (ESP)");
|
|
+ if(ip->protocol == IPPROTO_AH)
|
|
+ printk(" (AH)");
|
|
+ if(ip->protocol == IPPROTO_COMP)
|
|
+ printk(" (COMP)");
|
|
+ printk(" chk:%d", ntohs(ip->check));
|
|
+ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
|
|
+ printk(" saddr:%s", buf);
|
|
+ if(ip->protocol == IPPROTO_UDP)
|
|
+ printk(":%d",
|
|
+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
|
|
+ if(ip->protocol == IPPROTO_TCP)
|
|
+ printk(":%d",
|
|
+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
|
|
+ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
|
|
+ printk(" daddr:%s", buf);
|
|
+ if(ip->protocol == IPPROTO_UDP)
|
|
+ printk(":%d",
|
|
+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
|
|
+ if(ip->protocol == IPPROTO_TCP)
|
|
+ printk(":%d",
|
|
+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
|
|
+ if(ip->protocol == IPPROTO_ICMP)
|
|
+ printk(" type:code=%d:%d",
|
|
+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
|
|
+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
|
|
+ printk("\n");
|
|
+
|
|
+ if(sysctl_ipsec_debug_verbose) {
|
|
+ __u8 *c;
|
|
+ int len = ntohs(ip->tot_len) - ip->ihl*4;
|
|
+
|
|
+ c = ((__u8*)ip) + ip->ihl*4;
|
|
+ ipsec_dmp_block("ip_print", c, len);
|
|
+ }
|
|
+}
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+#ifdef MSS_HACK
|
|
+/*
|
|
+ * Issues:
|
|
+ * 1) Fragments arriving in the tunnel should probably be rejected.
|
|
+ * 2) How does this affect syncookies, mss_cache, dst cache ?
|
|
+ * 3) Path MTU discovery handling needs to be reviewed. For example,
|
|
+ * if we receive an ICMP 'packet too big' message from an intermediate
|
|
+ * router specifying it's next hop MTU, our stack may process this and
|
|
+ * adjust the MSS without taking our AH/ESP overheads into account.
|
|
+ */
|
|
+
|
|
+
|
|
+/*
|
|
+ * Recaclulate checksum using differences between changed datum,
|
|
+ * borrowed from netfilter.
|
|
+ */
|
|
+DEBUG_NO_STATIC u_int16_t
|
|
+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
|
|
+{
|
|
+ u_int32_t diffs[] = { oldvalinv, newval };
|
|
+ return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
|
|
+ oldcheck^0xFFFF));
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Determine effective MSS.
|
|
+ *
|
|
+ * Note that we assume that there is always an MSS option for our own
|
|
+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
|
|
+ * This could change, and we should probably parse TCP options instead.
|
|
+ *
|
|
+ */
|
|
+DEBUG_NO_STATIC u_int8_t
|
|
+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
|
|
+{
|
|
+ u_int16_t oldmss, newmss;
|
|
+ u_int32_t *mssp;
|
|
+ struct sock *sk = skb->sk;
|
|
+
|
|
+ newmss = tcp_sync_mss(sk, mtu);
|
|
+ printk(KERN_INFO "klips: setting mss to %u\n", newmss);
|
|
+ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
|
|
+ oldmss = ntohl(*mssp) & 0x0000FFFF;
|
|
+ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
|
|
+ tcph->check = ipsec_fast_csum(htons(~oldmss),
|
|
+ htons(newmss), tcph->check);
|
|
+ return 1;
|
|
+}
|
|
+#endif /* MSS_HACK */
|
|
+
|
|
+/*
|
|
+ * Sanity checks
|
|
+ */
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+
|
|
+ if (ixs->dev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_error:ipsec_xmit_sanity_check_dev: "
|
|
+ "No device associated with skb!\n" );
|
|
+ return IPSEC_XMIT_NODEV;
|
|
+ }
|
|
+
|
|
+ ixs->prv = ixs->dev->priv;
|
|
+ if (ixs->prv == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_error:ipsec_xmit_sanity_check_dev: "
|
|
+ "Device has no private structure!\n" );
|
|
+ return IPSEC_XMIT_NOPRIVDEV;
|
|
+ }
|
|
+
|
|
+ ixs->physdev = ixs->prv->dev;
|
|
+ if (ixs->physdev == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_error:ipsec_xmit_sanity_check_dev: "
|
|
+ "Device is not attached to physical device!\n" );
|
|
+ return IPSEC_XMIT_NOPHYSDEV;
|
|
+ }
|
|
+
|
|
+ ixs->physmtu = ixs->physdev->mtu;
|
|
+ ixs->cur_mtu = ixs->physdev->mtu;
|
|
+ ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+ /*
|
|
+ * Return if there is nothing to do. (Does this ever happen?) XXX
|
|
+ */
|
|
+ if (ixs->skb == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_error:ipsec_xmit_sanity_check_skb: "
|
|
+ "Nothing to do!\n" );
|
|
+ return IPSEC_XMIT_NOSKB;
|
|
+ }
|
|
+
|
|
+ /* if skb was cloned (most likely due to a packet sniffer such as
|
|
+ tcpdump being momentarily attached to the interface), make
|
|
+ a copy of our own to modify */
|
|
+ if(skb_cloned(ixs->skb)) {
|
|
+ if
|
|
+#ifdef SKB_COW_NEW
|
|
+ (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0)
|
|
+#else /* SKB_COW_NEW */
|
|
+ ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL)
|
|
+#endif /* SKB_COW_NEW */
|
|
+ {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_error:ipsec_xmit_sanity_check_skb: "
|
|
+ "skb_cow failed to allocate buffer, dropping.\n" );
|
|
+ ixs->stats->tx_dropped++;
|
|
+ return IPSEC_XMIT_ERRSKBALLOC;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ixs->iph = ixs->skb->nh.iph;
|
|
+
|
|
+ /* sanity check for IP version as we can't handle IPv6 right now */
|
|
+ if (ixs->iph->version != 4) {
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_xmit_sanity_check_skb: "
|
|
+ "found IP Version %d but cannot process other IP versions than v4.\n",
|
|
+ ixs->iph->version); /* XXX */
|
|
+ ixs->stats->tx_dropped++;
|
|
+ return IPSEC_XMIT_NOIPV6;
|
|
+ }
|
|
+
|
|
+#if IPSEC_DISALLOW_IPOPTIONS
|
|
+ if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) {
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_xmit_sanity_check_skb: "
|
|
+ "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */
|
|
+ ixs->stats->tx_dropped++;
|
|
+ return IPSEC_XMIT_NOIPOPTIONS;
|
|
+ }
|
|
+#endif /* IPSEC_DISALLOW_IPOPTIONS */
|
|
+
|
|
+#ifndef NET_21
|
|
+ if (ixs->iph->ttl <= 0) {
|
|
+ /* Tell the sender its packet died... */
|
|
+ ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev);
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: "
|
|
+ "TTL=0, too many hops!\n");
|
|
+ ixs->stats->tx_dropped++;
|
|
+ return IPSEC_XMIT_TTLEXPIRED;
|
|
+ }
|
|
+#endif /* !NET_21 */
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+ struct esphdr *espp;
|
|
+ unsigned char *idat, *pad;
|
|
+ int authlen = 0, padlen = 0, i;
|
|
+#endif /* !CONFIG_KLIPS_ESP */
|
|
+#ifdef CONFIG_KLIPS_AH
|
|
+ struct iphdr ipo;
|
|
+ struct ahhdr *ahp;
|
|
+#endif /* CONFIG_KLIPS_AH */
|
|
+#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
|
|
+ union {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ MD5_CTX md5;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ SHA1_CTX sha1;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ } tctx;
|
|
+ __u8 hash[AH_AMAX];
|
|
+#endif /* defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMACn_SHA1) */
|
|
+ int headroom = 0, tailroom = 0, ilen = 0, len = 0;
|
|
+ unsigned char *dat;
|
|
+ int blocksize = 8; /* XXX: should be inside ixs --jjo */
|
|
+ struct ipsec_alg_enc *ixt_e = NULL;
|
|
+ struct ipsec_alg_auth *ixt_a = NULL;
|
|
+
|
|
+ ixs->iphlen = ixs->iph->ihl << 2;
|
|
+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
|
|
+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
|
|
+ "klips_debug:ipsec_xmit_encap_once: "
|
|
+ "calling output for <%s%s%s>, SA:%s\n",
|
|
+ IPS_XFORM_NAME(ixs->ipsp),
|
|
+ ixs->sa_len ? ixs->sa_txt : " (error)");
|
|
+
|
|
+ switch(ixs->ipsp->ips_said.proto) {
|
|
+#ifdef CONFIG_KLIPS_AH
|
|
+ case IPPROTO_AH:
|
|
+ headroom += sizeof(struct ahhdr);
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AH */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+ case IPPROTO_ESP:
|
|
+ ixt_e=ixs->ipsp->ips_alg_enc;
|
|
+ if (ixt_e) {
|
|
+ blocksize = ixt_e->ixt_common.ixt_blocksize;
|
|
+ headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
|
|
+ } else {
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_ESP_BADALG;
|
|
+ }
|
|
+
|
|
+ ixt_a=ixs->ipsp->ips_alg_auth;
|
|
+ if (ixt_a) {
|
|
+ tailroom += AHHMAC_HASHLEN;
|
|
+ authlen = AHHMAC_HASHLEN;
|
|
+ } else
|
|
+ switch(ixs->ipsp->ips_authalg) {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ case AH_MD5:
|
|
+ authlen = AHHMAC_HASHLEN;
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ case AH_SHA:
|
|
+ authlen = AHHMAC_HASHLEN;
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ case AH_NONE:
|
|
+ break;
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_ESP_BADALG;
|
|
+ }
|
|
+ tailroom += blocksize != 1 ?
|
|
+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
|
|
+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
|
|
+ tailroom += authlen;
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_ESP */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPIP
|
|
+ case IPPROTO_IPIP:
|
|
+ headroom += sizeof(struct iphdr);
|
|
+ ixs->iphlen = sizeof(struct iphdr);
|
|
+ break;
|
|
+#endif /* !CONFIG_KLIPS_IPIP */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ case IPPROTO_COMP:
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_BADPROTO;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_once: "
|
|
+ "pushing %d bytes, putting %d, proto %d.\n",
|
|
+ headroom, tailroom, ixs->ipsp->ips_said.proto);
|
|
+ if(skb_headroom(ixs->skb) < headroom) {
|
|
+ printk(KERN_WARNING
|
|
+ "klips_error:ipsec_xmit_encap_once: "
|
|
+ "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n",
|
|
+ headroom, skb_headroom(ixs->skb));
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_ESP_PUSHPULLERR;
|
|
+ }
|
|
+
|
|
+ dat = skb_push(ixs->skb, headroom);
|
|
+ ilen = ixs->skb->len - tailroom;
|
|
+ if(skb_tailroom(ixs->skb) < tailroom) {
|
|
+ printk(KERN_WARNING
|
|
+ "klips_error:ipsec_xmit_encap_once: "
|
|
+ "tried to skb_put %d, %d available. This should never happen, please report.\n",
|
|
+ tailroom, skb_tailroom(ixs->skb));
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_ESP_PUSHPULLERR;
|
|
+ }
|
|
+ skb_put(ixs->skb, tailroom);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_once: "
|
|
+ "head,tailroom: %d,%d before xform.\n",
|
|
+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
|
|
+ len = ixs->skb->len;
|
|
+ if(len > 0xfff0) {
|
|
+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: "
|
|
+ "tot_len (%d) > 65520. This should never happen, please report.\n",
|
|
+ len);
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_BADLEN;
|
|
+ }
|
|
+ memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen);
|
|
+ ixs->iph = (struct iphdr *)dat;
|
|
+ ixs->iph->tot_len = htons(ixs->skb->len);
|
|
+
|
|
+ switch(ixs->ipsp->ips_said.proto) {
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+ case IPPROTO_ESP:
|
|
+ espp = (struct esphdr *)(dat + ixs->iphlen);
|
|
+ espp->esp_spi = ixs->ipsp->ips_said.spi;
|
|
+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
|
|
+
|
|
+ if (!ixt_e) {
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_ESP_BADALG;
|
|
+ }
|
|
+
|
|
+ idat = dat + ixs->iphlen + headroom;
|
|
+ ilen = len - (ixs->iphlen + headroom + authlen);
|
|
+
|
|
+ /* Self-describing padding */
|
|
+ pad = &dat[len - tailroom];
|
|
+ padlen = tailroom - 2 - authlen;
|
|
+ for (i = 0; i < padlen; i++) {
|
|
+ pad[i] = i + 1;
|
|
+ }
|
|
+ dat[len - authlen - 2] = padlen;
|
|
+
|
|
+ dat[len - authlen - 1] = ixs->iph->protocol;
|
|
+ ixs->iph->protocol = IPPROTO_ESP;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_tunnel & DB_TN_ENCAP) {
|
|
+ dmp("pre-encrypt", dat, len);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ /*
|
|
+ * Do all operations here:
|
|
+ * copy IV->ESP, encrypt, update ips IV
|
|
+ *
|
|
+ */
|
|
+ {
|
|
+ int ret;
|
|
+ memcpy(espp->esp_iv,
|
|
+ ixs->ipsp->ips_iv,
|
|
+ ixs->ipsp->ips_iv_size);
|
|
+ ret=ipsec_alg_esp_encrypt(ixs->ipsp,
|
|
+ idat, ilen, espp->esp_iv,
|
|
+ IPSEC_ALG_ENCRYPT);
|
|
+
|
|
+ prng_bytes(&ipsec_prng,
|
|
+ (char *)ixs->ipsp->ips_iv,
|
|
+ ixs->ipsp->ips_iv_size);
|
|
+ }
|
|
+
|
|
+ if (ixt_a) {
|
|
+ ipsec_alg_sa_esp_hash(ixs->ipsp,
|
|
+ (caddr_t)espp, len - ixs->iphlen - authlen,
|
|
+ &(dat[len - authlen]), authlen);
|
|
+
|
|
+ } else
|
|
+ switch(ixs->ipsp->ips_authalg) {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ case AH_MD5:
|
|
+ dmp("espp", (char*)espp, len - ixs->iphlen - authlen);
|
|
+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
|
|
+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen);
|
|
+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Final(hash, &tctx.md5);
|
|
+ dmp("ictx hash", (char*)&hash, sizeof(hash));
|
|
+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
|
|
+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
|
|
+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Final(hash, &tctx.md5);
|
|
+ dmp("octx hash", (char*)&hash, sizeof(hash));
|
|
+ memcpy(&(dat[len - authlen]), hash, authlen);
|
|
+
|
|
+ /* paranoid */
|
|
+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
|
|
+ memset((caddr_t)hash, 0, sizeof(*hash));
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ case AH_SHA:
|
|
+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
|
|
+ SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen);
|
|
+ SHA1Final(hash, &tctx.sha1);
|
|
+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
|
|
+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
|
|
+ SHA1Final(hash, &tctx.sha1);
|
|
+ memcpy(&(dat[len - authlen]), hash, authlen);
|
|
+
|
|
+ /* paranoid */
|
|
+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
|
|
+ memset((caddr_t)hash, 0, sizeof(*hash));
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ case AH_NONE:
|
|
+ break;
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_AH_BADALG;
|
|
+ }
|
|
+#ifdef NET_21
|
|
+ ixs->skb->h.raw = (unsigned char*)espp;
|
|
+#endif /* NET_21 */
|
|
+ break;
|
|
+#endif /* !CONFIG_KLIPS_ESP */
|
|
+#ifdef CONFIG_KLIPS_AH
|
|
+ case IPPROTO_AH:
|
|
+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
|
|
+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
|
|
+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
|
|
+ ahp->ah_rv = 0;
|
|
+ ahp->ah_nh = ixs->iph->protocol;
|
|
+ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
|
|
+ ixs->iph->protocol = IPPROTO_AH;
|
|
+ dmp("ahp", (char*)ahp, sizeof(*ahp));
|
|
+
|
|
+ ipo = *ixs->iph;
|
|
+ ipo.tos = 0;
|
|
+ ipo.frag_off = 0;
|
|
+ ipo.ttl = 0;
|
|
+ ipo.check = 0;
|
|
+ dmp("ipo", (char*)&ipo, sizeof(ipo));
|
|
+
|
|
+ switch(ixs->ipsp->ips_authalg) {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ case AH_MD5:
|
|
+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
|
|
+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
|
|
+ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
|
|
+ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
|
|
+ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
|
|
+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Final(hash, &tctx.md5);
|
|
+ dmp("ictx hash", (char*)&hash, sizeof(hash));
|
|
+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
|
|
+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
|
|
+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
|
|
+ osMD5Final(hash, &tctx.md5);
|
|
+ dmp("octx hash", (char*)&hash, sizeof(hash));
|
|
+
|
|
+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
|
|
+
|
|
+ /* paranoid */
|
|
+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
|
|
+ memset((caddr_t)hash, 0, sizeof(*hash));
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ case AH_SHA:
|
|
+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
|
|
+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
|
|
+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
|
|
+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
|
|
+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
|
|
+ SHA1Final(hash, &tctx.sha1);
|
|
+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
|
|
+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
|
|
+ SHA1Final(hash, &tctx.sha1);
|
|
+
|
|
+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
|
|
+
|
|
+ /* paranoid */
|
|
+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
|
|
+ memset((caddr_t)hash, 0, sizeof(*hash));
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_AH_BADALG;
|
|
+ }
|
|
+#ifdef NET_21
|
|
+ ixs->skb->h.raw = (unsigned char*)ahp;
|
|
+#endif /* NET_21 */
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AH */
|
|
+#ifdef CONFIG_KLIPS_IPIP
|
|
+ case IPPROTO_IPIP:
|
|
+ ixs->iph->version = 4;
|
|
+ switch(sysctl_ipsec_tos) {
|
|
+ case 0:
|
|
+#ifdef NET_21
|
|
+ ixs->iph->tos = ixs->skb->nh.iph->tos;
|
|
+#else /* NET_21 */
|
|
+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
|
|
+#endif /* NET_21 */
|
|
+ break;
|
|
+ case 1:
|
|
+ ixs->iph->tos = 0;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
|
|
+ ixs->iph->frag_off = 0;
|
|
+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
|
|
+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
|
|
+ ixs->iph->protocol = IPPROTO_IPIP;
|
|
+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
|
|
+
|
|
+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
|
|
+
|
|
+ ixs->newdst = (__u32)ixs->iph->daddr;
|
|
+ ixs->newsrc = (__u32)ixs->iph->saddr;
|
|
+
|
|
+#ifdef NET_21
|
|
+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
|
|
+#endif /* NET_21 */
|
|
+ break;
|
|
+#endif /* !CONFIG_KLIPS_IPIP */
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ case IPPROTO_COMP:
|
|
+ {
|
|
+ unsigned int flags = 0;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
|
|
+
|
|
+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
|
|
+
|
|
+#ifdef NET_21
|
|
+ ixs->iph = ixs->skb->nh.iph;
|
|
+#else /* NET_21 */
|
|
+ ixs->iph = ixs->skb->ip_hdr;
|
|
+#endif /* NET_21 */
|
|
+
|
|
+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if (debug_tunnel & DB_TN_CROUT)
|
|
+ {
|
|
+ if (old_tot_len > ntohs(ixs->iph->tot_len))
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_once: "
|
|
+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
|
|
+ old_tot_len, ntohs(ixs->iph->tot_len),
|
|
+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
|
|
+ ntohl(ixs->ipsp->ips_said.spi),
|
|
+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
|
|
+ else
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_once: "
|
|
+ "packet did not compress (flags = %d).\n",
|
|
+ flags);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ }
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ return IPSEC_XMIT_BADPROTO;
|
|
+ }
|
|
+
|
|
+#ifdef NET_21
|
|
+ ixs->skb->nh.raw = ixs->skb->data;
|
|
+#else /* NET_21 */
|
|
+ ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data;
|
|
+#endif /* NET_21 */
|
|
+ ixs->iph->check = 0;
|
|
+ ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl);
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_once: "
|
|
+ "after <%s%s%s>, SA:%s:\n",
|
|
+ IPS_XFORM_NAME(ixs->ipsp),
|
|
+ ixs->sa_len ? ixs->sa_txt : " (error)");
|
|
+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
|
|
+
|
|
+ ixs->ipsp->ips_life.ipl_bytes.ipl_count += len;
|
|
+ ixs->ipsp->ips_life.ipl_bytes.ipl_last = len;
|
|
+
|
|
+ if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) {
|
|
+ ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
|
|
+ }
|
|
+ ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
|
|
+ ixs->ipsp->ips_life.ipl_packets.ipl_count++;
|
|
+
|
|
+ ixs->ipsp = ixs->ipsp->ips_onext;
|
|
+
|
|
+ return IPSEC_XMIT_OK;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
|
|
+ * source and destination ports to those from the TCP/UDP header.
|
|
+ */
|
|
+void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
|
|
+{
|
|
+ struct udphdr *udp;
|
|
+
|
|
+ switch (iph->protocol) {
|
|
+ case IPPROTO_UDP:
|
|
+ case IPPROTO_TCP:
|
|
+ /*
|
|
+ * The ports are at the same offsets in a TCP and UDP
|
|
+ * header so hack it ...
|
|
+ */
|
|
+ udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
|
|
+ er->sen_sport = udp->source;
|
|
+ er->sen_dport = udp->dest;
|
|
+ break;
|
|
+ default:
|
|
+ er->sen_sport = 0;
|
|
+ er->sen_dport = 0;
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * A TRAP eroute is installed and we want to replace it with a HOLD
|
|
+ * eroute.
|
|
+ */
|
|
+static int create_hold_eroute(struct eroute *origtrap,
|
|
+ struct sk_buff * skb, struct iphdr * iph,
|
|
+ uint32_t eroute_pid)
|
|
+{
|
|
+ struct eroute hold_eroute;
|
|
+ ip_said hold_said;
|
|
+ struct sk_buff *first, *last;
|
|
+ int error;
|
|
+
|
|
+ first = last = NULL;
|
|
+ memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
|
|
+ memset((caddr_t)&hold_said, 0, sizeof(hold_said));
|
|
+
|
|
+ hold_said.proto = IPPROTO_INT;
|
|
+ hold_said.spi = htonl(SPI_HOLD);
|
|
+ hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
|
|
+
|
|
+ hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
|
|
+ hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
|
|
+ hold_eroute.er_eaddr.sen_family = AF_ENCAP;
|
|
+ hold_eroute.er_emask.sen_family = AF_ENCAP;
|
|
+ hold_eroute.er_eaddr.sen_type = SENT_IP4;
|
|
+ hold_eroute.er_emask.sen_type = 255;
|
|
+
|
|
+ hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
|
|
+ hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
|
|
+ hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
|
|
+ hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
|
|
+ hold_eroute.er_emask.sen_sport = 0;
|
|
+ hold_eroute.er_emask.sen_dport = 0;
|
|
+ hold_eroute.er_pid = eroute_pid;
|
|
+ hold_eroute.er_count = 0;
|
|
+ hold_eroute.er_lasttime = jiffies/HZ;
|
|
+
|
|
+ /*
|
|
+ * if it wasn't captured by a wildcard, then don't record it as
|
|
+ * a wildcard.
|
|
+ */
|
|
+ if(origtrap->er_eaddr.sen_proto != 0) {
|
|
+ hold_eroute.er_eaddr.sen_proto = iph->protocol;
|
|
+
|
|
+ if((iph->protocol == IPPROTO_TCP ||
|
|
+ iph->protocol == IPPROTO_UDP) &&
|
|
+ (origtrap->er_eaddr.sen_sport != 0 ||
|
|
+ origtrap->er_eaddr.sen_dport != 0)) {
|
|
+
|
|
+ if(origtrap->er_eaddr.sen_sport != 0)
|
|
+ hold_eroute.er_emask.sen_sport = ~0;
|
|
+
|
|
+ if(origtrap->er_eaddr.sen_dport != 0)
|
|
+ hold_eroute.er_emask.sen_dport = ~0;
|
|
+
|
|
+ ipsec_extract_ports(iph, &hold_eroute.er_eaddr);
|
|
+ }
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if (debug_pfkey) {
|
|
+ char buf1[64], buf2[64];
|
|
+ subnettoa(hold_eroute.er_eaddr.sen_ip_src,
|
|
+ hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
|
|
+ hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
|
|
+ buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
|
|
+ buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
|
|
+ hold_eroute.er_eaddr.sen_proto);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
|
|
+ &first, &last)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "HOLD breakeroute found nothing.\n");
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
|
|
+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
|
|
+ ntohs(hold_eroute.er_eaddr.sen_sport),
|
|
+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
|
|
+ ntohs(hold_eroute.er_eaddr.sen_dport),
|
|
+ hold_eroute.er_eaddr.sen_proto);
|
|
+ }
|
|
+ if (first != NULL)
|
|
+ kfree_skb(first);
|
|
+ if (last != NULL)
|
|
+ kfree_skb(last);
|
|
+
|
|
+ error = ipsec_makeroute(&(hold_eroute.er_eaddr),
|
|
+ &(hold_eroute.er_emask),
|
|
+ hold_said, eroute_pid, skb, NULL, NULL);
|
|
+ if (error) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "HOLD makeroute returned %d, failed.\n", error);
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "HOLD makeroute call successful.\n");
|
|
+ }
|
|
+ return (error == 0);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * upon entry to this function, ixs->skb should be setup
|
|
+ * as follows:
|
|
+ *
|
|
+ * data = beginning of IP packet <- differs from ipsec_rcv().
|
|
+ * nh.raw = beginning of IP packet.
|
|
+ * h.raw = data after the IP packet.
|
|
+ *
|
|
+ */
|
|
+enum ipsec_xmit_value
|
|
+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs)
|
|
+{
|
|
+ struct ipsec_alg_enc *ixt_e = NULL;
|
|
+ struct ipsec_alg_auth *ixt_a = NULL;
|
|
+ int blocksize = 8;
|
|
+ enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK;
|
|
+
|
|
+ ixs->newdst = ixs->orgdst = ixs->iph->daddr;
|
|
+ ixs->newsrc = ixs->orgsrc = ixs->iph->saddr;
|
|
+ ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr;
|
|
+ ixs->iphlen = ixs->iph->ihl << 2;
|
|
+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
|
|
+ ixs->max_headroom = ixs->max_tailroom = 0;
|
|
+
|
|
+ if (ixs->outgoing_said.proto == IPPROTO_INT) {
|
|
+ switch (ntohl(ixs->outgoing_said.spi)) {
|
|
+ case SPI_DROP:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "shunt SA of DROP or no eroute: dropping.\n");
|
|
+ ixs->stats->tx_dropped++;
|
|
+ break;
|
|
+
|
|
+ case SPI_REJECT:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "shunt SA of REJECT: notifying and dropping.\n");
|
|
+ ICMP_SEND(ixs->skb,
|
|
+ ICMP_DEST_UNREACH,
|
|
+ ICMP_PKT_FILTERED,
|
|
+ 0,
|
|
+ ixs->physdev);
|
|
+ ixs->stats->tx_dropped++;
|
|
+ break;
|
|
+
|
|
+ case SPI_PASS:
|
|
+#ifdef NET_21
|
|
+ ixs->pass = 1;
|
|
+#endif /* NET_21 */
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "PASS: calling dev_queue_xmit\n");
|
|
+ return IPSEC_XMIT_PASS;
|
|
+ goto cleanup;
|
|
+
|
|
+ case SPI_HOLD:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "shunt SA of HOLD: this does not make sense here, dropping.\n");
|
|
+ ixs->stats->tx_dropped++;
|
|
+ break;
|
|
+
|
|
+ case SPI_TRAP:
|
|
+ case SPI_TRAPSUBNET:
|
|
+ {
|
|
+ struct sockaddr_in src, dst;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ /* Signal all listening KMds with a PF_KEY ACQUIRE */
|
|
+
|
|
+ memset(&src, 0, sizeof(src));
|
|
+ memset(&dst, 0, sizeof(dst));
|
|
+ src.sin_family = AF_INET;
|
|
+ dst.sin_family = AF_INET;
|
|
+ src.sin_addr.s_addr = ixs->iph->saddr;
|
|
+ dst.sin_addr.s_addr = ixs->iph->daddr;
|
|
+
|
|
+ ixs->ips.ips_transport_protocol = 0;
|
|
+ src.sin_port = 0;
|
|
+ dst.sin_port = 0;
|
|
+
|
|
+ if(ixs->eroute->er_eaddr.sen_proto != 0) {
|
|
+ ixs->ips.ips_transport_protocol = ixs->iph->protocol;
|
|
+
|
|
+ if(ixs->eroute->er_eaddr.sen_sport != 0) {
|
|
+ src.sin_port =
|
|
+ (ixs->iph->protocol == IPPROTO_UDP
|
|
+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source
|
|
+ : (ixs->iph->protocol == IPPROTO_TCP
|
|
+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source
|
|
+ : 0));
|
|
+ }
|
|
+ if(ixs->eroute->er_eaddr.sen_dport != 0) {
|
|
+ dst.sin_port =
|
|
+ (ixs->iph->protocol == IPPROTO_UDP
|
|
+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest
|
|
+ : (ixs->iph->protocol == IPPROTO_TCP
|
|
+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest
|
|
+ : 0));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ixs->ips.ips_addr_s = (struct sockaddr*)(&src);
|
|
+ ixs->ips.ips_addr_d = (struct sockaddr*)(&dst);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
|
|
+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
|
|
+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port),
|
|
+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
|
|
+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port),
|
|
+ ixs->ips.ips_said.proto);
|
|
+
|
|
+ /* increment count of total traps needed */
|
|
+ ipsec_xmit_trap_count++;
|
|
+
|
|
+ if (pfkey_acquire(&ixs->ips) == 0) {
|
|
+
|
|
+ /* note that we succeeded */
|
|
+ ipsec_xmit_trap_sendcount++;
|
|
+
|
|
+ if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
|
|
+ /*
|
|
+ * The spinlock is to prevent any other
|
|
+ * process from accessing or deleting
|
|
+ * the eroute while we are using and
|
|
+ * updating it.
|
|
+ */
|
|
+ spin_lock(&eroute_lock);
|
|
+ ixs->eroute = ipsec_findroute(&ixs->matcher);
|
|
+ if(ixs->eroute) {
|
|
+ ixs->eroute->er_said.spi = htonl(SPI_HOLD);
|
|
+ ixs->eroute->er_first = ixs->skb;
|
|
+ ixs->skb = NULL;
|
|
+ }
|
|
+ spin_unlock(&eroute_lock);
|
|
+ } else if (create_hold_eroute(ixs->eroute,
|
|
+ ixs->skb,
|
|
+ ixs->iph,
|
|
+ ixs->eroute_pid)) {
|
|
+ ixs->skb = NULL;
|
|
+ }
|
|
+ /* whether or not the above succeeded, we continue */
|
|
+
|
|
+ }
|
|
+ ixs->stats->tx_dropped++;
|
|
+ }
|
|
+ default:
|
|
+ /* XXX what do we do with an unknown shunt spi? */
|
|
+ break;
|
|
+ } /* switch (ntohl(ixs->outgoing_said.spi)) */
|
|
+ return IPSEC_XMIT_STOLEN;
|
|
+ } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */
|
|
+
|
|
+ /*
|
|
+ The spinlock is to prevent any other process from
|
|
+ accessing or deleting the ipsec_sa hash table or any of the
|
|
+ ipsec_sa s while we are using and updating them.
|
|
+
|
|
+ This is not optimal, but was relatively straightforward
|
|
+ at the time. A better way to do it has been planned for
|
|
+ more than a year, to lock the hash table and put reference
|
|
+ counts on each ipsec_sa instead. This is not likely to happen
|
|
+ in KLIPS1 unless a volunteer contributes it, but will be
|
|
+ designed into KLIPS2.
|
|
+ */
|
|
+ spin_lock(&tdb_lock);
|
|
+
|
|
+ ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said);
|
|
+ ixs->sa_len = satot(&ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
|
|
+
|
|
+ if (ixs->ipsp == NULL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
|
|
+ ixs->sa_len ? ixs->sa_txt : " (error)");
|
|
+ if(ixs->stats) {
|
|
+ ixs->stats->tx_dropped++;
|
|
+ }
|
|
+ bundle_stat = IPSEC_XMIT_SAIDNOTFOUND;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "found ipsec_sa -- SA:<%s%s%s> %s\n",
|
|
+ IPS_XFORM_NAME(ixs->ipsp),
|
|
+ ixs->sa_len ? ixs->sa_txt : " (error)");
|
|
+
|
|
+ /*
|
|
+ * How much headroom do we need to be able to apply
|
|
+ * all the grouped transforms?
|
|
+ */
|
|
+ ixs->ipsq = ixs->ipsp; /* save the head of the ipsec_sa chain */
|
|
+ while (ixs->ipsp) {
|
|
+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
|
|
+ if(ixs->sa_len == 0) {
|
|
+ strcpy(ixs->sa_txt, "(error)");
|
|
+ }
|
|
+
|
|
+ /* If it is in larval state, drop the packet, we cannot process yet. */
|
|
+ if(ixs->ipsp->ips_state == SADB_SASTATE_LARVAL) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
|
|
+ IPS_XFORM_NAME(ixs->ipsp),
|
|
+ ixs->sa_len ? ixs->sa_txt : " (error)");
|
|
+ if(ixs->stats) {
|
|
+ ixs->stats->tx_errors++;
|
|
+ }
|
|
+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ if(ixs->ipsp->ips_state == SADB_SASTATE_DEAD) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
|
|
+ IPS_XFORM_NAME(ixs->ipsp),
|
|
+ ixs->sa_len ? ixs->sa_txt : " (error)");
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ /* If the replay window counter == -1, expire SA, it will roll */
|
|
+ if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) {
|
|
+ pfkey_expire(ixs->ipsp, 1);
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
|
|
+ IPS_XFORM_NAME(ixs->ipsp),
|
|
+ ixs->sa_len ? ixs->sa_txt : " (error)");
|
|
+ ipsec_sa_delchain(ixs->ipsp);
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_REPLAYROLLED;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * if this is the first time we are using this SA, mark start time,
|
|
+ * and offset hard/soft counters by "now" for later checking.
|
|
+ */
|
|
+#if 0
|
|
+ if(ixs->ipsp->ips_life.ipl_usetime.count == 0) {
|
|
+ ixs->ipsp->ips_life.ipl_usetime.count = jiffies;
|
|
+ ixs->ipsp->ips_life.ipl_usetime.hard += jiffies;
|
|
+ ixs->ipsp->ips_life.ipl_usetime.soft += jiffies;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+
|
|
+ if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt,
|
|
+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
|
|
+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt,
|
|
+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
|
|
+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt,
|
|
+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
|
|
+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt,
|
|
+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) {
|
|
+
|
|
+ ipsec_sa_delchain(ixs->ipsp);
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_LIFETIMEFAILED;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+
|
|
+ ixs->headroom = ixs->tailroom = 0;
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "calling room for <%s%s%s>, SA:%s\n",
|
|
+ IPS_XFORM_NAME(ixs->ipsp),
|
|
+ ixs->sa_len ? ixs->sa_txt : " (error)");
|
|
+ switch(ixs->ipsp->ips_said.proto) {
|
|
+#ifdef CONFIG_KLIPS_AH
|
|
+ case IPPROTO_AH:
|
|
+ ixs->headroom += sizeof(struct ahhdr);
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AH */
|
|
+#ifdef CONFIG_KLIPS_ESP
|
|
+ case IPPROTO_ESP:
|
|
+ ixt_e=ixs->ipsp->ips_alg_enc;
|
|
+ if (ixt_e) {
|
|
+ blocksize = ixt_e->ixt_common.ixt_blocksize;
|
|
+ ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
|
|
+ }
|
|
+ else {
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_ESP_BADALG;
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
|
|
+ ixs->tailroom += AHHMAC_HASHLEN;
|
|
+ } else
|
|
+ switch(ixs->ipsp->ips_authalg) {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ case AH_MD5:
|
|
+ ixs->tailroom += AHHMAC_HASHLEN;
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ case AH_SHA:
|
|
+ ixs->tailroom += AHHMAC_HASHLEN;
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ case AH_NONE:
|
|
+ break;
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_AH_BADALG;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ ixs->tailroom += blocksize != 1 ?
|
|
+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
|
|
+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) {
|
|
+ ixs->natt_type = ixs->ipsp->ips_natt_type;
|
|
+ ixs->natt_sport = ixs->ipsp->ips_natt_sport;
|
|
+ ixs->natt_dport = ixs->ipsp->ips_natt_dport;
|
|
+ switch (ixs->natt_type) {
|
|
+ case ESPINUDP_WITH_NON_IKE:
|
|
+ ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32));
|
|
+ break;
|
|
+
|
|
+ case ESPINUDP_WITH_NON_ESP:
|
|
+ ixs->natt_head = sizeof(struct udphdr);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT
|
|
+ , "klips_xmit: invalid nat-t type %d"
|
|
+ , ixs->natt_type);
|
|
+ bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;
|
|
+ goto cleanup;
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ ixs->tailroom += ixs->natt_head;
|
|
+ }
|
|
+#endif
|
|
+ break;
|
|
+#endif /* !CONFIG_KLIPS_ESP */
|
|
+#ifdef CONFIG_KLIPS_IPIP
|
|
+ case IPPROTO_IPIP:
|
|
+ ixs->headroom += sizeof(struct iphdr);
|
|
+ break;
|
|
+#endif /* !CONFIG_KLIPS_IPIP */
|
|
+ case IPPROTO_COMP:
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ /*
|
|
+ We can't predict how much the packet will
|
|
+ shrink without doing the actual compression.
|
|
+ We could do it here, if we were the first
|
|
+ encapsulation in the chain. That might save
|
|
+ us a skb_copy_expand, since we might fit
|
|
+ into the existing skb then. However, this
|
|
+ would be a bit unclean (and this hack has
|
|
+ bit us once), so we better not do it. After
|
|
+ all, the skb_copy_expand is cheap in
|
|
+ comparison to the actual compression.
|
|
+ At least we know the packet will not grow.
|
|
+ */
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ default:
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_BADPROTO;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ ixs->ipsp = ixs->ipsp->ips_onext;
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "Required head,tailroom: %d,%d\n",
|
|
+ ixs->headroom, ixs->tailroom);
|
|
+ ixs->max_headroom += ixs->headroom;
|
|
+ ixs->max_tailroom += ixs->tailroom;
|
|
+ ixs->pyldsz += (ixs->headroom + ixs->tailroom);
|
|
+ }
|
|
+ ixs->ipsp = ixs->ipsq; /* restore the head of the ipsec_sa chain */
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
|
|
+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb),
|
|
+ ixs->max_headroom, ixs->max_tailroom);
|
|
+
|
|
+ ixs->tot_headroom += ixs->max_headroom;
|
|
+ ixs->tot_tailroom += ixs->max_tailroom;
|
|
+
|
|
+ ixs->mtudiff = ixs->cur_mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
|
|
+ ixs->cur_mtu, ixs->physmtu,
|
|
+ ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));
|
|
+ if(ixs->mtudiff > 0) {
|
|
+ int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);
|
|
+
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_info:ipsec_xmit_encap_bundle: "
|
|
+ "dev %s mtu of %d decreased by %d to %d\n",
|
|
+ ixs->dev ? ixs->dev->name : "ifX",
|
|
+ ixs->cur_mtu,
|
|
+ ixs->cur_mtu - newmtu,
|
|
+ newmtu);
|
|
+ ixs->cur_mtu = newmtu;
|
|
+
|
|
+ /* this would seem to adjust the MTU of the route as well */
|
|
+#if 0
|
|
+ ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */
|
|
+#endif /* 0 */
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ If the sender is doing PMTU discovery, and the
|
|
+ packet doesn't fit within ixs->prv->mtu, notify him
|
|
+ (unless it was an ICMP packet, or it was not the
|
|
+ zero-offset packet) and send it anyways.
|
|
+
|
|
+ Note: buggy firewall configuration may prevent the
|
|
+ ICMP packet from getting back.
|
|
+ */
|
|
+ if(sysctl_ipsec_icmp
|
|
+ && ixs->cur_mtu < ntohs(ixs->iph->tot_len)
|
|
+ && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {
|
|
+ int notify = ixs->iph->protocol != IPPROTO_ICMP
|
|
+ && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
|
|
+
|
|
+#ifdef IPSEC_obey_DF
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "fragmentation needed and DF set; %sdropping packet\n",
|
|
+ notify ? "sending ICMP and " : "");
|
|
+ if (notify)
|
|
+ ICMP_SEND(ixs->skb,
|
|
+ ICMP_DEST_UNREACH,
|
|
+ ICMP_FRAG_NEEDED,
|
|
+ ixs->cur_mtu,
|
|
+ ixs->physdev);
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_CANNOTFRAG;
|
|
+ goto cleanup;
|
|
+#else /* IPSEC_obey_DF */
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "fragmentation needed and DF set; %spassing packet\n",
|
|
+ notify ? "sending ICMP and " : "");
|
|
+ if (notify)
|
|
+ ICMP_SEND(ixs->skb,
|
|
+ ICMP_DEST_UNREACH,
|
|
+ ICMP_FRAG_NEEDED,
|
|
+ ixs->cur_mtu,
|
|
+ ixs->physdev);
|
|
+#endif /* IPSEC_obey_DF */
|
|
+ }
|
|
+
|
|
+#ifdef MSS_HACK
|
|
+ /*
|
|
+ * If this is a transport mode TCP packet with
|
|
+ * SYN set, determine an effective MSS based on
|
|
+ * AH/ESP overheads determined above.
|
|
+ */
|
|
+ if (ixs->iph->protocol == IPPROTO_TCP
|
|
+ && ixs->outgoing_said.proto != IPPROTO_IPIP) {
|
|
+ struct tcphdr *tcph = ixs->skb->h.th;
|
|
+ if (tcph->syn && !tcph->ack) {
|
|
+ if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->cur_mtu)) {
|
|
+ printk(KERN_WARNING
|
|
+ "klips_warning:ipsec_xmit_encap_bundle: "
|
|
+ "ipsec_adjust_mss() failed\n");
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_MSSERR;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#endif /* MSS_HACK */
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {
|
|
+ /**
|
|
+ * NAT-Traversal and Transport Mode:
|
|
+ * we need to correct TCP/UDP checksum
|
|
+ *
|
|
+ * If we've got NAT-OA, we can fix checksum without recalculation.
|
|
+ * If we don't we can zero udp checksum.
|
|
+ */
|
|
+ __u32 natt_oa = ixs->ipsp->ips_natt_oa ?
|
|
+ ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
|
|
+ __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph;
|
|
+ __u16 data_len = pkt_len - (ixs->iph->ihl << 2);
|
|
+ switch (ixs->iph->protocol) {
|
|
+ case IPPROTO_TCP:
|
|
+ if (data_len >= sizeof(struct tcphdr)) {
|
|
+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
|
|
+ if (natt_oa) {
|
|
+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "NAT-T & TRANSPORT: "
|
|
+ "fix TCP checksum using NAT-OA\n");
|
|
+ tcp->check = csum_fold(
|
|
+ csum_partial((unsigned char *)buff, sizeof(buff),
|
|
+ tcp->check^0xffff));
|
|
+ }
|
|
+ else {
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "NAT-T & TRANSPORT: do not recalc TCP checksum\n");
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
|
|
+ }
|
|
+ break;
|
|
+ case IPPROTO_UDP:
|
|
+ if (data_len >= sizeof(struct udphdr)) {
|
|
+ struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
|
|
+ if (udp->check == 0) {
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
|
|
+ }
|
|
+ else if (natt_oa) {
|
|
+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "NAT-T & TRANSPORT: "
|
|
+ "fix UDP checksum using NAT-OA\n");
|
|
+ udp->check = csum_fold(
|
|
+ csum_partial((unsigned char *)buff, sizeof(buff),
|
|
+ udp->check^0xffff));
|
|
+ }
|
|
+ else {
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "NAT-T & TRANSPORT: zero UDP checksum\n");
|
|
+ udp->check = 0;
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_tunnel,
|
|
+ "klips_debug:ipsec_tunnel_start_xmit: "
|
|
+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
|
|
+
|
|
+ if(!ixs->hard_header_stripped && ixs->hard_header_len>0) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "allocating %d bytes for hardheader.\n",
|
|
+ ixs->hard_header_len);
|
|
+ if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {
|
|
+ printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "Failed, tried to allocate %d bytes for temp hard_header.\n",
|
|
+ ixs->hard_header_len);
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_ERRMEMALLOC;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ {
|
|
+ int i;
|
|
+ for (i = 0; i < ixs->hard_header_len; i++) {
|
|
+ ixs->saved_header[i] = ixs->skb->data[i];
|
|
+ }
|
|
+ }
|
|
+ if(ixs->skb->len < ixs->hard_header_len) {
|
|
+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: "
|
|
+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
|
|
+ ixs->hard_header_len, (int)(ixs->skb->len));
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ skb_pull(ixs->skb, ixs->hard_header_len);
|
|
+ ixs->hard_header_stripped = 1;
|
|
+
|
|
+/* ixs->iph = (struct iphdr *) (ixs->skb->data); */
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "head,tailroom: %d,%d after hard_header stripped.\n",
|
|
+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
|
|
+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "hard header already stripped.\n");
|
|
+ }
|
|
+
|
|
+ ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;
|
|
+
|
|
+ if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) &&
|
|
+ (skb_tailroom(ixs->skb) >= ixs->max_tailroom)
|
|
+#ifndef NET_21
|
|
+ && ixs->skb->free
|
|
+#endif /* !NET_21 */
|
|
+ ) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "data fits in existing skb\n");
|
|
+ } else {
|
|
+ struct sk_buff* tskb;
|
|
+
|
|
+ if(!ixs->oskb) {
|
|
+ ixs->oskb = ixs->skb;
|
|
+ }
|
|
+
|
|
+ tskb = skb_copy_expand(ixs->skb,
|
|
+ /* The need for 2 * link layer length here remains unexplained...RGB */
|
|
+ ixs->max_headroom + 2 * ixs->ll_headroom,
|
|
+ ixs->max_tailroom,
|
|
+ GFP_ATOMIC);
|
|
+
|
|
+ if(tskb && ixs->skb->sk) {
|
|
+ skb_set_owner_w(tskb, ixs->skb->sk);
|
|
+ }
|
|
+
|
|
+ if(ixs->skb != ixs->oskb) {
|
|
+ ipsec_kfree_skb(ixs->skb);
|
|
+ }
|
|
+ ixs->skb = tskb;
|
|
+ if (!ixs->skb) {
|
|
+ printk(KERN_WARNING
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "Failed, tried to allocate %d head and %d tailroom\n",
|
|
+ ixs->max_headroom, ixs->max_tailroom);
|
|
+ ixs->stats->tx_errors++;
|
|
+ bundle_stat = IPSEC_XMIT_ERRSKBALLOC;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: "
|
|
+ "head,tailroom: %d,%d after allocation\n",
|
|
+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
|
|
+ }
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_tunnel & DB_TN_ENCAP) {
|
|
+ ipsec_print_ip(ixs->iph);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ /*
|
|
+ * Apply grouped transforms to packet
|
|
+ */
|
|
+ while (ixs->ipsp) {
|
|
+ enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK;
|
|
+
|
|
+ encap_stat = ipsec_xmit_encap_once(ixs);
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_tunnel & DB_TN_ENCAP) {
|
|
+ ipsec_print_ip(ixs->iph);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if(encap_stat != IPSEC_XMIT_OK) {
|
|
+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
|
|
+ "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n",
|
|
+ encap_stat);
|
|
+
|
|
+ bundle_stat = IPSEC_XMIT_ENCAPFAIL;
|
|
+ goto cleanup;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* we are done with this SA */
|
|
+ ipsec_sa_put(ixs->ipsp);
|
|
+
|
|
+ /* end encapsulation loop here XXX */
|
|
+ cleanup:
|
|
+ spin_unlock(&tdb_lock);
|
|
+ return bundle_stat;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: ipsec_xmit.c,v $
|
|
+ * Revision 1.20.2.9 2007/07/06 17:18:43 paul
|
|
+ * Fix for authentication field on sent packets has size equals to zero when
|
|
+ * using custom auth algorithms. This is bug #811. Patch by "iamscared".
|
|
+ *
|
|
+ * Revision 1.20.2.8 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.20.2.7 2006/08/24 03:02:01 paul
|
|
+ * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
|
|
+ *
|
|
+ * Revision 1.20.2.6 2006/07/07 22:09:49 paul
|
|
+ * From: Bart Trojanowski <bart@xelerance.com>
|
|
+ * Removing a left over '#else' that split another '#if/#endif' block in two.
|
|
+ *
|
|
+ * Revision 1.20.2.5 2006/07/07 15:43:17 paul
|
|
+ * From: Bart Trojanowski <bart@xelerance.com>
|
|
+ * improved protocol detection in ipsec_print_ip() -- a debug aid.
|
|
+ *
|
|
+ * Revision 1.20.2.4 2006/04/20 16:33:07 mcr
|
|
+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
|
|
+ * Fix in-kernel module compilation. Sub-makefiles do not work.
|
|
+ *
|
|
+ * Revision 1.20.2.3 2005/11/29 21:52:57 ken
|
|
+ * Fix for #518 MTU issues
|
|
+ *
|
|
+ * Revision 1.20.2.2 2005/11/27 21:41:03 paul
|
|
+ * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"in for klips as module.
|
|
+ *
|
|
+ * Revision 1.20.2.1 2005/08/27 23:40:00 paul
|
|
+ * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
|
|
+ *
|
|
+ * Revision 1.20 2005/07/12 15:39:27 paul
|
|
+ * include asm/uaccess.h for VERIFY_WRITE
|
|
+ *
|
|
+ * Revision 1.19 2005/05/24 01:02:35 mcr
|
|
+ * some refactoring/simplification of situation where alg
|
|
+ * is not found.
|
|
+ *
|
|
+ * Revision 1.18 2005/05/23 23:52:33 mcr
|
|
+ * adjust comments, add additional debugging.
|
|
+ *
|
|
+ * Revision 1.17 2005/05/23 22:57:23 mcr
|
|
+ * removed explicit 3DES support.
|
|
+ *
|
|
+ * Revision 1.16 2005/05/21 03:29:15 mcr
|
|
+ * fixed warning about unused zeroes if AH is off.
|
|
+ *
|
|
+ * Revision 1.15 2005/05/20 16:47:59 mcr
|
|
+ * include asm/checksum.h to get ip_fast_csum macro.
|
|
+ *
|
|
+ * Revision 1.14 2005/05/11 01:43:03 mcr
|
|
+ * removed "poor-man"s OOP in favour of proper C structures.
|
|
+ *
|
|
+ * Revision 1.13 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.12 2005/04/15 01:28:34 mcr
|
|
+ * use ipsec_dmp_block.
|
|
+ *
|
|
+ * Revision 1.11 2005/01/26 00:50:35 mcr
|
|
+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
|
|
+ * and make sure that NAT_TRAVERSAL is set as well to match
|
|
+ * userspace compiles of code.
|
|
+ *
|
|
+ * Revision 1.10 2004/09/13 17:55:21 ken
|
|
+ * MD5* -> osMD5*
|
|
+ *
|
|
+ * Revision 1.9 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.8 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.7 2004/02/03 03:13:41 mcr
|
|
+ * mark invalid encapsulation states.
|
|
+ *
|
|
+ * Revision 1.6.2.1 2003/12/22 15:25:52 jjo
|
|
+ * Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.6 2003/12/10 01:14:27 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.5 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.4.4.2 2003/10/29 01:37:39 mcr
|
|
+ * when creating %hold from %trap, only make the %hold as
|
|
+ * specific as the %trap was - so if the protocol and ports
|
|
+ * were wildcards, then the %hold will be too.
|
|
+ *
|
|
+ * Revision 1.4.4.1 2003/09/21 13:59:56 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.4 2003/06/20 02:28:10 mcr
|
|
+ * misstype of variable name, not detected by module build.
|
|
+ *
|
|
+ * Revision 1.3 2003/06/20 01:42:21 mcr
|
|
+ * added counters to measure how many ACQUIREs we send to pluto,
|
|
+ * and how many are successfully sent.
|
|
+ *
|
|
+ * Revision 1.2 2003/04/03 17:38:35 rgb
|
|
+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
|
|
+ * Normalised coding style.
|
|
+ * Simplified logic and reduced duplication of code.
|
|
+ *
|
|
+ * Revision 1.1 2003/02/12 19:31:23 rgb
|
|
+ * Refactored from ipsec_tunnel.c
|
|
+ *
|
|
+ * Local Variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/match586.S Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,357 @@
|
|
+/* match.s -- Pentium-optimized version of longest_match()
|
|
+ * Written for zlib 1.1.2
|
|
+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
|
|
+ *
|
|
+ * This is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License.
|
|
+ */
|
|
+
|
|
+#ifndef NO_UNDERLINE
|
|
+#define match_init _ipcomp_match_init
|
|
+#define longest_match _ipcomp_longest_match
|
|
+#else
|
|
+#define match_init ipcomp_match_init
|
|
+#define longest_match ipcomp_longest_match
|
|
+#endif
|
|
+
|
|
+#define MAX_MATCH (258)
|
|
+#define MIN_MATCH (3)
|
|
+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
|
|
+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
|
|
+
|
|
+/* stack frame offsets */
|
|
+
|
|
+#define wmask 0 /* local copy of s->wmask */
|
|
+#define window 4 /* local copy of s->window */
|
|
+#define windowbestlen 8 /* s->window + bestlen */
|
|
+#define chainlenscanend 12 /* high word: current chain len */
|
|
+ /* low word: last bytes sought */
|
|
+#define scanstart 16 /* first two bytes of string */
|
|
+#define scanalign 20 /* dword-misalignment of string */
|
|
+#define nicematch 24 /* a good enough match size */
|
|
+#define bestlen 28 /* size of best match so far */
|
|
+#define scan 32 /* ptr to string wanting match */
|
|
+
|
|
+#define LocalVarsSize (36)
|
|
+/* saved ebx 36 */
|
|
+/* saved edi 40 */
|
|
+/* saved esi 44 */
|
|
+/* saved ebp 48 */
|
|
+/* return address 52 */
|
|
+#define deflatestate 56 /* the function arguments */
|
|
+#define curmatch 60
|
|
+
|
|
+/* Offsets for fields in the deflate_state structure. These numbers
|
|
+ * are calculated from the definition of deflate_state, with the
|
|
+ * assumption that the compiler will dword-align the fields. (Thus,
|
|
+ * changing the definition of deflate_state could easily cause this
|
|
+ * program to crash horribly, without so much as a warning at
|
|
+ * compile time. Sigh.)
|
|
+ */
|
|
+#define dsWSize 36
|
|
+#define dsWMask 44
|
|
+#define dsWindow 48
|
|
+#define dsPrev 56
|
|
+#define dsMatchLen 88
|
|
+#define dsPrevMatch 92
|
|
+#define dsStrStart 100
|
|
+#define dsMatchStart 104
|
|
+#define dsLookahead 108
|
|
+#define dsPrevLen 112
|
|
+#define dsMaxChainLen 116
|
|
+#define dsGoodMatch 132
|
|
+#define dsNiceMatch 136
|
|
+
|
|
+
|
|
+.file "match.S"
|
|
+
|
|
+.globl match_init, longest_match
|
|
+
|
|
+.text
|
|
+
|
|
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
|
|
+
|
|
+longest_match:
|
|
+
|
|
+/* Save registers that the compiler may be using, and adjust %esp to */
|
|
+/* make room for our stack frame. */
|
|
+
|
|
+ pushl %ebp
|
|
+ pushl %edi
|
|
+ pushl %esi
|
|
+ pushl %ebx
|
|
+ subl $LocalVarsSize, %esp
|
|
+
|
|
+/* Retrieve the function arguments. %ecx will hold cur_match */
|
|
+/* throughout the entire function. %edx will hold the pointer to the */
|
|
+/* deflate_state structure during the function's setup (before */
|
|
+/* entering the main loop). */
|
|
+
|
|
+ movl deflatestate(%esp), %edx
|
|
+ movl curmatch(%esp), %ecx
|
|
+
|
|
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
|
|
+
|
|
+ movl dsNiceMatch(%edx), %eax
|
|
+ movl dsLookahead(%edx), %ebx
|
|
+ cmpl %eax, %ebx
|
|
+ jl LookaheadLess
|
|
+ movl %eax, %ebx
|
|
+LookaheadLess: movl %ebx, nicematch(%esp)
|
|
+
|
|
+/* register Bytef *scan = s->window + s->strstart; */
|
|
+
|
|
+ movl dsWindow(%edx), %esi
|
|
+ movl %esi, window(%esp)
|
|
+ movl dsStrStart(%edx), %ebp
|
|
+ lea (%esi,%ebp), %edi
|
|
+ movl %edi, scan(%esp)
|
|
+
|
|
+/* Determine how many bytes the scan ptr is off from being */
|
|
+/* dword-aligned. */
|
|
+
|
|
+ movl %edi, %eax
|
|
+ negl %eax
|
|
+ andl $3, %eax
|
|
+ movl %eax, scanalign(%esp)
|
|
+
|
|
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
|
|
+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
|
|
+
|
|
+ movl dsWSize(%edx), %eax
|
|
+ subl $MIN_LOOKAHEAD, %eax
|
|
+ subl %eax, %ebp
|
|
+ jg LimitPositive
|
|
+ xorl %ebp, %ebp
|
|
+LimitPositive:
|
|
+
|
|
+/* unsigned chain_length = s->max_chain_length; */
|
|
+/* if (s->prev_length >= s->good_match) { */
|
|
+/* chain_length >>= 2; */
|
|
+/* } */
|
|
+
|
|
+ movl dsPrevLen(%edx), %eax
|
|
+ movl dsGoodMatch(%edx), %ebx
|
|
+ cmpl %ebx, %eax
|
|
+ movl dsMaxChainLen(%edx), %ebx
|
|
+ jl LastMatchGood
|
|
+ shrl $2, %ebx
|
|
+LastMatchGood:
|
|
+
|
|
+/* chainlen is decremented once beforehand so that the function can */
|
|
+/* use the sign flag instead of the zero flag for the exit test. */
|
|
+/* It is then shifted into the high word, to make room for the scanend */
|
|
+/* scanend value, which it will always accompany. */
|
|
+
|
|
+ decl %ebx
|
|
+ shll $16, %ebx
|
|
+
|
|
+/* int best_len = s->prev_length; */
|
|
+
|
|
+ movl dsPrevLen(%edx), %eax
|
|
+ movl %eax, bestlen(%esp)
|
|
+
|
|
+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
|
|
+
|
|
+ addl %eax, %esi
|
|
+ movl %esi, windowbestlen(%esp)
|
|
+
|
|
+/* register ush scan_start = *(ushf*)scan; */
|
|
+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
|
|
+
|
|
+ movw (%edi), %bx
|
|
+ movw %bx, scanstart(%esp)
|
|
+ movw -1(%edi,%eax), %bx
|
|
+ movl %ebx, chainlenscanend(%esp)
|
|
+
|
|
+/* Posf *prev = s->prev; */
|
|
+/* uInt wmask = s->w_mask; */
|
|
+
|
|
+ movl dsPrev(%edx), %edi
|
|
+ movl dsWMask(%edx), %edx
|
|
+ mov %edx, wmask(%esp)
|
|
+
|
|
+/* Jump into the main loop. */
|
|
+
|
|
+ jmp LoopEntry
|
|
+
|
|
+.balign 16
|
|
+
|
|
+/* do {
|
|
+ * match = s->window + cur_match;
|
|
+ * if (*(ushf*)(match+best_len-1) != scan_end ||
|
|
+ * *(ushf*)match != scan_start) continue;
|
|
+ * [...]
|
|
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
|
|
+ * && --chain_length != 0);
|
|
+ *
|
|
+ * Here is the inner loop of the function. The function will spend the
|
|
+ * majority of its time in this loop, and majority of that time will
|
|
+ * be spent in the first ten instructions.
|
|
+ *
|
|
+ * Within this loop:
|
|
+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
|
|
+ * %ecx = curmatch
|
|
+ * %edx = curmatch & wmask
|
|
+ * %esi = windowbestlen - i.e., (window + bestlen)
|
|
+ * %edi = prev
|
|
+ * %ebp = limit
|
|
+ *
|
|
+ * Two optimization notes on the choice of instructions:
|
|
+ *
|
|
+ * The first instruction uses a 16-bit address, which costs an extra,
|
|
+ * unpairable cycle. This is cheaper than doing a 32-bit access and
|
|
+ * zeroing the high word, due to the 3-cycle misalignment penalty which
|
|
+ * would occur half the time. This also turns out to be cheaper than
|
|
+ * doing two separate 8-bit accesses, as the memory is so rarely in the
|
|
+ * L1 cache.
|
|
+ *
|
|
+ * The window buffer, however, apparently spends a lot of time in the
|
|
+ * cache, and so it is faster to retrieve the word at the end of the
|
|
+ * match string with two 8-bit loads. The instructions that test the
|
|
+ * word at the beginning of the match string, however, are executed
|
|
+ * much less frequently, and there it was cheaper to use 16-bit
|
|
+ * instructions, which avoided the necessity of saving off and
|
|
+ * subsequently reloading one of the other registers.
|
|
+ */
|
|
+LookupLoop:
|
|
+ /* 1 U & V */
|
|
+ movw (%edi,%edx,2), %cx /* 2 U pipe */
|
|
+ movl wmask(%esp), %edx /* 2 V pipe */
|
|
+ cmpl %ebp, %ecx /* 3 U pipe */
|
|
+ jbe LeaveNow /* 3 V pipe */
|
|
+ subl $0x00010000, %ebx /* 4 U pipe */
|
|
+ js LeaveNow /* 4 V pipe */
|
|
+LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
|
|
+ andl %ecx, %edx /* 5 V pipe */
|
|
+ cmpb %bl, %al /* 6 U pipe */
|
|
+ jnz LookupLoop /* 6 V pipe */
|
|
+ movb (%esi,%ecx), %ah
|
|
+ cmpb %bh, %ah
|
|
+ jnz LookupLoop
|
|
+ movl window(%esp), %eax
|
|
+ movw (%eax,%ecx), %ax
|
|
+ cmpw scanstart(%esp), %ax
|
|
+ jnz LookupLoop
|
|
+
|
|
+/* Store the current value of chainlen. */
|
|
+
|
|
+ movl %ebx, chainlenscanend(%esp)
|
|
+
|
|
+/* Point %edi to the string under scrutiny, and %esi to the string we */
|
|
+/* are hoping to match it up with. In actuality, %esi and %edi are */
|
|
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
|
|
+/* initialized to -(MAX_MATCH_8 - scanalign). */
|
|
+
|
|
+ movl window(%esp), %esi
|
|
+ movl scan(%esp), %edi
|
|
+ addl %ecx, %esi
|
|
+ movl scanalign(%esp), %eax
|
|
+ movl $(-MAX_MATCH_8), %edx
|
|
+ lea MAX_MATCH_8(%edi,%eax), %edi
|
|
+ lea MAX_MATCH_8(%esi,%eax), %esi
|
|
+
|
|
+/* Test the strings for equality, 8 bytes at a time. At the end,
|
|
+ * adjust %edx so that it is offset to the exact byte that mismatched.
|
|
+ *
|
|
+ * We already know at this point that the first three bytes of the
|
|
+ * strings match each other, and they can be safely passed over before
|
|
+ * starting the compare loop. So what this code does is skip over 0-3
|
|
+ * bytes, as much as necessary in order to dword-align the %edi
|
|
+ * pointer. (%esi will still be misaligned three times out of four.)
|
|
+ *
|
|
+ * It should be confessed that this loop usually does not represent
|
|
+ * much of the total running time. Replacing it with a more
|
|
+ * straightforward "rep cmpsb" would not drastically degrade
|
|
+ * performance.
|
|
+ */
|
|
+LoopCmps:
|
|
+ movl (%esi,%edx), %eax
|
|
+ movl (%edi,%edx), %ebx
|
|
+ xorl %ebx, %eax
|
|
+ jnz LeaveLoopCmps
|
|
+ movl 4(%esi,%edx), %eax
|
|
+ movl 4(%edi,%edx), %ebx
|
|
+ xorl %ebx, %eax
|
|
+ jnz LeaveLoopCmps4
|
|
+ addl $8, %edx
|
|
+ jnz LoopCmps
|
|
+ jmp LenMaximum
|
|
+LeaveLoopCmps4: addl $4, %edx
|
|
+LeaveLoopCmps: testl $0x0000FFFF, %eax
|
|
+ jnz LenLower
|
|
+ addl $2, %edx
|
|
+ shrl $16, %eax
|
|
+LenLower: subb $1, %al
|
|
+ adcl $0, %edx
|
|
+
|
|
+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
|
|
+/* then automatically accept it as the best possible match and leave. */
|
|
+
|
|
+ lea (%edi,%edx), %eax
|
|
+ movl scan(%esp), %edi
|
|
+ subl %edi, %eax
|
|
+ cmpl $MAX_MATCH, %eax
|
|
+ jge LenMaximum
|
|
+
|
|
+/* If the length of the match is not longer than the best match we */
|
|
+/* have so far, then forget it and return to the lookup loop. */
|
|
+
|
|
+ movl deflatestate(%esp), %edx
|
|
+ movl bestlen(%esp), %ebx
|
|
+ cmpl %ebx, %eax
|
|
+ jg LongerMatch
|
|
+ movl chainlenscanend(%esp), %ebx
|
|
+ movl windowbestlen(%esp), %esi
|
|
+ movl dsPrev(%edx), %edi
|
|
+ movl wmask(%esp), %edx
|
|
+ andl %ecx, %edx
|
|
+ jmp LookupLoop
|
|
+
|
|
+/* s->match_start = cur_match; */
|
|
+/* best_len = len; */
|
|
+/* if (len >= nice_match) break; */
|
|
+/* scan_end = *(ushf*)(scan+best_len-1); */
|
|
+
|
|
+LongerMatch: movl nicematch(%esp), %ebx
|
|
+ movl %eax, bestlen(%esp)
|
|
+ movl %ecx, dsMatchStart(%edx)
|
|
+ cmpl %ebx, %eax
|
|
+ jge LeaveNow
|
|
+ movl window(%esp), %esi
|
|
+ addl %eax, %esi
|
|
+ movl %esi, windowbestlen(%esp)
|
|
+ movl chainlenscanend(%esp), %ebx
|
|
+ movw -1(%edi,%eax), %bx
|
|
+ movl dsPrev(%edx), %edi
|
|
+ movl %ebx, chainlenscanend(%esp)
|
|
+ movl wmask(%esp), %edx
|
|
+ andl %ecx, %edx
|
|
+ jmp LookupLoop
|
|
+
|
|
+/* Accept the current string, with the maximum possible length. */
|
|
+
|
|
+LenMaximum: movl deflatestate(%esp), %edx
|
|
+ movl $MAX_MATCH, bestlen(%esp)
|
|
+ movl %ecx, dsMatchStart(%edx)
|
|
+
|
|
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
|
|
+/* return s->lookahead; */
|
|
+
|
|
+LeaveNow:
|
|
+ movl deflatestate(%esp), %edx
|
|
+ movl bestlen(%esp), %ebx
|
|
+ movl dsLookahead(%edx), %eax
|
|
+ cmpl %eax, %ebx
|
|
+ jg LookaheadRet
|
|
+ movl %ebx, %eax
|
|
+LookaheadRet:
|
|
+
|
|
+/* Restore the stack and return from whence we came. */
|
|
+
|
|
+ addl $LocalVarsSize, %esp
|
|
+ popl %ebx
|
|
+ popl %esi
|
|
+ popl %edi
|
|
+ popl %ebp
|
|
+match_init: ret
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/match686.S Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,330 @@
|
|
+/* match.s -- Pentium-Pro-optimized version of longest_match()
|
|
+ * Written for zlib 1.1.2
|
|
+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
|
|
+ *
|
|
+ * This is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License.
|
|
+ */
|
|
+
|
|
+#ifndef NO_UNDERLINE
|
|
+#define match_init _ipcomp_match_init
|
|
+#define longest_match _ipcomp_longest_match
|
|
+#else
|
|
+#define match_init ipcomp_match_init
|
|
+#define longest_match ipcomp_longest_match
|
|
+#endif
|
|
+
|
|
+#define MAX_MATCH (258)
|
|
+#define MIN_MATCH (3)
|
|
+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
|
|
+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
|
|
+
|
|
+/* stack frame offsets */
|
|
+
|
|
+#define chainlenwmask 0 /* high word: current chain len */
|
|
+ /* low word: s->wmask */
|
|
+#define window 4 /* local copy of s->window */
|
|
+#define windowbestlen 8 /* s->window + bestlen */
|
|
+#define scanstart 16 /* first two bytes of string */
|
|
+#define scanend 12 /* last two bytes of string */
|
|
+#define scanalign 20 /* dword-misalignment of string */
|
|
+#define nicematch 24 /* a good enough match size */
|
|
+#define bestlen 28 /* size of best match so far */
|
|
+#define scan 32 /* ptr to string wanting match */
|
|
+
|
|
+#define LocalVarsSize (36)
|
|
+/* saved ebx 36 */
|
|
+/* saved edi 40 */
|
|
+/* saved esi 44 */
|
|
+/* saved ebp 48 */
|
|
+/* return address 52 */
|
|
+#define deflatestate 56 /* the function arguments */
|
|
+#define curmatch 60
|
|
+
|
|
+/* Offsets for fields in the deflate_state structure. These numbers
|
|
+ * are calculated from the definition of deflate_state, with the
|
|
+ * assumption that the compiler will dword-align the fields. (Thus,
|
|
+ * changing the definition of deflate_state could easily cause this
|
|
+ * program to crash horribly, without so much as a warning at
|
|
+ * compile time. Sigh.)
|
|
+ */
|
|
+#define dsWSize 36
|
|
+#define dsWMask 44
|
|
+#define dsWindow 48
|
|
+#define dsPrev 56
|
|
+#define dsMatchLen 88
|
|
+#define dsPrevMatch 92
|
|
+#define dsStrStart 100
|
|
+#define dsMatchStart 104
|
|
+#define dsLookahead 108
|
|
+#define dsPrevLen 112
|
|
+#define dsMaxChainLen 116
|
|
+#define dsGoodMatch 132
|
|
+#define dsNiceMatch 136
|
|
+
|
|
+
|
|
+.file "match.S"
|
|
+
|
|
+.globl match_init, longest_match
|
|
+
|
|
+.text
|
|
+
|
|
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
|
|
+
|
|
+longest_match:
|
|
+
|
|
+/* Save registers that the compiler may be using, and adjust %esp to */
|
|
+/* make room for our stack frame. */
|
|
+
|
|
+ pushl %ebp
|
|
+ pushl %edi
|
|
+ pushl %esi
|
|
+ pushl %ebx
|
|
+ subl $LocalVarsSize, %esp
|
|
+
|
|
+/* Retrieve the function arguments. %ecx will hold cur_match */
|
|
+/* throughout the entire function. %edx will hold the pointer to the */
|
|
+/* deflate_state structure during the function's setup (before */
|
|
+/* entering the main loop). */
|
|
+
|
|
+ movl deflatestate(%esp), %edx
|
|
+ movl curmatch(%esp), %ecx
|
|
+
|
|
+/* uInt wmask = s->w_mask; */
|
|
+/* unsigned chain_length = s->max_chain_length; */
|
|
+/* if (s->prev_length >= s->good_match) { */
|
|
+/* chain_length >>= 2; */
|
|
+/* } */
|
|
+
|
|
+ movl dsPrevLen(%edx), %eax
|
|
+ movl dsGoodMatch(%edx), %ebx
|
|
+ cmpl %ebx, %eax
|
|
+ movl dsWMask(%edx), %eax
|
|
+ movl dsMaxChainLen(%edx), %ebx
|
|
+ jl LastMatchGood
|
|
+ shrl $2, %ebx
|
|
+LastMatchGood:
|
|
+
|
|
+/* chainlen is decremented once beforehand so that the function can */
|
|
+/* use the sign flag instead of the zero flag for the exit test. */
|
|
+/* It is then shifted into the high word, to make room for the wmask */
|
|
+/* value, which it will always accompany. */
|
|
+
|
|
+ decl %ebx
|
|
+ shll $16, %ebx
|
|
+ orl %eax, %ebx
|
|
+ movl %ebx, chainlenwmask(%esp)
|
|
+
|
|
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
|
|
+
|
|
+ movl dsNiceMatch(%edx), %eax
|
|
+ movl dsLookahead(%edx), %ebx
|
|
+ cmpl %eax, %ebx
|
|
+ jl LookaheadLess
|
|
+ movl %eax, %ebx
|
|
+LookaheadLess: movl %ebx, nicematch(%esp)
|
|
+
|
|
+/* register Bytef *scan = s->window + s->strstart; */
|
|
+
|
|
+ movl dsWindow(%edx), %esi
|
|
+ movl %esi, window(%esp)
|
|
+ movl dsStrStart(%edx), %ebp
|
|
+ lea (%esi,%ebp), %edi
|
|
+ movl %edi, scan(%esp)
|
|
+
|
|
+/* Determine how many bytes the scan ptr is off from being */
|
|
+/* dword-aligned. */
|
|
+
|
|
+ movl %edi, %eax
|
|
+ negl %eax
|
|
+ andl $3, %eax
|
|
+ movl %eax, scanalign(%esp)
|
|
+
|
|
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
|
|
+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
|
|
+
|
|
+ movl dsWSize(%edx), %eax
|
|
+ subl $MIN_LOOKAHEAD, %eax
|
|
+ subl %eax, %ebp
|
|
+ jg LimitPositive
|
|
+ xorl %ebp, %ebp
|
|
+LimitPositive:
|
|
+
|
|
+/* int best_len = s->prev_length; */
|
|
+
|
|
+ movl dsPrevLen(%edx), %eax
|
|
+ movl %eax, bestlen(%esp)
|
|
+
|
|
+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
|
|
+
|
|
+ addl %eax, %esi
|
|
+ movl %esi, windowbestlen(%esp)
|
|
+
|
|
+/* register ush scan_start = *(ushf*)scan; */
|
|
+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
|
|
+/* Posf *prev = s->prev; */
|
|
+
|
|
+ movzwl (%edi), %ebx
|
|
+ movl %ebx, scanstart(%esp)
|
|
+ movzwl -1(%edi,%eax), %ebx
|
|
+ movl %ebx, scanend(%esp)
|
|
+ movl dsPrev(%edx), %edi
|
|
+
|
|
+/* Jump into the main loop. */
|
|
+
|
|
+ movl chainlenwmask(%esp), %edx
|
|
+ jmp LoopEntry
|
|
+
|
|
+.balign 16
|
|
+
|
|
+/* do {
|
|
+ * match = s->window + cur_match;
|
|
+ * if (*(ushf*)(match+best_len-1) != scan_end ||
|
|
+ * *(ushf*)match != scan_start) continue;
|
|
+ * [...]
|
|
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
|
|
+ * && --chain_length != 0);
|
|
+ *
|
|
+ * Here is the inner loop of the function. The function will spend the
|
|
+ * majority of its time in this loop, and majority of that time will
|
|
+ * be spent in the first ten instructions.
|
|
+ *
|
|
+ * Within this loop:
|
|
+ * %ebx = scanend
|
|
+ * %ecx = curmatch
|
|
+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
|
|
+ * %esi = windowbestlen - i.e., (window + bestlen)
|
|
+ * %edi = prev
|
|
+ * %ebp = limit
|
|
+ */
|
|
+LookupLoop:
|
|
+ andl %edx, %ecx
|
|
+ movzwl (%edi,%ecx,2), %ecx
|
|
+ cmpl %ebp, %ecx
|
|
+ jbe LeaveNow
|
|
+ subl $0x00010000, %edx
|
|
+ js LeaveNow
|
|
+LoopEntry: movzwl -1(%esi,%ecx), %eax
|
|
+ cmpl %ebx, %eax
|
|
+ jnz LookupLoop
|
|
+ movl window(%esp), %eax
|
|
+ movzwl (%eax,%ecx), %eax
|
|
+ cmpl scanstart(%esp), %eax
|
|
+ jnz LookupLoop
|
|
+
|
|
+/* Store the current value of chainlen. */
|
|
+
|
|
+ movl %edx, chainlenwmask(%esp)
|
|
+
|
|
+/* Point %edi to the string under scrutiny, and %esi to the string we */
|
|
+/* are hoping to match it up with. In actuality, %esi and %edi are */
|
|
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
|
|
+/* initialized to -(MAX_MATCH_8 - scanalign). */
|
|
+
|
|
+ movl window(%esp), %esi
|
|
+ movl scan(%esp), %edi
|
|
+ addl %ecx, %esi
|
|
+ movl scanalign(%esp), %eax
|
|
+ movl $(-MAX_MATCH_8), %edx
|
|
+ lea MAX_MATCH_8(%edi,%eax), %edi
|
|
+ lea MAX_MATCH_8(%esi,%eax), %esi
|
|
+
|
|
+/* Test the strings for equality, 8 bytes at a time. At the end,
|
|
+ * adjust %edx so that it is offset to the exact byte that mismatched.
|
|
+ *
|
|
+ * We already know at this point that the first three bytes of the
|
|
+ * strings match each other, and they can be safely passed over before
|
|
+ * starting the compare loop. So what this code does is skip over 0-3
|
|
+ * bytes, as much as necessary in order to dword-align the %edi
|
|
+ * pointer. (%esi will still be misaligned three times out of four.)
|
|
+ *
|
|
+ * It should be confessed that this loop usually does not represent
|
|
+ * much of the total running time. Replacing it with a more
|
|
+ * straightforward "rep cmpsb" would not drastically degrade
|
|
+ * performance.
|
|
+ */
|
|
+LoopCmps:
|
|
+ movl (%esi,%edx), %eax
|
|
+ xorl (%edi,%edx), %eax
|
|
+ jnz LeaveLoopCmps
|
|
+ movl 4(%esi,%edx), %eax
|
|
+ xorl 4(%edi,%edx), %eax
|
|
+ jnz LeaveLoopCmps4
|
|
+ addl $8, %edx
|
|
+ jnz LoopCmps
|
|
+ jmp LenMaximum
|
|
+LeaveLoopCmps4: addl $4, %edx
|
|
+LeaveLoopCmps: testl $0x0000FFFF, %eax
|
|
+ jnz LenLower
|
|
+ addl $2, %edx
|
|
+ shrl $16, %eax
|
|
+LenLower: subb $1, %al
|
|
+ adcl $0, %edx
|
|
+
|
|
+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
|
|
+/* then automatically accept it as the best possible match and leave. */
|
|
+
|
|
+ lea (%edi,%edx), %eax
|
|
+ movl scan(%esp), %edi
|
|
+ subl %edi, %eax
|
|
+ cmpl $MAX_MATCH, %eax
|
|
+ jge LenMaximum
|
|
+
|
|
+/* If the length of the match is not longer than the best match we */
|
|
+/* have so far, then forget it and return to the lookup loop. */
|
|
+
|
|
+ movl deflatestate(%esp), %edx
|
|
+ movl bestlen(%esp), %ebx
|
|
+ cmpl %ebx, %eax
|
|
+ jg LongerMatch
|
|
+ movl windowbestlen(%esp), %esi
|
|
+ movl dsPrev(%edx), %edi
|
|
+ movl scanend(%esp), %ebx
|
|
+ movl chainlenwmask(%esp), %edx
|
|
+ jmp LookupLoop
|
|
+
|
|
+/* s->match_start = cur_match; */
|
|
+/* best_len = len; */
|
|
+/* if (len >= nice_match) break; */
|
|
+/* scan_end = *(ushf*)(scan+best_len-1); */
|
|
+
|
|
+LongerMatch: movl nicematch(%esp), %ebx
|
|
+ movl %eax, bestlen(%esp)
|
|
+ movl %ecx, dsMatchStart(%edx)
|
|
+ cmpl %ebx, %eax
|
|
+ jge LeaveNow
|
|
+ movl window(%esp), %esi
|
|
+ addl %eax, %esi
|
|
+ movl %esi, windowbestlen(%esp)
|
|
+ movzwl -1(%edi,%eax), %ebx
|
|
+ movl dsPrev(%edx), %edi
|
|
+ movl %ebx, scanend(%esp)
|
|
+ movl chainlenwmask(%esp), %edx
|
|
+ jmp LookupLoop
|
|
+
|
|
+/* Accept the current string, with the maximum possible length. */
|
|
+
|
|
+LenMaximum: movl deflatestate(%esp), %edx
|
|
+ movl $MAX_MATCH, bestlen(%esp)
|
|
+ movl %ecx, dsMatchStart(%edx)
|
|
+
|
|
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
|
|
+/* return s->lookahead; */
|
|
+
|
|
+LeaveNow:
|
|
+ movl deflatestate(%esp), %edx
|
|
+ movl bestlen(%esp), %ebx
|
|
+ movl dsLookahead(%edx), %eax
|
|
+ cmpl %eax, %ebx
|
|
+ jg LookaheadRet
|
|
+ movl %ebx, %eax
|
|
+LookaheadRet:
|
|
+
|
|
+/* Restore the stack and return from whence we came. */
|
|
+
|
|
+ addl $LocalVarsSize, %esp
|
|
+ popl %ebx
|
|
+ popl %esi
|
|
+ popl %edi
|
|
+ popl %ebp
|
|
+match_init: ret
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/null/ipsec_alg_null.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,145 @@
|
|
+/*
|
|
+ * ipsec_alg NULL cipher stubs
|
|
+ *
|
|
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
|
|
+ *
|
|
+ * $Id: ipsec_alg_null.c,v 1.1.2.1 2006/10/11 18:14:33 paul Exp $
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ */
|
|
+#include <linux/config.h>
|
|
+#include <linux/version.h>
|
|
+
|
|
+/*
|
|
+ * special case: ipsec core modular with this static algo inside:
|
|
+ * must avoid MODULE magic for this file
|
|
+ */
|
|
+#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_NULL)
|
|
+#undef MODULE
|
|
+#endif
|
|
+
|
|
+#include <linux/module.h>
|
|
+#include <linux/init.h>
|
|
+
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/string.h>
|
|
+
|
|
+/* Check if __exit is defined, if not null it */
|
|
+#ifndef __exit
|
|
+#define __exit
|
|
+#endif
|
|
+
|
|
+/* Low freeswan header coupling */
|
|
+#include "openswan/ipsec_alg.h"
|
|
+
|
|
+#define ESP_NULL 11 /* from ipsec drafts */
|
|
+#define ESP_NULL_BLK_LEN 1
|
|
+
|
|
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
|
|
+static int debug_null=0;
|
|
+static int test_null=0;
|
|
+#ifdef module_param
|
|
+module_param(debug_null, int, 0600);
|
|
+module_param(test_null, int, 0600);
|
|
+#else
|
|
+MODULE_PARM(debug_null, "i");
|
|
+MODULE_PARM(test_null, "i");
|
|
+#endif
|
|
+
|
|
+typedef int null_context;
|
|
+
|
|
+struct null_eks{
|
|
+ null_context null_ctx;
|
|
+};
|
|
+static int _null_set_key(struct ipsec_alg_enc *alg,
|
|
+ __u8 * key_e, const __u8 * key,
|
|
+ size_t keysize) {
|
|
+ null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
|
|
+ if (debug_null > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_null_set_key:"
|
|
+ "key_e=%p key=%p keysize=%d\n",
|
|
+ key_e, key, keysize);
|
|
+ *ctx = 1;
|
|
+ return 0;
|
|
+}
|
|
+static int _null_cbc_encrypt(struct ipsec_alg_enc *alg,
|
|
+ __u8 * key_e, __u8 * in, int ilen, const __u8 * iv,
|
|
+ int encrypt) {
|
|
+ null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
|
|
+ if (debug_null > 0)
|
|
+ printk(KERN_DEBUG "klips_debug:_null_cbc_encrypt:"
|
|
+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
|
|
+ key_e, in, ilen, iv, encrypt);
|
|
+ (*ctx)++;
|
|
+ return ilen;
|
|
+}
|
|
+static struct ipsec_alg_enc ipsec_alg_NULL = {
|
|
+ ixt_common: { ixt_version: IPSEC_ALG_VERSION,
|
|
+ ixt_refcnt: ATOMIC_INIT(0),
|
|
+ ixt_name: "null",
|
|
+ ixt_blocksize: ESP_NULL_BLK_LEN,
|
|
+ ixt_support: {
|
|
+ ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
|
|
+ ias_id: ESP_NULL,
|
|
+ ias_ivlen: 0,
|
|
+ ias_keyminbits: 0,
|
|
+ ias_keymaxbits: 0,
|
|
+ },
|
|
+ },
|
|
+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
|
|
+ ixt_module: THIS_MODULE,
|
|
+#endif
|
|
+ ixt_e_keylen: 0,
|
|
+ ixt_e_ctx_size: sizeof(null_context),
|
|
+ ixt_e_set_key: _null_set_key,
|
|
+ ixt_e_cbc_encrypt:_null_cbc_encrypt,
|
|
+};
|
|
+
|
|
+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
|
|
+IPSEC_ALG_MODULE_INIT_MOD( ipsec_null_init )
|
|
+#else
|
|
+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_null_init )
|
|
+#endif
|
|
+{
|
|
+ int ret, test_ret;
|
|
+ ret=register_ipsec_alg_enc(&ipsec_alg_NULL);
|
|
+ printk("ipsec_null_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
|
|
+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
|
|
+ ipsec_alg_NULL.ixt_common.ixt_name,
|
|
+ ret);
|
|
+ if (ret==0 && test_null) {
|
|
+ test_ret=ipsec_alg_test(
|
|
+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
|
|
+ test_null);
|
|
+ printk("ipsec_null_init(alg_type=%d alg_id=%d): test_ret=%d\n",
|
|
+ ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
|
|
+ ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
|
|
+ test_ret);
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
|
|
+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_null_fini )
|
|
+#else
|
|
+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_null_fini )
|
|
+#endif
|
|
+{
|
|
+ unregister_ipsec_alg_enc(&ipsec_alg_NULL);
|
|
+ return;
|
|
+}
|
|
+#ifdef MODULE_LICENSE
|
|
+MODULE_LICENSE("GPL");
|
|
+#endif
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,2022 @@
|
|
+/*
|
|
+ * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
|
|
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: pfkey_v2.c,v 1.97.2.12 2006/11/24 05:43:29 paul Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
|
|
+ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
|
|
+ */
|
|
+
|
|
+#define __NO_VERSION__
|
|
+#include <linux/module.h>
|
|
+#include <linux/version.h>
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/kernel.h>
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#include <linux/major.h>
|
|
+#include <linux/signal.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/errno.h>
|
|
+#include <linux/string.h>
|
|
+#include <linux/stat.h>
|
|
+#include <linux/socket.h>
|
|
+#include <linux/un.h>
|
|
+#include <linux/fcntl.h>
|
|
+#include <linux/termios.h>
|
|
+#include <linux/socket.h>
|
|
+#include <linux/sockios.h>
|
|
+#include <linux/net.h> /* struct socket */
|
|
+#include <linux/in.h>
|
|
+#include <linux/fs.h>
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <asm/segment.h>
|
|
+#include <linux/skbuff.h>
|
|
+#include <linux/netdevice.h>
|
|
+#include <net/sock.h> /* struct sock */
|
|
+#include <net/protocol.h>
|
|
+/* #include <net/tcp.h> */
|
|
+#include <net/af_unix.h>
|
|
+#ifdef CONFIG_PROC_FS
|
|
+# include <linux/proc_fs.h>
|
|
+#endif /* CONFIG_PROC_FS */
|
|
+
|
|
+#include <linux/types.h>
|
|
+
|
|
+#include <openswan.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#include "openswan/ipsec_kern24.h"
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+int debug_pfkey = 0;
|
|
+extern int sysctl_ipsec_debug_verbose;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
|
|
+
|
|
+#ifndef SOCKOPS_WRAPPED
|
|
+#define SOCKOPS_WRAPPED(name) name
|
|
+#endif /* SOCKOPS_WRAPPED */
|
|
+
|
|
+#ifdef NET_26
|
|
+static rwlock_t pfkey_sock_lock = RW_LOCK_UNLOCKED;
|
|
+HLIST_HEAD(pfkey_sock_list);
|
|
+static DECLARE_WAIT_QUEUE_HEAD(pfkey_sock_wait);
|
|
+static atomic_t pfkey_sock_users = ATOMIC_INIT(0);
|
|
+#else
|
|
+struct sock *pfkey_sock_list = NULL;
|
|
+#endif
|
|
+
|
|
+struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
|
|
+
|
|
+struct socket_list *pfkey_open_sockets = NULL;
|
|
+struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
|
|
+
|
|
+int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
|
|
+
|
|
+DEBUG_NO_STATIC int pfkey_create(struct socket *sock, int protocol);
|
|
+DEBUG_NO_STATIC int pfkey_shutdown(struct socket *sock, int mode);
|
|
+DEBUG_NO_STATIC int pfkey_release(struct socket *sock);
|
|
+
|
|
+#ifdef NET_26
|
|
+DEBUG_NO_STATIC int pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len);
|
|
+DEBUG_NO_STATIC int pfkey_recvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg
|
|
+ , size_t size, int flags);
|
|
+#else
|
|
+DEBUG_NO_STATIC int pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm);
|
|
+DEBUG_NO_STATIC int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm);
|
|
+#endif
|
|
+
|
|
+struct net_proto_family pfkey_family_ops = {
|
|
+#ifdef NETDEV_23
|
|
+ .family = PF_KEY,
|
|
+ .create = pfkey_create,
|
|
+#ifdef NET_26
|
|
+ .owner = THIS_MODULE,
|
|
+#endif
|
|
+#else
|
|
+ PF_KEY,
|
|
+ pfkey_create
|
|
+#endif
|
|
+};
|
|
+
|
|
+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
|
|
+#ifdef NETDEV_23
|
|
+ family: PF_KEY,
|
|
+#ifdef NET_26
|
|
+ owner: THIS_MODULE,
|
|
+#endif
|
|
+ release: pfkey_release,
|
|
+ bind: sock_no_bind,
|
|
+ connect: sock_no_connect,
|
|
+ socketpair: sock_no_socketpair,
|
|
+ accept: sock_no_accept,
|
|
+ getname: sock_no_getname,
|
|
+ poll: datagram_poll,
|
|
+ ioctl: sock_no_ioctl,
|
|
+ listen: sock_no_listen,
|
|
+ shutdown: pfkey_shutdown,
|
|
+ setsockopt: sock_no_setsockopt,
|
|
+ getsockopt: sock_no_getsockopt,
|
|
+ sendmsg: pfkey_sendmsg,
|
|
+ recvmsg: pfkey_recvmsg,
|
|
+ mmap: sock_no_mmap,
|
|
+#else /* NETDEV_23 */
|
|
+ PF_KEY,
|
|
+ sock_no_dup,
|
|
+ pfkey_release,
|
|
+ sock_no_bind,
|
|
+ sock_no_connect,
|
|
+ sock_no_socketpair,
|
|
+ sock_no_accept,
|
|
+ sock_no_getname,
|
|
+ datagram_poll,
|
|
+ sock_no_ioctl,
|
|
+ sock_no_listen,
|
|
+ pfkey_shutdown,
|
|
+ sock_no_setsockopt,
|
|
+ sock_no_getsockopt,
|
|
+ sock_no_fcntl,
|
|
+ pfkey_sendmsg,
|
|
+ pfkey_recvmsg
|
|
+#endif /* NETDEV_23 */
|
|
+};
|
|
+
|
|
+#ifdef NETDEV_23
|
|
+#include <linux/smp_lock.h>
|
|
+SOCKOPS_WRAP(pfkey, PF_KEY);
|
|
+#endif /* NETDEV_23 */
|
|
+
|
|
+#ifdef NET_26
|
|
+static void pfkey_sock_list_grab(void)
|
|
+{
|
|
+ write_lock_bh(&pfkey_sock_lock);
|
|
+
|
|
+ if (atomic_read(&pfkey_sock_users)) {
|
|
+ DECLARE_WAITQUEUE(wait, current);
|
|
+
|
|
+ add_wait_queue_exclusive(&pfkey_sock_wait, &wait);
|
|
+ for(;;) {
|
|
+ set_current_state(TASK_UNINTERRUPTIBLE);
|
|
+ if (atomic_read(&pfkey_sock_users) == 0)
|
|
+ break;
|
|
+ write_unlock_bh(&pfkey_sock_lock);
|
|
+ schedule();
|
|
+ write_lock_bh(&pfkey_sock_lock);
|
|
+ }
|
|
+
|
|
+ __set_current_state(TASK_RUNNING);
|
|
+ remove_wait_queue(&pfkey_sock_wait, &wait);
|
|
+ }
|
|
+}
|
|
+
|
|
+static __inline__ void pfkey_sock_list_ungrab(void)
|
|
+{
|
|
+ write_unlock_bh(&pfkey_sock_lock);
|
|
+ wake_up(&pfkey_sock_wait);
|
|
+}
|
|
+
|
|
+static __inline__ void pfkey_lock_sock_list(void)
|
|
+{
|
|
+ /* read_lock() synchronizes us to pfkey_table_grab */
|
|
+
|
|
+ read_lock(&pfkey_sock_lock);
|
|
+ atomic_inc(&pfkey_sock_users);
|
|
+ read_unlock(&pfkey_sock_lock);
|
|
+}
|
|
+
|
|
+static __inline__ void pfkey_unlock_sock_list(void)
|
|
+{
|
|
+ if (atomic_dec_and_test(&pfkey_sock_users))
|
|
+ wake_up(&pfkey_sock_wait);
|
|
+}
|
|
+#endif
|
|
+
|
|
+int
|
|
+pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
|
|
+{
|
|
+ struct socket_list *socket_listp,*prev;
|
|
+
|
|
+ if(!socketp) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_remove_socket: "
|
|
+ "NULL socketp handed in, failed.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if(!sockets) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_remove_socket: "
|
|
+ "NULL sockets list handed in, failed.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ socket_listp = *sockets;
|
|
+ prev = NULL;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_remove_socket: "
|
|
+ "removing sock=0p%p\n",
|
|
+ socketp);
|
|
+
|
|
+ while(socket_listp != NULL) {
|
|
+ if(socket_listp->socketp == socketp) {
|
|
+ if(prev != NULL) {
|
|
+ prev->next = socket_listp->next;
|
|
+ } else {
|
|
+ *sockets = socket_listp->next;
|
|
+ }
|
|
+
|
|
+ kfree((void*)socket_listp);
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ prev = socket_listp;
|
|
+ socket_listp = socket_listp->next;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
|
|
+{
|
|
+ struct socket_list *socket_listp;
|
|
+
|
|
+ if(!socketp) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_insert_socket: "
|
|
+ "NULL socketp handed in, failed.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if(!sockets) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_insert_socket: "
|
|
+ "NULL sockets list handed in, failed.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_insert_socket: "
|
|
+ "allocating %lu bytes for socketp=0p%p\n",
|
|
+ (unsigned long) sizeof(struct socket_list),
|
|
+ socketp);
|
|
+
|
|
+ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_insert_socket: "
|
|
+ "memory allocation error.\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ socket_listp->socketp = socketp;
|
|
+ socket_listp->next = *sockets;
|
|
+ *sockets = socket_listp;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_list_remove_supported(struct ipsec_alg_supported *supported, struct supported_list **supported_list)
|
|
+{
|
|
+ struct supported_list *supported_listp = *supported_list, *prev = NULL;
|
|
+
|
|
+ if(!supported) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_remove_supported: "
|
|
+ "NULL supported handed in, failed.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if(!supported_list) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_remove_supported: "
|
|
+ "NULL supported_list handed in, failed.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_remove_supported: "
|
|
+ "removing supported=0p%p\n",
|
|
+ supported);
|
|
+
|
|
+ while(supported_listp != NULL) {
|
|
+ if(supported_listp->supportedp == supported) {
|
|
+ if(prev != NULL) {
|
|
+ prev->next = supported_listp->next;
|
|
+ } else {
|
|
+ *supported_list = supported_listp->next;
|
|
+ }
|
|
+
|
|
+ kfree((void*)supported_listp);
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ prev = supported_listp;
|
|
+ supported_listp = supported_listp->next;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_list_insert_supported(struct ipsec_alg_supported *supported
|
|
+ , struct supported_list **supported_list)
|
|
+{
|
|
+ struct supported_list *supported_listp;
|
|
+
|
|
+ if(!supported) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_insert_supported: "
|
|
+ "NULL supported handed in, failed.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if(!supported_list) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_insert_supported: "
|
|
+ "NULL supported_list handed in, failed.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_insert_supported: "
|
|
+ "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
|
|
+ (unsigned long) sizeof(struct supported_list),
|
|
+ supported,
|
|
+ supported_list);
|
|
+
|
|
+ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
|
|
+
|
|
+ if(supported_listp == NULL)
|
|
+ {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_insert_supported: "
|
|
+ "memory allocation error.\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ supported_listp->supportedp = supported;
|
|
+ supported_listp->next = *supported_list;
|
|
+ *supported_list = supported_listp;
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_list_insert_supported: "
|
|
+ "outgoing, supported=0p%p, supported_list=0p%p\n",
|
|
+ supported,
|
|
+ supported_list);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#ifdef NET_26
|
|
+DEBUG_NO_STATIC void
|
|
+pfkey_insert_socket(struct sock *sk)
|
|
+{
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_insert_socket: "
|
|
+ "sk=0p%p\n",
|
|
+ sk);
|
|
+ pfkey_sock_list_grab();
|
|
+ sk_add_node(sk, &pfkey_sock_list);
|
|
+ pfkey_sock_list_ungrab();
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC void
|
|
+pfkey_remove_socket(struct sock *sk)
|
|
+{
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_remove_socket: 0p%p\n", sk);
|
|
+ pfkey_sock_list_grab();
|
|
+ sk_del_node_init(sk);
|
|
+ pfkey_sock_list_ungrab();
|
|
+ return;
|
|
+}
|
|
+#else
|
|
+
|
|
+DEBUG_NO_STATIC void
|
|
+pfkey_insert_socket(struct sock *sk)
|
|
+{
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_insert_socket: "
|
|
+ "sk=0p%p\n",
|
|
+ sk);
|
|
+ cli();
|
|
+ sk->next=pfkey_sock_list;
|
|
+ pfkey_sock_list=sk;
|
|
+ sti();
|
|
+}
|
|
+DEBUG_NO_STATIC void
|
|
+pfkey_remove_socket(struct sock *sk)
|
|
+{
|
|
+ struct sock **s;
|
|
+
|
|
+ s = NULL;
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_remove_socket: .\n");
|
|
+
|
|
+ cli();
|
|
+ s=&pfkey_sock_list;
|
|
+
|
|
+ while(*s!=NULL) {
|
|
+ if(*s==sk) {
|
|
+ *s=sk->next;
|
|
+ sk->next=NULL;
|
|
+ sti();
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_remove_socket: "
|
|
+ "succeeded.\n");
|
|
+ return;
|
|
+ }
|
|
+ s=&((*s)->next);
|
|
+ }
|
|
+ sti();
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_remove_socket: "
|
|
+ "not found.\n");
|
|
+ return;
|
|
+}
|
|
+#endif
|
|
+
|
|
+DEBUG_NO_STATIC void
|
|
+pfkey_destroy_socket(struct sock *sk)
|
|
+{
|
|
+ struct sk_buff *skb;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_destroy_socket: 0p%p\n",sk);
|
|
+ pfkey_remove_socket(sk);
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_destroy_socket: "
|
|
+ "pfkey_remove_socket called, sk=0p%p\n",sk);
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_destroy_socket: "
|
|
+ "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
|
|
+ sk,
|
|
+ &(sk->sk_receive_queue),
|
|
+ sk->sk_receive_queue.next,
|
|
+ sk->sk_receive_queue.prev);
|
|
+
|
|
+ while(sk && ((skb=skb_dequeue(&(sk->sk_receive_queue)))!=NULL)) {
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_pfkey && sysctl_ipsec_debug_verbose) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_destroy_socket: "
|
|
+ "skb=0p%p dequeued.\n", skb);
|
|
+ printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
|
|
+ "pfkey_skb contents:");
|
|
+ printk(" next:0p%p", skb->next);
|
|
+ printk(" prev:0p%p", skb->prev);
|
|
+ printk(" sk:0p%p", skb->sk);
|
|
+ printk(" dev:0p%p", skb->dev);
|
|
+ if(skb->dev) {
|
|
+ if(skb->dev->name) {
|
|
+ printk(" dev->name:%s", skb->dev->name);
|
|
+ } else {
|
|
+ printk(" dev->name:NULL?");
|
|
+ }
|
|
+ } else {
|
|
+ printk(" dev:NULL");
|
|
+ }
|
|
+ printk(" h:0p%p", skb->h.raw);
|
|
+ printk(" nh:0p%p", skb->nh.raw);
|
|
+ printk(" mac:0p%p", skb->mac.raw);
|
|
+ printk(" dst:0p%p", skb->dst);
|
|
+ if(sysctl_ipsec_debug_verbose) {
|
|
+ int i;
|
|
+
|
|
+ printk(" cb");
|
|
+ for(i=0; i<48; i++) {
|
|
+ printk(":%2x", skb->cb[i]);
|
|
+ }
|
|
+ }
|
|
+ printk(" len:%d", skb->len);
|
|
+ printk(" csum:%d", skb->csum);
|
|
+#ifndef NETDEV_23
|
|
+ printk(" used:%d", skb->used);
|
|
+ printk(" is_clone:%d", skb->is_clone);
|
|
+#endif /* NETDEV_23 */
|
|
+ printk(" cloned:%d", skb->cloned);
|
|
+ printk(" pkt_type:%d", skb->pkt_type);
|
|
+ printk(" ip_summed:%d", skb->ip_summed);
|
|
+ printk(" priority:%d", skb->priority);
|
|
+ printk(" protocol:%d", skb->protocol);
|
|
+#ifdef HAVE_SOCK_SECURITY
|
|
+ printk(" security:%d", skb->security);
|
|
+#endif
|
|
+ printk(" truesize:%d", skb->truesize);
|
|
+ printk(" head:0p%p", skb->head);
|
|
+ printk(" data:0p%p", skb->data);
|
|
+ printk(" tail:0p%p", skb->tail);
|
|
+ printk(" end:0p%p", skb->end);
|
|
+ if(sysctl_ipsec_debug_verbose) {
|
|
+ unsigned char* i;
|
|
+ printk(" data");
|
|
+ for(i = skb->head; i < skb->end; i++) {
|
|
+ printk(":%2x", (unsigned char)(*(i)));
|
|
+ }
|
|
+ }
|
|
+ printk(" destructor:0p%p", skb->destructor);
|
|
+ printk("\n");
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_destroy_socket: "
|
|
+ "skb=0p%p freed.\n",
|
|
+ skb);
|
|
+ ipsec_kfree_skb(skb);
|
|
+ }
|
|
+
|
|
+#ifdef NET_26
|
|
+ sock_set_flag(sk, SOCK_DEAD);
|
|
+#else
|
|
+ sk->dead = 1;
|
|
+#endif
|
|
+ sk_free(sk);
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_destroy_socket: destroyed.\n");
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sk_buff * skb = NULL;
|
|
+ struct sock *sk;
|
|
+
|
|
+ if(sock == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_upmsg: "
|
|
+ "NULL socket passed in.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if(pfkey_msg == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_upmsg: "
|
|
+ "NULL pfkey_msg passed in.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ sk = sock->sk;
|
|
+
|
|
+ if(sk == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_upmsg: "
|
|
+ "NULL sock passed in.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_upmsg: "
|
|
+ "allocating %d bytes...\n",
|
|
+ (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
|
|
+ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_upmsg: "
|
|
+ "no buffers left to send up a message.\n");
|
|
+ return -ENOBUFS;
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_upmsg: "
|
|
+ "...allocated at 0p%p.\n",
|
|
+ skb);
|
|
+
|
|
+ skb->dev = NULL;
|
|
+
|
|
+ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
|
|
+ printk(KERN_WARNING "klips_error:pfkey_upmsg: "
|
|
+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
|
|
+ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
|
|
+ skb_tailroom(skb));
|
|
+ ipsec_kfree_skb(skb);
|
|
+ return -ENOBUFS;
|
|
+ }
|
|
+ skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
|
|
+ memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
|
|
+
|
|
+ if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
|
|
+ skb->sk=NULL;
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_upmsg: "
|
|
+ "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
|
|
+ error,
|
|
+ skb);
|
|
+ ipsec_kfree_skb(skb);
|
|
+ return error;
|
|
+ }
|
|
+ return error;
|
|
+}
|
|
+
|
|
+#ifdef NET_26_12_SKALLOC
|
|
+static struct proto key_proto = {
|
|
+ .name = "KEY",
|
|
+ .owner = THIS_MODULE,
|
|
+ .obj_size = sizeof(struct sock),
|
|
+
|
|
+};
|
|
+#endif
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_create(struct socket *sock, int protocol)
|
|
+{
|
|
+ struct sock *sk;
|
|
+
|
|
+ if(sock == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_create: "
|
|
+ "socket NULL.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_create: "
|
|
+ "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
|
|
+ sock,
|
|
+ sock->type,
|
|
+ (unsigned int)(sock->state),
|
|
+ sock->flags, protocol);
|
|
+
|
|
+ if(sock->type != SOCK_RAW) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_create: "
|
|
+ "only SOCK_RAW supported.\n");
|
|
+ return -ESOCKTNOSUPPORT;
|
|
+ }
|
|
+
|
|
+ if(protocol != PF_KEY_V2) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_create: "
|
|
+ "protocol not PF_KEY_V2.\n");
|
|
+ return -EPROTONOSUPPORT;
|
|
+ }
|
|
+
|
|
+ if((current->uid != 0)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_create: "
|
|
+ "must be root to open pfkey sockets.\n");
|
|
+ return -EACCES;
|
|
+ }
|
|
+
|
|
+ sock->state = SS_UNCONNECTED;
|
|
+
|
|
+ KLIPS_INC_USE;
|
|
+
|
|
+#ifdef NET_26
|
|
+#ifdef NET_26_12_SKALLOC
|
|
+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
|
|
+#else
|
|
+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);
|
|
+#endif
|
|
+#else
|
|
+ /* 2.4 interface */
|
|
+ sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1);
|
|
+#endif
|
|
+
|
|
+ if(sk == NULL)
|
|
+ {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_create: "
|
|
+ "Out of memory trying to allocate.\n");
|
|
+ KLIPS_DEC_USE;
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ sock_init_data(sock, sk);
|
|
+
|
|
+ sk->sk_destruct = NULL;
|
|
+ sk->sk_reuse = 1;
|
|
+ sock->ops = &pfkey_ops;
|
|
+
|
|
+ sk->sk_family = PF_KEY;
|
|
+/* sk->num = protocol; */
|
|
+ sk->sk_protocol = protocol;
|
|
+ key_pid(sk) = current->pid;
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_create: "
|
|
+ "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
|
|
+ sock->fasync_list,
|
|
+ sk->sk_sleep);
|
|
+
|
|
+ pfkey_insert_socket(sk);
|
|
+ pfkey_list_insert_socket(sock, &pfkey_open_sockets);
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_create: "
|
|
+ "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+#ifdef NETDEV_23
|
|
+pfkey_release(struct socket *sock)
|
|
+#else /* NETDEV_23 */
|
|
+pfkey_release(struct socket *sock, struct socket *peersock)
|
|
+#endif /* NETDEV_23 */
|
|
+{
|
|
+ struct sock *sk;
|
|
+ int i;
|
|
+
|
|
+ if(sock==NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_release: "
|
|
+ "No socket attached.\n");
|
|
+ return 0; /* -EINVAL; */
|
|
+ }
|
|
+
|
|
+ sk=sock->sk;
|
|
+
|
|
+ /* May not have data attached */
|
|
+ if(sk==NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_release: "
|
|
+ "No sk attached to sock=0p%p.\n", sock);
|
|
+ return 0; /* -EINVAL; */
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_release: "
|
|
+ "sock=0p%p sk=0p%p\n", sock, sk);
|
|
+
|
|
+ if(sock_flag(sk, SOCK_DEAD))
|
|
+ if(sk->sk_state_change) {
|
|
+ sk->sk_state_change(sk);
|
|
+ }
|
|
+
|
|
+ sock->sk = NULL;
|
|
+
|
|
+ /* Try to flush out this socket. Throw out buffers at least */
|
|
+ pfkey_destroy_socket(sk);
|
|
+ pfkey_list_remove_socket(sock, &pfkey_open_sockets);
|
|
+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
|
|
+ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
|
|
+ }
|
|
+
|
|
+ KLIPS_DEC_USE;
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_release: "
|
|
+ "succeeded.\n");
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_shutdown(struct socket *sock, int mode)
|
|
+{
|
|
+ struct sock *sk;
|
|
+
|
|
+ if(sock == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_shutdown: "
|
|
+ "NULL socket passed in.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ sk=sock->sk;
|
|
+
|
|
+ if(sk == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_shutdown: "
|
|
+ "No sock attached to socket.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_shutdown: "
|
|
+ "mode=%x.\n", mode);
|
|
+ mode++;
|
|
+
|
|
+ if(mode&SEND_SHUTDOWN) {
|
|
+ sk->sk_shutdown|=SEND_SHUTDOWN;
|
|
+ sk->sk_state_change(sk);
|
|
+ }
|
|
+
|
|
+ if(mode&RCV_SHUTDOWN) {
|
|
+ sk->sk_shutdown|=RCV_SHUTDOWN;
|
|
+ sk->sk_state_change(sk);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Send PF_KEY data down.
|
|
+ */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+#ifdef NET_26
|
|
+pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
|
|
+#else
|
|
+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
|
|
+#endif
|
|
+{
|
|
+ struct sock *sk;
|
|
+ int error = 0;
|
|
+ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
|
|
+
|
|
+ if(sock == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "Null socket passed in.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ sk = sock->sk;
|
|
+
|
|
+ if(sk == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "Null sock passed in.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(msg == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "Null msghdr passed in.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: .\n");
|
|
+ if(sk->sk_err) {
|
|
+ error = sock_error(sk);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "sk->err is non-zero, returns %d.\n",
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((current->uid != 0)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "must be root to send messages to pfkey sockets.\n");
|
|
+ SENDERR(EACCES);
|
|
+ }
|
|
+
|
|
+ if(msg->msg_control)
|
|
+ {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "can't set flags or set msg_control.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(sk->sk_shutdown & SEND_SHUTDOWN) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "shutdown.\n");
|
|
+ send_sig(SIGPIPE, current, 0);
|
|
+ SENDERR(EPIPE);
|
|
+ }
|
|
+
|
|
+ if(len < sizeof(struct sadb_msg)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "bogus msg len of %d, too small.\n", (int)len);
|
|
+ SENDERR(EMSGSIZE);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "allocating %d bytes for downward message.\n",
|
|
+ (int)len);
|
|
+ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "memory allocation error.\n");
|
|
+ SENDERR(ENOBUFS);
|
|
+ }
|
|
+
|
|
+ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
|
|
+
|
|
+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
|
|
+ KLIPS_PRINT(1 || debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
|
|
+ pfkey_msg->sadb_msg_version,
|
|
+ PF_KEY_V2);
|
|
+ kfree((void*)pfkey_msg);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "bogus msg len of %d, not %d byte aligned.\n",
|
|
+ (int)len, (int)IPSEC_PFKEYv2_ALIGN);
|
|
+ SENDERR(EMSGSIZE);
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ /* This check is questionable, since a downward message could be
|
|
+ the result of an ACQUIRE either from kernel (PID==0) or
|
|
+ userspace (some other PID). */
|
|
+ /* check PID */
|
|
+ if(pfkey_msg->sadb_msg_pid != current->pid) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "pid (%d) does not equal sending process pid (%d).\n",
|
|
+ pfkey_msg->sadb_msg_pid, current->pid);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if(pfkey_msg->sadb_msg_reserved) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "reserved field must be zero, set to %d.\n",
|
|
+ pfkey_msg->sadb_msg_reserved);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "msg type too large or small:%d.\n",
|
|
+ pfkey_msg->sadb_msg_type);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "msg sent for parsing.\n");
|
|
+
|
|
+ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
|
|
+ "pfkey_msg_parse returns %d.\n",
|
|
+ error);
|
|
+
|
|
+ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "memory allocation error.\n");
|
|
+ SENDERR(ENOBUFS);
|
|
+ }
|
|
+ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
|
|
+ pfkey_reply->sadb_msg_errno = -error;
|
|
+ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
|
|
+
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ int error_upmsg = 0;
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
|
|
+ "sending up error=%d message=0p%p to socket=0p%p.\n",
|
|
+ error,
|
|
+ pfkey_reply,
|
|
+ pfkey_socketsp->socketp);
|
|
+ if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
|
|
+ "sending up error message to socket=0p%p failed with error=%d.\n",
|
|
+ pfkey_socketsp->socketp,
|
|
+ error_upmsg);
|
|
+ /* pfkey_msg_free(&pfkey_reply); */
|
|
+ /* SENDERR(-error); */
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
|
|
+ "sending up error message to socket=0p%p succeeded.\n",
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_msg) {
|
|
+ kfree((void*)pfkey_msg);
|
|
+ }
|
|
+
|
|
+ if(error) {
|
|
+ return error;
|
|
+ } else {
|
|
+ return len;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Receive PF_KEY data up.
|
|
+ */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+#ifdef NET_26
|
|
+pfkey_recvmsg(struct kiocb *kiocb
|
|
+ , struct socket *sock
|
|
+ , struct msghdr *msg
|
|
+ , size_t size
|
|
+ , int flags)
|
|
+#else
|
|
+pfkey_recvmsg(struct socket *sock
|
|
+ , struct msghdr *msg
|
|
+ , int size, int flags
|
|
+ , struct scm_cookie *scm)
|
|
+#endif
|
|
+{
|
|
+ struct sock *sk;
|
|
+ int noblock = flags & MSG_DONTWAIT;
|
|
+ struct sk_buff *skb;
|
|
+ int error;
|
|
+
|
|
+ if(sock == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_recvmsg: "
|
|
+ "Null socket passed in.\n");
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ sk = sock->sk;
|
|
+
|
|
+ if(sk == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_recvmsg: "
|
|
+ "Null sock passed in for sock=0p%p.\n", sock);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if(msg == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_recvmsg: "
|
|
+ "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
|
|
+ sock, sk);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
|
|
+ sock, sk, msg, (int)size);
|
|
+ if(flags & ~MSG_PEEK) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "flags (%d) other than MSG_PEEK not supported.\n",
|
|
+ flags);
|
|
+ return -EOPNOTSUPP;
|
|
+ }
|
|
+
|
|
+ msg->msg_namelen = 0; /* sizeof(*ska); */
|
|
+
|
|
+ if(sk->sk_err) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sendmsg: "
|
|
+ "sk->sk_err=%d.\n", sk->sk_err);
|
|
+ return sock_error(sk);
|
|
+ }
|
|
+
|
|
+ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
|
|
+ return error;
|
|
+ }
|
|
+
|
|
+ if(size > skb->len) {
|
|
+ size = skb->len;
|
|
+ }
|
|
+ else if(size <skb->len) {
|
|
+ msg->msg_flags |= MSG_TRUNC;
|
|
+ }
|
|
+
|
|
+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
|
|
+#ifdef HAVE_TSTAMP
|
|
+ sk->sk_stamp.tv_sec = skb->tstamp.off_sec;
|
|
+ sk->sk_stamp.tv_usec = skb->tstamp.off_usec;
|
|
+#else
|
|
+ sk->sk_stamp=skb->stamp;
|
|
+#endif
|
|
+
|
|
+ skb_free_datagram(sk, skb);
|
|
+ return size;
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_PROC_FS
|
|
+#ifndef PROC_FS_2325
|
|
+DEBUG_NO_STATIC
|
|
+#endif /* PROC_FS_2325 */
|
|
+int
|
|
+pfkey_get_info(char *buffer, char **start, off_t offset, int length
|
|
+#ifndef PROC_NO_DUMMY
|
|
+, int dummy
|
|
+#endif /* !PROC_NO_DUMMY */
|
|
+)
|
|
+{
|
|
+ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
|
|
+#ifdef NET_26
|
|
+ struct hlist_node *node;
|
|
+#endif
|
|
+ off_t begin=0;
|
|
+ int len=0;
|
|
+ struct sock *sk;
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(!sysctl_ipsec_debug_verbose) {
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ len += ipsec_snprintf(buffer, length,
|
|
+ " sock pid socket next prev e n p sndbf Flags Type St\n");
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ } else {
|
|
+ len += ipsec_snprintf(buffer, length,
|
|
+ " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ sk_for_each(sk, node, &pfkey_sock_list) {
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(!sysctl_ipsec_debug_verbose) {
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ len += ipsec_snprintf(buffer+len, length-len,
|
|
+ "%8p %5d %8p %d %d %5d %08lX %8X %2X\n",
|
|
+ sk,
|
|
+ key_pid(sk),
|
|
+ sk->sk_socket,
|
|
+ sk->sk_err,
|
|
+ sk->sk_protocol,
|
|
+ sk->sk_sndbuf,
|
|
+ sk->sk_socket->flags,
|
|
+ sk->sk_socket->type,
|
|
+ sk->sk_socket->state);
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ } else {
|
|
+ len += ipsec_snprintf(buffer+len, length-len,
|
|
+ "%8p %5d %d %8p %8p %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
|
|
+ sk,
|
|
+ key_pid(sk),
|
|
+ sock_flag(sk, SOCK_DEAD),
|
|
+ sk->sk_sleep,
|
|
+ sk->sk_socket,
|
|
+ sk->sk_err,
|
|
+ sk->sk_reuse,
|
|
+#ifdef HAVE_SOCK_ZAPPED
|
|
+ sock_flag(sk, SOCK_ZAPPED),
|
|
+#else
|
|
+ sk->sk_zapped,
|
|
+#endif
|
|
+ sk->sk_protocol,
|
|
+ sk->sk_sndbuf,
|
|
+ (unsigned int)sk->sk_stamp.tv_sec,
|
|
+ (unsigned int)sk->sk_stamp.tv_usec,
|
|
+ sk->sk_socket->flags,
|
|
+ sk->sk_socket->type,
|
|
+ sk->sk_socket->state);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ if (len >= max_content) {
|
|
+ /* we've done all that can fit -- stop loop */
|
|
+ len = max_content; /* truncate crap */
|
|
+ break;
|
|
+ } else {
|
|
+ const off_t pos = begin + len; /* file position of end of what we've generated */
|
|
+
|
|
+ if (pos <= offset) {
|
|
+ /* all is before first interesting character:
|
|
+ * discard, but note where we are.
|
|
+ */
|
|
+ len = 0;
|
|
+ begin = pos;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ return len - (offset - begin);
|
|
+}
|
|
+
|
|
+#ifndef PROC_FS_2325
|
|
+DEBUG_NO_STATIC
|
|
+#endif /* PROC_FS_2325 */
|
|
+int
|
|
+pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
|
|
+#ifndef PROC_NO_DUMMY
|
|
+, int dummy
|
|
+#endif /* !PROC_NO_DUMMY */
|
|
+)
|
|
+{
|
|
+ /* limit of useful snprintf output */
|
|
+ const int max_content = length > 0? length-1 : 0;
|
|
+ off_t begin=0;
|
|
+ int len=0;
|
|
+ int satype;
|
|
+ struct supported_list *ps;
|
|
+
|
|
+ len += ipsec_snprintf(buffer, length,
|
|
+ "satype exttype alg_id ivlen minbits maxbits name\n");
|
|
+
|
|
+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
|
|
+ ps = pfkey_supported_list[satype];
|
|
+ while(ps) {
|
|
+ struct ipsec_alg_supported *alg = ps->supportedp;
|
|
+ unsigned char *n = alg->ias_name;
|
|
+ if(n == NULL) n = "unknown";
|
|
+
|
|
+ len += ipsec_snprintf(buffer+len, length-len,
|
|
+ " %2d %2d %2d %3d %3d %3d %20s\n",
|
|
+ satype,
|
|
+ alg->ias_exttype,
|
|
+ alg->ias_id,
|
|
+ alg->ias_ivlen,
|
|
+ alg->ias_keyminbits,
|
|
+ alg->ias_keymaxbits,
|
|
+ n);
|
|
+
|
|
+ if (len >= max_content) {
|
|
+ /* we've done all that can fit -- stop loop */
|
|
+ len = max_content; /* truncate crap */
|
|
+ break;
|
|
+ } else {
|
|
+ const off_t pos = begin + len; /* file position of end of what we've generated */
|
|
+
|
|
+ if (pos <= offset) {
|
|
+ /* all is before first interesting character:
|
|
+ * discard, but note where we are.
|
|
+ */
|
|
+ len = 0;
|
|
+ begin = pos;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ps = ps->next;
|
|
+ }
|
|
+ }
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ return len - (offset - begin);
|
|
+}
|
|
+
|
|
+#ifndef PROC_FS_2325
|
|
+DEBUG_NO_STATIC
|
|
+#endif /* PROC_FS_2325 */
|
|
+int
|
|
+pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
|
|
+#ifndef PROC_NO_DUMMY
|
|
+, int dummy
|
|
+#endif /* !PROC_NO_DUMMY */
|
|
+)
|
|
+{
|
|
+ const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
|
|
+ off_t begin=0;
|
|
+ int len=0;
|
|
+ int satype;
|
|
+ struct socket_list *pfkey_sockets;
|
|
+
|
|
+ len += ipsec_snprintf(buffer, length,
|
|
+ "satype socket pid sk\n");
|
|
+
|
|
+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
|
|
+ pfkey_sockets = pfkey_registered_sockets[satype];
|
|
+ while(pfkey_sockets) {
|
|
+ len += ipsec_snprintf(buffer+len, length-len,
|
|
+ " %2d %8p %5d %8p\n",
|
|
+ satype,
|
|
+ pfkey_sockets->socketp,
|
|
+ key_pid(pfkey_sockets->socketp->sk),
|
|
+ pfkey_sockets->socketp->sk);
|
|
+
|
|
+ if (len >= max_content) {
|
|
+ /* we've done all that can fit -- stop loop (could stop two) */
|
|
+ len = max_content; /* truncate crap */
|
|
+ break;
|
|
+ } else {
|
|
+ const off_t pos = begin + len; /* file position of end of what we've generated */
|
|
+
|
|
+ if (pos <= offset) {
|
|
+ /* all is before first interesting character:
|
|
+ * discard, but note where we are.
|
|
+ */
|
|
+ len = 0;
|
|
+ begin = pos;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pfkey_sockets = pfkey_sockets->next;
|
|
+ }
|
|
+ }
|
|
+ *start = buffer + (offset - begin); /* Start of wanted data */
|
|
+ return len - (offset - begin);
|
|
+}
|
|
+
|
|
+#ifndef PROC_FS_2325
|
|
+struct proc_dir_entry proc_net_pfkey =
|
|
+{
|
|
+ 0,
|
|
+ 6, "pf_key",
|
|
+ S_IFREG | S_IRUGO, 1, 0, 0,
|
|
+ 0, &proc_net_inode_operations,
|
|
+ pfkey_get_info
|
|
+};
|
|
+struct proc_dir_entry proc_net_pfkey_supported =
|
|
+{
|
|
+ 0,
|
|
+ 16, "pf_key_supported",
|
|
+ S_IFREG | S_IRUGO, 1, 0, 0,
|
|
+ 0, &proc_net_inode_operations,
|
|
+ pfkey_supported_get_info
|
|
+};
|
|
+struct proc_dir_entry proc_net_pfkey_registered =
|
|
+{
|
|
+ 0,
|
|
+ 17, "pf_key_registered",
|
|
+ S_IFREG | S_IRUGO, 1, 0, 0,
|
|
+ 0, &proc_net_inode_operations,
|
|
+ pfkey_registered_get_info
|
|
+};
|
|
+#endif /* !PROC_FS_2325 */
|
|
+#endif /* CONFIG_PROC_FS */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+supported_add_all(int satype, struct ipsec_alg_supported supported[], int size)
|
|
+{
|
|
+ int i;
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:init_pfkey: "
|
|
+ "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct ipsec_alg_supported)[%d]=%d.\n",
|
|
+ satype,
|
|
+ size,
|
|
+ (int)sizeof(struct ipsec_alg_supported),
|
|
+ (int)(size/sizeof(struct ipsec_alg_supported)));
|
|
+
|
|
+ for(i = 0; i < size / sizeof(struct ipsec_alg_supported); i++) {
|
|
+
|
|
+ unsigned char *n = supported[i].ias_name;
|
|
+ if(n == NULL) n="unknown";
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:init_pfkey: "
|
|
+ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
|
|
+ i,
|
|
+ satype,
|
|
+ supported[i].ias_exttype,
|
|
+ supported[i].ias_id,
|
|
+ supported[i].ias_ivlen,
|
|
+ supported[i].ias_keyminbits,
|
|
+ supported[i].ias_keymaxbits,
|
|
+ n);
|
|
+
|
|
+ error |= pfkey_list_insert_supported(&(supported[i]),
|
|
+ &(pfkey_supported_list[satype]));
|
|
+ }
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+supported_remove_all(int satype)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct ipsec_alg_supported*supportedp;
|
|
+
|
|
+ while(pfkey_supported_list[satype]) {
|
|
+ unsigned char *n;
|
|
+ supportedp = pfkey_supported_list[satype]->supportedp;
|
|
+
|
|
+ n = supportedp->ias_name;
|
|
+ if(n == NULL) n="unknown";
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:init_pfkey: "
|
|
+ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
|
|
+ satype,
|
|
+ supportedp->ias_exttype,
|
|
+ supportedp->ias_id,
|
|
+ supportedp->ias_ivlen,
|
|
+ supportedp->ias_keyminbits,
|
|
+ supportedp->ias_keymaxbits, n);
|
|
+
|
|
+ error |= pfkey_list_remove_supported(supportedp,
|
|
+ &(pfkey_supported_list[satype]));
|
|
+ }
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_init(void)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+
|
|
+ static struct ipsec_alg_supported supported_init_ah[] = {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+ };
|
|
+ static struct ipsec_alg_supported supported_init_esp[] = {
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
|
|
+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
|
|
+#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
|
|
+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
|
|
+#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
|
|
+#ifdef CONFIG_KLIPS_ENC_3DES
|
|
+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168},
|
|
+#endif /* CONFIG_KLIPS_ENC_3DES */
|
|
+ };
|
|
+ static struct ipsec_alg_supported supported_init_ipip[] = {
|
|
+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
|
|
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
|
|
+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
|
|
+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
|
|
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
|
|
+ };
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ static struct ipsec_alg_supported supported_init_ipcomp[] = {
|
|
+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
|
|
+ };
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#if 0
|
|
+ printk(KERN_INFO
|
|
+ "klips_info:pfkey_init: "
|
|
+ "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
|
|
+#endif
|
|
+
|
|
+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
|
|
+ pfkey_registered_sockets[i] = NULL;
|
|
+ pfkey_supported_list[i] = NULL;
|
|
+ }
|
|
+
|
|
+ error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
|
|
+ error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
|
|
+
|
|
+ error |= sock_register(&pfkey_family_ops);
|
|
+
|
|
+#ifdef CONFIG_PROC_FS
|
|
+# ifndef PROC_FS_2325
|
|
+# ifdef PROC_FS_21
|
|
+ error |= proc_register(proc_net, &proc_net_pfkey);
|
|
+ error |= proc_register(proc_net, &proc_net_pfkey_supported);
|
|
+ error |= proc_register(proc_net, &proc_net_pfkey_registered);
|
|
+# else /* PROC_FS_21 */
|
|
+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
|
|
+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
|
|
+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
|
|
+# endif /* PROC_FS_21 */
|
|
+# else /* !PROC_FS_2325 */
|
|
+ proc_net_create ("pf_key", 0, pfkey_get_info);
|
|
+ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
|
|
+ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
|
|
+# endif /* !PROC_FS_2325 */
|
|
+#endif /* CONFIG_PROC_FS */
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_cleanup(void)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ printk(KERN_INFO "klips_info:pfkey_cleanup: "
|
|
+ "shutting down PF_KEY domain sockets.\n");
|
|
+ sock_unregister(PF_KEY);
|
|
+
|
|
+ error |= supported_remove_all(SADB_SATYPE_AH);
|
|
+ error |= supported_remove_all(SADB_SATYPE_ESP);
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ error |= supported_remove_all(SADB_X_SATYPE_COMP);
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ error |= supported_remove_all(SADB_X_SATYPE_IPIP);
|
|
+
|
|
+#ifdef CONFIG_PROC_FS
|
|
+# ifndef PROC_FS_2325
|
|
+ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
|
|
+ printk("klips_debug:pfkey_cleanup: "
|
|
+ "cannot unregister /proc/net/pf_key\n");
|
|
+ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
|
|
+ printk("klips_debug:pfkey_cleanup: "
|
|
+ "cannot unregister /proc/net/pf_key_supported\n");
|
|
+ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
|
|
+ printk("klips_debug:pfkey_cleanup: "
|
|
+ "cannot unregister /proc/net/pf_key_registered\n");
|
|
+# else /* !PROC_FS_2325 */
|
|
+ proc_net_remove ("pf_key");
|
|
+ proc_net_remove ("pf_key_supported");
|
|
+ proc_net_remove ("pf_key_registered");
|
|
+# endif /* !PROC_FS_2325 */
|
|
+#endif /* CONFIG_PROC_FS */
|
|
+
|
|
+ /* other module unloading cleanup happens here */
|
|
+ return error;
|
|
+}
|
|
+
|
|
+#ifdef MODULE
|
|
+#if 0
|
|
+int
|
|
+init_module(void)
|
|
+{
|
|
+ pfkey_init();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void
|
|
+cleanup_module(void)
|
|
+{
|
|
+ pfkey_cleanup();
|
|
+}
|
|
+#endif /* 0 */
|
|
+#else /* MODULE */
|
|
+struct net_protocol;
|
|
+void pfkey_proto_init(struct net_protocol *pro)
|
|
+{
|
|
+ pfkey_init();
|
|
+}
|
|
+#endif /* MODULE */
|
|
+
|
|
+/*
|
|
+ * $Log: pfkey_v2.c,v $
|
|
+ * Revision 1.97.2.12 2006/11/24 05:43:29 paul
|
|
+ * kernels after 2.6.18 do not return a code from unregister_socket()
|
|
+ * backport from git 41e54a2684dc809d7952e816860ea646a3194a72
|
|
+ *
|
|
+ * Revision 1.97.2.11 2006/11/15 16:05:57 paul
|
|
+ * fix for compiling on 2.4. kernels by Matthias Haas.
|
|
+ *
|
|
+ * Revision 1.97.2.10 2006/10/10 20:43:28 paul
|
|
+ * Add family/create/owner for pfkey_family_ops. This fixes bug #671
|
|
+ *
|
|
+ * Revision 1.97.2.9 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.97.2.8 2006/07/10 15:56:11 paul
|
|
+ * Fix for bug #642 by Bart.
|
|
+ *
|
|
+ * Revision 1.97.2.7 2006/04/04 11:34:19 ken
|
|
+ * Backport SMP fixes + #ifdef cleanup from #public
|
|
+ *
|
|
+ * Revision 1.97.2.6 2006/02/15 05:00:20 paul
|
|
+ * Fix for crasher on 2.6.12+ with klips (mostly seen on redhat kernels)
|
|
+ *
|
|
+ * Revision 1.97.2.5 2005/11/22 04:11:52 ken
|
|
+ * Backport fixes for 2.6.14 kernels from HEAD
|
|
+ *
|
|
+ * Revision 1.97.2.4 2005/09/14 16:40:45 mcr
|
|
+ * pull up of compilation on 2.4
|
|
+ *
|
|
+ * Revision 1.97.2.3 2005/09/06 02:10:03 mcr
|
|
+ * pulled up possible SMP-related compilation fix
|
|
+ *
|
|
+ * Revision 1.97.2.2 2005/08/28 01:21:12 paul
|
|
+ * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on
|
|
+ * SMP kernels.
|
|
+ *
|
|
+ * Revision 1.97.2.1 2005/08/27 23:40:00 paul
|
|
+ * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
|
|
+ *
|
|
+ * Revision 1.102 2005/09/14 16:37:23 mcr
|
|
+ * fix to compile on 2.4.
|
|
+ *
|
|
+ * Revision 1.101 2005/09/06 01:42:25 mcr
|
|
+ * removed additional SOCKOPS_WRAPPED code
|
|
+ *
|
|
+ * Revision 1.100 2005/08/30 18:10:15 mcr
|
|
+ * remove SOCKOPS_WRAPPED() code, add proper locking to the
|
|
+ * pfkey code. (cross fingers)
|
|
+ *
|
|
+ * Revision 1.99 2005/08/28 01:53:37 paul
|
|
+ * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on SMP kernels.
|
|
+ *
|
|
+ * Revision 1.98 2005/08/27 23:07:21 paul
|
|
+ * Somewhere between 2.6.12 and 2.6.13rc7 the unused security memnber in sk_buff
|
|
+ * has been removed. This patch should fix compilation for both cases.
|
|
+ *
|
|
+ * Revision 1.97 2005/07/20 00:33:36 mcr
|
|
+ * fixed typo in #ifdef for SKALLOC.
|
|
+ *
|
|
+ * Revision 1.96 2005/07/19 20:02:15 mcr
|
|
+ * sk_alloc() interface change.
|
|
+ *
|
|
+ * Revision 1.95 2005/07/09 00:40:06 ken
|
|
+ * Fix for GCC4 - it doesn't like the potential for duplicate declaration
|
|
+ *
|
|
+ * Revision 1.94 2005/07/09 00:14:04 ken
|
|
+ * Casts for 64bit cleanliness
|
|
+ *
|
|
+ * Revision 1.93 2005/07/08 16:20:05 mcr
|
|
+ * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
|
|
+ *
|
|
+ * Revision 1.92 2005/05/21 03:29:39 mcr
|
|
+ * fixed missing prototype definition.
|
|
+ *
|
|
+ * Revision 1.91 2005/05/11 01:43:45 mcr
|
|
+ * removed "poor-man"s OOP in favour of proper C structures.
|
|
+ *
|
|
+ * Revision 1.90 2005/05/02 18:42:47 mcr
|
|
+ * fix for cut&paste error with pfkey_v2.c "supported_name"
|
|
+ *
|
|
+ * Revision 1.89 2005/05/01 03:12:31 mcr
|
|
+ * print name if it is available.
|
|
+ *
|
|
+ * Revision 1.88 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.87 2005/04/15 19:57:10 mcr
|
|
+ * make sure that address has 0p so that it will
|
|
+ * sanitized.
|
|
+ *
|
|
+ * Revision 1.86 2005/04/08 18:28:36 mcr
|
|
+ * some minor #ifdef simplification in pursuit of a possible bug.
|
|
+ *
|
|
+ * Revision 1.85 2004/12/03 21:25:57 mcr
|
|
+ * compile time fixes for running on 2.6.
|
|
+ * still experimental.
|
|
+ *
|
|
+ * Revision 1.84 2004/08/17 03:27:23 mcr
|
|
+ * klips 2.6 edits.
|
|
+ *
|
|
+ * Revision 1.83 2004/08/04 15:57:07 mcr
|
|
+ * moved des .h files to include/des/ *
|
|
+ * included 2.6 protocol specific things
|
|
+ * started at NAT-T support, but it will require a kernel patch.
|
|
+ *
|
|
+ * Revision 1.82 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.81 2004/04/25 21:23:11 ken
|
|
+ * Pull in dhr's changes from FreeS/WAN 2.06
|
|
+ *
|
|
+ * Revision 1.80 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.79.4.1 2003/12/22 15:25:52 jjo
|
|
+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.79 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.78.4.1 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.78 2003/04/03 17:38:09 rgb
|
|
+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
|
|
+ *
|
|
+ * Revision 1.77 2002/10/17 16:49:36 mcr
|
|
+ * sock->ops should reference the unwrapped options so that
|
|
+ * we get hacked in locking on SMP systems.
|
|
+ *
|
|
+ * Revision 1.76 2002/10/12 23:11:53 dhr
|
|
+ *
|
|
+ * [KenB + DHR] more 64-bit cleanup
|
|
+ *
|
|
+ * Revision 1.75 2002/09/20 05:01:57 rgb
|
|
+ * Added memory allocation debugging.
|
|
+ *
|
|
+ * Revision 1.74 2002/09/19 02:42:50 mcr
|
|
+ * do not define the pfkey_ops function for now.
|
|
+ *
|
|
+ * Revision 1.73 2002/09/17 17:29:23 mcr
|
|
+ * #if 0 out some dead code - pfkey_ops is never used as written.
|
|
+ *
|
|
+ * Revision 1.72 2002/07/24 18:44:54 rgb
|
|
+ * Type fiddling to tame ia64 compiler.
|
|
+ *
|
|
+ * Revision 1.71 2002/05/23 07:14:11 rgb
|
|
+ * Cleaned up %p variants to 0p%p for test suite cleanup.
|
|
+ *
|
|
+ * Revision 1.70 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.69 2002/04/24 07:36:33 mcr
|
|
+ * Moved from ./klips/net/ipsec/pfkey_v2.c,v
|
|
+ *
|
|
+ * Revision 1.68 2002/03/08 01:15:17 mcr
|
|
+ * put some internal structure only debug messages behind
|
|
+ * && sysctl_ipsec_debug_verbose.
|
|
+ *
|
|
+ * Revision 1.67 2002/01/29 17:17:57 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.66 2002/01/29 04:00:54 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.65 2002/01/29 02:13:18 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.64 2001/11/26 09:23:51 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.61.2.1 2001/09/25 02:28:44 mcr
|
|
+ * cleaned up includes.
|
|
+ *
|
|
+ * Revision 1.63 2001/11/12 19:38:00 rgb
|
|
+ * Continue trying other sockets even if one fails and return only original
|
|
+ * error.
|
|
+ *
|
|
+ * Revision 1.62 2001/10/18 04:45:22 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/freeswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.61 2001/09/20 15:32:59 rgb
|
|
+ * Min/max cleanup.
|
|
+ *
|
|
+ * Revision 1.60 2001/06/14 19:35:12 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.59 2001/06/13 15:35:48 rgb
|
|
+ * Fixed #endif comments.
|
|
+ *
|
|
+ * Revision 1.58 2001/05/04 16:37:24 rgb
|
|
+ * Remove erroneous checking of return codes for proc_net_* in 2.4.
|
|
+ *
|
|
+ * Revision 1.57 2001/05/03 19:43:36 rgb
|
|
+ * Initialise error return variable.
|
|
+ * Check error return codes in startup and shutdown.
|
|
+ * Standardise on SENDERR() macro.
|
|
+ *
|
|
+ * Revision 1.56 2001/04/21 23:05:07 rgb
|
|
+ * Define out skb->used for 2.4 kernels.
|
|
+ *
|
|
+ * Revision 1.55 2001/02/28 05:03:28 rgb
|
|
+ * Clean up and rationalise startup messages.
|
|
+ *
|
|
+ * Revision 1.54 2001/02/27 22:24:55 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.53 2001/02/27 06:48:18 rgb
|
|
+ * Fixed pfkey socket unregister log message to reflect type and function.
|
|
+ *
|
|
+ * Revision 1.52 2001/02/26 22:34:38 rgb
|
|
+ * Fix error return code that was getting overwritten by the error return
|
|
+ * code of an upmsg.
|
|
+ *
|
|
+ * Revision 1.51 2001/01/30 23:42:47 rgb
|
|
+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
|
|
+ * and subsequent ADD or UDATE.
|
|
+ *
|
|
+ * Revision 1.50 2001/01/23 20:22:59 rgb
|
|
+ * 2.4 fix to remove removed is_clone member.
|
|
+ *
|
|
+ * Revision 1.49 2000/11/06 04:33:47 rgb
|
|
+ * Changed non-exported functions to DEBUG_NO_STATIC.
|
|
+ *
|
|
+ * Revision 1.48 2000/09/29 19:47:41 rgb
|
|
+ * Update copyright.
|
|
+ *
|
|
+ * Revision 1.47 2000/09/22 04:23:04 rgb
|
|
+ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
|
|
+ *
|
|
+ * Revision 1.46 2000/09/21 04:20:44 rgb
|
|
+ * Fixed array size off-by-one error. (Thanks Svenning!)
|
|
+ *
|
|
+ * Revision 1.45 2000/09/20 04:01:26 rgb
|
|
+ * Changed static functions to DEBUG_NO_STATIC for revealing function names
|
|
+ * in oopsen.
|
|
+ *
|
|
+ * Revision 1.44 2000/09/19 00:33:17 rgb
|
|
+ * 2.0 fixes.
|
|
+ *
|
|
+ * Revision 1.43 2000/09/16 01:28:13 rgb
|
|
+ * Fixed use of 0 in p format warning.
|
|
+ *
|
|
+ * Revision 1.42 2000/09/16 01:09:41 rgb
|
|
+ * Fixed debug format warning for pointers that was expecting ints.
|
|
+ *
|
|
+ * Revision 1.41 2000/09/13 15:54:00 rgb
|
|
+ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
|
|
+ * Moved supported algos add and remove to functions.
|
|
+ *
|
|
+ * Revision 1.40 2000/09/12 18:49:28 rgb
|
|
+ * Added IPIP tunnel and IPCOMP register support.
|
|
+ *
|
|
+ * Revision 1.39 2000/09/12 03:23:49 rgb
|
|
+ * Converted #if0 debugs to sysctl.
|
|
+ * Removed debug_pfkey initialisations that prevented no_debug loading or
|
|
+ * linking.
|
|
+ *
|
|
+ * Revision 1.38 2000/09/09 06:38:02 rgb
|
|
+ * Return positive errno in pfkey_reply error message.
|
|
+ *
|
|
+ * Revision 1.37 2000/09/08 19:19:09 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ * Clean-up of long-unused crud...
|
|
+ * Create pfkey error message on on failure.
|
|
+ * Give pfkey_list_{insert,remove}_{socket,supported}() some error
|
|
+ * checking.
|
|
+ *
|
|
+ * Revision 1.36 2000/09/01 18:49:38 rgb
|
|
+ * Reap experimental NET_21_ bits.
|
|
+ * Turned registered sockets list into an array of one list per satype.
|
|
+ * Remove references to deprecated sklist_{insert,remove}_socket.
|
|
+ * Removed leaking socket debugging code.
|
|
+ * Removed duplicate pfkey_insert_socket in pfkey_create.
|
|
+ * Removed all references to pfkey msg->msg_name, since it is not used for
|
|
+ * pfkey.
|
|
+ * Added a supported algorithms array lists, one per satype and registered
|
|
+ * existing algorithms.
|
|
+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
|
|
+ * list.
|
|
+ * Only send pfkey_expire() messages to sockets registered for that satype.
|
|
+ *
|
|
+ * Revision 1.35 2000/08/24 17:03:00 rgb
|
|
+ * Corrected message size error return code for PF_KEYv2.
|
|
+ * Removed downward error prohibition.
|
|
+ *
|
|
+ * Revision 1.34 2000/08/21 16:32:26 rgb
|
|
+ * Re-formatted for cosmetic consistency and readability.
|
|
+ *
|
|
+ * Revision 1.33 2000/08/20 21:38:24 rgb
|
|
+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
|
|
+ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
|
|
+ *
|
|
+ * Revision 1.32 2000/07/28 14:58:31 rgb
|
|
+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
|
|
+ *
|
|
+ * Revision 1.31 2000/05/16 03:04:00 rgb
|
|
+ * Updates for 2.3.99pre8 from MB.
|
|
+ *
|
|
+ * Revision 1.30 2000/05/10 19:22:21 rgb
|
|
+ * Use sklist private functions for 2.3.xx compatibility.
|
|
+ *
|
|
+ * Revision 1.29 2000/03/22 16:17:03 rgb
|
|
+ * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
|
|
+ *
|
|
+ * Revision 1.28 2000/02/21 19:30:45 rgb
|
|
+ * Removed references to pkt_bridged for 2.3.47 compatibility.
|
|
+ *
|
|
+ * Revision 1.27 2000/02/14 21:07:00 rgb
|
|
+ * Fixed /proc/net/pf-key legend spacing.
|
|
+ *
|
|
+ * Revision 1.26 2000/01/22 03:46:59 rgb
|
|
+ * Fixed pfkey error return mechanism so that we are able to free the
|
|
+ * local copy of the pfkey_msg, plugging a memory leak and silencing
|
|
+ * the bad object free complaints.
|
|
+ *
|
|
+ * Revision 1.25 2000/01/21 06:19:44 rgb
|
|
+ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
|
|
+ * Added debugging to pfkey_upmsg.
|
|
+ *
|
|
+ * Revision 1.24 2000/01/10 16:38:23 rgb
|
|
+ * MB fixups for 2.3.x.
|
|
+ *
|
|
+ * Revision 1.23 1999/12/09 23:22:16 rgb
|
|
+ * Added more instrumentation for debugging 2.0 socket
|
|
+ * selection/reading.
|
|
+ * Removed erroneous 2.0 wait==NULL check bug in select.
|
|
+ *
|
|
+ * Revision 1.22 1999/12/08 20:32:16 rgb
|
|
+ * Tidied up 2.0.xx support, after major pfkey work, eliminating
|
|
+ * msg->msg_name twiddling in the process, since it is not defined
|
|
+ * for PF_KEYv2.
|
|
+ *
|
|
+ * Revision 1.21 1999/12/01 22:17:19 rgb
|
|
+ * Set skb->dev to zero on new skb in case it is a reused skb.
|
|
+ * Added check for skb_put overflow and freeing to avoid upmsg on error.
|
|
+ * Added check for wrong pfkey version and freeing to avoid upmsg on
|
|
+ * error.
|
|
+ * Shut off content dumping in pfkey_destroy.
|
|
+ * Added debugging message for size of buffer allocated for upmsg.
|
|
+ *
|
|
+ * Revision 1.20 1999/11/27 12:11:00 rgb
|
|
+ * Minor clean-up, enabling quiet operation of pfkey if desired.
|
|
+ *
|
|
+ * Revision 1.19 1999/11/25 19:04:21 rgb
|
|
+ * Update proc_fs code for pfkey to use dynamic registration.
|
|
+ *
|
|
+ * Revision 1.18 1999/11/25 09:07:17 rgb
|
|
+ * Implemented SENDERR macro for propagating error codes.
|
|
+ * Fixed error return code bug.
|
|
+ *
|
|
+ * Revision 1.17 1999/11/23 23:07:20 rgb
|
|
+ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
|
|
+ * parses. (PJO)
|
|
+ * Sort out pfkey and freeswan headers, putting them in a library path.
|
|
+ *
|
|
+ * Revision 1.16 1999/11/20 22:00:22 rgb
|
|
+ * Moved socketlist type declarations and prototypes for shared use.
|
|
+ * Renamed reformatted and generically extended for use by other socket
|
|
+ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
|
|
+ *
|
|
+ * Revision 1.15 1999/11/18 04:15:09 rgb
|
|
+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
|
|
+ * Clean up pfkey_destroy_socket() debugging statements.
|
|
+ * Add Peter Onion's code to send messages up to all listening sockets.
|
|
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
|
|
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
|
|
+ * klips/net/ipsec/Makefile.
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
|
|
+ *
|
|
+ * Revision 1.14 1999/11/17 16:01:00 rgb
|
|
+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
|
|
+ * Clean up pfkey_destroy_socket() debugging statements.
|
|
+ * Add Peter Onion's code to send messages up to all listening sockets.
|
|
+ * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
|
|
+ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
|
|
+ *
|
|
+ * Revision 1.13 1999/10/27 19:59:51 rgb
|
|
+ * Removed af_unix comments that are no longer relevant.
|
|
+ * Added debug prink statements.
|
|
+ * Added to the /proc output in pfkey_get_info.
|
|
+ * Made most functions non-static to enable oops tracing.
|
|
+ * Re-enable skb dequeueing and freeing.
|
|
+ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
|
|
+ *
|
|
+ * Revision 1.12 1999/10/26 17:05:42 rgb
|
|
+ * Complete re-ordering based on proto_ops structure order.
|
|
+ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
|
|
+ * Simplification to use built-in socket ops where possible for 2.2.x.
|
|
+ * Add shorter macros for compiler directives to visually clean-up.
|
|
+ * Add lots of sk skb dequeueing debugging statements.
|
|
+ * Added to the /proc output in pfkey_get_info.
|
|
+ *
|
|
+ * Revision 1.11 1999/09/30 02:55:10 rgb
|
|
+ * Bogus skb detection.
|
|
+ * Fix incorrect /proc/net/ipsec-eroute printk message.
|
|
+ *
|
|
+ * Revision 1.10 1999/09/21 15:22:13 rgb
|
|
+ * Temporary fix while I figure out the right way to destroy sockets.
|
|
+ *
|
|
+ * Revision 1.9 1999/07/08 19:19:44 rgb
|
|
+ * Fix pointer format warning.
|
|
+ * Fix missing member error under 2.0.xx kernels.
|
|
+ *
|
|
+ * Revision 1.8 1999/06/13 07:24:04 rgb
|
|
+ * Add more debugging.
|
|
+ *
|
|
+ * Revision 1.7 1999/06/10 05:24:17 rgb
|
|
+ * Clarified compiler directives.
|
|
+ * Renamed variables to reduce confusion.
|
|
+ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
|
|
+ * Added lots of sanity checking.
|
|
+ *
|
|
+ * Revision 1.6 1999/06/03 18:59:50 rgb
|
|
+ * More updates to 2.2.x socket support. Almost works, oops at end of call.
|
|
+ *
|
|
+ * Revision 1.5 1999/05/25 22:44:05 rgb
|
|
+ * Start fixing 2.2 sockets.
|
|
+ *
|
|
+ * Revision 1.4 1999/04/29 15:21:34 rgb
|
|
+ * Move log to the end of the file.
|
|
+ * Eliminate min/max redefinition in #include <net/tcp.h>.
|
|
+ * Correct path for pfkey #includes
|
|
+ * Standardise an error return method.
|
|
+ * Add debugging instrumentation.
|
|
+ * Move message type checking to pfkey_msg_parse().
|
|
+ * Add check for errno incorrectly set.
|
|
+ * Add check for valid PID.
|
|
+ * Add check for reserved illegally set.
|
|
+ * Add check for message out of bounds.
|
|
+ *
|
|
+ * Revision 1.3 1999/04/15 17:58:07 rgb
|
|
+ * Add RCSID labels.
|
|
+ *
|
|
+ * Revision 1.2 1999/04/15 15:37:26 rgb
|
|
+ * Forward check changes from POST1_00 branch.
|
|
+ *
|
|
+ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
|
|
+ * Header Title correction.
|
|
+ *
|
|
+ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
|
|
+ * Add pfkeyv2 support to KLIPS.
|
|
+ *
|
|
+ *
|
|
+ * RFC 2367
|
|
+ * PF_KEY_v2 Key Management API
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/pfkey_v2_build.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1581 @@
|
|
+/*
|
|
+ * RFC2367 PF_KEYv2 Key management API message parser
|
|
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: pfkey_v2_build.c,v 1.51.8.1 2006/05/01 14:36:39 mcr Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
|
|
+ */
|
|
+
|
|
+char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.51.8.1 2006/05/01 14:36:39 mcr Exp $";
|
|
+
|
|
+/*
|
|
+ * Some ugly stuff to allow consistent debugging code for use in the
|
|
+ * kernel and in user space
|
|
+*/
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+# include <linux/kernel.h> /* for printk */
|
|
+
|
|
+# include "openswan/ipsec_kversion.h" /* for malloc switch */
|
|
+# ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+# else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+# endif /* MALLOC_SLAB */
|
|
+# include <linux/errno.h> /* error codes */
|
|
+# include <linux/types.h> /* size_t */
|
|
+# include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+# include <linux/netdevice.h> /* struct device, and other headers */
|
|
+# include <linux/etherdevice.h> /* eth_type_trans */
|
|
+# include <linux/ip.h> /* struct iphdr */
|
|
+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
+# include <linux/ipv6.h> /* struct ipv6hdr */
|
|
+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
|
|
+
|
|
+# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
|
|
+# define FREE(obj) kfree(obj)
|
|
+# include <openswan.h>
|
|
+#else /* __KERNEL__ */
|
|
+
|
|
+# include <sys/types.h>
|
|
+# include <linux/types.h>
|
|
+# include <linux/errno.h>
|
|
+# include <malloc.h>
|
|
+# include <string.h> /* memset */
|
|
+
|
|
+# include <openswan.h>
|
|
+
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+#include "openswan/radij.h" /* rd_nodes */
|
|
+#include "openswan/ipsec_encap.h" /* sockaddr_encap */
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+
|
|
+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
|
|
+#include "openswan/pfkey_debug.h"
|
|
+
|
|
+
|
|
+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
|
|
+
|
|
+void
|
|
+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i != SADB_EXT_MAX + 1; i++) {
|
|
+ extensions[i] = NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if(!extensions) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if(extensions[0]) {
|
|
+ memset(extensions[0], 0, sizeof(struct sadb_msg));
|
|
+ FREE(extensions[0]);
|
|
+ extensions[0] = NULL;
|
|
+ }
|
|
+
|
|
+ for (i = 1; i != SADB_EXT_MAX + 1; i++) {
|
|
+ if(extensions[i]) {
|
|
+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
|
|
+ FREE(extensions[i]);
|
|
+ extensions[i] = NULL;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+pfkey_msg_free(struct sadb_msg **pfkey_msg)
|
|
+{
|
|
+ if(*pfkey_msg) {
|
|
+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
|
|
+ FREE(*pfkey_msg);
|
|
+ *pfkey_msg = NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
+/* Default extension builders taken from the KLIPS code */
|
|
+
|
|
+int
|
|
+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
|
|
+ uint8_t msg_type,
|
|
+ uint8_t satype,
|
|
+ uint8_t msg_errno,
|
|
+ uint32_t seq,
|
|
+ uint32_t pid)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_hdr_build:\n");
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_hdr_build: "
|
|
+ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
|
|
+ &pfkey_ext,
|
|
+ pfkey_ext,
|
|
+ *pfkey_ext);
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_msg) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_hdr_build: "
|
|
+ "why is pfkey_msg already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!msg_type) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_hdr_build: "
|
|
+ "msg type not set, must be non-zero..\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(msg_type > SADB_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_hdr_build: "
|
|
+ "msg type too large:%d.\n",
|
|
+ msg_type);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(satype > SADB_SATYPE_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_hdr_build: "
|
|
+ "satype %d > max %d\n",
|
|
+ satype, SADB_SATYPE_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ pfkey_msg = (struct sadb_msg*)MALLOC(sizeof(struct sadb_msg));
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_msg;
|
|
+
|
|
+ if(pfkey_msg == NULL) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_hdr_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_msg, 0, sizeof(struct sadb_msg));
|
|
+
|
|
+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
|
|
+
|
|
+ pfkey_msg->sadb_msg_type = msg_type;
|
|
+ pfkey_msg->sadb_msg_satype = satype;
|
|
+
|
|
+ pfkey_msg->sadb_msg_version = PF_KEY_V2;
|
|
+ pfkey_msg->sadb_msg_errno = msg_errno;
|
|
+ pfkey_msg->sadb_msg_reserved = 0;
|
|
+ pfkey_msg->sadb_msg_seq = seq;
|
|
+ pfkey_msg->sadb_msg_pid = pid;
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_hdr_build: "
|
|
+ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
|
|
+ &pfkey_ext,
|
|
+ pfkey_ext,
|
|
+ *pfkey_ext);
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint32_t spi,
|
|
+ uint8_t replay_window,
|
|
+ uint8_t sa_state,
|
|
+ uint8_t auth,
|
|
+ uint8_t encrypt,
|
|
+ uint32_t flags,
|
|
+ uint32_t/*IPsecSAref_t*/ ref)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
|
|
+ ntohl(spi), /* in network order */
|
|
+ replay_window,
|
|
+ sa_state,
|
|
+ auth,
|
|
+ encrypt,
|
|
+ flags);
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_sa) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "why is pfkey_sa already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(exttype != SADB_EXT_SA &&
|
|
+ exttype != SADB_X_EXT_SA2) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "invalid exttype=%d.\n",
|
|
+ exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(replay_window > 64) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "replay window size: %d -- must be 0 <= size <= 64\n",
|
|
+ replay_window);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(auth > SADB_AALG_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "auth=%d > SADB_AALG_MAX=%d.\n",
|
|
+ auth,
|
|
+ SADB_AALG_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+#if SADB_EALG_MAX < 255
|
|
+ if(encrypt > SADB_EALG_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "encrypt=%d > SADB_EALG_MAX=%d.\n",
|
|
+ encrypt,
|
|
+ SADB_EALG_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if(sa_state > SADB_SASTATE_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "sa_state=%d exceeds MAX=%d.\n",
|
|
+ sa_state,
|
|
+ SADB_SASTATE_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(sa_state == SADB_SASTATE_DEAD) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "sa_state=%d is DEAD=%d is not allowed.\n",
|
|
+ sa_state,
|
|
+ SADB_SASTATE_DEAD);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
|
|
+ ref,
|
|
+ IPSEC_SAREF_NULL,
|
|
+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ pfkey_sa = (struct sadb_sa*)MALLOC(sizeof(struct sadb_sa));
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_sa;
|
|
+
|
|
+ if(pfkey_sa == NULL) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sa_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_sa, 0, sizeof(struct sadb_sa));
|
|
+
|
|
+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
|
|
+ pfkey_sa->sadb_sa_exttype = exttype;
|
|
+ pfkey_sa->sadb_sa_spi = spi;
|
|
+ pfkey_sa->sadb_sa_replay = replay_window;
|
|
+ pfkey_sa->sadb_sa_state = sa_state;
|
|
+ pfkey_sa->sadb_sa_auth = auth;
|
|
+ pfkey_sa->sadb_sa_encrypt = encrypt;
|
|
+ pfkey_sa->sadb_sa_flags = flags;
|
|
+ pfkey_sa->sadb_x_sa_ref = ref;
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint32_t spi,
|
|
+ uint8_t replay_window,
|
|
+ uint8_t sa_state,
|
|
+ uint8_t auth,
|
|
+ uint8_t encrypt,
|
|
+ uint32_t flags)
|
|
+{
|
|
+ return pfkey_sa_ref_build(pfkey_ext,
|
|
+ exttype,
|
|
+ spi,
|
|
+ replay_window,
|
|
+ sa_state,
|
|
+ auth,
|
|
+ encrypt,
|
|
+ flags,
|
|
+ IPSEC_SAREF_NULL);
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint32_t allocations,
|
|
+ uint64_t bytes,
|
|
+ uint64_t addtime,
|
|
+ uint64_t usetime,
|
|
+ uint32_t packets)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_lifetime_build:\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_lifetime) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_lifetime_build: "
|
|
+ "why is pfkey_lifetime already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(exttype != SADB_EXT_LIFETIME_CURRENT &&
|
|
+ exttype != SADB_EXT_LIFETIME_HARD &&
|
|
+ exttype != SADB_EXT_LIFETIME_SOFT) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_lifetime_build: "
|
|
+ "invalid exttype=%d.\n",
|
|
+ exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ pfkey_lifetime = (struct sadb_lifetime*)MALLOC(sizeof(struct sadb_lifetime));
|
|
+ *pfkey_ext = (struct sadb_ext*) pfkey_lifetime;
|
|
+
|
|
+ if(pfkey_lifetime == NULL) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_lifetime_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
|
|
+
|
|
+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
|
|
+ pfkey_lifetime->sadb_lifetime_exttype = exttype;
|
|
+ pfkey_lifetime->sadb_lifetime_allocations = allocations;
|
|
+ pfkey_lifetime->sadb_lifetime_bytes = bytes;
|
|
+ pfkey_lifetime->sadb_lifetime_addtime = addtime;
|
|
+ pfkey_lifetime->sadb_lifetime_usetime = usetime;
|
|
+ pfkey_lifetime->sadb_x_lifetime_packets = packets;
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_address_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint8_t proto,
|
|
+ uint8_t prefixlen,
|
|
+ struct sockaddr* address)
|
|
+{
|
|
+ int error = 0;
|
|
+ int saddr_len = 0;
|
|
+ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
|
|
+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_address_build: "
|
|
+ "exttype=%d proto=%d prefixlen=%d\n",
|
|
+ exttype,
|
|
+ proto,
|
|
+ prefixlen);
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_address) {
|
|
+ ERROR("pfkey_address_build: "
|
|
+ "why is pfkey_address already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if (!address) {
|
|
+ ERROR("pfkey_address_build: " "address is NULL\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(exttype) {
|
|
+ case SADB_EXT_ADDRESS_SRC:
|
|
+ case SADB_EXT_ADDRESS_DST:
|
|
+ case SADB_EXT_ADDRESS_PROXY:
|
|
+ case SADB_X_EXT_ADDRESS_DST2:
|
|
+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
|
|
+ case SADB_X_EXT_ADDRESS_DST_FLOW:
|
|
+ case SADB_X_EXT_ADDRESS_SRC_MASK:
|
|
+ case SADB_X_EXT_ADDRESS_DST_MASK:
|
|
+#ifdef NAT_TRAVERSAL
|
|
+ case SADB_X_EXT_NAT_T_OA:
|
|
+#endif
|
|
+ break;
|
|
+ default:
|
|
+ ERROR("pfkey_address_build: "
|
|
+ "unrecognised ext_type=%d.\n",
|
|
+ exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(address->sa_family) {
|
|
+ case AF_INET:
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_address_build: "
|
|
+ "found address family AF_INET.\n");
|
|
+ saddr_len = sizeof(struct sockaddr_in);
|
|
+ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
|
|
+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
|
|
+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
|
|
+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
|
|
+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
|
|
+ , ntohs(((struct sockaddr_in*)address)->sin_port));
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_address_build: "
|
|
+ "found address family AF_INET6.\n");
|
|
+ saddr_len = sizeof(struct sockaddr_in6);
|
|
+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
|
|
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
|
|
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
|
|
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
|
|
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
|
|
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
|
|
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
|
|
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
|
|
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
|
|
+ , ntohs(((struct sockaddr_in6*)address)->sin6_port));
|
|
+ break;
|
|
+ default:
|
|
+ ERROR("pfkey_address_build: "
|
|
+ "address->sa_family=%d not supported.\n",
|
|
+ address->sa_family);
|
|
+ SENDERR(EPFNOSUPPORT);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_address_build: "
|
|
+ "found address=%s.\n",
|
|
+ ipaddr_txt);
|
|
+ if(prefixlen != 0) {
|
|
+ ERROR("pfkey_address_build: "
|
|
+ "address prefixes not supported yet.\n");
|
|
+ SENDERR(EAFNOSUPPORT); /* not supported yet */
|
|
+ }
|
|
+
|
|
+ /* allocate some memory for the extension */
|
|
+ pfkey_address = (struct sadb_address*)
|
|
+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_address;
|
|
+
|
|
+ if(pfkey_address == NULL ) {
|
|
+ ERROR("pfkey_lifetime_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_address,
|
|
+ 0,
|
|
+ ALIGN_N(sizeof(struct sadb_address) + saddr_len,
|
|
+ IPSEC_PFKEYv2_ALIGN));
|
|
+
|
|
+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
|
|
+ IPSEC_PFKEYv2_ALIGN);
|
|
+
|
|
+ pfkey_address->sadb_address_exttype = exttype;
|
|
+ pfkey_address->sadb_address_proto = proto;
|
|
+ pfkey_address->sadb_address_prefixlen = prefixlen;
|
|
+ pfkey_address->sadb_address_reserved = 0;
|
|
+
|
|
+ memcpy((char*)pfkey_address + sizeof(struct sadb_address),
|
|
+ address,
|
|
+ saddr_len);
|
|
+
|
|
+#if 0
|
|
+ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
|
|
+ pfkey_address_s_ska.sin_zero[i] = 0;
|
|
+ }
|
|
+#endif
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_address_build: "
|
|
+ "successful created len: %d.\n", pfkey_address->sadb_address_len);
|
|
+
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_key_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint16_t key_bits,
|
|
+ char* key)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_key_build:\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_key) {
|
|
+ ERROR("pfkey_key_build: "
|
|
+ "why is pfkey_key already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!key_bits) {
|
|
+ ERROR("pfkey_key_build: "
|
|
+ "key_bits is zero, it must be non-zero.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
|
|
+ ERROR("pfkey_key_build: "
|
|
+ "unsupported extension type=%d.\n",
|
|
+ exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ pfkey_key = (struct sadb_key*)
|
|
+ MALLOC(sizeof(struct sadb_key) +
|
|
+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_key;
|
|
+
|
|
+ if(pfkey_key == NULL) {
|
|
+ ERROR("pfkey_key_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_key,
|
|
+ 0,
|
|
+ sizeof(struct sadb_key) +
|
|
+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
|
|
+
|
|
+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
|
|
+ 64);
|
|
+ pfkey_key->sadb_key_exttype = exttype;
|
|
+ pfkey_key->sadb_key_bits = key_bits;
|
|
+ pfkey_key->sadb_key_reserved = 0;
|
|
+ memcpy((char*)pfkey_key + sizeof(struct sadb_key),
|
|
+ key,
|
|
+ DIVUP(key_bits, 8));
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_ident_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint16_t ident_type,
|
|
+ uint64_t ident_id,
|
|
+ uint8_t ident_len,
|
|
+ char* ident_string)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
|
|
+ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_ident_build:\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_ident) {
|
|
+ ERROR("pfkey_ident_build: "
|
|
+ "why is pfkey_ident already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
|
|
+ (exttype == SADB_EXT_IDENTITY_DST))) {
|
|
+ ERROR("pfkey_ident_build: "
|
|
+ "unsupported extension type=%d.\n",
|
|
+ exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if((ident_type == SADB_IDENTTYPE_RESERVED)) {
|
|
+ ERROR("pfkey_ident_build: "
|
|
+ "ident_type must be non-zero.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(ident_type > SADB_IDENTTYPE_MAX) {
|
|
+ ERROR("pfkey_ident_build: "
|
|
+ "identtype=%d out of range.\n",
|
|
+ ident_type);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
|
|
+ (ident_type == SADB_IDENTTYPE_FQDN)) &&
|
|
+ !ident_string) {
|
|
+ ERROR("pfkey_ident_build: "
|
|
+ "string required to allocate size of extension.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ pfkey_ident = (struct sadb_ident*)
|
|
+ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_ident;
|
|
+
|
|
+ if(pfkey_ident == NULL) {
|
|
+ ERROR("pfkey_ident_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
|
|
+
|
|
+ pfkey_ident->sadb_ident_len = ident_len;
|
|
+ pfkey_ident->sadb_ident_exttype = exttype;
|
|
+ pfkey_ident->sadb_ident_type = ident_type;
|
|
+ pfkey_ident->sadb_ident_reserved = 0;
|
|
+ pfkey_ident->sadb_ident_id = ident_id;
|
|
+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
|
|
+ ident_string,
|
|
+ data_len);
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_sens_build(struct sadb_ext** pfkey_ext,
|
|
+ uint32_t dpd,
|
|
+ uint8_t sens_level,
|
|
+ uint8_t sens_len,
|
|
+ uint64_t* sens_bitmap,
|
|
+ uint8_t integ_level,
|
|
+ uint8_t integ_len,
|
|
+ uint64_t* integ_bitmap)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
|
|
+ int i;
|
|
+ uint64_t* bitmap;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sens_build:\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_sens) {
|
|
+ ERROR("pfkey_sens_build: "
|
|
+ "why is pfkey_sens already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_sens_build: "
|
|
+ "Sorry, I can't build exttype=%d yet.\n",
|
|
+ (*pfkey_ext)->sadb_ext_type);
|
|
+ SENDERR(EINVAL); /* don't process these yet */
|
|
+
|
|
+ pfkey_sens = (struct sadb_sens*)
|
|
+ MALLOC(sizeof(struct sadb_sens) +
|
|
+ (sens_len + integ_len) * sizeof(uint64_t));
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_sens;
|
|
+
|
|
+ if(pfkey_sens == NULL) {
|
|
+ ERROR("pfkey_sens_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_sens,
|
|
+ 0,
|
|
+ sizeof(struct sadb_sens) +
|
|
+ (sens_len + integ_len) * sizeof(uint64_t));
|
|
+
|
|
+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
|
|
+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
|
|
+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
|
|
+ pfkey_sens->sadb_sens_dpd = dpd;
|
|
+ pfkey_sens->sadb_sens_sens_level = sens_level;
|
|
+ pfkey_sens->sadb_sens_sens_len = sens_len;
|
|
+ pfkey_sens->sadb_sens_integ_level = integ_level;
|
|
+ pfkey_sens->sadb_sens_integ_len = integ_len;
|
|
+ pfkey_sens->sadb_sens_reserved = 0;
|
|
+
|
|
+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
|
|
+ for(i = 0; i < sens_len; i++) {
|
|
+ *bitmap = sens_bitmap[i];
|
|
+ bitmap++;
|
|
+ }
|
|
+ for(i = 0; i < integ_len; i++) {
|
|
+ *bitmap = integ_bitmap[i];
|
|
+ bitmap++;
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_prop_build(struct sadb_ext** pfkey_ext,
|
|
+ uint8_t replay,
|
|
+ unsigned int comb_num,
|
|
+ struct sadb_comb* comb)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
|
|
+ struct sadb_comb *combp;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_prop_build:\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_prop) {
|
|
+ ERROR("pfkey_prop_build: "
|
|
+ "why is pfkey_prop already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ pfkey_prop = (struct sadb_prop*)
|
|
+ MALLOC(sizeof(struct sadb_prop) +
|
|
+ comb_num * sizeof(struct sadb_comb));
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_prop;
|
|
+
|
|
+ if(pfkey_prop == NULL) {
|
|
+ ERROR("pfkey_prop_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_prop,
|
|
+ 0,
|
|
+ sizeof(struct sadb_prop) +
|
|
+ comb_num * sizeof(struct sadb_comb));
|
|
+
|
|
+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
|
|
+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
|
|
+
|
|
+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
|
|
+ pfkey_prop->sadb_prop_replay = replay;
|
|
+
|
|
+ for(i=0; i<3; i++) {
|
|
+ pfkey_prop->sadb_prop_reserved[i] = 0;
|
|
+ }
|
|
+
|
|
+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
|
|
+ for(i = 0; i < comb_num; i++) {
|
|
+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
|
|
+ combp++;
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ uint8_t sadb_comb_auth;
|
|
+ uint8_t sadb_comb_encrypt;
|
|
+ uint16_t sadb_comb_flags;
|
|
+ uint16_t sadb_comb_auth_minbits;
|
|
+ uint16_t sadb_comb_auth_maxbits;
|
|
+ uint16_t sadb_comb_encrypt_minbits;
|
|
+ uint16_t sadb_comb_encrypt_maxbits;
|
|
+ uint32_t sadb_comb_reserved;
|
|
+ uint32_t sadb_comb_soft_allocations;
|
|
+ uint32_t sadb_comb_hard_allocations;
|
|
+ uint64_t sadb_comb_soft_bytes;
|
|
+ uint64_t sadb_comb_hard_bytes;
|
|
+ uint64_t sadb_comb_soft_addtime;
|
|
+ uint64_t sadb_comb_hard_addtime;
|
|
+ uint64_t sadb_comb_soft_usetime;
|
|
+ uint64_t sadb_comb_hard_usetime;
|
|
+ uint32_t sadb_comb_soft_packets;
|
|
+ uint32_t sadb_comb_hard_packets;
|
|
+#endif
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_supported_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ unsigned int alg_num,
|
|
+ struct sadb_alg* alg)
|
|
+{
|
|
+ int error = 0;
|
|
+ unsigned int i;
|
|
+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
|
|
+ struct sadb_alg *pfkey_alg;
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_supported) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_supported_build: "
|
|
+ "why is pfkey_supported already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_supported_build: "
|
|
+ "unsupported extension type=%d.\n",
|
|
+ exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ pfkey_supported = (struct sadb_supported*)
|
|
+ MALLOC(sizeof(struct sadb_supported) +
|
|
+ alg_num *
|
|
+ sizeof(struct sadb_alg));
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_supported;
|
|
+
|
|
+ if(pfkey_supported == NULL) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_supported_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_supported,
|
|
+ 0,
|
|
+ sizeof(struct sadb_supported) +
|
|
+ alg_num *
|
|
+ sizeof(struct sadb_alg));
|
|
+
|
|
+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
|
|
+ alg_num *
|
|
+ sizeof(struct sadb_alg)) /
|
|
+ IPSEC_PFKEYv2_ALIGN;
|
|
+ pfkey_supported->sadb_supported_exttype = exttype;
|
|
+ pfkey_supported->sadb_supported_reserved = 0;
|
|
+
|
|
+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
|
|
+ for(i = 0; i < alg_num; i++) {
|
|
+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
|
|
+ pfkey_alg->sadb_alg_reserved = 0;
|
|
+ pfkey_alg++;
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_supported_build: "
|
|
+ "Sorry, I can't build exttype=%d yet.\n",
|
|
+ (*pfkey_ext)->sadb_ext_type);
|
|
+ SENDERR(EINVAL); /* don't process these yet */
|
|
+
|
|
+ uint8_t sadb_alg_id;
|
|
+ uint8_t sadb_alg_ivlen;
|
|
+ uint16_t sadb_alg_minbits;
|
|
+ uint16_t sadb_alg_maxbits;
|
|
+ uint16_t sadb_alg_reserved;
|
|
+#endif
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint32_t min, /* in network order */
|
|
+ uint32_t max) /* in network order */
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_spirange) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_spirange_build: "
|
|
+ "why is pfkey_spirange already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(ntohl(max) < ntohl(min)) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_spirange_build: "
|
|
+ "minspi=%08x must be < maxspi=%08x.\n",
|
|
+ ntohl(min),
|
|
+ ntohl(max));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(ntohl(min) <= 255) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_spirange_build: "
|
|
+ "minspi=%08x must be > 255.\n",
|
|
+ ntohl(min));
|
|
+ SENDERR(EEXIST);
|
|
+ }
|
|
+
|
|
+ pfkey_spirange = (struct sadb_spirange*)
|
|
+ MALLOC(sizeof(struct sadb_spirange));
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
|
|
+
|
|
+ if(pfkey_spirange == NULL) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_spirange_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_spirange,
|
|
+ 0,
|
|
+ sizeof(struct sadb_spirange));
|
|
+
|
|
+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
|
|
+
|
|
+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
|
|
+ pfkey_spirange->sadb_spirange_min = min;
|
|
+ pfkey_spirange->sadb_spirange_max = max;
|
|
+ pfkey_spirange->sadb_spirange_reserved = 0;
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_x_kmprivate) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_kmprivate_build: "
|
|
+ "why is pfkey_x_kmprivate already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_kmprivate_build: "
|
|
+ "Sorry, I can't build exttype=%d yet.\n",
|
|
+ (*pfkey_ext)->sadb_ext_type);
|
|
+ SENDERR(EINVAL); /* don't process these yet */
|
|
+
|
|
+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
|
|
+ MALLOC(sizeof(struct sadb_x_kmprivate));
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
|
|
+
|
|
+ if(pfkey_x_kmprivate == NULL) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_kmprivate_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_x_kmprivate,
|
|
+ 0,
|
|
+ sizeof(struct sadb_x_kmprivate));
|
|
+
|
|
+ pfkey_x_kmprivate->sadb_x_kmprivate_len =
|
|
+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
|
|
+
|
|
+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
|
|
+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
|
|
+ uint8_t satype)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_satype_build:\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_x_satype) {
|
|
+ ERROR("pfkey_x_satype_build: "
|
|
+ "why is pfkey_x_satype already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!satype) {
|
|
+ ERROR("pfkey_x_satype_build: "
|
|
+ "SA type not set, must be non-zero.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(satype > SADB_SATYPE_MAX) {
|
|
+ ERROR("pfkey_x_satype_build: "
|
|
+ "satype %d > max %d\n",
|
|
+ satype, SADB_SATYPE_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ pfkey_x_satype = (struct sadb_x_satype*)
|
|
+ MALLOC(sizeof(struct sadb_x_satype));
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
|
|
+ if(pfkey_x_satype == NULL) {
|
|
+ ERROR("pfkey_x_satype_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memset(pfkey_x_satype,
|
|
+ 0,
|
|
+ sizeof(struct sadb_x_satype));
|
|
+
|
|
+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
|
|
+
|
|
+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
|
|
+ pfkey_x_satype->sadb_x_satype_satype = satype;
|
|
+ for(i=0; i<3; i++) {
|
|
+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
|
|
+ uint32_t tunnel,
|
|
+ uint32_t netlink,
|
|
+ uint32_t xform,
|
|
+ uint32_t eroute,
|
|
+ uint32_t spi,
|
|
+ uint32_t radij,
|
|
+ uint32_t esp,
|
|
+ uint32_t ah,
|
|
+ uint32_t rcv,
|
|
+ uint32_t pfkey,
|
|
+ uint32_t ipcomp,
|
|
+ uint32_t verbose)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_debug_build:\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_x_debug) {
|
|
+ ERROR("pfkey_x_debug_build: "
|
|
+ "why is pfkey_x_debug already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_debug_build: "
|
|
+ "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n",
|
|
+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
|
|
+
|
|
+ pfkey_x_debug = (struct sadb_x_debug*)
|
|
+ MALLOC(sizeof(struct sadb_x_debug));
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
|
|
+
|
|
+ if(pfkey_x_debug == NULL) {
|
|
+ ERROR("pfkey_x_debug_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+#if 0
|
|
+ memset(pfkey_x_debug,
|
|
+ 0,
|
|
+ sizeof(struct sadb_x_debug));
|
|
+#endif
|
|
+
|
|
+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
|
|
+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
|
|
+
|
|
+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
|
|
+ pfkey_x_debug->sadb_x_debug_netlink = netlink;
|
|
+ pfkey_x_debug->sadb_x_debug_xform = xform;
|
|
+ pfkey_x_debug->sadb_x_debug_eroute = eroute;
|
|
+ pfkey_x_debug->sadb_x_debug_spi = spi;
|
|
+ pfkey_x_debug->sadb_x_debug_radij = radij;
|
|
+ pfkey_x_debug->sadb_x_debug_esp = esp;
|
|
+ pfkey_x_debug->sadb_x_debug_ah = ah;
|
|
+ pfkey_x_debug->sadb_x_debug_rcv = rcv;
|
|
+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
|
|
+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
|
|
+ pfkey_x_debug->sadb_x_debug_verbose = verbose;
|
|
+
|
|
+ for(i=0; i<4; i++) {
|
|
+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
|
|
+ uint8_t type)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_nat_t_type_build:\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_x_nat_t_type) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_nat_t_type_build: "
|
|
+ "why is pfkey_x_nat_t_type already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_nat_t_type_build: "
|
|
+ "type=%d\n", type);
|
|
+
|
|
+ pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
|
|
+ MALLOC(sizeof(struct sadb_x_nat_t_type));
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
|
|
+
|
|
+ if(pfkey_x_nat_t_type == NULL) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_nat_t_type_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+
|
|
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
|
|
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
|
|
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
|
|
+ for(i=0; i<3; i++) {
|
|
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+int
|
|
+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
|
|
+ uint16_t exttype,
|
|
+ uint16_t port)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_nat_t_port_build:\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_x_nat_t_port) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_nat_t_port_build: "
|
|
+ "why is pfkey_x_nat_t_port already pointing to something?\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(exttype) {
|
|
+ case SADB_X_EXT_NAT_T_SPORT:
|
|
+ case SADB_X_EXT_NAT_T_DPORT:
|
|
+ break;
|
|
+ default:
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_nat_t_port_build: "
|
|
+ "unrecognised ext_type=%d.\n",
|
|
+ exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_nat_t_port_build: "
|
|
+ "ext=%d, port=%d\n", exttype, port);
|
|
+
|
|
+ pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
|
|
+ MALLOC(sizeof(struct sadb_x_nat_t_port));
|
|
+
|
|
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
|
|
+
|
|
+ if(pfkey_x_nat_t_port == NULL) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_x_nat_t_port_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+
|
|
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
|
|
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
|
|
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
|
|
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
|
|
+ uint8_t protocol)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol);
|
|
+ /* sanity checks... */
|
|
+ if (p != 0) {
|
|
+ ERROR("pfkey_x_protocol_build: bogus protocol pointer\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
|
|
+ ERROR("pfkey_build: memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ *pfkey_ext = (struct sadb_ext *)p;
|
|
+ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
|
|
+ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
|
|
+ p->sadb_protocol_proto = protocol;
|
|
+ p->sadb_protocol_flags = 0;
|
|
+ p->sadb_protocol_reserved2 = 0;
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
|
|
+{
|
|
+ int error = 0;
|
|
+ unsigned ext;
|
|
+ unsigned total_size;
|
|
+ struct sadb_ext *pfkey_ext;
|
|
+ int extensions_seen = 0;
|
|
+#ifndef __KERNEL__
|
|
+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
|
|
+#endif
|
|
+
|
|
+ if(!extensions[0]) {
|
|
+ ERROR("pfkey_msg_build: "
|
|
+ "extensions[0] must be specified (struct sadb_msg).\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ /* figure out the total size for all the requested extensions */
|
|
+ total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
|
|
+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
|
|
+ if(extensions[ext]) {
|
|
+ total_size += (extensions[ext])->sadb_ext_len;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* allocate that much space */
|
|
+ *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN);
|
|
+ if(*pfkey_msg == NULL) {
|
|
+ ERROR("pfkey_msg_build: "
|
|
+ "memory allocation failed\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_build: "
|
|
+ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
|
|
+ *pfkey_msg,
|
|
+ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
|
|
+ &(extensions[0]));
|
|
+
|
|
+ memcpy(*pfkey_msg,
|
|
+ extensions[0],
|
|
+ sizeof(struct sadb_msg));
|
|
+ (*pfkey_msg)->sadb_msg_len = total_size;
|
|
+ (*pfkey_msg)->sadb_msg_reserved = 0;
|
|
+ extensions_seen = 1 ;
|
|
+
|
|
+ /*
|
|
+ * point pfkey_ext to immediately after the space for the header,
|
|
+ * i.e. at the first extension location.
|
|
+ */
|
|
+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
|
|
+
|
|
+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
|
|
+ /* copy from extension[ext] to buffer */
|
|
+ if(extensions[ext]) {
|
|
+ /* Is this type of extension permitted for this type of message? */
|
|
+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
|
|
+ 1<<ext)) {
|
|
+ ERROR("pfkey_msg_build: "
|
|
+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
|
|
+ ext,
|
|
+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
|
|
+ 1<<ext);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_build: "
|
|
+ "copying %lu bytes from extensions[%u] (type=%d)\n",
|
|
+ (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
|
|
+ ext,
|
|
+ extensions[ext]->sadb_ext_type);
|
|
+
|
|
+ memcpy(pfkey_ext,
|
|
+ extensions[ext],
|
|
+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
|
|
+ {
|
|
+ char *pfkey_ext_c = (char *)pfkey_ext;
|
|
+
|
|
+ pfkey_ext_c += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
|
|
+ pfkey_ext = (struct sadb_ext *)pfkey_ext_c;
|
|
+ }
|
|
+
|
|
+ /* Mark that we have seen this extension and remember the header location */
|
|
+ extensions_seen |= ( 1 << ext );
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* check required extensions */
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_build: "
|
|
+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
|
|
+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
|
|
+ extensions_seen,
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
|
|
+
|
|
+ if((extensions_seen &
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_BUILD,
|
|
+ "pfkey_msg_build: "
|
|
+ "required extensions missing:%08x.\n",
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
|
|
+ (extensions_seen &
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+#ifndef __KERNEL__
|
|
+/*
|
|
+ * this is silly, there is no need to reparse the message that we just built.
|
|
+ *
|
|
+ */
|
|
+ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
|
|
+ ERROR(
|
|
+ "pfkey_msg_build: "
|
|
+ "Trouble parsing newly built pfkey message, error=%d.\n",
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+errlab:
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: pfkey_v2_build.c,v $
|
|
+ * Revision 1.51.8.1 2006/05/01 14:36:39 mcr
|
|
+ * get rid of dead code.
|
|
+ *
|
|
+ * Revision 1.51 2004/10/03 01:26:36 mcr
|
|
+ * fixes for gcc 3.4 compilation.
|
|
+ *
|
|
+ * Revision 1.50 2004/07/10 07:48:35 mcr
|
|
+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
|
|
+ *
|
|
+ * Revision 1.49 2004/04/12 02:59:06 mcr
|
|
+ * erroneously moved pfkey_v2_build.c
|
|
+ *
|
|
+ * Revision 1.48 2004/04/09 18:00:40 mcr
|
|
+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
|
|
+ *
|
|
+ * Revision 1.47 2004/03/08 01:59:08 ken
|
|
+ * freeswan.h -> openswan.h
|
|
+ *
|
|
+ * Revision 1.46 2003/12/10 01:20:19 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.45 2003/12/04 23:01:12 mcr
|
|
+ * removed ipsec_netlink.h
|
|
+ *
|
|
+ * Revision 1.44 2003/10/31 02:27:12 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.43.4.2 2003/10/29 01:11:32 mcr
|
|
+ * added debugging for pfkey library.
|
|
+ *
|
|
+ * Revision 1.43.4.1 2003/09/21 13:59:44 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.43 2003/05/07 17:29:17 mcr
|
|
+ * new function pfkey_debug_func added for us in debugging from
|
|
+ * pfkey library.
|
|
+ *
|
|
+ * Revision 1.42 2003/01/30 02:32:09 rgb
|
|
+ *
|
|
+ * Rename SAref table macro names for clarity.
|
|
+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
|
|
+ *
|
|
+ * Revision 1.41 2002/12/13 18:16:02 mcr
|
|
+ * restored sa_ref code
|
|
+ *
|
|
+ * Revision 1.40 2002/12/13 18:06:52 mcr
|
|
+ * temporarily removed sadb_x_sa_ref reference for 2.xx
|
|
+ *
|
|
+ * Revision 1.39 2002/12/13 17:43:28 mcr
|
|
+ * commented out access to sadb_x_sa_ref for 2.xx branch
|
|
+ *
|
|
+ * Revision 1.38 2002/10/09 03:12:05 dhr
|
|
+ *
|
|
+ * [kenb+dhr] 64-bit fixes
|
|
+ *
|
|
+ * Revision 1.37 2002/09/20 15:40:39 rgb
|
|
+ * Added new function pfkey_sa_ref_build() to accomodate saref parameter.
|
|
+ *
|
|
+ * Revision 1.36 2002/09/20 05:01:22 rgb
|
|
+ * Generalise for platform independance: fix (ia64) using unsigned for sizes.
|
|
+ *
|
|
+ * Revision 1.35 2002/07/24 18:44:54 rgb
|
|
+ * Type fiddling to tame ia64 compiler.
|
|
+ *
|
|
+ * Revision 1.34 2002/05/23 07:14:11 rgb
|
|
+ * Cleaned up %p variants to 0p%p for test suite cleanup.
|
|
+ *
|
|
+ * Revision 1.33 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.32 2002/04/24 07:36:40 mcr
|
|
+ * Moved from ./lib/pfkey_v2_build.c,v
|
|
+ *
|
|
+ * Revision 1.31 2002/01/29 22:25:35 rgb
|
|
+ * Re-add ipsec_kversion.h to keep MALLOC happy.
|
|
+ *
|
|
+ * Revision 1.30 2002/01/29 01:59:09 mcr
|
|
+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
|
|
+ * updating of IPv6 structures to match latest in6.h version.
|
|
+ * removed dead code from openswan.h that also duplicated kversions.h
|
|
+ * code.
|
|
+ *
|
|
+ * Revision 1.29 2001/12/19 21:06:09 rgb
|
|
+ * Added port numbers to pfkey_address_build() debugging.
|
|
+ *
|
|
+ * Revision 1.28 2001/11/06 19:47:47 rgb
|
|
+ * Added packet parameter to lifetime and comb structures.
|
|
+ *
|
|
+ * Revision 1.27 2001/10/18 04:45:24 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/openswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.26 2001/09/08 21:13:34 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.25 2001/06/14 19:35:16 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.24 2001/03/20 03:49:45 rgb
|
|
+ * Ditch superfluous debug_pfkey declaration.
|
|
+ * Move misplaced openswan.h inclusion for kernel case.
|
|
+ *
|
|
+ * Revision 1.23 2001/03/16 07:41:50 rgb
|
|
+ * Put openswan.h include before pluto includes.
|
|
+ *
|
|
+ * Revision 1.22 2001/02/27 22:24:56 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.21 2000/11/17 18:10:30 rgb
|
|
+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
|
|
+ * network byte order since this is the way PF_KEYv2 stored spis.
|
|
+ *
|
|
+ * Revision 1.20 2000/10/12 00:02:39 rgb
|
|
+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
|
|
+ *
|
|
+ * Revision 1.19 2000/10/10 20:10:20 rgb
|
|
+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
|
|
+ *
|
|
+ * Revision 1.18 2000/09/12 18:59:54 rgb
|
|
+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
|
|
+ *
|
|
+ * Revision 1.17 2000/09/12 03:27:00 rgb
|
|
+ * Moved DEBUGGING definition to compile kernel with debug off.
|
|
+ *
|
|
+ * Revision 1.16 2000/09/08 19:22:12 rgb
|
|
+ * Fixed pfkey_prop_build() parameter to be only single indirection.
|
|
+ * Fixed struct alg copy.
|
|
+ *
|
|
+ * Revision 1.15 2000/08/20 21:40:01 rgb
|
|
+ * Added an address parameter sanity check to pfkey_address_build().
|
|
+ *
|
|
+ * Revision 1.14 2000/08/15 17:29:23 rgb
|
|
+ * Fixes from SZI to untested pfkey_prop_build().
|
|
+ *
|
|
+ * Revision 1.13 2000/06/02 22:54:14 rgb
|
|
+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
|
|
+ *
|
|
+ * Revision 1.12 2000/05/10 19:24:01 rgb
|
|
+ * Fleshed out sensitivity, proposal and supported extensions.
|
|
+ *
|
|
+ * Revision 1.11 2000/03/16 14:07:23 rgb
|
|
+ * Renamed ALIGN macro to avoid fighting with others in kernel.
|
|
+ *
|
|
+ * Revision 1.10 2000/01/24 21:14:35 rgb
|
|
+ * Added disabled pluto pfkey lib debug flag.
|
|
+ *
|
|
+ * Revision 1.9 2000/01/21 06:27:32 rgb
|
|
+ * Added address cases for eroute flows.
|
|
+ * Removed unused code.
|
|
+ * Dropped unused argument to pfkey_x_satype_build().
|
|
+ * Indented compiler directives for readability.
|
|
+ * Added klipsdebug switching capability.
|
|
+ * Fixed SADB_EXT_MAX bug not permitting last extension access.
|
|
+ *
|
|
+ * Revision 1.8 1999/12/29 21:17:41 rgb
|
|
+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
|
|
+ * parameter for cleaner manipulation of extensions[] and to guard
|
|
+ * against potential memory leaks.
|
|
+ * Changed the I/F to pfkey_msg_free() for the same reason.
|
|
+ *
|
|
+ * Revision 1.7 1999/12/09 23:12:20 rgb
|
|
+ * Removed unused cruft.
|
|
+ * Added argument to pfkey_sa_build() to do eroutes.
|
|
+ * Fixed exttype check in as yet unused pfkey_lifetime_build().
|
|
+ *
|
|
+ * Revision 1.6 1999/12/07 19:54:29 rgb
|
|
+ * Removed static pluto debug flag.
|
|
+ * Added functions for pfkey message and extensions initialisation
|
|
+ * and cleanup.
|
|
+ *
|
|
+ * Revision 1.5 1999/12/01 22:20:06 rgb
|
|
+ * Changed pfkey_sa_build to accept an SPI in network byte order.
|
|
+ * Added <string.h> to quiet userspace compiler.
|
|
+ * Moved pfkey_lib_debug variable into the library.
|
|
+ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
|
|
+ * Added extension assembly debugging.
|
|
+ * Isolated assignment with brackets to be sure of scope.
|
|
+ *
|
|
+ * Revision 1.4 1999/11/27 11:57:35 rgb
|
|
+ * Added ipv6 headers.
|
|
+ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
|
|
+ * Debugging error messages added.
|
|
+ * Fixed missing auth and encrypt assignment bug.
|
|
+ * Add argument to pfkey_msg_parse() for direction.
|
|
+ * Move parse-after-build check inside pfkey_msg_build().
|
|
+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
|
|
+ * Add CVS log entry to bottom of file.
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,181 @@
|
|
+/*
|
|
+ * @(#) pfkey version 2 debugging messages
|
|
+ *
|
|
+ * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org>
|
|
+ * and Michael Richardson <mcr@openswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: pfkey_v2_debug.c,v 1.11 2005/04/06 17:45:16 mcr Exp $
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+# include <linux/kernel.h> /* for printk */
|
|
+
|
|
+# include "openswan/ipsec_kversion.h" /* for malloc switch */
|
|
+# ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+# else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+# endif /* MALLOC_SLAB */
|
|
+# include <linux/errno.h> /* error codes */
|
|
+# include <linux/types.h> /* size_t */
|
|
+# include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+# include <linux/netdevice.h> /* struct device, and other headers */
|
|
+# include <linux/etherdevice.h> /* eth_type_trans */
|
|
+extern int debug_pfkey;
|
|
+
|
|
+#else /* __KERNEL__ */
|
|
+
|
|
+# include <sys/types.h>
|
|
+# include <linux/types.h>
|
|
+# include <linux/errno.h>
|
|
+
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+#include "openswan.h"
|
|
+#include "pfkeyv2.h"
|
|
+#include "pfkey.h"
|
|
+
|
|
+/*
|
|
+ * This file provides ASCII translations of PF_KEY magic numbers.
|
|
+ *
|
|
+ */
|
|
+
|
|
+static char *pfkey_sadb_ext_strings[]={
|
|
+ "reserved", /* SADB_EXT_RESERVED 0 */
|
|
+ "security-association", /* SADB_EXT_SA 1 */
|
|
+ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */
|
|
+ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */
|
|
+ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */
|
|
+ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */
|
|
+ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */
|
|
+ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */
|
|
+ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */
|
|
+ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */
|
|
+ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */
|
|
+ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */
|
|
+ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */
|
|
+ "proposal", /* SADB_EXT_PROPOSAL 13 */
|
|
+ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */
|
|
+ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */
|
|
+ "spi-range", /* SADB_EXT_SPIRANGE 16 */
|
|
+ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */
|
|
+ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */
|
|
+ "X-security-association", /* SADB_X_EXT_SA2 19 */
|
|
+ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */
|
|
+ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
|
|
+ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */
|
|
+ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */
|
|
+ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */
|
|
+ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */
|
|
+ /* NAT_TRAVERSAL */
|
|
+ "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */
|
|
+ "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */
|
|
+ "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */
|
|
+ "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */
|
|
+};
|
|
+
|
|
+const char *
|
|
+pfkey_v2_sadb_ext_string(int ext)
|
|
+{
|
|
+ if(ext <= SADB_EXT_MAX) {
|
|
+ return pfkey_sadb_ext_strings[ext];
|
|
+ } else {
|
|
+ return "unknown-ext";
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+static char *pfkey_sadb_type_strings[]={
|
|
+ "reserved", /* SADB_RESERVED */
|
|
+ "getspi", /* SADB_GETSPI */
|
|
+ "update", /* SADB_UPDATE */
|
|
+ "add", /* SADB_ADD */
|
|
+ "delete", /* SADB_DELETE */
|
|
+ "get", /* SADB_GET */
|
|
+ "acquire", /* SADB_ACQUIRE */
|
|
+ "register", /* SADB_REGISTER */
|
|
+ "expire", /* SADB_EXPIRE */
|
|
+ "flush", /* SADB_FLUSH */
|
|
+ "dump", /* SADB_DUMP */
|
|
+ "x-promisc", /* SADB_X_PROMISC */
|
|
+ "x-pchange", /* SADB_X_PCHANGE */
|
|
+ "x-groupsa", /* SADB_X_GRPSA */
|
|
+ "x-addflow(eroute)", /* SADB_X_ADDFLOW */
|
|
+ "x-delflow(eroute)", /* SADB_X_DELFLOW */
|
|
+ "x-debug", /* SADB_X_DEBUG */
|
|
+};
|
|
+
|
|
+const char *
|
|
+pfkey_v2_sadb_type_string(int sadb_type)
|
|
+{
|
|
+ if(sadb_type <= SADB_MAX) {
|
|
+ return pfkey_sadb_type_strings[sadb_type];
|
|
+ } else {
|
|
+ return "unknown-sadb-type";
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * $Log: pfkey_v2_debug.c,v $
|
|
+ * Revision 1.11 2005/04/06 17:45:16 mcr
|
|
+ * always include NAT-T names.
|
|
+ *
|
|
+ * Revision 1.10 2004/07/10 07:48:35 mcr
|
|
+ * Moved from linux/lib/libfreeswan/pfkey_v2_debug.c,v
|
|
+ *
|
|
+ * Revision 1.9 2004/03/08 01:59:08 ken
|
|
+ * freeswan.h -> openswan.h
|
|
+ *
|
|
+ * Revision 1.8 2003/12/10 01:20:19 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.7 2002/09/20 05:01:26 rgb
|
|
+ * Fixed limit inclusion error in both type and ext string conversion.
|
|
+ *
|
|
+ * Revision 1.6 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.5 2002/04/24 07:36:40 mcr
|
|
+ * Moved from ./lib/pfkey_v2_debug.c,v
|
|
+ *
|
|
+ * Revision 1.4 2002/01/29 22:25:36 rgb
|
|
+ * Re-add ipsec_kversion.h to keep MALLOC happy.
|
|
+ *
|
|
+ * Revision 1.3 2002/01/29 01:59:09 mcr
|
|
+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
|
|
+ * updating of IPv6 structures to match latest in6.h version.
|
|
+ * removed dead code from openswan.h that also duplicated kversions.h
|
|
+ * code.
|
|
+ *
|
|
+ * Revision 1.2 2002/01/20 20:34:50 mcr
|
|
+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
|
|
+ *
|
|
+ * Revision 1.1 2001/11/27 05:30:06 mcr
|
|
+ * initial set of debug strings for pfkey debugging.
|
|
+ * this will eventually only be included for debug builds.
|
|
+ *
|
|
+ * Revision 1.1 2001/09/21 04:12:03 mcr
|
|
+ * first compilable version.
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,814 @@
|
|
+/*
|
|
+ * RFC2367 PF_KEYv2 Key management API message parser
|
|
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
|
|
+ */
|
|
+
|
|
+char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $";
|
|
+
|
|
+/*
|
|
+ * Some ugly stuff to allow consistent debugging code for use in the
|
|
+ * kernel and in user space
|
|
+*/
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+# include <linux/kernel.h> /* for printk */
|
|
+
|
|
+# include "openswan/ipsec_kversion.h" /* for malloc switch */
|
|
+# ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+# else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+# endif /* MALLOC_SLAB */
|
|
+# include <linux/errno.h> /* error codes */
|
|
+# include <linux/types.h> /* size_t */
|
|
+# include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+# include <linux/netdevice.h> /* struct device, and other headers */
|
|
+# include <linux/etherdevice.h> /* eth_type_trans */
|
|
+# include <linux/ip.h> /* struct iphdr */
|
|
+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
+# include <linux/ipv6.h>
|
|
+# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
|
|
+
|
|
+#else /* __KERNEL__ */
|
|
+
|
|
+# include <sys/types.h>
|
|
+# include <linux/types.h>
|
|
+# include <linux/errno.h>
|
|
+#endif
|
|
+
|
|
+#include <openswan.h>
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX] = {
|
|
+
|
|
+/* INBOUND EXTENSIONS */
|
|
+{
|
|
+
|
|
+/* PERMITTED IN */
|
|
+{
|
|
+/* SADB_RESERVED */
|
|
+0
|
|
+,
|
|
+/* SADB_GETSPI */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+,
|
|
+/* SADB_UPDATE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+,
|
|
+/* SADB_ADD */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_X_EXT_NAT_T_TYPE
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_OA
|
|
+,
|
|
+/* SADB_DELETE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_GET */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_ACQUIRE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+,
|
|
+/* SADB_REGISTER */
|
|
+1<<SADB_EXT_RESERVED
|
|
+,
|
|
+/* SADB_EXPIRE */
|
|
+0
|
|
+,
|
|
+/* SADB_FLUSH */
|
|
+1<<SADB_EXT_RESERVED
|
|
+,
|
|
+/* SADB_DUMP */
|
|
+1<<SADB_EXT_RESERVED
|
|
+,
|
|
+/* SADB_X_PROMISC */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+| 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+| 1<<SADB_X_EXT_KMPRIVATE
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_PCHANGE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+| 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+| 1<<SADB_X_EXT_KMPRIVATE
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_GRPSA */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_ADDFLOW */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_X_EXT_PROTOCOL
|
|
+,
|
|
+/* SADB_X_DELFLOW */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_X_EXT_PROTOCOL
|
|
+,
|
|
+/* SADB_X_DEBUG */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_X_EXT_DEBUG
|
|
+,
|
|
+/* SADB_X_NAT_T_NEW_MAPPING */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+},
|
|
+
|
|
+/* REQUIRED IN */
|
|
+{
|
|
+/* SADB_RESERVED */
|
|
+0
|
|
+,
|
|
+/* SADB_GETSPI */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+,
|
|
+/* SADB_UPDATE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+/*| 1<<SADB_EXT_KEY_AUTH*/
|
|
+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
|
|
+,
|
|
+/* SADB_ADD */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+/*| 1<<SADB_EXT_KEY_AUTH*/
|
|
+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
|
|
+,
|
|
+/* SADB_DELETE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_GET */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_ACQUIRE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+,
|
|
+/* SADB_REGISTER */
|
|
+1<<SADB_EXT_RESERVED
|
|
+,
|
|
+/* SADB_EXPIRE */
|
|
+0
|
|
+,
|
|
+/* SADB_FLUSH */
|
|
+1<<SADB_EXT_RESERVED
|
|
+,
|
|
+/* SADB_DUMP */
|
|
+1<<SADB_EXT_RESERVED
|
|
+,
|
|
+/* SADB_X_PROMISC */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+| 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+| 1<<SADB_X_EXT_KMPRIVATE
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_PCHANGE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+| 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+| 1<<SADB_X_EXT_KMPRIVATE
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_GRPSA */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+/*| 1<<SADB_X_EXT_SATYPE2*/
|
|
+/*| 1<<SADB_X_EXT_SA2*/
|
|
+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
|
|
+,
|
|
+/* SADB_X_ADDFLOW */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
|
|
+,
|
|
+/* SADB_X_DELFLOW */
|
|
+1<<SADB_EXT_RESERVED
|
|
+/*| 1<<SADB_EXT_SA*/
|
|
+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
|
|
+#endif
|
|
+,
|
|
+/* SADB_X_DEBUG */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_X_EXT_DEBUG
|
|
+,
|
|
+/* SADB_X_NAT_T_NEW_MAPPING */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+}
|
|
+
|
|
+},
|
|
+
|
|
+/* OUTBOUND EXTENSIONS */
|
|
+{
|
|
+
|
|
+/* PERMITTED OUT */
|
|
+{
|
|
+/* SADB_RESERVED */
|
|
+0
|
|
+,
|
|
+/* SADB_GETSPI */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_UPDATE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+,
|
|
+/* SADB_ADD */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_X_EXT_NAT_T_TYPE
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_OA
|
|
+,
|
|
+/* SADB_DELETE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_GET */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_X_EXT_NAT_T_TYPE
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_OA
|
|
+,
|
|
+/* SADB_ACQUIRE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+,
|
|
+/* SADB_REGISTER */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
|
|
+,
|
|
+/* SADB_EXPIRE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_FLUSH */
|
|
+1<<SADB_EXT_RESERVED
|
|
+,
|
|
+/* SADB_DUMP */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_X_EXT_NAT_T_TYPE
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_OA
|
|
+,
|
|
+/* SADB_X_PROMISC */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+| 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+| 1<<SADB_X_EXT_KMPRIVATE
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_PCHANGE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+| 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+| 1<<SADB_X_EXT_KMPRIVATE
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_GRPSA */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_ADDFLOW */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
|
|
+| 1<<SADB_X_EXT_PROTOCOL
|
|
+,
|
|
+/* SADB_X_DELFLOW */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
|
|
+| 1<<SADB_X_EXT_PROTOCOL
|
|
+,
|
|
+/* SADB_X_DEBUG */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_X_EXT_DEBUG
|
|
+,
|
|
+/* SADB_X_NAT_T_NEW_MAPPING */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+},
|
|
+
|
|
+/* REQUIRED OUT */
|
|
+{
|
|
+/* SADB_RESERVED */
|
|
+0
|
|
+,
|
|
+/* SADB_GETSPI */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_UPDATE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_ADD */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_DELETE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_GET */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+/* | 1<<SADB_EXT_KEY_AUTH */
|
|
+/* | 1<<SADB_EXT_KEY_ENCRYPT */
|
|
+,
|
|
+/* SADB_ACQUIRE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+,
|
|
+/* SADB_REGISTER */
|
|
+1<<SADB_EXT_RESERVED
|
|
+/* | 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
|
|
+,
|
|
+/* SADB_EXPIRE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+/* | 1<<SADB_EXT_LIFETIME_HARD
|
|
+ | 1<<SADB_EXT_LIFETIME_SOFT */
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_FLUSH */
|
|
+1<<SADB_EXT_RESERVED
|
|
+,
|
|
+/* SADB_DUMP */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+,
|
|
+/* SADB_X_PROMISC */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+| 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+| 1<<SADB_X_EXT_KMPRIVATE
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_PCHANGE */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_LIFETIME_CURRENT
|
|
+| 1<<SADB_EXT_LIFETIME_HARD
|
|
+| 1<<SADB_EXT_LIFETIME_SOFT
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_EXT_ADDRESS_PROXY
|
|
+| 1<<SADB_EXT_KEY_AUTH
|
|
+| 1<<SADB_EXT_KEY_ENCRYPT
|
|
+| 1<<SADB_EXT_IDENTITY_SRC
|
|
+| 1<<SADB_EXT_IDENTITY_DST
|
|
+| 1<<SADB_EXT_SENSITIVITY
|
|
+| 1<<SADB_EXT_PROPOSAL
|
|
+| 1<<SADB_EXT_SUPPORTED_AUTH
|
|
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
|
|
+| 1<<SADB_EXT_SPIRANGE
|
|
+| 1<<SADB_X_EXT_KMPRIVATE
|
|
+| 1<<SADB_X_EXT_SATYPE2
|
|
+| 1<<SADB_X_EXT_SA2
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST2
|
|
+,
|
|
+/* SADB_X_GRPSA */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+,
|
|
+/* SADB_X_ADDFLOW */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
|
|
+,
|
|
+/* SADB_X_DELFLOW */
|
|
+1<<SADB_EXT_RESERVED
|
|
+/*| 1<<SADB_EXT_SA*/
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
|
|
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
|
|
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
|
|
+,
|
|
+/* SADB_X_DEBUG */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_X_EXT_DEBUG
|
|
+,
|
|
+/* SADB_X_NAT_T_NEW_MAPPING */
|
|
+1<<SADB_EXT_RESERVED
|
|
+| 1<<SADB_EXT_SA
|
|
+| 1<<SADB_EXT_ADDRESS_SRC
|
|
+| 1<<SADB_EXT_ADDRESS_DST
|
|
+| 1<<SADB_X_EXT_NAT_T_SPORT
|
|
+| 1<<SADB_X_EXT_NAT_T_DPORT
|
|
+}
|
|
+}
|
|
+};
|
|
+
|
|
+/*
|
|
+ * $Log: pfkey_v2_ext_bits.c,v $
|
|
+ * Revision 1.22 2005/05/11 01:45:31 mcr
|
|
+ * make pfkey.h standalone.
|
|
+ *
|
|
+ * Revision 1.21 2004/07/10 07:48:36 mcr
|
|
+ * Moved from linux/lib/libfreeswan/pfkey_v2_ext_bits.c,v
|
|
+ *
|
|
+ * Revision 1.20 2004/03/08 01:59:08 ken
|
|
+ * freeswan.h -> openswan.h
|
|
+ *
|
|
+ * Revision 1.19 2003/12/22 21:38:13 mcr
|
|
+ * removed extraenous #endif.
|
|
+ *
|
|
+ * Revision 1.18 2003/12/22 19:34:41 mcr
|
|
+ * added 0.6c NAT-T patch.
|
|
+ *
|
|
+ * Revision 1.17 2003/12/10 01:20:19 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.16 2003/10/31 02:27:12 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.15.30.1 2003/09/21 13:59:44 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.15 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.14 2002/04/24 07:36:40 mcr
|
|
+ * Moved from ./lib/pfkey_v2_ext_bits.c,v
|
|
+ *
|
|
+ * Revision 1.13 2002/01/29 22:25:36 rgb
|
|
+ * Re-add ipsec_kversion.h to keep MALLOC happy.
|
|
+ *
|
|
+ * Revision 1.12 2002/01/29 01:59:10 mcr
|
|
+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
|
|
+ * updating of IPv6 structures to match latest in6.h version.
|
|
+ * removed dead code from openswan.h that also duplicated kversions.h
|
|
+ * code.
|
|
+ *
|
|
+ * Revision 1.11 2001/10/18 04:45:24 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/openswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.10 2001/09/08 21:13:35 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ *
|
|
+ * Revision 1.9 2001/06/14 19:35:16 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.8 2001/03/26 23:07:36 rgb
|
|
+ * Remove requirement for auth and enc key from UPDATE.
|
|
+ *
|
|
+ * Revision 1.7 2000/09/12 22:35:37 rgb
|
|
+ * Restructured to remove unused extensions from CLEARFLOW messages.
|
|
+ *
|
|
+ * Revision 1.6 2000/09/09 06:39:01 rgb
|
|
+ * Added comments for clarity.
|
|
+ *
|
|
+ * Revision 1.5 2000/06/02 22:54:14 rgb
|
|
+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
|
|
+ *
|
|
+ * Revision 1.4 2000/01/21 06:27:56 rgb
|
|
+ * Added address cases for eroute flows.
|
|
+ * Added comments for each message type.
|
|
+ * Added klipsdebug switching capability.
|
|
+ * Fixed GRPSA bitfields.
|
|
+ *
|
|
+ * Revision 1.3 1999/12/01 22:20:27 rgb
|
|
+ * Remove requirement for a proxy address in an incoming getspi message.
|
|
+ *
|
|
+ * Revision 1.2 1999/11/27 11:57:06 rgb
|
|
+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
|
|
+ * Add CVS log entry to bottom of file.
|
|
+ * Cleaned out unused bits.
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,951 @@
|
|
+/*
|
|
+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
|
|
+ * Copyright (C) 1998-2003 Richard Guy Briggs.
|
|
+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: pfkey_v2_ext_process.c,v 1.20.2.2 2006/10/06 21:39:26 paul Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
|
|
+ */
|
|
+
|
|
+char pfkey_v2_ext_process_c_version[] = "$Id: pfkey_v2_ext_process.c,v 1.20.2.2 2006/10/06 21:39:26 paul Exp $";
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+
|
|
+#include <openswan.h>
|
|
+
|
|
+#include <crypto/des.h>
|
|
+
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+#ifdef NET_21
|
|
+# include <linux/in6.h>
|
|
+# define ip_chk_addr inet_addr_type
|
|
+# define IS_MYADDR RTN_LOCAL
|
|
+#endif
|
|
+
|
|
+#include <net/ip.h>
|
|
+#ifdef NETLINK_SOCK
|
|
+# include <linux/netlink.h>
|
|
+#else
|
|
+# include <net/netlink.h>
|
|
+#endif
|
|
+
|
|
+#include <linux/random.h> /* get_random_bytes() */
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_esp.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#include "openswan/ipcomp.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#include "openswan/ipsec_alg.h"
|
|
+
|
|
+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
|
|
+
|
|
+int
|
|
+pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
|
|
+ int error = 0;
|
|
+ struct ipsec_sa* ipsp;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sa_process: .\n");
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sa_process: "
|
|
+ "extr or extr->ips is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_ext->sadb_ext_type) {
|
|
+ case SADB_EXT_SA:
|
|
+ ipsp = extr->ips;
|
|
+ break;
|
|
+ case SADB_X_EXT_SA2:
|
|
+ if(extr->ips2 == NULL) {
|
|
+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
|
|
+ }
|
|
+ if(extr->ips2 == NULL) {
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ ipsp = extr->ips2;
|
|
+ break;
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sa_process: "
|
|
+ "invalid exttype=%d.\n",
|
|
+ pfkey_ext->sadb_ext_type);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
|
|
+ ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
|
|
+ ipsp->ips_state = pfkey_sa->sadb_sa_state;
|
|
+ ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
|
|
+ ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
|
|
+ ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref;
|
|
+
|
|
+ switch(ipsp->ips_said.proto) {
|
|
+ case IPPROTO_AH:
|
|
+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
|
|
+ ipsp->ips_encalg = SADB_EALG_NONE;
|
|
+ break;
|
|
+ case IPPROTO_ESP:
|
|
+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
|
|
+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
|
|
+ ipsec_alg_sa_init(ipsp);
|
|
+ break;
|
|
+ case IPPROTO_IPIP:
|
|
+ ipsp->ips_authalg = AH_NONE;
|
|
+ ipsp->ips_encalg = ESP_NONE;
|
|
+ break;
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ case IPPROTO_COMP:
|
|
+ ipsp->ips_authalg = AH_NONE;
|
|
+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
|
|
+ break;
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ case IPPROTO_INT:
|
|
+ ipsp->ips_authalg = AH_NONE;
|
|
+ ipsp->ips_encalg = ESP_NONE;
|
|
+ break;
|
|
+ case 0:
|
|
+ break;
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sa_process: "
|
|
+ "unknown proto=%d.\n",
|
|
+ ipsp->ips_said.proto);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_lifetime_process: .\n");
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_lifetime_process: "
|
|
+ "extr or extr->ips is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_lifetime->sadb_lifetime_exttype) {
|
|
+ case SADB_EXT_LIFETIME_CURRENT:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_lifetime_process: "
|
|
+ "lifetime_current not supported yet.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ break;
|
|
+ case SADB_EXT_LIFETIME_HARD:
|
|
+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
|
|
+ pfkey_lifetime->sadb_lifetime_allocations);
|
|
+
|
|
+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
|
|
+ pfkey_lifetime->sadb_lifetime_bytes);
|
|
+
|
|
+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
|
|
+ pfkey_lifetime->sadb_lifetime_addtime);
|
|
+
|
|
+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
|
|
+ pfkey_lifetime->sadb_lifetime_usetime);
|
|
+
|
|
+ break;
|
|
+
|
|
+ case SADB_EXT_LIFETIME_SOFT:
|
|
+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
|
|
+ pfkey_lifetime->sadb_lifetime_allocations);
|
|
+
|
|
+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
|
|
+ pfkey_lifetime->sadb_lifetime_bytes);
|
|
+
|
|
+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
|
|
+ pfkey_lifetime->sadb_lifetime_addtime);
|
|
+
|
|
+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
|
|
+ pfkey_lifetime->sadb_lifetime_usetime);
|
|
+
|
|
+ break;
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_lifetime_process: "
|
|
+ "invalid exttype=%d.\n",
|
|
+ pfkey_ext->sadb_ext_type);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ int saddr_len = 0;
|
|
+ char ipaddr_txt[ADDRTOA_BUF];
|
|
+ unsigned char **sap;
|
|
+ unsigned short * portp = 0;
|
|
+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
|
|
+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
|
|
+ struct ipsec_sa* ipsp;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process:\n");
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "extr or extr->ips is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(s->sa_family) {
|
|
+ case AF_INET:
|
|
+ saddr_len = sizeof(struct sockaddr_in);
|
|
+ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found address family=%d, AF_INET, %s.\n",
|
|
+ s->sa_family,
|
|
+ ipaddr_txt);
|
|
+ break;
|
|
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
+ case AF_INET6:
|
|
+ saddr_len = sizeof(struct sockaddr_in6);
|
|
+ break;
|
|
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "s->sa_family=%d not supported.\n",
|
|
+ s->sa_family);
|
|
+ SENDERR(EPFNOSUPPORT);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_address->sadb_address_exttype) {
|
|
+ case SADB_EXT_ADDRESS_SRC:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found src address.\n");
|
|
+ sap = (unsigned char **)&(extr->ips->ips_addr_s);
|
|
+ extr->ips->ips_addr_s_size = saddr_len;
|
|
+ break;
|
|
+ case SADB_EXT_ADDRESS_DST:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found dst address.\n");
|
|
+ sap = (unsigned char **)&(extr->ips->ips_addr_d);
|
|
+ extr->ips->ips_addr_d_size = saddr_len;
|
|
+ break;
|
|
+ case SADB_EXT_ADDRESS_PROXY:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found proxy address.\n");
|
|
+ sap = (unsigned char **)&(extr->ips->ips_addr_p);
|
|
+ extr->ips->ips_addr_p_size = saddr_len;
|
|
+ break;
|
|
+ case SADB_X_EXT_ADDRESS_DST2:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found 2nd dst address.\n");
|
|
+ if(extr->ips2 == NULL) {
|
|
+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
|
|
+ }
|
|
+ if(extr->ips2 == NULL) {
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ sap = (unsigned char **)&(extr->ips2->ips_addr_d);
|
|
+ extr->ips2->ips_addr_d_size = saddr_len;
|
|
+ break;
|
|
+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found src flow address.\n");
|
|
+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
|
|
+ portp = &(extr->eroute->er_eaddr.sen_sport);
|
|
+ break;
|
|
+ case SADB_X_EXT_ADDRESS_DST_FLOW:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found dst flow address.\n");
|
|
+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
|
|
+ portp = &(extr->eroute->er_eaddr.sen_dport);
|
|
+ break;
|
|
+ case SADB_X_EXT_ADDRESS_SRC_MASK:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found src mask address.\n");
|
|
+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
|
|
+ portp = &(extr->eroute->er_emask.sen_sport);
|
|
+ break;
|
|
+ case SADB_X_EXT_ADDRESS_DST_MASK:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found dst mask address.\n");
|
|
+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
|
|
+ portp = &(extr->eroute->er_emask.sen_dport);
|
|
+ break;
|
|
+#ifdef NAT_TRAVERSAL
|
|
+ case SADB_X_EXT_NAT_T_OA:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "found NAT-OA address.\n");
|
|
+ sap = (unsigned char **)&(extr->ips->ips_natt_oa);
|
|
+ extr->ips->ips_natt_oa_size = saddr_len;
|
|
+ break;
|
|
+#endif
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "unrecognised ext_type=%d.\n",
|
|
+ pfkey_address->sadb_address_exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_address->sadb_address_exttype) {
|
|
+ case SADB_EXT_ADDRESS_SRC:
|
|
+ case SADB_EXT_ADDRESS_DST:
|
|
+ case SADB_EXT_ADDRESS_PROXY:
|
|
+ case SADB_X_EXT_ADDRESS_DST2:
|
|
+#ifdef NAT_TRAVERSAL
|
|
+ case SADB_X_EXT_NAT_T_OA:
|
|
+#endif
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "allocating %d bytes for saddr.\n",
|
|
+ saddr_len);
|
|
+ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memcpy(*sap, s, saddr_len);
|
|
+ break;
|
|
+ default:
|
|
+ if(s->sa_family != AF_INET) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "s->sa_family=%d not supported.\n",
|
|
+ s->sa_family);
|
|
+ SENDERR(EPFNOSUPPORT);
|
|
+ }
|
|
+ {
|
|
+ unsigned long *ulsap = (unsigned long *)sap;
|
|
+ *ulsap = ((struct sockaddr_in*)s)->sin_addr.s_addr;
|
|
+ }
|
|
+
|
|
+ if (portp != 0)
|
|
+ *portp = ((struct sockaddr_in*)s)->sin_port;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(extr->eroute) {
|
|
+ char buf1[64], buf2[64];
|
|
+ if (debug_pfkey) {
|
|
+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
|
|
+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
|
|
+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_parse: "
|
|
+ "extr->eroute set to %s:%d->%s:%d\n",
|
|
+ buf1,
|
|
+ ntohs(extr->eroute->er_eaddr.sen_sport),
|
|
+ buf2,
|
|
+ ntohs(extr->eroute->er_eaddr.sen_dport));
|
|
+ }
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ }
|
|
+
|
|
+ ipsp = extr->ips;
|
|
+ switch(pfkey_address->sadb_address_exttype) {
|
|
+ case SADB_X_EXT_ADDRESS_DST2:
|
|
+ ipsp = extr->ips2;
|
|
+ case SADB_EXT_ADDRESS_DST:
|
|
+ if(s->sa_family == AF_INET) {
|
|
+ ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
|
|
+ ipsp->ips_said.dst.u.v4.sin_family = AF_INET;
|
|
+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
|
|
+ 0,
|
|
+ ipaddr_txt,
|
|
+ sizeof(ipaddr_txt));
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "ips_said.dst set to %s.\n",
|
|
+ ipaddr_txt);
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: "
|
|
+ "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
|
|
+ s->sa_family);
|
|
+ }
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* XXX check if port!=0 */
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_address_process: successful.\n");
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_key_process: .\n");
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_key_process: "
|
|
+ "extr or extr->ips is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_key->sadb_key_exttype) {
|
|
+ case SADB_EXT_KEY_AUTH:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_key_process: "
|
|
+ "allocating %d bytes for authkey.\n",
|
|
+ DIVUP(pfkey_key->sadb_key_bits, 8));
|
|
+ if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_key_process: "
|
|
+ "memory allocation error.\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
|
|
+ extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
|
|
+ memcpy(extr->ips->ips_key_a,
|
|
+ (char*)pfkey_key + sizeof(struct sadb_key),
|
|
+ extr->ips->ips_key_a_size);
|
|
+ break;
|
|
+ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_key_process: "
|
|
+ "allocating %d bytes for enckey.\n",
|
|
+ DIVUP(pfkey_key->sadb_key_bits, 8));
|
|
+ if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_key_process: "
|
|
+ "memory allocation error.\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
|
|
+ extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
|
|
+ memcpy(extr->ips->ips_key_e,
|
|
+ (char*)pfkey_key + sizeof(struct sadb_key),
|
|
+ extr->ips->ips_key_e_size);
|
|
+ break;
|
|
+ default:
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_key_process: "
|
|
+ "success.\n");
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
|
|
+ int data_len;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_ident_process: .\n");
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_ident_process: "
|
|
+ "extr or extr->ips is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_ident->sadb_ident_exttype) {
|
|
+ case SADB_EXT_IDENTITY_SRC:
|
|
+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
|
|
+
|
|
+ extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
|
|
+ extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
|
|
+ extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
|
|
+ if(data_len) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_ident_process: "
|
|
+ "allocating %d bytes for ident_s.\n",
|
|
+ data_len);
|
|
+ if(!(extr->ips->ips_ident_s.data
|
|
+ = kmalloc(data_len, GFP_KERNEL))) {
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memcpy(extr->ips->ips_ident_s.data,
|
|
+ (char*)pfkey_ident + sizeof(struct sadb_ident),
|
|
+ data_len);
|
|
+ } else {
|
|
+ extr->ips->ips_ident_s.data = NULL;
|
|
+ }
|
|
+ break;
|
|
+ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
|
|
+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
|
|
+
|
|
+ extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
|
|
+ extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
|
|
+ extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
|
|
+ if(data_len) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_ident_process: "
|
|
+ "allocating %d bytes for ident_d.\n",
|
|
+ data_len);
|
|
+ if(!(extr->ips->ips_ident_d.data
|
|
+ = kmalloc(data_len, GFP_KERNEL))) {
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ memcpy(extr->ips->ips_ident_d.data,
|
|
+ (char*)pfkey_ident + sizeof(struct sadb_ident),
|
|
+ data_len);
|
|
+ } else {
|
|
+ extr->ips->ips_ident_d.data = NULL;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_sens_process: "
|
|
+ "Sorry, I can't process exttype=%d yet.\n",
|
|
+ pfkey_ext->sadb_ext_type);
|
|
+ SENDERR(EINVAL); /* don't process these yet */
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_prop_process: "
|
|
+ "Sorry, I can't process exttype=%d yet.\n",
|
|
+ pfkey_ext->sadb_ext_type);
|
|
+ SENDERR(EINVAL); /* don't process these yet */
|
|
+
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_supported_process: "
|
|
+ "Sorry, I can't process exttype=%d yet.\n",
|
|
+ pfkey_ext->sadb_ext_type);
|
|
+ SENDERR(EINVAL); /* don't process these yet */
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_spirange_process: .\n");
|
|
+/* errlab: */
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_kmprivate_process: "
|
|
+ "Sorry, I can't process exttype=%d yet.\n",
|
|
+ pfkey_ext->sadb_ext_type);
|
|
+ SENDERR(EINVAL); /* don't process these yet */
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_satype_process: .\n");
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_satype_process: "
|
|
+ "extr or extr->ips is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(extr->ips2 == NULL) {
|
|
+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
|
|
+ }
|
|
+ if(extr->ips2 == NULL) {
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_satype_process: "
|
|
+ "proto lookup from satype=%d failed.\n",
|
|
+ pfkey_x_satype->sadb_x_satype_satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_satype_process: "
|
|
+ "protocol==%d decoded from satype==%d(%s).\n",
|
|
+ extr->ips2->ips_said.proto,
|
|
+ pfkey_x_satype->sadb_x_satype_satype,
|
|
+ satype2name(pfkey_x_satype->sadb_x_satype_satype));
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+int
|
|
+pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
|
|
+
|
|
+ if(!pfkey_x_nat_t_type) {
|
|
+ printk("klips_debug:pfkey_x_nat_t_type_process: "
|
|
+ "null pointer passed in\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
|
|
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_nat_t_type_process: "
|
|
+ "extr or extr->ips is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
|
|
+ case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */
|
|
+ case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
|
|
+
|
|
+ extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
|
|
+ break;
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_nat_t_type_process: "
|
|
+ "unknown type %d.\n",
|
|
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
|
|
+ SENDERR(EINVAL);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
|
|
+
|
|
+ if(!pfkey_x_nat_t_port) {
|
|
+ printk("klips_debug:pfkey_x_nat_t_port_process: "
|
|
+ "null pointer passed in\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
|
|
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
|
|
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_nat_t_type_process: "
|
|
+ "extr or extr->ips is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
|
|
+ case SADB_X_EXT_NAT_T_SPORT:
|
|
+ extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
|
|
+ break;
|
|
+ case SADB_X_EXT_NAT_T_DPORT:
|
|
+ extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
|
|
+ break;
|
|
+ default:
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_nat_t_port_process: "
|
|
+ "unknown exttype %d.\n",
|
|
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+#endif
|
|
+
|
|
+int
|
|
+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
|
|
+
|
|
+ if(!pfkey_x_debug) {
|
|
+ printk("klips_debug:pfkey_x_debug_process: "
|
|
+ "null pointer passed in\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_debug_process: .\n");
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(pfkey_x_debug->sadb_x_debug_netlink >>
|
|
+ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
|
|
+ pfkey_x_debug->sadb_x_debug_netlink &=
|
|
+ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
|
|
+ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
|
|
+ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
|
|
+ debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
|
|
+ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
|
|
+ debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
|
|
+ debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
|
|
+ debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
|
|
+ debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
|
|
+ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
|
|
+ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_debug_process: "
|
|
+ "set\n");
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_debug_process: "
|
|
+ "unset\n");
|
|
+ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
|
|
+ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
|
|
+ debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
|
|
+ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
|
|
+ debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
|
|
+ debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
|
|
+ debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
|
|
+ debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
|
|
+ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
|
|
+ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
|
|
+ }
|
|
+#else /* CONFIG_KLIPS_DEBUG */
|
|
+ printk("klips_debug:pfkey_x_debug_process: "
|
|
+ "debugging not enabled\n");
|
|
+ SENDERR(EINVAL);
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: pfkey_v2_ext_process.c,v $
|
|
+ * Revision 1.20.2.2 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.20.2.1 2006/04/20 16:33:07 mcr
|
|
+ * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
|
|
+ * Fix in-kernel module compilation. Sub-makefiles do not work.
|
|
+ *
|
|
+ * Revision 1.20 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.19 2004/12/04 07:14:18 mcr
|
|
+ * resolution to gcc3-ism was wrong. fixed to assign correct
|
|
+ * variable.
|
|
+ *
|
|
+ * Revision 1.18 2004/12/03 21:25:57 mcr
|
|
+ * compile time fixes for running on 2.6.
|
|
+ * still experimental.
|
|
+ *
|
|
+ * Revision 1.17 2004/08/21 00:45:04 mcr
|
|
+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
|
|
+ *
|
|
+ * Revision 1.16 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.15 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.14 2004/02/03 03:13:59 mcr
|
|
+ * no longer #ifdef out NON_ESP mode. That was a mistake.
|
|
+ *
|
|
+ * Revision 1.13 2003/12/15 18:13:12 mcr
|
|
+ * when compiling with NAT traversal, don't assume that the
|
|
+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
|
|
+ * is set.
|
|
+ *
|
|
+ * Revision 1.12.2.1 2003/12/22 15:25:52 jjo
|
|
+ * Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.12 2003/12/10 01:14:27 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.11 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.10.4.2 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.10.4.1 2003/09/21 13:59:56 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.10 2003/02/06 01:51:41 rgb
|
|
+ * Removed no longer relevant comment
|
|
+ *
|
|
+ * Revision 1.9 2003/01/30 02:32:44 rgb
|
|
+ *
|
|
+ * Transmit error code through to caller from callee for better diagnosis of problems.
|
|
+ *
|
|
+ * Revision 1.8 2002/12/13 22:42:22 mcr
|
|
+ * restored sa_ref code
|
|
+ *
|
|
+ * Revision 1.7 2002/12/13 22:40:48 mcr
|
|
+ * temporarily removed sadb_x_sa_ref reference for 2.xx
|
|
+ *
|
|
+ * Revision 1.6 2002/10/05 05:02:58 dhr
|
|
+ *
|
|
+ * C labels go on statements
|
|
+ *
|
|
+ * Revision 1.5 2002/09/20 15:41:08 rgb
|
|
+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
|
|
+ * Added sadb_x_sa_ref to struct sadb_sa.
|
|
+ *
|
|
+ * Revision 1.4 2002/09/20 05:02:02 rgb
|
|
+ * Added memory allocation debugging.
|
|
+ *
|
|
+ * Revision 1.3 2002/07/24 18:44:54 rgb
|
|
+ * Type fiddling to tame ia64 compiler.
|
|
+ *
|
|
+ * Revision 1.2 2002/05/27 18:55:03 rgb
|
|
+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
|
|
+ *
|
|
+ * Revision 1.1 2002/05/14 02:33:51 rgb
|
|
+ * Moved all the extension processing functions to pfkey_v2_ext_process.c.
|
|
+ *
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1846 @@
|
|
+/*
|
|
+ * RFC2367 PF_KEYv2 Key management API message parser
|
|
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
|
|
+ */
|
|
+
|
|
+char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $";
|
|
+
|
|
+/*
|
|
+ * Some ugly stuff to allow consistent debugging code for use in the
|
|
+ * kernel and in user space
|
|
+*/
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+# include <linux/kernel.h> /* for printk */
|
|
+
|
|
+#include "openswan/ipsec_kversion.h" /* for malloc switch */
|
|
+
|
|
+# ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+# else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+# endif /* MALLOC_SLAB */
|
|
+# include <linux/errno.h> /* error codes */
|
|
+# include <linux/types.h> /* size_t */
|
|
+# include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+# include <linux/netdevice.h> /* struct device, and other headers */
|
|
+# include <linux/etherdevice.h> /* eth_type_trans */
|
|
+# include <linux/ip.h> /* struct iphdr */
|
|
+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
+# include <linux/ipv6.h> /* struct ipv6hdr */
|
|
+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
|
|
+extern int debug_pfkey;
|
|
+
|
|
+# include <openswan.h>
|
|
+
|
|
+#include "openswan/ipsec_encap.h"
|
|
+
|
|
+#else /* __KERNEL__ */
|
|
+
|
|
+# include <sys/types.h>
|
|
+# include <linux/types.h>
|
|
+# include <linux/errno.h>
|
|
+
|
|
+# include <openswan.h>
|
|
+# include "constants.h"
|
|
+# include "programs/pluto/defs.h" /* for PRINTF_LIKE */
|
|
+
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
|
|
+
|
|
+/*
|
|
+ * how to handle debugging for pfkey.
|
|
+ */
|
|
+#include <openswan/pfkey_debug.h>
|
|
+
|
|
+unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;
|
|
+void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
|
|
+void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
|
|
+
|
|
+
|
|
+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
|
|
+
|
|
+struct satype_tbl {
|
|
+ uint8_t proto;
|
|
+ uint8_t satype;
|
|
+ char* name;
|
|
+} static satype_tbl[] = {
|
|
+#ifdef __KERNEL__
|
|
+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
|
|
+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
|
|
+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
|
|
+#else /* __KERNEL__ */
|
|
+ { SA_ESP, SADB_SATYPE_ESP, "ESP" },
|
|
+ { SA_AH, SADB_SATYPE_AH, "AH" },
|
|
+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
|
|
+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
|
|
+ { SA_INT, SADB_X_SATYPE_INT, "INT" },
|
|
+#endif /* __KERNEL__ */
|
|
+ { 0, 0, "UNKNOWN" }
|
|
+};
|
|
+
|
|
+uint8_t
|
|
+satype2proto(uint8_t satype)
|
|
+{
|
|
+ int i =0;
|
|
+
|
|
+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
|
|
+ i++;
|
|
+ }
|
|
+ return satype_tbl[i].proto;
|
|
+}
|
|
+
|
|
+uint8_t
|
|
+proto2satype(uint8_t proto)
|
|
+{
|
|
+ int i = 0;
|
|
+
|
|
+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
|
|
+ i++;
|
|
+ }
|
|
+ return satype_tbl[i].satype;
|
|
+}
|
|
+
|
|
+char*
|
|
+satype2name(uint8_t satype)
|
|
+{
|
|
+ int i = 0;
|
|
+
|
|
+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
|
|
+ i++;
|
|
+ }
|
|
+ return satype_tbl[i].name;
|
|
+}
|
|
+
|
|
+char*
|
|
+proto2name(uint8_t proto)
|
|
+{
|
|
+ int i = 0;
|
|
+
|
|
+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
|
|
+ i++;
|
|
+ }
|
|
+ return satype_tbl[i].name;
|
|
+}
|
|
+
|
|
+/* Default extension parsers taken from the KLIPS code */
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_sa_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
|
|
+#if 0
|
|
+ struct sadb_sa sav2;
|
|
+#endif
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if(!pfkey_sa) {
|
|
+ ERROR("pfkey_sa_parse: "
|
|
+ "NULL pointer passed in.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ /* check if this structure is short, and if so, fix it up.
|
|
+ * XXX this is NOT the way to do things.
|
|
+ */
|
|
+ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
|
|
+
|
|
+ /* yes, so clear out a temporary structure, and copy first */
|
|
+ memset(&sav2, 0, sizeof(sav2));
|
|
+ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
|
|
+ sav2.sadb_x_sa_ref=-1;
|
|
+ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
|
|
+
|
|
+ pfkey_sa = &sav2;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+
|
|
+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ ERROR(
|
|
+ "pfkey_sa_parse: "
|
|
+ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
|
|
+ pfkey_sa->sadb_sa_len,
|
|
+ (int)sizeof(struct sadb_sa));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+#if SADB_EALG_MAX < 255
|
|
+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
|
|
+ ERROR(
|
|
+ "pfkey_sa_parse: "
|
|
+ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
|
|
+ pfkey_sa->sadb_sa_encrypt,
|
|
+ SADB_EALG_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#if SADB_AALG_MAX < 255
|
|
+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
|
|
+ ERROR(
|
|
+ "pfkey_sa_parse: "
|
|
+ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
|
|
+ pfkey_sa->sadb_sa_auth,
|
|
+ SADB_AALG_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#if SADB_SASTATE_MAX < 255
|
|
+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
|
|
+ ERROR(
|
|
+ "pfkey_sa_parse: "
|
|
+ "state=%d exceeds MAX=%d.\n",
|
|
+ pfkey_sa->sadb_sa_state,
|
|
+ SADB_SASTATE_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
|
|
+ ERROR(
|
|
+ "pfkey_sa_parse: "
|
|
+ "state=%d is DEAD=%d.\n",
|
|
+ pfkey_sa->sadb_sa_state,
|
|
+ SADB_SASTATE_DEAD);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_sa->sadb_sa_replay > 64) {
|
|
+ ERROR(
|
|
+ "pfkey_sa_parse: "
|
|
+ "replay window size: %d -- must be 0 <= size <= 64\n",
|
|
+ pfkey_sa->sadb_sa_replay);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
|
|
+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
|
|
+ {
|
|
+ ERROR(
|
|
+ "pfkey_sa_parse: "
|
|
+ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
|
|
+ pfkey_sa->sadb_sa_exttype,
|
|
+ SADB_EXT_SA,
|
|
+ SADB_X_EXT_SA2);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
|
|
+ ERROR(
|
|
+ "pfkey_sa_parse: "
|
|
+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
|
|
+ pfkey_sa->sadb_x_sa_ref,
|
|
+ IPSEC_SAREF_NULL,
|
|
+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_sa_parse: "
|
|
+ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
|
|
+ pfkey_sa->sadb_sa_len,
|
|
+ pfkey_sa->sadb_sa_exttype,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
|
|
+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
|
|
+ pfkey_sa->sadb_sa_replay,
|
|
+ pfkey_sa->sadb_sa_state,
|
|
+ pfkey_sa->sadb_sa_auth,
|
|
+ pfkey_sa->sadb_sa_encrypt,
|
|
+ pfkey_sa->sadb_sa_flags,
|
|
+ pfkey_sa->sadb_x_sa_ref);
|
|
+
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
|
|
+ "pfkey_lifetime_parse:enter\n");
|
|
+ /* sanity checks... */
|
|
+ if(!pfkey_lifetime) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_lifetime_parse: "
|
|
+ "NULL pointer passed in.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_lifetime->sadb_lifetime_len !=
|
|
+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_lifetime_parse: "
|
|
+ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
|
|
+ pfkey_lifetime->sadb_lifetime_len,
|
|
+ (int)sizeof(struct sadb_lifetime));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
|
|
+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
|
|
+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_lifetime_parse: "
|
|
+ "unexpected ext_type=%d.\n",
|
|
+ pfkey_lifetime->sadb_lifetime_exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_lifetime_parse: "
|
|
+ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n",
|
|
+ pfkey_lifetime->sadb_lifetime_exttype,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
|
|
+ pfkey_lifetime->sadb_lifetime_allocations,
|
|
+ (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
|
|
+ (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
|
|
+ (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
|
|
+ pfkey_lifetime->sadb_x_lifetime_packets);
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_address_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ int saddr_len = 0;
|
|
+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
|
|
+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
|
|
+ char ipaddr_txt[ADDRTOT_BUF];
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if(!pfkey_address) {
|
|
+ ERROR(
|
|
+ "pfkey_address_parse: "
|
|
+ "NULL pointer passed in.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_address->sadb_address_len <
|
|
+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
|
|
+ IPSEC_PFKEYv2_ALIGN) {
|
|
+ ERROR("pfkey_address_parse: "
|
|
+ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
|
|
+ pfkey_address->sadb_address_len,
|
|
+ (int)sizeof(struct sadb_address),
|
|
+ (int)sizeof(struct sockaddr));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_address->sadb_address_reserved) {
|
|
+ ERROR("pfkey_address_parse: "
|
|
+ "res=%d, must be zero.\n",
|
|
+ pfkey_address->sadb_address_reserved);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_address->sadb_address_exttype) {
|
|
+ case SADB_EXT_ADDRESS_SRC:
|
|
+ case SADB_EXT_ADDRESS_DST:
|
|
+ case SADB_EXT_ADDRESS_PROXY:
|
|
+ case SADB_X_EXT_ADDRESS_DST2:
|
|
+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
|
|
+ case SADB_X_EXT_ADDRESS_DST_FLOW:
|
|
+ case SADB_X_EXT_ADDRESS_SRC_MASK:
|
|
+ case SADB_X_EXT_ADDRESS_DST_MASK:
|
|
+#ifdef NAT_TRAVERSAL
|
|
+ case SADB_X_EXT_NAT_T_OA:
|
|
+#endif
|
|
+ break;
|
|
+ default:
|
|
+ ERROR(
|
|
+ "pfkey_address_parse: "
|
|
+ "unexpected ext_type=%d.\n",
|
|
+ pfkey_address->sadb_address_exttype);
|
|
+ SENDERR(ENOPKG);
|
|
+ }
|
|
+
|
|
+ switch(s->sa_family) {
|
|
+ case AF_INET:
|
|
+ saddr_len = sizeof(struct sockaddr_in);
|
|
+ sprintf(ipaddr_txt, "%d.%d.%d.%d"
|
|
+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
|
|
+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
|
|
+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
|
|
+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_address_parse: "
|
|
+ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
|
|
+ pfkey_address->sadb_address_exttype,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
|
|
+ s->sa_family,
|
|
+ ipaddr_txt,
|
|
+ pfkey_address->sadb_address_proto,
|
|
+ ntohs(((struct sockaddr_in*)s)->sin_port));
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ saddr_len = sizeof(struct sockaddr_in6);
|
|
+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
|
|
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
|
|
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
|
|
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
|
|
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
|
|
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
|
|
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
|
|
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
|
|
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_address_parse: "
|
|
+ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
|
|
+ pfkey_address->sadb_address_exttype,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
|
|
+ s->sa_family,
|
|
+ ipaddr_txt,
|
|
+ pfkey_address->sadb_address_proto,
|
|
+ ((struct sockaddr_in6*)s)->sin6_port);
|
|
+ break;
|
|
+ default:
|
|
+ ERROR(
|
|
+ "pfkey_address_parse: "
|
|
+ "s->sa_family=%d not supported.\n",
|
|
+ s->sa_family);
|
|
+ SENDERR(EPFNOSUPPORT);
|
|
+ }
|
|
+
|
|
+ if(pfkey_address->sadb_address_len !=
|
|
+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
|
|
+ ERROR(
|
|
+ "pfkey_address_parse: "
|
|
+ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
|
|
+ pfkey_address->sadb_address_len,
|
|
+ (int)sizeof(struct sadb_address),
|
|
+ saddr_len);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_address->sadb_address_prefixlen != 0) {
|
|
+ ERROR(
|
|
+ "pfkey_address_parse: "
|
|
+ "address prefixes not supported yet.\n");
|
|
+ SENDERR(EAFNOSUPPORT); /* not supported yet */
|
|
+ }
|
|
+
|
|
+ /* XXX check if port!=0 */
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
|
|
+ "pfkey_address_parse: successful.\n");
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_key_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
|
|
+
|
|
+ /* sanity checks... */
|
|
+
|
|
+ if(!pfkey_key) {
|
|
+ ERROR(
|
|
+ "pfkey_key_parse: "
|
|
+ "NULL pointer passed in.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ ERROR(
|
|
+ "pfkey_key_parse: "
|
|
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
|
|
+ pfkey_key->sadb_key_len,
|
|
+ (int)sizeof(struct sadb_key));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!pfkey_key->sadb_key_bits) {
|
|
+ ERROR(
|
|
+ "pfkey_key_parse: "
|
|
+ "key length set to zero, must be non-zero.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_key->sadb_key_len !=
|
|
+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
|
|
+ PFKEYBITS)) {
|
|
+ ERROR(
|
|
+ "pfkey_key_parse: "
|
|
+ "key length=%d does not agree with extension length=%d.\n",
|
|
+ pfkey_key->sadb_key_bits,
|
|
+ pfkey_key->sadb_key_len);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_key->sadb_key_reserved) {
|
|
+ ERROR(
|
|
+ "pfkey_key_parse: "
|
|
+ "res=%d, must be zero.\n",
|
|
+ pfkey_key->sadb_key_reserved);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
|
|
+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
|
|
+ ERROR(
|
|
+ "pfkey_key_parse: "
|
|
+ "expecting extension type AUTH or ENCRYPT, got %d.\n",
|
|
+ pfkey_key->sadb_key_exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_key_parse: "
|
|
+ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
|
|
+ pfkey_key->sadb_key_len,
|
|
+ pfkey_key->sadb_key_exttype,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
|
|
+ pfkey_key->sadb_key_bits,
|
|
+ pfkey_key->sadb_key_reserved);
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_ident_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ ERROR(
|
|
+ "pfkey_ident_parse: "
|
|
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
|
|
+ pfkey_ident->sadb_ident_len,
|
|
+ (int)sizeof(struct sadb_ident));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
|
|
+ ERROR(
|
|
+ "pfkey_ident_parse: "
|
|
+ "ident_type=%d out of range, must be less than %d.\n",
|
|
+ pfkey_ident->sadb_ident_type,
|
|
+ SADB_IDENTTYPE_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_ident->sadb_ident_reserved) {
|
|
+ ERROR(
|
|
+ "pfkey_ident_parse: "
|
|
+ "res=%d, must be zero.\n",
|
|
+ pfkey_ident->sadb_ident_reserved);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ /* string terminator/padding must be zero */
|
|
+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
|
|
+ ERROR(
|
|
+ "pfkey_ident_parse: "
|
|
+ "string padding must be zero, last is 0x%02x.\n",
|
|
+ *((char*)pfkey_ident +
|
|
+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
|
|
+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
|
|
+ ERROR(
|
|
+ "pfkey_key_parse: "
|
|
+ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
|
|
+ pfkey_ident->sadb_ident_exttype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_sens_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_sens_parse: "
|
|
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
|
|
+ pfkey_sens->sadb_sens_len,
|
|
+ (int)sizeof(struct sadb_sens));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_sens_parse: "
|
|
+ "Sorry, I can't parse exttype=%d yet.\n",
|
|
+ pfkey_ext->sadb_ext_type);
|
|
+#if 0
|
|
+ SENDERR(EINVAL); /* don't process these yet */
|
|
+#endif
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_prop_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i, num_comb;
|
|
+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
|
|
+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
|
|
+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
|
|
+ pfkey_prop->sadb_prop_len,
|
|
+ (int)sizeof(struct sadb_prop),
|
|
+ (int)sizeof(struct sadb_comb));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_prop->sadb_prop_replay > 64) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "replay window size: %d -- must be 0 <= size <= 64\n",
|
|
+ pfkey_prop->sadb_prop_replay);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ for(i=0; i<3; i++) {
|
|
+ if(pfkey_prop->sadb_prop_reserved[i]) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "res[%d]=%d, must be zero.\n",
|
|
+ i, pfkey_prop->sadb_prop_reserved[i]);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
|
|
+
|
|
+ for(i = 0; i < num_comb; i++) {
|
|
+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_auth,
|
|
+ SADB_AALG_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_comb->sadb_comb_auth) {
|
|
+ if(!pfkey_comb->sadb_comb_auth_minbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
|
|
+ i);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if(!pfkey_comb->sadb_comb_auth_maxbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
|
|
+ i);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_auth_minbits,
|
|
+ pfkey_comb->sadb_comb_auth_maxbits);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ } else {
|
|
+ if(pfkey_comb->sadb_comb_auth_minbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_auth_minbits);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if(pfkey_comb->sadb_comb_auth_maxbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_auth_maxbits);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ }
|
|
+
|
|
+#if SADB_EALG_MAX < 255
|
|
+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_comb_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_encrypt,
|
|
+ SADB_EALG_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if(pfkey_comb->sadb_comb_encrypt) {
|
|
+ if(!pfkey_comb->sadb_comb_encrypt_minbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
|
|
+ i);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
|
|
+ i);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_encrypt_minbits,
|
|
+ pfkey_comb->sadb_comb_encrypt_maxbits);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ } else {
|
|
+ if(pfkey_comb->sadb_comb_encrypt_minbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_encrypt_minbits);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if(pfkey_comb->sadb_comb_encrypt_maxbits) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_encrypt_maxbits);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* XXX do sanity check on flags */
|
|
+
|
|
+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_soft_allocations,
|
|
+ pfkey_comb->sadb_comb_hard_allocations);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
|
|
+ i,
|
|
+ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
|
|
+ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
|
|
+ i,
|
|
+ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
|
|
+ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
|
|
+ i,
|
|
+ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
|
|
+ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_x_comb_soft_packets,
|
|
+ pfkey_comb->sadb_x_comb_hard_packets);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_comb->sadb_comb_reserved) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_prop_parse: "
|
|
+ "comb[%d].res=%d, must be zero.\n",
|
|
+ i,
|
|
+ pfkey_comb->sadb_comb_reserved);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ pfkey_comb++;
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_supported_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ unsigned int i, num_alg;
|
|
+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
|
|
+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if((pfkey_supported->sadb_supported_len <
|
|
+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
|
|
+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
|
|
+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_supported_parse: "
|
|
+ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
|
|
+ pfkey_supported->sadb_supported_len,
|
|
+ (int)sizeof(struct sadb_supported),
|
|
+ (int)sizeof(struct sadb_alg));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_supported->sadb_supported_reserved) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_supported_parse: "
|
|
+ "res=%d, must be zero.\n",
|
|
+ pfkey_supported->sadb_supported_reserved);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
|
|
+
|
|
+ for(i = 0; i < num_alg; i++) {
|
|
+ /* process algo description */
|
|
+ if(pfkey_alg->sadb_alg_reserved) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_supported_parse: "
|
|
+ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
|
|
+ i,
|
|
+ pfkey_alg->sadb_alg_id,
|
|
+ pfkey_alg->sadb_alg_ivlen,
|
|
+ pfkey_alg->sadb_alg_minbits,
|
|
+ pfkey_alg->sadb_alg_maxbits,
|
|
+ pfkey_alg->sadb_alg_reserved);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ /* XXX can alg_id auth/enc be determined from info given?
|
|
+ Yes, but OpenBSD's method does not iteroperate with rfc2367.
|
|
+ rgb, 2000-04-06 */
|
|
+
|
|
+ switch(pfkey_supported->sadb_supported_exttype) {
|
|
+ case SADB_EXT_SUPPORTED_AUTH:
|
|
+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_supported_parse: "
|
|
+ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
|
|
+ i,
|
|
+ pfkey_alg->sadb_alg_id,
|
|
+ SADB_AALG_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ break;
|
|
+ case SADB_EXT_SUPPORTED_ENCRYPT:
|
|
+#if SADB_EALG_MAX < 255
|
|
+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_supported_parse: "
|
|
+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
|
|
+ i,
|
|
+ pfkey_alg->sadb_alg_id,
|
|
+ SADB_EALG_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+#endif
|
|
+ break;
|
|
+ default:
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_supported_parse: "
|
|
+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
|
|
+ i,
|
|
+ pfkey_alg->sadb_alg_id,
|
|
+ SADB_EALG_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ pfkey_alg++;
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_spirange->sadb_spirange_len !=
|
|
+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_spirange_parse: "
|
|
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
|
|
+ pfkey_spirange->sadb_spirange_len,
|
|
+ (int)sizeof(struct sadb_spirange));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_spirange->sadb_spirange_reserved) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_spirange_parse: "
|
|
+ "reserved=%d must be set to zero.\n",
|
|
+ pfkey_spirange->sadb_spirange_reserved);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_spirange_parse: "
|
|
+ "minspi=%08x must be < maxspi=%08x.\n",
|
|
+ ntohl(pfkey_spirange->sadb_spirange_min),
|
|
+ ntohl(pfkey_spirange->sadb_spirange_max));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_spirange_parse: "
|
|
+ "minspi=%08x must be > 255.\n",
|
|
+ ntohl(pfkey_spirange->sadb_spirange_min));
|
|
+ SENDERR(EEXIST);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_spirange_parse: "
|
|
+ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
|
|
+ pfkey_spirange->sadb_spirange_len,
|
|
+ pfkey_spirange->sadb_spirange_exttype,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
|
|
+ pfkey_spirange->sadb_spirange_min,
|
|
+ pfkey_spirange->sadb_spirange_max,
|
|
+ pfkey_spirange->sadb_spirange_reserved);
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
|
|
+
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
|
|
+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_kmprivate_parse: "
|
|
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
|
|
+ pfkey_x_kmprivate->sadb_x_kmprivate_len,
|
|
+ (int)sizeof(struct sadb_x_kmprivate));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_kmprivate_parse: "
|
|
+ "reserved=%d must be set to zero.\n",
|
|
+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_kmprivate_parse: "
|
|
+ "Sorry, I can't parse exttype=%d yet.\n",
|
|
+ pfkey_ext->sadb_ext_type);
|
|
+ SENDERR(EINVAL); /* don't process these yet */
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
|
|
+ "pfkey_x_satype_parse: enter\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_x_satype->sadb_x_satype_len !=
|
|
+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_satype_parse: "
|
|
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
|
|
+ pfkey_x_satype->sadb_x_satype_len,
|
|
+ (int)sizeof(struct sadb_x_satype));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!pfkey_x_satype->sadb_x_satype_satype) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_satype_parse: "
|
|
+ "satype is zero, must be non-zero.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_satype_parse: "
|
|
+ "satype %d > max %d, invalid.\n",
|
|
+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_satype_parse: "
|
|
+ "proto lookup from satype=%d failed.\n",
|
|
+ pfkey_x_satype->sadb_x_satype_satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ for(i = 0; i < 3; i++) {
|
|
+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_satype_parse: "
|
|
+ "reserved[%d]=%d must be set to zero.\n",
|
|
+ i, pfkey_x_satype->sadb_x_satype_reserved[i]);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_x_satype_parse: "
|
|
+ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
|
|
+ pfkey_x_satype->sadb_x_satype_len,
|
|
+ pfkey_x_satype->sadb_x_satype_exttype,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
|
|
+ pfkey_x_satype->sadb_x_satype_satype,
|
|
+ satype2name(pfkey_x_satype->sadb_x_satype_satype),
|
|
+ pfkey_x_satype->sadb_x_satype_reserved[0],
|
|
+ pfkey_x_satype->sadb_x_satype_reserved[1],
|
|
+ pfkey_x_satype->sadb_x_satype_reserved[2]);
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
|
|
+ "pfkey_x_debug_parse: enter\n");
|
|
+ /* sanity checks... */
|
|
+ if(pfkey_x_debug->sadb_x_debug_len !=
|
|
+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_debug_parse: "
|
|
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
|
|
+ pfkey_x_debug->sadb_x_debug_len,
|
|
+ (int)sizeof(struct sadb_x_debug));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ for(i = 0; i < 4; i++) {
|
|
+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_debug_parse: "
|
|
+ "reserved[%d]=%d must be set to zero.\n",
|
|
+ i, pfkey_x_debug->sadb_x_debug_reserved[i]);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ }
|
|
+
|
|
+errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
|
|
+ /* sanity checks... */
|
|
+
|
|
+ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
|
|
+ p->sadb_protocol_len, (int)sizeof(*p));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if (p->sadb_protocol_reserved2 != 0) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_protocol_parse: res=%d, must be zero.\n",
|
|
+ p->sadb_protocol_reserved2);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+#ifdef NAT_TRAVERSAL
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
+#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
|
|
+
|
|
+DEFINEPARSER(pfkey_sa_parse);
|
|
+DEFINEPARSER(pfkey_lifetime_parse);
|
|
+DEFINEPARSER(pfkey_address_parse);
|
|
+DEFINEPARSER(pfkey_key_parse);
|
|
+DEFINEPARSER(pfkey_ident_parse);
|
|
+DEFINEPARSER(pfkey_sens_parse);
|
|
+DEFINEPARSER(pfkey_prop_parse);
|
|
+DEFINEPARSER(pfkey_supported_parse);
|
|
+DEFINEPARSER(pfkey_spirange_parse);
|
|
+DEFINEPARSER(pfkey_x_kmprivate_parse);
|
|
+DEFINEPARSER(pfkey_x_satype_parse);
|
|
+DEFINEPARSER(pfkey_x_ext_debug_parse);
|
|
+DEFINEPARSER(pfkey_x_ext_protocol_parse);
|
|
+#ifdef NAT_TRAVERSAL
|
|
+DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
|
|
+DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
|
|
+#endif
|
|
+
|
|
+struct pf_key_ext_parsers_def *ext_default_parsers[]=
|
|
+{
|
|
+ NULL, /* pfkey_msg_parse, */
|
|
+ &pfkey_sa_parse_def,
|
|
+ &pfkey_lifetime_parse_def,
|
|
+ &pfkey_lifetime_parse_def,
|
|
+ &pfkey_lifetime_parse_def,
|
|
+ &pfkey_address_parse_def,
|
|
+ &pfkey_address_parse_def,
|
|
+ &pfkey_address_parse_def,
|
|
+ &pfkey_key_parse_def,
|
|
+ &pfkey_key_parse_def,
|
|
+ &pfkey_ident_parse_def,
|
|
+ &pfkey_ident_parse_def,
|
|
+ &pfkey_sens_parse_def,
|
|
+ &pfkey_prop_parse_def,
|
|
+ &pfkey_supported_parse_def,
|
|
+ &pfkey_supported_parse_def,
|
|
+ &pfkey_spirange_parse_def,
|
|
+ &pfkey_x_kmprivate_parse_def,
|
|
+ &pfkey_x_satype_parse_def,
|
|
+ &pfkey_sa_parse_def,
|
|
+ &pfkey_address_parse_def,
|
|
+ &pfkey_address_parse_def,
|
|
+ &pfkey_address_parse_def,
|
|
+ &pfkey_address_parse_def,
|
|
+ &pfkey_address_parse_def,
|
|
+ &pfkey_x_ext_debug_parse_def,
|
|
+ &pfkey_x_ext_protocol_parse_def
|
|
+#ifdef NAT_TRAVERSAL
|
|
+ ,
|
|
+ &pfkey_x_ext_nat_t_type_parse_def,
|
|
+ &pfkey_x_ext_nat_t_port_parse_def,
|
|
+ &pfkey_x_ext_nat_t_port_parse_def,
|
|
+ &pfkey_address_parse_def
|
|
+#endif
|
|
+};
|
|
+
|
|
+int
|
|
+pfkey_msg_parse(struct sadb_msg *pfkey_msg,
|
|
+ struct pf_key_ext_parsers_def *ext_parsers[],
|
|
+ struct sadb_ext *extensions[],
|
|
+ int dir)
|
|
+{
|
|
+ int error = 0;
|
|
+ int remain;
|
|
+ struct sadb_ext *pfkey_ext;
|
|
+ int extensions_seen = 0;
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_msg_parse: "
|
|
+ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
|
|
+ pfkey_msg->sadb_msg_version,
|
|
+ pfkey_msg->sadb_msg_type,
|
|
+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
|
|
+ pfkey_msg->sadb_msg_errno,
|
|
+ pfkey_msg->sadb_msg_satype,
|
|
+ satype2name(pfkey_msg->sadb_msg_satype),
|
|
+ pfkey_msg->sadb_msg_len,
|
|
+ pfkey_msg->sadb_msg_reserved,
|
|
+ pfkey_msg->sadb_msg_seq,
|
|
+ pfkey_msg->sadb_msg_pid);
|
|
+
|
|
+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
|
|
+
|
|
+ pfkey_extensions_init(extensions);
|
|
+
|
|
+ remain = pfkey_msg->sadb_msg_len;
|
|
+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
|
|
+
|
|
+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
|
|
+ sizeof(struct sadb_msg));
|
|
+
|
|
+ extensions[0] = (struct sadb_ext *) pfkey_msg;
|
|
+
|
|
+
|
|
+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
|
|
+ ERROR("pfkey_msg_parse: "
|
|
+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
|
|
+ pfkey_msg->sadb_msg_version,
|
|
+ PF_KEY_V2);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!pfkey_msg->sadb_msg_type) {
|
|
+ ERROR("pfkey_msg_parse: "
|
|
+ "msg type not set, must be non-zero..\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(pfkey_msg->sadb_msg_type > SADB_MAX) {
|
|
+ ERROR("pfkey_msg_parse: "
|
|
+ "msg type=%d > max=%d.\n",
|
|
+ pfkey_msg->sadb_msg_type,
|
|
+ SADB_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_msg->sadb_msg_type) {
|
|
+ case SADB_GETSPI:
|
|
+ case SADB_UPDATE:
|
|
+ case SADB_ADD:
|
|
+ case SADB_DELETE:
|
|
+ case SADB_GET:
|
|
+ case SADB_X_GRPSA:
|
|
+ case SADB_X_ADDFLOW:
|
|
+ if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
|
|
+ ERROR("pfkey_msg_parse: "
|
|
+ "satype %d conversion to proto failed for msg_type %d (%s).\n",
|
|
+ pfkey_msg->sadb_msg_satype,
|
|
+ pfkey_msg->sadb_msg_type,
|
|
+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
|
|
+ SENDERR(EINVAL);
|
|
+ } else {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
|
|
+ pfkey_msg->sadb_msg_satype,
|
|
+ satype2name(pfkey_msg->sadb_msg_satype),
|
|
+ satype2proto(pfkey_msg->sadb_msg_satype),
|
|
+ pfkey_msg->sadb_msg_type,
|
|
+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
|
|
+ }
|
|
+ case SADB_ACQUIRE:
|
|
+ case SADB_REGISTER:
|
|
+ case SADB_EXPIRE:
|
|
+ if(!pfkey_msg->sadb_msg_satype) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "satype is zero, must be non-zero for msg_type %d(%s).\n",
|
|
+ pfkey_msg->sadb_msg_type,
|
|
+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* errno must not be set in downward messages */
|
|
+ /* this is not entirely true... a response to an ACQUIRE could return an error */
|
|
+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "errno set to %d.\n",
|
|
+ pfkey_msg->sadb_msg_errno);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
|
|
+ "pfkey_msg_parse: "
|
|
+ "remain=%d\n",
|
|
+ remain
|
|
+ );
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
|
|
+ "pfkey_msg_parse: "
|
|
+ "extensions permitted=%08x, required=%08x.\n",
|
|
+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
|
|
+
|
|
+ extensions_seen = 1;
|
|
+
|
|
+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
|
|
+ /* Is there enough message left to support another extension header? */
|
|
+ if(remain < pfkey_ext->sadb_ext_len) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "remain %d less than ext len %d.\n",
|
|
+ remain, pfkey_ext->sadb_ext_len);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
|
|
+ "pfkey_msg_parse: "
|
|
+ "parsing ext type=%d(%s) remain=%d.\n",
|
|
+ pfkey_ext->sadb_ext_type,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
|
|
+ remain);
|
|
+
|
|
+ /* Is the extension header type valid? */
|
|
+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
|
|
+ pfkey_ext->sadb_ext_type,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
|
|
+ SADB_EXT_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ /* Have we already seen this type of extension? */
|
|
+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
|
|
+ {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "ext type %d(%s) already seen.\n",
|
|
+ pfkey_ext->sadb_ext_type,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ /* Do I even know about this type of extension? */
|
|
+ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
|
|
+ ERROR("pfkey_msg_parse: "
|
|
+ "ext type %d(%s) unknown, ignoring.\n",
|
|
+ pfkey_ext->sadb_ext_type,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
|
|
+ goto next_ext;
|
|
+ }
|
|
+
|
|
+ /* Is this type of extension permitted for this type of message? */
|
|
+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
|
|
+ 1<<pfkey_ext->sadb_ext_type)) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
|
|
+ pfkey_ext->sadb_ext_type,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
|
|
+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
|
|
+ 1<<pfkey_ext->sadb_ext_type);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_msg_parse: "
|
|
+ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
|
|
+ remain,
|
|
+ pfkey_ext->sadb_ext_type,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
|
|
+ pfkey_ext->sadb_ext_len,
|
|
+ pfkey_ext,
|
|
+ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
|
|
+
|
|
+ /* Parse the extension */
|
|
+ if((error =
|
|
+ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "extension parsing for type %d(%s) failed with error %d.\n",
|
|
+ pfkey_ext->sadb_ext_type,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
|
|
+ "pfkey_msg_parse: "
|
|
+ "Extension %d(%s) parsed.\n",
|
|
+ pfkey_ext->sadb_ext_type,
|
|
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
|
|
+
|
|
+ /* Mark that we have seen this extension and remember the header location */
|
|
+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
|
|
+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
|
|
+
|
|
+ next_ext:
|
|
+ /* Calculate how much message remains */
|
|
+ remain -= pfkey_ext->sadb_ext_len;
|
|
+
|
|
+ if(!remain) {
|
|
+ break;
|
|
+ }
|
|
+ /* Find the next extension header */
|
|
+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
|
|
+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
|
|
+ }
|
|
+
|
|
+ if(remain) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "unexpected remainder of %d.\n",
|
|
+ remain);
|
|
+ /* why is there still something remaining? */
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ /* check required extensions */
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
|
|
+ "pfkey_msg_parse: "
|
|
+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
|
|
+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
|
|
+ extensions_seen,
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
|
|
+
|
|
+ /* don't check further if it is an error return message since it
|
|
+ may not have a body */
|
|
+ if(pfkey_msg->sadb_msg_errno) {
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((extensions_seen &
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "required extensions missing:%08x.\n",
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
|
|
+ (extensions_seen &
|
|
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
|
|
+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
|
|
+ != SADB_X_EXT_ADDRESS_DELFLOW)
|
|
+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
|
|
+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
|
|
+ & SADB_X_SAFLAGS_CLEARFLOW)
|
|
+ != SADB_X_SAFLAGS_CLEARFLOW))) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
|
|
+ SADB_X_EXT_ADDRESS_DELFLOW
|
|
+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
|
|
+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_msg->sadb_msg_type) {
|
|
+ case SADB_ADD:
|
|
+ case SADB_UPDATE:
|
|
+ /* check maturity */
|
|
+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
|
|
+ SADB_SASTATE_MATURE) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "state=%d for add or update should be MATURE=%d.\n",
|
|
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
|
|
+ SADB_SASTATE_MATURE);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ /* check AH and ESP */
|
|
+ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
|
|
+ case SADB_SATYPE_AH:
|
|
+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
|
|
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
|
|
+ SADB_AALG_NONE)) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "auth alg is zero, must be non-zero for AH SAs.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
|
|
+ SADB_EALG_NONE) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "AH handed encalg=%d, must be zero.\n",
|
|
+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ break;
|
|
+ case SADB_SATYPE_ESP:
|
|
+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
|
|
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
|
|
+ SADB_EALG_NONE)) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
|
|
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
|
|
+ SADB_EALG_NULL) &&
|
|
+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
|
|
+ SADB_AALG_NONE) ) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "ESP handed encNULL+authNONE, illegal combination.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ break;
|
|
+ case SADB_X_SATYPE_COMP:
|
|
+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
|
|
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
|
|
+ SADB_EALG_NONE)) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
|
|
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
|
|
+ SADB_AALG_NONE) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "COMP handed auth=%d, must be zero.\n",
|
|
+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
|
|
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
|
|
+ "pfkey_msg_parse: "
|
|
+ "spi=%08x must be > 255.\n",
|
|
+ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+errlab:
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: pfkey_v2_parse.c,v $
|
|
+ * Revision 1.65 2005/04/06 17:46:05 mcr
|
|
+ * failure to recognize an extension is considered an error.
|
|
+ * This could be a problem in the future, but we need some kind
|
|
+ * of logging. This should be rate limited, probably.
|
|
+ *
|
|
+ * Revision 1.64 2005/01/26 00:50:35 mcr
|
|
+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
|
|
+ * and make sure that NAT_TRAVERSAL is set as well to match
|
|
+ * userspace compiles of code.
|
|
+ *
|
|
+ * Revision 1.63 2004/10/28 22:54:10 mcr
|
|
+ * results from valgrind, thanks to: Harald Hoyer <harald@redhat.com>
|
|
+ *
|
|
+ * Revision 1.62 2004/10/03 01:26:36 mcr
|
|
+ * fixes for gcc 3.4 compilation.
|
|
+ *
|
|
+ * Revision 1.61 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.59 2004/04/18 03:03:49 mcr
|
|
+ * renamed common include files from pluto directory.
|
|
+ *
|
|
+ * Revision 1.58 2004/03/08 01:59:08 ken
|
|
+ * freeswan.h -> openswan.h
|
|
+ *
|
|
+ * Revision 1.57 2003/12/10 01:20:19 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.56 2003/12/04 23:01:12 mcr
|
|
+ * removed ipsec_netlink.h
|
|
+ *
|
|
+ * Revision 1.55 2003/11/07 01:30:37 ken
|
|
+ * Cast sizeof() to int to keep things 64bit clean
|
|
+ *
|
|
+ * Revision 1.54 2003/10/31 02:27:12 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.53.20.2 2003/10/29 01:11:32 mcr
|
|
+ * added debugging for pfkey library.
|
|
+ *
|
|
+ * Revision 1.53.20.1 2003/09/21 13:59:44 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.53 2003/01/30 02:32:09 rgb
|
|
+ *
|
|
+ * Rename SAref table macro names for clarity.
|
|
+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
|
|
+ *
|
|
+ * Revision 1.52 2002/12/30 06:53:07 mcr
|
|
+ * deal with short SA structures... #if 0 out for now. Probably
|
|
+ * not quite the right way.
|
|
+ *
|
|
+ * Revision 1.51 2002/12/13 18:16:02 mcr
|
|
+ * restored sa_ref code
|
|
+ *
|
|
+ * Revision 1.50 2002/12/13 18:06:52 mcr
|
|
+ * temporarily removed sadb_x_sa_ref reference for 2.xx
|
|
+ *
|
|
+ * Revision 1.49 2002/10/05 05:02:58 dhr
|
|
+ *
|
|
+ * C labels go on statements
|
|
+ *
|
|
+ * Revision 1.48 2002/09/20 15:40:45 rgb
|
|
+ * Added sadb_x_sa_ref to struct sadb_sa.
|
|
+ *
|
|
+ * Revision 1.47 2002/09/20 05:01:31 rgb
|
|
+ * Fixed usage of pfkey_lib_debug.
|
|
+ * Format for function declaration style consistency.
|
|
+ * Added text labels to elucidate numeric values presented.
|
|
+ * Re-organised debug output to reduce noise in output.
|
|
+ *
|
|
+ * Revision 1.46 2002/07/24 18:44:54 rgb
|
|
+ * Type fiddling to tame ia64 compiler.
|
|
+ *
|
|
+ * Revision 1.45 2002/05/23 07:14:11 rgb
|
|
+ * Cleaned up %p variants to 0p%p for test suite cleanup.
|
|
+ *
|
|
+ * Revision 1.44 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.43 2002/04/24 07:36:40 mcr
|
|
+ * Moved from ./lib/pfkey_v2_parse.c,v
|
|
+ *
|
|
+ * Revision 1.42 2002/01/29 22:25:36 rgb
|
|
+ * Re-add ipsec_kversion.h to keep MALLOC happy.
|
|
+ *
|
|
+ * Revision 1.41 2002/01/29 01:59:10 mcr
|
|
+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
|
|
+ * updating of IPv6 structures to match latest in6.h version.
|
|
+ * removed dead code from openswan.h that also duplicated kversions.h
|
|
+ * code.
|
|
+ *
|
|
+ * Revision 1.40 2002/01/20 20:34:50 mcr
|
|
+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
|
|
+ *
|
|
+ * Revision 1.39 2001/11/27 05:29:22 mcr
|
|
+ * pfkey parses are now maintained by a structure
|
|
+ * that includes their name for debug purposes.
|
|
+ * DEBUGGING() macro changed so that it takes a debug
|
|
+ * level so that pf_key() can use this to decode the
|
|
+ * structures without innundanting humans.
|
|
+ * Also uses pfkey_v2_sadb_ext_string() in messages.
|
|
+ *
|
|
+ * Revision 1.38 2001/11/06 19:47:47 rgb
|
|
+ * Added packet parameter to lifetime and comb structures.
|
|
+ *
|
|
+ * Revision 1.37 2001/10/18 04:45:24 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/openswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.36 2001/06/14 19:35:16 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.35 2001/05/03 19:44:51 rgb
|
|
+ * Standardise on SENDERR() macro.
|
|
+ *
|
|
+ * Revision 1.34 2001/03/16 07:41:51 rgb
|
|
+ * Put openswan.h include before pluto includes.
|
|
+ *
|
|
+ * Revision 1.33 2001/02/27 07:13:51 rgb
|
|
+ * Added satype2name() function.
|
|
+ * Added text to default satype_tbl entry.
|
|
+ * Added satype2name() conversions for most satype debug output.
|
|
+ *
|
|
+ * Revision 1.32 2001/02/26 20:01:09 rgb
|
|
+ * Added internal IP protocol 61 for magic SAs.
|
|
+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
|
|
+ * Re-formatted debug output (split lines, consistent spacing).
|
|
+ * Removed acquire, register and expire requirements for a known satype.
|
|
+ * Changed message type checking to a switch structure.
|
|
+ * Verify expected NULL auth for IPCOMP.
|
|
+ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for
|
|
+ * appropriate message types.
|
|
+ *
|
|
+ * Revision 1.31 2000/12/01 07:09:00 rgb
|
|
+ * Added ipcomp sanity check to require encalgo is set.
|
|
+ *
|
|
+ * Revision 1.30 2000/11/17 18:10:30 rgb
|
|
+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
|
|
+ * network byte order since this is the way PF_KEYv2 stored spis.
|
|
+ *
|
|
+ * Revision 1.29 2000/10/12 00:02:39 rgb
|
|
+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
|
|
+ *
|
|
+ * Revision 1.28 2000/09/20 16:23:04 rgb
|
|
+ * Remove over-paranoid extension check in the presence of sadb_msg_errno.
|
|
+ *
|
|
+ * Revision 1.27 2000/09/20 04:04:21 rgb
|
|
+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
|
|
+ * oopsen.
|
|
+ *
|
|
+ * Revision 1.26 2000/09/15 11:37:02 rgb
|
|
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
|
|
+ * IPCOMP zlib deflate code.
|
|
+ *
|
|
+ * Revision 1.25 2000/09/12 22:35:37 rgb
|
|
+ * Restructured to remove unused extensions from CLEARFLOW messages.
|
|
+ *
|
|
+ * Revision 1.24 2000/09/12 18:59:54 rgb
|
|
+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
|
|
+ *
|
|
+ * Revision 1.23 2000/09/12 03:27:00 rgb
|
|
+ * Moved DEBUGGING definition to compile kernel with debug off.
|
|
+ *
|
|
+ * Revision 1.22 2000/09/09 06:39:27 rgb
|
|
+ * Restrict pfkey errno check to downward messages only.
|
|
+ *
|
|
+ * Revision 1.21 2000/09/08 19:22:34 rgb
|
|
+ * Enabled pfkey_sens_parse().
|
|
+ * Added check for errno on downward acquire messages only.
|
|
+ *
|
|
+ * Revision 1.20 2000/09/01 18:48:23 rgb
|
|
+ * Fixed reserved check bug and added debug output in
|
|
+ * pfkey_supported_parse().
|
|
+ * Fixed debug output label bug in pfkey_ident_parse().
|
|
+ *
|
|
+ * Revision 1.19 2000/08/27 01:55:26 rgb
|
|
+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
|
|
+ *
|
|
+ * Revision 1.18 2000/08/24 17:00:36 rgb
|
|
+ * Ignore unknown extensions instead of failing.
|
|
+ *
|
|
+ * Revision 1.17 2000/06/02 22:54:14 rgb
|
|
+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
|
|
+ *
|
|
+ * Revision 1.16 2000/05/10 19:25:11 rgb
|
|
+ * Fleshed out proposal and supported extensions.
|
|
+ *
|
|
+ * Revision 1.15 2000/01/24 21:15:31 rgb
|
|
+ * Added disabled pluto pfkey lib debug flag.
|
|
+ * Added algo debugging reporting.
|
|
+ *
|
|
+ * Revision 1.14 2000/01/22 23:24:29 rgb
|
|
+ * Added new functions proto2satype() and satype2proto() and lookup
|
|
+ * table satype_tbl. Also added proto2name() since it was easy.
|
|
+ *
|
|
+ * Revision 1.13 2000/01/21 09:43:59 rgb
|
|
+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
|
|
+ *
|
|
+ * Revision 1.12 2000/01/21 06:28:19 rgb
|
|
+ * Added address cases for eroute flows.
|
|
+ * Indented compiler directives for readability.
|
|
+ * Added klipsdebug switching capability.
|
|
+ *
|
|
+ * Revision 1.11 1999/12/29 21:14:59 rgb
|
|
+ * Fixed debug text cut and paste typo.
|
|
+ *
|
|
+ * Revision 1.10 1999/12/10 17:45:24 rgb
|
|
+ * Added address debugging.
|
|
+ *
|
|
+ * Revision 1.9 1999/12/09 23:11:42 rgb
|
|
+ * Ditched <string.h> include since we no longer use memset().
|
|
+ * Use new pfkey_extensions_init() instead of memset().
|
|
+ * Added check for SATYPE in pfkey_msg_build().
|
|
+ * Tidy up comments and debugging comments.
|
|
+ *
|
|
+ * Revision 1.8 1999/12/07 19:55:26 rgb
|
|
+ * Removed unused first argument from extension parsers.
|
|
+ * Removed static pluto debug flag.
|
|
+ * Moved message type and state checking to pfkey_msg_parse().
|
|
+ * Changed print[fk] type from lx to x to quiet compiler.
|
|
+ * Removed redundant remain check.
|
|
+ * Changed __u* types to uint* to avoid use of asm/types.h and
|
|
+ * sys/types.h in userspace code.
|
|
+ *
|
|
+ * Revision 1.7 1999/12/01 22:20:51 rgb
|
|
+ * Moved pfkey_lib_debug variable into the library.
|
|
+ * Added pfkey version check into header parsing.
|
|
+ * Added check for SATYPE only for those extensions that require a
|
|
+ * non-zero value.
|
|
+ *
|
|
+ * Revision 1.6 1999/11/27 11:58:05 rgb
|
|
+ * Added ipv6 headers.
|
|
+ * Moved sadb_satype2proto protocol lookup table from
|
|
+ * klips/net/ipsec/pfkey_v2_parser.c.
|
|
+ * Enable lifetime_current checking.
|
|
+ * Debugging error messages added.
|
|
+ * Add argument to pfkey_msg_parse() for direction.
|
|
+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
|
|
+ * Add CVS log entry to bottom of file.
|
|
+ * Moved auth and enc alg check to pfkey_msg_parse().
|
|
+ * Enable accidentally disabled spirange parsing.
|
|
+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,3520 @@
|
|
+/*
|
|
+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
|
|
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: pfkey_v2_parser.c,v 1.134.2.2 2006/10/06 21:39:26 paul Exp $
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
|
|
+ */
|
|
+
|
|
+char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.134.2.2 2006/10/06 21:39:26 paul Exp $";
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+
|
|
+#include <openswan.h>
|
|
+
|
|
+#include <crypto/des.h>
|
|
+
|
|
+#ifdef SPINLOCK
|
|
+# ifdef SPINLOCK_23
|
|
+# include <linux/spinlock.h> /* *lock* */
|
|
+# else /* SPINLOCK_23 */
|
|
+# include <asm/spinlock.h> /* *lock* */
|
|
+# endif /* SPINLOCK_23 */
|
|
+#endif /* SPINLOCK */
|
|
+
|
|
+#include <linux/in6.h>
|
|
+#include <net/route.h>
|
|
+
|
|
+#include <net/ip.h>
|
|
+#ifdef NETLINK_SOCK
|
|
+# include <linux/netlink.h>
|
|
+#else
|
|
+# include <net/netlink.h>
|
|
+#endif
|
|
+
|
|
+#include <linux/random.h> /* get_random_bytes() */
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_sa.h"
|
|
+
|
|
+#include "openswan/ipsec_radij.h"
|
|
+#include "openswan/ipsec_xform.h"
|
|
+#include "openswan/ipsec_ah.h"
|
|
+#include "openswan/ipsec_esp.h"
|
|
+#include "openswan/ipsec_tunnel.h"
|
|
+#include "openswan/ipsec_rcv.h"
|
|
+#include "openswan/ipcomp.h"
|
|
+
|
|
+#include <pfkeyv2.h>
|
|
+#include <pfkey.h>
|
|
+
|
|
+#include "openswan/ipsec_proto.h"
|
|
+#include "openswan/ipsec_alg.h"
|
|
+
|
|
+#include "openswan/ipsec_kern24.h"
|
|
+
|
|
+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
|
|
+
|
|
+struct sklist_t {
|
|
+ struct socket *sk;
|
|
+ struct sklist_t* next;
|
|
+} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
|
|
+
|
|
+__u32 pfkey_msg_seq = 0;
|
|
+
|
|
+
|
|
+#if 0
|
|
+#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)
|
|
+#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)
|
|
+static void dump_said(ip_said *s, int line)
|
|
+{
|
|
+ char msa[SATOT_BUF];
|
|
+ size_t msa_len;
|
|
+
|
|
+ msa_len = satot(s, 0, msa, sizeof(msa));
|
|
+
|
|
+ printk("line: %d msa: %s\n", line, msa);
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
+int
|
|
+pfkey_alloc_eroute(struct eroute** eroute)
|
|
+{
|
|
+ int error = 0;
|
|
+ if(*eroute) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_alloc_eroute: "
|
|
+ "eroute struct already allocated\n");
|
|
+ SENDERR(EEXIST);
|
|
+ }
|
|
+
|
|
+ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_alloc_eroute: "
|
|
+ "memory allocation error\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_alloc_eroute: "
|
|
+ "allocating %lu bytes for an eroute at 0p%p\n",
|
|
+ (unsigned long) sizeof(**eroute), *eroute);
|
|
+
|
|
+ memset((caddr_t)*eroute, 0, sizeof(**eroute));
|
|
+ (*eroute)->er_eaddr.sen_len =
|
|
+ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
|
|
+ (*eroute)->er_eaddr.sen_family =
|
|
+ (*eroute)->er_emask.sen_family = AF_ENCAP;
|
|
+ (*eroute)->er_eaddr.sen_type = SENT_IP4;
|
|
+ (*eroute)->er_emask.sen_type = 255;
|
|
+ (*eroute)->er_pid = 0;
|
|
+ (*eroute)->er_count = 0;
|
|
+ (*eroute)->er_lasttime = jiffies/HZ;
|
|
+
|
|
+ errlab:
|
|
+ return(error);
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
|
|
+ struct pfkey_extracted_data *extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
|
|
+
|
|
+ if (extr == 0) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_protocol_process:"
|
|
+ "extr is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if (extr->eroute == 0) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_protocol_process:"
|
|
+ "extr->eroute is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
|
|
+ extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
|
|
+ p->sadb_protocol_proto);
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_ipsec_sa_init(struct ipsec_sa *ipsp)
|
|
+{
|
|
+
|
|
+ return ipsec_sa_init(ipsp);
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
|
|
+{
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
|
|
+ "error=%d\n",
|
|
+ error);
|
|
+ if (!error) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
|
|
+ "success.\n");
|
|
+ return 1;
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
|
|
+ "caught error %d\n",
|
|
+ error);
|
|
+ pfkey_extensions_free(extensions);
|
|
+ return 0;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
|
|
+ int found_avail = 0;
|
|
+ struct ipsec_sa *ipsq;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_reply = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_getspi_parse: .\n");
|
|
+
|
|
+ pfkey_extensions_init(extensions_reply);
|
|
+
|
|
+ if(extr == NULL || extr->ips == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_getspi_parse: "
|
|
+ "error, extr or extr->ipsec_sa pointer NULL\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(extensions[SADB_EXT_SPIRANGE]) {
|
|
+ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
|
|
+ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
|
|
+ }
|
|
+
|
|
+ if(maxspi == minspi) {
|
|
+ extr->ips->ips_said.spi = maxspi;
|
|
+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
|
|
+ if(ipsq != NULL) {
|
|
+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
|
|
+ ipsec_sa_put(ipsq);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_getspi_parse: "
|
|
+ "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(EEXIST);
|
|
+ } else {
|
|
+ found_avail = 1;
|
|
+ }
|
|
+ } else {
|
|
+ int i = 0;
|
|
+ __u32 rand_val;
|
|
+ __u32 spi_diff;
|
|
+ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
|
|
+ prng_bytes(&ipsec_prng, (char *) &(rand_val),
|
|
+ ( (spi_diff < (2^8)) ? 1 :
|
|
+ ( (spi_diff < (2^16)) ? 2 :
|
|
+ ( (spi_diff < (2^24)) ? 3 :
|
|
+ 4 ) ) ) );
|
|
+ extr->ips->ips_said.spi = htonl(ntohl(minspi) +
|
|
+ (rand_val %
|
|
+ (spi_diff + 1)));
|
|
+ i++;
|
|
+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
|
|
+ if(ipsq == NULL) {
|
|
+ found_avail = 1;
|
|
+ } else {
|
|
+ ipsec_sa_put(ipsq);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
|
|
+
|
|
+ if (!found_avail) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_getspi_parse: "
|
|
+ "found an old ipsec_sa for SA: %s, delete it first.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(EEXIST);
|
|
+ }
|
|
+
|
|
+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
|
|
+ extr->ips->ips_flags |= EMT_INBOUND;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_getspi_parse: "
|
|
+ "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
|
|
+ sa_len ? sa : " (error)",
|
|
+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
|
|
+
|
|
+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
|
|
+ extr->ips->ips_rcvif = NULL;
|
|
+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
|
|
+
|
|
+ extr->ips->ips_state = SADB_SASTATE_LARVAL;
|
|
+
|
|
+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
|
|
+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
|
|
+ }
|
|
+
|
|
+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
|
|
+ SADB_GETSPI,
|
|
+ satype,
|
|
+ 0,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ extr->ips->ips_said.spi,
|
|
+ 0,
|
|
+ SADB_SASTATE_LARVAL,
|
|
+ 0,
|
|
+ 0,
|
|
+ 0,
|
|
+ extr->ips->ips_ref),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_s),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_d),
|
|
+ extensions_reply) )) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
|
|
+ "failed to build the getspi reply message extensions\n");
|
|
+ goto errlab;
|
|
+ }
|
|
+
|
|
+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
|
|
+ "failed to build the getspi reply message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
|
|
+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
|
|
+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ if((error = ipsec_sa_add(extr->ips))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
|
|
+ "failed to add the larval SA=%s with error=%d.\n",
|
|
+ sa_len ? sa : " (error)",
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ extr->ips = NULL;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_getspi_parse: "
|
|
+ "successful for SA: %s\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_reply) {
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions_reply);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct ipsec_sa* ipsq;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_reply = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ struct ipsec_sa *nat_t_ips_saved = NULL;
|
|
+#endif
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse: .\n");
|
|
+
|
|
+ pfkey_extensions_init(extensions_reply);
|
|
+
|
|
+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse: "
|
|
+ "error, sa_state=%d must be MATURE=%d\n",
|
|
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
|
|
+ SADB_SASTATE_MATURE);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(extr == NULL || extr->ips == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse: "
|
|
+ "error, extr or extr->ips pointer NULL\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
|
|
+
|
|
+ spin_lock_bh(&tdb_lock);
|
|
+
|
|
+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
|
|
+ if (ipsq == NULL) {
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse: "
|
|
+ "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(ENOENT);
|
|
+ }
|
|
+
|
|
+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
|
|
+ extr->ips->ips_flags |= EMT_INBOUND;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse: "
|
|
+ "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
|
|
+ sa_len ? sa : " (error)",
|
|
+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse: only updating NAT-T ports "
|
|
+ "(%u:%u -> %u:%u)\n",
|
|
+ ipsq->ips_natt_sport, ipsq->ips_natt_dport,
|
|
+ extr->ips->ips_natt_sport, extr->ips->ips_natt_dport);
|
|
+
|
|
+ if (extr->ips->ips_natt_sport) {
|
|
+ ipsq->ips_natt_sport = extr->ips->ips_natt_sport;
|
|
+ if (ipsq->ips_addr_s->sa_family == AF_INET) {
|
|
+ ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (extr->ips->ips_natt_dport) {
|
|
+ ipsq->ips_natt_dport = extr->ips->ips_natt_dport;
|
|
+ if (ipsq->ips_addr_d->sa_family == AF_INET) {
|
|
+ ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ nat_t_ips_saved = extr->ips;
|
|
+ extr->ips = ipsq;
|
|
+ }
|
|
+ else {
|
|
+#endif
|
|
+
|
|
+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
|
|
+ extr->ips->ips_rcvif = NULL;
|
|
+ if ((error = pfkey_ipsec_sa_init(extr->ips))) {
|
|
+ ipsec_sa_put(ipsq);
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse: "
|
|
+ "not successful for SA: %s, deleting.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
|
|
+ ipsec_sa_put(ipsq);
|
|
+ if((error = ipsec_sa_delchain(ipsq))) {
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse: "
|
|
+ "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n",
|
|
+ error,
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+
|
|
+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
|
|
+ SADB_UPDATE,
|
|
+ satype,
|
|
+ 0,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ extr->ips->ips_said.spi,
|
|
+ extr->ips->ips_replaywin,
|
|
+ extr->ips->ips_state,
|
|
+ extr->ips->ips_authalg,
|
|
+ extr->ips->ips_encalg,
|
|
+ extr->ips->ips_flags,
|
|
+ extr->ips->ips_ref),
|
|
+ extensions_reply)
|
|
+ /* The 3 lifetime extentions should only be sent if non-zero. */
|
|
+ && (extensions[SADB_EXT_LIFETIME_HARD]
|
|
+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
|
|
+ SADB_EXT_LIFETIME_HARD,
|
|
+ extr->ips->ips_life.ipl_allocations.ipl_hard,
|
|
+ extr->ips->ips_life.ipl_bytes.ipl_hard,
|
|
+ extr->ips->ips_life.ipl_addtime.ipl_hard,
|
|
+ extr->ips->ips_life.ipl_usetime.ipl_hard,
|
|
+ extr->ips->ips_life.ipl_packets.ipl_hard),
|
|
+ extensions_reply) : 1)
|
|
+ && (extensions[SADB_EXT_LIFETIME_SOFT]
|
|
+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
|
|
+ SADB_EXT_LIFETIME_SOFT,
|
|
+ extr->ips->ips_life.ipl_allocations.ipl_count,
|
|
+ extr->ips->ips_life.ipl_bytes.ipl_count,
|
|
+ extr->ips->ips_life.ipl_addtime.ipl_count,
|
|
+ extr->ips->ips_life.ipl_usetime.ipl_count,
|
|
+ extr->ips->ips_life.ipl_packets.ipl_count),
|
|
+ extensions_reply) : 1)
|
|
+ && (extr->ips->ips_life.ipl_allocations.ipl_count
|
|
+ || extr->ips->ips_life.ipl_bytes.ipl_count
|
|
+ || extr->ips->ips_life.ipl_addtime.ipl_count
|
|
+ || extr->ips->ips_life.ipl_usetime.ipl_count
|
|
+ || extr->ips->ips_life.ipl_packets.ipl_count
|
|
+
|
|
+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
|
|
+ SADB_EXT_LIFETIME_CURRENT,
|
|
+ extr->ips->ips_life.ipl_allocations.ipl_count,
|
|
+ extr->ips->ips_life.ipl_bytes.ipl_count,
|
|
+ extr->ips->ips_life.ipl_addtime.ipl_count,
|
|
+ extr->ips->ips_life.ipl_usetime.ipl_count,
|
|
+ extr->ips->ips_life.ipl_packets.ipl_count),
|
|
+ extensions_reply) : 1)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_s),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_d),
|
|
+ extensions_reply)
|
|
+ && (extr->ips->ips_ident_s.data
|
|
+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
|
|
+ SADB_EXT_IDENTITY_SRC,
|
|
+ extr->ips->ips_ident_s.type,
|
|
+ extr->ips->ips_ident_s.id,
|
|
+ extr->ips->ips_ident_s.len,
|
|
+ extr->ips->ips_ident_s.data),
|
|
+ extensions_reply) : 1)
|
|
+ && (extr->ips->ips_ident_d.data
|
|
+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
|
|
+ SADB_EXT_IDENTITY_DST,
|
|
+ extr->ips->ips_ident_d.type,
|
|
+ extr->ips->ips_ident_d.id,
|
|
+ extr->ips->ips_ident_d.len,
|
|
+ extr->ips->ips_ident_d.data),
|
|
+ extensions_reply) : 1)
|
|
+#if 0
|
|
+ /* FIXME: This won't work yet because I have not finished
|
|
+ it. */
|
|
+ && (extr->ips->ips_sens_
|
|
+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
|
|
+ extr->ips->ips_sens_dpd,
|
|
+ extr->ips->ips_sens_sens_level,
|
|
+ extr->ips->ips_sens_sens_len,
|
|
+ extr->ips->ips_sens_sens_bitmap,
|
|
+ extr->ips->ips_sens_integ_level,
|
|
+ extr->ips->ips_sens_integ_len,
|
|
+ extr->ips->ips_sens_integ_bitmap),
|
|
+ extensions_reply) : 1)
|
|
+#endif
|
|
+ )) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
|
|
+ "failed to build the update reply message extensions\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
|
|
+ "failed to build the update reply message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
|
|
+ "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
|
|
+ "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ if (nat_t_ips_saved) {
|
|
+ /**
|
|
+ * As we _really_ update existing SA, we keep tdbq and need to delete
|
|
+ * parsed ips (nat_t_ips_saved, was extr->ips).
|
|
+ *
|
|
+ * goto errlab with extr->ips = nat_t_ips_saved will free it.
|
|
+ */
|
|
+
|
|
+ extr->ips = nat_t_ips_saved;
|
|
+
|
|
+ error = 0;
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse (NAT-T ports): "
|
|
+ "successful for SA: %s\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+
|
|
+ goto errlab;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if((error = ipsec_sa_add(extr->ips))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
|
|
+ "failed to update the mature SA=%s with error=%d.\n",
|
|
+ sa_len ? sa : " (error)",
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ extr->ips = NULL;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_update_parse: "
|
|
+ "successful for SA: %s\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_reply) {
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions_reply);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct ipsec_sa* ipsq;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_reply = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_add_parse: .\n");
|
|
+
|
|
+ pfkey_extensions_init(extensions_reply);
|
|
+
|
|
+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_add_parse: "
|
|
+ "error, sa_state=%d must be MATURE=%d\n",
|
|
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
|
|
+ SADB_SASTATE_MATURE);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_add_parse: "
|
|
+ "extr or extr->ips pointer NULL\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
|
|
+
|
|
+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
|
|
+ if(ipsq != NULL) {
|
|
+ ipsec_sa_put(ipsq);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_add_parse: "
|
|
+ "found an old ipsec_sa for SA%s, delete it first.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(EEXIST);
|
|
+ }
|
|
+
|
|
+ if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
|
|
+ extr->ips->ips_flags |= EMT_INBOUND;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_add_parse: "
|
|
+ "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
|
|
+ sa_len ? sa : " (error)",
|
|
+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
|
|
+
|
|
+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
|
|
+ extr->ips->ips_rcvif = NULL;
|
|
+
|
|
+ if ((error = pfkey_ipsec_sa_init(extr->ips))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_add_parse: "
|
|
+ "not successful for SA: %s, deleting.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
|
|
+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
|
|
+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
|
|
+ }
|
|
+
|
|
+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
|
|
+ SADB_ADD,
|
|
+ satype,
|
|
+ 0,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ extr->ips->ips_said.spi,
|
|
+ extr->ips->ips_replaywin,
|
|
+ extr->ips->ips_state,
|
|
+ extr->ips->ips_authalg,
|
|
+ extr->ips->ips_encalg,
|
|
+ extr->ips->ips_flags,
|
|
+ extr->ips->ips_ref),
|
|
+ extensions_reply)
|
|
+ /* The 3 lifetime extentions should only be sent if non-zero. */
|
|
+ && (extensions[SADB_EXT_LIFETIME_HARD]
|
|
+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
|
|
+ SADB_EXT_LIFETIME_HARD,
|
|
+ extr->ips->ips_life.ipl_allocations.ipl_hard,
|
|
+ extr->ips->ips_life.ipl_bytes.ipl_hard,
|
|
+ extr->ips->ips_life.ipl_addtime.ipl_hard,
|
|
+ extr->ips->ips_life.ipl_usetime.ipl_hard,
|
|
+ extr->ips->ips_life.ipl_packets.ipl_hard),
|
|
+ extensions_reply) : 1)
|
|
+ && (extensions[SADB_EXT_LIFETIME_SOFT]
|
|
+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
|
|
+ SADB_EXT_LIFETIME_SOFT,
|
|
+ extr->ips->ips_life.ipl_allocations.ipl_soft,
|
|
+ extr->ips->ips_life.ipl_bytes.ipl_soft,
|
|
+ extr->ips->ips_life.ipl_addtime.ipl_soft,
|
|
+ extr->ips->ips_life.ipl_usetime.ipl_soft,
|
|
+ extr->ips->ips_life.ipl_packets.ipl_soft),
|
|
+ extensions_reply) : 1)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_s),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_d),
|
|
+ extensions_reply)
|
|
+ && (extr->ips->ips_ident_s.data
|
|
+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
|
|
+ SADB_EXT_IDENTITY_SRC,
|
|
+ extr->ips->ips_ident_s.type,
|
|
+ extr->ips->ips_ident_s.id,
|
|
+ extr->ips->ips_ident_s.len,
|
|
+ extr->ips->ips_ident_s.data),
|
|
+ extensions_reply) : 1)
|
|
+ && (extr->ips->ips_ident_d.data
|
|
+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
|
|
+ SADB_EXT_IDENTITY_DST,
|
|
+ extr->ips->ips_ident_d.type,
|
|
+ extr->ips->ips_ident_d.id,
|
|
+ extr->ips->ips_ident_d.len,
|
|
+ extr->ips->ips_ident_d.data),
|
|
+ extensions_reply) : 1)
|
|
+#if 0
|
|
+ /* FIXME: This won't work yet because I have not finished
|
|
+ it. */
|
|
+ && (extr->ips->ips_sens_
|
|
+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
|
|
+ extr->ips->ips_sens_dpd,
|
|
+ extr->ips->ips_sens_sens_level,
|
|
+ extr->ips->ips_sens_sens_len,
|
|
+ extr->ips->ips_sens_sens_bitmap,
|
|
+ extr->ips->ips_sens_integ_level,
|
|
+ extr->ips->ips_sens_integ_len,
|
|
+ extr->ips->ips_sens_integ_bitmap),
|
|
+ extensions_reply) : 1)
|
|
+#endif
|
|
+ )) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
|
|
+ "failed to build the add reply message extensions\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
|
|
+ "failed to build the add reply message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
|
|
+ "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
|
|
+ "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ if((error = ipsec_sa_add(extr->ips))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
|
|
+ "failed to add the mature SA=%s with error=%d.\n",
|
|
+ sa_len ? sa : " (error)",
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ extr->ips = NULL;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_add_parse: "
|
|
+ "successful for SA: %s\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_reply) {
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions_reply);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ struct ipsec_sa *ipsp;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+ int error = 0;
|
|
+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_reply = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_delete_parse: .\n");
|
|
+
|
|
+ pfkey_extensions_init(extensions_reply);
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_delete_parse: "
|
|
+ "extr or extr->ips pointer NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
|
|
+
|
|
+ spin_lock_bh(&tdb_lock);
|
|
+
|
|
+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
|
|
+ if (ipsp == NULL) {
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_delete_parse: "
|
|
+ "ipsec_sa not found for SA:%s, could not delete.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(ESRCH);
|
|
+ }
|
|
+
|
|
+ ipsec_sa_put(ipsp);
|
|
+ if((error = ipsec_sa_delchain(ipsp))) {
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_delete_parse: "
|
|
+ "error=%d returned trying to delete ipsec_sa for SA:%s.\n",
|
|
+ error,
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+
|
|
+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
|
|
+ SADB_DELETE,
|
|
+ satype,
|
|
+ 0,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ extr->ips->ips_said.spi,
|
|
+ 0,
|
|
+ 0,
|
|
+ 0,
|
|
+ 0,
|
|
+ 0,
|
|
+ extr->ips->ips_ref),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_s),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_d),
|
|
+ extensions_reply)
|
|
+ )) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
|
|
+ "failed to build the delete reply message extensions\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
|
|
+ "failed to build the delete reply message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
|
|
+ "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
|
|
+ "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_reply) {
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions_reply);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct ipsec_sa *ipsp;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_reply = NULL;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_get_parse: .\n");
|
|
+
|
|
+ pfkey_extensions_init(extensions_reply);
|
|
+
|
|
+ if(!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_get_parse: "
|
|
+ "extr or extr->ips pointer NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
|
|
+
|
|
+ spin_lock_bh(&tdb_lock);
|
|
+
|
|
+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
|
|
+ if (ipsp == NULL) {
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
|
|
+ "ipsec_sa not found for SA=%s, could not get.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ SENDERR(ESRCH);
|
|
+ }
|
|
+
|
|
+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
|
|
+ SADB_GET,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
|
|
+ 0,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ extr->ips->ips_said.spi,
|
|
+ extr->ips->ips_replaywin,
|
|
+ extr->ips->ips_state,
|
|
+ extr->ips->ips_authalg,
|
|
+ extr->ips->ips_encalg,
|
|
+ extr->ips->ips_flags,
|
|
+ extr->ips->ips_ref),
|
|
+ extensions_reply)
|
|
+ /* The 3 lifetime extentions should only be sent if non-zero. */
|
|
+ && (ipsp->ips_life.ipl_allocations.ipl_count
|
|
+ || ipsp->ips_life.ipl_bytes.ipl_count
|
|
+ || ipsp->ips_life.ipl_addtime.ipl_count
|
|
+ || ipsp->ips_life.ipl_usetime.ipl_count
|
|
+ || ipsp->ips_life.ipl_packets.ipl_count
|
|
+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
|
|
+ SADB_EXT_LIFETIME_CURRENT,
|
|
+ ipsp->ips_life.ipl_allocations.ipl_count,
|
|
+ ipsp->ips_life.ipl_bytes.ipl_count,
|
|
+ ipsp->ips_life.ipl_addtime.ipl_count,
|
|
+ ipsp->ips_life.ipl_usetime.ipl_count,
|
|
+ ipsp->ips_life.ipl_packets.ipl_count),
|
|
+ extensions_reply) : 1)
|
|
+ && (ipsp->ips_life.ipl_allocations.ipl_hard
|
|
+ || ipsp->ips_life.ipl_bytes.ipl_hard
|
|
+ || ipsp->ips_life.ipl_addtime.ipl_hard
|
|
+ || ipsp->ips_life.ipl_usetime.ipl_hard
|
|
+ || ipsp->ips_life.ipl_packets.ipl_hard
|
|
+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
|
|
+ SADB_EXT_LIFETIME_HARD,
|
|
+ ipsp->ips_life.ipl_allocations.ipl_hard,
|
|
+ ipsp->ips_life.ipl_bytes.ipl_hard,
|
|
+ ipsp->ips_life.ipl_addtime.ipl_hard,
|
|
+ ipsp->ips_life.ipl_usetime.ipl_hard,
|
|
+ ipsp->ips_life.ipl_packets.ipl_hard),
|
|
+ extensions_reply) : 1)
|
|
+ && (ipsp->ips_life.ipl_allocations.ipl_soft
|
|
+ || ipsp->ips_life.ipl_bytes.ipl_soft
|
|
+ || ipsp->ips_life.ipl_addtime.ipl_soft
|
|
+ || ipsp->ips_life.ipl_usetime.ipl_soft
|
|
+ || ipsp->ips_life.ipl_packets.ipl_soft
|
|
+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
|
|
+ SADB_EXT_LIFETIME_SOFT,
|
|
+ ipsp->ips_life.ipl_allocations.ipl_soft,
|
|
+ ipsp->ips_life.ipl_bytes.ipl_soft,
|
|
+ ipsp->ips_life.ipl_addtime.ipl_soft,
|
|
+ ipsp->ips_life.ipl_usetime.ipl_soft,
|
|
+ ipsp->ips_life.ipl_packets.ipl_soft),
|
|
+ extensions_reply) : 1)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_s),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_d),
|
|
+ extensions_reply)
|
|
+ && (extr->ips->ips_addr_p
|
|
+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
|
|
+ SADB_EXT_ADDRESS_PROXY,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_p),
|
|
+ extensions_reply) : 1)
|
|
+#if 0
|
|
+ /* FIXME: This won't work yet because the keys are not
|
|
+ stored directly in the ipsec_sa. They are stored as
|
|
+ contexts. */
|
|
+ && (extr->ips->ips_key_a_size
|
|
+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
|
|
+ SADB_EXT_KEY_AUTH,
|
|
+ extr->ips->ips_key_a_size * 8,
|
|
+ extr->ips->ips_key_a),
|
|
+ extensions_reply) : 1)
|
|
+ /* FIXME: This won't work yet because the keys are not
|
|
+ stored directly in the ipsec_sa. They are stored as
|
|
+ key schedules. */
|
|
+ && (extr->ips->ips_key_e_size
|
|
+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
|
|
+ SADB_EXT_KEY_ENCRYPT,
|
|
+ extr->ips->ips_key_e_size * 8,
|
|
+ extr->ips->ips_key_e),
|
|
+ extensions_reply) : 1)
|
|
+#endif
|
|
+ && (extr->ips->ips_ident_s.data
|
|
+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
|
|
+ SADB_EXT_IDENTITY_SRC,
|
|
+ extr->ips->ips_ident_s.type,
|
|
+ extr->ips->ips_ident_s.id,
|
|
+ extr->ips->ips_ident_s.len,
|
|
+ extr->ips->ips_ident_s.data),
|
|
+ extensions_reply) : 1)
|
|
+ && (extr->ips->ips_ident_d.data
|
|
+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
|
|
+ SADB_EXT_IDENTITY_DST,
|
|
+ extr->ips->ips_ident_d.type,
|
|
+ extr->ips->ips_ident_d.id,
|
|
+ extr->ips->ips_ident_d.len,
|
|
+ extr->ips->ips_ident_d.data),
|
|
+ extensions_reply) : 1)
|
|
+#if 0
|
|
+ /* FIXME: This won't work yet because I have not finished
|
|
+ it. */
|
|
+ && (extr->ips->ips_sens_
|
|
+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
|
|
+ extr->ips->ips_sens_dpd,
|
|
+ extr->ips->ips_sens_sens_level,
|
|
+ extr->ips->ips_sens_sens_len,
|
|
+ extr->ips->ips_sens_sens_bitmap,
|
|
+ extr->ips->ips_sens_integ_level,
|
|
+ extr->ips->ips_sens_integ_len,
|
|
+ extr->ips->ips_sens_integ_bitmap),
|
|
+ extensions_reply) : 1)
|
|
+#endif
|
|
+ )) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
|
|
+ "failed to build the get reply message extensions\n");
|
|
+ ipsec_sa_put(ipsp);
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ ipsec_sa_put(ipsp);
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+
|
|
+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
|
|
+ "failed to build the get reply message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((error = pfkey_upmsg(sk->sk_socket, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
|
|
+ "failed to send the get reply message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
|
|
+ "succeeded in sending get reply message.\n");
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_reply) {
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions_reply);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_acquire_parse: .\n");
|
|
+
|
|
+ /* XXX I don't know if we want an upper bound, since userspace may
|
|
+ want to register itself for an satype > SADB_SATYPE_MAX. */
|
|
+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_acquire_parse: "
|
|
+ "SATYPE=%d invalid.\n",
|
|
+ satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!(pfkey_registered_sockets[satype])) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
|
|
+ "no sockets registered for SAtype=%d(%s).\n",
|
|
+ satype,
|
|
+ satype2name(satype));
|
|
+ SENDERR(EPROTONOSUPPORT);
|
|
+ }
|
|
+
|
|
+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
|
|
+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
|
|
+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_parse: .\n");
|
|
+
|
|
+ /* XXX I don't know if we want an upper bound, since userspace may
|
|
+ want to register itself for an satype > SADB_SATYPE_MAX. */
|
|
+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_parse: "
|
|
+ "SATYPE=%d invalid.\n",
|
|
+ satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!pfkey_list_insert_socket(sk->sk_socket,
|
|
+ &(pfkey_registered_sockets[satype]))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_parse: "
|
|
+ "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ key_pid(sk));
|
|
+ };
|
|
+
|
|
+ /* send up register msg with supported SATYPE algos */
|
|
+
|
|
+ error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]);
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
|
|
+{
|
|
+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_reply = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ struct supported_list *pfkey_supported_listp;
|
|
+ unsigned int alg_num_a = 0, alg_num_e = 0;
|
|
+ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
|
|
+ int error = 0;
|
|
+
|
|
+ pfkey_extensions_init(extensions_reply);
|
|
+
|
|
+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
|
|
+ "SAtype=%d unspecified or unknown.\n",
|
|
+ satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+ if(!(pfkey_registered_sockets[satype])) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
|
|
+ "no sockets registered for SAtype=%d(%s).\n",
|
|
+ satype,
|
|
+ satype2name(satype));
|
|
+ SENDERR(EPROTONOSUPPORT);
|
|
+ }
|
|
+ /* send up register msg with supported SATYPE algos */
|
|
+ pfkey_supported_listp = pfkey_supported_list[satype];
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "pfkey_supported_list[%d]=0p%p\n",
|
|
+ satype,
|
|
+ pfkey_supported_list[satype]);
|
|
+ while(pfkey_supported_listp) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "checking supported=0p%p\n",
|
|
+ pfkey_supported_listp);
|
|
+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "adding auth alg.\n");
|
|
+ alg_num_a++;
|
|
+ }
|
|
+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "adding encrypt alg.\n");
|
|
+ alg_num_e++;
|
|
+ }
|
|
+ pfkey_supported_listp = pfkey_supported_listp->next;
|
|
+ }
|
|
+
|
|
+ if(alg_num_a) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "allocating %lu bytes for auth algs.\n",
|
|
+ (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
|
|
+ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "auth alg memory allocation error\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ alg_ap = alg_a;
|
|
+ }
|
|
+
|
|
+ if(alg_num_e) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "allocating %lu bytes for enc algs.\n",
|
|
+ (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
|
|
+ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "enc alg memory allocation error\n");
|
|
+ SENDERR(ENOMEM);
|
|
+ }
|
|
+ alg_ep = alg_e;
|
|
+ }
|
|
+
|
|
+ pfkey_supported_listp = pfkey_supported_list[satype];
|
|
+ while(pfkey_supported_listp) {
|
|
+ if(alg_num_a) {
|
|
+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
|
|
+ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
|
|
+ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
|
|
+ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
|
|
+ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
|
|
+ alg_ap->sadb_alg_reserved = 0;
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "adding auth=0p%p\n",
|
|
+ alg_ap);
|
|
+ alg_ap++;
|
|
+ }
|
|
+ }
|
|
+ if(alg_num_e) {
|
|
+ if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
|
|
+ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
|
|
+ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
|
|
+ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
|
|
+ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
|
|
+ alg_ep->sadb_alg_reserved = 0;
|
|
+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "adding encrypt=0p%p\n",
|
|
+ alg_ep);
|
|
+ alg_ep++;
|
|
+ }
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_register_reply: "
|
|
+ "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_supported_listp->supportedp->ias_exttype,
|
|
+ pfkey_supported_listp->supportedp->ias_id,
|
|
+ pfkey_supported_listp->supportedp->ias_ivlen,
|
|
+ pfkey_supported_listp->supportedp->ias_keyminbits,
|
|
+ pfkey_supported_listp->supportedp->ias_keymaxbits);
|
|
+ pfkey_supported_listp = pfkey_supported_listp->next;
|
|
+ }
|
|
+
|
|
+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
|
|
+ SADB_REGISTER,
|
|
+ satype,
|
|
+ 0,
|
|
+ sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
|
|
+ sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
|
|
+ extensions_reply) &&
|
|
+ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
|
|
+ SADB_EXT_SUPPORTED_AUTH,
|
|
+ alg_num_a,
|
|
+ alg_a),
|
|
+ extensions_reply) : 1) &&
|
|
+ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
|
|
+ SADB_EXT_SUPPORTED_ENCRYPT,
|
|
+ alg_num_e,
|
|
+ alg_e),
|
|
+ extensions_reply) : 1))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
|
|
+ "failed to build the register message extensions_reply\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
|
|
+ "failed to build the register message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ /* this should go to all registered sockets for that satype only */
|
|
+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
|
|
+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
|
|
+ "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ if(alg_a) {
|
|
+ kfree(alg_a);
|
|
+ }
|
|
+ if(alg_e) {
|
|
+ kfree(alg_e);
|
|
+ }
|
|
+
|
|
+ if (pfkey_reply) {
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions_reply);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_expire_parse: .\n");
|
|
+
|
|
+ if(pfkey_open_sockets) {
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
|
|
+ "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
|
|
+ "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+ uint8_t proto = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_flush_parse: "
|
|
+ "flushing type %d SAs\n",
|
|
+ satype);
|
|
+
|
|
+ if(satype && !(proto = satype2proto(satype))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_flush_parse: "
|
|
+ "satype %d lookup failed.\n",
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if ((error = ipsec_sadb_cleanup(proto))) {
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if(pfkey_open_sockets) {
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
|
|
+ "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ proto,
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
|
|
+ "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_dump_parse: .\n");
|
|
+
|
|
+ SENDERR(ENOSYS);
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_promisc_parse: .\n");
|
|
+
|
|
+ SENDERR(ENOSYS);
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_pchange_parse: .\n");
|
|
+
|
|
+ SENDERR(ENOSYS);
|
|
+ errlab:
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ struct ipsec_sa *ips1p, *ips2p, *ipsp;
|
|
+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_reply = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+ char sa1[SATOT_BUF], sa2[SATOT_BUF];
|
|
+ size_t sa_len1, sa_len2 = 0;
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_grpsa_parse: .\n");
|
|
+
|
|
+ pfkey_extensions_init(extensions_reply);
|
|
+
|
|
+ if(extr == NULL || extr->ips == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "extr or extr->ips is NULL, fatal.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1));
|
|
+ if(extr->ips2 != NULL) {
|
|
+ sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2));
|
|
+ }
|
|
+
|
|
+ spin_lock_bh(&tdb_lock);
|
|
+
|
|
+ ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
|
|
+ if(ips1p == NULL) {
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n",
|
|
+ sa_len1 ? sa1 : " (error)");
|
|
+ SENDERR(ENOENT);
|
|
+ }
|
|
+ if(extr->ips2) { /* GRPSA */
|
|
+ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
|
|
+ if(ips2p == NULL) {
|
|
+ ipsec_sa_put(ips1p);
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n",
|
|
+ sa_len2 ? sa2 : " (error)");
|
|
+ SENDERR(ENOENT);
|
|
+ }
|
|
+
|
|
+ /* Is either one already linked? */
|
|
+ if(ips1p->ips_onext) {
|
|
+ ipsec_sa_put(ips1p);
|
|
+ ipsec_sa_put(ips2p);
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "ipsec_sa for SA: %s is already linked.\n",
|
|
+ sa_len1 ? sa1 : " (error)");
|
|
+ SENDERR(EEXIST);
|
|
+ }
|
|
+ if(ips2p->ips_inext) {
|
|
+ ipsec_sa_put(ips1p);
|
|
+ ipsec_sa_put(ips2p);
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "ipsec_sa for SA: %s is already linked.\n",
|
|
+ sa_len2 ? sa2 : " (error)");
|
|
+ SENDERR(EEXIST);
|
|
+ }
|
|
+
|
|
+ /* Is extr->ips already linked to extr->ips2? */
|
|
+ ipsp = ips2p;
|
|
+ while(ipsp) {
|
|
+ if(ipsp == ips1p) {
|
|
+ ipsec_sa_put(ips1p);
|
|
+ ipsec_sa_put(ips2p);
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "ipsec_sa for SA: %s is already linked to %s.\n",
|
|
+ sa_len1 ? sa1 : " (error)",
|
|
+ sa_len2 ? sa2 : " (error)");
|
|
+ SENDERR(EEXIST);
|
|
+ }
|
|
+ ipsp = ipsp->ips_onext;
|
|
+ }
|
|
+
|
|
+ /* link 'em */
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "linking ipsec_sa SA: %s with %s.\n",
|
|
+ sa_len1 ? sa1 : " (error)",
|
|
+ sa_len2 ? sa2 : " (error)");
|
|
+ ips1p->ips_onext = ips2p;
|
|
+ ips2p->ips_inext = ips1p;
|
|
+ } else { /* UNGRPSA */
|
|
+ ipsec_sa_put(ips1p);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "unlinking ipsec_sa SA: %s.\n",
|
|
+ sa_len1 ? sa1 : " (error)");
|
|
+ while(ips1p->ips_onext) {
|
|
+ ips1p = ips1p->ips_onext;
|
|
+ }
|
|
+ while(ips1p->ips_inext) {
|
|
+ ipsp = ips1p;
|
|
+ ips1p = ips1p->ips_inext;
|
|
+ ipsec_sa_put(ips1p);
|
|
+ ipsp->ips_inext = NULL;
|
|
+ ipsec_sa_put(ipsp);
|
|
+ ips1p->ips_onext = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ spin_unlock_bh(&tdb_lock);
|
|
+
|
|
+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
|
|
+ SADB_X_GRPSA,
|
|
+ satype,
|
|
+ 0,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ extr->ips->ips_said.spi,
|
|
+ extr->ips->ips_replaywin,
|
|
+ extr->ips->ips_state,
|
|
+ extr->ips->ips_authalg,
|
|
+ extr->ips->ips_encalg,
|
|
+ extr->ips->ips_flags,
|
|
+ extr->ips->ips_ref),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_d),
|
|
+ extensions_reply)
|
|
+ && (extr->ips2
|
|
+ ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
|
|
+ ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
|
|
+ /* proto2satype(extr->ips2->ips_said.proto) */),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2],
|
|
+ SADB_X_EXT_SA2,
|
|
+ extr->ips2->ips_said.spi,
|
|
+ extr->ips2->ips_replaywin,
|
|
+ extr->ips2->ips_state,
|
|
+ extr->ips2->ips_authalg,
|
|
+ extr->ips2->ips_encalg,
|
|
+ extr->ips2->ips_flags,
|
|
+ extr->ips2->ips_ref),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
|
|
+ SADB_X_EXT_ADDRESS_DST2,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips2->ips_addr_d),
|
|
+ extensions_reply) ) : 1 )
|
|
+ )) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "failed to build the x_grpsa reply message extensions\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "failed to build the x_grpsa reply message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
|
|
+ "succeeded in sending x_grpsa reply message.\n");
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_reply) {
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions_reply);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ char buf1[64], buf2[64];
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_reply = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+ ip_address srcflow, dstflow, srcmask, dstmask;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: .\n");
|
|
+
|
|
+ pfkey_extensions_init(extensions_reply);
|
|
+
|
|
+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
|
|
+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
|
|
+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
|
|
+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
|
|
+
|
|
+ if(!extr || !(extr->ips) || !(extr->eroute)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "missing extr, ipsec_sa or eroute data.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ srcflow.u.v4.sin_family = AF_INET;
|
|
+ dstflow.u.v4.sin_family = AF_INET;
|
|
+ srcmask.u.v4.sin_family = AF_INET;
|
|
+ dstmask.u.v4.sin_family = AF_INET;
|
|
+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
|
|
+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
|
|
+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
|
|
+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if (debug_pfkey) {
|
|
+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
|
|
+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
|
|
+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "calling breakeroute and/or makeroute for %s->%s\n",
|
|
+ buf1, buf2);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
|
|
+ struct ipsec_sa *ipsp, *ipsq;
|
|
+ char sa[SATOT_BUF];
|
|
+ size_t sa_len;
|
|
+
|
|
+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
|
|
+ if(ipsq == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "ipsec_sa not found, cannot set incoming policy.\n");
|
|
+ SENDERR(ENOENT);
|
|
+ }
|
|
+
|
|
+ ipsp = ipsq;
|
|
+ while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
|
|
+ ipsp = ipsp->ips_inext;
|
|
+ }
|
|
+
|
|
+ if(ipsp == NULL) {
|
|
+ ipsec_sa_put(ipsq);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
|
|
+ SENDERR(ENOENT);
|
|
+ }
|
|
+
|
|
+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
|
|
+
|
|
+ ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
|
|
+ ipsp->ips_flow_s = srcflow;
|
|
+ ipsp->ips_flow_d = dstflow;
|
|
+ ipsp->ips_mask_s = srcmask;
|
|
+ ipsp->ips_mask_d = dstmask;
|
|
+
|
|
+ ipsec_sa_put(ipsq);
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
|
|
+ sa_len ? sa : " (error)");
|
|
+ } else {
|
|
+ struct sk_buff *first = NULL, *last = NULL;
|
|
+
|
|
+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "REPLACEFLOW flag set, calling breakeroute.\n");
|
|
+ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
|
|
+ &(extr->eroute->er_emask),
|
|
+ &first, &last))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
|
|
+ error,
|
|
+ first,
|
|
+ last);
|
|
+ if(first != NULL) {
|
|
+ ipsec_kfree_skb(first);
|
|
+ }
|
|
+ if(last != NULL) {
|
|
+ ipsec_kfree_skb(last);
|
|
+ }
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "calling makeroute.\n");
|
|
+
|
|
+ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
|
|
+ &(extr->eroute->er_emask),
|
|
+ extr->ips->ips_said,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
|
|
+ NULL,
|
|
+ &(extr->ips->ips_ident_s),
|
|
+ &(extr->ips->ips_ident_d)))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "makeroute returned %d.\n", error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ if(first != NULL) {
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "first=0p%p HOLD packet re-injected.\n",
|
|
+ first);
|
|
+ DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL);
|
|
+ }
|
|
+ if(last != NULL) {
|
|
+ KLIPS_PRINT(debug_eroute,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "last=0p%p HOLD packet re-injected.\n",
|
|
+ last);
|
|
+ DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "makeroute call successful.\n");
|
|
+
|
|
+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
|
|
+ SADB_X_ADDFLOW,
|
|
+ satype,
|
|
+ 0,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ extr->ips->ips_said.spi,
|
|
+ extr->ips->ips_replaywin,
|
|
+ extr->ips->ips_state,
|
|
+ extr->ips->ips_authalg,
|
|
+ extr->ips->ips_encalg,
|
|
+ extr->ips->ips_flags,
|
|
+ extr->ips->ips_ref),
|
|
+ extensions_reply)
|
|
+ && (extensions[SADB_EXT_ADDRESS_SRC]
|
|
+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_s),
|
|
+ extensions_reply) : 1)
|
|
+ && (extensions[SADB_EXT_ADDRESS_DST]
|
|
+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ extr->ips->ips_addr_d),
|
|
+ extensions_reply) : 1)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
|
|
+ SADB_X_EXT_ADDRESS_SRC_FLOW,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ (struct sockaddr*)&srcflow),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
|
|
+ SADB_X_EXT_ADDRESS_DST_FLOW,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ (struct sockaddr*)&dstflow),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
|
|
+ SADB_X_EXT_ADDRESS_SRC_MASK,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ (struct sockaddr*)&srcmask),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
|
|
+ SADB_X_EXT_ADDRESS_DST_MASK,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ (struct sockaddr*)&dstmask),
|
|
+ extensions_reply)
|
|
+ )) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "failed to build the x_addflow reply message extensions\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "failed to build the x_addflow reply message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ extr->ips->ips_said.proto,
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_addflow_parse: "
|
|
+ "extr->ips cleaned up and freed.\n");
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_reply) {
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions_reply);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ char buf1[64], buf2[64];
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_reply = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
|
|
+ ip_address srcflow, dstflow, srcmask, dstmask;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_delflow_parse: .\n");
|
|
+
|
|
+ pfkey_extensions_init(extensions_reply);
|
|
+
|
|
+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
|
|
+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
|
|
+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
|
|
+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
|
|
+
|
|
+ if(!extr || !(extr->ips)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "extr, or extr->ips is NULL, fatal\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "CLEARFLOW flag set, calling cleareroutes.\n");
|
|
+ if ((error = ipsec_cleareroutes()))
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "cleareroutes returned %d.\n", error);
|
|
+ SENDERR(-error);
|
|
+ } else {
|
|
+ struct sk_buff *first = NULL, *last = NULL;
|
|
+
|
|
+ if(!(extr->eroute)) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "extr->eroute is NULL, fatal.\n");
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ srcflow.u.v4.sin_family = AF_INET;
|
|
+ dstflow.u.v4.sin_family = AF_INET;
|
|
+ srcmask.u.v4.sin_family = AF_INET;
|
|
+ dstmask.u.v4.sin_family = AF_INET;
|
|
+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
|
|
+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
|
|
+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
|
|
+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
|
|
+
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if (debug_pfkey) {
|
|
+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
|
|
+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
|
|
+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
|
|
+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "calling breakeroute for %s->%s\n",
|
|
+ buf1, buf2);
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ error = ipsec_breakroute(&(extr->eroute->er_eaddr),
|
|
+ &(extr->eroute->er_emask),
|
|
+ &first, &last);
|
|
+ if(error) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
|
|
+ error,
|
|
+ first,
|
|
+ last);
|
|
+ }
|
|
+ if(first != NULL) {
|
|
+ ipsec_kfree_skb(first);
|
|
+ }
|
|
+ if(last != NULL) {
|
|
+ ipsec_kfree_skb(last);
|
|
+ }
|
|
+ if(error) {
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
|
|
+ SADB_X_DELFLOW,
|
|
+ satype,
|
|
+ 0,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
|
|
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ extr->ips->ips_said.spi,
|
|
+ extr->ips->ips_replaywin,
|
|
+ extr->ips->ips_state,
|
|
+ extr->ips->ips_authalg,
|
|
+ extr->ips->ips_encalg,
|
|
+ extr->ips->ips_flags,
|
|
+ extr->ips->ips_ref),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
|
|
+ SADB_X_EXT_ADDRESS_SRC_FLOW,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ (struct sockaddr*)&srcflow),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
|
|
+ SADB_X_EXT_ADDRESS_DST_FLOW,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ (struct sockaddr*)&dstflow),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
|
|
+ SADB_X_EXT_ADDRESS_SRC_MASK,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ (struct sockaddr*)&srcmask),
|
|
+ extensions_reply)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
|
|
+ SADB_X_EXT_ADDRESS_DST_MASK,
|
|
+ 0, /*extr->ips->ips_said.proto,*/
|
|
+ 0,
|
|
+ (struct sockaddr*)&dstmask),
|
|
+ extensions_reply)
|
|
+ )) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "failed to build the x_delflow reply message extensions\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "failed to build the x_delflow reply message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_delflow_parse: "
|
|
+ "extr->ips cleaned up and freed.\n");
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_reply) {
|
|
+ pfkey_msg_free(&pfkey_reply);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions_reply);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_x_msg_debug_parse: .\n");
|
|
+
|
|
+/* errlab:*/
|
|
+ return error;
|
|
+}
|
|
+
|
|
+/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
|
|
+int
|
|
+pfkey_expire(struct ipsec_sa *ipsp, int hard)
|
|
+{
|
|
+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_msg = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ int error = 0;
|
|
+ uint8_t satype;
|
|
+
|
|
+ pfkey_extensions_init(extensions);
|
|
+
|
|
+ if(!(satype = proto2satype(ipsp->ips_said.proto))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_expire: "
|
|
+ "satype lookup for protocol %d lookup failed.\n",
|
|
+ ipsp->ips_said.proto);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!pfkey_open_sockets) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
|
|
+ "no sockets listening.\n");
|
|
+ SENDERR(EPROTONOSUPPORT);
|
|
+ }
|
|
+
|
|
+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
|
|
+ SADB_EXPIRE,
|
|
+ satype,
|
|
+ 0,
|
|
+ ++pfkey_msg_seq,
|
|
+ 0),
|
|
+ extensions)
|
|
+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ ipsp->ips_said.spi,
|
|
+ ipsp->ips_replaywin,
|
|
+ ipsp->ips_state,
|
|
+ ipsp->ips_authalg,
|
|
+ ipsp->ips_encalg,
|
|
+ ipsp->ips_flags,
|
|
+ ipsp->ips_ref),
|
|
+ extensions)
|
|
+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
|
|
+ SADB_EXT_LIFETIME_CURRENT,
|
|
+ ipsp->ips_life.ipl_allocations.ipl_count,
|
|
+ ipsp->ips_life.ipl_bytes.ipl_count,
|
|
+ ipsp->ips_life.ipl_addtime.ipl_count,
|
|
+ ipsp->ips_life.ipl_usetime.ipl_count,
|
|
+ ipsp->ips_life.ipl_packets.ipl_count),
|
|
+ extensions)
|
|
+ && (hard ?
|
|
+ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
|
|
+ SADB_EXT_LIFETIME_HARD,
|
|
+ ipsp->ips_life.ipl_allocations.ipl_hard,
|
|
+ ipsp->ips_life.ipl_bytes.ipl_hard,
|
|
+ ipsp->ips_life.ipl_addtime.ipl_hard,
|
|
+ ipsp->ips_life.ipl_usetime.ipl_hard,
|
|
+ ipsp->ips_life.ipl_packets.ipl_hard),
|
|
+ extensions)
|
|
+ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
|
|
+ SADB_EXT_LIFETIME_SOFT,
|
|
+ ipsp->ips_life.ipl_allocations.ipl_soft,
|
|
+ ipsp->ips_life.ipl_bytes.ipl_soft,
|
|
+ ipsp->ips_life.ipl_addtime.ipl_soft,
|
|
+ ipsp->ips_life.ipl_usetime.ipl_soft,
|
|
+ ipsp->ips_life.ipl_packets.ipl_soft),
|
|
+ extensions))
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC,
|
|
+ 0, /* ipsp->ips_said.proto, */
|
|
+ 0,
|
|
+ ipsp->ips_addr_s),
|
|
+ extensions)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ 0, /* ipsp->ips_said.proto, */
|
|
+ 0,
|
|
+ ipsp->ips_addr_d),
|
|
+ extensions))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
|
|
+ "failed to build the expire message extensions\n");
|
|
+ spin_unlock(&tdb_lock);
|
|
+ goto errlab;
|
|
+ }
|
|
+
|
|
+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
|
|
+ "failed to build the expire message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ for(pfkey_socketsp = pfkey_open_sockets;
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
|
|
+ "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
|
|
+ "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ ipsp->ips_said.proto,
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_msg) {
|
|
+ pfkey_msg_free(&pfkey_msg);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_acquire(struct ipsec_sa *ipsp)
|
|
+{
|
|
+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_msg = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ int error = 0;
|
|
+ struct sadb_comb comb[] = {
|
|
+ /* auth; encrypt; flags; */
|
|
+ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
|
|
+ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
|
|
+ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
|
|
+ /* soft_packets; hard_packets; */
|
|
+ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
|
|
+ 128, 128, 168, 168,
|
|
+ 0, 0, 0, 0, 0,
|
|
+ 57600, 86400, 57600, 86400,
|
|
+ 0, 0 },
|
|
+ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
|
|
+ 160, 160, 168, 168,
|
|
+ 0, 0, 0, 0, 0,
|
|
+ 57600, 86400, 57600, 86400,
|
|
+ 0, 0 }
|
|
+ };
|
|
+
|
|
+ /* XXX This should not be hard-coded. It should be taken from the spdb */
|
|
+ uint8_t satype = SADB_SATYPE_ESP;
|
|
+
|
|
+ pfkey_extensions_init(extensions);
|
|
+
|
|
+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
|
|
+ "SAtype=%d unspecified or unknown.\n",
|
|
+ satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!(pfkey_registered_sockets[satype])) {
|
|
+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
|
|
+ "no sockets registered for SAtype=%d(%s).\n",
|
|
+ satype,
|
|
+ satype2name(satype));
|
|
+ SENDERR(EPROTONOSUPPORT);
|
|
+ }
|
|
+
|
|
+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
|
|
+ SADB_ACQUIRE,
|
|
+ satype,
|
|
+ 0,
|
|
+ ++pfkey_msg_seq,
|
|
+ 0),
|
|
+ extensions)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC,
|
|
+ ipsp->ips_transport_protocol,
|
|
+ 0,
|
|
+ ipsp->ips_addr_s),
|
|
+ extensions)
|
|
+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ ipsp->ips_transport_protocol,
|
|
+ 0,
|
|
+ ipsp->ips_addr_d),
|
|
+ extensions)
|
|
+#if 0
|
|
+ && (ipsp->ips_addr_p
|
|
+ ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
|
|
+ SADB_EXT_ADDRESS_PROXY,
|
|
+ ipsp->ips_transport_protocol,
|
|
+ 0,
|
|
+ ipsp->ips_addr_p),
|
|
+ extensions) : 1)
|
|
+#endif
|
|
+ && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
|
|
+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
|
|
+ SADB_EXT_IDENTITY_SRC,
|
|
+ ipsp->ips_ident_s.type,
|
|
+ ipsp->ips_ident_s.id,
|
|
+ ipsp->ips_ident_s.len,
|
|
+ ipsp->ips_ident_s.data),
|
|
+ extensions) : 1)
|
|
+
|
|
+ && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
|
|
+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
|
|
+ SADB_EXT_IDENTITY_DST,
|
|
+ ipsp->ips_ident_d.type,
|
|
+ ipsp->ips_ident_d.id,
|
|
+ ipsp->ips_ident_d.len,
|
|
+ ipsp->ips_ident_d.data),
|
|
+ extensions) : 1)
|
|
+#if 0
|
|
+ /* FIXME: This won't work yet because I have not finished
|
|
+ it. */
|
|
+ && (ipsp->ips_sens_
|
|
+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
|
|
+ ipsp->ips_sens_dpd,
|
|
+ ipsp->ips_sens_sens_level,
|
|
+ ipsp->ips_sens_sens_len,
|
|
+ ipsp->ips_sens_sens_bitmap,
|
|
+ ipsp->ips_sens_integ_level,
|
|
+ ipsp->ips_sens_integ_len,
|
|
+ ipsp->ips_sens_integ_bitmap),
|
|
+ extensions) : 1)
|
|
+#endif
|
|
+ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
|
|
+ 64, /* replay */
|
|
+ sizeof(comb)/sizeof(struct sadb_comb),
|
|
+ &(comb[0])),
|
|
+ extensions)
|
|
+ )) {
|
|
+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
|
|
+ "failed to build the acquire message extensions\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
|
|
+ "failed to build the acquire message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
|
|
+ if(sysctl_ipsec_regress_pfkey_lossage) {
|
|
+ return(0);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ /* this should go to all registered sockets for that satype only */
|
|
+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
|
|
+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
|
|
+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
|
|
+ "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_msg) {
|
|
+ pfkey_msg_free(&pfkey_msg);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+int
|
|
+pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr,
|
|
+ __u16 sport)
|
|
+{
|
|
+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
|
|
+ struct sadb_msg *pfkey_msg = NULL;
|
|
+ struct socket_list *pfkey_socketsp;
|
|
+ int error = 0;
|
|
+ uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0;
|
|
+
|
|
+ /* Construct SADB_X_NAT_T_NEW_MAPPING message */
|
|
+
|
|
+ pfkey_extensions_init(extensions);
|
|
+
|
|
+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
|
|
+ "SAtype=%d unspecified or unknown.\n",
|
|
+ satype);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ if(!(pfkey_registered_sockets[satype])) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
|
|
+ "no sockets registered for SAtype=%d(%s).\n",
|
|
+ satype,
|
|
+ satype2name(satype));
|
|
+ SENDERR(EPROTONOSUPPORT);
|
|
+ }
|
|
+
|
|
+ if (!(pfkey_safe_build
|
|
+ (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING,
|
|
+ satype, 0, ++pfkey_msg_seq, 0), extensions)
|
|
+ /* SA */
|
|
+ && pfkey_safe_build
|
|
+ (error = pfkey_sa_build(&extensions[SADB_EXT_SA],
|
|
+ SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions)
|
|
+ /* ADDRESS_SRC = old addr */
|
|
+ && pfkey_safe_build
|
|
+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s),
|
|
+ extensions)
|
|
+ /* NAT_T_SPORT = old port */
|
|
+ && pfkey_safe_build
|
|
+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT],
|
|
+ SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions)
|
|
+ /* ADDRESS_DST = new addr */
|
|
+ && pfkey_safe_build
|
|
+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions)
|
|
+ /* NAT_T_DPORT = new port */
|
|
+ && pfkey_safe_build
|
|
+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT],
|
|
+ SADB_X_EXT_NAT_T_DPORT, sport), extensions)
|
|
+ )) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
|
|
+ "failed to build the nat_t_new_mapping message extensions\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
|
|
+ "failed to build the nat_t_new_mapping message\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ /* this should go to all registered sockets for that satype only */
|
|
+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
|
|
+ pfkey_socketsp;
|
|
+ pfkey_socketsp = pfkey_socketsp->next) {
|
|
+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
|
|
+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
|
|
+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
|
|
+ satype,
|
|
+ satype2name(satype),
|
|
+ pfkey_socketsp->socketp);
|
|
+ }
|
|
+
|
|
+ errlab:
|
|
+ if (pfkey_msg) {
|
|
+ pfkey_msg_free(&pfkey_msg);
|
|
+ }
|
|
+ pfkey_extensions_free(extensions);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+DEBUG_NO_STATIC int
|
|
+pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
|
|
+{
|
|
+ /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */
|
|
+ return -EINVAL;
|
|
+}
|
|
+#endif
|
|
+
|
|
+DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
|
|
+{
|
|
+ NULL, /* pfkey_msg_process, */
|
|
+ pfkey_sa_process,
|
|
+ pfkey_lifetime_process,
|
|
+ pfkey_lifetime_process,
|
|
+ pfkey_lifetime_process,
|
|
+ pfkey_address_process,
|
|
+ pfkey_address_process,
|
|
+ pfkey_address_process,
|
|
+ pfkey_key_process,
|
|
+ pfkey_key_process,
|
|
+ pfkey_ident_process,
|
|
+ pfkey_ident_process,
|
|
+ pfkey_sens_process,
|
|
+ pfkey_prop_process,
|
|
+ pfkey_supported_process,
|
|
+ pfkey_supported_process,
|
|
+ pfkey_spirange_process,
|
|
+ pfkey_x_kmprivate_process,
|
|
+ pfkey_x_satype_process,
|
|
+ pfkey_sa_process,
|
|
+ pfkey_address_process,
|
|
+ pfkey_address_process,
|
|
+ pfkey_address_process,
|
|
+ pfkey_address_process,
|
|
+ pfkey_address_process,
|
|
+ pfkey_x_debug_process,
|
|
+ pfkey_x_protocol_process
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ ,
|
|
+ pfkey_x_nat_t_type_process,
|
|
+ pfkey_x_nat_t_port_process,
|
|
+ pfkey_x_nat_t_port_process,
|
|
+ pfkey_address_process
|
|
+#endif
|
|
+};
|
|
+
|
|
+
|
|
+DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
|
|
+ =
|
|
+{
|
|
+ NULL, /* RESERVED */
|
|
+ pfkey_getspi_parse,
|
|
+ pfkey_update_parse,
|
|
+ pfkey_add_parse,
|
|
+ pfkey_delete_parse,
|
|
+ pfkey_get_parse,
|
|
+ pfkey_acquire_parse,
|
|
+ pfkey_register_parse,
|
|
+ pfkey_expire_parse,
|
|
+ pfkey_flush_parse,
|
|
+ pfkey_dump_parse,
|
|
+ pfkey_x_promisc_parse,
|
|
+ pfkey_x_pchange_parse,
|
|
+ pfkey_x_grpsa_parse,
|
|
+ pfkey_x_addflow_parse,
|
|
+ pfkey_x_delflow_parse,
|
|
+ pfkey_x_msg_debug_parse
|
|
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
|
|
+ , pfkey_x_nat_t_new_mapping_parse
|
|
+#endif
|
|
+};
|
|
+
|
|
+int
|
|
+pfkey_build_reply(struct sadb_msg *pfkey_msg,
|
|
+ struct pfkey_extracted_data *extr,
|
|
+ struct sadb_msg **pfkey_reply)
|
|
+{
|
|
+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
|
|
+ int error = 0;
|
|
+ int msg_type = pfkey_msg->sadb_msg_type;
|
|
+ int seq = pfkey_msg->sadb_msg_seq;
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
|
|
+ "building reply with type: %d\n",
|
|
+ msg_type);
|
|
+ pfkey_extensions_init(extensions);
|
|
+ if (!extr || !extr->ips) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
|
|
+ "bad ipsec_sa passed\n");
|
|
+ return EINVAL;
|
|
+ }
|
|
+ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
|
|
+ msg_type,
|
|
+ proto2satype(extr->ips->ips_said.proto),
|
|
+ 0,
|
|
+ seq,
|
|
+ pfkey_msg->sadb_msg_pid),
|
|
+ extensions) &&
|
|
+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
|
|
+ 1 << SADB_EXT_SA)
|
|
+ || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
|
|
+ SADB_EXT_SA,
|
|
+ extr->ips->ips_said.spi,
|
|
+ extr->ips->ips_replaywin,
|
|
+ extr->ips->ips_state,
|
|
+ extr->ips->ips_authalg,
|
|
+ extr->ips->ips_encalg,
|
|
+ extr->ips->ips_flags,
|
|
+ extr->ips->ips_ref),
|
|
+ extensions)) &&
|
|
+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
|
|
+ 1 << SADB_EXT_LIFETIME_CURRENT)
|
|
+ || pfkey_safe_build(pfkey_lifetime_build(&extensions
|
|
+ [SADB_EXT_LIFETIME_CURRENT],
|
|
+ SADB_EXT_LIFETIME_CURRENT,
|
|
+ extr->ips->ips_life.ipl_allocations.ipl_count,
|
|
+ extr->ips->ips_life.ipl_bytes.ipl_count,
|
|
+ extr->ips->ips_life.ipl_addtime.ipl_count,
|
|
+ extr->ips->ips_life.ipl_usetime.ipl_count,
|
|
+ extr->ips->ips_life.ipl_packets.ipl_count),
|
|
+ extensions)) &&
|
|
+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
|
|
+ 1 << SADB_EXT_ADDRESS_SRC)
|
|
+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
|
|
+ SADB_EXT_ADDRESS_SRC,
|
|
+ extr->ips->ips_said.proto,
|
|
+ 0,
|
|
+ extr->ips->ips_addr_s),
|
|
+ extensions)) &&
|
|
+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
|
|
+ 1 << SADB_EXT_ADDRESS_DST)
|
|
+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
|
|
+ SADB_EXT_ADDRESS_DST,
|
|
+ extr->ips->ips_said.proto,
|
|
+ 0,
|
|
+ extr->ips->ips_addr_d),
|
|
+ extensions));
|
|
+
|
|
+ if (error == 0) {
|
|
+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
|
|
+ "building extensions failed\n");
|
|
+ return EINVAL;
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_build_reply: "
|
|
+ "built extensions, proceed to build the message\n");
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_build_reply: "
|
|
+ "extensions[1]=0p%p\n",
|
|
+ extensions[1]);
|
|
+ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
|
|
+ pfkey_extensions_free(extensions);
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+int
|
|
+pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
|
|
+ struct sadb_msg **pfkey_reply)
|
|
+{
|
|
+ int error = 0;
|
|
+ int i;
|
|
+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
|
|
+ struct pfkey_extracted_data extr = {NULL, NULL, NULL};
|
|
+
|
|
+ pfkey_extensions_init(extensions);
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
|
|
+ pfkey_msg->sadb_msg_version,
|
|
+ pfkey_msg->sadb_msg_type,
|
|
+ pfkey_msg->sadb_msg_errno,
|
|
+ pfkey_msg->sadb_msg_satype,
|
|
+ satype2name(pfkey_msg->sadb_msg_satype),
|
|
+ pfkey_msg->sadb_msg_len,
|
|
+ pfkey_msg->sadb_msg_reserved,
|
|
+ pfkey_msg->sadb_msg_seq,
|
|
+ pfkey_msg->sadb_msg_pid);
|
|
+
|
|
+ extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
|
|
+ if(extr.ips == NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "memory allocation error.\n");
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "allocated extr->ips=0p%p.\n",
|
|
+ extr.ips);
|
|
+
|
|
+ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "satype %d > max %d\n",
|
|
+ pfkey_msg->sadb_msg_satype,
|
|
+ SADB_SATYPE_MAX);
|
|
+ SENDERR(EINVAL);
|
|
+ }
|
|
+
|
|
+ switch(pfkey_msg->sadb_msg_type) {
|
|
+ case SADB_GETSPI:
|
|
+ case SADB_UPDATE:
|
|
+ case SADB_ADD:
|
|
+ case SADB_DELETE:
|
|
+ case SADB_X_GRPSA:
|
|
+ case SADB_X_ADDFLOW:
|
|
+ if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "satype %d lookup failed.\n",
|
|
+ pfkey_msg->sadb_msg_satype);
|
|
+ SENDERR(EINVAL);
|
|
+ } else {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "satype %d lookups to proto=%d.\n",
|
|
+ pfkey_msg->sadb_msg_satype,
|
|
+ extr.ips->ips_said.proto);
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* The NULL below causes the default extension parsers to be used */
|
|
+ /* Parse the extensions */
|
|
+ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
|
|
+ {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "message parsing failed with error %d.\n",
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ /* Process the extensions */
|
|
+ for(i=1; i <= SADB_EXT_MAX;i++) {
|
|
+ if(extensions[i] != NULL) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "processing ext %d 0p%p with processor 0p%p.\n",
|
|
+ i, extensions[i], ext_processors[i]);
|
|
+ if((error = ext_processors[i](extensions[i], &extr))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "extension processing for type %d failed with error %d.\n",
|
|
+ i,
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ /* Parse the message types */
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "parsing message type %d(%s) with msg_parser 0p%p.\n",
|
|
+ pfkey_msg->sadb_msg_type,
|
|
+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
|
|
+ msg_parsers[pfkey_msg->sadb_msg_type]);
|
|
+ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
|
|
+ KLIPS_PRINT(debug_pfkey,
|
|
+ "klips_debug:pfkey_msg_interp: "
|
|
+ "message parsing failed with error %d.\n",
|
|
+ error);
|
|
+ SENDERR(-error);
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
|
|
+ if (error) {
|
|
+ *pfkey_reply = NULL;
|
|
+ }
|
|
+#endif
|
|
+ errlab:
|
|
+ if(extr.ips != NULL) {
|
|
+ ipsec_sa_wipe(extr.ips);
|
|
+ }
|
|
+ if(extr.ips2 != NULL) {
|
|
+ ipsec_sa_wipe(extr.ips2);
|
|
+ }
|
|
+ if (extr.eroute != NULL) {
|
|
+ kfree(extr.eroute);
|
|
+ }
|
|
+ return(error);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: pfkey_v2_parser.c,v $
|
|
+ * Revision 1.134.2.2 2006/10/06 21:39:26 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.134.2.1 2006/05/01 14:37:25 mcr
|
|
+ * ip_chk_addr -> inet_addr_type for more direct 2.4/2.6 support.
|
|
+ *
|
|
+ * Revision 1.134 2005/05/11 01:48:20 mcr
|
|
+ * removed "poor-man"s OOP in favour of proper C structures.
|
|
+ *
|
|
+ * Revision 1.133 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.132 2005/04/14 20:56:24 mcr
|
|
+ * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
|
|
+ *
|
|
+ * Revision 1.131 2005/01/26 00:50:35 mcr
|
|
+ * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
|
|
+ * and make sure that NAT_TRAVERSAL is set as well to match
|
|
+ * userspace compiles of code.
|
|
+ *
|
|
+ * Revision 1.130 2004/09/08 17:21:36 ken
|
|
+ * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
|
|
+ *
|
|
+ * Revision 1.129 2004/09/06 18:36:30 mcr
|
|
+ * if a protocol can not be found, then log it. This is not
|
|
+ * debugging.
|
|
+ *
|
|
+ * Revision 1.128 2004/08/21 00:45:19 mcr
|
|
+ * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
|
|
+ *
|
|
+ * Revision 1.127 2004/08/20 21:45:45 mcr
|
|
+ * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
|
|
+ * be 26sec compatible. But, some defines where changed.
|
|
+ *
|
|
+ * Revision 1.126 2004/08/17 03:27:23 mcr
|
|
+ * klips 2.6 edits.
|
|
+ *
|
|
+ * Revision 1.125 2004/08/04 15:57:07 mcr
|
|
+ * moved des .h files to include/des/ *
|
|
+ * included 2.6 protocol specific things
|
|
+ * started at NAT-T support, but it will require a kernel patch.
|
|
+ *
|
|
+ * Revision 1.124 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.123 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.122.2.2 2004/04/05 04:30:46 mcr
|
|
+ * patches for alg-branch to compile/work with 2.x openswan
|
|
+ *
|
|
+ * Revision 1.122.2.1 2003/12/22 15:25:52 jjo
|
|
+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
|
|
+ *
|
|
+ * Revision 1.122 2003/12/10 01:14:27 mcr
|
|
+ * NAT-traversal patches to KLIPS.
|
|
+ *
|
|
+ * Revision 1.121 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.120.4.2 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.120.4.1 2003/09/21 13:59:56 mcr
|
|
+ * pre-liminary X.509 patch - does not yet pass tests.
|
|
+ *
|
|
+ * Revision 1.120 2003/04/03 17:38:09 rgb
|
|
+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
|
|
+ *
|
|
+ * Revision 1.119 2003/02/06 01:52:37 rgb
|
|
+ * Removed no longer relevant comment
|
|
+ *
|
|
+ * Revision 1.118 2003/01/30 02:32:44 rgb
|
|
+ *
|
|
+ * Transmit error code through to caller from callee for better diagnosis of problems.
|
|
+ *
|
|
+ * Revision 1.117 2003/01/16 18:48:13 rgb
|
|
+ *
|
|
+ * Fixed sign bug in error return from an sa allocation call in
|
|
+ * pfkey_msg_interp.
|
|
+ *
|
|
+ * Revision 1.116 2002/10/17 16:38:01 rgb
|
|
+ * Change pfkey_alloc_eroute() to never static since its consumers
|
|
+ * have been moved outside the file.
|
|
+ *
|
|
+ * Revision 1.115 2002/10/12 23:11:53 dhr
|
|
+ *
|
|
+ * [KenB + DHR] more 64-bit cleanup
|
|
+ *
|
|
+ * Revision 1.114 2002/10/05 05:02:58 dhr
|
|
+ *
|
|
+ * C labels go on statements
|
|
+ *
|
|
+ * Revision 1.113 2002/09/30 19:11:22 rgb
|
|
+ * Turn on debugging for upgoing acquire messages to test for reliability.
|
|
+ *
|
|
+ * Revision 1.112 2002/09/20 15:41:16 rgb
|
|
+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
|
|
+ * Added sadb_x_sa_ref to struct sadb_sa.
|
|
+ * Added ref parameter to pfkey_sa_build().
|
|
+ *
|
|
+ * Revision 1.111 2002/09/20 05:02:08 rgb
|
|
+ * Added memory allocation debugging.
|
|
+ * Convert to switch to divulge hmac keys for debugging.
|
|
+ * Added text labels to elucidate numeric values presented.
|
|
+ *
|
|
+ * Revision 1.110 2002/08/03 18:03:05 mcr
|
|
+ * loop that checks for SPI's to have been already linked
|
|
+ * fails to actually step to next pointer, but continuously
|
|
+ * resets to head of list. Wrong pointer used.
|
|
+ * test east-icmp-02 revealed this.
|
|
+ *
|
|
+ * Revision 1.109 2002/07/26 08:48:31 rgb
|
|
+ * Added SA ref table code.
|
|
+ *
|
|
+ * Revision 1.108 2002/05/27 18:55:03 rgb
|
|
+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
|
|
+ *
|
|
+ * Revision 1.107 2002/05/23 07:16:08 rgb
|
|
+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
|
|
+ * Pointer clean-up.
|
|
+ * Added refcount code.
|
|
+ *
|
|
+ * Revision 1.106 2002/05/14 02:34:13 rgb
|
|
+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
|
|
+ * with "put" usage in the kernel.
|
|
+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
|
|
+ * ipsec_sa or ipsec_sa.
|
|
+ * Moved all the extension parsing functions to pfkey_v2_ext_process.c.
|
|
+ *
|
|
+ * Revision 1.105 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.104 2002/04/24 07:36:34 mcr
|
|
+ * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v
|
|
+ *
|
|
+ * Revision 1.103 2002/04/20 00:12:25 rgb
|
|
+ * Added esp IV CBC attack fix, disabled.
|
|
+ *
|
|
+ * Revision 1.102 2002/03/08 01:15:17 mcr
|
|
+ * put some internal structure only debug messages behind
|
|
+ * && sysctl_ipsec_debug_verbose.
|
|
+ *
|
|
+ * Revision 1.101 2002/01/29 17:17:57 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.100 2002/01/29 04:00:54 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.99 2002/01/29 02:13:19 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.98 2002/01/12 02:57:57 mcr
|
|
+ * first regression test causes acquire messages to be lost
|
|
+ * 100% of the time. This is to help testing of pluto.
|
|
+ *
|
|
+ * Revision 1.97 2001/11/26 09:23:52 rgb
|
|
+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
|
|
+ *
|
|
+ * Revision 1.93.2.4 2001/10/23 04:20:27 mcr
|
|
+ * parity was forced on wrong structure! prototypes help here.
|
|
+ *
|
|
+ * Revision 1.93.2.3 2001/10/22 21:14:59 mcr
|
|
+ * include des.h, removed phony prototypes and fixed calling
|
|
+ * conventions to match real prototypes.
|
|
+ *
|
|
+ * Revision 1.93.2.2 2001/10/15 05:39:03 mcr
|
|
+ * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
|
|
+ *
|
|
+ * Revision 1.93.2.1 2001/09/25 02:30:14 mcr
|
|
+ * struct tdb -> struct ipsec_sa.
|
|
+ * use new lifetime structure. common format routines for debug.
|
|
+ *
|
|
+ * Revision 1.96 2001/11/06 20:47:54 rgb
|
|
+ * Fixed user context call to ipsec_dev_start_xmit() bug. Call
|
|
+ * dev_queue_xmit() instead.
|
|
+ *
|
|
+ * Revision 1.95 2001/11/06 19:47:46 rgb
|
|
+ * Added packet parameter to lifetime and comb structures.
|
|
+ *
|
|
+ * Revision 1.94 2001/10/18 04:45:23 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/freeswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.93 2001/09/20 15:32:59 rgb
|
|
+ * Min/max cleanup.
|
|
+ *
|
|
+ * Revision 1.92 2001/09/19 16:35:48 rgb
|
|
+ * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
|
|
+ *
|
|
+ * Revision 1.91 2001/09/15 16:24:06 rgb
|
|
+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
|
|
+ *
|
|
+ * Revision 1.90 2001/09/14 16:58:38 rgb
|
|
+ * Added support for storing the first and last packets through a HOLD.
|
|
+ *
|
|
+ * Revision 1.89 2001/09/08 21:14:07 rgb
|
|
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
|
|
+ * Better state coherency (error management) between pf_key and IKE daemon.
|
|
+ * (NetCelo)
|
|
+ *
|
|
+ * Revision 1.88 2001/08/27 19:42:44 rgb
|
|
+ * Fix memory leak of encrypt and auth structs in pfkey register.
|
|
+ *
|
|
+ * Revision 1.87 2001/07/06 19:50:46 rgb
|
|
+ * Removed unused debugging code.
|
|
+ * Added inbound policy checking code for IPIP SAs.
|
|
+ *
|
|
+ * Revision 1.86 2001/06/20 06:26:04 rgb
|
|
+ * Changed missing SA errors from EEXIST to ENOENT and added debug output
|
|
+ * for already linked SAs.
|
|
+ *
|
|
+ * Revision 1.85 2001/06/15 04:57:02 rgb
|
|
+ * Remove single error return condition check and check for all errors in
|
|
+ * the case of a replace eroute delete operation. This means that
|
|
+ * applications must expect to be deleting something before replacing it
|
|
+ * and if nothing is found, complain.
|
|
+ *
|
|
+ * Revision 1.84 2001/06/14 19:35:12 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.83 2001/06/12 00:03:19 rgb
|
|
+ * Silence debug set/unset under normal conditions.
|
|
+ *
|
|
+ * Revision 1.82 2001/05/30 08:14:04 rgb
|
|
+ * Removed vestiges of esp-null transforms.
|
|
+ *
|
|
+ * Revision 1.81 2001/05/27 06:12:12 rgb
|
|
+ * Added structures for pid, packet count and last access time to eroute.
|
|
+ * Added packet count to beginning of /proc/net/ipsec_eroute.
|
|
+ *
|
|
+ * Revision 1.80 2001/05/03 19:43:59 rgb
|
|
+ * Check error return codes for all build function calls.
|
|
+ * Standardise on SENDERR() macro.
|
|
+ *
|
|
+ * Revision 1.79 2001/04/20 21:09:16 rgb
|
|
+ * Cleaned up fixed tdbwipes.
|
|
+ * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
|
|
+ * delflow (Per Cederqvist) plugging memleaks.
|
|
+ *
|
|
+ * Revision 1.78 2001/04/19 19:02:39 rgb
|
|
+ * Fixed extr.tdb freeing, stealing it for getspi, update and add.
|
|
+ * Refined a couple of spinlocks, fixed the one in update.
|
|
+ *
|
|
+ * Revision 1.77 2001/04/18 20:26:16 rgb
|
|
+ * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
|
|
+ * instead of inside each message type parser. This fixes two memleaks.
|
|
+ *
|
|
+ * Revision 1.76 2001/04/17 23:51:18 rgb
|
|
+ * Quiet down pfkey_x_debug_process().
|
|
+ *
|
|
+ * Revision 1.75 2001/03/29 01:55:05 rgb
|
|
+ * Fixed pfkey key init memleak.
|
|
+ * Fixed pfkey encryption key debug output.
|
|
+ *
|
|
+ * Revision 1.74 2001/03/27 05:29:14 rgb
|
|
+ * Debug output cleanup/silencing.
|
|
+ *
|
|
+ * Revision 1.73 2001/02/28 05:03:28 rgb
|
|
+ * Clean up and rationalise startup messages.
|
|
+ *
|
|
+ * Revision 1.72 2001/02/27 22:24:56 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.71 2001/02/27 06:59:30 rgb
|
|
+ * Added satype2name() conversions most places satype is debug printed.
|
|
+ *
|
|
+ * Revision 1.70 2001/02/26 22:37:08 rgb
|
|
+ * Fixed 'unknown proto' INT bug in new code.
|
|
+ * Added satype to protocol debugging instrumentation.
|
|
+ *
|
|
+ * Revision 1.69 2001/02/26 19:57:51 rgb
|
|
+ * Re-formatted debug output (split lines, consistent spacing).
|
|
+ * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
|
|
+ * with an satype instead of proto.
|
|
+ * Checked for satype consistency and fixed minor bugs.
|
|
+ * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
|
|
+ * Check for satype sanity in pfkey_expire().
|
|
+ * Added satype sanity check to addflow.
|
|
+ *
|
|
+ * Revision 1.68 2001/02/12 23:14:40 rgb
|
|
+ * Remove double spin lock in pfkey_expire().
|
|
+ *
|
|
+ * Revision 1.67 2001/01/31 19:23:40 rgb
|
|
+ * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
|
|
+ *
|
|
+ * Revision 1.66 2001/01/29 22:20:04 rgb
|
|
+ * Fix minor add upmsg lifetime bug.
|
|
+ *
|
|
+ * Revision 1.65 2001/01/24 06:12:33 rgb
|
|
+ * Fixed address extension compile bugs just introduced.
|
|
+ *
|
|
+ * Revision 1.64 2001/01/24 00:31:15 rgb
|
|
+ * Added upmsg for addflow/delflow.
|
|
+ *
|
|
+ * Revision 1.63 2001/01/23 22:02:55 rgb
|
|
+ * Added upmsg to x_grpsa.
|
|
+ * Fixed lifetimes extentions to add/update/get upmsg.
|
|
+ *
|
|
+ * Revision 1.62 2000/11/30 21:47:51 rgb
|
|
+ * Fix error return bug after returning from pfkey_tdb_init().
|
|
+ *
|
|
+ * Revision 1.61 2000/11/17 18:10:29 rgb
|
|
+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
|
|
+ * network byte order since this is the way PF_KEYv2 stored spis.
|
|
+ *
|
|
+ * Revision 1.60 2000/11/06 04:34:53 rgb
|
|
+ * Changed non-exported functions to DEBUG_NO_STATIC.
|
|
+ * Add Svenning's adaptive content compression.
|
|
+ * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
|
|
+ * Fixed double unlock bug (Svenning).
|
|
+ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
|
|
+ * Fixed incorrect extension type (prop) in pfkey)acquire().
|
|
+ *
|
|
+ * Revision 1.59 2000/10/11 15:25:12 rgb
|
|
+ * Fixed IPCOMP disabled compile bug.
|
|
+ *
|
|
+ * Revision 1.58 2000/10/11 14:54:03 rgb
|
|
+ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
|
|
+ * protocol violations of setting pfkey_address_build() protocol parameter
|
|
+ * to non-zero except in the case of pfkey_acquire().
|
|
+ *
|
|
+ * Revision 1.57 2000/10/10 20:10:18 rgb
|
|
+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
|
|
+ *
|
|
+ * Revision 1.56 2000/10/06 20:24:36 rgb
|
|
+ * Fixes to pfkey_acquire to initialize extensions[] and use correct
|
|
+ * ipproto.
|
|
+ *
|
|
+ * Revision 1.55 2000/10/03 03:20:57 rgb
|
|
+ * Added brackets to get a?b:c scope right for pfkey_register reply.
|
|
+ *
|
|
+ * Revision 1.54 2000/09/29 19:49:30 rgb
|
|
+ * As-yet-unused-bits cleanup.
|
|
+ *
|
|
+ * Revision 1.53 2000/09/28 00:35:45 rgb
|
|
+ * Padded SATYPE printout in pfkey_register for vertical alignment.
|
|
+ *
|
|
+ * Revision 1.52 2000/09/20 16:21:58 rgb
|
|
+ * Cleaned up ident string alloc/free.
|
|
+ *
|
|
+ * Revision 1.51 2000/09/20 04:04:20 rgb
|
|
+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
|
|
+ * oopsen.
|
|
+ *
|
|
+ * Revision 1.50 2000/09/16 01:10:53 rgb
|
|
+ * Fixed unused var warning with debug off.
|
|
+ *
|
|
+ * Revision 1.49 2000/09/15 11:37:02 rgb
|
|
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
|
|
+ * IPCOMP zlib deflate code.
|
|
+ *
|
|
+ * Revision 1.48 2000/09/15 04:57:57 rgb
|
|
+ * Cleaned up existing IPCOMP code before svenning addition.
|
|
+ * Initialize pfkey_reply and extensions_reply in case of early error in
|
|
+ * message parsing functions (thanks Kai!).
|
|
+ *
|
|
+ * Revision 1.47 2000/09/13 08:02:56 rgb
|
|
+ * Added KMd registration notification.
|
|
+ *
|
|
+ * Revision 1.46 2000/09/12 22:35:36 rgb
|
|
+ * Restructured to remove unused extensions from CLEARFLOW messages.
|
|
+ *
|
|
+ * Revision 1.45 2000/09/12 03:24:23 rgb
|
|
+ * Converted #if0 debugs to sysctl.
|
|
+ *
|
|
+ * Revision 1.44 2000/09/09 06:38:39 rgb
|
|
+ * Correct SADB message type for update, add and delete.
|
|
+ *
|
|
+ * Revision 1.43 2000/09/08 19:19:56 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
|
|
+ * Put in sanity checks in most msg type parsers to catch invalid satypes
|
|
+ * and empty socket lists.
|
|
+ * Moved spin-locks in pfkey_get_parse() to simplify.
|
|
+ * Added pfkey_acquire().
|
|
+ * Added upwards messages to update, add, delete, acquire_parse,
|
|
+ * expire_parse and flush.
|
|
+ * Fix pfkey_prop_build() parameter to be only single indirection.
|
|
+ * Changed all replies to use pfkey_reply.
|
|
+ * Check return code on puttdb() and deltdbchain() in getspi, update,
|
|
+ * add, delete.
|
|
+ * Fixed up all pfkey replies to open and registered sockets.
|
|
+ *
|
|
+ * Revision 1.42 2000/09/01 18:50:26 rgb
|
|
+ * Added a supported algorithms array lists, one per satype and registered
|
|
+ * existing algorithms.
|
|
+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
|
|
+ * list.
|
|
+ * Only send pfkey_expire() messages to sockets registered for that satype.
|
|
+ * Added reply to pfkey_getspi_parse().
|
|
+ * Added reply to pfkey_get_parse().
|
|
+ * Fixed debug output label bug in pfkey_lifetime_process().
|
|
+ * Cleaned up pfkey_sa_process a little.
|
|
+ * Moved pfkey_safe_build() above message type parsers to make it available
|
|
+ * for creating replies.
|
|
+ * Added comments for future work in pfkey_acquire_parse().
|
|
+ * Fleshed out guts of pfkey_register_parse().
|
|
+ *
|
|
+ * Revision 1.41 2000/08/24 16:58:11 rgb
|
|
+ * Fixed key debugging variables.
|
|
+ * Fixed error return code for a failed search.
|
|
+ * Changed order of pfkey_get operations.
|
|
+ *
|
|
+ * Revision 1.40 2000/08/21 16:32:27 rgb
|
|
+ * Re-formatted for cosmetic consistency and readability.
|
|
+ *
|
|
+ * Revision 1.39 2000/08/20 21:38:57 rgb
|
|
+ * Bugfixes to as-yet-unused pfkey_update_parse() and
|
|
+ * pfkey_register_parse(). (Momchil)
|
|
+ * Added functions pfkey_safe_build(), pfkey_expire() and
|
|
+ * pfkey_build_reply(). (Momchil)
|
|
+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
|
|
+ *
|
|
+ * Revision 1.38 2000/08/18 21:30:41 rgb
|
|
+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
|
|
+ *
|
|
+ * Revision 1.37 2000/08/18 18:18:02 rgb
|
|
+ * Cosmetic and descriptive changes made to debug test.
|
|
+ * getspi and update fixes from Momchil.
|
|
+ *
|
|
+ * Revision 1.36 2000/08/15 15:41:55 rgb
|
|
+ * Fixed the (as yet unused and untested) pfkey_getspi() routine.
|
|
+ *
|
|
+ * Revision 1.35 2000/08/01 14:51:52 rgb
|
|
+ * Removed _all_ remaining traces of DES.
|
|
+ *
|
|
+ * Revision 1.34 2000/07/28 14:58:32 rgb
|
|
+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
|
|
+ *
|
|
+ * Revision 1.33 2000/06/28 05:50:11 rgb
|
|
+ * Actually set iv_bits.
|
|
+ *
|
|
+ * Revision 1.32 2000/05/30 18:36:56 rgb
|
|
+ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY
|
|
+ * FreeS/WAN, but fixes interop with other implementations.
|
|
+ *
|
|
+ * Revision 1.31 2000/03/16 14:05:48 rgb
|
|
+ * Fixed brace scope preventing non-debug compile.
|
|
+ * Added null parameter check for pfkey_x_debug().
|
|
+ *
|
|
+ * Revision 1.30 2000/01/22 23:21:13 rgb
|
|
+ * Use new function satype2proto().
|
|
+ *
|
|
+ * Revision 1.29 2000/01/22 08:40:21 rgb
|
|
+ * Invert condition to known value to avoid AF_INET6 in 2.0.36.
|
|
+ *
|
|
+ * Revision 1.28 2000/01/22 07:58:57 rgb
|
|
+ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
|
|
+ *
|
|
+ * Revision 1.27 2000/01/22 03:48:01 rgb
|
|
+ * Added extr pointer component debugging.
|
|
+ *
|
|
+ * Revision 1.26 2000/01/21 09:41:25 rgb
|
|
+ * Changed a (void*) to (char*) cast to do proper pointer math.
|
|
+ * Don't call tdbwipe if tdb2 is NULL.
|
|
+ *
|
|
+ * Revision 1.25 2000/01/21 06:21:01 rgb
|
|
+ * Added address cases for eroute flows.
|
|
+ * Tidied up compiler directive indentation for readability.
|
|
+ * Added ictx,octx vars for simplification.
|
|
+ * Added macros for HMAC padding magic numbers.
|
|
+ * Converted from double tdb arguments to one structure (extr)
|
|
+ * containing pointers to all temporary information structures
|
|
+ * and checking for valid arguments to all ext processors and
|
|
+ * msg type parsers.
|
|
+ * Added spiungrp'ing.
|
|
+ * Added klipsdebug switching capability.
|
|
+ * Removed sa_process() check for zero protocol.
|
|
+ * Added address case for DST2 for grouping.
|
|
+ * Added/changed minor debugging instrumentation.
|
|
+ * Fixed spigrp for single said, ungrouping case.
|
|
+ * Added code to parse addflow and delflow messages.
|
|
+ * Removed redundant statements duplicating tdbwipe() functionality
|
|
+ * and causing double kfrees.
|
|
+ * Permit addflow to have a protocol of 0.
|
|
+ *
|
|
+ * Revision 1.24 1999/12/09 23:23:00 rgb
|
|
+ * Added check to pfkey_sa_process() to do eroutes.
|
|
+ * Converted to DIVUP() macro.
|
|
+ * Converted if() to switch() in pfkey_register_parse().
|
|
+ * Use new pfkey_extensions_init() instead of memset().
|
|
+ *
|
|
+ * Revision 1.23 1999/12/01 22:18:13 rgb
|
|
+ * Preset minspi and maxspi values in case and spirange extension is not
|
|
+ * included and check for the presence of an spirange extension before
|
|
+ * using it. Initialise tdb_sastate to LARVAL.
|
|
+ * Fixed debugging output typo.
|
|
+ * Fixed authentication context initialisation bugs (4 places).
|
|
+ *
|
|
+ * Revision 1.22 1999/11/27 11:53:08 rgb
|
|
+ * Moved pfkey_msg_parse prototype to pfkey.h
|
|
+ * Moved exts_permitted/required prototype to pfkey.h.
|
|
+ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
|
|
+ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
|
|
+ * be called.
|
|
+ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
|
|
+ * Debugging error messages added.
|
|
+ * Enable lifetime_current checking.
|
|
+ * Remove illegal requirement for SA extension to be present in an
|
|
+ * originating GETSPI call.
|
|
+ * Re-instate requirement for UPDATE or ADD message to be MATURE.
|
|
+ * Add argument to pfkey_msg_parse() for direction.
|
|
+ * Fixed IPIP dst address bug and purged redundant, leaky code.
|
|
+ *
|
|
+ * Revision 1.21 1999/11/24 05:24:20 rgb
|
|
+ * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
|
|
+ * Fixed indention.
|
|
+ * Ditched redundant replay check.
|
|
+ * Fixed debug message text from 'parse' to 'process'.
|
|
+ * Added more debug output.
|
|
+ * Forgot to zero extensions array causing bug, fixed.
|
|
+ *
|
|
+ * Revision 1.20 1999/11/23 23:08:13 rgb
|
|
+ * Move all common parsing code to lib/pfkey_v2_parse.c and rename
|
|
+ * remaining bits to *_process. (PJO)
|
|
+ * Add macros for dealing with alignment and rounding up more opaquely.
|
|
+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
|
|
+ * Sort out pfkey and freeswan headers, putting them in a library path.
|
|
+ * Corrected a couple of bugs in as-yet-inactive code.
|
|
+ *
|
|
+ * Revision 1.19 1999/11/20 22:01:10 rgb
|
|
+ * Add more descriptive error messages for non-zero reserved fields.
|
|
+ * Add more descriptive error message for spirange parsing.
|
|
+ * Start on supported extension parsing.
|
|
+ * Start on register and get message parsing.
|
|
+ *
|
|
+ * Revision 1.18 1999/11/18 04:09:20 rgb
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ *
|
|
+ * Revision 1.17 1999/11/17 15:53:41 rgb
|
|
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
|
|
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
|
|
+ * klips/net/ipsec/Makefile.
|
|
+ *
|
|
+ * Revision 1.16 1999/10/26 16:57:43 rgb
|
|
+ * Add shorter macros for compiler directives to visually clean-up.
|
|
+ * Give ipv6 code meaningful compiler directive.
|
|
+ * Add comments to other #if 0 debug code.
|
|
+ * Remove unused *_bh_atomic() calls.
|
|
+ * Fix mis-placed spinlock.
|
|
+ *
|
|
+ * Revision 1.15 1999/10/16 18:27:10 rgb
|
|
+ * Clean-up unused cruft.
|
|
+ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
|
|
+ *
|
|
+ * Revision 1.14 1999/10/08 18:37:34 rgb
|
|
+ * Fix end-of-line spacing to sate whining PHMs.
|
|
+ *
|
|
+ * Revision 1.13 1999/10/03 18:49:12 rgb
|
|
+ * Spinlock fixes for 2.0.xx and 2.3.xx.
|
|
+ *
|
|
+ * Revision 1.12 1999/10/01 15:44:54 rgb
|
|
+ * Move spinlock header include to 2.1> scope.
|
|
+ *
|
|
+ * Revision 1.11 1999/10/01 00:05:45 rgb
|
|
+ * Added tdb structure locking.
|
|
+ * Use 'jiffies' instead of do_get_timeofday().
|
|
+ * Fix lifetime assignments.
|
|
+ *
|
|
+ * Revision 1.10 1999/09/21 15:24:45 rgb
|
|
+ * Rework spirange code to save entropy and prevent endless loops.
|
|
+ *
|
|
+ * Revision 1.9 1999/09/16 12:10:21 rgb
|
|
+ * Minor fixes to random spi selection for correctness and entropy conservation.
|
|
+ *
|
|
+ * Revision 1.8 1999/05/25 22:54:46 rgb
|
|
+ * Fix comparison that should be an assignment in an if.
|
|
+ *
|
|
+ * Revision 1.7 1999/05/09 03:25:37 rgb
|
|
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
|
|
+ *
|
|
+ * Revision 1.6 1999/05/08 21:32:30 rgb
|
|
+ * Fix error return reporting.
|
|
+ *
|
|
+ * Revision 1.5 1999/05/05 22:02:33 rgb
|
|
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
|
|
+ *
|
|
+ * Revision 1.4 1999/04/29 15:22:40 rgb
|
|
+ * Standardise an error return method.
|
|
+ * Add debugging instrumentation.
|
|
+ * Add check for existence of macros min/max.
|
|
+ * Add extensions permitted/required in/out filters.
|
|
+ * Add satype-to-protocol table.
|
|
+ * Add a second tdb pointer to each parser to accomodate GRPSA.
|
|
+ * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
|
|
+ * Add OOO window check.
|
|
+ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
|
|
+ * Add timestamp to lifetime parse.
|
|
+ * Fix address structure length checking bug.
|
|
+ * Fix address structure allocation bug (forgot to kmalloc!).
|
|
+ * Add checks for extension lengths.
|
|
+ * Add checks for extension reserved illegal values.
|
|
+ * Add check for spirange legal values.
|
|
+ * Add an extension type for parsing a second satype, SA and
|
|
+ * DST_ADDRESS.
|
|
+ * Make changes to tdb_init() template to get pfkey_tdb_init(),
|
|
+ * eliminating any mention of xformsw.
|
|
+ * Implement getspi, update and grpsa (not tested).
|
|
+ * Add stubs for as yet unimplemented message types.
|
|
+ * Add table of message parsers to substitute for msg_parse switch.
|
|
+ *
|
|
+ * Revision 1.3 1999/04/15 17:58:07 rgb
|
|
+ * Add RCSID labels.
|
|
+ *
|
|
+ * Revision 1.2 1999/04/15 15:37:26 rgb
|
|
+ * Forward check changes from POST1_00 branch.
|
|
+ *
|
|
+ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb
|
|
+ * Add pfkeyv2 support to KLIPS.
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-file-style: "linux"
|
|
+ * End:
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/prng.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,201 @@
|
|
+/*
|
|
+ * crypto-class pseudorandom number generator
|
|
+ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
|
|
+ * Copyright (C) 2002 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: prng.c,v 1.7 2004/07/10 07:48:36 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+/*
|
|
+ - prng_init - initialize PRNG from a key
|
|
+ */
|
|
+void
|
|
+prng_init(prng, key, keylen)
|
|
+struct prng *prng;
|
|
+const unsigned char *key;
|
|
+size_t keylen;
|
|
+{
|
|
+ unsigned char k[256];
|
|
+ int i, j;
|
|
+ unsigned const char *p;
|
|
+ unsigned const char *keyend = key + keylen;
|
|
+ unsigned char t;
|
|
+
|
|
+ for (i = 0; i <= 255; i++)
|
|
+ prng->sbox[i] = i;
|
|
+ p = key;
|
|
+ for (i = 0; i <= 255; i++) {
|
|
+ k[i] = *p++;
|
|
+ if (p >= keyend)
|
|
+ p = key;
|
|
+ }
|
|
+ j = 0;
|
|
+ for (i = 0; i <= 255; i++) {
|
|
+ j = (j + prng->sbox[i] + k[i]) & 0xff;
|
|
+ t = prng->sbox[i];
|
|
+ prng->sbox[i] = prng->sbox[j];
|
|
+ prng->sbox[j] = t;
|
|
+ k[i] = 0; /* clear out key memory */
|
|
+ }
|
|
+ prng->i = 0;
|
|
+ prng->j = 0;
|
|
+ prng->count = 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - prng_bytes - get some pseudorandom bytes from PRNG
|
|
+ */
|
|
+void
|
|
+prng_bytes(prng, dst, dstlen)
|
|
+struct prng *prng;
|
|
+unsigned char *dst;
|
|
+size_t dstlen;
|
|
+{
|
|
+ int i, j, t;
|
|
+ unsigned char *p = dst;
|
|
+ size_t remain = dstlen;
|
|
+# define MAX 4000000000ul
|
|
+
|
|
+ while (remain > 0) {
|
|
+ i = (prng->i + 1) & 0xff;
|
|
+ prng->i = i;
|
|
+ j = (prng->j + prng->sbox[i]) & 0xff;
|
|
+ prng->j = j;
|
|
+ t = prng->sbox[i];
|
|
+ prng->sbox[i] = prng->sbox[j];
|
|
+ prng->sbox[j] = t;
|
|
+ t = (t + prng->sbox[i]) & 0xff;
|
|
+ *p++ = prng->sbox[t];
|
|
+ remain--;
|
|
+ }
|
|
+ if (prng->count < MAX - dstlen)
|
|
+ prng->count += dstlen;
|
|
+ else
|
|
+ prng->count = MAX;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - prnt_count - how many bytes have been extracted from PRNG so far?
|
|
+ */
|
|
+unsigned long
|
|
+prng_count(prng)
|
|
+struct prng *prng;
|
|
+{
|
|
+ return prng->count;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - prng_final - clear out PRNG to ensure nothing left in memory
|
|
+ */
|
|
+void
|
|
+prng_final(prng)
|
|
+struct prng *prng;
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i <= 255; i++)
|
|
+ prng->sbox[i] = 0;
|
|
+ prng->i = 0;
|
|
+ prng->j = 0;
|
|
+ prng->count = 0; /* just for good measure */
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+#ifdef PRNG_MAIN
|
|
+
|
|
+#include <stdio.h>
|
|
+
|
|
+void regress();
|
|
+
|
|
+int
|
|
+main(argc, argv)
|
|
+int argc;
|
|
+char *argv[];
|
|
+{
|
|
+ struct prng pr;
|
|
+ unsigned char buf[100];
|
|
+ unsigned char *p;
|
|
+ size_t n;
|
|
+
|
|
+ if (argc < 2) {
|
|
+ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
|
|
+ exit(2);
|
|
+ }
|
|
+
|
|
+ if (strcmp(argv[1], "-r") == 0) {
|
|
+ regress();
|
|
+ fprintf(stderr, "regress() returned?!?\n");
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ prng_init(&pr, argv[1], strlen(argv[1]));
|
|
+ prng_bytes(&pr, buf, 32);
|
|
+ printf("0x");
|
|
+ for (p = buf, n = 32; n > 0; p++, n--)
|
|
+ printf("%02x", *p);
|
|
+ printf("\n%lu bytes\n", prng_count(&pr));
|
|
+ prng_final(&pr);
|
|
+ exit(0);
|
|
+}
|
|
+
|
|
+void
|
|
+regress()
|
|
+{
|
|
+ struct prng pr;
|
|
+ unsigned char buf[100];
|
|
+ unsigned char *p;
|
|
+ size_t n;
|
|
+ /* somewhat non-random sample key */
|
|
+ unsigned char key[] = "here we go gathering nuts in May";
|
|
+ /* first thirty bytes of output from that key */
|
|
+ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
|
|
+ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
|
|
+ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
|
|
+ int nzero, none;
|
|
+ int show = 0;
|
|
+
|
|
+ prng_init(&pr, key, strlen(key));
|
|
+ prng_bytes(&pr, buf, sizeof(buf));
|
|
+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
|
|
+ if (*p == 0)
|
|
+ nzero++;
|
|
+ if (*p == 255)
|
|
+ none++;
|
|
+ }
|
|
+ if (nzero > 3 || none > 3) {
|
|
+ fprintf(stderr, "suspiciously non-random output!\n");
|
|
+ show = 1;
|
|
+ }
|
|
+ if (memcmp(buf, good, strlen(good)) != 0) {
|
|
+ fprintf(stderr, "incorrect output!\n");
|
|
+ show = 1;
|
|
+ }
|
|
+ if (show) {
|
|
+ fprintf(stderr, "0x");
|
|
+ for (p = buf, n = sizeof(buf); n > 0; p++, n--)
|
|
+ fprintf(stderr, "%02x", *p);
|
|
+ fprintf(stderr, "\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ if (prng_count(&pr) != sizeof(buf)) {
|
|
+ fprintf(stderr, "got %u bytes, but count is %lu\n",
|
|
+ sizeof(buf), prng_count(&pr));
|
|
+ exit(1);
|
|
+ }
|
|
+ prng_final(&pr);
|
|
+ exit(0);
|
|
+}
|
|
+
|
|
+#endif /* PRNG_MAIN */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1237 @@
|
|
+char radij_c_version[] = "RCSID $Id: radij.c,v 1.48.2.1 2006/10/06 21:39:27 paul Exp $";
|
|
+
|
|
+/*
|
|
+ * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
|
|
+ *
|
|
+ * Variable and procedure names have been modified so that they don't
|
|
+ * conflict with the original BSD code, as a small number of modifications
|
|
+ * have been introduced and we may want to reuse this code in BSD.
|
|
+ *
|
|
+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
|
|
+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
|
|
+ * spanish j as in Juan. It is not as far back in the throat like
|
|
+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
|
|
+ * It has nothing to do with the Dutch ij sound.
|
|
+ *
|
|
+ * Here is the appropriate copyright notice:
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Copyright (c) 1988, 1989, 1993
|
|
+ * The Regents of the University of California. All rights reserved.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * This product includes software developed by the University of
|
|
+ * California, Berkeley and its contributors.
|
|
+ * 4. Neither the name of the University nor the names of its contributors
|
|
+ * may be used to endorse or promote products derived from this software
|
|
+ * without specific prior written permission.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * @(#)radix.c 8.2 (Berkeley) 1/4/94
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Routines to build and maintain radix trees for routing lookups.
|
|
+ */
|
|
+
|
|
+#ifndef AUTOCONF_INCLUDED
|
|
+#include <linux/config.h>
|
|
+#endif
|
|
+#include <linux/version.h>
|
|
+#include <linux/kernel.h> /* printk() */
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef MALLOC_SLAB
|
|
+# include <linux/slab.h> /* kmalloc() */
|
|
+#else /* MALLOC_SLAB */
|
|
+# include <linux/malloc.h> /* kmalloc() */
|
|
+#endif /* MALLOC_SLAB */
|
|
+#include <linux/errno.h> /* error codes */
|
|
+#include <linux/types.h> /* size_t */
|
|
+#include <linux/interrupt.h> /* mark_bh */
|
|
+
|
|
+#include <linux/netdevice.h> /* struct device, and other headers */
|
|
+#include <linux/etherdevice.h> /* eth_type_trans */
|
|
+#include <linux/ip.h> /* struct iphdr */
|
|
+#include <linux/skbuff.h>
|
|
+#ifdef NET_21
|
|
+# include <linux/in6.h>
|
|
+#endif /* NET_21 */
|
|
+
|
|
+#include <net/ip.h>
|
|
+
|
|
+#include <openswan.h>
|
|
+
|
|
+#include "openswan/radij.h"
|
|
+#include "openswan/ipsec_encap.h"
|
|
+#include "openswan/ipsec_radij.h"
|
|
+
|
|
+int maj_keylen;
|
|
+struct radij_mask *rj_mkfreelist;
|
|
+struct radij_node_head *mask_rjhead;
|
|
+static int gotOddMasks;
|
|
+static char *maskedKey;
|
|
+static char *rj_zeroes, *rj_ones;
|
|
+
|
|
+#define rj_masktop (mask_rjhead->rnh_treetop)
|
|
+#ifdef Bcmp
|
|
+# undef Bcmp
|
|
+#endif /* Bcmp */
|
|
+#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
|
|
+/*
|
|
+ * The data structure for the keys is a radix tree with one way
|
|
+ * branching removed. The index rj_b at an internal node n represents a bit
|
|
+ * position to be tested. The tree is arranged so that all descendants
|
|
+ * of a node n have keys whose bits all agree up to position rj_b - 1.
|
|
+ * (We say the index of n is rj_b.)
|
|
+ *
|
|
+ * There is at least one descendant which has a one bit at position rj_b,
|
|
+ * and at least one with a zero there.
|
|
+ *
|
|
+ * A route is determined by a pair of key and mask. We require that the
|
|
+ * bit-wise logical and of the key and mask to be the key.
|
|
+ * We define the index of a route to associated with the mask to be
|
|
+ * the first bit number in the mask where 0 occurs (with bit number 0
|
|
+ * representing the highest order bit).
|
|
+ *
|
|
+ * We say a mask is normal if every bit is 0, past the index of the mask.
|
|
+ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
|
|
+ * and m is a normal mask, then the route applies to every descendant of n.
|
|
+ * If the index(m) < rj_b, this implies the trailing last few bits of k
|
|
+ * before bit b are all 0, (and hence consequently true of every descendant
|
|
+ * of n), so the route applies to all descendants of the node as well.
|
|
+ *
|
|
+ * The present version of the code makes no use of normal routes,
|
|
+ * but similar logic shows that a non-normal mask m such that
|
|
+ * index(m) <= index(n) could potentially apply to many children of n.
|
|
+ * Thus, for each non-host route, we attach its mask to a list at an internal
|
|
+ * node as high in the tree as we can go.
|
|
+ */
|
|
+
|
|
+struct radij_node *
|
|
+rj_search(v_arg, head)
|
|
+ void *v_arg;
|
|
+ struct radij_node *head;
|
|
+{
|
|
+ register struct radij_node *x;
|
|
+ register caddr_t v;
|
|
+
|
|
+ for (x = head, v = v_arg; x->rj_b >= 0;) {
|
|
+ if (x->rj_bmask & v[x->rj_off])
|
|
+ x = x->rj_r;
|
|
+ else
|
|
+ x = x->rj_l;
|
|
+ }
|
|
+ return (x);
|
|
+};
|
|
+
|
|
+struct radij_node *
|
|
+rj_search_m(v_arg, head, m_arg)
|
|
+ struct radij_node *head;
|
|
+ void *v_arg, *m_arg;
|
|
+{
|
|
+ register struct radij_node *x;
|
|
+ register caddr_t v = v_arg, m = m_arg;
|
|
+
|
|
+ for (x = head; x->rj_b >= 0;) {
|
|
+ if ((x->rj_bmask & m[x->rj_off]) &&
|
|
+ (x->rj_bmask & v[x->rj_off]))
|
|
+ x = x->rj_r;
|
|
+ else
|
|
+ x = x->rj_l;
|
|
+ }
|
|
+ return x;
|
|
+};
|
|
+
|
|
+int
|
|
+rj_refines(m_arg, n_arg)
|
|
+ void *m_arg, *n_arg;
|
|
+{
|
|
+ register caddr_t m = m_arg, n = n_arg;
|
|
+ register caddr_t lim, lim2 = lim = n + *(u_char *)n;
|
|
+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
|
|
+ int masks_are_equal = 1;
|
|
+
|
|
+ if (longer > 0)
|
|
+ lim -= longer;
|
|
+ while (n < lim) {
|
|
+ if (*n & ~(*m))
|
|
+ return 0;
|
|
+ if (*n++ != *m++)
|
|
+ masks_are_equal = 0;
|
|
+
|
|
+ }
|
|
+ while (n < lim2)
|
|
+ if (*n++)
|
|
+ return 0;
|
|
+ if (masks_are_equal && (longer < 0))
|
|
+ for (lim2 = m - longer; m < lim2; )
|
|
+ if (*m++)
|
|
+ return 1;
|
|
+ return (!masks_are_equal);
|
|
+}
|
|
+
|
|
+
|
|
+struct radij_node *
|
|
+rj_match(v_arg, head)
|
|
+ void *v_arg;
|
|
+ struct radij_node_head *head;
|
|
+{
|
|
+ caddr_t v = v_arg;
|
|
+ register struct radij_node *t = head->rnh_treetop, *x;
|
|
+ register caddr_t cp = v, cp2, cp3;
|
|
+ caddr_t cplim, mstart;
|
|
+ struct radij_node *saved_t, *top = t;
|
|
+ int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
|
|
+
|
|
+ /*
|
|
+ * Open code rj_search(v, top) to avoid overhead of extra
|
|
+ * subroutine call.
|
|
+ */
|
|
+ for (; t->rj_b >= 0; ) {
|
|
+ if (t->rj_bmask & cp[t->rj_off])
|
|
+ t = t->rj_r;
|
|
+ else
|
|
+ t = t->rj_l;
|
|
+ }
|
|
+ /*
|
|
+ * See if we match exactly as a host destination
|
|
+ */
|
|
+ KLIPS_PRINT(debug_radij,
|
|
+ "klips_debug:rj_match: "
|
|
+ "* See if we match exactly as a host destination\n");
|
|
+
|
|
+ cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
|
|
+ for (; cp < cplim; cp++, cp2++)
|
|
+ if (*cp != *cp2)
|
|
+ goto on1;
|
|
+ /*
|
|
+ * This extra grot is in case we are explicitly asked
|
|
+ * to look up the default. Ugh!
|
|
+ */
|
|
+ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
|
|
+ t = t->rj_dupedkey;
|
|
+ return t;
|
|
+on1:
|
|
+ matched_off = cp - v;
|
|
+ saved_t = t;
|
|
+ KLIPS_PRINT(debug_radij,
|
|
+ "klips_debug:rj_match: "
|
|
+ "** try to match a leaf, t=0p%p\n", t);
|
|
+ do {
|
|
+ if (t->rj_mask) {
|
|
+ /*
|
|
+ * Even if we don't match exactly as a hosts;
|
|
+ * we may match if the leaf we wound up at is
|
|
+ * a route to a net.
|
|
+ */
|
|
+ cp3 = matched_off + t->rj_mask;
|
|
+ cp2 = matched_off + t->rj_key;
|
|
+ for (; cp < cplim; cp++)
|
|
+ if ((*cp2++ ^ *cp) & *cp3++)
|
|
+ break;
|
|
+ if (cp == cplim)
|
|
+ return t;
|
|
+ cp = matched_off + v;
|
|
+ }
|
|
+ } while ((t = t->rj_dupedkey));
|
|
+ t = saved_t;
|
|
+ /* start searching up the tree */
|
|
+ KLIPS_PRINT(debug_radij,
|
|
+ "klips_debug:rj_match: "
|
|
+ "*** start searching up the tree, t=0p%p\n",
|
|
+ t);
|
|
+ do {
|
|
+ register struct radij_mask *m;
|
|
+
|
|
+ t = t->rj_p;
|
|
+ KLIPS_PRINT(debug_radij,
|
|
+ "klips_debug:rj_match: "
|
|
+ "**** t=0p%p\n",
|
|
+ t);
|
|
+ if ((m = t->rj_mklist)) {
|
|
+ /*
|
|
+ * After doing measurements here, it may
|
|
+ * turn out to be faster to open code
|
|
+ * rj_search_m here instead of always
|
|
+ * copying and masking.
|
|
+ */
|
|
+ /* off = min(t->rj_off, matched_off); */
|
|
+ off = t->rj_off;
|
|
+ if (matched_off < off)
|
|
+ off = matched_off;
|
|
+ mstart = maskedKey + off;
|
|
+ do {
|
|
+ cp2 = mstart;
|
|
+ cp3 = m->rm_mask + off;
|
|
+ KLIPS_PRINT(debug_radij,
|
|
+ "klips_debug:rj_match: "
|
|
+ "***** cp2=0p%p cp3=0p%p\n",
|
|
+ cp2, cp3);
|
|
+ for (cp = v + off; cp < cplim;)
|
|
+ *cp2++ = *cp++ & *cp3++;
|
|
+ x = rj_search(maskedKey, t);
|
|
+ while (x && x->rj_mask != m->rm_mask)
|
|
+ x = x->rj_dupedkey;
|
|
+ if (x &&
|
|
+ (Bcmp(mstart, x->rj_key + off,
|
|
+ vlen - off) == 0))
|
|
+ return x;
|
|
+ } while ((m = m->rm_mklist));
|
|
+ }
|
|
+ } while (t != top);
|
|
+ KLIPS_PRINT(debug_radij,
|
|
+ "klips_debug:rj_match: "
|
|
+ "***** not found.\n");
|
|
+ return 0;
|
|
+};
|
|
+
|
|
+#ifdef RJ_DEBUG
|
|
+int rj_nodenum;
|
|
+struct radij_node *rj_clist;
|
|
+int rj_saveinfo;
|
|
+DEBUG_NO_STATIC void traverse(struct radij_node *);
|
|
+#ifdef RJ_DEBUG2
|
|
+int rj_debug = 1;
|
|
+#else
|
|
+int rj_debug = 0;
|
|
+#endif /* RJ_DEBUG2 */
|
|
+#endif /* RJ_DEBUG */
|
|
+
|
|
+struct radij_node *
|
|
+rj_newpair(v, b, nodes)
|
|
+ void *v;
|
|
+ int b;
|
|
+ struct radij_node nodes[2];
|
|
+{
|
|
+ register struct radij_node *tt = nodes, *t = tt + 1;
|
|
+ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
|
|
+ t->rj_l = tt; t->rj_off = b >> 3;
|
|
+ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
|
|
+ tt->rj_flags = t->rj_flags = RJF_ACTIVE;
|
|
+#ifdef RJ_DEBUG
|
|
+ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
|
|
+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
|
|
+#endif /* RJ_DEBUG */
|
|
+ return t;
|
|
+}
|
|
+
|
|
+struct radij_node *
|
|
+rj_insert(v_arg, head, dupentry, nodes)
|
|
+ void *v_arg;
|
|
+ struct radij_node_head *head;
|
|
+ int *dupentry;
|
|
+ struct radij_node nodes[2];
|
|
+{
|
|
+ caddr_t v = v_arg;
|
|
+ struct radij_node *top = head->rnh_treetop;
|
|
+ int head_off = top->rj_off, vlen = (int)*((u_char *)v);
|
|
+ register struct radij_node *t = rj_search(v_arg, top);
|
|
+ register caddr_t cp = v + head_off;
|
|
+ register int b;
|
|
+ struct radij_node *tt;
|
|
+ /*
|
|
+ *find first bit at which v and t->rj_key differ
|
|
+ */
|
|
+ {
|
|
+ register caddr_t cp2 = t->rj_key + head_off;
|
|
+ register int cmp_res;
|
|
+ caddr_t cplim = v + vlen;
|
|
+
|
|
+ while (cp < cplim)
|
|
+ if (*cp2++ != *cp++)
|
|
+ goto on1;
|
|
+ *dupentry = 1;
|
|
+ return t;
|
|
+on1:
|
|
+ *dupentry = 0;
|
|
+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
|
|
+ for (b = (cp - v) << 3; cmp_res; b--)
|
|
+ cmp_res >>= 1;
|
|
+ }
|
|
+ {
|
|
+ register struct radij_node *p, *x = top;
|
|
+ cp = v;
|
|
+ do {
|
|
+ p = x;
|
|
+ if (cp[x->rj_off] & x->rj_bmask)
|
|
+ x = x->rj_r;
|
|
+ else x = x->rj_l;
|
|
+ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
|
|
+#ifdef RJ_DEBUG
|
|
+ if (rj_debug)
|
|
+ printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
|
|
+#endif /* RJ_DEBUG */
|
|
+ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
|
|
+ if ((cp[p->rj_off] & p->rj_bmask) == 0)
|
|
+ p->rj_l = t;
|
|
+ else
|
|
+ p->rj_r = t;
|
|
+ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
|
|
+ if ((cp[t->rj_off] & t->rj_bmask) == 0) {
|
|
+ t->rj_r = x;
|
|
+ } else {
|
|
+ t->rj_r = tt; t->rj_l = x;
|
|
+ }
|
|
+#ifdef RJ_DEBUG
|
|
+ if (rj_debug)
|
|
+ printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
|
|
+#endif /* RJ_DEBUG */
|
|
+ }
|
|
+ return (tt);
|
|
+}
|
|
+
|
|
+struct radij_node *
|
|
+rj_addmask(n_arg, search, skip)
|
|
+ int search, skip;
|
|
+ void *n_arg;
|
|
+{
|
|
+ caddr_t netmask = (caddr_t)n_arg;
|
|
+ register struct radij_node *x;
|
|
+ register caddr_t cp, cplim;
|
|
+ register int b, mlen, j;
|
|
+ int maskduplicated;
|
|
+
|
|
+ mlen = *(u_char *)netmask;
|
|
+ if (search) {
|
|
+ x = rj_search(netmask, rj_masktop);
|
|
+ mlen = *(u_char *)netmask;
|
|
+ if (Bcmp(netmask, x->rj_key, mlen) == 0)
|
|
+ return (x);
|
|
+ }
|
|
+ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
|
|
+ if (x == 0)
|
|
+ return (0);
|
|
+ Bzero(x, maj_keylen + 2 * sizeof (*x));
|
|
+ cp = (caddr_t)(x + 2);
|
|
+ Bcopy(netmask, cp, mlen);
|
|
+ netmask = cp;
|
|
+ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
|
|
+ /*
|
|
+ * Calculate index of mask.
|
|
+ */
|
|
+ cplim = netmask + mlen;
|
|
+ for (cp = netmask + skip; cp < cplim; cp++)
|
|
+ if (*(u_char *)cp != 0xff)
|
|
+ break;
|
|
+ b = (cp - netmask) << 3;
|
|
+ if (cp != cplim) {
|
|
+ if (*cp != 0) {
|
|
+ gotOddMasks = 1;
|
|
+ for (j = 0x80; j; b++, j >>= 1)
|
|
+ if ((j & *cp) == 0)
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ x->rj_b = -1 - b;
|
|
+ return (x);
|
|
+}
|
|
+
|
|
+#if 0
|
|
+struct radij_node *
|
|
+#endif
|
|
+int
|
|
+rj_addroute(v_arg, n_arg, head, treenodes)
|
|
+ void *v_arg, *n_arg;
|
|
+ struct radij_node_head *head;
|
|
+ struct radij_node treenodes[2];
|
|
+{
|
|
+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
|
|
+ register struct radij_node *t, *x=NULL, *tt;
|
|
+ struct radij_node *saved_tt, *top = head->rnh_treetop;
|
|
+ short b = 0, b_leaf;
|
|
+ int mlen, keyduplicated;
|
|
+ caddr_t cplim;
|
|
+ struct radij_mask *m, **mp;
|
|
+
|
|
+ /*
|
|
+ * In dealing with non-contiguous masks, there may be
|
|
+ * many different routes which have the same mask.
|
|
+ * We will find it useful to have a unique pointer to
|
|
+ * the mask to speed avoiding duplicate references at
|
|
+ * nodes and possibly save time in calculating indices.
|
|
+ */
|
|
+ if (netmask) {
|
|
+ x = rj_search(netmask, rj_masktop);
|
|
+ mlen = *(u_char *)netmask;
|
|
+ if (Bcmp(netmask, x->rj_key, mlen) != 0) {
|
|
+ x = rj_addmask(netmask, 0, top->rj_off);
|
|
+ if (x == 0)
|
|
+ return -ENOMEM; /* (0) rgb */
|
|
+ }
|
|
+ netmask = x->rj_key;
|
|
+ b = -1 - x->rj_b;
|
|
+ }
|
|
+ /*
|
|
+ * Deal with duplicated keys: attach node to previous instance
|
|
+ */
|
|
+ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
|
|
+#ifdef RJ_DEBUG
|
|
+ printk("addkey: duplicated: %d\n", keyduplicated);
|
|
+#endif
|
|
+ if (keyduplicated) {
|
|
+ do {
|
|
+ if (tt->rj_mask == netmask)
|
|
+ return -EEXIST; /* -ENXIO; (0) rgb */
|
|
+ t = tt;
|
|
+ if (netmask == 0 ||
|
|
+ (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
|
|
+ break;
|
|
+ } while ((tt = tt->rj_dupedkey));
|
|
+ /*
|
|
+ * If the mask is not duplicated, we wouldn't
|
|
+ * find it among possible duplicate key entries
|
|
+ * anyway, so the above test doesn't hurt.
|
|
+ *
|
|
+ * We sort the masks for a duplicated key the same way as
|
|
+ * in a masklist -- most specific to least specific.
|
|
+ * This may require the unfortunate nuisance of relocating
|
|
+ * the head of the list.
|
|
+ */
|
|
+ if (tt && t == saved_tt) {
|
|
+ struct radij_node *xx = x;
|
|
+ /* link in at head of list */
|
|
+ (tt = treenodes)->rj_dupedkey = t;
|
|
+ tt->rj_flags = t->rj_flags;
|
|
+ tt->rj_p = x = t->rj_p;
|
|
+ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
|
|
+ saved_tt = tt; x = xx;
|
|
+ } else {
|
|
+ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
|
|
+ t->rj_dupedkey = tt;
|
|
+ }
|
|
+#ifdef RJ_DEBUG
|
|
+ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
|
|
+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
|
|
+#endif /* RJ_DEBUG */
|
|
+ t = saved_tt;
|
|
+ tt->rj_key = (caddr_t) v;
|
|
+ tt->rj_b = -1;
|
|
+ tt->rj_flags = t->rj_flags & ~RJF_ROOT;
|
|
+ }
|
|
+ /*
|
|
+ * Put mask in tree.
|
|
+ */
|
|
+ if (netmask) {
|
|
+ tt->rj_mask = netmask;
|
|
+ tt->rj_b = x->rj_b;
|
|
+ }
|
|
+ t = saved_tt->rj_p;
|
|
+ b_leaf = -1 - t->rj_b;
|
|
+ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
|
|
+ /* Promote general routes from below */
|
|
+ if (x->rj_b < 0) {
|
|
+ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
|
|
+ MKGet(m);
|
|
+ if (m) {
|
|
+ Bzero(m, sizeof *m);
|
|
+ m->rm_b = x->rj_b;
|
|
+ m->rm_mask = x->rj_mask;
|
|
+ x->rj_mklist = t->rj_mklist = m;
|
|
+ }
|
|
+ }
|
|
+ } else if (x->rj_mklist) {
|
|
+ /*
|
|
+ * Skip over masks whose index is > that of new node
|
|
+ */
|
|
+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
|
|
+ if (m->rm_b >= b_leaf)
|
|
+ break;
|
|
+ t->rj_mklist = m; *mp = 0;
|
|
+ }
|
|
+ /* Add new route to highest possible ancestor's list */
|
|
+ if ((netmask == 0) || (b > t->rj_b )) {
|
|
+#ifdef RJ_DEBUG
|
|
+ printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b);
|
|
+#endif
|
|
+ return 0; /* tt rgb */ /* can't lift at all */
|
|
+ }
|
|
+ b_leaf = tt->rj_b;
|
|
+ do {
|
|
+ x = t;
|
|
+ t = t->rj_p;
|
|
+ } while (b <= t->rj_b && x != top);
|
|
+ /*
|
|
+ * Search through routes associated with node to
|
|
+ * insert new route according to index.
|
|
+ * For nodes of equal index, place more specific
|
|
+ * masks first.
|
|
+ */
|
|
+ cplim = netmask + mlen;
|
|
+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
|
|
+ if (m->rm_b < b_leaf)
|
|
+ continue;
|
|
+ if (m->rm_b > b_leaf)
|
|
+ break;
|
|
+ if (m->rm_mask == netmask) {
|
|
+ m->rm_refs++;
|
|
+ tt->rj_mklist = m;
|
|
+#ifdef RJ_DEBUG
|
|
+ printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask);
|
|
+#endif
|
|
+ return 0; /* tt rgb */
|
|
+ }
|
|
+ if (rj_refines(netmask, m->rm_mask))
|
|
+ break;
|
|
+ }
|
|
+ MKGet(m);
|
|
+ if (m == 0) {
|
|
+ printk("klips_debug:rj_addroute: "
|
|
+ "Mask for route not entered\n");
|
|
+ return 0; /* (tt) rgb */
|
|
+ }
|
|
+ Bzero(m, sizeof *m);
|
|
+ m->rm_b = b_leaf;
|
|
+ m->rm_mask = netmask;
|
|
+ m->rm_mklist = *mp;
|
|
+ *mp = m;
|
|
+ tt->rj_mklist = m;
|
|
+#ifdef RJ_DEBUG
|
|
+ printk("klips:radij.c: addroute done\n");
|
|
+#endif
|
|
+ return 0; /* tt rgb */
|
|
+}
|
|
+
|
|
+int
|
|
+rj_delete(v_arg, netmask_arg, head, node)
|
|
+ void *v_arg, *netmask_arg;
|
|
+ struct radij_node_head *head;
|
|
+ struct radij_node **node;
|
|
+{
|
|
+ register struct radij_node *t, *p, *x, *tt;
|
|
+ struct radij_mask *m, *saved_m, **mp;
|
|
+ struct radij_node *dupedkey, *saved_tt, *top;
|
|
+ caddr_t v, netmask;
|
|
+ int b, head_off, vlen;
|
|
+
|
|
+ v = v_arg;
|
|
+ netmask = netmask_arg;
|
|
+ x = head->rnh_treetop;
|
|
+ tt = rj_search(v, x);
|
|
+ head_off = x->rj_off;
|
|
+ vlen = *(u_char *)v;
|
|
+ saved_tt = tt;
|
|
+ top = x;
|
|
+ if (tt == 0 ||
|
|
+ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
|
|
+ return -EFAULT; /* (0) rgb */
|
|
+ /*
|
|
+ * Delete our route from mask lists.
|
|
+ */
|
|
+ if ((dupedkey = tt->rj_dupedkey)) {
|
|
+ if (netmask)
|
|
+ netmask = rj_search(netmask, rj_masktop)->rj_key;
|
|
+ while (tt->rj_mask != netmask)
|
|
+ if ((tt = tt->rj_dupedkey) == 0)
|
|
+ return -ENOENT; /* -ENXIO; (0) rgb */
|
|
+ }
|
|
+ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
|
|
+ goto on1;
|
|
+ if (m->rm_mask != tt->rj_mask) {
|
|
+ printk("klips_debug:rj_delete: "
|
|
+ "inconsistent annotation\n");
|
|
+ goto on1;
|
|
+ }
|
|
+ if (--m->rm_refs >= 0)
|
|
+ goto on1;
|
|
+ b = -1 - tt->rj_b;
|
|
+ t = saved_tt->rj_p;
|
|
+ if (b > t->rj_b)
|
|
+ goto on1; /* Wasn't lifted at all */
|
|
+ do {
|
|
+ x = t;
|
|
+ t = t->rj_p;
|
|
+ } while (b <= t->rj_b && x != top);
|
|
+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
|
|
+ if (m == saved_m) {
|
|
+ *mp = m->rm_mklist;
|
|
+ MKFree(m);
|
|
+ break;
|
|
+ }
|
|
+ if (m == 0)
|
|
+ printk("klips_debug:rj_delete: "
|
|
+ "couldn't find our annotation\n");
|
|
+on1:
|
|
+ /*
|
|
+ * Eliminate us from tree
|
|
+ */
|
|
+ if (tt->rj_flags & RJF_ROOT)
|
|
+ return -EFAULT; /* (0) rgb */
|
|
+#ifdef RJ_DEBUG
|
|
+ /* Get us out of the creation list */
|
|
+ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
|
|
+ if (t) t->rj_ybro = tt->rj_ybro;
|
|
+#endif /* RJ_DEBUG */
|
|
+ t = tt->rj_p;
|
|
+ if (dupedkey) {
|
|
+ if (tt == saved_tt) {
|
|
+ x = dupedkey; x->rj_p = t;
|
|
+ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
|
|
+ } else {
|
|
+ for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
|
|
+ p = p->rj_dupedkey;
|
|
+ if (p) p->rj_dupedkey = tt->rj_dupedkey;
|
|
+ else printk("klips_debug:rj_delete: "
|
|
+ "couldn't find node that we started with\n");
|
|
+ }
|
|
+ t = tt + 1;
|
|
+ if (t->rj_flags & RJF_ACTIVE) {
|
|
+#ifndef RJ_DEBUG
|
|
+ *++x = *t; p = t->rj_p;
|
|
+#else
|
|
+ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
|
|
+#endif /* RJ_DEBUG */
|
|
+ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
|
|
+ x->rj_l->rj_p = x; x->rj_r->rj_p = x;
|
|
+ }
|
|
+ goto out;
|
|
+ }
|
|
+ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
|
|
+ p = t->rj_p;
|
|
+ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
|
|
+ x->rj_p = p;
|
|
+ /*
|
|
+ * Demote routes attached to us.
|
|
+ */
|
|
+ if (t->rj_mklist) {
|
|
+ if (x->rj_b >= 0) {
|
|
+ for (mp = &x->rj_mklist; (m = *mp);)
|
|
+ mp = &m->rm_mklist;
|
|
+ *mp = t->rj_mklist;
|
|
+ } else {
|
|
+ for (m = t->rj_mklist; m;) {
|
|
+ struct radij_mask *mm = m->rm_mklist;
|
|
+ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
|
|
+ x->rj_mklist = 0;
|
|
+ MKFree(m);
|
|
+ } else
|
|
+ printk("klips_debug:rj_delete: "
|
|
+ "Orphaned Mask 0p%p at 0p%p\n", m, x);
|
|
+ m = mm;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ /*
|
|
+ * We may be holding an active internal node in the tree.
|
|
+ */
|
|
+ x = tt + 1;
|
|
+ if (t != x) {
|
|
+#ifndef RJ_DEBUG
|
|
+ *t = *x;
|
|
+#else
|
|
+ b = t->rj_info; *t = *x; t->rj_info = b;
|
|
+#endif /* RJ_DEBUG */
|
|
+ t->rj_l->rj_p = t; t->rj_r->rj_p = t;
|
|
+ p = x->rj_p;
|
|
+ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
|
|
+ }
|
|
+out:
|
|
+ tt->rj_flags &= ~RJF_ACTIVE;
|
|
+ tt[1].rj_flags &= ~RJF_ACTIVE;
|
|
+ *node = tt;
|
|
+ return 0; /* (tt) rgb */
|
|
+}
|
|
+
|
|
+int
|
|
+rj_walktree(h, f, w)
|
|
+ struct radij_node_head *h;
|
|
+ register int (*f)(struct radij_node *,void *);
|
|
+ void *w;
|
|
+{
|
|
+ int error;
|
|
+ struct radij_node *base, *next;
|
|
+ register struct radij_node *rn;
|
|
+
|
|
+ if(!h || !f /* || !w */) {
|
|
+ return -ENODATA;
|
|
+ }
|
|
+
|
|
+ rn = h->rnh_treetop;
|
|
+ /*
|
|
+ * This gets complicated because we may delete the node
|
|
+ * while applying the function f to it, so we need to calculate
|
|
+ * the successor node in advance.
|
|
+ */
|
|
+ /* First time through node, go left */
|
|
+ while (rn->rj_b >= 0)
|
|
+ rn = rn->rj_l;
|
|
+ for (;;) {
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_radij) {
|
|
+ printk("klips_debug:rj_walktree: "
|
|
+ "for: rn=0p%p rj_b=%d rj_flags=%x",
|
|
+ rn,
|
|
+ rn->rj_b,
|
|
+ rn->rj_flags);
|
|
+ rn->rj_b >= 0 ?
|
|
+ printk(" node off=%x\n",
|
|
+ rn->rj_off) :
|
|
+ printk(" leaf key = %08x->%08x\n",
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
|
|
+ ;
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ base = rn;
|
|
+ /* If at right child go back up, otherwise, go right */
|
|
+ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
|
|
+ rn = rn->rj_p;
|
|
+ /* Find the next *leaf* since next node might vanish, too */
|
|
+ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
|
|
+ rn = rn->rj_l;
|
|
+ next = rn;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_radij) {
|
|
+ printk("klips_debug:rj_walktree: "
|
|
+ "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
|
|
+ rn,
|
|
+ rn->rj_b,
|
|
+ rn->rj_flags);
|
|
+ rn->rj_b >= 0 ?
|
|
+ printk(" node off=%x\n",
|
|
+ rn->rj_off) :
|
|
+ printk(" leaf key = %08x->%08x\n",
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
|
|
+ ;
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ /* Process leaves */
|
|
+ while ((rn = base)) {
|
|
+ base = rn->rj_dupedkey;
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ if(debug_radij) {
|
|
+ printk("klips_debug:rj_walktree: "
|
|
+ "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
|
|
+ base,
|
|
+ rn,
|
|
+ rn->rj_b,
|
|
+ rn->rj_flags);
|
|
+ rn->rj_b >= 0 ?
|
|
+ printk(" node off=%x\n",
|
|
+ rn->rj_off) :
|
|
+ printk(" leaf key = %08x->%08x\n",
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
|
|
+ ;
|
|
+ }
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
|
|
+ return (-error);
|
|
+ }
|
|
+ rn = next;
|
|
+ if (rn->rj_flags & RJF_ROOT)
|
|
+ return (0);
|
|
+ }
|
|
+ /* NOTREACHED */
|
|
+}
|
|
+
|
|
+int
|
|
+rj_inithead(head, off)
|
|
+ void **head;
|
|
+ int off;
|
|
+{
|
|
+ register struct radij_node_head *rnh;
|
|
+ register struct radij_node *t, *tt, *ttt;
|
|
+ if (*head)
|
|
+ return (1);
|
|
+ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
|
|
+ if (rnh == NULL)
|
|
+ return (0);
|
|
+ Bzero(rnh, sizeof (*rnh));
|
|
+ *head = rnh;
|
|
+ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
|
|
+ ttt = rnh->rnh_nodes + 2;
|
|
+ t->rj_r = ttt;
|
|
+ t->rj_p = t;
|
|
+ tt = t->rj_l;
|
|
+ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
|
|
+ tt->rj_b = -1 - off;
|
|
+ *ttt = *tt;
|
|
+ ttt->rj_key = rj_ones;
|
|
+ rnh->rnh_addaddr = rj_addroute;
|
|
+ rnh->rnh_deladdr = rj_delete;
|
|
+ rnh->rnh_matchaddr = rj_match;
|
|
+ rnh->rnh_walktree = rj_walktree;
|
|
+ rnh->rnh_treetop = t;
|
|
+ return (1);
|
|
+}
|
|
+
|
|
+void
|
|
+rj_init()
|
|
+{
|
|
+ char *cp, *cplim;
|
|
+
|
|
+ if (maj_keylen == 0) {
|
|
+ printk("klips_debug:rj_init: "
|
|
+ "radij functions require maj_keylen be set\n");
|
|
+ return;
|
|
+ }
|
|
+ R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
|
|
+ if (rj_zeroes == NULL)
|
|
+ panic("rj_init");
|
|
+ Bzero(rj_zeroes, 3 * maj_keylen);
|
|
+ rj_ones = cp = rj_zeroes + maj_keylen;
|
|
+ maskedKey = cplim = rj_ones + maj_keylen;
|
|
+ while (cp < cplim)
|
|
+ *cp++ = -1;
|
|
+ if (rj_inithead((void **)&mask_rjhead, 0) == 0)
|
|
+ panic("rj_init 2");
|
|
+}
|
|
+
|
|
+void
|
|
+rj_preorder(struct radij_node *rn, int l)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (rn == NULL){
|
|
+ printk("klips_debug:rj_preorder: "
|
|
+ "NULL pointer\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (rn->rj_b >= 0){
|
|
+ rj_preorder(rn->rj_l, l+1);
|
|
+ rj_preorder(rn->rj_r, l+1);
|
|
+ printk("klips_debug:");
|
|
+ for (i=0; i<l; i++)
|
|
+ printk("*");
|
|
+ printk(" off = %d\n",
|
|
+ rn->rj_off);
|
|
+ } else {
|
|
+ printk("klips_debug:");
|
|
+ for (i=0; i<l; i++)
|
|
+ printk("@");
|
|
+ printk(" flags = %x",
|
|
+ (u_int)rn->rj_flags);
|
|
+ if (rn->rj_flags & RJF_ACTIVE) {
|
|
+ printk(" @key=0p%p",
|
|
+ rn->rj_key);
|
|
+ printk(" key = %08x->%08x",
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
|
|
+ printk(" @mask=0p%p",
|
|
+ rn->rj_mask);
|
|
+ if (rn->rj_mask)
|
|
+ printk(" mask = %08x->%08x",
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
|
|
+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
|
|
+ if (rn->rj_dupedkey)
|
|
+ printk(" dupedkey = 0p%p",
|
|
+ rn->rj_dupedkey);
|
|
+ }
|
|
+ printk("\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+#ifdef RJ_DEBUG
|
|
+DEBUG_NO_STATIC void traverse(struct radij_node *p)
|
|
+{
|
|
+ rj_preorder(p, 0);
|
|
+}
|
|
+#endif /* RJ_DEBUG */
|
|
+
|
|
+void
|
|
+rj_dumptrees(void)
|
|
+{
|
|
+ rj_preorder(rnh->rnh_treetop, 0);
|
|
+}
|
|
+
|
|
+void
|
|
+rj_free_mkfreelist(void)
|
|
+{
|
|
+ struct radij_mask *mknp, *mknp2;
|
|
+
|
|
+ mknp = rj_mkfreelist;
|
|
+ while(mknp)
|
|
+ {
|
|
+ mknp2 = mknp;
|
|
+ mknp = mknp->rm_mklist;
|
|
+ kfree(mknp2);
|
|
+ }
|
|
+}
|
|
+
|
|
+int
|
|
+radijcleartree(void)
|
|
+{
|
|
+ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
|
|
+}
|
|
+
|
|
+int
|
|
+radijcleanup(void)
|
|
+{
|
|
+ int error = 0;
|
|
+
|
|
+ error = radijcleartree();
|
|
+
|
|
+ rj_free_mkfreelist();
|
|
+
|
|
+/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
|
|
+ if(mask_rjhead) {
|
|
+ kfree(mask_rjhead);
|
|
+ }
|
|
+
|
|
+ if(rj_zeroes) {
|
|
+ kfree(rj_zeroes);
|
|
+ }
|
|
+
|
|
+ if(rnh) {
|
|
+ kfree(rnh);
|
|
+ }
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * $Log: radij.c,v $
|
|
+ * Revision 1.48.2.1 2006/10/06 21:39:27 paul
|
|
+ * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
|
|
+ * set. This is defined through autoconf.h which is included through the
|
|
+ * linux kernel build macros.
|
|
+ *
|
|
+ * Revision 1.48 2005/04/29 05:10:22 mcr
|
|
+ * removed from extraenous includes to make unit testing easier.
|
|
+ *
|
|
+ * Revision 1.47 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.46 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.45 2003/10/31 02:27:55 mcr
|
|
+ * pulled up port-selector patches and sa_id elimination.
|
|
+ *
|
|
+ * Revision 1.44.30.1 2003/10/29 01:30:41 mcr
|
|
+ * elimited "struct sa_id".
|
|
+ *
|
|
+ * Revision 1.44 2002/07/24 18:44:54 rgb
|
|
+ * Type fiddling to tame ia64 compiler.
|
|
+ *
|
|
+ * Revision 1.43 2002/05/23 07:14:11 rgb
|
|
+ * Cleaned up %p variants to 0p%p for test suite cleanup.
|
|
+ *
|
|
+ * Revision 1.42 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.41 2002/04/24 07:36:35 mcr
|
|
+ * Moved from ./klips/net/ipsec/radij.c,v
|
|
+ *
|
|
+ * Revision 1.40 2002/01/29 17:17:58 mcr
|
|
+ * moved include of ipsec_param.h to after include of linux/kernel.h
|
|
+ * otherwise, it seems that some option that is set in ipsec_param.h
|
|
+ * screws up something subtle in the include path to kernel.h, and
|
|
+ * it complains on the snprintf() prototype.
|
|
+ *
|
|
+ * Revision 1.39 2002/01/29 04:00:55 mcr
|
|
+ * more excise of kversions.h header.
|
|
+ *
|
|
+ * Revision 1.38 2002/01/29 02:13:19 mcr
|
|
+ * introduction of ipsec_kversion.h means that include of
|
|
+ * ipsec_param.h must preceed any decisions about what files to
|
|
+ * include to deal with differences in kernel source.
|
|
+ *
|
|
+ * Revision 1.37 2001/10/18 04:45:23 rgb
|
|
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
|
|
+ * lib/freeswan.h version macros moved to lib/kversions.h.
|
|
+ * Other compiler directive cleanups.
|
|
+ *
|
|
+ * Revision 1.36 2001/08/22 13:43:51 henry
|
|
+ * eliminate the single use of min() to avoid problems with Linus changing it
|
|
+ *
|
|
+ * Revision 1.35 2001/06/15 04:57:29 rgb
|
|
+ * Clarified error return codes.
|
|
+ * Changed mask add already exists to EEXIST.
|
|
+ * Changed mask delete did not exist to ENOENT.
|
|
+ *
|
|
+ * Revision 1.34 2001/05/03 19:44:26 rgb
|
|
+ * Fix sign of error return codes for rj_addroute().
|
|
+ *
|
|
+ * Revision 1.33 2001/02/27 22:24:56 rgb
|
|
+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
|
|
+ * Check for satoa() return codes.
|
|
+ *
|
|
+ * Revision 1.32 2001/02/27 06:23:15 rgb
|
|
+ * Debug line splitting.
|
|
+ *
|
|
+ * Revision 1.31 2000/11/06 04:35:21 rgb
|
|
+ * Clear table *before* releasing other items in radijcleanup.
|
|
+ *
|
|
+ * Revision 1.30 2000/09/20 04:07:40 rgb
|
|
+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
|
|
+ * oopsen.
|
|
+ *
|
|
+ * Revision 1.29 2000/09/12 03:25:02 rgb
|
|
+ * Moved radij_c_version printing to ipsec_version_get_info().
|
|
+ *
|
|
+ * Revision 1.28 2000/09/08 19:12:56 rgb
|
|
+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
|
|
+ *
|
|
+ * Revision 1.27 2000/07/28 14:58:32 rgb
|
|
+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
|
|
+ *
|
|
+ * Revision 1.26 2000/05/10 23:11:37 rgb
|
|
+ * Comment out most of the startup version information.
|
|
+ *
|
|
+ * Revision 1.25 2000/01/21 06:21:47 rgb
|
|
+ * Change return codes to negative on error.
|
|
+ *
|
|
+ * Revision 1.24 1999/11/18 04:09:20 rgb
|
|
+ * Replaced all kernel version macros to shorter, readable form.
|
|
+ *
|
|
+ * Revision 1.23 1999/11/17 15:53:41 rgb
|
|
+ * Changed all occurrences of #include "../../../lib/freeswan.h"
|
|
+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
|
|
+ * klips/net/ipsec/Makefile.
|
|
+ *
|
|
+ * Revision 1.22 1999/10/15 22:17:28 rgb
|
|
+ * Modify radijcleanup() to call radijcleartree().
|
|
+ *
|
|
+ * Revision 1.21 1999/10/08 18:37:34 rgb
|
|
+ * Fix end-of-line spacing to sate whining PHMs.
|
|
+ *
|
|
+ * Revision 1.20 1999/10/01 15:44:54 rgb
|
|
+ * Move spinlock header include to 2.1> scope.
|
|
+ *
|
|
+ * Revision 1.19 1999/10/01 08:35:52 rgb
|
|
+ * Add spinlock include to shut up compiler for 2.0.38.
|
|
+ *
|
|
+ * Revision 1.18 1999/09/23 18:02:52 rgb
|
|
+ * De-alarm the search failure message so it doesn't sound so grave.
|
|
+ *
|
|
+ * Revision 1.17 1999/05/25 21:26:01 rgb
|
|
+ * Fix rj_walktree() sanity checking bug.
|
|
+ *
|
|
+ * Revision 1.16 1999/05/09 03:25:38 rgb
|
|
+ * Fix bug introduced by 2.2 quick-and-dirty patch.
|
|
+ *
|
|
+ * Revision 1.15 1999/05/05 22:02:33 rgb
|
|
+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
|
|
+ *
|
|
+ * Revision 1.14 1999/04/29 15:24:15 rgb
|
|
+ * Add sanity checking for null pointer arguments.
|
|
+ * Standardise an error return method.
|
|
+ *
|
|
+ * Revision 1.13 1999/04/11 00:29:02 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.12 1999/04/06 04:54:28 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ * Revision 1.11 1999/02/17 16:52:53 rgb
|
|
+ * Convert DEBUG_IPSEC to KLIPS_PRINT
|
|
+ * Clean out unused cruft.
|
|
+ *
|
|
+ * Revision 1.10 1999/01/22 06:30:05 rgb
|
|
+ * Cruft clean-out.
|
|
+ * 64-bit clean-up.
|
|
+ *
|
|
+ * Revision 1.9 1998/12/01 13:22:04 rgb
|
|
+ * Added support for debug printing of version info.
|
|
+ *
|
|
+ * Revision 1.8 1998/11/30 13:22:55 rgb
|
|
+ * Rationalised all the klips kernel file headers. They are much shorter
|
|
+ * now and won't conflict under RH5.2.
|
|
+ *
|
|
+ * Revision 1.7 1998/10/25 02:43:26 rgb
|
|
+ * Change return type on rj_addroute and rj_delete and add and argument
|
|
+ * to the latter to be able to transmit more infomation about errors.
|
|
+ *
|
|
+ * Revision 1.6 1998/10/19 14:30:06 rgb
|
|
+ * Added inclusion of freeswan.h.
|
|
+ *
|
|
+ * Revision 1.5 1998/10/09 04:33:27 rgb
|
|
+ * Added 'klips_debug' prefix to all klips printk debug statements.
|
|
+ * Fixed output formatting slightly.
|
|
+ *
|
|
+ * Revision 1.4 1998/07/28 00:06:59 rgb
|
|
+ * Add debug detail to tree traversing.
|
|
+ *
|
|
+ * Revision 1.3 1998/07/14 18:07:58 rgb
|
|
+ * Add a routine to clear the eroute tree.
|
|
+ *
|
|
+ * Revision 1.2 1998/06/25 20:03:22 rgb
|
|
+ * Cleanup #endif comments. Debug output for rj_init.
|
|
+ *
|
|
+ * Revision 1.1 1998/06/18 21:30:22 henry
|
|
+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
|
|
+ * build scripts happier about symlinks
|
|
+ *
|
|
+ * Revision 1.8 1998/05/25 20:34:15 rgb
|
|
+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
|
|
+ *
|
|
+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
|
|
+ * add ipsec_rj_walker_delete.
|
|
+ *
|
|
+ * Recover memory for eroute table on unload of module.
|
|
+ *
|
|
+ * Revision 1.7 1998/05/21 12:58:58 rgb
|
|
+ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
|
|
+ *
|
|
+ * Revision 1.6 1998/04/23 20:57:29 rgb
|
|
+ * Cleaned up compiler warnings for unused debugging functions.
|
|
+ *
|
|
+ * Revision 1.5 1998/04/22 16:51:38 rgb
|
|
+ * Tidy up radij debug code from recent rash of modifications to debug code.
|
|
+ *
|
|
+ * Revision 1.4 1998/04/21 21:28:56 rgb
|
|
+ * Rearrange debug switches to change on the fly debug output from user
|
|
+ * space. Only kernel changes checked in at this time. radij.c was also
|
|
+ * changed to temporarily remove buggy debugging code in rj_delete causing
|
|
+ * an OOPS and hence, netlink device open errors.
|
|
+ *
|
|
+ * Revision 1.3 1998/04/14 17:30:37 rgb
|
|
+ * Fix up compiling errors for radij tree memory reclamation.
|
|
+ *
|
|
+ * Revision 1.2 1998/04/12 22:03:25 rgb
|
|
+ * Updated ESP-3DES-HMAC-MD5-96,
|
|
+ * ESP-DES-HMAC-MD5-96,
|
|
+ * AH-HMAC-MD5-96,
|
|
+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
|
|
+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
|
|
+ *
|
|
+ * Fixed eroute references in /proc/net/ipsec*.
|
|
+ *
|
|
+ * Started to patch module unloading memory leaks in ipsec_netlink and
|
|
+ * radij tree unloading.
|
|
+ *
|
|
+ * Revision 1.1 1998/04/09 03:06:15 henry
|
|
+ * sources moved up from linux/net/ipsec
|
|
+ *
|
|
+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
|
|
+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
|
|
+ *
|
|
+ * Revision 0.4 1997/01/15 01:28:15 ji
|
|
+ * No changes.
|
|
+ *
|
|
+ * Revision 0.3 1996/11/20 14:39:04 ji
|
|
+ * Minor cleanups.
|
|
+ * Rationalized debugging code.
|
|
+ *
|
|
+ * Revision 0.2 1996/11/02 00:18:33 ji
|
|
+ * First limited release.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/rangetoa.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,60 @@
|
|
+/*
|
|
+ * convert binary form of address range to ASCII
|
|
+ * Copyright (C) 1998, 1999 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: rangetoa.c,v 1.9 2004/07/10 07:48:37 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+/*
|
|
+ - rangetoa - convert address range to ASCII
|
|
+ */
|
|
+size_t /* space needed for full conversion */
|
|
+rangetoa(addrs, format, dst, dstlen)
|
|
+struct in_addr addrs[2];
|
|
+int format; /* character */
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ size_t len;
|
|
+ size_t rest;
|
|
+ int n;
|
|
+ char *p;
|
|
+
|
|
+ switch (format) {
|
|
+ case 0:
|
|
+ break;
|
|
+ default:
|
|
+ return 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ len = addrtoa(addrs[0], 0, dst, dstlen);
|
|
+ if (len < dstlen)
|
|
+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
|
|
+ p++, len++, n--)
|
|
+ *p = '.';
|
|
+ else
|
|
+ p = NULL;
|
|
+ if (len < dstlen)
|
|
+ rest = dstlen - len;
|
|
+ else {
|
|
+ if (dstlen > 0)
|
|
+ *(dst + dstlen - 1) = '\0';
|
|
+ rest = 0;
|
|
+ }
|
|
+
|
|
+ len += addrtoa(addrs[1], 0, p, rest);
|
|
+
|
|
+ return len;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/satot.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,133 @@
|
|
+/*
|
|
+ * convert from binary form of SA ID to text
|
|
+ * Copyright (C) 2000, 2001 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: satot.c,v 1.13 2004/07/10 07:48:37 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+static struct typename {
|
|
+ char type;
|
|
+ char *name;
|
|
+} typenames[] = {
|
|
+ { SA_AH, "ah" },
|
|
+ { SA_ESP, "esp" },
|
|
+ { SA_IPIP, "tun" },
|
|
+ { SA_COMP, "comp" },
|
|
+ { SA_INT, "int" },
|
|
+ { 0, NULL }
|
|
+};
|
|
+
|
|
+/*
|
|
+ - satot - convert SA to text "ah507@1.2.3.4"
|
|
+ */
|
|
+size_t /* space needed for full conversion */
|
|
+satot(sa, format, dst, dstlen)
|
|
+const ip_said *sa;
|
|
+int format; /* character */
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ size_t len = 0; /* 0 means "not recognized yet" */
|
|
+ int base;
|
|
+ int showversion; /* use delimiter to show IP version? */
|
|
+ struct typename *tn;
|
|
+ char *p;
|
|
+ char *pre;
|
|
+ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
|
|
+ char unk[10];
|
|
+
|
|
+ switch (format) {
|
|
+ case 0:
|
|
+ base = 16;
|
|
+ showversion = 1;
|
|
+ break;
|
|
+ case 'f':
|
|
+ base = 17;
|
|
+ showversion = 1;
|
|
+ break;
|
|
+ case 'x':
|
|
+ base = 'x';
|
|
+ showversion = 0;
|
|
+ break;
|
|
+ case 'd':
|
|
+ base = 10;
|
|
+ showversion = 0;
|
|
+ break;
|
|
+ default:
|
|
+ return 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+
|
|
+ pre = NULL;
|
|
+ for (tn = typenames; tn->name != NULL; tn++)
|
|
+ if (sa->proto == tn->type) {
|
|
+ pre = tn->name;
|
|
+ break; /* NOTE BREAK OUT */
|
|
+ }
|
|
+ if (pre == NULL) { /* unknown protocol */
|
|
+ strcpy(unk, "unk");
|
|
+ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
|
|
+ sizeof(unk)-strlen(unk));
|
|
+ pre = unk;
|
|
+ }
|
|
+
|
|
+ if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
|
|
+ sa->spi == PASSTHROUGHSPI &&
|
|
+ isunspecaddr(&sa->dst)) {
|
|
+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
|
|
+ PASSTHROUGH4NAME :
|
|
+ PASSTHROUGH6NAME);
|
|
+ len = strlen(buf);
|
|
+ }
|
|
+
|
|
+ if (sa->proto == SA_INT) {
|
|
+ switch (ntohl(sa->spi)) {
|
|
+ case SPI_PASS: p = "%pass"; break;
|
|
+ case SPI_DROP: p = "%drop"; break;
|
|
+ case SPI_REJECT: p = "%reject"; break;
|
|
+ case SPI_HOLD: p = "%hold"; break;
|
|
+ case SPI_TRAP: p = "%trap"; break;
|
|
+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
|
|
+ default: p = NULL; break;
|
|
+ }
|
|
+ if (p != NULL) {
|
|
+ strcpy(buf, p);
|
|
+ len = strlen(buf);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (len == 0) { /* general case needed */
|
|
+ strcpy(buf, pre);
|
|
+ len = strlen(buf);
|
|
+ if (showversion) {
|
|
+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
|
|
+ ':';
|
|
+ len++;
|
|
+ *(buf+len) = '\0';
|
|
+ }
|
|
+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
|
|
+ *(buf+len-1) = '@';
|
|
+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
|
|
+ *(buf+len) = '\0';
|
|
+ }
|
|
+
|
|
+ if (dst != NULL) {
|
|
+ if (len > dstlen)
|
|
+ *(buf+dstlen-1) = '\0';
|
|
+ strcpy(dst, buf);
|
|
+ }
|
|
+ return len;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/subnetof.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,59 @@
|
|
+/*
|
|
+ * minor network-address manipulation utilities
|
|
+ * Copyright (C) 1998, 1999 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: subnetof.c,v 1.8 2004/07/10 07:48:37 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+/*
|
|
+ - subnetof - given address and mask, return subnet part
|
|
+ */
|
|
+struct in_addr
|
|
+subnetof(addr, mask)
|
|
+struct in_addr addr;
|
|
+struct in_addr mask;
|
|
+{
|
|
+ struct in_addr result;
|
|
+
|
|
+ result.s_addr = addr.s_addr & mask.s_addr;
|
|
+ return result;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - hostof - given address and mask, return host part
|
|
+ */
|
|
+struct in_addr
|
|
+hostof(addr, mask)
|
|
+struct in_addr addr;
|
|
+struct in_addr mask;
|
|
+{
|
|
+ struct in_addr result;
|
|
+
|
|
+ result.s_addr = addr.s_addr & ~mask.s_addr;
|
|
+ return result;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - broadcastof - given (network) address and mask, return broadcast address
|
|
+ */
|
|
+struct in_addr
|
|
+broadcastof(addr, mask)
|
|
+struct in_addr addr;
|
|
+struct in_addr mask;
|
|
+{
|
|
+ struct in_addr result;
|
|
+
|
|
+ result.s_addr = addr.s_addr | ~mask.s_addr;
|
|
+ return result;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/subnettoa.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,61 @@
|
|
+/*
|
|
+ * convert binary form of subnet description to ASCII
|
|
+ * Copyright (C) 1998, 1999 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: subnettoa.c,v 1.11 2004/07/10 07:48:37 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+/*
|
|
+ - subnettoa - convert address and mask to ASCII "addr/mask"
|
|
+ * Output expresses the mask as a bit count if possible, else dotted decimal.
|
|
+ */
|
|
+size_t /* space needed for full conversion */
|
|
+subnettoa(addr, mask, format, dst, dstlen)
|
|
+struct in_addr addr;
|
|
+struct in_addr mask;
|
|
+int format; /* character */
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ size_t len;
|
|
+ size_t rest;
|
|
+ int n;
|
|
+ char *p;
|
|
+
|
|
+ switch (format) {
|
|
+ case 0:
|
|
+ break;
|
|
+ default:
|
|
+ return 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ len = addrtoa(addr, 0, dst, dstlen);
|
|
+ if (len < dstlen) {
|
|
+ dst[len - 1] = '/';
|
|
+ p = dst + len;
|
|
+ rest = dstlen - len;
|
|
+ } else {
|
|
+ p = NULL;
|
|
+ rest = 0;
|
|
+ }
|
|
+
|
|
+ n = masktobits(mask);
|
|
+ if (n >= 0)
|
|
+ len += ultoa((unsigned long)n, 10, p, rest);
|
|
+ else
|
|
+ len += addrtoa(mask, 0, p, rest);
|
|
+
|
|
+ return len;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,199 @@
|
|
+/*
|
|
+ * sysctl interface to net IPSEC subsystem.
|
|
+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License as published by the
|
|
+ * Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * RCSID $Id: sysctl_net_ipsec.c,v 1.17 2004/07/10 19:11:18 mcr Exp $
|
|
+ */
|
|
+
|
|
+/* -*- linux-c -*-
|
|
+ *
|
|
+ * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
|
|
+ */
|
|
+
|
|
+#include <linux/mm.h>
|
|
+#include <linux/sysctl.h>
|
|
+
|
|
+#include "openswan/ipsec_param.h"
|
|
+
|
|
+#ifdef CONFIG_SYSCTL
|
|
+
|
|
+#define NET_IPSEC 2112 /* Random number */
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+extern int debug_ah;
|
|
+extern int debug_esp;
|
|
+extern int debug_tunnel;
|
|
+extern int debug_eroute;
|
|
+extern int debug_spi;
|
|
+extern int debug_radij;
|
|
+extern int debug_netlink;
|
|
+extern int debug_xform;
|
|
+extern int debug_rcv;
|
|
+extern int debug_pfkey;
|
|
+extern int sysctl_ipsec_debug_verbose;
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+extern int sysctl_ipsec_debug_ipcomp;
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+
|
|
+extern int sysctl_ipsec_icmp;
|
|
+extern int sysctl_ipsec_inbound_policy_check;
|
|
+extern int sysctl_ipsec_tos;
|
|
+int sysctl_ipsec_regress_pfkey_lossage;
|
|
+
|
|
+enum {
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ NET_IPSEC_DEBUG_AH=1,
|
|
+ NET_IPSEC_DEBUG_ESP=2,
|
|
+ NET_IPSEC_DEBUG_TUNNEL=3,
|
|
+ NET_IPSEC_DEBUG_EROUTE=4,
|
|
+ NET_IPSEC_DEBUG_SPI=5,
|
|
+ NET_IPSEC_DEBUG_RADIJ=6,
|
|
+ NET_IPSEC_DEBUG_NETLINK=7,
|
|
+ NET_IPSEC_DEBUG_XFORM=8,
|
|
+ NET_IPSEC_DEBUG_RCV=9,
|
|
+ NET_IPSEC_DEBUG_PFKEY=10,
|
|
+ NET_IPSEC_DEBUG_VERBOSE=11,
|
|
+ NET_IPSEC_DEBUG_IPCOMP=12,
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ NET_IPSEC_ICMP=13,
|
|
+ NET_IPSEC_INBOUND_POLICY_CHECK=14,
|
|
+ NET_IPSEC_TOS=15,
|
|
+ NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
|
|
+};
|
|
+
|
|
+static ctl_table ipsec_table[] = {
|
|
+#ifdef CONFIG_KLIPS_DEBUG
|
|
+ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+#ifdef CONFIG_KLIPS_IPCOMP
|
|
+ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+#endif /* CONFIG_KLIPS_IPCOMP */
|
|
+
|
|
+#ifdef CONFIG_KLIPS_REGRESS
|
|
+ { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
|
|
+ &sysctl_ipsec_regress_pfkey_lossage,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+#endif /* CONFIG_KLIPS_REGRESS */
|
|
+
|
|
+#endif /* CONFIG_KLIPS_DEBUG */
|
|
+ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
|
|
+ sizeof(int), 0644, NULL, &proc_dointvec},
|
|
+ {0}
|
|
+};
|
|
+
|
|
+static ctl_table ipsec_net_table[] = {
|
|
+ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
|
|
+ { 0 }
|
|
+};
|
|
+
|
|
+static ctl_table ipsec_root_table[] = {
|
|
+ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
|
|
+ { 0 }
|
|
+};
|
|
+
|
|
+static struct ctl_table_header *ipsec_table_header;
|
|
+
|
|
+int ipsec_sysctl_register(void)
|
|
+{
|
|
+ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
|
|
+ if (!ipsec_table_header) {
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void ipsec_sysctl_unregister(void)
|
|
+{
|
|
+ unregister_sysctl_table(ipsec_table_header);
|
|
+}
|
|
+
|
|
+#endif /* CONFIG_SYSCTL */
|
|
+
|
|
+/*
|
|
+ * $Log: sysctl_net_ipsec.c,v $
|
|
+ * Revision 1.17 2004/07/10 19:11:18 mcr
|
|
+ * CONFIG_IPSEC -> CONFIG_KLIPS.
|
|
+ *
|
|
+ * Revision 1.16 2004/04/06 02:49:26 mcr
|
|
+ * pullup of algo code from alg-branch.
|
|
+ *
|
|
+ * Revision 1.15 2002/04/24 07:55:32 mcr
|
|
+ * #include patches and Makefiles for post-reorg compilation.
|
|
+ *
|
|
+ * Revision 1.14 2002/04/24 07:36:35 mcr
|
|
+ * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
|
|
+ *
|
|
+ * Revision 1.13 2002/01/12 02:58:32 mcr
|
|
+ * first regression test causes acquire messages to be lost
|
|
+ * 100% of the time. This is to help testing of pluto.
|
|
+ *
|
|
+ * Revision 1.12 2001/06/14 19:35:13 rgb
|
|
+ * Update copyright date.
|
|
+ *
|
|
+ * Revision 1.11 2001/02/26 19:58:13 rgb
|
|
+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
|
|
+ *
|
|
+ * Revision 1.10 2000/09/16 01:50:15 rgb
|
|
+ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
|
|
+ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
|
|
+ *
|
|
+ * Revision 1.9 2000/09/15 23:17:51 rgb
|
|
+ * Moved stuff around to compile with debug off.
|
|
+ *
|
|
+ * Revision 1.8 2000/09/15 11:37:02 rgb
|
|
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
|
|
+ * IPCOMP zlib deflate code.
|
|
+ *
|
|
+ * Revision 1.7 2000/09/15 07:37:15 rgb
|
|
+ * Munged silly log comment that was causing a warning.
|
|
+ *
|
|
+ * Revision 1.6 2000/09/15 04:58:23 rgb
|
|
+ * Added tos runtime switch.
|
|
+ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
|
|
+ *
|
|
+ * Revision 1.5 2000/09/12 03:25:28 rgb
|
|
+ * Filled in and implemented sysctl.
|
|
+ *
|
|
+ * Revision 1.4 1999/04/11 00:29:03 henry
|
|
+ * GPL boilerplate
|
|
+ *
|
|
+ * Revision 1.3 1999/04/06 04:54:29 rgb
|
|
+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
|
|
+ * patch shell fixes.
|
|
+ *
|
|
+ */
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/trees.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,1214 @@
|
|
+/* trees.c -- output deflated data using Huffman coding
|
|
+ * Copyright (C) 1995-2002 Jean-loup Gailly
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * ALGORITHM
|
|
+ *
|
|
+ * The "deflation" process uses several Huffman trees. The more
|
|
+ * common source values are represented by shorter bit sequences.
|
|
+ *
|
|
+ * Each code tree is stored in a compressed form which is itself
|
|
+ * a Huffman encoding of the lengths of all the code strings (in
|
|
+ * ascending order by source values). The actual code strings are
|
|
+ * reconstructed from the lengths in the inflate process, as described
|
|
+ * in the deflate specification.
|
|
+ *
|
|
+ * REFERENCES
|
|
+ *
|
|
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
|
|
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
|
|
+ *
|
|
+ * Storer, James A.
|
|
+ * Data Compression: Methods and Theory, pp. 49-50.
|
|
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
|
|
+ *
|
|
+ * Sedgewick, R.
|
|
+ * Algorithms, p290.
|
|
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
|
|
+ */
|
|
+
|
|
+/* @(#) $Id: trees.c,v 1.4 2004/07/10 07:48:39 mcr Exp $ */
|
|
+
|
|
+/* #define GEN_TREES_H */
|
|
+
|
|
+#include "deflate.h"
|
|
+
|
|
+#ifdef DEBUG
|
|
+# include <ctype.h>
|
|
+#endif
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Constants
|
|
+ */
|
|
+
|
|
+#define MAX_BL_BITS 7
|
|
+/* Bit length codes must not exceed MAX_BL_BITS bits */
|
|
+
|
|
+#define END_BLOCK 256
|
|
+/* end of block literal code */
|
|
+
|
|
+#define REP_3_6 16
|
|
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
|
|
+
|
|
+#define REPZ_3_10 17
|
|
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
|
|
+
|
|
+#define REPZ_11_138 18
|
|
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
|
|
+
|
|
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
|
|
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
|
|
+
|
|
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
|
|
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
|
|
+
|
|
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
|
|
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
|
|
+
|
|
+local const uch bl_order[BL_CODES]
|
|
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
|
|
+/* The lengths of the bit length codes are sent in order of decreasing
|
|
+ * probability, to avoid transmitting the lengths for unused bit length codes.
|
|
+ */
|
|
+
|
|
+#define Buf_size (8 * 2*sizeof(char))
|
|
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
|
|
+ * more than 16 bits on some systems.)
|
|
+ */
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Local data. These are initialized only once.
|
|
+ */
|
|
+
|
|
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
|
|
+
|
|
+#if defined(GEN_TREES_H) || !defined(STDC)
|
|
+/* non ANSI compilers may not accept trees.h */
|
|
+
|
|
+local ct_data static_ltree[L_CODES+2];
|
|
+/* The static literal tree. Since the bit lengths are imposed, there is no
|
|
+ * need for the L_CODES extra codes used during heap construction. However
|
|
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
|
|
+ * below).
|
|
+ */
|
|
+
|
|
+local ct_data static_dtree[D_CODES];
|
|
+/* The static distance tree. (Actually a trivial tree since all codes use
|
|
+ * 5 bits.)
|
|
+ */
|
|
+
|
|
+uch _dist_code[DIST_CODE_LEN];
|
|
+/* Distance codes. The first 256 values correspond to the distances
|
|
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
|
|
+ * the 15 bit distances.
|
|
+ */
|
|
+
|
|
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
|
|
+/* length code for each normalized match length (0 == MIN_MATCH) */
|
|
+
|
|
+local int base_length[LENGTH_CODES];
|
|
+/* First normalized length for each code (0 = MIN_MATCH) */
|
|
+
|
|
+local int base_dist[D_CODES];
|
|
+/* First normalized distance for each code (0 = distance of 1) */
|
|
+
|
|
+#else
|
|
+# include "trees.h"
|
|
+#endif /* GEN_TREES_H */
|
|
+
|
|
+struct static_tree_desc_s {
|
|
+ const ct_data *static_tree; /* static tree or NULL */
|
|
+ const intf *extra_bits; /* extra bits for each code or NULL */
|
|
+ int extra_base; /* base index for extra_bits */
|
|
+ int elems; /* max number of elements in the tree */
|
|
+ int max_length; /* max bit length for the codes */
|
|
+};
|
|
+
|
|
+local static_tree_desc static_l_desc =
|
|
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
|
|
+
|
|
+local static_tree_desc static_d_desc =
|
|
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
|
|
+
|
|
+local static_tree_desc static_bl_desc =
|
|
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Local (static) routines in this file.
|
|
+ */
|
|
+
|
|
+local void tr_static_init OF((void));
|
|
+local void init_block OF((deflate_state *s));
|
|
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
|
|
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
|
|
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
|
|
+local void build_tree OF((deflate_state *s, tree_desc *desc));
|
|
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
|
|
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
|
|
+local int build_bl_tree OF((deflate_state *s));
|
|
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
|
|
+ int blcodes));
|
|
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
|
|
+ const ct_data *dtree));
|
|
+local void set_data_type OF((deflate_state *s));
|
|
+local unsigned bi_reverse OF((unsigned value, int length));
|
|
+local void bi_windup OF((deflate_state *s));
|
|
+local void bi_flush OF((deflate_state *s));
|
|
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
|
|
+ int header));
|
|
+
|
|
+#ifdef GEN_TREES_H
|
|
+local void gen_trees_header OF((void));
|
|
+#endif
|
|
+
|
|
+#ifndef DEBUG
|
|
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
|
|
+ /* Send a code of the given tree. c and tree must not have side effects */
|
|
+
|
|
+#else /* DEBUG */
|
|
+# define send_code(s, c, tree) \
|
|
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
|
|
+ send_bits(s, tree[c].Code, tree[c].Len); }
|
|
+#endif
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Output a short LSB first on the stream.
|
|
+ * IN assertion: there is enough room in pendingBuf.
|
|
+ */
|
|
+#define put_short(s, w) { \
|
|
+ put_byte(s, (uch)((w) & 0xff)); \
|
|
+ put_byte(s, (uch)((ush)(w) >> 8)); \
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Send a value on a given number of bits.
|
|
+ * IN assertion: length <= 16 and value fits in length bits.
|
|
+ */
|
|
+#ifdef DEBUG
|
|
+local void send_bits OF((deflate_state *s, int value, int length));
|
|
+
|
|
+local void send_bits(s, value, length)
|
|
+ deflate_state *s;
|
|
+ int value; /* value to send */
|
|
+ int length; /* number of bits */
|
|
+{
|
|
+ Tracevv((stderr," l %2d v %4x ", length, value));
|
|
+ Assert(length > 0 && length <= 15, "invalid length");
|
|
+ s->bits_sent += (ulg)length;
|
|
+
|
|
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
|
|
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
|
|
+ * unused bits in value.
|
|
+ */
|
|
+ if (s->bi_valid > (int)Buf_size - length) {
|
|
+ s->bi_buf |= (value << s->bi_valid);
|
|
+ put_short(s, s->bi_buf);
|
|
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
|
|
+ s->bi_valid += length - Buf_size;
|
|
+ } else {
|
|
+ s->bi_buf |= value << s->bi_valid;
|
|
+ s->bi_valid += length;
|
|
+ }
|
|
+}
|
|
+#else /* !DEBUG */
|
|
+
|
|
+#define send_bits(s, value, length) \
|
|
+{ int len = length;\
|
|
+ if (s->bi_valid > (int)Buf_size - len) {\
|
|
+ int val = value;\
|
|
+ s->bi_buf |= (val << s->bi_valid);\
|
|
+ put_short(s, s->bi_buf);\
|
|
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
|
|
+ s->bi_valid += len - Buf_size;\
|
|
+ } else {\
|
|
+ s->bi_buf |= (value) << s->bi_valid;\
|
|
+ s->bi_valid += len;\
|
|
+ }\
|
|
+}
|
|
+#endif /* DEBUG */
|
|
+
|
|
+
|
|
+#define MAX(a,b) (a >= b ? a : b)
|
|
+/* the arguments must not have side effects */
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Initialize the various 'constant' tables.
|
|
+ */
|
|
+local void tr_static_init()
|
|
+{
|
|
+#if defined(GEN_TREES_H) || !defined(STDC)
|
|
+ static int static_init_done = 0;
|
|
+ int n; /* iterates over tree elements */
|
|
+ int bits; /* bit counter */
|
|
+ int length; /* length value */
|
|
+ int code; /* code value */
|
|
+ int dist; /* distance index */
|
|
+ ush bl_count[MAX_BITS+1];
|
|
+ /* number of codes at each bit length for an optimal tree */
|
|
+
|
|
+ if (static_init_done) return;
|
|
+
|
|
+ /* For some embedded targets, global variables are not initialized: */
|
|
+ static_l_desc.static_tree = static_ltree;
|
|
+ static_l_desc.extra_bits = extra_lbits;
|
|
+ static_d_desc.static_tree = static_dtree;
|
|
+ static_d_desc.extra_bits = extra_dbits;
|
|
+ static_bl_desc.extra_bits = extra_blbits;
|
|
+
|
|
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
|
|
+ length = 0;
|
|
+ for (code = 0; code < LENGTH_CODES-1; code++) {
|
|
+ base_length[code] = length;
|
|
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
|
|
+ _length_code[length++] = (uch)code;
|
|
+ }
|
|
+ }
|
|
+ Assert (length == 256, "tr_static_init: length != 256");
|
|
+ /* Note that the length 255 (match length 258) can be represented
|
|
+ * in two different ways: code 284 + 5 bits or code 285, so we
|
|
+ * overwrite length_code[255] to use the best encoding:
|
|
+ */
|
|
+ _length_code[length-1] = (uch)code;
|
|
+
|
|
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
|
|
+ dist = 0;
|
|
+ for (code = 0 ; code < 16; code++) {
|
|
+ base_dist[code] = dist;
|
|
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
|
|
+ _dist_code[dist++] = (uch)code;
|
|
+ }
|
|
+ }
|
|
+ Assert (dist == 256, "tr_static_init: dist != 256");
|
|
+ dist >>= 7; /* from now on, all distances are divided by 128 */
|
|
+ for ( ; code < D_CODES; code++) {
|
|
+ base_dist[code] = dist << 7;
|
|
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
|
|
+ _dist_code[256 + dist++] = (uch)code;
|
|
+ }
|
|
+ }
|
|
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
|
|
+
|
|
+ /* Construct the codes of the static literal tree */
|
|
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
|
|
+ n = 0;
|
|
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
|
|
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
|
|
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
|
|
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
|
|
+ /* Codes 286 and 287 do not exist, but we must include them in the
|
|
+ * tree construction to get a canonical Huffman tree (longest code
|
|
+ * all ones)
|
|
+ */
|
|
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
|
|
+
|
|
+ /* The static distance tree is trivial: */
|
|
+ for (n = 0; n < D_CODES; n++) {
|
|
+ static_dtree[n].Len = 5;
|
|
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
|
|
+ }
|
|
+ static_init_done = 1;
|
|
+
|
|
+# ifdef GEN_TREES_H
|
|
+ gen_trees_header();
|
|
+# endif
|
|
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Genererate the file trees.h describing the static trees.
|
|
+ */
|
|
+#ifdef GEN_TREES_H
|
|
+# ifndef DEBUG
|
|
+# include <stdio.h>
|
|
+# endif
|
|
+
|
|
+# define SEPARATOR(i, last, width) \
|
|
+ ((i) == (last)? "\n};\n\n" : \
|
|
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
|
|
+
|
|
+void gen_trees_header()
|
|
+{
|
|
+ FILE *header = fopen("trees.h", "w");
|
|
+ int i;
|
|
+
|
|
+ Assert (header != NULL, "Can't open trees.h");
|
|
+ fprintf(header,
|
|
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
|
|
+
|
|
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
|
|
+ for (i = 0; i < L_CODES+2; i++) {
|
|
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
|
|
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
|
|
+ }
|
|
+
|
|
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
|
|
+ for (i = 0; i < D_CODES; i++) {
|
|
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
|
|
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
|
|
+ }
|
|
+
|
|
+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
|
|
+ for (i = 0; i < DIST_CODE_LEN; i++) {
|
|
+ fprintf(header, "%2u%s", _dist_code[i],
|
|
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
|
|
+ }
|
|
+
|
|
+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
|
|
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
|
|
+ fprintf(header, "%2u%s", _length_code[i],
|
|
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
|
|
+ }
|
|
+
|
|
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
|
|
+ for (i = 0; i < LENGTH_CODES; i++) {
|
|
+ fprintf(header, "%1u%s", base_length[i],
|
|
+ SEPARATOR(i, LENGTH_CODES-1, 20));
|
|
+ }
|
|
+
|
|
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
|
|
+ for (i = 0; i < D_CODES; i++) {
|
|
+ fprintf(header, "%5u%s", base_dist[i],
|
|
+ SEPARATOR(i, D_CODES-1, 10));
|
|
+ }
|
|
+
|
|
+ fclose(header);
|
|
+}
|
|
+#endif /* GEN_TREES_H */
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Initialize the tree data structures for a new zlib stream.
|
|
+ */
|
|
+void _tr_init(s)
|
|
+ deflate_state *s;
|
|
+{
|
|
+ tr_static_init();
|
|
+
|
|
+ s->l_desc.dyn_tree = s->dyn_ltree;
|
|
+ s->l_desc.stat_desc = &static_l_desc;
|
|
+
|
|
+ s->d_desc.dyn_tree = s->dyn_dtree;
|
|
+ s->d_desc.stat_desc = &static_d_desc;
|
|
+
|
|
+ s->bl_desc.dyn_tree = s->bl_tree;
|
|
+ s->bl_desc.stat_desc = &static_bl_desc;
|
|
+
|
|
+ s->bi_buf = 0;
|
|
+ s->bi_valid = 0;
|
|
+ s->last_eob_len = 8; /* enough lookahead for inflate */
|
|
+#ifdef DEBUG
|
|
+ s->compressed_len = 0L;
|
|
+ s->bits_sent = 0L;
|
|
+#endif
|
|
+
|
|
+ /* Initialize the first block of the first file: */
|
|
+ init_block(s);
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Initialize a new block.
|
|
+ */
|
|
+local void init_block(s)
|
|
+ deflate_state *s;
|
|
+{
|
|
+ int n; /* iterates over tree elements */
|
|
+
|
|
+ /* Initialize the trees. */
|
|
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
|
|
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
|
|
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
|
|
+
|
|
+ s->dyn_ltree[END_BLOCK].Freq = 1;
|
|
+ s->opt_len = s->static_len = 0L;
|
|
+ s->last_lit = s->matches = 0;
|
|
+}
|
|
+
|
|
+#define SMALLEST 1
|
|
+/* Index within the heap array of least frequent node in the Huffman tree */
|
|
+
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Remove the smallest element from the heap and recreate the heap with
|
|
+ * one less element. Updates heap and heap_len.
|
|
+ */
|
|
+#define pqremove(s, tree, top) \
|
|
+{\
|
|
+ top = s->heap[SMALLEST]; \
|
|
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
|
|
+ pqdownheap(s, tree, SMALLEST); \
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Compares to subtrees, using the tree depth as tie breaker when
|
|
+ * the subtrees have equal frequency. This minimizes the worst case length.
|
|
+ */
|
|
+#define smaller(tree, n, m, depth) \
|
|
+ (tree[n].Freq < tree[m].Freq || \
|
|
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Restore the heap property by moving down the tree starting at node k,
|
|
+ * exchanging a node with the smallest of its two sons if necessary, stopping
|
|
+ * when the heap property is re-established (each father smaller than its
|
|
+ * two sons).
|
|
+ */
|
|
+local void pqdownheap(s, tree, k)
|
|
+ deflate_state *s;
|
|
+ ct_data *tree; /* the tree to restore */
|
|
+ int k; /* node to move down */
|
|
+{
|
|
+ int v = s->heap[k];
|
|
+ int j = k << 1; /* left son of k */
|
|
+ while (j <= s->heap_len) {
|
|
+ /* Set j to the smallest of the two sons: */
|
|
+ if (j < s->heap_len &&
|
|
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
|
|
+ j++;
|
|
+ }
|
|
+ /* Exit if v is smaller than both sons */
|
|
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
|
|
+
|
|
+ /* Exchange v with the smallest son */
|
|
+ s->heap[k] = s->heap[j]; k = j;
|
|
+
|
|
+ /* And continue down the tree, setting j to the left son of k */
|
|
+ j <<= 1;
|
|
+ }
|
|
+ s->heap[k] = v;
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Compute the optimal bit lengths for a tree and update the total bit length
|
|
+ * for the current block.
|
|
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
|
|
+ * above are the tree nodes sorted by increasing frequency.
|
|
+ * OUT assertions: the field len is set to the optimal bit length, the
|
|
+ * array bl_count contains the frequencies for each bit length.
|
|
+ * The length opt_len is updated; static_len is also updated if stree is
|
|
+ * not null.
|
|
+ */
|
|
+local void gen_bitlen(s, desc)
|
|
+ deflate_state *s;
|
|
+ tree_desc *desc; /* the tree descriptor */
|
|
+{
|
|
+ ct_data *tree = desc->dyn_tree;
|
|
+ int max_code = desc->max_code;
|
|
+ const ct_data *stree = desc->stat_desc->static_tree;
|
|
+ const intf *extra = desc->stat_desc->extra_bits;
|
|
+ int base = desc->stat_desc->extra_base;
|
|
+ int max_length = desc->stat_desc->max_length;
|
|
+ int h; /* heap index */
|
|
+ int n, m; /* iterate over the tree elements */
|
|
+ int bits; /* bit length */
|
|
+ int xbits; /* extra bits */
|
|
+ ush f; /* frequency */
|
|
+ int overflow = 0; /* number of elements with bit length too large */
|
|
+
|
|
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
|
|
+
|
|
+ /* In a first pass, compute the optimal bit lengths (which may
|
|
+ * overflow in the case of the bit length tree).
|
|
+ */
|
|
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
|
|
+
|
|
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
|
|
+ n = s->heap[h];
|
|
+ bits = tree[tree[n].Dad].Len + 1;
|
|
+ if (bits > max_length) bits = max_length, overflow++;
|
|
+ tree[n].Len = (ush)bits;
|
|
+ /* We overwrite tree[n].Dad which is no longer needed */
|
|
+
|
|
+ if (n > max_code) continue; /* not a leaf node */
|
|
+
|
|
+ s->bl_count[bits]++;
|
|
+ xbits = 0;
|
|
+ if (n >= base) xbits = extra[n-base];
|
|
+ f = tree[n].Freq;
|
|
+ s->opt_len += (ulg)f * (bits + xbits);
|
|
+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
|
|
+ }
|
|
+ if (overflow == 0) return;
|
|
+
|
|
+ Trace((stderr,"\nbit length overflow\n"));
|
|
+ /* This happens for example on obj2 and pic of the Calgary corpus */
|
|
+
|
|
+ /* Find the first bit length which could increase: */
|
|
+ do {
|
|
+ bits = max_length-1;
|
|
+ while (s->bl_count[bits] == 0) bits--;
|
|
+ s->bl_count[bits]--; /* move one leaf down the tree */
|
|
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
|
|
+ s->bl_count[max_length]--;
|
|
+ /* The brother of the overflow item also moves one step up,
|
|
+ * but this does not affect bl_count[max_length]
|
|
+ */
|
|
+ overflow -= 2;
|
|
+ } while (overflow > 0);
|
|
+
|
|
+ /* Now recompute all bit lengths, scanning in increasing frequency.
|
|
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
|
|
+ * lengths instead of fixing only the wrong ones. This idea is taken
|
|
+ * from 'ar' written by Haruhiko Okumura.)
|
|
+ */
|
|
+ for (bits = max_length; bits != 0; bits--) {
|
|
+ n = s->bl_count[bits];
|
|
+ while (n != 0) {
|
|
+ m = s->heap[--h];
|
|
+ if (m > max_code) continue;
|
|
+ if (tree[m].Len != (unsigned) bits) {
|
|
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
|
|
+ s->opt_len += ((long)bits - (long)tree[m].Len)
|
|
+ *(long)tree[m].Freq;
|
|
+ tree[m].Len = (ush)bits;
|
|
+ }
|
|
+ n--;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Generate the codes for a given tree and bit counts (which need not be
|
|
+ * optimal).
|
|
+ * IN assertion: the array bl_count contains the bit length statistics for
|
|
+ * the given tree and the field len is set for all tree elements.
|
|
+ * OUT assertion: the field code is set for all tree elements of non
|
|
+ * zero code length.
|
|
+ */
|
|
+local void gen_codes (tree, max_code, bl_count)
|
|
+ ct_data *tree; /* the tree to decorate */
|
|
+ int max_code; /* largest code with non zero frequency */
|
|
+ ushf *bl_count; /* number of codes at each bit length */
|
|
+{
|
|
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
|
|
+ ush code = 0; /* running code value */
|
|
+ int bits; /* bit index */
|
|
+ int n; /* code index */
|
|
+
|
|
+ /* The distribution counts are first used to generate the code values
|
|
+ * without bit reversal.
|
|
+ */
|
|
+ for (bits = 1; bits <= MAX_BITS; bits++) {
|
|
+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
|
|
+ }
|
|
+ /* Check that the bit counts in bl_count are consistent. The last code
|
|
+ * must be all ones.
|
|
+ */
|
|
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
|
|
+ "inconsistent bit counts");
|
|
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
|
|
+
|
|
+ for (n = 0; n <= max_code; n++) {
|
|
+ int len = tree[n].Len;
|
|
+ if (len == 0) continue;
|
|
+ /* Now reverse the bits */
|
|
+ tree[n].Code = bi_reverse(next_code[len]++, len);
|
|
+
|
|
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
|
|
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
|
|
+ }
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
|
|
+ * Update the total bit length for the current block.
|
|
+ * IN assertion: the field freq is set for all tree elements.
|
|
+ * OUT assertions: the fields len and code are set to the optimal bit length
|
|
+ * and corresponding code. The length opt_len is updated; static_len is
|
|
+ * also updated if stree is not null. The field max_code is set.
|
|
+ */
|
|
+local void build_tree(s, desc)
|
|
+ deflate_state *s;
|
|
+ tree_desc *desc; /* the tree descriptor */
|
|
+{
|
|
+ ct_data *tree = desc->dyn_tree;
|
|
+ const ct_data *stree = desc->stat_desc->static_tree;
|
|
+ int elems = desc->stat_desc->elems;
|
|
+ int n, m; /* iterate over heap elements */
|
|
+ int max_code = -1; /* largest code with non zero frequency */
|
|
+ int node; /* new node being created */
|
|
+
|
|
+ /* Construct the initial heap, with least frequent element in
|
|
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
|
|
+ * heap[0] is not used.
|
|
+ */
|
|
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
|
|
+
|
|
+ for (n = 0; n < elems; n++) {
|
|
+ if (tree[n].Freq != 0) {
|
|
+ s->heap[++(s->heap_len)] = max_code = n;
|
|
+ s->depth[n] = 0;
|
|
+ } else {
|
|
+ tree[n].Len = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* The pkzip format requires that at least one distance code exists,
|
|
+ * and that at least one bit should be sent even if there is only one
|
|
+ * possible code. So to avoid special checks later on we force at least
|
|
+ * two codes of non zero frequency.
|
|
+ */
|
|
+ while (s->heap_len < 2) {
|
|
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
|
|
+ tree[node].Freq = 1;
|
|
+ s->depth[node] = 0;
|
|
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
|
|
+ /* node is 0 or 1 so it does not have extra bits */
|
|
+ }
|
|
+ desc->max_code = max_code;
|
|
+
|
|
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
|
|
+ * establish sub-heaps of increasing lengths:
|
|
+ */
|
|
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
|
|
+
|
|
+ /* Construct the Huffman tree by repeatedly combining the least two
|
|
+ * frequent nodes.
|
|
+ */
|
|
+ node = elems; /* next internal node of the tree */
|
|
+ do {
|
|
+ pqremove(s, tree, n); /* n = node of least frequency */
|
|
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
|
|
+
|
|
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
|
|
+ s->heap[--(s->heap_max)] = m;
|
|
+
|
|
+ /* Create a new node father of n and m */
|
|
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
|
|
+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
|
|
+ tree[n].Dad = tree[m].Dad = (ush)node;
|
|
+#ifdef DUMP_BL_TREE
|
|
+ if (tree == s->bl_tree) {
|
|
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
|
|
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
|
|
+ }
|
|
+#endif
|
|
+ /* and insert the new node in the heap */
|
|
+ s->heap[SMALLEST] = node++;
|
|
+ pqdownheap(s, tree, SMALLEST);
|
|
+
|
|
+ } while (s->heap_len >= 2);
|
|
+
|
|
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
|
|
+
|
|
+ /* At this point, the fields freq and dad are set. We can now
|
|
+ * generate the bit lengths.
|
|
+ */
|
|
+ gen_bitlen(s, (tree_desc *)desc);
|
|
+
|
|
+ /* The field len is now set, we can generate the bit codes */
|
|
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Scan a literal or distance tree to determine the frequencies of the codes
|
|
+ * in the bit length tree.
|
|
+ */
|
|
+local void scan_tree (s, tree, max_code)
|
|
+ deflate_state *s;
|
|
+ ct_data *tree; /* the tree to be scanned */
|
|
+ int max_code; /* and its largest code of non zero frequency */
|
|
+{
|
|
+ int n; /* iterates over all tree elements */
|
|
+ int prevlen = -1; /* last emitted length */
|
|
+ int curlen; /* length of current code */
|
|
+ int nextlen = tree[0].Len; /* length of next code */
|
|
+ int count = 0; /* repeat count of the current code */
|
|
+ int max_count = 7; /* max repeat count */
|
|
+ int min_count = 4; /* min repeat count */
|
|
+
|
|
+ if (nextlen == 0) max_count = 138, min_count = 3;
|
|
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
|
|
+
|
|
+ for (n = 0; n <= max_code; n++) {
|
|
+ curlen = nextlen; nextlen = tree[n+1].Len;
|
|
+ if (++count < max_count && curlen == nextlen) {
|
|
+ continue;
|
|
+ } else if (count < min_count) {
|
|
+ s->bl_tree[curlen].Freq += count;
|
|
+ } else if (curlen != 0) {
|
|
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
|
|
+ s->bl_tree[REP_3_6].Freq++;
|
|
+ } else if (count <= 10) {
|
|
+ s->bl_tree[REPZ_3_10].Freq++;
|
|
+ } else {
|
|
+ s->bl_tree[REPZ_11_138].Freq++;
|
|
+ }
|
|
+ count = 0; prevlen = curlen;
|
|
+ if (nextlen == 0) {
|
|
+ max_count = 138, min_count = 3;
|
|
+ } else if (curlen == nextlen) {
|
|
+ max_count = 6, min_count = 3;
|
|
+ } else {
|
|
+ max_count = 7, min_count = 4;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Send a literal or distance tree in compressed form, using the codes in
|
|
+ * bl_tree.
|
|
+ */
|
|
+local void send_tree (s, tree, max_code)
|
|
+ deflate_state *s;
|
|
+ ct_data *tree; /* the tree to be scanned */
|
|
+ int max_code; /* and its largest code of non zero frequency */
|
|
+{
|
|
+ int n; /* iterates over all tree elements */
|
|
+ int prevlen = -1; /* last emitted length */
|
|
+ int curlen; /* length of current code */
|
|
+ int nextlen = tree[0].Len; /* length of next code */
|
|
+ int count = 0; /* repeat count of the current code */
|
|
+ int max_count = 7; /* max repeat count */
|
|
+ int min_count = 4; /* min repeat count */
|
|
+
|
|
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
|
|
+ if (nextlen == 0) max_count = 138, min_count = 3;
|
|
+
|
|
+ for (n = 0; n <= max_code; n++) {
|
|
+ curlen = nextlen; nextlen = tree[n+1].Len;
|
|
+ if (++count < max_count && curlen == nextlen) {
|
|
+ continue;
|
|
+ } else if (count < min_count) {
|
|
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
|
|
+
|
|
+ } else if (curlen != 0) {
|
|
+ if (curlen != prevlen) {
|
|
+ send_code(s, curlen, s->bl_tree); count--;
|
|
+ }
|
|
+ Assert(count >= 3 && count <= 6, " 3_6?");
|
|
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
|
|
+
|
|
+ } else if (count <= 10) {
|
|
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
|
|
+
|
|
+ } else {
|
|
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
|
|
+ }
|
|
+ count = 0; prevlen = curlen;
|
|
+ if (nextlen == 0) {
|
|
+ max_count = 138, min_count = 3;
|
|
+ } else if (curlen == nextlen) {
|
|
+ max_count = 6, min_count = 3;
|
|
+ } else {
|
|
+ max_count = 7, min_count = 4;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Construct the Huffman tree for the bit lengths and return the index in
|
|
+ * bl_order of the last bit length code to send.
|
|
+ */
|
|
+local int build_bl_tree(s)
|
|
+ deflate_state *s;
|
|
+{
|
|
+ int max_blindex; /* index of last bit length code of non zero freq */
|
|
+
|
|
+ /* Determine the bit length frequencies for literal and distance trees */
|
|
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
|
|
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
|
|
+
|
|
+ /* Build the bit length tree: */
|
|
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
|
|
+ /* opt_len now includes the length of the tree representations, except
|
|
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
|
|
+ */
|
|
+
|
|
+ /* Determine the number of bit length codes to send. The pkzip format
|
|
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
|
|
+ * 3 but the actual value used is 4.)
|
|
+ */
|
|
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
|
|
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
|
|
+ }
|
|
+ /* Update opt_len to include the bit length tree and counts */
|
|
+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
|
|
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
|
|
+ s->opt_len, s->static_len));
|
|
+
|
|
+ return max_blindex;
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Send the header for a block using dynamic Huffman trees: the counts, the
|
|
+ * lengths of the bit length codes, the literal tree and the distance tree.
|
|
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
|
|
+ */
|
|
+local void send_all_trees(s, lcodes, dcodes, blcodes)
|
|
+ deflate_state *s;
|
|
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
|
|
+{
|
|
+ int rank; /* index in bl_order */
|
|
+
|
|
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
|
|
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
|
|
+ "too many codes");
|
|
+ Tracev((stderr, "\nbl counts: "));
|
|
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
|
|
+ send_bits(s, dcodes-1, 5);
|
|
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
|
|
+ for (rank = 0; rank < blcodes; rank++) {
|
|
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
|
|
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
|
|
+ }
|
|
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
|
|
+
|
|
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
|
|
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
|
|
+
|
|
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
|
|
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Send a stored block
|
|
+ */
|
|
+void _tr_stored_block(s, buf, stored_len, eof)
|
|
+ deflate_state *s;
|
|
+ charf *buf; /* input block */
|
|
+ ulg stored_len; /* length of input block */
|
|
+ int eof; /* true if this is the last block for a file */
|
|
+{
|
|
+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
|
|
+#ifdef DEBUG
|
|
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
|
|
+ s->compressed_len += (stored_len + 4) << 3;
|
|
+#endif
|
|
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Send one empty static block to give enough lookahead for inflate.
|
|
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
|
|
+ * The current inflate code requires 9 bits of lookahead. If the
|
|
+ * last two codes for the previous block (real code plus EOB) were coded
|
|
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
|
|
+ * the last real code. In this case we send two empty static blocks instead
|
|
+ * of one. (There are no problems if the previous block is stored or fixed.)
|
|
+ * To simplify the code, we assume the worst case of last real code encoded
|
|
+ * on one bit only.
|
|
+ */
|
|
+void _tr_align(s)
|
|
+ deflate_state *s;
|
|
+{
|
|
+ send_bits(s, STATIC_TREES<<1, 3);
|
|
+ send_code(s, END_BLOCK, static_ltree);
|
|
+#ifdef DEBUG
|
|
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
|
|
+#endif
|
|
+ bi_flush(s);
|
|
+ /* Of the 10 bits for the empty block, we have already sent
|
|
+ * (10 - bi_valid) bits. The lookahead for the last real code (before
|
|
+ * the EOB of the previous block) was thus at least one plus the length
|
|
+ * of the EOB plus what we have just sent of the empty static block.
|
|
+ */
|
|
+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
|
|
+ send_bits(s, STATIC_TREES<<1, 3);
|
|
+ send_code(s, END_BLOCK, static_ltree);
|
|
+#ifdef DEBUG
|
|
+ s->compressed_len += 10L;
|
|
+#endif
|
|
+ bi_flush(s);
|
|
+ }
|
|
+ s->last_eob_len = 7;
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Determine the best encoding for the current block: dynamic trees, static
|
|
+ * trees or store, and output the encoded block to the zip file.
|
|
+ */
|
|
+void _tr_flush_block(s, buf, stored_len, eof)
|
|
+ deflate_state *s;
|
|
+ charf *buf; /* input block, or NULL if too old */
|
|
+ ulg stored_len; /* length of input block */
|
|
+ int eof; /* true if this is the last block for a file */
|
|
+{
|
|
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
|
|
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
|
|
+
|
|
+ /* Build the Huffman trees unless a stored block is forced */
|
|
+ if (s->level > 0) {
|
|
+
|
|
+ /* Check if the file is ascii or binary */
|
|
+ if (s->data_type == Z_UNKNOWN) set_data_type(s);
|
|
+
|
|
+ /* Construct the literal and distance trees */
|
|
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
|
|
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
|
|
+ s->static_len));
|
|
+
|
|
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
|
|
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
|
|
+ s->static_len));
|
|
+ /* At this point, opt_len and static_len are the total bit lengths of
|
|
+ * the compressed block data, excluding the tree representations.
|
|
+ */
|
|
+
|
|
+ /* Build the bit length tree for the above two trees, and get the index
|
|
+ * in bl_order of the last bit length code to send.
|
|
+ */
|
|
+ max_blindex = build_bl_tree(s);
|
|
+
|
|
+ /* Determine the best encoding. Compute first the block length in bytes*/
|
|
+ opt_lenb = (s->opt_len+3+7)>>3;
|
|
+ static_lenb = (s->static_len+3+7)>>3;
|
|
+
|
|
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
|
|
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
|
|
+ s->last_lit));
|
|
+
|
|
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
|
|
+
|
|
+ } else {
|
|
+ Assert(buf != (char*)0, "lost buf");
|
|
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
|
|
+ }
|
|
+
|
|
+#ifdef FORCE_STORED
|
|
+ if (buf != (char*)0) { /* force stored block */
|
|
+#else
|
|
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
|
|
+ /* 4: two words for the lengths */
|
|
+#endif
|
|
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
|
|
+ * Otherwise we can't have processed more than WSIZE input bytes since
|
|
+ * the last block flush, because compression would have been
|
|
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
|
|
+ * transform a block into a stored block.
|
|
+ */
|
|
+ _tr_stored_block(s, buf, stored_len, eof);
|
|
+
|
|
+#ifdef FORCE_STATIC
|
|
+ } else if (static_lenb >= 0) { /* force static trees */
|
|
+#else
|
|
+ } else if (static_lenb == opt_lenb) {
|
|
+#endif
|
|
+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
|
|
+ compress_block(s, static_ltree, static_dtree);
|
|
+#ifdef DEBUG
|
|
+ s->compressed_len += 3 + s->static_len;
|
|
+#endif
|
|
+ } else {
|
|
+ send_bits(s, (DYN_TREES<<1)+eof, 3);
|
|
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
|
|
+ max_blindex+1);
|
|
+ compress_block(s, s->dyn_ltree, s->dyn_dtree);
|
|
+#ifdef DEBUG
|
|
+ s->compressed_len += 3 + s->opt_len;
|
|
+#endif
|
|
+ }
|
|
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
|
|
+ /* The above check is made mod 2^32, for files larger than 512 MB
|
|
+ * and uLong implemented on 32 bits.
|
|
+ */
|
|
+ init_block(s);
|
|
+
|
|
+ if (eof) {
|
|
+ bi_windup(s);
|
|
+#ifdef DEBUG
|
|
+ s->compressed_len += 7; /* align on byte boundary */
|
|
+#endif
|
|
+ }
|
|
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
|
|
+ s->compressed_len-7*eof));
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Save the match info and tally the frequency counts. Return true if
|
|
+ * the current block must be flushed.
|
|
+ */
|
|
+int _tr_tally (s, dist, lc)
|
|
+ deflate_state *s;
|
|
+ unsigned dist; /* distance of matched string */
|
|
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
|
+{
|
|
+ s->d_buf[s->last_lit] = (ush)dist;
|
|
+ s->l_buf[s->last_lit++] = (uch)lc;
|
|
+ if (dist == 0) {
|
|
+ /* lc is the unmatched char */
|
|
+ s->dyn_ltree[lc].Freq++;
|
|
+ } else {
|
|
+ s->matches++;
|
|
+ /* Here, lc is the match length - MIN_MATCH */
|
|
+ dist--; /* dist = match distance - 1 */
|
|
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
|
|
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
|
|
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
|
|
+
|
|
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
|
|
+ s->dyn_dtree[d_code(dist)].Freq++;
|
|
+ }
|
|
+
|
|
+#ifdef TRUNCATE_BLOCK
|
|
+ /* Try to guess if it is profitable to stop the current block here */
|
|
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
|
|
+ /* Compute an upper bound for the compressed length */
|
|
+ ulg out_length = (ulg)s->last_lit*8L;
|
|
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
|
|
+ int dcode;
|
|
+ for (dcode = 0; dcode < D_CODES; dcode++) {
|
|
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
|
|
+ (5L+extra_dbits[dcode]);
|
|
+ }
|
|
+ out_length >>= 3;
|
|
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
|
|
+ s->last_lit, in_length, out_length,
|
|
+ 100L - out_length*100L/in_length));
|
|
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
|
|
+ }
|
|
+#endif
|
|
+ return (s->last_lit == s->lit_bufsize-1);
|
|
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
|
|
+ * on 16 bit machines and because stored blocks are restricted to
|
|
+ * 64K-1 bytes.
|
|
+ */
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Send the block data compressed using the given Huffman trees
|
|
+ */
|
|
+local void compress_block(s, ltree, dtree)
|
|
+ deflate_state *s;
|
|
+ const ct_data *ltree; /* literal tree */
|
|
+ const ct_data *dtree; /* distance tree */
|
|
+{
|
|
+ unsigned dist; /* distance of matched string */
|
|
+ int lc; /* match length or unmatched char (if dist == 0) */
|
|
+ unsigned lx = 0; /* running index in l_buf */
|
|
+ unsigned code; /* the code to send */
|
|
+ int extra; /* number of extra bits to send */
|
|
+
|
|
+ if (s->last_lit != 0) do {
|
|
+ dist = s->d_buf[lx];
|
|
+ lc = s->l_buf[lx++];
|
|
+ if (dist == 0) {
|
|
+ send_code(s, lc, ltree); /* send a literal byte */
|
|
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
|
|
+ } else {
|
|
+ /* Here, lc is the match length - MIN_MATCH */
|
|
+ code = _length_code[lc];
|
|
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
|
|
+ extra = extra_lbits[code];
|
|
+ if (extra != 0) {
|
|
+ lc -= base_length[code];
|
|
+ send_bits(s, lc, extra); /* send the extra length bits */
|
|
+ }
|
|
+ dist--; /* dist is now the match distance - 1 */
|
|
+ code = d_code(dist);
|
|
+ Assert (code < D_CODES, "bad d_code");
|
|
+
|
|
+ send_code(s, code, dtree); /* send the distance code */
|
|
+ extra = extra_dbits[code];
|
|
+ if (extra != 0) {
|
|
+ dist -= base_dist[code];
|
|
+ send_bits(s, dist, extra); /* send the extra distance bits */
|
|
+ }
|
|
+ } /* literal or match pair ? */
|
|
+
|
|
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
|
|
+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
|
|
+
|
|
+ } while (lx < s->last_lit);
|
|
+
|
|
+ send_code(s, END_BLOCK, ltree);
|
|
+ s->last_eob_len = ltree[END_BLOCK].Len;
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Set the data type to ASCII or BINARY, using a crude approximation:
|
|
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
|
|
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
|
|
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
|
|
+ */
|
|
+local void set_data_type(s)
|
|
+ deflate_state *s;
|
|
+{
|
|
+ int n = 0;
|
|
+ unsigned ascii_freq = 0;
|
|
+ unsigned bin_freq = 0;
|
|
+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
|
|
+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
|
|
+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
|
|
+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Reverse the first len bits of a code, using straightforward code (a faster
|
|
+ * method would use a table)
|
|
+ * IN assertion: 1 <= len <= 15
|
|
+ */
|
|
+local unsigned bi_reverse(code, len)
|
|
+ unsigned code; /* the value to invert */
|
|
+ int len; /* its bit length */
|
|
+{
|
|
+ register unsigned res = 0;
|
|
+ do {
|
|
+ res |= code & 1;
|
|
+ code >>= 1, res <<= 1;
|
|
+ } while (--len > 0);
|
|
+ return res >> 1;
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Flush the bit buffer, keeping at most 7 bits in it.
|
|
+ */
|
|
+local void bi_flush(s)
|
|
+ deflate_state *s;
|
|
+{
|
|
+ if (s->bi_valid == 16) {
|
|
+ put_short(s, s->bi_buf);
|
|
+ s->bi_buf = 0;
|
|
+ s->bi_valid = 0;
|
|
+ } else if (s->bi_valid >= 8) {
|
|
+ put_byte(s, (Byte)s->bi_buf);
|
|
+ s->bi_buf >>= 8;
|
|
+ s->bi_valid -= 8;
|
|
+ }
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Flush the bit buffer and align the output on a byte boundary
|
|
+ */
|
|
+local void bi_windup(s)
|
|
+ deflate_state *s;
|
|
+{
|
|
+ if (s->bi_valid > 8) {
|
|
+ put_short(s, s->bi_buf);
|
|
+ } else if (s->bi_valid > 0) {
|
|
+ put_byte(s, (Byte)s->bi_buf);
|
|
+ }
|
|
+ s->bi_buf = 0;
|
|
+ s->bi_valid = 0;
|
|
+#ifdef DEBUG
|
|
+ s->bits_sent = (s->bits_sent+7) & ~7;
|
|
+#endif
|
|
+}
|
|
+
|
|
+/* ===========================================================================
|
|
+ * Copy a stored block, storing first the length and its
|
|
+ * one's complement if requested.
|
|
+ */
|
|
+local void copy_block(s, buf, len, header)
|
|
+ deflate_state *s;
|
|
+ charf *buf; /* the input data */
|
|
+ unsigned len; /* its length */
|
|
+ int header; /* true if block header must be written */
|
|
+{
|
|
+ bi_windup(s); /* align on byte boundary */
|
|
+ s->last_eob_len = 8; /* enough lookahead for inflate */
|
|
+
|
|
+ if (header) {
|
|
+ put_short(s, (ush)len);
|
|
+ put_short(s, (ush)~len);
|
|
+#ifdef DEBUG
|
|
+ s->bits_sent += 2*16;
|
|
+#endif
|
|
+ }
|
|
+#ifdef DEBUG
|
|
+ s->bits_sent += (ulg)len<<3;
|
|
+#endif
|
|
+ while (len--) {
|
|
+ put_byte(s, *buf++);
|
|
+ }
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/trees.h Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,128 @@
|
|
+/* header created automatically with -DGEN_TREES_H */
|
|
+
|
|
+local const ct_data static_ltree[L_CODES+2] = {
|
|
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
|
|
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
|
|
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
|
|
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
|
|
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
|
|
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
|
|
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
|
|
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
|
|
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
|
|
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
|
|
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
|
|
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
|
|
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
|
|
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
|
|
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
|
|
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
|
|
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
|
|
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
|
|
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
|
|
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
|
|
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
|
|
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
|
|
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
|
|
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
|
|
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
|
|
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
|
|
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
|
|
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
|
|
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
|
|
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
|
|
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
|
|
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
|
|
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
|
|
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
|
|
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
|
|
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
|
|
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
|
|
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
|
|
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
|
|
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
|
|
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
|
|
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
|
|
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
|
|
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
|
|
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
|
|
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
|
|
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
|
|
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
|
|
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
|
|
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
|
|
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
|
|
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
|
|
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
|
|
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
|
|
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
|
|
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
|
|
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
|
|
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
|
|
+};
|
|
+
|
|
+local const ct_data static_dtree[D_CODES] = {
|
|
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
|
|
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
|
|
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
|
|
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
|
|
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
|
|
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
|
|
+};
|
|
+
|
|
+const uch _dist_code[DIST_CODE_LEN] = {
|
|
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
|
|
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
|
|
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
|
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
|
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
|
|
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
|
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
|
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
|
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
|
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
|
|
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
|
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
|
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
|
|
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
|
|
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
|
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
|
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
|
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
|
|
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
|
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
|
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
|
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
|
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
|
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
|
|
+};
|
|
+
|
|
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
|
|
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
|
|
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
|
|
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
|
|
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
|
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
|
|
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
|
|
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
|
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
|
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
|
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
|
|
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
|
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
|
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
|
|
+};
|
|
+
|
|
+local const int base_length[LENGTH_CODES] = {
|
|
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
|
|
+64, 80, 96, 112, 128, 160, 192, 224, 0
|
|
+};
|
|
+
|
|
+local const int base_dist[D_CODES] = {
|
|
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
|
|
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
|
|
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
|
|
+};
|
|
+
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ultoa.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,66 @@
|
|
+/*
|
|
+ * convert unsigned long to ASCII
|
|
+ * Copyright (C) 1998, 1999 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: ultoa.c,v 1.10 2004/07/10 07:48:37 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+/*
|
|
+ - ultoa - convert unsigned long to decimal ASCII
|
|
+ */
|
|
+size_t /* length required for full conversion */
|
|
+ultoa(n, base, dst, dstlen)
|
|
+unsigned long n;
|
|
+int base;
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ char buf[3*sizeof(unsigned long) + 1];
|
|
+ char *bufend = buf + sizeof(buf);
|
|
+ size_t len;
|
|
+ char *p;
|
|
+ static char hex[] = "0123456789abcdef";
|
|
+
|
|
+ p = bufend;
|
|
+ *--p = '\0';
|
|
+ if (base == 10) {
|
|
+ do {
|
|
+ *--p = n%10 + '0';
|
|
+ n /= 10;
|
|
+ } while (n != 0);
|
|
+ } else if (base == 16) {
|
|
+ do {
|
|
+ *--p = hex[n&0xf];
|
|
+ n >>= 4;
|
|
+ } while (n != 0);
|
|
+ *--p = 'x';
|
|
+ *--p = '0';
|
|
+ } else if (base == 8) {
|
|
+ do {
|
|
+ *--p = (n&07) + '0';
|
|
+ n >>= 3;
|
|
+ } while (n != 0);
|
|
+ *--p = '0';
|
|
+ } else
|
|
+ *--p = '?';
|
|
+
|
|
+ len = bufend - p;
|
|
+
|
|
+ if (dstlen > 0) {
|
|
+ if (len > dstlen)
|
|
+ *(p + dstlen - 1) = '\0';
|
|
+ strcpy(dst, p);
|
|
+ }
|
|
+ return len;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/ultot.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,82 @@
|
|
+/*
|
|
+ * convert unsigned long to text
|
|
+ * Copyright (C) 2000 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: ultot.c,v 1.5 2004/07/10 07:48:37 mcr Exp $
|
|
+ */
|
|
+#include "openswan.h"
|
|
+
|
|
+/*
|
|
+ - ultot - convert unsigned long to text
|
|
+ */
|
|
+size_t /* length required for full conversion */
|
|
+ultot(n, base, dst, dstlen)
|
|
+unsigned long n;
|
|
+int base;
|
|
+char *dst; /* need not be valid if dstlen is 0 */
|
|
+size_t dstlen;
|
|
+{
|
|
+ char buf[3*sizeof(unsigned long) + 1];
|
|
+ char *bufend = buf + sizeof(buf);
|
|
+ size_t len;
|
|
+ char *p;
|
|
+ static char hex[] = "0123456789abcdef";
|
|
+# define HEX32 (32/4)
|
|
+
|
|
+ p = bufend;
|
|
+ *--p = '\0';
|
|
+ switch (base) {
|
|
+ case 10:
|
|
+ case 'd':
|
|
+ do {
|
|
+ *--p = n%10 + '0';
|
|
+ n /= 10;
|
|
+ } while (n != 0);
|
|
+ break;
|
|
+ case 16:
|
|
+ case 17:
|
|
+ case 'x':
|
|
+ do {
|
|
+ *--p = hex[n&0xf];
|
|
+ n >>= 4;
|
|
+ } while (n != 0);
|
|
+ if (base == 17)
|
|
+ while (bufend - p < HEX32 + 1)
|
|
+ *--p = '0';
|
|
+ if (base == 'x') {
|
|
+ *--p = 'x';
|
|
+ *--p = '0';
|
|
+ }
|
|
+ break;
|
|
+ case 8:
|
|
+ case 'o':
|
|
+ do {
|
|
+ *--p = (n&07) + '0';
|
|
+ n >>= 3;
|
|
+ } while (n != 0);
|
|
+ if (base == 'o')
|
|
+ *--p = '0';
|
|
+ break;
|
|
+ default:
|
|
+ return 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ len = bufend - p;
|
|
+ if (dstlen > 0) {
|
|
+ if (len > dstlen)
|
|
+ *(p + dstlen - 1) = '\0';
|
|
+ strcpy(dst, p);
|
|
+ }
|
|
+ return len;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,44 @@
|
|
+/*
|
|
+ * return IPsec version information
|
|
+ * Copyright (C) 2001 Henry Spencer.
|
|
+ *
|
|
+ * This library is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU Library General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or (at your
|
|
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
+ * License for more details.
|
|
+ *
|
|
+ * RCSID $Id: version.in.c,v 1.2 2004/04/14 05:09:46 ken Exp $
|
|
+ */
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+#include <linux/netdevice.h>
|
|
+#endif
|
|
+
|
|
+#include "openswan.h"
|
|
+
|
|
+#define V "2.4.9" /* substituted in by Makefile */
|
|
+static const char openswan_number[] = V;
|
|
+static const char openswan_string[] = "Openswan " V;
|
|
+
|
|
+/*
|
|
+ - ipsec_version_code - return IPsec version number/code, as string
|
|
+ */
|
|
+const char *
|
|
+ipsec_version_code()
|
|
+{
|
|
+ return openswan_number;
|
|
+}
|
|
+
|
|
+/*
|
|
+ - ipsec_version_string - return full version string
|
|
+ */
|
|
+const char *
|
|
+ipsec_version_string()
|
|
+{
|
|
+ return openswan_string;
|
|
+}
|
|
--- /dev/null Tue Mar 11 13:02:56 2003
|
|
+++ linux/net/ipsec/zutil.c Mon Feb 9 13:51:03 2004
|
|
@@ -0,0 +1,227 @@
|
|
+/* zutil.c -- target dependent utility functions for the compression library
|
|
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
|
|
+ * For conditions of distribution and use, see copyright notice in zlib.h
|
|
+ */
|
|
+
|
|
+/* @(#) $Id: zutil.c,v 1.5 2004/07/10 07:48:40 mcr Exp $ */
|
|
+
|
|
+#include <zlib/zutil.h>
|
|
+
|
|
+#define MY_ZCALLOC
|
|
+
|
|
+struct internal_state {int dummy;}; /* for buggy compilers */
|
|
+
|
|
+#ifndef STDC
|
|
+extern void exit OF((int));
|
|
+#endif
|
|
+
|
|
+const char *z_errmsg[10] = {
|
|
+"need dictionary", /* Z_NEED_DICT 2 */
|
|
+"stream end", /* Z_STREAM_END 1 */
|
|
+"", /* Z_OK 0 */
|
|
+"file error", /* Z_ERRNO (-1) */
|
|
+"stream error", /* Z_STREAM_ERROR (-2) */
|
|
+"data error", /* Z_DATA_ERROR (-3) */
|
|
+"insufficient memory", /* Z_MEM_ERROR (-4) */
|
|
+"buffer error", /* Z_BUF_ERROR (-5) */
|
|
+"incompatible version",/* Z_VERSION_ERROR (-6) */
|
|
+""};
|
|
+
|
|
+
|
|
+const char * ZEXPORT zlibVersion()
|
|
+{
|
|
+ return ZLIB_VERSION;
|
|
+}
|
|
+
|
|
+#ifdef DEBUG
|
|
+
|
|
+# ifndef verbose
|
|
+# define verbose 0
|
|
+# endif
|
|
+int z_verbose = verbose;
|
|
+
|
|
+void z_error (m)
|
|
+ char *m;
|
|
+{
|
|
+ fprintf(stderr, "%s\n", m);
|
|
+ exit(1);
|
|
+}
|
|
+#endif
|
|
+
|
|
+/* exported to allow conversion of error code to string for compress() and
|
|
+ * uncompress()
|
|
+ */
|
|
+const char * ZEXPORT zError(err)
|
|
+ int err;
|
|
+{
|
|
+ return ERR_MSG(err);
|
|
+}
|
|
+
|
|
+
|
|
+#ifndef HAVE_MEMCPY
|
|
+
|
|
+void zmemcpy(dest, source, len)
|
|
+ Bytef* dest;
|
|
+ const Bytef* source;
|
|
+ uInt len;
|
|
+{
|
|
+ if (len == 0) return;
|
|
+ do {
|
|
+ *dest++ = *source++; /* ??? to be unrolled */
|
|
+ } while (--len != 0);
|
|
+}
|
|
+
|
|
+int zmemcmp(s1, s2, len)
|
|
+ const Bytef* s1;
|
|
+ const Bytef* s2;
|
|
+ uInt len;
|
|
+{
|
|
+ uInt j;
|
|
+
|
|
+ for (j = 0; j < len; j++) {
|
|
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void zmemzero(dest, len)
|
|
+ Bytef* dest;
|
|
+ uInt len;
|
|
+{
|
|
+ if (len == 0) return;
|
|
+ do {
|
|
+ *dest++ = 0; /* ??? to be unrolled */
|
|
+ } while (--len != 0);
|
|
+}
|
|
+#endif
|
|
+
|
|
+#ifdef __TURBOC__
|
|
+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
|
|
+/* Small and medium model in Turbo C are for now limited to near allocation
|
|
+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
|
|
+ */
|
|
+# define MY_ZCALLOC
|
|
+
|
|
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
|
|
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
|
|
+ * must fix the pointer. Warning: the pointer must be put back to its
|
|
+ * original form in order to free it, use zcfree().
|
|
+ */
|
|
+
|
|
+#define MAX_PTR 10
|
|
+/* 10*64K = 640K */
|
|
+
|
|
+local int next_ptr = 0;
|
|
+
|
|
+typedef struct ptr_table_s {
|
|
+ voidpf org_ptr;
|
|
+ voidpf new_ptr;
|
|
+} ptr_table;
|
|
+
|
|
+local ptr_table table[MAX_PTR];
|
|
+/* This table is used to remember the original form of pointers
|
|
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
|
|
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
|
|
+ * protected from concurrent access. This hack doesn't work anyway on
|
|
+ * a protected system like OS/2. Use Microsoft C instead.
|
|
+ */
|
|
+
|
|
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
|
+{
|
|
+ voidpf buf = opaque; /* just to make some compilers happy */
|
|
+ ulg bsize = (ulg)items*size;
|
|
+
|
|
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
|
|
+ * will return a usable pointer which doesn't have to be normalized.
|
|
+ */
|
|
+ if (bsize < 65520L) {
|
|
+ buf = farmalloc(bsize);
|
|
+ if (*(ush*)&buf != 0) return buf;
|
|
+ } else {
|
|
+ buf = farmalloc(bsize + 16L);
|
|
+ }
|
|
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
|
|
+ table[next_ptr].org_ptr = buf;
|
|
+
|
|
+ /* Normalize the pointer to seg:0 */
|
|
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
|
|
+ *(ush*)&buf = 0;
|
|
+ table[next_ptr++].new_ptr = buf;
|
|
+ return buf;
|
|
+}
|
|
+
|
|
+void zcfree (voidpf opaque, voidpf ptr)
|
|
+{
|
|
+ int n;
|
|
+ if (*(ush*)&ptr != 0) { /* object < 64K */
|
|
+ farfree(ptr);
|
|
+ return;
|
|
+ }
|
|
+ /* Find the original pointer */
|
|
+ for (n = 0; n < next_ptr; n++) {
|
|
+ if (ptr != table[n].new_ptr) continue;
|
|
+
|
|
+ farfree(table[n].org_ptr);
|
|
+ while (++n < next_ptr) {
|
|
+ table[n-1] = table[n];
|
|
+ }
|
|
+ next_ptr--;
|
|
+ return;
|
|
+ }
|
|
+ ptr = opaque; /* just to make some compilers happy */
|
|
+ Assert(0, "zcfree: ptr not found");
|
|
+}
|
|
+#endif
|
|
+#endif /* __TURBOC__ */
|
|
+
|
|
+
|
|
+#if defined(M_I86) && !defined(__32BIT__)
|
|
+/* Microsoft C in 16-bit mode */
|
|
+
|
|
+# define MY_ZCALLOC
|
|
+
|
|
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
|
|
+# define _halloc halloc
|
|
+# define _hfree hfree
|
|
+#endif
|
|
+
|
|
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
|
+{
|
|
+ if (opaque) opaque = 0; /* to make compiler happy */
|
|
+ return _halloc((long)items, size);
|
|
+}
|
|
+
|
|
+void zcfree (voidpf opaque, voidpf ptr)
|
|
+{
|
|
+ if (opaque) opaque = 0; /* to make compiler happy */
|
|
+ _hfree(ptr);
|
|
+}
|
|
+
|
|
+#endif /* MSC */
|
|
+
|
|
+
|
|
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
|
|
+
|
|
+#ifndef STDC
|
|
+extern voidp calloc OF((uInt items, uInt size));
|
|
+extern void free OF((voidpf ptr));
|
|
+#endif
|
|
+
|
|
+voidpf zcalloc (opaque, items, size)
|
|
+ voidpf opaque;
|
|
+ unsigned items;
|
|
+ unsigned size;
|
|
+{
|
|
+ if (opaque) items += size - size; /* make compiler happy */
|
|
+ return (voidpf)calloc(items, size);
|
|
+}
|
|
+
|
|
+void zcfree (opaque, ptr)
|
|
+ voidpf opaque;
|
|
+ voidpf ptr;
|
|
+{
|
|
+ free(ptr);
|
|
+ if (opaque) return; /* make compiler happy */
|
|
+}
|
|
+
|
|
+#endif /* MY_ZCALLOC */
|
|
--- swan26/net/ipv4/af_inet.c.orig Wed Jun 16 01:18:58 2004
|
|
+++ swan26/net/ipv4/af_inet.c Fri Aug 13 23:09:27 2004
|
|
@@ -1169,6 +1169,18 @@
|
|
#if defined(CONFIG_IP_MROUTE)
|
|
ip_mr_init();
|
|
#endif
|
|
+
|
|
+#if defined(CONFIG_KLIPS)
|
|
+ {
|
|
+ extern int ipsec_klips_init(void);
|
|
+ /*
|
|
+ * Initialise AF_INET ESP and AH protocol support including
|
|
+ * e-routing and SA tables
|
|
+ */
|
|
+ ipsec_klips_init();
|
|
+ }
|
|
+#endif /* CONFIG_IPSEC */
|
|
+
|
|
/*
|
|
* Initialise per-cpu ipv4 mibs
|
|
*/
|
|
--- /dev/null Fri May 10 13:59:54 2002
|
|
+++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002
|
|
@@ -0,0 +1 @@
|
|
+IPSECVERSION=2.4.9
|