]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.2.18-freeswan-1.8.patch
- added CONFIG_PDC202XXX_FORCE, for new ide drivers
[packages/kernel.git] / linux-2.2.18-freeswan-1.8.patch
CommitLineData
f4aed85b
AF
1diff -druN linux-noipsec/Documentation/Configure.help linux/Documentation/Configure.help
2--- linux-noipsec/Documentation/Configure.help Fri Dec 15 15:17:02 2000
3+++ linux/Documentation/Configure.help Fri Dec 15 15:18:21 2000
4@@ -3715,6 +3715,59 @@
5 This is a backward compatibility option, choose Y for now.
6 This option will be removed soon.
7
8+IP Security Protocol (IPSEC) (EXPERIMENTAL)
9+CONFIG_IPSEC
10+ This unit is experimental code.
11+ Pick 'y' for static linking, 'm' for module support or 'n' for none.
12+ This option adds support for network layer packet encryption and/or
13+ authentication with participating hosts. The standards start with:
14+ RFCs 2411, 2407 and 2401. Others are mentioned where they refer to
15+ specific features below. There are more pending which can be found
16+ at: ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*.
17+ A description of each document can also be found at:
18+ http://ietf.org/ids.by.wg/ipsec.html.
19+ Their charter can be found at:
20+ http://www.ietf.org/html.charters/ipsec-charter.html
21+ Snapshots and releases of the current work can be found at:
22+ http://www.freeswan.org/
23+
24+IPSEC: IP-in-IP encapsulation
25+CONFIG_IPSEC_IPIP
26+ This option provides support for tunnel mode IPSEC. It is recommended
27+ to enable this.
28+
29+IPSEC: Authentication Header
30+CONFIG_IPSEC_AH
31+ This option provides support for the IPSEC Authentication Header
32+ (IP protocol 51) which provides packet layer sender and content
33+ authentication. It is recommended to enable this. RFC2402
34+
35+HMAC-MD5 algorithm
36+CONFIG_IPSEC_AUTH_HMAC_MD5
37+ Provides support for authentication using the HMAC MD5
38+ algorithm with 96 bits of hash used as the authenticator. RFC2403
39+
40+HMAC-SHA1 algorithm
41+CONFIG_IPSEC_AUTH_HMAC_SHA1
42+ Provides support for Authentication Header using the HMAC SHA1
43+ algorithm with 96 bits of hash used as the authenticator. RFC2404
44+
45+IPSEC: Encapsulating Security Payload
46+CONFIG_IPSEC_ESP
47+ This option provides support for the IPSEC Encapsulation Security
48+ Payload (IP protocol 50) which provides packet layer content
49+ hiding. It is recommended to enable this. RFC2406
50+
51+3DES algorithm
52+CONFIG_IPSEC_ENC_3DES
53+ Provides support for Encapsulation Security Payload protocol, using
54+ the triple DES encryption algorithm. RFC2451
55+
56+IPSEC Debugging Option
57+CONFIG_IPSEC_DEBUG
58+ Enables IPSEC kernel debugging. It is further controlled by the
59+ user space utility 'klipsdebug'.
60+
61 SCSI support?
62 CONFIG_SCSI
63 If you want to use a SCSI hard disk, SCSI tape drive, SCSI CDROM or
f4aed85b
AF
64diff -druN linux-noipsec/arch/i386/defconfig linux/arch/i386/defconfig
65--- linux-noipsec/arch/i386/defconfig Fri Dec 15 15:16:54 2000
66+++ linux/arch/i386/defconfig Fri Dec 15 15:18:22 2000
67@@ -392,3 +392,96 @@
68 # Kernel hacking
69 #
70 # CONFIG_MAGIC_SYSRQ is not set
71+#
72+# RCSID $Id$
73+#
74+
75+#
76+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
77+#
78+
79+#
80+# First, lets override stuff already set or not in the kernel config.
81+#
82+# We can't even think about leaving this off...
83+CONFIG_INET=y
84+
85+#
86+# This must be on for subnet protection.
87+CONFIG_IP_FORWARD=y
88+
89+# Shut off IPSEC masquerading if it has been enabled, since it will
90+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
91+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
92+CONFIG_IP_MASQUERADE_IPSEC=n
93+
94+#
95+# Next, lets set the recommended FreeS/WAN configuration.
96+#
97+
98+# To config as static (preferred), 'y'. To config as module, 'm'.
99+CONFIG_IPSEC=y
100+
101+# To do tunnel mode IPSec, this must be enabled.
102+CONFIG_IPSEC_IPIP=y
103+
104+# To enable authentication, say 'y'. (Highly recommended)
105+CONFIG_IPSEC_AH=y
106+
107+# Authentication algorithm(s):
108+CONFIG_IPSEC_AUTH_HMAC_MD5=y
109+CONFIG_IPSEC_AUTH_HMAC_SHA1=y
110+
111+# To enable encryption, say 'y'. (Highly recommended)
112+CONFIG_IPSEC_ESP=y
113+
114+# Encryption algorithm(s):
115+CONFIG_IPSEC_ENC_3DES=y
116+
117+# IP Compression: new, probably still has minor bugs.
118+CONFIG_IPSEC_IPCOMP=y
119+
120+# To enable userspace-switchable KLIPS debugging, say 'y'.
121+CONFIG_IPSEC_DEBUG=y
122+
123+#
124+#
125+# $Log$
126+# Revision 1.18 2000/11/30 17:26:56 rgb
127+# Cleaned out unused options and enabled ipcomp by default.
128+#
129+# Revision 1.17 2000/09/15 11:37:01 rgb
130+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
131+# IPCOMP zlib deflate code.
132+#
133+# Revision 1.16 2000/09/08 19:12:55 rgb
134+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
135+#
136+# Revision 1.15 2000/05/24 19:37:13 rgb
137+# *** empty log message ***
138+#
139+# Revision 1.14 2000/05/11 21:14:57 henry
140+# just commenting the FOOBAR=y lines out is not enough
141+#
142+# Revision 1.13 2000/05/10 20:17:58 rgb
143+# Comment out netlink defaults, which are no longer needed.
144+#
145+# Revision 1.12 2000/05/10 19:13:38 rgb
146+# Added configure option to shut off no eroute passthrough.
147+#
148+# Revision 1.11 2000/03/16 07:09:46 rgb
149+# Hardcode PF_KEYv2 support.
150+# Disable IPSEC_ICMP by default.
151+# Remove DES config option from defaults file.
152+#
153+# Revision 1.10 2000/01/11 03:09:42 rgb
154+# Added a default of 'y' to PF_KEYv2 keying I/F.
155+#
156+# Revision 1.9 1999/05/08 21:23:12 rgb
157+# Added support for 2.2.x kernels.
158+#
159+# Revision 1.8 1999/04/06 04:54:25 rgb
160+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
161+# patch shell fixes.
162+#
163+#
164--- linux-noipsec/net/Config.in Fri Dec 15 15:15:48 2000
165+++ linux/net/Config.in Fri Dec 15 15:18:21 2000
166@@ -67,4 +67,8 @@
167 endmenu
168 fi
169 fi
170+tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC
171+if [ "$CONFIG_IPSEC" != "n" ]; then
172+ source net/ipsec/Config.in
173+fi
174 endmenu
f4aed85b
AF
175diff -druN linux-noipsec/net/Makefile linux/net/Makefile
176--- linux-noipsec/net/Makefile Fri Dec 15 15:15:46 2000
177+++ linux/net/Makefile Fri Dec 15 15:18:21 2000
178@@ -161,6 +161,16 @@
179 endif
180 endif
181
182+ifeq ($(CONFIG_IPSEC),y)
183+ALL_SUB_DIRS += ipsec
184+SUB_DIRS += ipsec
185+else
186+ ifeq ($(CONFIG_IPSEC),m)
187+ ALL_SUB_DIRS += ipsec
188+ MOD_SUB_DIRS += ipsec
189+ endif
190+endif
191+
192 # We must attach netsyms.o to socket.o, as otherwise there is nothing
193 # to pull the object file from the archive.
194
3cb090dd
JR
195diff -druN linux-noipsec/net/ipsec/Config.in linux/net/ipsec/Config.in
196--- linux-noipsec/net/ipsec/Config.in Thu Jan 1 01:00:00 1970
197+++ linux/net/ipsec/Config.in Fri Sep 15 13:37:00 2000
198@@ -0,0 +1,34 @@
f4aed85b 199+#
3cb090dd
JR
200+# IPSEC configuration
201+# Copyright (C) 1998, 1999 Richard Guy Briggs.
202+#
203+# This program is free software; you can redistribute it and/or modify it
204+# under the terms of the GNU General Public License as published by the
205+# Free Software Foundation; either version 2 of the License, or (at your
206+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
207+#
208+# This program is distributed in the hope that it will be useful, but
209+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
210+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
211+# for more details.
f4aed85b 212+#
3cb090dd 213+# RCSID $Id$
f4aed85b 214+
3cb090dd 215+comment 'IPSec options (FreeS/WAN)'
f4aed85b 216+
3cb090dd 217+bool ' IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP
f4aed85b 218+
3cb090dd
JR
219+bool ' IPSEC: Authentication Header' CONFIG_IPSEC_AH
220+if [ "$CONFIG_IPSEC_AH" = "y" -o "$CONFIG_IPSEC_ESP" = "y" ]; then
221+ bool ' HMAC-MD5 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_MD5
222+ bool ' HMAC-SHA1 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_SHA1
223+fi
f4aed85b 224+
3cb090dd
JR
225+bool ' IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP
226+if [ "$CONFIG_IPSEC_ESP" = "y" ]; then
227+ bool ' 3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES
228+fi
f4aed85b 229+
3cb090dd 230+bool ' IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP
f4aed85b 231+
3cb090dd
JR
232+bool ' IPSEC Debugging Option' CONFIG_IPSEC_DEBUG
233diff -druN linux-noipsec/net/ipsec/Makefile linux/net/ipsec/Makefile
234--- linux-noipsec/net/ipsec/Makefile Thu Jan 1 01:00:00 1970
235+++ linux/net/ipsec/Makefile Fri Sep 29 21:51:57 2000
236@@ -0,0 +1,242 @@
237+# Makefile for KLIPS kernel code
238+# Copyright (C) 1998, 1999 Richard Guy Briggs.
239+#
240+# This program is free software; you can redistribute it and/or modify it
241+# under the terms of the GNU General Public License as published by the
242+# Free Software Foundation; either version 2 of the License, or (at your
243+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
244+#
245+# This program is distributed in the hope that it will be useful, but
246+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
247+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
248+# for more details.
249+#
250+# RCSID $Id$
251+#
252+# Note! Dependencies are done automagically by 'make dep', which also
253+# removes any old dependencies. DON'T put your own dependencies here
254+# unless it's something special (ie not a .c file).
255+#
256+# Note 2! The CFLAGS definition is now in the main makefile...
f4aed85b 257+
3cb090dd
JR
258+ifndef TOPDIR
259+TOPDIR := /usr/src/linux
f4aed85b
AF
260+endif
261+
3cb090dd
JR
262+SUB_DIRS :=
263+ALL_SUB_DIRS := libfreeswan zlib
264+MOD_SUB_DIRS :=
f4aed85b 265+
3cb090dd
JR
266+O_TARGET := ipsec.o
267+O_OBJS := ipsec_init.o ipsec_xform.o ipsec_netlink.o ipsec_radij.o ipsec_tunnel.o ipsec_rcv.o sysctl_net_ipsec.o pfkey_v2.o pfkey_v2_parser.o
f4aed85b 268+
3cb090dd
JR
269+OX_OBJS := radij.o
270+M_OBJS := $(O_TARGET)
f4aed85b 271+
3cb090dd 272+override CFLAGS += -Ilibfreeswan
f4aed85b 273+
3cb090dd
JR
274+ifeq ($(CONFIG_IPSEC_DEBUG),y)
275+override CFLAGS += -g
f4aed85b
AF
276+endif
277+
3cb090dd
JR
278+override CFLAGS += -Wall
279+#override CFLAGS += -Wconversion
280+#override CFLAGS += -Wmissing-prototypes
281+override CFLAGS += -Wpointer-arith
282+#override CFLAGS += -Wcast-qual
283+#override CFLAGS += -Wmissing-declarations
284+override CFLAGS += -Wstrict-prototypes
285+#override CFLAGS += -pedantic
286+#override CFLAGS += -O3
287+#override CFLAGS += -W
288+#override CFLAGS += -Wwrite-strings
289+override CFLAGS += -Wbad-function-cast
f4aed85b 290+
f4aed85b 291+
3cb090dd
JR
292+ifeq ($(CONFIG_IPSEC_ENC_DES),y)
293+INCLUDE_DES = y
f4aed85b
AF
294+endif
295+
3cb090dd
JR
296+ifeq ($(CONFIG_IPSEC_ENC_3DES),y)
297+INCLUDE_DES = y
f4aed85b
AF
298+endif
299+
3cb090dd
JR
300+ifeq ($(CONFIG_IPSEC_AUTH_HMAC_MD5),y)
301+O_OBJS += ipsec_md5c.o
f4aed85b
AF
302+endif
303+
3cb090dd
JR
304+ifeq ($(CONFIG_IPSEC_AUTH_HMAC_SHA1),y)
305+O_OBJS += ipsec_sha1.o
f4aed85b
AF
306+endif
307+
3cb090dd
JR
308+ifeq ($(CONFIG_IPSEC_IPCOMP),y)
309+ O_OBJS += ipcomp.o zlib/zlib.a
310+ SUB_DIRS += zlib
311+ MOD_SUB_DIRS += zlib
f4aed85b
AF
312+endif
313+
3cb090dd
JR
314+ifeq ($(INCLUDE_DES),y)
315+O_OBJS += libdes/libdes.a
f4aed85b
AF
316+endif
317+
3cb090dd 318+O_OBJS += libfreeswan/libkernel.a
f4aed85b
AF
319+
320+ifeq ($(CONFIG_IPSEC),y)
3cb090dd 321+SUB_DIRS += libfreeswan
f4aed85b
AF
322+else
323+ ifeq ($(CONFIG_IPSEC),m)
3cb090dd 324+ override MOD_SUB_DIRS += libfreeswan
f4aed85b
AF
325+ endif
326+endif
327+
3cb090dd 328+include $(TOPDIR)/Rules.make
f4aed85b 329+
3cb090dd 330+$(O_OBJS) $(OX_OBJS): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
f4aed85b 331+
3cb090dd
JR
332+libdes/libdes.a:
333+ ( cd libdes && \
334+ if test " `arch | sed 's/^i[3456]/x/'`" = " x86" ; \
335+ then $(MAKE) CC='$(CC)' CFLAG='$(CFLAGS)' TESTING='' x86-elf ; \
336+ else $(MAKE) CC='$(CC)' CFLAG='$(CFLAGS)' libdes.a ; \
337+ fi )
f4aed85b 338+
3cb090dd
JR
339+libfreeswan/libkernel.a:
340+ $(MAKE) -C libfreeswan
f4aed85b 341+
3cb090dd
JR
342+zlib/zlib.a:
343+ $(MAKE) -C zlib
f4aed85b
AF
344+
345+clean:
346+ -rm -f *.o
347+
348+tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
349+ find . -name '*.[ch]' |xargs etags
350+ find . -name '*.[ch]' |xargs ctags
351+
352+tar:
353+ tar -cvf /dev/f1 .
354+
355+#
356+# $Log$
357+# Revision 1.30 2000/09/29 19:51:57 rgb
358+# Moved klips/net/ipsec/ipcomp_* to zlib/* (Svenning).
359+#
360+# Revision 1.29 2000/09/15 11:37:01 rgb
361+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
362+# IPCOMP zlib deflate code.
363+#
364+# Revision 1.28 2000/09/15 04:55:25 rgb
365+# Clean up pfkey object inclusion into the default object.
366+#
367+# Revision 1.27 2000/09/12 03:20:47 rgb
368+# Cleared out now unused pfkeyv2 switch.
369+# Enabled sysctl.
370+#
371+# Revision 1.26 2000/09/08 19:12:55 rgb
372+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
373+#
374+# Revision 1.25 2000/06/16 03:09:16 rgb
375+# Shut up cast lost warning due to changes in 2.4.0-test1.
376+#
377+# Revision 1.24 2000/03/16 06:40:48 rgb
378+# Hardcode PF_KEYv2 support.
379+#
380+# Revision 1.23 2000/02/14 21:10:38 rgb
381+# Added gcc debug flag when KLIPS_DEBUG is swtiched on.
382+#
383+# Revision 1.22 2000/01/21 09:44:29 rgb
384+# Added compiler switches to be a lot more fussy.
385+#
386+# Revision 1.21 1999/11/25 23:35:20 rgb
387+# Removed quotes to fix Alpha compile issues.
388+#
389+# Revision 1.20 1999/11/17 15:49:34 rgb
390+# Changed all occurrences of ../../../lib in pathnames to libfreeswan,
391+# which refers to the /usr/src/linux/net/ipsec/lib directory setup by the
392+# klink target in the top-level Makefile; and libdeslite.o to
393+# libdes/libdes.a.
394+# Added SUB_DIRS := lib definition for the kernel libraries.
395+#
396+# Revision 1.19 1999/04/27 19:06:47 rgb
397+# dd libs and dependancies to tags generation.
398+#
399+# Revision 1.18 1999/04/16 16:28:12 rgb
400+# Minor bugfix to avoid including DES if only AH is used.
401+#
402+# Revision 1.17 1999/04/15 15:37:23 rgb
403+# Forward check changes from POST1_00 branch.
404+#
405+# Revision 1.14.2.1 1999/03/30 17:29:17 rgb
406+# Add support for pfkey.
407+#
408+# Revision 1.16 1999/04/11 00:28:56 henry
409+# GPL boilerplate
410+#
411+# Revision 1.15 1999/04/06 04:54:25 rgb
412+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
413+# patch shell fixes.
414+#
415+# Revision 1.14 1999/02/18 16:50:45 henry
416+# update for new DES library
417+#
418+# Revision 1.13 1999/02/12 21:11:45 rgb
419+# Prepare for newer LIBDES (patch from P.Onion).
420+#
421+# Revision 1.12 1999/01/26 02:05:08 rgb
422+# Remove references to INET_GET_PROTOCOL.
423+# Removed CONFIG_IPSEC_ALGO_SWITCH macro.
424+# Change from transform switch to algorithm switch.
425+#
426+# Revision 1.11 1999/01/22 06:16:09 rgb
427+# Added algorithm switch code config option.
428+#
429+# Revision 1.10 1998/11/08 05:31:21 henry
430+# be a little fussier
431+#
432+# Revision 1.9 1998/11/08 05:29:41 henry
433+# revisions for new libdes handling
434+#
435+# Revision 1.8 1998/08/12 00:05:48 rgb
436+# Added new xforms to Makefile (moved des-cbc to des-old).
437+#
438+# Revision 1.7 1998/07/27 21:48:47 rgb
439+# Add libkernel.
440+#
441+# Revision 1.6 1998/07/14 15:50:47 rgb
442+# Add dependancies on linux config files.
443+#
444+# Revision 1.5 1998/07/09 17:44:06 rgb
445+# Added 'clean' and 'tags' targets.
446+# Added TOPDIR macro.
447+# Change module back from symbol exporting to not.
448+#
449+# Revision 1.3 1998/06/25 19:25:04 rgb
450+# Rearrange to support static linking and objects with exported symbol
451+# tables.
452+#
453+# Revision 1.1 1998/06/18 21:27:42 henry
454+# move sources from klips/src to klips/net/ipsec, to keep stupid
455+# kernel-build scripts happier in the presence of symlinks
456+#
457+# Revision 1.3 1998/04/15 23:18:43 rgb
458+# Unfixed the ../../libdes fix to avoid messing up Henry's script.
459+#
460+# Revision 1.2 1998/04/14 17:50:47 rgb
461+# Fixed to find the new location of libdes.
462+#
463+# Revision 1.1 1998/04/09 03:05:22 henry
464+# sources moved up from linux/net/ipsec
465+# modifications to centralize libdes code
466+#
467+# Revision 1.1.1.1 1998/04/08 05:35:02 henry
468+# RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
469+#
470+# Revision 0.5 1997/06/03 04:24:48 ji
471+# Added ESP-3DES-MD5-96
472+#
473+# Revision 0.4 1997/01/15 01:32:59 ji
474+# Added new transforms.
475+#
476+# Revision 0.3 1996/11/20 14:22:53 ji
477+# *** empty log message ***
478+#
479diff -druN linux-noipsec/net/ipsec/defconfig linux/net/ipsec/defconfig
480--- linux-noipsec/net/ipsec/defconfig Thu Jan 1 01:00:00 1970
481+++ linux/net/ipsec/defconfig Thu Nov 30 18:26:56 2000
482@@ -0,0 +1,93 @@
483+#
484+# RCSID $Id$
485+#
486+
487+#
488+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
489+#
490+
491+#
492+# First, lets override stuff already set or not in the kernel config.
493+#
494+# We can't even think about leaving this off...
495+CONFIG_INET=y
496+
497+#
498+# This must be on for subnet protection.
499+CONFIG_IP_FORWARD=y
500+
501+# Shut off IPSEC masquerading if it has been enabled, since it will
502+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
503+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
504+CONFIG_IP_MASQUERADE_IPSEC=n
505+
506+#
507+# Next, lets set the recommended FreeS/WAN configuration.
508+#
509+
510+# To config as static (preferred), 'y'. To config as module, 'm'.
511+CONFIG_IPSEC=y
512+
513+# To do tunnel mode IPSec, this must be enabled.
514+CONFIG_IPSEC_IPIP=y
515+
516+# To enable authentication, say 'y'. (Highly recommended)
517+CONFIG_IPSEC_AH=y
518+
519+# Authentication algorithm(s):
520+CONFIG_IPSEC_AUTH_HMAC_MD5=y
521+CONFIG_IPSEC_AUTH_HMAC_SHA1=y
522+
523+# To enable encryption, say 'y'. (Highly recommended)
524+CONFIG_IPSEC_ESP=y
525+
526+# Encryption algorithm(s):
527+CONFIG_IPSEC_ENC_3DES=y
528+
529+# IP Compression: new, probably still has minor bugs.
530+CONFIG_IPSEC_IPCOMP=y
531+
532+# To enable userspace-switchable KLIPS debugging, say 'y'.
533+CONFIG_IPSEC_DEBUG=y
534+
535+#
536+#
537+# $Log$
538+# Revision 1.18 2000/11/30 17:26:56 rgb
539+# Cleaned out unused options and enabled ipcomp by default.
540+#
541+# Revision 1.17 2000/09/15 11:37:01 rgb
542+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
543+# IPCOMP zlib deflate code.
544+#
545+# Revision 1.16 2000/09/08 19:12:55 rgb
546+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
547+#
548+# Revision 1.15 2000/05/24 19:37:13 rgb
549+# *** empty log message ***
550+#
551+# Revision 1.14 2000/05/11 21:14:57 henry
552+# just commenting the FOOBAR=y lines out is not enough
553+#
554+# Revision 1.13 2000/05/10 20:17:58 rgb
555+# Comment out netlink defaults, which are no longer needed.
556+#
557+# Revision 1.12 2000/05/10 19:13:38 rgb
558+# Added configure option to shut off no eroute passthrough.
559+#
560+# Revision 1.11 2000/03/16 07:09:46 rgb
561+# Hardcode PF_KEYv2 support.
562+# Disable IPSEC_ICMP by default.
563+# Remove DES config option from defaults file.
564+#
565+# Revision 1.10 2000/01/11 03:09:42 rgb
566+# Added a default of 'y' to PF_KEYv2 keying I/F.
567+#
568+# Revision 1.9 1999/05/08 21:23:12 rgb
569+# Added support for 2.2.x kernels.
570+#
571+# Revision 1.8 1999/04/06 04:54:25 rgb
572+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
573+# patch shell fixes.
574+#
575+#
576diff -druN linux-noipsec/net/ipsec/ipcomp.c linux/net/ipsec/ipcomp.c
577--- linux-noipsec/net/ipsec/ipcomp.c Thu Jan 1 01:00:00 1970
578+++ linux/net/ipsec/ipcomp.c Sat Nov 25 04:48:49 2000
579@@ -0,0 +1,725 @@
580+/*
581+ * IPCOMP zlib interface code.
582+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
583+ * Copyright (C) 2000 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
584+ *
585+ * This program is free software; you can redistribute it and/or modify it
586+ * under the terms of the GNU General Public License as published by the
587+ * Free Software Foundation; either version 2 of the License, or (at your
588+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
589+ *
590+ * This program is distributed in the hope that it will be useful, but
591+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
592+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
593+ * for more details.
594+ */
595+
596+char ipcomp_c_version[] = "RCSID $Id$";
597+
598+/* SSS */
599+
600+#include <linux/config.h>
601+#include <linux/version.h>
602+
603+#define __NO_VERSION__
604+#include <linux/module.h>
605+
606+#include <linux/kernel.h> /* printk() */
607+#include <linux/malloc.h>
608+#include <linux/errno.h> /* error codes */
609+#include <linux/types.h>
610+#include <linux/netdevice.h>
611+#include <linux/ip.h>
612+#include <linux/skbuff.h>
613+
614+#include <linux/netdevice.h> /* struct device, and other headers */
615+#include <linux/etherdevice.h> /* eth_type_trans */
616+#include <linux/ip.h> /* struct iphdr */
617+#include <linux/skbuff.h>
618+
619+#include <freeswan.h>
620+#ifdef NET_21
621+#include <net/dst.h>
622+#include <asm/uaccess.h>
623+#include <linux/in6.h>
624+#define proto_priv cb
625+#endif /* NET21 */
626+#include <asm/checksum.h>
627+#include <net/ip.h>
628+
629+#include "radij.h"
630+#include "ipsec_encap.h"
631+#include "ipsec_netlink.h"
632+#include "ipsec_xform.h"
633+#include "ipsec_tunnel.h"
634+#include "ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
635+#include "ipcomp.h"
636+#include "zlib/zlib.h"
637+#include "zlib/zutil.h"
638+
639+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
640+
641+#ifdef CONFIG_IPSEC_DEBUG
642+int sysctl_ipsec_debug_ipcomp = 0;
643+#endif /* CONFIG_IPSEC_DEBUG */
644+
645+static
646+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
647+
648+static
649+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
650+{
651+ return (voidpf) kmalloc(items*size, GFP_ATOMIC);
652+}
653+
654+static
655+void my_zfree(voidpf opaque, voidpf address)
656+{
657+ kfree(address);
658+}
659+
660+struct sk_buff *skb_compress(struct sk_buff *skb, struct tdb *tdb, unsigned int *flags)
661+{
662+ struct iphdr *iph;
663+ unsigned int iphlen, pyldsz, cpyldsz;
664+ unsigned char *buffer;
665+ z_stream zs;
666+ int zresult;
667+
668+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
669+ "klips_debug:skb_compress: .\n");
670+
671+ if(!skb) {
672+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
673+ "klips_debug:skb_compress: "
674+ "passed in NULL skb, returning ERROR.\n");
675+ if (flags) *flags |= IPCOMP_PARMERROR;
676+ return skb;
677+ }
678+
679+ if(!tdb) {
680+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
681+ "klips_debug:skb_compress: "
682+ "passed in NULL tdb needed for cpi, returning ERROR.\n");
683+ if (flags) *flags |= IPCOMP_PARMERROR;
684+ return skb;
685+ }
686+
687+ if (!flags) {
688+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
689+ "klips_debug:skb_compress: "
690+ "passed in NULL flags, returning ERROR.\n");
691+#ifdef NET_21
692+ kfree_skb(skb);
693+#else /* NET_21 */
694+ dev_kfree_skb(skb, FREE_WRITE);
695+#endif /* NET_21 */
696+ return NULL;
697+ }
698+
699+#ifdef NET_21
700+ iph = skb->nh.iph;
701+#else /* NET_21 */
702+ iph = skb->ip_hdr;
703+#endif /* NET_21 */
704+
705+ switch (iph->protocol) {
706+ case IPPROTO_COMP:
707+ case IPPROTO_AH:
708+ case IPPROTO_ESP:
709+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
710+ "klips_debug:skb_compress: "
711+ "skipping compression of packet with ip protocol %d.\n",
712+ iph->protocol);
713+ *flags |= IPCOMP_UNCOMPRESSABLE;
714+ return skb;
715+ }
716+
717+ /* Don't compress packets already fragmented */
718+ if (ntohs(iph->frag_off) & ~0x4000) {
719+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
720+ "klips_debug:skb_compress: "
721+ "skipping compression of fragmented packet.\n");
722+ *flags |= IPCOMP_UNCOMPRESSABLE;
723+ return skb;
724+ }
725+
726+ iphlen = iph->ihl << 2;
727+ pyldsz = ntohs(iph->tot_len) - iphlen;
728+
729+ /* Don't compress less than 90 bytes (rfc 2394) */
730+ if (pyldsz < 90) {
731+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
732+ "klips_debug:skb_compress: "
733+ "skipping compression of tiny packet, len=%d.\n",
734+ pyldsz);
735+ *flags |= IPCOMP_UNCOMPRESSABLE;
736+ return skb;
737+ }
738+
739+ /* Adaptive decision */
740+ if (tdb->tdb_comp_adapt_skip) {
741+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
742+ "klips_debug:skb_compress: "
743+ "skipping compression: tdb_comp_adapt_skip=%d.\n",
744+ tdb->tdb_comp_adapt_skip);
745+ tdb->tdb_comp_adapt_skip--;
746+ *flags |= IPCOMP_UNCOMPRESSABLE;
747+ return skb;
748+ }
749+
750+ zs.zalloc = my_zcalloc;
751+ zs.zfree = my_zfree;
752+ zs.opaque = 0;
753+
754+ /* We want to use deflateInit2 because we don't want the adler
755+ header. */
756+ zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
757+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
758+ if (zresult != Z_OK) {
759+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
760+ "klips_error:skb_compress: "
761+ "deflateInit2() returned error %d (%s), "
762+ "skipping compression.\n",
763+ zresult,
764+ zs.msg ? zs.msg : zError(zresult));
765+ *flags |= IPCOMP_COMPRESSIONERROR;
766+ return skb;
767+ }
768+
769+
770+ /* Max output size. Result should be max this size.
771+ * Implementation specific tweak:
772+ * If it's not at least 32 bytes and 6.25% smaller than
773+ * the original packet, it's probably not worth wasting
774+ * the receiver's CPU cycles decompressing it.
775+ * Your mileage may vary.
776+ */
777+ cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
778+
779+ buffer = kmalloc(cpyldsz, GFP_ATOMIC);
780+ if (!buffer) {
781+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
782+ "klips_error:skb_compress: "
783+ "unable to kmalloc(%d, GFP_ATOMIC), "
784+ "skipping compression.\n",
785+ cpyldsz);
786+ *flags |= IPCOMP_COMPRESSIONERROR;
787+ deflateEnd(&zs);
788+ return skb;
789+ }
790+
791+#ifdef CONFIG_IPSEC_DEBUG
792+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
793+ __u8 *c;
794+ int i;
795+
796+ c = (__u8*)iph + iphlen;
797+ for(i = 0; i < pyldsz; i++, c++) {
798+ if(!(i % 16)) {
799+ printk(KERN_INFO "skb_compress: before:");
800+ }
801+ printk("%02x ", *c);
802+ if(!((i + 1) % 16)) {
803+ printk("\n");
804+ }
805+ }
806+ if(i % 16) {
807+ printk("\n");
808+ }
809+ }
810+#endif /* CONFIG_IPSEC_DEBUG */
811+
812+ zs.next_in = (char *) iph + iphlen; /* start of payload */
813+ zs.avail_in = pyldsz;
814+ zs.next_out = buffer; /* start of compressed payload */
815+ zs.avail_out = cpyldsz;
816+
817+ /* Finish compression in one step */
818+ zresult = deflate(&zs, Z_FINISH);
819+
820+ /* Free all dynamically allocated buffers */
821+ deflateEnd(&zs);
822+ if (zresult != Z_STREAM_END) {
823+ *flags |= IPCOMP_UNCOMPRESSABLE;
824+ kfree(buffer);
825+
826+ /* Adjust adaptive counters */
827+ if (++(tdb->tdb_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
828+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
829+ "klips_debug:skb_compress: "
830+ "first %d packets didn't compress, "
831+ "skipping next %d\n",
832+ IPCOMP_ADAPT_INITIAL_TRIES,
833+ IPCOMP_ADAPT_INITIAL_SKIP);
834+ tdb->tdb_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
835+ }
836+ else if (tdb->tdb_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
837+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
838+ "klips_debug:skb_compress: "
839+ "next %d packets didn't compress, "
840+ "skipping next %d\n",
841+ IPCOMP_ADAPT_SUBSEQ_TRIES,
842+ IPCOMP_ADAPT_SUBSEQ_SKIP);
843+ tdb->tdb_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
844+ tdb->tdb_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
845+ }
846+
847+ return skb;
848+ }
849+
850+ /* resulting compressed size */
851+ cpyldsz -= zs.avail_out;
852+
853+ /* Insert IPCOMP header */
854+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
855+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
856+ /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
857+ for internal reference only. */
858+ ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(tdb->tdb_said.spi) & 0x0000ffff));
859+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
860+ "klips_debug:skb_compress: "
861+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
862+ ntohl(tdb->tdb_said.spi),
863+ ntohl(tdb->tdb_said.spi) & 0x0000ffff,
864+ ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
865+ pyldsz,
866+ cpyldsz);
867+
868+ /* Update IP header */
869+ iph->protocol = IPPROTO_COMP;
870+ iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
871+#if 1 /* XXX checksum is done by ipsec_tunnel ? */
872+ iph->check = 0;
873+ iph->check = ip_fast_csum((char *) iph, iph->ihl);
874+#endif
875+
876+ /* Copy compressed payload */
877+ memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
878+ buffer,
879+ cpyldsz);
880+ kfree(buffer);
881+
882+ /* Update skb length/tail by "unputting" the shrinkage */
883+ skb_put(skb,
884+ cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
885+
886+#ifdef CONFIG_IPSEC_DEBUG
887+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
888+ __u8 *c;
889+ int i;
890+
891+ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
892+ for(i = 0; i < cpyldsz; i++, c++) {
893+ if(!(i % 16)) {
894+ printk(KERN_INFO "skb_compress: result:");
895+ }
896+ printk("%02x ", *c);
897+ if(!((i + 1) % 16)) {
898+ printk("\n");
899+ }
900+ }
901+ if(i % 16) {
902+ printk("\n");
903+ }
904+ }
905+#endif /* CONFIG_IPSEC_DEBUG */
906+
907+ tdb->tdb_comp_adapt_skip = 0;
908+ tdb->tdb_comp_adapt_tries = 0;
909+
910+ return skb;
911+}
912+
913+struct sk_buff *skb_decompress(struct sk_buff *skb, struct tdb *tdb, unsigned int *flags)
914+{
915+ struct sk_buff *nskb = NULL;
916+
917+ /* original ip header */
918+ struct iphdr *oiph, *iph;
919+ unsigned int iphlen, pyldsz, cpyldsz;
920+ z_stream zs;
921+ int zresult;
922+
923+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
924+ "klips_debug:skb_decompress: .\n");
925+
926+ if(!skb) {
927+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
928+ "klips_error:skb_decompress: "
929+ "passed in NULL skb, returning ERROR.\n");
930+ if (flags) *flags |= IPCOMP_PARMERROR;
931+ return skb;
932+ }
933+
934+ if(!tdb && sysctl_ipsec_inbound_policy_check) {
935+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
936+ "klips_error:skb_decompress: "
937+ "passed in NULL tdb needed for comp alg, returning ERROR.\n");
938+ if (flags) *flags |= IPCOMP_PARMERROR;
939+ return skb;
940+ }
941+
942+ if (!flags) {
943+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
944+ "klips_error:skb_decompress: "
945+ "passed in NULL flags, returning ERROR.\n");
946+#ifdef NET_21
947+ kfree_skb(skb);
948+#else /* NET_21 */
949+ dev_kfree_skb(skb, FREE_WRITE);
950+#endif /* NET_21 */
951+ return NULL;
952+ }
953+
954+#ifdef NET_21
955+ oiph = skb->nh.iph;
956+#else /* NET_21 */
957+ oiph = skb->ip_hdr;
958+#endif /* NET_21 */
959+
960+ iphlen = oiph->ihl << 2;
961+
962+ if (oiph->protocol != IPPROTO_COMP) {
963+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
964+ "klips_error:skb_decompress: "
965+ "called with non-IPCOMP packet (protocol=%d),"
966+ "skipping decompression.\n",
967+ oiph->protocol);
968+ *flags |= IPCOMP_PARMERROR;
969+ return skb;
970+ }
971+
972+ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
973+ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
974+ != htons(SADB_X_CALG_DEFLATE))
975+ && sysctl_ipsec_inbound_policy_check
976+ && (!tdb || (tdb && (tdb->tdb_encalg != SADB_X_CALG_DEFLATE)))) ) {
977+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
978+ "klips_error:skb_decompress: "
979+ "called with incompatible IPCOMP packet (flags=%d, "
980+ "cpi=%d), tdb-compalg=%d, skipping decompression.\n",
981+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
982+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
983+ tdb ? tdb->tdb_encalg : 0);
984+ *flags |= IPCOMP_PARMERROR;
985+
986+ return skb;
987+ }
988+
989+ if (ntohs(oiph->frag_off) & ~0x4000) {
990+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
991+ "klips_error:skb_decompress: "
992+ "called with fragmented IPCOMP packet, "
993+ "skipping decompression.\n");
994+ *flags |= IPCOMP_PARMERROR;
995+ return skb;
996+ }
997+
998+ /* original compressed payload size */
999+ cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
1000+
1001+ zs.zalloc = my_zcalloc;
1002+ zs.zfree = my_zfree;
1003+ zs.opaque = 0;
1004+
1005+ zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
1006+ zs.avail_in = cpyldsz;
1007+
1008+ /* Maybe we should be a bit conservative about memory
1009+ requirements and use inflateInit2 */
1010+ /* Beware, that this might make us unable to decompress packets
1011+ from other implementations - HINT: check PGPnet source code */
1012+ /* We want to use inflateInit2 because we don't want the adler
1013+ header. */
1014+ zresult = inflateInit2(&zs, -15);
1015+ if (zresult != Z_OK) {
1016+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
1017+ "klips_error:skb_decompress: "
1018+ "inflateInit2() returned error %d (%s), "
1019+ "skipping decompression.\n",
1020+ zresult,
1021+ zs.msg ? zs.msg : zError(zresult));
1022+ *flags |= IPCOMP_DECOMPRESSIONERROR;
1023+
1024+ return skb;
1025+ }
1026+
1027+ /* We have no way of knowing the exact length of the resulting
1028+ decompressed output before we have actually done the decompression.
1029+ For now, we guess that the packet will not be bigger than the
1030+ attached ipsec device's mtu or 16260, whichever is biggest.
1031+ This may be wrong, since the sender's mtu may be bigger yet.
1032+ XXX This must be dealt with later XXX
1033+ */
1034+
1035+ /* max payload size */
1036+ pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
1037+ : (65520 - iphlen);
1038+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
1039+ "klips_debug:skb_decompress: "
1040+ "max payload size: %d\n", pyldsz);
1041+
1042+ while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
1043+ (nskb = skb_copy_ipcomp(skb,
1044+ pyldsz - cpyldsz - sizeof(struct ipcomphdr),
1045+ GFP_ATOMIC)) == NULL) {
1046+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
1047+ "klips_error:skb_decompress: "
1048+ "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
1049+ "trying with less payload size.\n",
1050+ pyldsz - cpyldsz - sizeof(struct ipcomphdr));
1051+ pyldsz >>=1;
1052+ }
1053+
1054+ if (!nskb) {
1055+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
1056+ "klips_error:skb_decompress: "
1057+ "unable to allocate memory, dropping packet.\n");
1058+ *flags |= IPCOMP_DECOMPRESSIONERROR;
1059+ inflateEnd(&zs);
1060+
1061+ return skb;
1062+ }
1063+
1064+#ifdef CONFIG_IPSEC_DEBUG
1065+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
1066+ __u8 *c;
1067+ int i;
1068+
1069+ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
1070+ for(i = 0; i < cpyldsz; i++, c++) {
1071+ if(!(i % 16)) {
1072+ printk(KERN_INFO "skb_decompress: before:");
1073+ }
1074+ printk("%02x ", *c);
1075+ if(!((i + 1) % 16)) {
1076+ printk("\n");
1077+ }
1078+ }
1079+ if(i % 16) {
1080+ printk("\n");
1081+ }
1082+ }
1083+#endif /* CONFIG_IPSEC_DEBUG */
1084+
1085+#ifdef NET_21
1086+ iph = nskb->nh.iph;
1087+#else /* NET_21 */
1088+ iph = nskb->ip_hdr;
1089+#endif /* NET_21 */
1090+ zs.next_out = (char *)iph + iphlen;
1091+ zs.avail_out = pyldsz;
1092+
1093+ zresult = inflate(&zs, Z_SYNC_FLUSH);
1094+
1095+ /* work around a bug in zlib, which sometimes wants to taste an extra
1096+ * byte when being used in the (undocumented) raw deflate mode.
1097+ */
1098+ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
1099+ __u8 zerostuff = 0;
1100+
1101+ zs.next_in = &zerostuff;
1102+ zs.avail_in = 1;
1103+ zresult = inflate(&zs, Z_FINISH);
1104+ }
1105+
1106+ inflateEnd(&zs);
1107+ if (zresult != Z_STREAM_END) {
1108+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
1109+ "klips_error:skb_decompress: "
1110+ "inflate() returned error %d (%s), "
1111+ "skipping decompression.\n",
1112+ zresult,
1113+ zs.msg ? zs.msg : zError(zresult));
1114+ *flags |= IPCOMP_DECOMPRESSIONERROR;
1115+#ifdef NET_21
1116+ kfree_skb(nskb);
1117+#else /* NET_21 */
1118+ dev_kfree_skb(nskb, FREE_WRITE);
1119+#endif /* NET_21 */
1120+
1121+ return skb;
1122+ }
1123+
1124+ /* Update IP header */
1125+ /* resulting decompressed size */
1126+ pyldsz -= zs.avail_out;
1127+ iph->tot_len = htons(iphlen + pyldsz);
1128+ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
1129+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
1130+ "klips_debug:skb_decompress: "
1131+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
1132+ tdb ? ntohl(tdb->tdb_said.spi) : 0,
1133+ tdb ? ntohl(tdb->tdb_said.spi) & 0x0000ffff : 0,
1134+ ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
1135+ cpyldsz,
1136+ pyldsz,
1137+ iph->protocol);
1138+
1139+#if 1 /* XXX checksum is done by ipsec_rcv ? */
1140+ iph->check = 0;
1141+ iph->check = ip_fast_csum((char*) iph, iph->ihl);
1142+#endif
1143+
1144+ /* Update skb length/tail by "unputting" the unused data area */
1145+ skb_put(nskb, -zs.avail_out);
1146+
1147+#ifdef NET_21
1148+ kfree_skb(skb);
1149+#else /* NET_21 */
1150+ dev_kfree_skb(skb, FREE_WRITE);
1151+#endif /* NET_21 */
1152+
1153+ if (iph->protocol == IPPROTO_COMP)
1154+ {
1155+#ifdef CONFIG_IPSEC_DEBUG
1156+ if(sysctl_ipsec_debug_ipcomp)
1157+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
1158+ "klips_debug:skb_decompress: "
1159+ "Eh? inner packet is also compressed, dropping.\n");
1160+#endif /* CONFIG_IPSEC_DEBUG */
1161+
1162+#ifdef NET_21
1163+ kfree_skb(nskb);
1164+#else /* NET_21 */
1165+ dev_kfree_skb(nskb, FREE_WRITE);
1166+#endif /* NET_21 */
1167+ return NULL;
1168+ }
1169+
1170+#ifdef CONFIG_IPSEC_DEBUG
1171+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
1172+ __u8 *c;
1173+ int i;
1174+
1175+ c = (__u8*)iph + iphlen;
1176+ for(i = 0; i < pyldsz; i++, c++) {
1177+ if(!(i % 16)) {
1178+ printk(KERN_INFO "skb_decompress: result:");
1179+ }
1180+ printk("%02x ", *c);
1181+ if(!((i + 1) % 16)) {
1182+ printk("\n");
1183+ }
1184+ }
1185+ if(i % 16) {
1186+ printk("\n");
1187+ }
1188+ }
1189+#endif /* CONFIG_IPSEC_DEBUG */
1190+
1191+ return nskb;
1192+}
1193+
1194+
1195+/* this is derived from skb_copy() in linux 2.2.14 */
1196+/* May be incompatible with other kernel versions!! */
1197+static
1198+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
1199+{
1200+ struct sk_buff *n;
1201+ struct iphdr *iph;
1202+ unsigned long offset;
1203+ unsigned int iphlen;
1204+
1205+ if(!skb) {
1206+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
1207+ "klips_debug:skb_copy_ipcomp: "
1208+ "passed in NULL skb, returning NULL.\n");
1209+ return NULL;
1210+ }
1211+
1212+ /*
1213+ * Allocate the copy buffer
1214+ */
1215+
1216+#ifdef NET_21
1217+ iph = skb->nh.iph;
1218+#else /* NET_21 */
1219+ iph = skb->ip_hdr;
1220+#endif /* NET_21 */
1221+ if (!iph) return NULL;
1222+ iphlen = iph->ihl << 2;
1223+
1224+ n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
1225+ if(n==NULL)
1226+ return NULL;
1227+
1228+ /*
1229+ * Shift between the two data areas in bytes
1230+ */
1231+
1232+ offset=n->head-skb->head;
1233+
1234+ /* Set the data pointer */
1235+ skb_reserve(n,skb->data-skb->head);
1236+ /* Set the tail pointer and length */
1237+ skb_put(n,skb->len+data_growth);
1238+ /* Copy the bytes up to and including the ip header */
1239+ memcpy(n->head,
1240+ skb->head,
1241+ ((char *)iph - (char *)skb->head) + iphlen);
1242+ n->list=NULL;
1243+ n->next=NULL;
1244+ n->prev=NULL;
1245+ n->sk=NULL;
1246+ n->dev=skb->dev;
1247+ if (skb->h.raw)
1248+ n->h.raw=skb->h.raw+offset;
1249+ else
1250+ n->h.raw=NULL;
1251+ n->protocol=skb->protocol;
1252+#ifdef NET_21
1253+ n->csum = 0;
1254+ n->priority=skb->priority;
1255+ n->dst=dst_clone(skb->dst);
1256+ n->nh.raw=skb->nh.raw+offset;
1257+ n->is_clone=0;
1258+ atomic_set(&n->users, 1);
1259+ n->destructor = NULL;
1260+ n->security=skb->security;
1261+ memcpy(n->cb, skb->cb, sizeof(skb->cb));
1262+#ifdef CONFIG_IP_FIREWALL
1263+ n->fwmark = skb->fwmark;
1264+#endif
1265+#else /* NET_21 */
1266+ n->link3=NULL;
1267+ n->when=skb->when;
1268+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
1269+ n->saddr=skb->saddr;
1270+ n->daddr=skb->daddr;
1271+ n->raddr=skb->raddr;
1272+ n->seq=skb->seq;
1273+ n->end_seq=skb->end_seq;
1274+ n->ack_seq=skb->ack_seq;
1275+ n->acked=skb->acked;
1276+ n->free=1;
1277+ n->arp=skb->arp;
1278+ n->tries=0;
1279+ n->lock=0;
1280+ n->users=0;
1281+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
1282+#endif /* NET_21 */
1283+ if (skb->mac.raw)
1284+ n->mac.raw=skb->mac.raw+offset;
1285+ else
1286+ n->mac.raw=NULL;
1287+ n->used=skb->used;
1288+ n->pkt_type=skb->pkt_type;
1289+ n->pkt_bridged=skb->pkt_bridged;
1290+ n->ip_summed=0;
1291+ n->stamp=skb->stamp;
1292+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
1293+ n->shapelatency=skb->shapelatency; /* Latency on frame */
1294+ n->shapeclock=skb->shapeclock; /* Time it should go out */
1295+ n->shapelen=skb->shapelen; /* Frame length in clocks */
1296+ n->shapestamp=skb->shapestamp; /* Stamp for shaper */
1297+ n->shapepend=skb->shapepend; /* Pending */
1298+#endif
1299+#ifdef CONFIG_HIPPI
1300+ n->private.ifield=skb->private.ifield;
1301+#endif
1302+
1303+ return n;
1304+}
1305diff -druN linux-noipsec/net/ipsec/ipcomp.h linux/net/ipsec/ipcomp.h
1306--- linux-noipsec/net/ipsec/ipcomp.h Thu Jan 1 01:00:00 1970
1307+++ linux/net/ipsec/ipcomp.h Mon Nov 6 05:30:40 2000
1308@@ -0,0 +1,59 @@
1309+/*
1310+ * IPCOMP zlib interface code.
1311+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
1312+ * Copyright (C) 2000 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
1313+ *
1314+ * This program is free software; you can redistribute it and/or modify it
1315+ * under the terms of the GNU General Public License as published by the
1316+ * Free Software Foundation; either version 2 of the License, or (at your
1317+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
1318+ *
1319+ * This program is distributed in the hope that it will be useful, but
1320+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1321+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1322+ * for more details.
1323+
1324+ RCSID $Id$
1325+
1326+ */
1327+
1328+/* SSS */
1329+
1330+#ifndef _IPCOMP_H
1331+#define _IPCOMP_H
1332+
1333+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
1334+#define IPCOMP_PREFIX
1335+
1336+#ifndef IPPROTO_COMP
1337+#define IPPROTO_COMP 108
1338+#endif /* IPPROTO_COMP */
1339+
1340+#ifdef CONFIG_IPSEC_DEBUG
1341+extern int sysctl_ipsec_debug_ipcomp;
1342+#endif /* CONFIG_IPSEC_DEBUG */
1343+
1344+struct ipcomphdr { /* IPCOMP header */
1345+ __u8 ipcomp_nh; /* Next header (protocol) */
1346+ __u8 ipcomp_flags; /* Reserved, must be 0 */
1347+ __u16 ipcomp_cpi; /* Compression Parameter Index */
1348+};
1349+
1350+extern struct inet_protocol comp_protocol;
1351+extern int sysctl_ipsec_debug_ipcomp;
1352+
1353+#define IPCOMP_UNCOMPRESSABLE 0x000000001
1354+#define IPCOMP_COMPRESSIONERROR 0x000000002
1355+#define IPCOMP_PARMERROR 0x000000004
1356+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
1357+
1358+#define IPCOMP_ADAPT_INITIAL_TRIES 8
1359+#define IPCOMP_ADAPT_INITIAL_SKIP 4
1360+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
1361+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
1362+
1363+/* Function prototypes */
1364+struct sk_buff *skb_compress(struct sk_buff *skb, struct tdb *tdb, unsigned int *flags);
1365+struct sk_buff *skb_decompress(struct sk_buff *skb, struct tdb *tdb, unsigned int *flags);
1366+
1367+#endif /* _IPCOMP_H */
1368diff -druN linux-noipsec/net/ipsec/ipsec_ah.h linux/net/ipsec/ipsec_ah.h
1369--- linux-noipsec/net/ipsec/ipsec_ah.h Thu Jan 1 01:00:00 1970
1370+++ linux/net/ipsec/ipsec_ah.h Tue Sep 12 05:21:20 2000
1371@@ -0,0 +1,232 @@
1372+/*
1373+ * Authentication Header declarations
1374+ * Copyright (C) 1996, 1997 John Ioannidis.
1375+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
1376+ *
1377+ * This program is free software; you can redistribute it and/or modify it
1378+ * under the terms of the GNU General Public License as published by the
1379+ * Free Software Foundation; either version 2 of the License, or (at your
1380+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
1381+ *
1382+ * This program is distributed in the hope that it will be useful, but
1383+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1384+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1385+ * for more details.
1386+ *
1387+ * RCSID $Id$
1388+ */
1389+
1390+#include "ipsec_md5h.h"
1391+#include "ipsec_sha1.h"
1392+
1393+#ifndef IPPROTO_AH
1394+#define IPPROTO_AH 51
1395+#endif /* IPPROTO_AH */
1396+
1397+#define AH_FLENGTH 12 /* size of fixed part */
1398+#define AHMD5_KMAX 64 /* MD5 max 512 bits key */
1399+#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */
1400+
1401+#define AHMD596_KLEN 16 /* MD5 128 bits key */
1402+#define AHSHA196_KLEN 20 /* SHA1 160 bits key */
1403+
1404+#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */
1405+#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */
1406+
1407+#define AHMD596_BLKLEN 64 /* MD5 block length */
1408+#define AHSHA196_BLKLEN 64 /* SHA1 block length */
1409+
1410+#define AH_AMAX AHSHA196_ALEN /* keep up to date! */
1411+#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */
1412+#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */
1413+
1414+#define DB_AH_PKTRX 0x0001
1415+#define DB_AH_PKTRX2 0x0002
1416+#define DB_AH_DMP 0x0004
1417+#define DB_AH_TDB 0x0010
1418+#define DB_AH_XF 0x0020
1419+#define DB_AH_INAU 0x0040
1420+#define DB_AH_REPLAY 0x0100
1421+
1422+struct ahmd5_xdata /* transform table data */
1423+{
1424+ __u16 amx_klen; /* Key material length */
1425+ __u16 amx_alen; /* authenticator length */
1426+ __u8 amx_key[AHMD5_KMAX]; /* Key material */
1427+};
1428+
1429+struct ahhmacmd5_edata /* struct for netlink interface */
1430+{
1431+ __u16 ame_klen; /* Key material length */
1432+ __u16 ame_alen; /* authenticator length */
1433+ __u8 ame_replayp; /* replay protection ? */
1434+ __u8 ame_ooowin; /* out-of-order window size */
1435+ __u16 ame_x0; /* filler */
1436+ __u8 ame_key[AHMD596_KLEN]; /* Key material */
1437+};
1438+
1439+struct ahhmacsha1_edata /* struct for netlink interface */
1440+{
1441+ __u16 ame_klen; /* Key material length */
1442+ __u16 ame_alen; /* authenticator length */
1443+ __u8 ame_replayp; /* replay protection ? */
1444+ __u8 ame_ooowin; /* out-of-order window size */
1445+ __u16 ame_x0; /* filler */
1446+ __u8 ame_key[AHSHA196_KLEN]; /* Key material */
1447+};
1448+
1449+#ifdef __KERNEL__
1450+
1451+/* General HMAC algorithm is described in RFC 2104 */
1452+
1453+#define HMAC_IPAD 0x36
1454+#define HMAC_OPAD 0x5C
1455+
1456+struct ahhmacmd5_xdata /* struct for xform table */
1457+{
1458+ __u16 amx_alen; /* length of authenticator, octets */
1459+ __u8 amx_replayp; /* 1 if replay prevention active */
1460+ __u8 amx_ooowin; /* out-of-order window size */
1461+ __u64 amx_bitmap; /* this&next should be 8 bytes each */
1462+ __u32 amx_lastseq; /* or just seq if sending!! */
1463+ MD5_CTX amx_octx; /* context after H(K XOR opad) */
1464+ MD5_CTX amx_ictx; /* context after H(K XOR ipad) */
1465+};
1466+
1467+struct ahhmacsha1_xdata /* struct for xform table */
1468+{
1469+ __u16 amx_alen; /* length of authenticator, octets */
1470+ __u8 amx_replayp; /* 1 if replay prevention active */
1471+ __u8 amx_ooowin; /* out-of-order window size */
1472+ __u64 amx_bitmap; /* this&next should be 8 bytes each */
1473+ __u32 amx_lastseq; /* or just seq if sending!! */
1474+ SHA1_CTX amx_octx; /* context after H(K XOR opad) */
1475+ SHA1_CTX amx_ictx; /* context after H(K XOR ipad) */
1476+};
1477+
1478+struct md5_ctx {
1479+ MD5_CTX ictx; /* context after H(K XOR ipad) */
1480+ MD5_CTX octx; /* context after H(K XOR opad) */
1481+};
1482+
1483+struct sha1_ctx {
1484+ SHA1_CTX ictx; /* context after H(K XOR ipad) */
1485+ SHA1_CTX octx; /* context after H(K XOR opad) */
1486+};
1487+
1488+extern struct inet_protocol ah_protocol;
1489+
1490+struct options;
1491+
1492+extern int
1493+ah_rcv(struct sk_buff *skb,
1494+ struct device *dev,
1495+ struct options *opt,
1496+ __u32 daddr,
1497+ unsigned short len,
1498+ __u32 saddr,
1499+ int redo,
1500+ struct inet_protocol *protocol);
1501+
1502+struct ah /* Generic AH header */
1503+{
1504+ __u8 ah_nh; /* Next header (protocol) */
1505+ __u8 ah_hl; /* AH length, in 32-bit words */
1506+ __u16 ah_rv; /* reserved, must be 0 */
1507+ __u32 ah_spi; /* Security Parameters Index */
1508+ __u32 ah_rpl; /* Replay prevention */
1509+ __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */
1510+};
1511+
1512+#ifdef CONFIG_IPSEC_DEBUG
1513+extern int debug_ah;
1514+#endif /* CONFIG_IPSEC_DEBUG */
1515+#endif /* __KERNEL__ */
1516+
1517+#ifdef CONFIG_IPSEC_DEBUG
1518+#define AHPRINTKEYS_
1519+#endif /* CONFIG_IPSEC_DEBUG */
1520+
1521+/*
1522+ * $Log$
1523+ * Revision 1.12 2000/09/12 03:21:20 rgb
1524+ * Cleared out unused htonq.
1525+ *
1526+ * Revision 1.11 2000/09/08 19:12:55 rgb
1527+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
1528+ *
1529+ * Revision 1.10 2000/01/21 06:13:10 rgb
1530+ * Tidied up spacing.
1531+ * Added macros for HMAC padding magic numbers.(kravietz)
1532+ *
1533+ * Revision 1.9 1999/12/07 18:16:23 rgb
1534+ * Fixed comments at end of #endif lines.
1535+ *
1536+ * Revision 1.8 1999/04/11 00:28:56 henry
1537+ * GPL boilerplate
1538+ *
1539+ * Revision 1.7 1999/04/06 04:54:25 rgb
1540+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
1541+ * patch shell fixes.
1542+ *
1543+ * Revision 1.6 1999/01/26 02:06:01 rgb
1544+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
1545+ *
1546+ * Revision 1.5 1999/01/22 06:17:49 rgb
1547+ * Updated macro comments.
1548+ * Added context types to support algorithm switch code.
1549+ * 64-bit clean-up -- converting 'u long long' to __u64.
1550+ *
1551+ * Revision 1.4 1998/07/14 15:54:56 rgb
1552+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
1553+ *
1554+ * Revision 1.3 1998/06/30 18:05:16 rgb
1555+ * Comment out references to htonq.
1556+ *
1557+ * Revision 1.2 1998/06/25 19:33:46 rgb
1558+ * Add prototype for protocol receive function.
1559+ * Rearrange for more logical layout.
1560+ *
1561+ * Revision 1.1 1998/06/18 21:27:43 henry
1562+ * move sources from klips/src to klips/net/ipsec, to keep stupid
1563+ * kernel-build scripts happier in the presence of symlinks
1564+ *
1565+ * Revision 1.4 1998/05/18 22:28:43 rgb
1566+ * Disable key printing facilities from /proc/net/ipsec_*.
1567+ *
1568+ * Revision 1.3 1998/04/21 21:29:07 rgb
1569+ * Rearrange debug switches to change on the fly debug output from user
1570+ * space. Only kernel changes checked in at this time. radij.c was also
1571+ * changed to temporarily remove buggy debugging code in rj_delete causing
1572+ * an OOPS and hence, netlink device open errors.
1573+ *
1574+ * Revision 1.2 1998/04/12 22:03:17 rgb
1575+ * Updated ESP-3DES-HMAC-MD5-96,
1576+ * ESP-DES-HMAC-MD5-96,
1577+ * AH-HMAC-MD5-96,
1578+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
1579+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
1580+ *
1581+ * Fixed eroute references in /proc/net/ipsec*.
1582+ *
1583+ * Started to patch module unloading memory leaks in ipsec_netlink and
1584+ * radij tree unloading.
1585+ *
1586+ * Revision 1.1 1998/04/09 03:05:55 henry
1587+ * sources moved up from linux/net/ipsec
1588+ *
1589+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
1590+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
1591+ *
1592+ * Revision 0.4 1997/01/15 01:28:15 ji
1593+ * Added definitions for new AH transforms.
1594+ *
1595+ * Revision 0.3 1996/11/20 14:35:48 ji
1596+ * Minor Cleanup.
1597+ * Rationalized debugging code.
1598+ *
1599+ * Revision 0.2 1996/11/02 00:18:33 ji
1600+ * First limited release.
1601+ *
1602+ *
1603+ */
1604diff -druN linux-noipsec/net/ipsec/ipsec_encap.h linux/net/ipsec/ipsec_encap.h
1605--- linux-noipsec/net/ipsec/ipsec_encap.h Thu Jan 1 01:00:00 1970
1606+++ linux/net/ipsec/ipsec_encap.h Fri Sep 8 21:12:56 2000
1607@@ -0,0 +1,168 @@
1608+/*
1609+ * declarations relevant to encapsulation-like operations
1610+ * Copyright (C) 1996, 1997 John Ioannidis.
1611+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
1612+ *
1613+ * This program is free software; you can redistribute it and/or modify it
1614+ * under the terms of the GNU General Public License as published by the
1615+ * Free Software Foundation; either version 2 of the License, or (at your
1616+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
1617+ *
1618+ * This program is distributed in the hope that it will be useful, but
1619+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1620+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1621+ * for more details.
1622+ *
1623+ * RCSID $Id$
1624+ */
1625+
1626+#define SENT_IP4 0x0008 /* data is two struct in_addr */
1627+
1628+#define SEN_HDRLEN (2*sizeof(__u8)+sizeof(__u16))
1629+
1630+#define SEN_IP4_SRCOFF (0)
1631+#define SEN_IP4_DSTOFF (sizeof (struct in_addr))
1632+#define SEN_IP4_OPTOFF (2 * sizeof (struct in_addr))
1633+
1634+#define SEN_IP4_LEN (SENT_HDRLEN + SENT_IP4_OPTOFF)
1635+
1636+#ifdef CONFIG_IPSEC_DEBUG
1637+#define DB_ER_PROCFS 0x0001
1638+#define DB_SP_PROCFS 0x0001
1639+#endif /* CONFIG_IPSEC_DEBUG */
1640+
1641+struct sockaddr_encap
1642+{
1643+ __u8 sen_len; /* length */
1644+ __u8 sen_family; /* AF_ENCAP */
1645+ __u16 sen_type; /* see SENT_* */
1646+ union
1647+ {
1648+ struct /* SENT_IP4 */
1649+ {
1650+ struct in_addr Src;
1651+ struct in_addr Dst;
1652+ } Sip4;
1653+ } Sen;
1654+};
1655+
1656+#define sen_ip_src Sen.Sip4.Src
1657+#define sen_ip_dst Sen.Sip4.Dst
1658+
1659+#ifndef AF_ENCAP
1660+#define AF_ENCAP 26
1661+#endif /* AF_ENCAP */
1662+
1663+/*
1664+ * The "type" is really part of the address as far as the routing
1665+ * system is concerned. By using only one bit in the type field
1666+ * for each type, we sort-of make sure that different types of
1667+ * encapsulation addresses won't be matched against the wrong type.
1668+ */
1669+
1670+#ifdef __KERNEL__
1671+/*
1672+ * An entry in the radix tree
1673+ */
1674+
1675+struct rjtentry
1676+{
1677+ struct radij_node rd_nodes[2]; /* tree glue, and other values */
1678+#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
1679+#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
1680+ short rd_flags;
1681+ short rd_count;
1682+};
1683+
1684+/*
1685+ * An encapsulation route consists of a pointer to a
1686+ * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
1687+ */
1688+
1689+struct
1690+eroute
1691+{
1692+ struct rjtentry er_rjt;
1693+ struct sa_id er_said;
1694+ struct sockaddr_encap er_eaddr;
1695+ struct sockaddr_encap er_emask;
1696+};
1697+
1698+#define er_dst er_said.dst
1699+#define er_spi er_said.spi
1700+#define er_proto er_said.proto
1701+#ifdef CONFIG_IPSEC_DEBUG
1702+extern int debug_eroute;
1703+extern int debug_spi;
1704+#endif /* CONFIG_IPSEC_DEBUG */
1705+
1706+#ifdef NETDEV_23
1707+#define device net_device
1708+#define ipsec_dev_get __dev_get_by_name
1709+#else
1710+#define ipsec_dev_get dev_get
1711+#endif /* NETDEV_23 */
1712+#endif /* __KERNEL__ */
1713+
1714+/*
1715+ * $Log$
1716+ * Revision 1.11 2000/09/08 19:12:56 rgb
1717+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
1718+ *
1719+ * Revision 1.10 2000/03/22 16:15:36 rgb
1720+ * Fixed renaming of dev_get (MB).
1721+ *
1722+ * Revision 1.9 2000/01/21 06:13:26 rgb
1723+ * Added a macro for AF_ENCAP
1724+ *
1725+ * Revision 1.8 1999/12/31 14:56:55 rgb
1726+ * MB fix for 2.3 dev-use-count.
1727+ *
1728+ * Revision 1.7 1999/11/18 04:09:18 rgb
1729+ * Replaced all kernel version macros to shorter, readable form.
1730+ *
1731+ * Revision 1.6 1999/09/24 00:34:13 rgb
1732+ * Add Marc Boucher's support for 2.3.xx+.
1733+ *
1734+ * Revision 1.5 1999/04/11 00:28:57 henry
1735+ * GPL boilerplate
1736+ *
1737+ * Revision 1.4 1999/04/06 04:54:25 rgb
1738+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
1739+ * patch shell fixes.
1740+ *
1741+ * Revision 1.3 1998/10/19 14:44:28 rgb
1742+ * Added inclusion of freeswan.h.
1743+ * sa_id structure implemented and used: now includes protocol.
1744+ *
1745+ * Revision 1.2 1998/07/14 18:19:33 rgb
1746+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
1747+ *
1748+ * Revision 1.1 1998/06/18 21:27:44 henry
1749+ * move sources from klips/src to klips/net/ipsec, to keep stupid
1750+ * kernel-build scripts happier in the presence of symlinks
1751+ *
1752+ * Revision 1.2 1998/04/21 21:29:10 rgb
1753+ * Rearrange debug switches to change on the fly debug output from user
1754+ * space. Only kernel changes checked in at this time. radij.c was also
1755+ * changed to temporarily remove buggy debugging code in rj_delete causing
1756+ * an OOPS and hence, netlink device open errors.
1757+ *
1758+ * Revision 1.1 1998/04/09 03:05:58 henry
1759+ * sources moved up from linux/net/ipsec
1760+ *
1761+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
1762+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
1763+ *
1764+ * Revision 0.4 1997/01/15 01:28:15 ji
1765+ * Minor cosmetic changes.
1766+ *
1767+ * Revision 0.3 1996/11/20 14:35:48 ji
1768+ * Minor Cleanup.
1769+ * Rationalized debugging code.
1770+ *
1771+ * Revision 0.2 1996/11/02 00:18:33 ji
1772+ * First limited release.
1773+ *
1774+ *
1775+ */
1776diff -druN linux-noipsec/net/ipsec/ipsec_esp.h linux/net/ipsec/ipsec_esp.h
1777--- linux-noipsec/net/ipsec/ipsec_esp.h Thu Jan 1 01:00:00 1970
1778+++ linux/net/ipsec/ipsec_esp.h Fri Sep 8 21:12:56 2000
1779@@ -0,0 +1,257 @@
1780+/*
1781+ * Copyright (C) 1996, 1997 John Ioannidis.
1782+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
1783+ *
1784+ * This program is free software; you can redistribute it and/or modify it
1785+ * under the terms of the GNU General Public License as published by the
1786+ * Free Software Foundation; either version 2 of the License, or (at your
1787+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
1788+ *
1789+ * This program is distributed in the hope that it will be useful, but
1790+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1791+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1792+ * for more details.
1793+ *
1794+ * RCSID $Id$
1795+ */
1796+
1797+#include "ipsec_md5h.h"
1798+#include "ipsec_sha1.h"
1799+
1800+#ifndef IPPROTO_ESP
1801+#define IPPROTO_ESP 50
1802+#endif /* IPPROTO_ESP */
1803+
1804+#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */
1805+#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */
1806+#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */
1807+#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */
1808+#define EMT_ESPDES_IV_SZ 8 /* IV size */
1809+#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */
1810+
1811+#define DB_ES_PKTRX 0x0001
1812+#define DB_ES_PKTRX2 0x0002
1813+#define DB_ES_TDB 0x0010
1814+#define DB_ES_XF 0x0020
1815+#define DB_ES_IPAD 0x0040
1816+#define DB_ES_INAU 0x0080
1817+#define DB_ES_OINFO 0x0100
1818+#define DB_ES_OINFO2 0x0200
1819+#define DB_ES_OH 0x0400
1820+#define DB_ES_REPLAY 0x0800
1821+
1822+struct espblkrply_edata
1823+{
1824+ __u16 eme_klen; /* encryption key length */
1825+ __u16 ame_klen; /* authentication key length */
1826+ __u16 eme_flags; /* see below */
1827+ __u16 eme_ooowin; /* out-of-order window size */
1828+#if 1
1829+ __u16 eme_ivlen; /* IV length */
1830+ __u16 filler;
1831+ union
1832+ {
1833+ __u8 Iv[8]; /* that's enough space */
1834+ __u32 Ivl[2];
1835+ __u64 Ivq;
1836+ }Iu;
1837+#define eme_iv Iu.Iv
1838+#define eme_ivl Iu.Ivl
1839+#define eme_ivq Iu.Ivq
1840+#endif
1841+ __u8 eme_key[EMT_ESPDES_KMAX]; /* the encryption raw key */
1842+ __u8 ame_key[AH_AMAX]; /* the authentication raw key */
1843+};
1844+
1845+#ifdef __KERNEL__
1846+struct esp3desmd5_xdata
1847+{
1848+ __u8 edmx_flags; /* same as before */
1849+ __u8 edmx_ooowin; /* out-of-order window size */
1850+ __u16 edmx_ivlen; /* IV length */
1851+ __u32 edmx_bitmap; /* this&next should be 4 bytes each */
1852+ __u32 edmx_lastseq; /* in host order */
1853+ __u32 edmx_eks1[16][2]; /* the first key schedule */
1854+ __u32 edmx_eks2[16][2]; /* the second key schedule */
1855+ __u32 edmx_eks3[16][2]; /* the third key schedule */
1856+ __u32 edmx_iv[2]; /* constant IV */
1857+ MD5_CTX edmx_ictx; /* derived from HMAC_key */
1858+ MD5_CTX edmx_octx; /* ditto */
1859+};
1860+
1861+struct espnullmd5_xdata
1862+{
1863+ __u8 edmx_flags; /* same as before */
1864+ __u8 edmx_ooowin; /* out-of-order window size */
1865+ __u32 edmx_bitmap; /* this&next should be 4 bytes each */
1866+ __u32 edmx_lastseq; /* in host order */
1867+ MD5_CTX edmx_ictx; /* derived from HMAC_key */
1868+ MD5_CTX edmx_octx; /* ditto */
1869+};
1870+
1871+struct esp3dessha1_xdata
1872+{
1873+ __u8 edmx_flags; /* same as before */
1874+ __u8 edmx_ooowin; /* out-of-order window size */
1875+ __u16 edmx_ivlen; /* IV length */
1876+ __u32 edmx_bitmap; /* this&next should be 4 bytes each */
1877+ __u32 edmx_lastseq; /* in host order */
1878+ __u32 edmx_eks1[16][2]; /* the first key schedule */
1879+ __u32 edmx_eks2[16][2]; /* the second key schedule */
1880+ __u32 edmx_eks3[16][2]; /* the third key schedule */
1881+ __u32 edmx_iv[2]; /* constant IV */
1882+ SHA1_CTX edmx_ictx; /* derived from HMAC_key */
1883+ SHA1_CTX edmx_octx; /* ditto */
1884+};
1885+
1886+struct espnullsha1_xdata
1887+{
1888+ __u8 edmx_flags; /* same as before */
1889+ __u8 edmx_ooowin; /* out-of-order window size */
1890+ __u32 edmx_bitmap; /* this&next should be 4 bytes each */
1891+ __u32 edmx_lastseq; /* in host order */
1892+ SHA1_CTX edmx_ictx; /* derived from HMAC_key */
1893+ SHA1_CTX edmx_octx; /* ditto */
1894+};
1895+
1896+struct esp3des_xdata
1897+{
1898+ __u8 edmx_flags; /* same as before */
1899+ __u8 edmx_ooowin; /* out-of-order window size */
1900+ __u16 edmx_ivlen; /* IV length */
1901+ __u32 edmx_bitmap; /* this&next should be 4 bytes each */
1902+ __u32 edmx_lastseq; /* in host order */
1903+ __u32 edmx_eks1[16][2]; /* the first key schedule */
1904+ __u32 edmx_eks2[16][2]; /* the second key schedule */
1905+ __u32 edmx_eks3[16][2]; /* the third key schedule */
1906+ __u32 edmx_iv[2]; /* constant IV */
1907+};
1908+
1909+struct des_eks {
1910+ __u32 eks[16][2]; /* the key schedule */
1911+};
1912+
1913+extern struct inet_protocol esp_protocol;
1914+
1915+struct options;
1916+
1917+extern int
1918+esp_rcv(struct sk_buff *skb,
1919+ struct device *dev,
1920+ struct options *opt,
1921+ __u32 daddr,
1922+ unsigned short len,
1923+ __u32 saddr,
1924+ int redo,
1925+ struct inet_protocol *protocol);
1926+
1927+struct esp
1928+{
1929+ __u32 esp_spi; /* Security Parameters Index */
1930+ __u32 esp_rpl; /* Replay counter */
1931+ __u8 esp_iv[8]; /* iv */
1932+};
1933+
1934+#ifdef CONFIG_IPSEC_DEBUG
1935+extern int debug_esp;
1936+#endif /* CONFIG_IPSEC_DEBUG */
1937+#endif /* __KERNEL__ */
1938+
1939+#ifdef CONFIG_IPSEC_DEBUG
1940+#define ESPPRINTKEYS_
1941+#endif /* CONFIG_IPSEC_DEBUG */
1942+
1943+/*
1944+ * $Log$
1945+ * Revision 1.13 2000/09/08 19:12:56 rgb
1946+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
1947+ *
1948+ * Revision 1.12 2000/08/01 14:51:50 rgb
1949+ * Removed _all_ remaining traces of DES.
1950+ *
1951+ * Revision 1.11 2000/01/10 16:36:20 rgb
1952+ * Ditch last of EME option flags, including initiator.
1953+ *
1954+ * Revision 1.10 1999/12/07 18:16:22 rgb
1955+ * Fixed comments at end of #endif lines.
1956+ *
1957+ * Revision 1.9 1999/04/11 00:28:57 henry
1958+ * GPL boilerplate
1959+ *
1960+ * Revision 1.8 1999/04/06 04:54:25 rgb
1961+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
1962+ * patch shell fixes.
1963+ *
1964+ * Revision 1.7 1999/01/26 02:06:00 rgb
1965+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
1966+ *
1967+ * Revision 1.6 1999/01/22 15:22:05 rgb
1968+ * Re-enable IV in the espblkrply_edata structure to avoid breaking pluto
1969+ * until pluto can be fixed properly.
1970+ *
1971+ * Revision 1.5 1999/01/22 06:18:16 rgb
1972+ * Updated macro comments.
1973+ * Added key schedule types to support algorithm switch code.
1974+ *
1975+ * Revision 1.4 1998/08/12 00:07:32 rgb
1976+ * Added data structures for new xforms: null, {,3}dessha1.
1977+ *
1978+ * Revision 1.3 1998/07/14 15:57:01 rgb
1979+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
1980+ *
1981+ * Revision 1.2 1998/06/25 19:33:46 rgb
1982+ * Add prototype for protocol receive function.
1983+ * Rearrange for more logical layout.
1984+ *
1985+ * Revision 1.1 1998/06/18 21:27:45 henry
1986+ * move sources from klips/src to klips/net/ipsec, to keep stupid
1987+ * kernel-build scripts happier in the presence of symlinks
1988+ *
1989+ * Revision 1.6 1998/06/05 02:28:08 rgb
1990+ * Minor comment fix.
1991+ *
1992+ * Revision 1.5 1998/05/27 22:34:00 rgb
1993+ * Changed structures to accomodate key separation.
1994+ *
1995+ * Revision 1.4 1998/05/18 22:28:43 rgb
1996+ * Disable key printing facilities from /proc/net/ipsec_*.
1997+ *
1998+ * Revision 1.3 1998/04/21 21:29:07 rgb
1999+ * Rearrange debug switches to change on the fly debug output from user
2000+ * space. Only kernel changes checked in at this time. radij.c was also
2001+ * changed to temporarily remove buggy debugging code in rj_delete causing
2002+ * an OOPS and hence, netlink device open errors.
2003+ *
2004+ * Revision 1.2 1998/04/12 22:03:20 rgb
2005+ * Updated ESP-3DES-HMAC-MD5-96,
2006+ * ESP-DES-HMAC-MD5-96,
2007+ * AH-HMAC-MD5-96,
2008+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
2009+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
2010+ *
2011+ * Fixed eroute references in /proc/net/ipsec*.
2012+ *
2013+ * Started to patch module unloading memory leaks in ipsec_netlink and
2014+ * radij tree unloading.
2015+ *
2016+ * Revision 1.1 1998/04/09 03:06:00 henry
2017+ * sources moved up from linux/net/ipsec
2018+ *
2019+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
2020+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
2021+ *
2022+ * Revision 0.5 1997/06/03 04:24:48 ji
2023+ * Added ESP-3DES-MD5-96 transform.
2024+ *
2025+ * Revision 0.4 1997/01/15 01:28:15 ji
2026+ * Added definitions for new ESP transforms.
2027+ *
2028+ * Revision 0.3 1996/11/20 14:35:48 ji
2029+ * Minor Cleanup.
2030+ * Rationalized debugging code.
2031+ *
2032+ * Revision 0.2 1996/11/02 00:18:33 ji
2033+ * First limited release.
2034+ *
2035+ *
2036+ */
2037diff -druN linux-noipsec/net/ipsec/ipsec_init.c linux/net/ipsec/ipsec_init.c
2038--- linux-noipsec/net/ipsec/ipsec_init.c Thu Jan 1 01:00:00 1970
2039+++ linux/net/ipsec/ipsec_init.c Wed Nov 29 21:14:06 2000
2040@@ -0,0 +1,1149 @@
2041+/*
2042+ * Initialization code, and /proc file system interface code.
2043+ * Copyright (C) 1996, 1997 John Ioannidis.
2044+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
2045+ *
2046+ * This program is free software; you can redistribute it and/or modify it
2047+ * under the terms of the GNU General Public License as published by the
2048+ * Free Software Foundation; either version 2 of the License, or (at your
2049+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2050+ *
2051+ * This program is distributed in the hope that it will be useful, but
2052+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2053+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2054+ * for more details.
2055+ */
2056+
2057+char ipsec_init_c_version[] = "RCSID $Id$";
2058+
2059+#include <linux/config.h>
2060+#include <linux/version.h>
2061+
2062+#include <linux/module.h>
2063+#include <linux/kernel.h> /* printk() */
2064+#include <linux/malloc.h> /* kmalloc() */
2065+#include <linux/errno.h> /* error codes */
2066+#include <linux/types.h> /* size_t */
2067+#include <linux/interrupt.h> /* mark_bh */
2068+
2069+#include <linux/netdevice.h> /* struct device, and other headers */
2070+#include <linux/etherdevice.h> /* eth_type_trans */
2071+#include <linux/ip.h> /* struct iphdr */
2072+#include <linux/in.h> /* struct sockaddr_in */
2073+#include <linux/skbuff.h>
2074+#include <freeswan.h>
2075+#ifdef SPINLOCK
2076+#ifdef SPINLOCK_23
2077+#include <linux/spinlock.h> /* *lock* */
2078+#else /* SPINLOCK_23 */
2079+#include <asm/spinlock.h> /* *lock* */
2080+#endif /* SPINLOCK_23 */
2081+#endif /* SPINLOCK */
2082+#ifdef NET_21
2083+#include <asm/uaccess.h>
2084+#include <linux/in6.h>
2085+#endif /* NET_21 */
2086+#include <asm/checksum.h>
2087+#include <net/ip.h>
2088+#ifdef CONFIG_PROC_FS
2089+#include <linux/proc_fs.h>
2090+#endif /* CONFIG_PROC_FS */
2091+#ifdef NETLINK_SOCK
2092+#include <linux/netlink.h>
2093+#else
2094+#include <net/netlink.h>
2095+#endif
2096+
2097+#include "radij.h"
2098+#include "ipsec_encap.h"
2099+#include "ipsec_radij.h"
2100+#include "ipsec_netlink.h"
2101+#include "ipsec_xform.h"
2102+#include "ipsec_tunnel.h"
2103+
2104+#include "version.c"
2105+
2106+#include "ipsec_rcv.h"
2107+#include "ipsec_ah.h"
2108+#include "ipsec_esp.h"
2109+
2110+#ifdef CONFIG_IPSEC_IPCOMP
2111+#include "ipcomp.h"
2112+#endif /* CONFIG_IPSEC_IPCOMP */
2113+
2114+#include <pfkeyv2.h>
2115+#include <pfkey.h>
2116+
2117+extern char *radij_c_version;
2118+
2119+#ifdef CONFIG_IPSEC_DEBUG
2120+int debug_eroute = 0;
2121+int debug_spi = 0;
2122+#endif /* CONFIG_IPSEC_DEBUG */
2123+
2124+#ifdef CONFIG_PROC_FS
2125+#ifndef PROC_FS_2325
2126+DEBUG_NO_STATIC
2127+#endif /* PROC_FS_2325 */
2128+int
2129+ipsec_eroute_get_info(char *buffer, char **start, off_t offset, int length
2130+#ifndef PROC_NO_DUMMY
2131+, int dummy
2132+#endif /* !PROC_NO_DUMMY */
2133+)
2134+{
2135+ struct wsbuf w = {buffer, length, offset, 0, 0, 0, 0};
2136+
2137+#ifdef CONFIG_IPSEC_DEBUG
2138+ if (debug_radij & DB_RJ_DUMPTREES)
2139+ rj_dumptrees(); /* XXXXXXXXX */
2140+#endif /* CONFIG_IPSEC_DEBUG */
2141+
2142+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2143+ "klips_debug:ipsec_eroute_get_info: buffer=0x%p,"
2144+ " *start=0x%x, offset=%d, length=%d\n",
2145+ buffer, (u_int)*start, (int)offset, length);
2146+
2147+ spin_lock_bh(&eroute_lock);
2148+
2149+ rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
2150+/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
2151+
2152+ spin_unlock_bh(&eroute_lock);
2153+
2154+ *start = buffer + (offset - w.begin); /* Start of wanted data */
2155+ w.len -= (offset - w.begin); /* Start slop */
2156+ if (w.len > length)
2157+ w.len = length;
2158+ return w.len;
2159+}
2160+
2161+#ifndef PROC_FS_2325
2162+DEBUG_NO_STATIC
2163+#endif /* PROC_FS_2325 */
2164+int
2165+ipsec_spi_get_info(char *buffer, char **start, off_t offset, int length
2166+#ifndef PROC_NO_DUMMY
2167+, int dummy
2168+#endif /* !PROC_NO_DUMMY */
2169+)
2170+{
2171+ int len = 0;
2172+ off_t pos = 0, begin = 0;
2173+ int i;
2174+ struct tdb *tdbp;
2175+ char sa[SATOA_BUF];
2176+ char buf_s[ADDRTOA_BUF];
2177+#if 0
2178+ char buf_d[ADDRTOA_BUF];
2179+#endif
2180+ size_t sa_len;
2181+
2182+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2183+ "klips_debug:ipsec_spi_get_info: buffer=0x%p,"
2184+ "*start=0x%x, offset=%d, length=%d\n",
2185+ buffer, (u_int)*start, (int)offset, length);
2186+
2187+ spin_lock_bh(&tdb_lock);
2188+
2189+ for (i = 0; i < TDB_HASHMOD; i++) {
2190+ for (tdbp = tdbh[i]; tdbp; tdbp = tdbp->tdb_hnext) {
2191+ sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
2192+ len += sprintf(buffer + len, "%s ", sa);
2193+ len += sprintf(buffer + len, "%s%s%s", TDB_XFORM_NAME(tdbp));
2194+ len += sprintf(buffer + len, ": dir=%s",
2195+ (tdbp->tdb_flags & EMT_INBOUND) ?
2196+ "in " : "out");
2197+#if 0
2198+ if((tdbp->tdb_said.proto == IPPROTO_IPIP) && tdbp->tdb_addr_s && tdbp->tdb_addr_d) {
2199+ addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr,
2200+ 0, buf_s, sizeof(buf_s));
2201+ addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr,
2202+ 0, buf_d, sizeof(buf_d));
2203+ len += sprintf(buffer + len, " %s -> %s",
2204+ buf_s, buf_d);
2205+ }
2206+#else
2207+ if(tdbp->tdb_addr_s) {
2208+ addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr,
2209+ 0, buf_s, sizeof(buf_s));
2210+ len += sprintf(buffer + len, " src=%s",
2211+ buf_s);
2212+ }
2213+#endif
2214+
2215+ if(tdbp->tdb_iv_bits) {
2216+ int j;
2217+ len += sprintf(buffer + len, " iv_bits=%dbits iv=0x",
2218+ tdbp->tdb_iv_bits);
2219+ for(j = 0; j < tdbp->tdb_iv_bits / 8; j++) {
2220+ len += sprintf(buffer + len, "%02x",
2221+ (__u32)((__u8*)(tdbp->tdb_iv))[j]);
2222+ }
2223+ }
2224+ if(tdbp->tdb_encalg || tdbp->tdb_authalg) {
2225+ if(tdbp->tdb_replaywin) {
2226+ len += sprintf(buffer + len, " ooowin=%d",
2227+ tdbp->tdb_replaywin);
2228+ }
2229+ if(tdbp->tdb_replaywin_errs) {
2230+ len += sprintf(buffer + len, " ooo_errs=%d",
2231+ tdbp->tdb_replaywin_errs);
2232+ }
2233+ if(tdbp->tdb_replaywin_lastseq) {
2234+ len += sprintf(buffer + len, " seq=%d",
2235+ tdbp->tdb_replaywin_lastseq);
2236+ }
2237+ if(tdbp->tdb_replaywin_bitmap) {
2238+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2239+ len += sprintf(buffer + len, " bit=0x%Lx",
2240+ tdbp->tdb_replaywin_bitmap);
2241+#else
2242+ len += sprintf(buffer + len, " bit=0x%x%08x",
2243+ (__u32)(tdbp->tdb_replaywin_bitmap >> 32),
2244+ (__u32)tdbp->tdb_replaywin_bitmap);
2245+#endif
2246+ }
2247+ if(tdbp->tdb_replaywin_maxdiff) {
2248+ len += sprintf(buffer + len, " max_seq_diff=%d",
2249+ tdbp->tdb_replaywin_maxdiff);
2250+ }
2251+ }
2252+ if(tdbp->tdb_flags & ~EMT_INBOUND) {
2253+ len += sprintf(buffer + len, " flags=0x%x",
2254+ tdbp->tdb_flags & ~EMT_INBOUND);
2255+ len += sprintf(buffer + len, "<");
2256+ /* flag printing goes here */
2257+ len += sprintf(buffer + len, ">");
2258+ }
2259+ if(tdbp->tdb_auth_bits) {
2260+ len += sprintf(buffer + len, " alen=%d",
2261+ tdbp->tdb_auth_bits);
2262+ }
2263+ if(tdbp->tdb_key_bits_a) {
2264+ len += sprintf(buffer + len, " aklen=%d",
2265+ tdbp->tdb_key_bits_a);
2266+ }
2267+ if(tdbp->tdb_auth_errs) {
2268+ len += sprintf(buffer + len, " auth_errs=%d",
2269+ tdbp->tdb_auth_errs);
2270+ }
2271+ if(tdbp->tdb_key_bits_e) {
2272+ len += sprintf(buffer + len, " eklen=%d",
2273+ tdbp->tdb_key_bits_e);
2274+ }
2275+ if(tdbp->tdb_encsize_errs) {
2276+ len += sprintf(buffer + len, " encr_size_errs=%d",
2277+ tdbp->tdb_encsize_errs);
2278+ }
2279+ if(tdbp->tdb_encpad_errs) {
2280+ len += sprintf(buffer + len, " encr_pad_errs=%d",
2281+ tdbp->tdb_encpad_errs);
2282+ }
2283+
2284+ len += sprintf(buffer + len, " life(c,s,h)=");
2285+ if(tdbp->tdb_lifetime_allocations_c > 1 ||
2286+ tdbp->tdb_lifetime_allocations_s ||
2287+ tdbp->tdb_lifetime_allocations_h) {
2288+ len += sprintf(buffer + len, "alloc(%d,%d,%d)",
2289+ (int)(jiffies - tdbp->tdb_lifetime_allocations_c),
2290+ tdbp->tdb_lifetime_allocations_s,
2291+ (int)tdbp->tdb_lifetime_allocations_h);
2292+ }
2293+ if(tdbp->tdb_lifetime_bytes_c ||
2294+ tdbp->tdb_lifetime_bytes_s ||
2295+ tdbp->tdb_lifetime_bytes_h) {
2296+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2297+ len += sprintf(buffer + len, "bytes(%Ld,%Ld,%Ld)",
2298+ tdbp->tdb_lifetime_bytes_c,
2299+ tdbp->tdb_lifetime_bytes_s,
2300+ tdbp->tdb_lifetime_bytes_h);
2301+#else /* XXX high 32 bits are not displayed */
2302+ len += sprintf(buffer + len, "bytes(%lu,%lu,%lu)",
2303+ (unsigned long)tdbp->tdb_lifetime_bytes_c,
2304+ (unsigned long)tdbp->tdb_lifetime_bytes_s,
2305+ (unsigned long)tdbp->tdb_lifetime_bytes_h);
2306+#endif
2307+
2308+ }
2309+ if(tdbp->tdb_lifetime_addtime_c ||
2310+ tdbp->tdb_lifetime_addtime_s ||
2311+ tdbp->tdb_lifetime_addtime_h) {
2312+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2313+ len += sprintf(buffer + len, "add(%Ld,%Ld,%Ld)",
2314+ jiffies / HZ - tdbp->tdb_lifetime_addtime_c,
2315+ tdbp->tdb_lifetime_addtime_s,
2316+ tdbp->tdb_lifetime_addtime_h);
2317+#else
2318+ len += sprintf(buffer + len, "add(%lu,%lu,%lu)",
2319+ jiffies / HZ - (unsigned long)tdbp->tdb_lifetime_addtime_c,
2320+ (unsigned long)tdbp->tdb_lifetime_addtime_s,
2321+ (unsigned long)tdbp->tdb_lifetime_addtime_h);
2322+#endif
2323+ }
2324+ if(tdbp->tdb_lifetime_usetime_c ||
2325+ tdbp->tdb_lifetime_usetime_s ||
2326+ tdbp->tdb_lifetime_usetime_h) {
2327+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2328+ len += sprintf(buffer + len, "use(%Ld,%Ld,%Ld)",
2329+ tdbp->tdb_lifetime_usetime_c ?
2330+ jiffies / HZ - tdbp->tdb_lifetime_usetime_c : 0,
2331+ tdbp->tdb_lifetime_usetime_s,
2332+ tdbp->tdb_lifetime_usetime_h);
2333+#else
2334+ len += sprintf(buffer + len, "use(%lu,%lu,%lu)",
2335+ tdbp->tdb_lifetime_usetime_c ?
2336+ jiffies / HZ - (unsigned long)tdbp->tdb_lifetime_usetime_c : 0,
2337+ (unsigned long)tdbp->tdb_lifetime_usetime_s,
2338+ (unsigned long)tdbp->tdb_lifetime_usetime_h);
2339+#endif
2340+ }
2341+ if(tdbp->tdb_lifetime_packets_c ||
2342+ tdbp->tdb_lifetime_packets_s ||
2343+ tdbp->tdb_lifetime_packets_h) {
2344+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2345+ len += sprintf(buffer + len, "packets(%Ld,%Ld,%Ld)",
2346+ tdbp->tdb_lifetime_packets_c,
2347+ tdbp->tdb_lifetime_packets_s,
2348+ tdbp->tdb_lifetime_packets_h);
2349+#else
2350+ len += sprintf(buffer + len, "packets(%lu,%lu,%lu)",
2351+ (unsigned long)tdbp->tdb_lifetime_packets_c,
2352+ (unsigned long)tdbp->tdb_lifetime_packets_s,
2353+ (unsigned long)tdbp->tdb_lifetime_packets_h);
2354+#endif
2355+ }
2356+
2357+ if(tdbp->tdb_lifetime_usetime_c) {
2358+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2359+ len += sprintf(buffer + len, " idle=%Ld",
2360+ jiffies / HZ - tdbp->tdb_lifetime_usetime_l);
2361+#else
2362+ len += sprintf(buffer + len, " idle=%lu",
2363+ jiffies / HZ - (unsigned long)tdbp->tdb_lifetime_usetime_l);
2364+#endif
2365+ }
2366+
2367+#ifdef CONFIG_IPSEC_IPCOMP
2368+ if(tdbp->tdb_said.proto == IPPROTO_COMP &&
2369+ (tdbp->tdb_comp_ratio_dbytes ||
2370+ tdbp->tdb_comp_ratio_cbytes)) {
2371+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
2372+ len += sprintf(buffer + len, " ratio=%Ld:%Ld",
2373+ tdbp->tdb_comp_ratio_dbytes,
2374+ tdbp->tdb_comp_ratio_cbytes);
2375+#else
2376+ len += sprintf(buffer + len, " ratio=%lu:%lu",
2377+ (unsigned long)tdbp->tdb_comp_ratio_dbytes,
2378+ (unsigned long)tdbp->tdb_comp_ratio_cbytes);
2379+#endif
2380+ }
2381+#endif /* CONFIG_IPSEC_IPCOMP */
2382+
2383+ len += sprintf(buffer + len, "\n");
2384+
2385+ pos = begin + len;
2386+ if(pos < offset) {
2387+ len = 0;
2388+ begin = pos;
2389+ }
2390+ if (pos > offset + length) {
2391+ goto done_spi_i;
2392+ }
2393+ }
2394+ }
2395+
2396+ done_spi_i:
2397+ spin_unlock_bh(&tdb_lock);
2398+
2399+ *start = buffer + (offset - begin); /* Start of wanted data */
2400+ len -= (offset - begin); /* Start slop */
2401+ if (len > length)
2402+ len = length;
2403+ return len;
2404+}
2405+
2406+#ifndef PROC_FS_2325
2407+DEBUG_NO_STATIC
2408+#endif /* PROC_FS_2325 */
2409+int
2410+ipsec_spigrp_get_info(char *buffer, char **start, off_t offset, int length
2411+#ifndef PROC_NO_DUMMY
2412+, int dummy
2413+#endif /* !PROC_NO_DUMMY */
2414+)
2415+{
2416+ int len = 0;
2417+ off_t pos = 0, begin = 0;
2418+ int i;
2419+ struct tdb *tdbp, *tdbp2;
2420+ char sa[SATOA_BUF];
2421+ size_t sa_len;
2422+
2423+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2424+ "klips_debug:ipsec_spigrp_get_info: buffer=0x%p,"
2425+ " *start=0x%x, offset=%d, length=%d\n",
2426+ buffer, (u_int)*start, (int)offset, length);
2427+
2428+ spin_lock_bh(&tdb_lock);
2429+
2430+ for (i = 0; i < TDB_HASHMOD; i++) {
2431+ for (tdbp = tdbh[i]; tdbp; tdbp = tdbp->tdb_hnext)
2432+ {
2433+ if(!tdbp->tdb_inext)
2434+ {
2435+ tdbp2 = tdbp;
2436+ while(tdbp2) {
2437+ sa_len = satoa(tdbp2->tdb_said, 0, sa, SATOA_BUF);
2438+ len += sprintf(buffer + len, "%s ",
2439+ sa);
2440+ tdbp2 = tdbp2->tdb_onext;
2441+ }
2442+ len += sprintf(buffer + len, "\n");
2443+ pos = begin + len;
2444+ if(pos < offset) {
2445+ len = 0;
2446+ begin = pos;
2447+ }
2448+ if (pos > offset + length) {
2449+ goto done_spigrp_i;
2450+ }
2451+ }
2452+ }
2453+ }
2454+
2455+ done_spigrp_i:
2456+ spin_unlock_bh(&tdb_lock);
2457+
2458+ *start = buffer + (offset - begin); /* Start of wanted data */
2459+ len -= (offset - begin); /* Start slop */
2460+ if (len > length)
2461+ len = length;
2462+ return len;
2463+}
2464+
2465+#ifndef PROC_FS_2325
2466+DEBUG_NO_STATIC
2467+#endif /* PROC_FS_2325 */
2468+int
2469+ipsec_tncfg_get_info(char *buffer, char **start, off_t offset, int length
2470+#ifndef PROC_NO_DUMMY
2471+, int dummy
2472+#endif /* !PROC_NO_DUMMY */
2473+)
2474+{
2475+ int len = 0;
2476+ off_t pos = 0, begin = 0;
2477+ int i;
2478+ char name[9];
2479+ struct device *dev, *privdev;
2480+ struct ipsecpriv *priv;
2481+
2482+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2483+ "klips_debug:ipsec_tncfg_get_info: buffer=0x%p,"
2484+ "*start=0x%x, offset=%d, length=%d\n",
2485+ buffer, (u_int)*start, (int)offset, length);
2486+
2487+ for(i = 0; i < IPSEC_NUM_IF; i++) {
2488+ sprintf(name, "ipsec%d", i);
2489+ dev = ipsec_dev_get(name);
2490+ if(dev) {
2491+ priv = (struct ipsecpriv *)(dev->priv);
2492+ len += sprintf(buffer + len, "%s",
2493+ dev->name);
2494+ if(priv) {
2495+ privdev = (struct device *)(priv->dev);
2496+ len += sprintf(buffer + len, " -> %s",
2497+ privdev ? privdev->name : "NULL");
2498+ len += sprintf(buffer + len, " mtu=%d -> %d",
2499+ /* priv */ dev->mtu, privdev ? privdev->mtu : 0);
2500+ } else {
2501+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2502+ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
2503+ dev->name);
2504+ }
2505+ len += sprintf(buffer + len, "\n");
2506+
2507+ pos = begin + len;
2508+ if(pos < offset) {
2509+ len = 0;
2510+ begin = pos;
2511+ }
2512+ else if (pos > offset + length) {
2513+ break;
2514+ }
2515+ }
2516+ }
2517+ *start = buffer + (offset - begin); /* Start of wanted data */
2518+ len -= (offset - begin); /* Start slop */
2519+ if (len > length)
2520+ len = length;
2521+ return len;
2522+}
2523+
2524+#ifndef PROC_FS_2325
2525+DEBUG_NO_STATIC
2526+#endif /* PROC_FS_2325 */
2527+int
2528+ipsec_version_get_info(char *buffer, char **start, off_t offset, int length
2529+#ifndef PROC_NO_DUMMY
2530+, int dummy
2531+#endif /* !PROC_NO_DUMMY */
2532+)
2533+{
2534+ int len = 0;
2535+ off_t begin = 0;
2536+
2537+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2538+ "klips_debug:ipsec_version_get_info: "
2539+ "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n",
2540+ buffer, (u_int)*start, (int)offset, length);
2541+
2542+ len += sprintf(buffer + len, "FreeS/WAN version: %s\n", freeswan_version);
2543+#if 0
2544+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2545+ "klips_debug:ipsec_version_get_info: "
2546+ "ipsec_init version: %s\n",
2547+ ipsec_init_c_version);
2548+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2549+ "klips_debug:ipsec_version_get_info: "
2550+ "ipsec_tunnel version: %s\n",
2551+ ipsec_tunnel_c_version);
2552+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2553+ "klips_debug:ipsec_version_get_info: "
2554+ "ipsec_netlink version: %s\n",
2555+ ipsec_netlink_c_version);
2556+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2557+ "klips_debug:ipsec_version_get_info: "
2558+ "radij_c_version: %s\n",
2559+ radij_c_version);
2560+#endif
2561+
2562+ *start = buffer + (offset - begin); /* Start of wanted data */
2563+ len -= (offset - begin); /* Start slop */
2564+ if (len > length)
2565+ len = length;
2566+ return len;
2567+}
2568+
2569+#ifdef CONFIG_IPSEC_DEBUG
2570+#ifndef PROC_FS_2325
2571+DEBUG_NO_STATIC
2572+#endif /* PROC_FS_2325 */
2573+int
2574+ipsec_klipsdebug_get_info(char *buffer, char **start, off_t offset, int length
2575+#ifndef PROC_NO_DUMMY
2576+, int dummy
2577+#endif /* !PROC_NO_DUMMY */
2578+)
2579+{
2580+ int len = 0;
2581+ off_t begin = 0;
2582+
2583+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
2584+ "klips_debug:ipsec_klipsdebug_get_info: buffer=0x%p,"
2585+ "*start=0x%x, offset=%d, length=%d\n",
2586+ buffer, (u_int)*start, (int)offset, length);
2587+
2588+ len += sprintf(buffer + len, "debug_tunnel=%08x.\n", debug_tunnel);
2589+ len += sprintf(buffer + len, "debug_netlink=%08x.\n", debug_netlink);
2590+ len += sprintf(buffer + len, "debug_xform=%08x.\n", debug_xform);
2591+ len += sprintf(buffer + len, "debug_eroute=%08x.\n", debug_eroute);
2592+ len += sprintf(buffer + len, "debug_spi=%08x.\n", debug_spi);
2593+ len += sprintf(buffer + len, "debug_radij=%08x.\n", debug_radij);
2594+ len += sprintf(buffer + len, "debug_esp=%08x.\n", debug_esp);
2595+ len += sprintf(buffer + len, "debug_ah=%08x.\n", debug_ah);
2596+ len += sprintf(buffer + len, "debug_rcv=%08x.\n", debug_rcv);
2597+ len += sprintf(buffer + len, "debug_pfkey=%08x.\n", debug_pfkey);
2598+
2599+ *start = buffer + (offset - begin); /* Start of wanted data */
2600+ len -= (offset - begin); /* Start slop */
2601+ if (len > length)
2602+ len = length;
2603+ return len;
2604+}
2605+#endif /* CONFIG_IPSEC_DEBUG */
2606+
2607+#ifndef PROC_FS_2325
2608+struct proc_dir_entry ipsec_eroute =
2609+{
2610+ 0,
2611+ 12, "ipsec_eroute",
2612+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
2613+ &proc_net_inode_operations,
2614+ ipsec_eroute_get_info,
2615+ NULL, NULL, NULL, NULL, NULL
2616+};
2617+
2618+struct proc_dir_entry ipsec_spi =
2619+{
2620+ 0,
2621+ 9, "ipsec_spi",
2622+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
2623+ &proc_net_inode_operations,
2624+ ipsec_spi_get_info,
2625+ NULL, NULL, NULL, NULL, NULL
2626+};
2627+
2628+struct proc_dir_entry ipsec_spigrp =
2629+{
2630+ 0,
2631+ 12, "ipsec_spigrp",
2632+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
2633+ &proc_net_inode_operations,
2634+ ipsec_spigrp_get_info,
2635+ NULL, NULL, NULL, NULL, NULL
2636+};
2637+
2638+struct proc_dir_entry ipsec_tncfg =
2639+{
2640+ 0,
2641+ 11, "ipsec_tncfg",
2642+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
2643+ &proc_net_inode_operations,
2644+ ipsec_tncfg_get_info,
2645+ NULL, NULL, NULL, NULL, NULL
2646+};
2647+
2648+struct proc_dir_entry ipsec_version =
2649+{
2650+ 0,
2651+ 13, "ipsec_version",
2652+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
2653+ &proc_net_inode_operations,
2654+ ipsec_version_get_info,
2655+ NULL, NULL, NULL, NULL, NULL
2656+};
2657+
2658+#ifdef CONFIG_IPSEC_DEBUG
2659+struct proc_dir_entry ipsec_klipsdebug =
2660+{
2661+ 0,
2662+ 16, "ipsec_klipsdebug",
2663+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
2664+ &proc_net_inode_operations,
2665+ ipsec_klipsdebug_get_info,
2666+ NULL, NULL, NULL, NULL, NULL
2667+};
2668+#endif /* CONFIG_IPSEC_DEBUG */
2669+#endif /* !PROC_FS_2325 */
2670+#endif /* CONFIG_PROC_FS */
2671+
2672+int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
2673+/*
2674+ * the following structure is required so that we receive
2675+ * event notifications when network devices are enabled and
2676+ * disabled (ifconfig up and down).
2677+ */
2678+static struct notifier_block ipsec_dev_notifier={
2679+ ipsec_device_event,
2680+ NULL,
2681+ 0
2682+};
2683+
2684+#ifdef CONFIG_SYSCTL
2685+extern int ipsec_sysctl_register(void);
2686+extern void ipsec_sysctl_unregister(void);
2687+#endif
2688+
2689+/* void */
2690+int
2691+ipsec_init(void)
2692+{
2693+ int error = 0;
2694+
2695+#ifdef CONFIG_PROC_FS
2696+# ifndef PROC_FS_2325
2697+# ifdef PROC_FS_21
2698+ proc_register(proc_net, &ipsec_eroute);
2699+ proc_register(proc_net, &ipsec_spi);
2700+ proc_register(proc_net, &ipsec_spigrp);
2701+ proc_register(proc_net, &ipsec_tncfg);
2702+ proc_register(proc_net, &ipsec_version);
2703+# ifdef CONFIG_IPSEC_DEBUG
2704+ proc_register(proc_net, &ipsec_klipsdebug);
2705+# endif /* CONFIG_IPSEC_DEBUG */
2706+# else /* PROC_FS_21 */
2707+ proc_register_dynamic(&proc_net, &ipsec_eroute);
2708+ proc_register_dynamic(&proc_net, &ipsec_spi);
2709+ proc_register_dynamic(&proc_net, &ipsec_spigrp);
2710+ proc_register_dynamic(&proc_net, &ipsec_tncfg);
2711+ proc_register_dynamic(&proc_net, &ipsec_version);
2712+# ifdef CONFIG_IPSEC_DEBUG
2713+ proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
2714+# endif /* CONFIG_IPSEC_DEBUG */
2715+# endif /* PROC_FS_21 */
2716+# else /* !PROC_FS_2325 */
2717+ proc_net_create ("ipsec_eroute", 0, ipsec_eroute_get_info);
2718+ proc_net_create ("ipsec_spi", 0, ipsec_spi_get_info);
2719+ proc_net_create ("ipsec_spigrp", 0, ipsec_spigrp_get_info);
2720+ proc_net_create ("ipsec_tncfg", 0, ipsec_tncfg_get_info);
2721+ proc_net_create ("ipsec_version", 0, ipsec_version_get_info);
2722+# ifdef CONFIG_IPSEC_DEBUG
2723+ proc_net_create ("ipsec_klipsdebug", 0, ipsec_klipsdebug_get_info);
2724+# endif /* CONFIG_IPSEC_DEBUG */
2725+# endif /* !PROC_FS_2325 */
2726+#endif /* CONFIG_PROC_FS */
2727+
2728+ printk("klips_debug:ipsec_init: ipsec module loading. freeswan version: %s\n",
2729+ freeswan_version);
2730+
2731+#ifndef SPINLOCK
2732+ tdb_lock.lock = 0;
2733+ eroute_lock.lock = 0;
2734+#endif /* !SPINLOCK */
2735+
2736+ error |= ipsec_tdbinit();
2737+ error |= ipsec_radijinit();
2738+
2739+ error |= pfkey_init();
2740+
2741+ register_netdevice_notifier(&ipsec_dev_notifier);
2742+
2743+#ifdef CONFIG_IPSEC_ESP
2744+ inet_add_protocol(&esp_protocol);
2745+#endif /* CONFIG_IPSEC_ESP */
2746+
2747+#ifdef CONFIG_IPSEC_AH
2748+ inet_add_protocol(&ah_protocol);
2749+#endif /* CONFIG_IPSEC_AH */
2750+
2751+#if 0
2752+#ifdef CONFIG_IPSEC_IPCOMP
2753+ inet_add_protocol(&comp_protocol);
2754+#endif /* CONFIG_IPSEC_IPCOMP */
2755+#endif
2756+
2757+ error |= ipsec_tunnel_init_devices();
2758+
2759+#ifdef CONFIG_SYSCTL
2760+ error |= ipsec_sysctl_register();
2761+#endif
2762+ return error;
2763+}
2764+
2765+
2766+/* void */
2767+int
2768+ipsec_cleanup(void)
2769+{
2770+ int error = 0;
2771+
2772+#ifdef CONFIG_SYSCTL
2773+ ipsec_sysctl_unregister();
2774+#endif
2775+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
2776+ "klips_debug:ipsec_cleanup: calling ipsec_tunnel_cleanup_devices.\n");
2777+ error |= ipsec_tunnel_cleanup_devices();
2778+
2779+#if 0
2780+#ifdef CONFIG_IPSEC_IPCOMP
2781+ if (inet_del_protocol(&comp_protocol) < 0)
2782+ printk(KERN_INFO "klips_debug:ipsec_cleanup:comp close: can't remove protocol\n");
2783+#endif
2784+#endif
2785+#ifdef CONFIG_IPSEC_AH
2786+ if ( inet_del_protocol(&ah_protocol) < 0 )
2787+ printk(KERN_INFO "klips_debug:ipsec_cleanup:ah close: can't remove protocol\n");
2788+#endif /* CONFIG_IPSEC_AH */
2789+#ifdef CONFIG_IPSEC_ESP
2790+ if ( inet_del_protocol(&esp_protocol) < 0 )
2791+ printk(KERN_INFO "klips_debug:ipsec_cleanup:esp close: can't remove protocol\n");
2792+#endif /* CONFIG_IPSEC_ESP */
2793+
2794+ unregister_netdevice_notifier(&ipsec_dev_notifier);
2795+
2796+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
2797+ "klips_debug:ipsec_cleanup: calling ipsec_tdbcleanup.\n");
2798+ error |= ipsec_tdbcleanup(0);
2799+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
2800+ "klips_debug:ipsec_cleanup: calling ipsec_radijcleanup.\n");
2801+ error |= ipsec_radijcleanup();
2802+
2803+ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
2804+ "klips_debug:ipsec_cleanup: calling pfkey_cleanup.\n");
2805+ error |= pfkey_cleanup();
2806+
2807+#ifdef CONFIG_PROC_FS
2808+# ifndef PROC_FS_2325
2809+# ifdef CONFIG_IPSEC_DEBUG
2810+ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
2811+ printk("klips_debug:ipsec_cleanup: cannot unregister /proc/net/ipsec_klipsdebug\n");
2812+# endif /* CONFIG_IPSEC_DEBUG */
2813+ if (proc_net_unregister(ipsec_version.low_ino) != 0)
2814+ printk("klips_debug:ipsec_cleanup: cannot unregister /proc/net/ipsec_version\n");
2815+ if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
2816+ printk("klips_debug:ipsec_cleanup: cannot unregister /proc/net/ipsec_eroute\n");
2817+ if (proc_net_unregister(ipsec_spi.low_ino) != 0)
2818+ printk("klips_debug:ipsec_cleanup: cannot unregister /proc/net/ipsec_spi\n");
2819+ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
2820+ printk("klips_debug:ipsec_cleanup: cannot unregister /proc/net/ipsec_spigrp\n");
2821+ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
2822+ printk("klips_debug:ipsec_cleanup: cannot unregister /proc/net/ipsec_tncfg\n");
2823+# else /* !PROC_FS_2325 */
2824+# ifdef CONFIG_IPSEC_DEBUG
2825+ proc_net_remove ("ipsec_klipsdebug");
2826+# endif /* CONFIG_IPSEC_DEBUG */
2827+ proc_net_remove ("ipsec_eroute");
2828+ proc_net_remove ("ipsec_spi");
2829+ proc_net_remove ("ipsec_spigrp");
2830+ proc_net_remove ("ipsec_tncfg");
2831+ proc_net_remove ("ipsec_version");
2832+# endif /* !PROC_FS_2325 */
2833+#endif /* CONFIG_PROC_FS */
2834+
2835+ return error;
2836+}
2837+
2838+#ifdef MODULE
2839+int
2840+init_module(void)
2841+{
2842+ int error = 0;
2843+
2844+ error |= ipsec_init();
2845+
2846+ return error;
2847+}
2848+
2849+int
2850+cleanup_module(void)
2851+{
2852+ int error = 0;
2853+
2854+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
2855+ "klips_debug:cleanup_module: calling ipsec_cleanup.\n");
2856+
2857+ error |= ipsec_cleanup();
2858+
2859+ KLIPS_PRINT(1, "klips_debug:cleanup_module: ipsec module unloaded.\n");
2860+
2861+ return error;
2862+}
2863+#endif /* MODULE */
2864+
2865+/*
2866+ * $Log$
2867+ * Revision 1.63 2000/11/29 20:14:06 rgb
2868+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
2869+ *
2870+ * Revision 1.62 2000/11/06 04:31:24 rgb
2871+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
2872+ * Fixed longlong for pre-2.4 kernels (Svenning).
2873+ * Add Svenning's adaptive content compression.
2874+ * Disabled registration of ipcomp handler.
2875+ *
2876+ * Revision 1.61 2000/10/11 13:37:54 rgb
2877+ * #ifdef out debug print that causes proc/net/ipsec_version to oops.
2878+ *
2879+ * Revision 1.60 2000/09/20 03:59:01 rgb
2880+ * Change static info functions to DEBUG_NO_STATIC to reveal function names
2881+ * in oopsen.
2882+ *
2883+ * Revision 1.59 2000/09/16 01:06:26 rgb
2884+ * Added cast of var to silence compiler warning about long fed to int
2885+ * format.
2886+ *
2887+ * Revision 1.58 2000/09/15 11:37:01 rgb
2888+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
2889+ * IPCOMP zlib deflate code.
2890+ *
2891+ * Revision 1.57 2000/09/12 03:21:50 rgb
2892+ * Moved radij_c_version printing to ipsec_version_get_info().
2893+ * Reformatted ipsec_version_get_info().
2894+ * Added sysctl_{,un}register() calls.
2895+ *
2896+ * Revision 1.56 2000/09/08 19:16:50 rgb
2897+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
2898+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
2899+ *
2900+ * Revision 1.55 2000/08/30 05:19:03 rgb
2901+ * Cleaned up no longer used spi_next, netlink register/unregister, other
2902+ * minor cleanup.
2903+ * Removed cruft replaced by TDB_XFORM_NAME.
2904+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
2905+ * Moved debug version strings to printk when /proc/net/ipsec_version is
2906+ * called.
2907+ *
2908+ * Revision 1.54 2000/08/20 18:31:05 rgb
2909+ * Changed cosmetic alignment in spi_info.
2910+ * Changed addtime and usetime to use actual value which is relative
2911+ * anyways, as intended. (Momchil)
2912+ *
2913+ * Revision 1.53 2000/08/18 17:37:03 rgb
2914+ * Added an (int) cast to shut up the compiler...
2915+ *
2916+ * Revision 1.52 2000/08/01 14:51:50 rgb
2917+ * Removed _all_ remaining traces of DES.
2918+ *
2919+ * Revision 1.51 2000/07/25 20:41:22 rgb
2920+ * Removed duplicate parameter in spi_getinfo.
2921+ *
2922+ * Revision 1.50 2000/07/17 03:21:45 rgb
2923+ * Removed /proc/net/ipsec_spinew.
2924+ *
2925+ * Revision 1.49 2000/06/28 05:46:51 rgb
2926+ * Renamed ivlen to iv_bits for consistency.
2927+ * Changed output of add and use times to be relative to now.
2928+ *
2929+ * Revision 1.48 2000/05/11 18:26:10 rgb
2930+ * Commented out calls to netlink_attach/detach to avoid activating netlink
2931+ * in the kenrel config.
2932+ *
2933+ * Revision 1.47 2000/05/10 22:35:26 rgb
2934+ * Comment out most of the startup version information.
2935+ *
2936+ * Revision 1.46 2000/03/22 16:15:36 rgb
2937+ * Fixed renaming of dev_get (MB).
2938+ *
2939+ * Revision 1.45 2000/03/16 06:40:48 rgb
2940+ * Hardcode PF_KEYv2 support.
2941+ *
2942+ * Revision 1.44 2000/01/22 23:19:20 rgb
2943+ * Simplified code to use existing macro TDB_XFORM_NAME().
2944+ *
2945+ * Revision 1.43 2000/01/21 06:14:04 rgb
2946+ * Print individual stats only if non-zero.
2947+ * Removed 'bits' from each keylength for brevity.
2948+ * Shortened lifetimes legend for brevity.
2949+ * Changed wording from 'last_used' to the clearer 'idle'.
2950+ *
2951+ * Revision 1.42 1999/12/31 14:57:19 rgb
2952+ * MB fix for new dummy-less proc_get_info in 2.3.35.
2953+ *
2954+ * Revision 1.41 1999/11/23 23:04:03 rgb
2955+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
2956+ * Sort out pfkey and freeswan headers, putting them in a library path.
2957+ *
2958+ * Revision 1.40 1999/11/18 18:47:01 rgb
2959+ * Added dynamic proc registration for 2.3.25+.
2960+ * Changed all device registrations for static linking to
2961+ * dynamic to reduce the number and size of patches.
2962+ * Changed all protocol registrations for static linking to
2963+ * dynamic to reduce the number and size of patches.
2964+ *
2965+ * Revision 1.39 1999/11/18 04:12:07 rgb
2966+ * Replaced all kernel version macros to shorter, readable form.
2967+ * Added Marc Boucher's 2.3.25 proc patches.
2968+ * Converted all PROC_FS entries to dynamic to reduce kernel patching.
2969+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
2970+ *
2971+ * Revision 1.38 1999/11/17 15:53:38 rgb
2972+ * Changed all occurrences of #include "../../../lib/freeswan.h"
2973+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
2974+ * klips/net/ipsec/Makefile.
2975+ *
2976+ * Revision 1.37 1999/10/16 04:23:06 rgb
2977+ * Add stats for replaywin_errs, replaywin_max_sequence_difference,
2978+ * authentication errors, encryption size errors, encryption padding
2979+ * errors, and time since last packet.
2980+ *
2981+ * Revision 1.36 1999/10/16 00:30:47 rgb
2982+ * Added SA lifetime counting.
2983+ *
2984+ * Revision 1.35 1999/10/15 22:14:00 rgb
2985+ * Clean out cruft.
2986+ *
2987+ * Revision 1.34 1999/10/03 18:46:28 rgb
2988+ * Spinlock fixes for 2.0.xx and 2.3.xx.
2989+ *
2990+ * Revision 1.33 1999/10/01 17:08:10 rgb
2991+ * Disable spinlock init.
2992+ *
2993+ * Revision 1.32 1999/10/01 16:22:24 rgb
2994+ * Switch from assignment init. to functional init. of spinlocks.
2995+ *
2996+ * Revision 1.31 1999/10/01 15:44:52 rgb
2997+ * Move spinlock header include to 2.1> scope.
2998+ *
2999+ * Revision 1.30 1999/10/01 00:00:16 rgb
3000+ * Added eroute structure locking.
3001+ * Added tdb structure locking.
3002+ * Minor formatting changes.
3003+ * Add call to initialize tdb hash table.
3004+ *
3005+ * Revision 1.29 1999/09/23 20:22:40 rgb
3006+ * Enable, tidy and fix network notifier code.
3007+ *
3008+ * Revision 1.28 1999/09/18 11:39:56 rgb
3009+ * Start to add (disabled) netdevice notifier code.
3010+ *
3011+ * Revision 1.27 1999/08/28 08:24:47 rgb
3012+ * Add compiler directives to compile cleanly without debugging.
3013+ *
3014+ * Revision 1.26 1999/08/06 16:03:22 rgb
3015+ * Correct error messages on failure to unload /proc entries.
3016+ *
3017+ * Revision 1.25 1999/08/03 17:07:25 rgb
3018+ * Report device MTU, not private MTU.
3019+ *
3020+ * Revision 1.24 1999/05/25 22:24:37 rgb
3021+ * /PROC/NET/ipsec* init problem fix.
3022+ *
3023+ * Revision 1.23 1999/05/25 02:16:38 rgb
3024+ * Make modular proc_fs entries dynamic and fix for 2.2.x.
3025+ *
3026+ * Revision 1.22 1999/05/09 03:25:35 rgb
3027+ * Fix bug introduced by 2.2 quick-and-dirty patch.
3028+ *
3029+ * Revision 1.21 1999/05/05 22:02:30 rgb
3030+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
3031+ *
3032+ * Revision 1.20 1999/04/29 15:15:50 rgb
3033+ * Fix undetected iv_len reporting bug.
3034+ * Add sanity checking for null pointer to private data space.
3035+ * Add return values to init and cleanup functions.
3036+ *
3037+ * Revision 1.19 1999/04/27 19:24:44 rgb
3038+ * Added /proc/net/ipsec_klipsdebug support for reading the current debug
3039+ * settings.
3040+ * Instrument module load/init/unload.
3041+ *
3042+ * Revision 1.18 1999/04/15 15:37:24 rgb
3043+ * Forward check changes from POST1_00 branch.
3044+ *
3045+ * Revision 1.15.2.3 1999/04/13 20:29:19 rgb
3046+ * /proc/net/ipsec_* cleanup.
3047+ *
3048+ * Revision 1.15.2.2 1999/04/02 04:28:23 rgb
3049+ * /proc/net/ipsec_* formatting enhancements.
3050+ *
3051+ * Revision 1.15.2.1 1999/03/30 17:08:33 rgb
3052+ * Add pfkey initialisation.
3053+ *
3054+ * Revision 1.17 1999/04/11 00:28:57 henry
3055+ * GPL boilerplate
3056+ *
3057+ * Revision 1.16 1999/04/06 04:54:25 rgb
3058+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3059+ * patch shell fixes.
3060+ *
3061+ * Revision 1.15 1999/02/24 20:15:07 rgb
3062+ * Update output format.
3063+ *
3064+ * Revision 1.14 1999/02/17 16:49:39 rgb
3065+ * Convert DEBUG_IPSEC to KLIPS_PRINT
3066+ * Ditch NET_IPIP dependancy.
3067+ *
3068+ * Revision 1.13 1999/01/26 02:06:37 rgb
3069+ * Remove ah/esp switching on include files.
3070+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
3071+ * Removed dead code.
3072+ * Remove references to INET_GET_PROTOCOL.
3073+ *
3074+ * Revision 1.12 1999/01/22 06:19:18 rgb
3075+ * Cruft clean-out.
3076+ * 64-bit clean-up.
3077+ * Added algorithm switch code.
3078+ *
3079+ * Revision 1.11 1998/12/01 05:54:53 rgb
3080+ * Cleanup and order debug version output.
3081+ *
3082+ * Revision 1.10 1998/11/30 13:22:54 rgb
3083+ * Rationalised all the klips kernel file headers. They are much shorter
3084+ * now and won't conflict under RH5.2.
3085+ *
3086+ * Revision 1.9 1998/11/10 05:35:13 rgb
3087+ * Print direction in/out flag from /proc/net/ipsec_spi.
3088+ *
3089+ * Revision 1.8 1998/10/27 13:48:10 rgb
3090+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
3091+ * Fixed less(1) truncated output bug.
3092+ * Code clean-up.
3093+ *
3094+ * Revision 1.7 1998/10/22 06:43:16 rgb
3095+ * Convert to use satoa for printk.
3096+ *
3097+ * Revision 1.6 1998/10/19 14:24:35 rgb
3098+ * Added inclusion of freeswan.h.
3099+ *
3100+ * Revision 1.5 1998/10/09 04:43:35 rgb
3101+ * Added 'klips_debug' prefix to all klips printk debug statements.
3102+ *
3103+ * Revision 1.4 1998/07/27 21:50:22 rgb
3104+ * Not necessary to traverse mask tree for /proc/net/ipsec_eroute.
3105+ *
3106+ * Revision 1.3 1998/06/25 19:51:20 rgb
3107+ * Clean up #endif comments.
3108+ * Shift debugging comment control for procfs to debug_tunnel.
3109+ * Make proc_dir_entries visible to rest of kernel for static link.
3110+ * Replace hardwired fileperms with macros.
3111+ * Use macros for procfs inode numbers.
3112+ * Rearrange initialisations between ipsec_init and module_init as appropriate
3113+ * for static loading.
3114+ *
3115+ * Revision 1.2 1998/06/23 02:55:43 rgb
3116+ * Slightly quieted init-time messages.
3117+ * Re-introduced inet_add_protocol after it mysteriously disappeared...
3118+ * Check for and warn of absence of IPIP protocol on install of module.
3119+ * Move tdbcleanup to ipsec_xform.c.
3120+ *
3121+ * Revision 1.10 1998/06/18 21:29:04 henry
3122+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
3123+ * build scripts happier in presence of symbolic links
3124+ *
3125+ * Revision 1.9 1998/06/14 23:49:40 rgb
3126+ * Clarify version reporting on module loading.
3127+ *
3128+ * Revision 1.8 1998/06/11 05:54:23 rgb
3129+ * Added /proc/net/ipsec_version to report freeswan and transform versions.
3130+ * Added /proc/net/ipsec_spinew to generate new and unique spi's..
3131+ * Fixed /proc/net/ipsec_tncfg bug.
3132+ *
3133+ * Revision 1.7 1998/05/25 20:23:13 rgb
3134+ * proc_register changed to dynamic registration to avoid arbitrary inode
3135+ * numbers.
3136+ *
3137+ * Implement memory recovery from tdb and eroute tables.
3138+ *
3139+ * Revision 1.6 1998/05/21 13:08:58 rgb
3140+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
3141+ * information is available for printout.
3142+ *
3143+ * Revision 1.5 1998/05/18 21:29:48 rgb
3144+ * Cleaned up /proc/net/ipsec_* output, including a title line, algorithm
3145+ * names instead of numbers, standard format for numerical output base,
3146+ * whitespace for legibility, and the names themselves for consistency.
3147+ *
3148+ * Added /proc/net/ipsec_spigrp and /proc/net/ipsec_tncfg.
3149+ *
3150+ * Revision 1.4 1998/04/30 15:42:24 rgb
3151+ * Silencing attach for normal operations with #ifdef IPSEC_DEBUG.
3152+ *
3153+ * Revision 1.3 1998/04/21 21:28:58 rgb
3154+ * Rearrange debug switches to change on the fly debug output from user
3155+ * space. Only kernel changes checked in at this time. radij.c was also
3156+ * changed to temporarily remove buggy debugging code in rj_delete causing
3157+ * an OOPS and hence, netlink device open errors.
3158+ *
3159+ * Revision 1.2 1998/04/12 22:03:22 rgb
3160+ * Updated ESP-3DES-HMAC-MD5-96,
3161+ * ESP-DES-HMAC-MD5-96,
3162+ * AH-HMAC-MD5-96,
3163+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
3164+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
3165+ *
3166+ * Fixed eroute references in /proc/net/ipsec*.
3167+ *
3168+ * Started to patch module unloading memory leaks in ipsec_netlink and
3169+ * radij tree unloading.
3170+ *
3171+ * Revision 1.1 1998/04/09 03:06:05 henry
3172+ * sources moved up from linux/net/ipsec
3173+ *
3174+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
3175+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3176+ *
3177+ * Revision 0.4 1997/01/15 01:28:15 ji
3178+ * No changes.
3179+ *
3180+ * Revision 0.3 1996/11/20 14:39:04 ji
3181+ * Fixed problem with node names of /proc/net entries.
3182+ * Other minor cleanups.
3183+ * Rationalized debugging code.
3184+ *
3185+ * Revision 0.2 1996/11/02 00:18:33 ji
3186+ * First limited release.
3187+ *
3188+ *
3189+ */
3190diff -druN linux-noipsec/net/ipsec/ipsec_ipe4.h linux/net/ipsec/ipsec_ipe4.h
3191--- linux-noipsec/net/ipsec/ipsec_ipe4.h Thu Jan 1 01:00:00 1970
3192+++ linux/net/ipsec/ipsec_ipe4.h Sun Apr 11 02:28:57 1999
3193@@ -0,0 +1,59 @@
3194+/*
3195+ * IP-in-IP Header declarations
3196+ * Copyright (C) 1996, 1997 John Ioannidis.
3197+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
3198+ *
3199+ * This program is free software; you can redistribute it and/or modify it
3200+ * under the terms of the GNU General Public License as published by the
3201+ * Free Software Foundation; either version 2 of the License, or (at your
3202+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3203+ *
3204+ * This program is distributed in the hope that it will be useful, but
3205+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3206+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3207+ * for more details.
3208+ *
3209+ * RCSID $Id$
3210+ */
3211+
3212+/* The packet header is an IP header! */
3213+
3214+struct ipe4_xdata /* transform table data */
3215+{
3216+ struct in_addr i4_src;
3217+ struct in_addr i4_dst;
3218+};
3219+
3220+#define EMT_IPE4_ULEN 8 /* coming from user mode */
3221+
3222+
3223+/*
3224+ * $Log$
3225+ * Revision 1.3 1999/04/11 00:28:57 henry
3226+ * GPL boilerplate
3227+ *
3228+ * Revision 1.2 1999/04/06 04:54:25 rgb
3229+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3230+ * patch shell fixes.
3231+ *
3232+ * Revision 1.1 1998/06/18 21:27:47 henry
3233+ * move sources from klips/src to klips/net/ipsec, to keep stupid
3234+ * kernel-build scripts happier in the presence of symlinks
3235+ *
3236+ * Revision 1.1 1998/04/09 03:06:07 henry
3237+ * sources moved up from linux/net/ipsec
3238+ *
3239+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
3240+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3241+ *
3242+ * Revision 0.4 1997/01/15 01:28:15 ji
3243+ * No changes.
3244+ *
3245+ * Revision 0.3 1996/11/20 14:48:53 ji
3246+ * Release update only.
3247+ *
3248+ * Revision 0.2 1996/11/02 00:18:33 ji
3249+ * First limited release.
3250+ *
3251+ *
3252+ */
3253diff -druN linux-noipsec/net/ipsec/ipsec_md5c.c linux/net/ipsec/ipsec_md5c.c
3254--- linux-noipsec/net/ipsec/ipsec_md5c.c Thu Jan 1 01:00:00 1970
3255+++ linux/net/ipsec/ipsec_md5c.c Mon Dec 13 14:59:12 1999
3256@@ -0,0 +1,430 @@
3257+/*
3258+ * RCSID $Id$
3259+ */
3260+
3261+/*
3262+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
3263+ * changes to accomodate it in the kernel by ji.
3264+ */
3265+
3266+#include <asm/byteorder.h>
3267+#include <linux/string.h>
3268+
3269+#include "ipsec_md5h.h"
3270+
3271+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
3272+ */
3273+
3274+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
3275+rights reserved.
3276+
3277+License to copy and use this software is granted provided that it
3278+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
3279+Algorithm" in all material mentioning or referencing this software
3280+or this function.
3281+
3282+License is also granted to make and use derivative works provided
3283+that such works are identified as "derived from the RSA Data
3284+Security, Inc. MD5 Message-Digest Algorithm" in all material
3285+mentioning or referencing the derived work.
3286+
3287+RSA Data Security, Inc. makes no representations concerning either
3288+the merchantability of this software or the suitability of this
3289+software for any particular purpose. It is provided "as is"
3290+without express or implied warranty of any kind.
3291+
3292+These notices must be retained in any copies of any part of this
3293+documentation and/or software.
3294+ */
3295+
3296+/*
3297+ * Additions by JI
3298+ *
3299+ * HAVEMEMCOPY is defined if mem* routines are available
3300+ *
3301+ * HAVEHTON is defined if htons() and htonl() can be used
3302+ * for big/little endian conversions
3303+ *
3304+ */
3305+
3306+#define HAVEMEMCOPY
3307+#ifdef __LITTLE_ENDIAN
3308+#define LITTLENDIAN
3309+#endif
3310+#ifdef __BIG_ENDIAN
3311+#define BIGENDIAN
3312+#endif
3313+
3314+/* Constants for MD5Transform routine.
3315+ */
3316+
3317+#define S11 7
3318+#define S12 12
3319+#define S13 17
3320+#define S14 22
3321+#define S21 5
3322+#define S22 9
3323+#define S23 14
3324+#define S24 20
3325+#define S31 4
3326+#define S32 11
3327+#define S33 16
3328+#define S34 23
3329+#define S41 6
3330+#define S42 10
3331+#define S43 15
3332+#define S44 21
3333+
3334+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
3335+
3336+#ifdef LITTLEENDIAN
3337+#define Encode MD5_memcpy
3338+#define Decode MD5_memcpy
3339+#else
3340+static void Encode PROTO_LIST
3341+ ((unsigned char *, UINT4 *, unsigned int));
3342+static void Decode PROTO_LIST
3343+ ((UINT4 *, unsigned char *, unsigned int));
3344+#endif
3345+
3346+#ifdef HAVEMEMCOPY
3347+/* no need to include <memory.h> here; <linux/string.h> defines these */
3348+#define MD5_memcpy memcpy
3349+#define MD5_memset memset
3350+#else
3351+#ifdef HAVEBCOPY
3352+#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
3353+#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
3354+#else
3355+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
3356+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
3357+#endif
3358+#endif
3359+static unsigned char PADDING[64] = {
3360+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3361+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3362+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3363+};
3364+
3365+/* F, G, H and I are basic MD5 functions.
3366+ */
3367+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
3368+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
3369+#define H(x, y, z) ((x) ^ (y) ^ (z))
3370+#define I(x, y, z) ((y) ^ ((x) | (~z)))
3371+
3372+/* ROTATE_LEFT rotates x left n bits.
3373+ */
3374+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
3375+
3376+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
3377+Rotation is separate from addition to prevent recomputation.
3378+ */
3379+#define FF(a, b, c, d, x, s, ac) { \
3380+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
3381+ (a) = ROTATE_LEFT ((a), (s)); \
3382+ (a) += (b); \
3383+ }
3384+#define GG(a, b, c, d, x, s, ac) { \
3385+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
3386+ (a) = ROTATE_LEFT ((a), (s)); \
3387+ (a) += (b); \
3388+ }
3389+#define HH(a, b, c, d, x, s, ac) { \
3390+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
3391+ (a) = ROTATE_LEFT ((a), (s)); \
3392+ (a) += (b); \
3393+ }
3394+#define II(a, b, c, d, x, s, ac) { \
3395+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
3396+ (a) = ROTATE_LEFT ((a), (s)); \
3397+ (a) += (b); \
3398+ }
3399+
3400+/* MD5 initialization. Begins an MD5 operation, writing a new context.
3401+ */
3402+void MD5Init (context)
3403+MD5_CTX *context; /* context */
3404+{
3405+ context->count[0] = context->count[1] = 0;
3406+ /* Load magic initialization constants.
3407+*/
3408+ context->state[0] = 0x67452301;
3409+ context->state[1] = 0xefcdab89;
3410+ context->state[2] = 0x98badcfe;
3411+ context->state[3] = 0x10325476;
3412+}
3413+
3414+/* MD5 block update operation. Continues an MD5 message-digest
3415+ operation, processing another message block, and updating the
3416+ context.
3417+ */
3418+void MD5Update (context, input, inputLen)
3419+MD5_CTX *context; /* context */
3420+unsigned char *input; /* input block */
3421+__u32 inputLen; /* length of input block */
3422+{
3423+ __u32 i;
3424+ unsigned int index, partLen;
3425+
3426+ /* Compute number of bytes mod 64 */
3427+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
3428+
3429+ /* Update number of bits */
3430+ if ((context->count[0] += ((UINT4)inputLen << 3))
3431+ < ((UINT4)inputLen << 3))
3432+ context->count[1]++;
3433+ context->count[1] += ((UINT4)inputLen >> 29);
3434+
3435+ partLen = 64 - index;
3436+
3437+ /* Transform as many times as possible.
3438+*/
3439+ if (inputLen >= partLen) {
3440+ MD5_memcpy
3441+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
3442+ MD5Transform (context->state, context->buffer);
3443+
3444+ for (i = partLen; i + 63 < inputLen; i += 64)
3445+ MD5Transform (context->state, &input[i]);
3446+
3447+ index = 0;
3448+ }
3449+ else
3450+ i = 0;
3451+
3452+ /* Buffer remaining input */
3453+ MD5_memcpy
3454+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
3455+ inputLen-i);
3456+}
3457+
3458+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
3459+ the message digest and zeroizing the context.
3460+ */
3461+void MD5Final (digest, context)
3462+unsigned char digest[16]; /* message digest */
3463+MD5_CTX *context; /* context */
3464+{
3465+ unsigned char bits[8];
3466+ unsigned int index, padLen;
3467+
3468+ /* Save number of bits */
3469+ Encode (bits, context->count, 8);
3470+
3471+ /* Pad out to 56 mod 64.
3472+*/
3473+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
3474+ padLen = (index < 56) ? (56 - index) : (120 - index);
3475+ MD5Update (context, PADDING, padLen);
3476+
3477+ /* Append length (before padding) */
3478+ MD5Update (context, bits, 8);
3479+
3480+ if (digest != NULL) /* Bill Simpson's padding */
3481+ {
3482+ /* store state in digest */
3483+ Encode (digest, context->state, 16);
3484+
3485+ /* Zeroize sensitive information.
3486+ */
3487+ MD5_memset ((POINTER)context, 0, sizeof (*context));
3488+ }
3489+}
3490+
3491+/* MD5 basic transformation. Transforms state based on block.
3492+ */
3493+static void MD5Transform (state, block)
3494+UINT4 state[4];
3495+unsigned char block[64];
3496+{
3497+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
3498+
3499+ Decode (x, block, 64);
3500+
3501+ /* Round 1 */
3502+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
3503+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
3504+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
3505+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
3506+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
3507+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
3508+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
3509+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
3510+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
3511+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
3512+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
3513+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
3514+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
3515+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
3516+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
3517+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
3518+
3519+ /* Round 2 */
3520+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
3521+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
3522+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
3523+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
3524+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
3525+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
3526+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
3527+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
3528+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
3529+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
3530+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
3531+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
3532+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
3533+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
3534+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
3535+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
3536+
3537+ /* Round 3 */
3538+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
3539+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
3540+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
3541+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
3542+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
3543+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
3544+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
3545+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
3546+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
3547+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
3548+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
3549+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
3550+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
3551+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
3552+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
3553+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
3554+
3555+ /* Round 4 */
3556+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
3557+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
3558+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
3559+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
3560+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
3561+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
3562+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
3563+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
3564+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
3565+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
3566+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
3567+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
3568+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
3569+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
3570+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
3571+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
3572+
3573+ state[0] += a;
3574+ state[1] += b;
3575+ state[2] += c;
3576+ state[3] += d;
3577+
3578+ /* Zeroize sensitive information.
3579+*/
3580+ MD5_memset ((POINTER)x, 0, sizeof (x));
3581+}
3582+
3583+#ifndef LITTLEENDIAN
3584+
3585+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
3586+ a multiple of 4.
3587+ */
3588+static void Encode (output, input, len)
3589+unsigned char *output;
3590+UINT4 *input;
3591+unsigned int len;
3592+{
3593+ unsigned int i, j;
3594+
3595+ for (i = 0, j = 0; j < len; i++, j += 4) {
3596+ output[j] = (unsigned char)(input[i] & 0xff);
3597+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
3598+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
3599+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
3600+ }
3601+}
3602+
3603+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
3604+ a multiple of 4.
3605+ */
3606+static void Decode (output, input, len)
3607+UINT4 *output;
3608+unsigned char *input;
3609+unsigned int len;
3610+{
3611+ unsigned int i, j;
3612+
3613+ for (i = 0, j = 0; j < len; i++, j += 4)
3614+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
3615+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
3616+}
3617+
3618+#endif
3619+
3620+#ifndef HAVEMEMCOPY
3621+#ifndef HAVEBCOPY
3622+/* Note: Replace "for loop" with standard memcpy if possible.
3623+ */
3624+
3625+static void MD5_memcpy (output, input, len)
3626+POINTER output;
3627+POINTER input;
3628+unsigned int len;
3629+{
3630+ unsigned int i;
3631+
3632+ for (i = 0; i < len; i++)
3633+
3634+ output[i] = input[i];
3635+}
3636+
3637+/* Note: Replace "for loop" with standard memset if possible.
3638+ */
3639+
3640+static void MD5_memset (output, value, len)
3641+POINTER output;
3642+int value;
3643+unsigned int len;
3644+{
3645+ unsigned int i;
3646+
3647+ for (i = 0; i < len; i++)
3648+ ((char *)output)[i] = (char)value;
3649+}
3650+#endif
3651+#endif
3652+
3653+/*
3654+ * $Log$
3655+ * Revision 1.4 1999/12/13 13:59:12 rgb
3656+ * Quick fix to argument size to Update bugs.
3657+ *
3658+ * Revision 1.3 1999/05/21 18:09:28 henry
3659+ * unnecessary <memory.h> include causes trouble in 2.2
3660+ *
3661+ * Revision 1.2 1999/04/06 04:54:26 rgb
3662+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3663+ * patch shell fixes.
3664+ *
3665+ * Revision 1.1 1998/06/18 21:27:48 henry
3666+ * move sources from klips/src to klips/net/ipsec, to keep stupid
3667+ * kernel-build scripts happier in the presence of symlinks
3668+ *
3669+ * Revision 1.2 1998/04/23 20:54:02 rgb
3670+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
3671+ * verified.
3672+ *
3673+ * Revision 1.1 1998/04/09 03:06:08 henry
3674+ * sources moved up from linux/net/ipsec
3675+ *
3676+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
3677+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3678+ *
3679+ * Revision 0.3 1996/11/20 14:48:53 ji
3680+ * Release update only.
3681+ *
3682+ * Revision 0.2 1996/11/02 00:18:33 ji
3683+ * First limited release.
3684+ *
3685+ *
3686+ */
3687diff -druN linux-noipsec/net/ipsec/ipsec_md5h.h linux/net/ipsec/ipsec_md5h.h
3688--- linux-noipsec/net/ipsec/ipsec_md5h.h Thu Jan 1 01:00:00 1970
3689+++ linux/net/ipsec/ipsec_md5h.h Mon Dec 13 14:59:13 1999
3690@@ -0,0 +1,129 @@
3691+/*
3692+ * RCSID $Id$
3693+ */
3694+
3695+/*
3696+ * The rest of this file is Copyright RSA DSI. See the following comments
3697+ * for the full Copyright notice.
3698+ */
3699+
3700+#ifndef _IPSEC_MD5H_H_
3701+#define _IPSEC_MD5H_H_
3702+
3703+/* GLOBAL.H - RSAREF types and constants
3704+ */
3705+
3706+/* PROTOTYPES should be set to one if and only if the compiler supports
3707+ function argument prototyping.
3708+ The following makes PROTOTYPES default to 0 if it has not already
3709+ been defined with C compiler flags.
3710+ */
3711+#ifndef PROTOTYPES
3712+#define PROTOTYPES 1
3713+#endif /* !PROTOTYPES */
3714+
3715+/* POINTER defines a generic pointer type */
3716+typedef __u8 *POINTER;
3717+
3718+/* UINT2 defines a two byte word */
3719+typedef __u16 UINT2;
3720+
3721+/* UINT4 defines a four byte word */
3722+typedef __u32 UINT4;
3723+
3724+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
3725+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
3726+ returns an empty list.
3727+ */
3728+
3729+#if PROTOTYPES
3730+#define PROTO_LIST(list) list
3731+#else /* PROTOTYPES */
3732+#define PROTO_LIST(list) ()
3733+#endif /* PROTOTYPES */
3734+
3735+
3736+/* MD5.H - header file for MD5C.C
3737+ */
3738+
3739+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
3740+rights reserved.
3741+
3742+License to copy and use this software is granted provided that it
3743+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
3744+Algorithm" in all material mentioning or referencing this software
3745+or this function.
3746+
3747+License is also granted to make and use derivative works provided
3748+that such works are identified as "derived from the RSA Data
3749+Security, Inc. MD5 Message-Digest Algorithm" in all material
3750+mentioning or referencing the derived work.
3751+
3752+RSA Data Security, Inc. makes no representations concerning either
3753+the merchantability of this software or the suitability of this
3754+software for any particular purpose. It is provided "as is"
3755+without express or implied warranty of any kind.
3756+
3757+These notices must be retained in any copies of any part of this
3758+documentation and/or software.
3759+ */
3760+
3761+/* MD5 context. */
3762+typedef struct {
3763+ UINT4 state[4]; /* state (ABCD) */
3764+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
3765+ unsigned char buffer[64]; /* input buffer */
3766+} MD5_CTX;
3767+
3768+void MD5Init PROTO_LIST ((MD5_CTX *));
3769+void MD5Update PROTO_LIST
3770+ ((MD5_CTX *, unsigned char *, __u32));
3771+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
3772+
3773+#endif /* _IPSEC_MD5H_H_ */
3774+
3775+/*
3776+ * $Log$
3777+ * Revision 1.6 1999/12/13 13:59:13 rgb
3778+ * Quick fix to argument size to Update bugs.
3779+ *
3780+ * Revision 1.5 1999/12/07 18:16:23 rgb
3781+ * Fixed comments at end of #endif lines.
3782+ *
3783+ * Revision 1.4 1999/04/06 04:54:26 rgb
3784+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3785+ * patch shell fixes.
3786+ *
3787+ * Revision 1.3 1999/01/22 06:19:58 rgb
3788+ * 64-bit clean-up.
3789+ *
3790+ * Revision 1.2 1998/11/30 13:22:54 rgb
3791+ * Rationalised all the klips kernel file headers. They are much shorter
3792+ * now and won't conflict under RH5.2.
3793+ *
3794+ * Revision 1.1 1998/06/18 21:27:48 henry
3795+ * move sources from klips/src to klips/net/ipsec, to keep stupid
3796+ * kernel-build scripts happier in the presence of symlinks
3797+ *
3798+ * Revision 1.2 1998/04/23 20:54:03 rgb
3799+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
3800+ * verified.
3801+ *
3802+ * Revision 1.1 1998/04/09 03:04:21 henry
3803+ * sources moved up from linux/net/ipsec
3804+ * these two include files modified not to include others except in kernel
3805+ *
3806+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
3807+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3808+ *
3809+ * Revision 0.4 1997/01/15 01:28:15 ji
3810+ * No changes.
3811+ *
3812+ * Revision 0.3 1996/11/20 14:48:53 ji
3813+ * Release update only.
3814+ *
3815+ * Revision 0.2 1996/11/02 00:18:33 ji
3816+ * First limited release.
3817+ *
3818+ *
3819+ */
3820diff -druN linux-noipsec/net/ipsec/ipsec_netlink.c linux/net/ipsec/ipsec_netlink.c
3821--- linux-noipsec/net/ipsec/ipsec_netlink.c Thu Jan 1 01:00:00 1970
3822+++ linux/net/ipsec/ipsec_netlink.c Mon Nov 6 05:32:08 2000
3823@@ -0,0 +1,635 @@
3824+/*
3825+ * IPSEC <> netlink interface
3826+ * Copyright (C) 1996, 1997 John Ioannidis.
3827+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
3828+ *
3829+ * This program is free software; you can redistribute it and/or modify it
3830+ * under the terms of the GNU General Public License as published by the
3831+ * Free Software Foundation; either version 2 of the License, or (at your
3832+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3833+ *
3834+ * This program is distributed in the hope that it will be useful, but
3835+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3836+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3837+ * for more details.
3838+ */
3839+
3840+char ipsec_netlink_c_version[] = "RCSID $Id$";
3841+
3842+#include <linux/config.h>
3843+#include <linux/version.h>
3844+
3845+#include <linux/kernel.h> /* printk() */
3846+#include <linux/malloc.h> /* kmalloc() */
3847+#include <linux/errno.h> /* error codes */
3848+#include <linux/types.h> /* size_t */
3849+#include <linux/interrupt.h> /* mark_bh */
3850+
3851+#include <linux/netdevice.h> /* struct device, and other headers */
3852+#include <linux/etherdevice.h> /* eth_type_trans */
3853+#include <linux/ip.h> /* struct iphdr */
3854+#include <linux/skbuff.h>
3855+#include <freeswan.h>
3856+#ifdef SPINLOCK
3857+ #ifdef SPINLOCK_23
3858+ #include <linux/spinlock.h> /* *lock* */
3859+ #else /* 23_SPINLOCK */
3860+ #include <asm/spinlock.h> /* *lock* */
3861+ #endif /* 23_SPINLOCK */
3862+#endif /* SPINLOCK */
3863+#ifdef NET_21
3864+ #include <asm/uaccess.h>
3865+ #include <linux/in6.h>
3866+ #define ip_chk_addr inet_addr_type
3867+ #define IS_MYADDR RTN_LOCAL
3868+#endif
3869+#include <asm/checksum.h>
3870+#include <net/ip.h>
3871+#ifdef NETLINK_SOCK
3872+ #include <linux/netlink.h>
3873+#else
3874+ #include <net/netlink.h>
3875+#endif
3876+
3877+#include "radij.h"
3878+#include "ipsec_encap.h"
3879+#include "ipsec_radij.h"
3880+#include "ipsec_netlink.h"
3881+#include "ipsec_xform.h"
3882+
3883+#include "ipsec_rcv.h"
3884+#include "ipsec_ah.h"
3885+#include "ipsec_esp.h"
3886+
3887+#ifdef CONFIG_IPSEC_DEBUG
3888+ #include "ipsec_tunnel.h"
3889+#endif /* CONFIG_IPSEC_DEBUG */
3890+
3891+#include <pfkeyv2.h>
3892+#include <pfkey.h>
3893+
3894+#ifdef CONFIG_IPSEC_DEBUG
3895+ int debug_netlink = 0;
3896+#endif /* CONFIG_IPSEC_DEBUG */
3897+
3898+#define SENDERR(_x) do { len = -(_x); goto errlab; } while (0)
3899+
3900+#if 0
3901+int
3902+#ifdef NETLINK_SOCK
3903+ipsec_callback(int proto, struct sk_buff *skb)
3904+#else /* NETLINK_SOCK */
3905+ipsec_callback(struct sk_buff *skb)
3906+#endif /* NETLINK_SOCK */
3907+{
3908+ /*
3909+ * this happens when we write to /dev/ipsec (c 36 10)
3910+ */
3911+ int len = skb->len;
3912+ u_char *dat = (u_char *)skb->data;
3913+ struct encap_msghdr *em = (struct encap_msghdr *)dat;
3914+ struct tdb *tdbp, *tprev;
3915+ int i, nspis, error = 0;
3916+#ifdef CONFIG_IPSEC_DEBUG
3917+ struct eroute *eret;
3918+ char sa[SATOA_BUF];
3919+
3920+
3921+ satoa(em->em_said, 0, sa, SATOA_BUF);
3922+
3923+ if(debug_netlink) {
3924+ printk("klips_debug:ipsec_callback: skb=0x%p skblen=%ld em_magic=%d em_type=%d\n",
3925+ skb, (unsigned long int)skb->len, em->em_magic, em->em_type);
3926+ switch(em->em_type) {
3927+ case EMT_SETDEBUG:
3928+ printk("klips_debug:ipsec_callback: set ipsec_debug level\n");
3929+ break;
3930+ case EMT_DELEROUTE:
3931+ case EMT_CLREROUTE:
3932+ case EMT_CLRSPIS:
3933+ break;
3934+ default:
3935+ printk("klips_debug:ipsec_callback: called for SA:%s\n", sa);
3936+ }
3937+ }
3938+#endif /* CONFIG_IPSEC_DEBUG */
3939+
3940+ /* XXXX Temporarily disable netlink I/F code until it gets permanantly
3941+ ripped out in favour of PF_KEYv2 I/F. */
3942+ SENDERR(EPROTONOSUPPORT);
3943+
3944+ /* em = (struct encap_msghdr *)dat; */
3945+ if (em->em_magic != EM_MAGIC) {
3946+ printk("klips_debug:ipsec_callback: bad magic=%d failed, should be %d\n",
3947+ em->em_magic,
3948+ EM_MAGIC);
3949+ SENDERR(EINVAL);
3950+ }
3951+ switch (em->em_type) {
3952+ case EMT_SETDEBUG:
3953+#ifdef CONFIG_IPSEC_DEBUG
3954+ if(em->em_db_nl >> (sizeof(em->em_db_nl) * 8 - 1)) {
3955+ em->em_db_nl &= ~(1 << (sizeof(em->em_db_nl) * 8 -1));
3956+ debug_tunnel |= em->em_db_tn;
3957+ debug_netlink |= em->em_db_nl;
3958+ debug_xform |= em->em_db_xf;
3959+ debug_eroute |= em->em_db_er;
3960+ debug_spi |= em->em_db_sp;
3961+ debug_radij |= em->em_db_rj;
3962+ debug_esp |= em->em_db_es;
3963+ debug_ah |= em->em_db_ah;
3964+ debug_rcv |= em->em_db_rx;
3965+ debug_pfkey |= em->em_db_ky;
3966+ if(debug_netlink)
3967+ printk("klips_debug:ipsec_callback: set\n");
3968+ } else {
3969+ if(debug_netlink)
3970+ printk("klips_debug:ipsec_callback: unset\n");
3971+ debug_tunnel &= em->em_db_tn;
3972+ debug_netlink &= em->em_db_nl;
3973+ debug_xform &= em->em_db_xf;
3974+ debug_eroute &= em->em_db_er;
3975+ debug_spi &= em->em_db_sp;
3976+ debug_radij &= em->em_db_rj;
3977+ debug_esp &= em->em_db_es;
3978+ debug_ah &= em->em_db_ah;
3979+ debug_rcv &= em->em_db_rx;
3980+ debug_pfkey &= em->em_db_ky;
3981+ }
3982+#else /* CONFIG_IPSEC_DEBUG */
3983+ printk("klips_debug:ipsec_callback: debugging not enabled\n");
3984+ SENDERR(EINVAL);
3985+#endif /* CONFIG_IPSEC_DEBUG */
3986+ break;
3987+
3988+ case EMT_SETEROUTE:
3989+ if ((error = ipsec_makeroute(&(em->em_eaddr), &(em->em_emask), em->em_ersaid)))
3990+ SENDERR(-error);
3991+ break;
3992+
3993+ case EMT_RPLACEROUTE:
3994+ if ((error = ipsec_breakroute(&(em->em_eaddr), &(em->em_emask))) == EINVAL) {
3995+ SENDERR(-error);
3996+ }
3997+ if ((error = ipsec_makeroute(&(em->em_eaddr), &(em->em_emask), em->em_ersaid)))
3998+ SENDERR(-error);
3999+ break;
4000+
4001+ case EMT_DELEROUTE:
4002+ if ((error = ipsec_breakroute(&(em->em_eaddr), &(em->em_emask))))
4003+ SENDERR(-error);
4004+ break;
4005+
4006+ case EMT_CLREROUTE:
4007+ if ((error = ipsec_cleareroutes()))
4008+ SENDERR(-error);
4009+ break;
4010+
4011+ case EMT_SETSPI:
4012+ if (em->em_if >= 5) /* XXX -- why 5? */
4013+ SENDERR(ENODEV);
4014+
4015+ tdbp = gettdb(&(em->em_said));
4016+ if (tdbp == NULL) {
4017+ tdbp = (struct tdb *)kmalloc(sizeof (*tdbp), GFP_ATOMIC);
4018+
4019+ if (tdbp == NULL)
4020+ SENDERR(ENOBUFS);
4021+
4022+ memset((caddr_t)tdbp, 0, sizeof(*tdbp));
4023+
4024+ tdbp->tdb_said = em->em_said;
4025+ tdbp->tdb_flags = em->em_flags;
4026+
4027+ if(ip_chk_addr((unsigned long)em->em_said.dst.s_addr) == IS_MYADDR) {
4028+ tdbp->tdb_flags |= EMT_INBOUND;
4029+ }
4030+ KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
4031+ "klips_debug:ipsec_callback: existing Tunnel Descriptor Block not found (this\n"
4032+ "klips_debug: is good) for SA: %s, %s-bound, allocating.\n",
4033+ sa, (tdbp->tdb_flags & EMT_INBOUND) ? "in" : "out");
4034+
4035+/* XXX tdbp->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/
4036+ tdbp->tdb_rcvif = NULL;
4037+ } else {
4038+ KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
4039+ "klips_debug:ipsec_callback: EMT_SETSPI found an old Tunnel Descriptor Block\n"
4040+ "klips_debug: for SA: %s, delete it first.\n", sa);
4041+ SENDERR(EEXIST);
4042+ }
4043+
4044+ if ((error = tdb_init(tdbp, em))) {
4045+ KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
4046+ "klips_debug:ipsec_callback: EMT_SETSPI not successful for SA: %s, deleting.\n", sa);
4047+ ipsec_tdbwipe(tdbp);
4048+
4049+ SENDERR(-error);
4050+ }
4051+
4052+ tdbp->tdb_lifetime_addtime_c = jiffies/HZ;
4053+ tdbp->tdb_state = 1;
4054+ if(!tdbp->tdb_lifetime_allocations_c) {
4055+ tdbp->tdb_lifetime_allocations_c += 1;
4056+ }
4057+
4058+ puttdb(tdbp);
4059+ KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
4060+ "klips_debug:ipsec_callback: EMT_SETSPI successful for SA: %s\n", sa);
4061+ break;
4062+
4063+ case EMT_DELSPI:
4064+ if (em->em_if >= 5) /* XXX -- why 5? */
4065+ SENDERR(ENODEV);
4066+
4067+ spin_lock_bh(&tdb_lock);
4068+
4069+ tdbp = gettdb(&(em->em_said));
4070+ if (tdbp == NULL) {
4071+ KLIPS_PRINT(debug_netlink & DB_NL_TDBCB,
4072+ "klips_debug:ipsec_callback: "
4073+ "EMT_DELSPI Tunnel Descriptor Block not found for SA:\n"
4074+ "klips_debug: %s, could not delete.\n", sa);
4075+ spin_unlock_bh(&tdb_lock);
4076+ SENDERR(ENXIO); /* XXX -- wrong error message... */
4077+ } else {
4078+ if((error = deltdbchain(tdbp))) {
4079+ spin_unlock_bh(&tdb_lock);
4080+ SENDERR(-error);
4081+ }
4082+ }
4083+ spin_unlock_bh(&tdb_lock);
4084+
4085+ break;
4086+
4087+ case EMT_GRPSPIS:
4088+ nspis = (len - EMT_GRPSPIS_FLEN) / sizeof(em->em_rel[0]);
4089+ if ((nspis * (sizeof(em->em_rel[0]))) != (len - EMT_GRPSPIS_FLEN)) {
4090+ printk("klips_debug:ipsec_callback: EMT_GRPSPI message size incorrect, expected nspis(%d)*%d, got %d.\n",
4091+ nspis,
4092+ sizeof(em->em_rel[0]),
4093+ (len - EMT_GRPSPIS_FLEN));
4094+ SENDERR(EINVAL);
4095+ break;
4096+ }
4097+
4098+ spin_lock_bh(&tdb_lock);
4099+
4100+ for (i = 0; i < nspis; i++) {
4101+ KLIPS_PRINT(debug_netlink,
4102+ "klips_debug:ipsec_callback: EMT_GRPSPI for SA(%d)\n"
4103+ "klips_debug: %s,\n", i, sa);
4104+ if ((tdbp = gettdb(&(em->em_rel[i].emr_said))) == NULL) {
4105+ KLIPS_PRINT(debug_netlink,
4106+ "klips_debug:ipsec_callback: "
4107+ "EMT_GRPSPI Tunnel Descriptor Block not found for SA:\n"
4108+ "klips_debug: %s, could not group.\n", sa);
4109+ spin_unlock_bh(&tdb_lock);
4110+ SENDERR(ENXIO);
4111+ } else {
4112+ if(tdbp->tdb_inext || tdbp->tdb_onext) {
4113+ KLIPS_PRINT(debug_netlink,
4114+ "klips_debug:ipsec_callback: "
4115+ "EMT_GRPSPI Tunnel Descriptor Block already grouped\n"
4116+ "klips_debug: for SA: %s, can't regroup.\n", sa);
4117+ spin_unlock_bh(&tdb_lock);
4118+ SENDERR(EBUSY);
4119+ }
4120+ em->em_rel[i].emr_tdb = tdbp;
4121+ }
4122+ }
4123+ tprev = em->em_rel[0].emr_tdb;
4124+ tprev->tdb_inext = NULL;
4125+ for (i = 1; i < nspis; i++) {
4126+ tdbp = em->em_rel[i].emr_tdb;
4127+ tprev->tdb_onext = tdbp;
4128+ tdbp->tdb_inext = tprev;
4129+ tprev = tdbp;
4130+ }
4131+ tprev->tdb_onext = NULL;
4132+
4133+ spin_unlock_bh(&tdb_lock);
4134+
4135+ error = 0;
4136+ break;
4137+
4138+ case EMT_UNGRPSPIS:
4139+ if (len != (8 + (sizeof(struct sa_id) + sizeof(struct tdb *)) /* 12 */) ) {
4140+ printk("klips_debug:ipsec_callback: "
4141+ "EMT_UNGRPSPIS message size incorrect, expected %d, got %d.\n",
4142+ 8 + (sizeof(struct sa_id) + sizeof(struct tdb *)),
4143+ len);
4144+ SENDERR(EINVAL);
4145+ break;
4146+ }
4147+
4148+ spin_lock_bh(&tdb_lock);
4149+
4150+ if ((tdbp = gettdb(&(em->em_rel[0].emr_said))) == NULL) {
4151+ KLIPS_PRINT(debug_netlink,
4152+ "klips_debug:ipsec_callback: "
4153+ "EMT_UGRPSPI Tunnel Descriptor Block not found for SA:\n"
4154+ "klips_debug: %s, could not ungroup.\n", sa);
4155+ spin_unlock_bh(&tdb_lock);
4156+ SENDERR(ENXIO);
4157+ }
4158+ while(tdbp->tdb_onext) {
4159+ tdbp = tdbp->tdb_onext;
4160+ }
4161+ while(tdbp->tdb_inext) {
4162+ tprev = tdbp;
4163+ tdbp = tdbp->tdb_inext;
4164+ tprev->tdb_inext = NULL;
4165+ tdbp->tdb_onext = NULL;
4166+ }
4167+
4168+ spin_unlock_bh(&tdb_lock);
4169+
4170+ break;
4171+
4172+ case EMT_CLRSPIS:
4173+ KLIPS_PRINT(debug_netlink,
4174+ "klips_debug:ipsec_callback: spi clear called.\n");
4175+ if (em->em_if >= 5) /* XXX -- why 5? */
4176+ SENDERR(ENODEV);
4177+ ipsec_tdbcleanup(0);
4178+ break;
4179+ default:
4180+ KLIPS_PRINT(debug_netlink,
4181+ "klips_debug:ipsec_callback: unknown message type\n");
4182+ SENDERR(EINVAL);
4183+ }
4184+ errlab:
4185+#ifdef NET_21
4186+ kfree_skb(skb);
4187+#else /* NET_21 */
4188+ kfree_skb(skb, FREE_WRITE);
4189+#endif /* NET_21 */
4190+ return len;
4191+}
4192+#endif
4193+
4194+/*
4195+ * $Log$
4196+ * Revision 1.47 2000/11/06 04:32:08 rgb
4197+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
4198+ *
4199+ * Revision 1.46 2000/09/08 19:16:50 rgb
4200+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
4201+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
4202+ *
4203+ * Revision 1.45 2000/08/30 05:23:55 rgb
4204+ * Compiler-define out ipsec_callback() function of ipsec_netlink.c.
4205+ * Nothing should be using it anyways.
4206+ *
4207+ * Revision 1.44 2000/03/16 14:01:26 rgb
4208+ * Indented headers for readability.
4209+ *
4210+ * Revision 1.43 2000/03/16 07:13:04 rgb
4211+ * Hardcode PF_KEYv2 support.
4212+ * Disable NET_LINK support.
4213+ *
4214+ * Revision 1.42 2000/01/21 06:14:27 rgb
4215+ * Moved debug message for expected output on set or clear.
4216+ *
4217+ * Revision 1.41 1999/12/01 22:14:37 rgb
4218+ * Added debugging message for bad netlink magic.
4219+ * Initialise tdb_sastate to MATURE (1).
4220+ * Added UNGRPSPIS bad length debugging message.
4221+ *
4222+ * Revision 1.40 1999/11/23 23:06:25 rgb
4223+ * Sort out pfkey and freeswan headers, putting them in a library path.
4224+ *
4225+ * Revision 1.39 1999/11/18 04:09:18 rgb
4226+ * Replaced all kernel version macros to shorter, readable form.
4227+ *
4228+ * Revision 1.38 1999/11/17 15:53:39 rgb
4229+ * Changed all occurrences of #include "../../../lib/freeswan.h"
4230+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
4231+ * klips/net/ipsec/Makefile.
4232+ *
4233+ * Revision 1.37 1999/10/26 13:58:32 rgb
4234+ * Put spinlock flags variable declaration outside the debug compiler
4235+ * directive to enable compilation with debug shut off.
4236+ *
4237+ * Revision 1.36 1999/10/16 18:24:22 rgb
4238+ * Initialize lifetime_addtime_c and lifetime_allocations_c.
4239+ * Clean-up unused cruft.
4240+ *
4241+ * Revision 1.35 1999/10/08 18:37:34 rgb
4242+ * Fix end-of-line spacing to sate whining PHMs.
4243+ *
4244+ * Revision 1.34 1999/10/03 18:49:11 rgb
4245+ * Spinlock fixes for 2.0.xx and 2.3.xx.
4246+ *
4247+ * Revision 1.33 1999/10/01 15:44:53 rgb
4248+ * Move spinlock header include to 2.1> scope.
4249+ *
4250+ * Revision 1.32 1999/10/01 00:00:53 rgb
4251+ * Fix for proper netlink debugging operation.
4252+ * Added tdb structure locking.
4253+ * Minor formatting changes.
4254+ *
4255+ * Revision 1.31 1999/05/25 21:21:43 rgb
4256+ * Fix deltdbchain() error return code checking.
4257+ *
4258+ * Revision 1.30 1999/05/09 03:25:36 rgb
4259+ * Fix bug introduced by 2.2 quick-and-dirty patch.
4260+ *
4261+ * Revision 1.29 1999/05/08 21:23:27 rgb
4262+ * Simplify satoa() calling.
4263+ * Fix error return reporting.
4264+ * Add casting to silence the 2.2.x compile.
4265+ *
4266+ * Revision 1.28 1999/05/05 22:02:31 rgb
4267+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
4268+ *
4269+ * Revision 1.27 1999/04/29 15:16:24 rgb
4270+ * Add pfkey support to debugging.
4271+ * Change gettdb parameter to a pointer to reduce stack loading and
4272+ * facilitate
4273+ * parameter sanity checking.
4274+ * Add IS_MYADDR support obviating the necessity of doing this in user
4275+ * space.
4276+ * Fix undetected bug by moving puttdb in SETSPI until after initialisation
4277+ * to
4278+ * prevent tdb usage before it is ready and to save work if it does not
4279+ * initialise.
4280+ * Clean up deltdb/wipe code.
4281+ * Fix undetected bug of returning error as positive value.
4282+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
4283+ *
4284+ * Revision 1.26 1999/04/16 15:39:35 rgb
4285+ * Fix already fixed unbalanced #endif.
4286+ *
4287+ * Revision 1.25 1999/04/15 15:37:24 rgb
4288+ * Forward check changes from POST1_00 branch.
4289+ *
4290+ * Revision 1.21.2.1 1999/04/13 20:30:26 rgb
4291+ * Add experimental 'getdebug'.
4292+ *
4293+ * Revision 1.24 1999/04/11 00:28:58 henry
4294+ * GPL boilerplate
4295+ *
4296+ * Revision 1.23 1999/04/07 17:44:21 rgb
4297+ * Fix ipsec_callback memory leak, skb not freed after use.
4298+ *
4299+ * Revision 1.22 1999/04/06 04:54:26 rgb
4300+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
4301+ * patch shell fixes.
4302+ *
4303+ * Revision 1.21 1999/02/17 16:50:11 rgb
4304+ * Consolidate satoa()s for space and speed efficiency.
4305+ * Convert DEBUG_IPSEC to KLIPS_PRINT
4306+ * Clean out unused cruft.
4307+ *
4308+ * Revision 1.20 1999/01/28 23:20:49 rgb
4309+ * Replace hard-coded numbers in macros and code with meaningful values
4310+ * automatically generated from sizeof() and offsetof() to further the
4311+ * goal of platform independance.
4312+ *
4313+ * Revision 1.19 1999/01/26 02:07:07 rgb
4314+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
4315+ * Remove ah/esp switching on include files.
4316+ * Removed dead code.
4317+ *
4318+ * Revision 1.18 1999/01/22 06:20:36 rgb
4319+ * Cruft clean-out.
4320+ * 64-bit clean-up.
4321+ * Added algorithm switch code.
4322+ *
4323+ * Revision 1.17 1998/12/02 03:09:39 rgb
4324+ * Clean up debug printing conditionals to compile with debugging off.
4325+ *
4326+ * Revision 1.16 1998/12/01 05:56:57 rgb
4327+ * Add support for debug printing of version info.
4328+ * Fail on unknown error for breakroute in replace command.
4329+ *
4330+ * Revision 1.15 1998/11/30 13:22:54 rgb
4331+ * Rationalised all the klips kernel file headers. They are much shorter
4332+ * now and won't conflict under RH5.2.
4333+ *
4334+ * Revision 1.14 1998/11/10 05:36:14 rgb
4335+ * Clean up debug output.
4336+ * Add direction to spi setup debug code.
4337+ * Add support for SA direction flag.
4338+ *
4339+ * Revision 1.13 1998/10/31 06:51:56 rgb
4340+ * Get zeroize to return something useful.
4341+ * Clean up code to isolate 'spi --add/del' memory leak.
4342+ * Fixed up comments in #endif directives.
4343+ *
4344+ * Revision 1.12 1998/10/27 00:35:02 rgb
4345+ * Supressed debug output during normal operation.
4346+ *
4347+ * Revision 1.11 1998/10/25 02:40:21 rgb
4348+ * Selective debug printing, depending upon called service.
4349+ * Institute more precise error return codes from eroute commands.
4350+ * Fix bug in size of stucture passed in from user space for grpspi command.
4351+ *
4352+ * Revision 1.10 1998/10/22 06:44:58 rgb
4353+ * Convert to use satoa for printk.
4354+ * Moved break; in 'set debug level code to avoid undetected bug.
4355+ * Fixed run-on error message to fit 80 columns.
4356+ *
4357+ * Revision 1.9 1998/10/19 14:44:28 rgb
4358+ * Added inclusion of freeswan.h.
4359+ * sa_id structure implemented and used: now includes protocol.
4360+ *
4361+ * Revision 1.8 1998/10/09 04:29:51 rgb
4362+ * Added support for '-replace' option to eroute.
4363+ * Fixed spiungroup bug.
4364+ * Added 'klips_debug' prefix to all klips printk debug statements.
4365+ *
4366+ * Revision 1.7 1998/08/12 00:10:06 rgb
4367+ * Fixed minor error return code syntax.
4368+ *
4369+ * Revision 1.6 1998/07/29 20:22:57 rgb
4370+ * Cosmetic cleanup.
4371+ *
4372+ * Revision 1.5 1998/07/27 21:53:11 rgb
4373+ * Check for proper return code from eroute clear command.
4374+ * Use appropriate error return codes from kernel.
4375+ * Add an option to clear the SA table.
4376+ *
4377+ * Revision 1.4 1998/07/14 18:02:40 rgb
4378+ * Add a command to clear the eroute table.
4379+ * Clean up some error codes.
4380+ *
4381+ * Revision 1.3 1998/06/25 19:52:33 rgb
4382+ * Code cosmetic changes only.
4383+ *
4384+ * Revision 1.2 1998/06/23 02:57:58 rgb
4385+ * Clean up after an error condition in setspi.
4386+ *
4387+ * Revision 1.9 1998/06/18 21:29:06 henry
4388+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
4389+ * build scripts happier in presence of symbolic links
4390+ *
4391+ * Revision 1.8 1998/06/08 17:57:15 rgb
4392+ * Very minor spacing change.
4393+ *
4394+ * Revision 1.7 1998/05/18 21:46:45 rgb
4395+ * Clean up for numerical consistency of output.
4396+ *
4397+ * Added debugging switch output.
4398+ *
4399+ * SETSPI will refuse to overwrite a previous SA. This is to make it
4400+ * consistent with the eroute command.
4401+ *
4402+ * spidel now deletes entire chain of spi's.
4403+ *
4404+ * spigrp can now ungroup a set of spi's.
4405+ *
4406+ * spigrp will not regroup a previously grouped spi.
4407+ *
4408+ * Key data is properly cleaned up, ie. zeroed.
4409+ *
4410+ * Revision 1.6 1998/05/07 20:36:27 rgb
4411+ * Fixed case where debugging not enabled that caused ipsec_netlink.c to
4412+ * not compile.
4413+ *
4414+ * Revision 1.5 1998/05/06 03:34:21 rgb
4415+ * Updated debugging output statements.
4416+ *
4417+ * Revision 1.4 1998/04/23 21:03:59 rgb
4418+ * Completed kernel development for userspace access to klips kernel debugging
4419+ * switches.
4420+ * Added detail to the kernel error message when trying to group non-existant
4421+ * spi's.
4422+ *
4423+ * Revision 1.3 1998/04/21 21:29:06 rgb
4424+ * Rearrange debug switches to change on the fly debug output from user
4425+ * space. Only kernel changes checked in at this time. radij.c was also
4426+ * changed to temporarily remove buggy debugging code in rj_delete causing
4427+ * an OOPS and hence, netlink device open errors.
4428+ *
4429+ * Revision 1.2 1998/04/12 22:03:23 rgb
4430+ * Updated ESP-3DES-HMAC-MD5-96,
4431+ * ESP-DES-HMAC-MD5-96,
4432+ * AH-HMAC-MD5-96,
4433+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
4434+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
4435+ *
4436+ * Fixed eroute references in /proc/net/ipsec*.
4437+ *
4438+ * Started to patch module unloading memory leaks in ipsec_netlink and
4439+ * radij tree unloading.
4440+ *
4441+ * Revision 1.1 1998/04/09 03:06:08 henry
4442+ * sources moved up from linux/net/ipsec
4443+ *
4444+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
4445+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
4446+ *
4447+ * Revision 0.4 1997/01/15 01:28:15 ji
4448+ * No changes.
4449+ *
4450+ * Revision 0.3 1996/11/20 14:39:04 ji
4451+ * Minor cleanups.
4452+ * Rationalized debugging code.
4453+ *
4454+ * Revision 0.2 1996/11/02 00:18:33 ji
4455+ * First limited release.
4456+ *
4457+ *
4458+ */
4459diff -druN linux-noipsec/net/ipsec/ipsec_netlink.h linux/net/ipsec/ipsec_netlink.h
4460--- linux-noipsec/net/ipsec/ipsec_netlink.h Thu Jan 1 01:00:00 1970
4461+++ linux/net/ipsec/ipsec_netlink.h Tue Oct 10 22:10:18 2000
4462@@ -0,0 +1,330 @@
4463+/*
4464+ * IPSEC <> netlink interface
4465+ * Copyright (C) 1996, 1997 John Ioannidis.
4466+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
4467+ *
4468+ * This program is free software; you can redistribute it and/or modify it
4469+ * under the terms of the GNU General Public License as published by the
4470+ * Free Software Foundation; either version 2 of the License, or (at your
4471+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4472+ *
4473+ * This program is distributed in the hope that it will be useful, but
4474+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4475+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4476+ * for more details.
4477+ *
4478+ * RCSID $Id$
4479+ */
4480+
4481+#include <linux/stddef.h>
4482+
4483+#ifndef NETLINK_IPSEC
4484+#define NETLINK_IPSEC 10 /* IPSEC */
4485+#endif /* !NETLINK_IPSEC */
4486+
4487+#define EM_MAXRELSPIS 4 /* at most five chained xforms */
4488+#define EM_MAGIC 0x5377616e /* "Swan" */
4489+
4490+#define EMT_IFADDR 1 /* set enc if addr */
4491+#define EMT_SETSPI 2 /* Set SPI properties */
4492+#define EMT_DELSPI 3 /* Delete an SPI */
4493+#define EMT_GRPSPIS 4 /* Group SPIs (output order) */
4494+#define EMT_SETEROUTE 5 /* set an extended route */
4495+#define EMT_DELEROUTE 6 /* del an extended route */
4496+#define EMT_TESTROUTE 7 /* try to find route, print to console */
4497+#define EMT_SETDEBUG 8 /* set debug level if active */
4498+#define EMT_UNGRPSPIS 9 /* UnGroup SPIs (output order) */
4499+#define EMT_CLREROUTE 10 /* clear the extended route table */
4500+#define EMT_CLRSPIS 11 /* clear the spi table */
4501+#define EMT_RPLACEROUTE 12 /* set an extended route */
4502+#define EMT_GETDEBUG 13 /* get debug level if active */
4503+
4504+#ifdef CONFIG_IPSEC_DEBUG
4505+#define DB_NL_TDBCB 0x0001
4506+#endif /* CONFIG_IPSEC_DEBUG */
4507+
4508+/* em_flags constants */
4509+/* be mindful that this flag conflicts with SADB_SAFLAGS_PFS in pfkeyv2 */
4510+/* perhaps it should be moved... */
4511+#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
4512+
4513+struct encap_msghdr
4514+{
4515+ __u32 em_magic; /* EM_MAGIC */
4516+#if 0
4517+ __u16 em_msglen; /* message length */
4518+#endif
4519+ __u8 em_msglen; /* message length */
4520+ __u8 em_flags; /* message flags */
4521+ __u8 em_version; /* for future expansion */
4522+ __u8 em_type; /* message type */
4523+ union
4524+ {
4525+ __u8 C; /* Free-text */
4526+
4527+ struct
4528+ {
4529+ struct sa_id Said; /* SA ID */
4530+ struct sockaddr_encap Eaddr;
4531+ struct sockaddr_encap Emask;
4532+ } Ert;
4533+
4534+ struct
4535+ {
4536+ struct in_addr Ia;
4537+ __u8 Ifn;
4538+ __u8 xxx[3]; /* makes life a lot easier */
4539+ } Ifa;
4540+
4541+ struct
4542+ {
4543+ struct sa_id Said; /* SA ID */
4544+ int If; /* enc i/f for input */
4545+ int Alg; /* Algorithm to use */
4546+
4547+ /* The following union is a surrogate for
4548+ * algorithm-specific data. To insure
4549+ * proper alignment, worst-case fields
4550+ * should be included. It would be even
4551+ * better to include the types that will
4552+ * actually be used, but they may not be
4553+ * defined for each use of this header.
4554+ * The actual length is expected to be longer
4555+ * than is declared here. References are normally
4556+ * made using the em_dat macro, as if it were a
4557+ * field name.
4558+ */
4559+ union { /* Data */
4560+ __u8 Dat[1];
4561+ __u64 Datq[1]; /* maximal alignment (?) */
4562+ } u;
4563+ } Xfm;
4564+
4565+ struct
4566+ {
4567+ struct sa_id emr_said; /* SA ID */
4568+ struct tdb * emr_tdb; /* used internally! */
4569+
4570+ } Rel[EM_MAXRELSPIS];
4571+
4572+#ifdef CONFIG_IPSEC_DEBUG
4573+ struct
4574+ {
4575+ int debug_tunnel;
4576+ int debug_netlink;
4577+ int debug_xform;
4578+ int debug_eroute;
4579+ int debug_spi;
4580+ int debug_radij;
4581+ int debug_esp;
4582+ int debug_ah;
4583+ int debug_rcv;
4584+ int debug_pfkey;
4585+ int debug_ipcomp;
4586+ int debug_verbose;
4587+ } Dbg;
4588+#endif /* CONFIG_IPSEC_DEBUG */
4589+ } Eu;
4590+};
4591+
4592+#define EM_MINLEN offsetof(struct encap_msghdr, Eu)
4593+#define EMT_SETSPI_FLEN offsetof(struct encap_msghdr, em_dat)
4594+#define EMT_GRPSPIS_FLEN offsetof(struct encap_msghdr, Eu.Rel)
4595+#define EMT_SETDEBUG_FLEN (offsetof(struct encap_msghdr, Eu.Dbg + \
4596+ sizeof(((struct encap_msghdr*)0)->Eu.Dbg)))
4597+
4598+#define em_c Eu.C
4599+#define em_eaddr Eu.Ert.Eaddr
4600+#define em_emask Eu.Ert.Emask
4601+#define em_ersaid Eu.Ert.Said
4602+#define em_erdst Eu.Ert.Said.dst
4603+#define em_erspi Eu.Ert.Said.spi
4604+#define em_erproto Eu.Ert.Said.proto
4605+
4606+#define em_ifa Eu.Ifa.Ia
4607+#define em_ifn Eu.Ifa.Ifn
4608+
4609+#define em_said Eu.Xfm.Said
4610+#define em_spi Eu.Xfm.Said.spi
4611+#define em_dst Eu.Xfm.Said.dst
4612+#define em_proto Eu.Xfm.Said.proto
4613+#define em_if Eu.Xfm.If
4614+#define em_alg Eu.Xfm.Alg
4615+#define em_dat Eu.Xfm.u.Dat
4616+
4617+#define em_rel Eu.Rel
4618+#define emr_dst emr_said.dst
4619+#define emr_spi emr_said.spi
4620+#define emr_proto emr_said.proto
4621+
4622+#ifdef CONFIG_IPSEC_DEBUG
4623+#define em_db_tn Eu.Dbg.debug_tunnel
4624+#define em_db_nl Eu.Dbg.debug_netlink
4625+#define em_db_xf Eu.Dbg.debug_xform
4626+#define em_db_er Eu.Dbg.debug_eroute
4627+#define em_db_sp Eu.Dbg.debug_spi
4628+#define em_db_rj Eu.Dbg.debug_radij
4629+#define em_db_es Eu.Dbg.debug_esp
4630+#define em_db_ah Eu.Dbg.debug_ah
4631+#define em_db_rx Eu.Dbg.debug_rcv
4632+#define em_db_ky Eu.Dbg.debug_pfkey
4633+#define em_db_gz Eu.Dbg.debug_ipcomp
4634+#define em_db_vb Eu.Dbg.debug_verbose
4635+#endif /* CONFIG_IPSEC_DEBUG */
4636+
4637+#ifdef __KERNEL__
4638+extern char ipsec_netlink_c_version[];
4639+#ifndef KERNEL_VERSION
4640+# include <linux/version.h>
4641+#endif
4642+#ifdef NETLINK_SOCK
4643+extern int ipsec_callback(int proto, struct sk_buff *skb);
4644+#else /* NETLINK_SOCK */
4645+extern int ipsec_callback(struct sk_buff *skb);
4646+#endif /* NETLINK_SOCK */
4647+extern void ipsec_print_ip(struct iphdr *ip);
4648+
4649+#ifdef CONFIG_IPSEC_DEBUG
4650+ #define KLIPS_PRINT(flag, format, args...) \
4651+ ((flag) ? printk(KERN_INFO format , ## args) : 0)
4652+ #define KLIPS_PRINTMORE(flag, format, args...) \
4653+ ((flag) ? printk(format , ## args) : 0)
4654+ #define KLIPS_IP_PRINT(flag, ip) \
4655+ ((flag) ? ipsec_print_ip(ip) : 0)
4656+#else /* CONFIG_IPSEC_DEBUG */
4657+ #define KLIPS_PRINT(flag, format, args...) do ; while(0)
4658+ #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
4659+ #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
4660+#endif /* CONFIG_IPSEC_DEBUG */
4661+
4662+#ifdef CONFIG_IPSEC_DEBUG
4663+extern int debug_netlink;
4664+#endif /* CONFIG_IPSEC_DEBUG */
4665+#endif /* __KERNEL__ */
4666+
4667+/*
4668+ * $Log$
4669+ * Revision 1.28 2000/10/10 20:10:18 rgb
4670+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
4671+ *
4672+ * Revision 1.27 2000/09/12 03:20:28 rgb
4673+ * Cleared out now unused pfkeyv2 switch.
4674+ *
4675+ * Revision 1.26 2000/09/08 19:16:50 rgb
4676+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
4677+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
4678+ *
4679+ * Revision 1.25 2000/08/24 16:51:59 rgb
4680+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
4681+ * info.
4682+ *
4683+ * Revision 1.24 2000/08/09 20:43:34 rgb
4684+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
4685+ *
4686+ * Revision 1.23 2000/03/16 14:01:48 rgb
4687+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
4688+ *
4689+ * Revision 1.22 1999/12/08 20:31:32 rgb
4690+ * Moved IPPROTO_COMP to lib/freeswan.h to simplify userspace includes.
4691+ *
4692+ * Revision 1.21 1999/11/18 18:47:41 rgb
4693+ * Added "#define NETLINK_IPSEC" in case kernel was not compiled with it.
4694+ *
4695+ * Revision 1.20 1999/11/18 04:09:18 rgb
4696+ * Replaced all kernel version macros to shorter, readable form.
4697+ *
4698+ * Revision 1.19 1999/08/28 08:27:05 rgb
4699+ * Add a temporary kludge for 2.0.37-38 to compile even if one patch failed.
4700+ *
4701+ * Revision 1.18 1999/08/03 17:09:33 rgb
4702+ * Tidy up debug output, use KERN_INFO macro in printk's.
4703+ *
4704+ * Revision 1.17 1999/05/25 01:45:37 rgb
4705+ * Fix version macros for 2.0.x as a module.
4706+ *
4707+ * Revision 1.16 1999/05/05 22:02:31 rgb
4708+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
4709+ *
4710+ * Revision 1.15 1999/04/29 15:16:55 rgb
4711+ * Add pfkey support to debugging.
4712+ *
4713+ * Revision 1.14 1999/04/15 15:37:24 rgb
4714+ * Forward check changes from POST1_00 branch.
4715+ *
4716+ * Revision 1.13 1999/04/11 00:28:58 henry
4717+ * GPL boilerplate
4718+ *
4719+ * Revision 1.12 1999/04/06 04:54:26 rgb
4720+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
4721+ * patch shell fixes.
4722+ *
4723+ * Revision 1.11 1999/02/12 21:13:17 rgb
4724+ * Moved KLIPS_PRINT into a more accessible place.
4725+ *
4726+ * Revision 1.10 1999/01/28 23:20:49 rgb
4727+ * Replace hard-coded numbers in macros and code with meaningful values
4728+ * automatically generated from sizeof() and offsetof() to further the
4729+ * goal of platform independance.
4730+ *
4731+ * Revision 1.9 1999/01/22 06:21:23 rgb
4732+ * Added algorithm switch code.
4733+ * Cruft clean-out.
4734+ * 64-bit clean-up.
4735+ *
4736+ * Revision 1.8 1998/12/01 05:57:42 rgb
4737+ * Add support for printing debug version info.
4738+ *
4739+ * Revision 1.7 1998/11/10 05:37:35 rgb
4740+ * Add support for SA direction flag.
4741+ *
4742+ * Revision 1.6 1998/10/25 02:40:45 rgb
4743+ * Fix bug in size of stucture passed in from user space for grpspi command.
4744+ *
4745+ * Revision 1.5 1998/10/19 14:44:29 rgb
4746+ * Added inclusion of freeswan.h.
4747+ * sa_id structure implemented and used: now includes protocol.
4748+ *
4749+ * Revision 1.4 1998/10/09 04:30:11 rgb
4750+ * Added support for '-replace' option to eroute.
4751+ *
4752+ * Revision 1.3 1998/07/27 21:54:22 rgb
4753+ * Rearrange structures for consistent alignment within a union.
4754+ * Add an option for clearing SA table.
4755+ *
4756+ * Revision 1.2 1998/07/14 18:05:51 rgb
4757+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
4758+ *
4759+ * Revision 1.1 1998/06/18 21:27:49 henry
4760+ * move sources from klips/src to klips/net/ipsec, to keep stupid
4761+ * kernel-build scripts happier in the presence of symlinks
4762+ *
4763+ * Revision 1.4 1998/05/18 21:48:24 rgb
4764+ * Added switch for ungrouping spi's.
4765+ *
4766+ * Revision 1.3 1998/04/23 21:01:50 rgb
4767+ * Added a macro for userspace access to klips kernel debugging switches.
4768+ *
4769+ * Revision 1.2 1998/04/21 21:29:09 rgb
4770+ * Rearrange debug switches to change on the fly debug output from user
4771+ * space. Only kernel changes checked in at this time. radij.c was also
4772+ * changed to temporarily remove buggy debugging code in rj_delete causing
4773+ * an OOPS and hence, netlink device open errors.
4774+ *
4775+ * Revision 1.1 1998/04/09 03:06:09 henry
4776+ * sources moved up from linux/net/ipsec
4777+ *
4778+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
4779+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
4780+ *
4781+ * Revision 0.4 1997/01/15 01:28:15 ji
4782+ * No changes.
4783+ *
4784+ * Revision 0.3 1996/11/20 14:39:04 ji
4785+ * Minor cleanups.
4786+ * Rationalized debugging code.
4787+ *
4788+ * Revision 0.2 1996/11/02 00:18:33 ji
4789+ * First limited release.
4790+ *
4791+ *
4792+ */
4793diff -druN linux-noipsec/net/ipsec/ipsec_radij.c linux/net/ipsec/ipsec_radij.c
4794--- linux-noipsec/net/ipsec/ipsec_radij.c Thu Jan 1 01:00:00 1970
4795+++ linux/net/ipsec/ipsec_radij.c Mon Nov 6 05:32:08 2000
4796@@ -0,0 +1,510 @@
4797+/*
4798+ * Interface between the IPSEC code and the radix (radij) tree code
4799+ * Copyright (C) 1996, 1997 John Ioannidis.
4800+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
4801+ *
4802+ * This program is free software; you can redistribute it and/or modify it
4803+ * under the terms of the GNU General Public License as published by the
4804+ * Free Software Foundation; either version 2 of the License, or (at your
4805+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4806+ *
4807+ * This program is distributed in the hope that it will be useful, but
4808+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4809+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4810+ * for more details.
4811+ *
4812+ * RCSID $Id$
4813+ */
4814+
4815+#include <linux/config.h>
4816+#include <linux/version.h>
4817+
4818+#include <linux/kernel.h> /* printk() */
4819+#include <linux/malloc.h> /* kmalloc() */
4820+#include <linux/errno.h> /* error codes */
4821+#include <linux/types.h> /* size_t */
4822+#include <linux/interrupt.h> /* mark_bh */
4823+
4824+#include <linux/netdevice.h> /* struct device, and other headers */
4825+#include <linux/etherdevice.h> /* eth_type_trans */
4826+#include <linux/ip.h> /* struct iphdr */
4827+#include <linux/skbuff.h>
4828+#include <freeswan.h>
4829+#ifdef SPINLOCK
4830+#ifdef SPINLOCK_23
4831+#include <linux/spinlock.h> /* *lock* */
4832+#else /* 23_SPINLOCK */
4833+#include <asm/spinlock.h> /* *lock* */
4834+#endif /* 23_SPINLOCK */
4835+#endif /* SPINLOCK */
4836+#ifdef NET_21
4837+#include <asm/uaccess.h>
4838+#include <linux/in6.h>
4839+#endif
4840+#include <asm/checksum.h>
4841+#include <net/ip.h>
4842+
4843+#include "radij.h"
4844+#include "ipsec_encap.h"
4845+#include "ipsec_radij.h"
4846+#include "ipsec_netlink.h"
4847+#include "ipsec_xform.h"
4848+
4849+#ifdef CONFIG_IPSEC_DEBUG
4850+int debug_radij = 0;
4851+#endif /* CONFIG_IPSEC_DEBUG */
4852+
4853+struct radij_node_head *rnh = 0;
4854+#ifdef SPINLOCK
4855+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
4856+#else /* SPINLOCK */
4857+spinlock_t eroute_lock;
4858+#endif /* SPINLOCK */
4859+
4860+int
4861+ipsec_radijinit(void)
4862+{
4863+ maj_keylen = sizeof (struct sockaddr_encap);
4864+
4865+ rj_init();
4866+
4867+ if (rj_inithead((void **)&rnh, 16) == 0) /* 16 is bit offset of sen_type */
4868+ return -1;
4869+ return 0;
4870+}
4871+
4872+int
4873+ipsec_radijcleanup(void)
4874+{
4875+ int error;
4876+
4877+ spin_lock_bh(&eroute_lock);
4878+
4879+ error = radijcleanup();
4880+
4881+ spin_unlock_bh(&eroute_lock);
4882+
4883+ return error;
4884+}
4885+
4886+int
4887+ipsec_cleareroutes(void)
4888+{
4889+ int error;
4890+
4891+ spin_lock_bh(&eroute_lock);
4892+
4893+ error = radijcleartree();
4894+
4895+ spin_unlock_bh(&eroute_lock);
4896+
4897+ return error;
4898+}
4899+
4900+int
4901+ipsec_breakroute(struct sockaddr_encap *eaddr, struct sockaddr_encap *emask)
4902+{
4903+ struct radij_node *rn;
4904+ int error;
4905+#ifdef CONFIG_IPSEC_DEBUG
4906+ char buf1[64], buf2[64];
4907+
4908+ if (debug_eroute) {
4909+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
4910+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
4911+ printk("klips_debug:ipsec_breakroute: attempting to delete eroute for %s->%s\n",
4912+ buf1, buf2);
4913+ }
4914+#endif /* CONFIG_IPSEC_DEBUG */
4915+
4916+ spin_lock_bh(&eroute_lock);
4917+
4918+ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
4919+ spin_unlock_bh(&eroute_lock);
4920+ KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_breakroute: "
4921+ "node not found, eroute delete failed.\n");
4922+ return error;
4923+ }
4924+
4925+ spin_unlock_bh(&eroute_lock);
4926+
4927+ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
4928+ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
4929+
4930+ memset((caddr_t)rn, 0, sizeof (struct eroute));
4931+ kfree(rn);
4932+
4933+ return 0;
4934+}
4935+
4936+int
4937+ipsec_makeroute(struct sockaddr_encap *eaddr, struct sockaddr_encap *emask, struct sa_id said)
4938+{
4939+ struct eroute *retrt;
4940+ int error;
4941+ char sa[SATOA_BUF];
4942+ size_t sa_len;
4943+#ifdef CONFIG_IPSEC_DEBUG
4944+ char buf1[64], buf2[64];
4945+
4946+ if (debug_eroute) {
4947+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
4948+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
4949+ sa_len = satoa(said, 0, sa, SATOA_BUF);
4950+ printk("klips_debug:ipsec_makeroute: attempting to insert eroute for %s->%s, SA: %s\n",
4951+ buf1, buf2, sa);
4952+ }
4953+#endif /* CONFIG_IPSEC_DEBUG */
4954+
4955+ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
4956+ if (retrt == NULL) {
4957+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory");
4958+ return ENOMEM;
4959+ }
4960+ memset((caddr_t)retrt, 0, sizeof (struct eroute));
4961+
4962+ retrt->er_eaddr = *eaddr;
4963+ retrt->er_emask = *emask;
4964+ retrt->er_said = said;
4965+ rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr);
4966+
4967+ spin_lock_bh(&eroute_lock);
4968+
4969+ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
4970+ rnh, retrt->er_rjt.rd_nodes);
4971+
4972+ spin_unlock_bh(&eroute_lock);
4973+
4974+ if(error) {
4975+ sa_len = satoa(said, 0, sa, SATOA_BUF);
4976+ printk("klips_debug:ipsec_makeroute: rj_addroute not able to insert eroute for SA:%s\n", sa);
4977+ kfree(retrt); /* XXX -- should we? */
4978+ return error;
4979+ }
4980+ KLIPS_PRINT(debug_eroute,
4981+ "klips_debug:ipsec_makeroute: succeeded, I think...\n");
4982+ return 0;
4983+}
4984+
4985+struct eroute *
4986+ipsec_findroute(struct sockaddr_encap *eaddr)
4987+{
4988+ struct radij_node *rn;
4989+#ifdef CONFIG_IPSEC_DEBUG
4990+ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
4991+
4992+ if (debug_radij & DB_RJ_FINDROUTE) {
4993+ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
4994+ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
4995+ printk("klips_debug:ipsec_findroute: %s->%s\n",
4996+ buf1, buf2);
4997+ }
4998+#endif /* CONFIG_IPSEC_DEBUG */
4999+ rn = rj_match((caddr_t)eaddr, rnh);
5000+ return (struct eroute *)rn;
5001+}
5002+
5003+#ifdef CONFIG_PROC_FS
5004+int
5005+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
5006+{
5007+ struct eroute *ro = (struct eroute *)rn;
5008+ struct rjtentry *rd = (struct rjtentry *)rn;
5009+ struct wsbuf *w = (struct wsbuf *)w0;
5010+ char buf1[64], buf2[64];
5011+ char sa[SATOA_BUF];
5012+ size_t sa_len;
5013+ struct sockaddr_encap *key, *mask;
5014+
5015+ KLIPS_PRINT(debug_radij,
5016+ "klips_debug:ipsec_rj_walker_procprint: rn=%p, w0=%p\n",
5017+ rn, w0);
5018+ if (rn == NULL) {
5019+ return 120;
5020+ }
5021+
5022+ if (rn->rj_b >= 0) {
5023+ return 0;
5024+ }
5025+
5026+ key = rd_key(rd);
5027+ mask = rd_mask(rd);
5028+
5029+ if ((key == 0) || (mask == 0)) {
5030+ return 0;
5031+ }
5032+
5033+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
5034+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
5035+ sa_len = satoa(ro->er_said, 0, sa, SATOA_BUF);
5036+ w->len += sprintf(w->buffer + w->len,
5037+ "%-18s -> %-18s => %s\n",
5038+ buf1, buf2, sa);
5039+
5040+ w->pos = w->begin + w->len;
5041+ if(w->pos < w->offset) {
5042+ w->len = 0;
5043+ w->begin = w->pos;
5044+ }
5045+ if (w->pos > w->offset + w->length) {
5046+ return -ENOBUFS;
5047+ }
5048+ return 0;
5049+}
5050+#endif /* CONFIG_PROC_FS */
5051+
5052+int
5053+ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
5054+{
5055+ struct rjtentry *rd = (struct rjtentry *)rn;
5056+ struct radij_node *rn2;
5057+ int error;
5058+ struct sockaddr_encap *key, *mask;
5059+#ifdef CONFIG_IPSEC_DEBUG
5060+ char buf1[64] = { 0 }, buf2[64] = { 0 };
5061+#endif /* CONFIG_IPSEC_DEBUG */
5062+
5063+ if (rn == NULL) {
5064+ return 120;
5065+ }
5066+
5067+ key = rd_key(rd);
5068+ mask = rd_mask(rd);
5069+
5070+ if(!key || !mask) {
5071+ return -1;
5072+ }
5073+#ifdef CONFIG_IPSEC_DEBUG
5074+ if(debug_radij) {
5075+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
5076+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
5077+ printk("klips_debug:ipsec_rj_walker_delete: deleting: %s -> %s\n",
5078+ buf1, buf2);
5079+ }
5080+#endif /* CONFIG_IPSEC_DEBUG */
5081+
5082+ if((error = rj_delete(key, mask, rnh, &rn2))) {
5083+ KLIPS_PRINT(debug_radij,
5084+ "klips_debug:ipsec_rj_walker_delete: "
5085+ "rj_delete failed with error=%d.\n", error);
5086+ return error;
5087+ }
5088+
5089+ if(rn2 != rn) {
5090+ printk("klips_debug:ipsec_rj_walker_delete: tried to delete a different node?!?"
5091+ "This should never happen!\n");
5092+ }
5093+ memset((caddr_t)rn, 0, sizeof (struct eroute));
5094+ kfree(rn);
5095+
5096+ return 0;
5097+}
5098+
5099+/*
5100+ * $Log$
5101+ * Revision 1.41 2000/11/06 04:32:08 rgb
5102+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
5103+ *
5104+ * Revision 1.40 2000/09/08 19:12:56 rgb
5105+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
5106+ *
5107+ * Revision 1.39 2000/08/30 05:25:20 rgb
5108+ * Correct debug text in ipsec_breakroute() from incorrect
5109+ * "ipsec_callback".
5110+ *
5111+ * Revision 1.38 2000/07/28 14:58:31 rgb
5112+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
5113+ *
5114+ * Revision 1.37 2000/03/16 14:02:50 rgb
5115+ * Fixed debug scope to enable compilation with debug off.
5116+ *
5117+ * Revision 1.36 2000/01/21 06:14:46 rgb
5118+ * Added debugging text to ipsec_rj_walker_delete().
5119+ * Set return code to negative for consistency.
5120+ *
5121+ * Revision 1.35 1999/11/23 23:05:24 rgb
5122+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
5123+ *
5124+ * Revision 1.34 1999/11/18 04:13:56 rgb
5125+ * Replaced all kernel version macros to shorter, readable form.
5126+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
5127+ *
5128+ * Revision 1.33 1999/11/17 15:53:39 rgb
5129+ * Changed all occurrences of #include "../../../lib/freeswan.h"
5130+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
5131+ * klips/net/ipsec/Makefile.
5132+ *
5133+ * Revision 1.32 1999/10/26 13:58:33 rgb
5134+ * Put spinlock flags variable declaration outside the debug compiler
5135+ * directive to enable compilation with debug shut off.
5136+ *
5137+ * Revision 1.31 1999/10/15 22:13:29 rgb
5138+ * Clean out cruft.
5139+ * Align /proc/net/ipsec_eroute output for easier readability.
5140+ * Fix double linefeed in radij debug output.
5141+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
5142+ *
5143+ * Revision 1.30 1999/10/08 18:37:33 rgb
5144+ * Fix end-of-line spacing to sate whining PHMs.
5145+ *
5146+ * Revision 1.29 1999/10/03 18:52:45 rgb
5147+ * Spinlock support for 2.0.xx.
5148+ * Dumb return code spin_unlock fix.
5149+ *
5150+ * Revision 1.28 1999/10/01 16:22:24 rgb
5151+ * Switch from assignment init. to functional init. of spinlocks.
5152+ *
5153+ * Revision 1.27 1999/10/01 15:44:53 rgb
5154+ * Move spinlock header include to 2.1> scope.
5155+ *
5156+ * Revision 1.26 1999/10/01 00:01:23 rgb
5157+ * Added eroute structure locking.
5158+ *
5159+ * Revision 1.25 1999/06/10 16:07:30 rgb
5160+ * Silence delete eroute on no debug.
5161+ *
5162+ * Revision 1.24 1999/05/09 03:25:36 rgb
5163+ * Fix bug introduced by 2.2 quick-and-dirty patch.
5164+ *
5165+ * Revision 1.23 1999/05/05 22:02:31 rgb
5166+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
5167+ *
5168+ * Revision 1.22 1999/04/29 15:17:23 rgb
5169+ * Add return values to init and cleanup functions.
5170+ * Add sanity checking for null pointer arguments.
5171+ *
5172+ * Revision 1.21 1999/04/11 00:28:58 henry
5173+ * GPL boilerplate
5174+ *
5175+ * Revision 1.20 1999/04/06 04:54:26 rgb
5176+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5177+ * patch shell fixes.
5178+ *
5179+ * Revision 1.19 1999/02/17 16:50:35 rgb
5180+ * Clean out unused cruft.
5181+ * Consolidate for space and speed efficiency.
5182+ * Convert DEBUG_IPSEC to KLIPS_PRINT
5183+ *
5184+ * Revision 1.18 1999/01/22 06:22:06 rgb
5185+ * Cruft clean-out.
5186+ * 64-bit clean-up.
5187+ *
5188+ * Revision 1.17 1998/12/02 03:09:39 rgb
5189+ * Clean up debug printing conditionals to compile with debugging off.
5190+ *
5191+ * Revision 1.16 1998/12/01 13:49:39 rgb
5192+ * Wrap version info printing in debug switches.
5193+ *
5194+ * Revision 1.15 1998/11/30 13:22:54 rgb
5195+ * Rationalised all the klips kernel file headers. They are much shorter
5196+ * now and won't conflict under RH5.2.
5197+ *
5198+ * Revision 1.14 1998/10/31 06:48:17 rgb
5199+ * Fixed up comments in #endif directives.
5200+ *
5201+ * Revision 1.13 1998/10/27 13:48:09 rgb
5202+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
5203+ * Fixed less(1) truncated output bug.
5204+ * Code clean-up.
5205+ *
5206+ * Revision 1.12 1998/10/25 02:41:36 rgb
5207+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
5208+ * argument to be able to transmit more infomation about errors.
5209+ * Fix cut-and-paste debug statement identifier.
5210+ *
5211+ * Revision 1.11 1998/10/22 06:45:39 rgb
5212+ * Cleaned up cruft.
5213+ * Convert to use satoa for printk.
5214+ *
5215+ * Revision 1.10 1998/10/19 14:44:28 rgb
5216+ * Added inclusion of freeswan.h.
5217+ * sa_id structure implemented and used: now includes protocol.
5218+ *
5219+ * Revision 1.9 1998/10/09 04:30:52 rgb
5220+ * Added 'klips_debug' prefix to all klips printk debug statements.
5221+ * Deleted old commented out cruft.
5222+ *
5223+ * Revision 1.8 1998/08/06 17:24:23 rgb
5224+ * Fix addrtoa return code bug from stale manpage advice preventing packets
5225+ * from being erouted.
5226+ *
5227+ * Revision 1.7 1998/08/06 07:44:59 rgb
5228+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
5229+ * ended up in nothing being printed.
5230+ *
5231+ * Revision 1.6 1998/08/05 22:16:41 rgb
5232+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
5233+ *
5234+ * Revision 1.5 1998/07/29 20:38:44 rgb
5235+ * Debug and fix subnettoa and addrtoa output.
5236+ *
5237+ * Revision 1.4 1998/07/28 00:02:39 rgb
5238+ * Converting to exclusive use of addrtoa.
5239+ * Fix eroute delete.
5240+ *
5241+ * Revision 1.3 1998/07/14 18:21:26 rgb
5242+ * Add function to clear the eroute table.
5243+ *
5244+ * Revision 1.2 1998/06/23 02:59:14 rgb
5245+ * Added debugging output to eroute add/delete routines.
5246+ *
5247+ * Revision 1.9 1998/06/18 21:29:06 henry
5248+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
5249+ * build scripts happier in presence of symbolic links
5250+ *
5251+ * Revision 1.8 1998/06/05 02:32:26 rgb
5252+ * Fix spi ntoh kernel debug output.
5253+ *
5254+ * Revision 1.7 1998/05/25 20:30:37 rgb
5255+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
5256+ *
5257+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
5258+ * add ipsec_rj_walker_delete.
5259+ *
5260+ * Revision 1.6 1998/05/21 13:08:57 rgb
5261+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
5262+ * information is available for printout.
5263+ *
5264+ * Revision 1.5 1998/05/18 21:35:55 rgb
5265+ * Clean up output for numerical consistency and readability. Zero freed
5266+ * eroute memory.
5267+ *
5268+ * Revision 1.4 1998/04/21 21:28:58 rgb
5269+ * Rearrange debug switches to change on the fly debug output from user
5270+ * space. Only kernel changes checked in at this time. radij.c was also
5271+ * changed to temporarily remove buggy debugging code in rj_delete causing
5272+ * an OOPS and hence, netlink device open errors.
5273+ *
5274+ * Revision 1.3 1998/04/14 17:30:39 rgb
5275+ * Fix up compiling errors for radij tree memory reclamation.
5276+ *
5277+ * Revision 1.2 1998/04/12 22:03:23 rgb
5278+ * Updated ESP-3DES-HMAC-MD5-96,
5279+ * ESP-DES-HMAC-MD5-96,
5280+ * AH-HMAC-MD5-96,
5281+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
5282+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
5283+ *
5284+ * Fixed eroute references in /proc/net/ipsec*.
5285+ *
5286+ * Started to patch module unloading memory leaks in ipsec_netlink and
5287+ * radij tree unloading.
5288+ *
5289+ * Revision 1.1 1998/04/09 03:06:10 henry
5290+ * sources moved up from linux/net/ipsec
5291+ *
5292+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
5293+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5294+ *
5295+ * Revision 0.4 1997/01/15 01:28:15 ji
5296+ * No changes.
5297+ *
5298+ * Revision 0.3 1996/11/20 14:39:04 ji
5299+ * Minor cleanups.
5300+ * Rationalized debugging code.
5301+ *
5302+ * Revision 0.2 1996/11/02 00:18:33 ji
5303+ * First limited release.
5304+ *
5305+ *
5306+ */
5307diff -druN linux-noipsec/net/ipsec/ipsec_radij.h linux/net/ipsec/ipsec_radij.h
5308--- linux-noipsec/net/ipsec/ipsec_radij.h Thu Jan 1 01:00:00 1970
5309+++ linux/net/ipsec/ipsec_radij.h Fri Sep 8 21:12:56 2000
5310@@ -0,0 +1,146 @@
5311+/*
5312+ * Definitions relevant to the IPSEC <> radij tree interfacing
5313+ * Copyright (C) 1996, 1997 John Ioannidis.
5314+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
5315+ *
5316+ * This program is free software; you can redistribute it and/or modify it
5317+ * under the terms of the GNU General Public License as published by the
5318+ * Free Software Foundation; either version 2 of the License, or (at your
5319+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5320+ *
5321+ * This program is distributed in the hope that it will be useful, but
5322+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5323+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5324+ * for more details.
5325+ *
5326+ * RCSID $Id$
5327+ */
5328+
5329+#include <freeswan.h>
5330+
5331+int ipsec_walk(char *);
5332+
5333+int ipsec_rj_walker_procprint(struct radij_node *, void *);
5334+int ipsec_rj_walker_delete(struct radij_node *, void *);
5335+
5336+struct wsbuf
5337+{
5338+ char *buffer;
5339+ int length;
5340+ off_t offset;
5341+ int len;
5342+ int prev_len;
5343+ off_t begin;
5344+ off_t pos;
5345+};
5346+
5347+#if 0
5348+struct eroute * ipsec_makeroute(struct sockaddr_encap *ea, struct sockaddr_encap *em, struct sa_id);
5349+#endif
5350+int ipsec_makeroute(struct sockaddr_encap *ea, struct sockaddr_encap *em, struct sa_id);
5351+
5352+#if 0
5353+struct eroute * ipsec_breakroute(struct sockaddr_encap *ea, struct sockaddr_encap *em);
5354+#endif
5355+int ipsec_breakroute(struct sockaddr_encap *ea, struct sockaddr_encap *em);
5356+
5357+int ipsec_radijinit(void);
5358+int ipsec_cleareroutes(void);
5359+int ipsec_radijcleanup(void);
5360+
5361+extern struct radij_node_head *rnh;
5362+extern spinlock_t eroute_lock;
5363+
5364+struct eroute * ipsec_findroute(struct sockaddr_encap *);
5365+
5366+#define O1(x) (int)(((x)>>24)&0xff)
5367+#define O2(x) (int)(((x)>>16)&0xff)
5368+#define O3(x) (int)(((x)>>8)&0xff)
5369+#define O4(x) (int)(((x))&0xff)
5370+
5371+#ifdef CONFIG_IPSEC_DEBUG
5372+extern int debug_radij;
5373+void rj_dumptrees(void);
5374+
5375+#define DB_RJ_DUMPTREES 0x0001
5376+#define DB_RJ_FINDROUTE 0x0002
5377+#endif /* CONFIG_IPSEC_DEBUG */
5378+
5379+/*
5380+ * $Log$
5381+ * Revision 1.11 2000/09/08 19:12:56 rgb
5382+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
5383+ *
5384+ * Revision 1.10 1999/11/17 15:53:39 rgb
5385+ * Changed all occurrences of #include "../../../lib/freeswan.h"
5386+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
5387+ * klips/net/ipsec/Makefile.
5388+ *
5389+ * Revision 1.9 1999/10/01 00:01:23 rgb
5390+ * Added eroute structure locking.
5391+ *
5392+ * Revision 1.8 1999/04/11 00:28:59 henry
5393+ * GPL boilerplate
5394+ *
5395+ * Revision 1.7 1999/04/06 04:54:26 rgb
5396+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5397+ * patch shell fixes.
5398+ *
5399+ * Revision 1.6 1999/01/22 06:23:26 rgb
5400+ * Cruft clean-out.
5401+ *
5402+ * Revision 1.5 1998/10/25 02:42:08 rgb
5403+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
5404+ * argument to be able to transmit more infomation about errors.
5405+ *
5406+ * Revision 1.4 1998/10/19 14:44:29 rgb
5407+ * Added inclusion of freeswan.h.
5408+ * sa_id structure implemented and used: now includes protocol.
5409+ *
5410+ * Revision 1.3 1998/07/28 00:03:31 rgb
5411+ * Comment out temporary inet_nto4u() kluge.
5412+ *
5413+ * Revision 1.2 1998/07/14 18:22:00 rgb
5414+ * Add function to clear the eroute table.
5415+ *
5416+ * Revision 1.1 1998/06/18 21:27:49 henry
5417+ * move sources from klips/src to klips/net/ipsec, to keep stupid
5418+ * kernel-build scripts happier in the presence of symlinks
5419+ *
5420+ * Revision 1.5 1998/05/25 20:30:38 rgb
5421+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
5422+ *
5423+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
5424+ * add ipsec_rj_walker_delete.
5425+ *
5426+ * Revision 1.4 1998/05/21 13:02:56 rgb
5427+ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
5428+ * limit fix.
5429+ *
5430+ * Revision 1.3 1998/04/21 21:29:09 rgb
5431+ * Rearrange debug switches to change on the fly debug output from user
5432+ * space. Only kernel changes checked in at this time. radij.c was also
5433+ * changed to temporarily remove buggy debugging code in rj_delete causing
5434+ * an OOPS and hence, netlink device open errors.
5435+ *
5436+ * Revision 1.2 1998/04/14 17:30:39 rgb
5437+ * Fix up compiling errors for radij tree memory reclamation.
5438+ *
5439+ * Revision 1.1 1998/04/09 03:06:10 henry
5440+ * sources moved up from linux/net/ipsec
5441+ *
5442+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
5443+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5444+ *
5445+ * Revision 0.4 1997/01/15 01:28:15 ji
5446+ * No changes.
5447+ *
5448+ * Revision 0.3 1996/11/20 14:39:04 ji
5449+ * Minor cleanups.
5450+ * Rationalized debugging code.
5451+ *
5452+ * Revision 0.2 1996/11/02 00:18:33 ji
5453+ * First limited release.
5454+ *
5455+ *
5456+ */
5457diff -druN linux-noipsec/net/ipsec/ipsec_rcv.c linux/net/ipsec/ipsec_rcv.c
5458--- linux-noipsec/net/ipsec/ipsec_rcv.c Thu Jan 1 01:00:00 1970
5459+++ linux/net/ipsec/ipsec_rcv.c Sat Nov 25 04:50:36 2000
5460@@ -0,0 +1,1973 @@
5461+/*
5462+ * receive code
5463+ * Copyright (C) 1996, 1997 John Ioannidis.
5464+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
5465+ *
5466+ * This program is free software; you can redistribute it and/or modify it
5467+ * under the terms of the GNU General Public License as published by the
5468+ * Free Software Foundation; either version 2 of the License, or (at your
5469+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5470+ *
5471+ * This program is distributed in the hope that it will be useful, but
5472+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5473+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5474+ * for more details.
5475+ */
5476+
5477+char ipsec_rcv_c_version[] = "RCSID $Id$";
5478+
5479+#include <linux/config.h>
5480+#include <linux/version.h>
5481+
5482+#define __NO_VERSION__
5483+#include <linux/module.h>
5484+
5485+#include <linux/kernel.h> /* printk() */
5486+#include <linux/malloc.h> /* kmalloc() */
5487+#include <linux/errno.h> /* error codes */
5488+#include <linux/types.h> /* size_t */
5489+#include <linux/interrupt.h> /* mark_bh */
5490+
5491+#include <linux/netdevice.h> /* struct device, and other headers */
5492+#include <linux/etherdevice.h> /* eth_type_trans */
5493+#include <linux/ip.h> /* struct iphdr */
5494+#include <linux/skbuff.h>
5495+#include <freeswan.h>
5496+#ifdef SPINLOCK
5497+#ifdef SPINLOCK_23
5498+#include <linux/spinlock.h> /* *lock* */
5499+#else /* SPINLOCK_23 */
5500+#include <asm/spinlock.h> /* *lock* */
5501+#endif /* SPINLOCK_23 */
5502+#endif /* SPINLOCK */
5503+#ifdef NET_21
5504+#include <asm/uaccess.h>
5505+#include <linux/in6.h>
5506+#define proto_priv cb
5507+#endif /* NET21 */
5508+#include <asm/checksum.h>
5509+#include <net/ip.h>
5510+
5511+#include "radij.h"
5512+#include "ipsec_encap.h"
5513+#include "ipsec_radij.h"
5514+#include "ipsec_netlink.h"
5515+#include "ipsec_xform.h"
5516+#include "ipsec_tunnel.h"
5517+#include "ipsec_rcv.h"
5518+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
5519+#include "ipsec_ah.h"
5520+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
5521+#ifdef CONFIG_IPSEC_ESP
5522+#include "ipsec_esp.h"
5523+#endif /* !CONFIG_IPSEC_ESP */
5524+#ifdef CONFIG_IPSEC_IPCOMP
5525+#include "ipcomp.h"
5526+#endif /* CONFIG_IPSEC_COMP */
5527+
5528+#include <pfkeyv2.h>
5529+#include <pfkey.h>
5530+
5531+#ifdef CONFIG_IPSEC_DEBUG
5532+int debug_ah = 0;
5533+int debug_esp = 0;
5534+int debug_rcv = 0;
5535+#endif /* CONFIG_IPSEC_DEBUG */
5536+
5537+int sysctl_ipsec_inbound_policy_check = 1;
5538+
5539+#ifdef CONFIG_IPSEC_ESP
5540+extern void des_ede3_cbc_encrypt(caddr_t, caddr_t, int, caddr_t, caddr_t, caddr_t, caddr_t, int);
5541+#endif /* !CONFIG_IPSEC_ESP */
5542+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
5543+__u32 zeroes[AH_AMAX];
5544+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
5545+
5546+/*
5547+ * Check-replay-window routine, adapted from the original
5548+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
5549+ *
5550+ * This is a routine that implements a 64 packet window. This is intend-
5551+ * ed on being an implementation sample.
5552+ */
5553+
5554+DEBUG_NO_STATIC int
5555+ipsec_checkreplaywindow(struct tdb*tdbp, __u32 seq)
5556+{
5557+ __u32 diff;
5558+
5559+ if (tdbp->tdb_replaywin == 0) /* replay shut off */
5560+ return 1;
5561+ if (seq == 0)
5562+ return 0; /* first == 0 or wrapped */
5563+
5564+ /* new larger sequence number */
5565+ if (seq > tdbp->tdb_replaywin_lastseq) {
5566+ return 1; /* larger is good */
5567+ }
5568+ diff = tdbp->tdb_replaywin_lastseq - seq;
5569+
5570+ /* too old or wrapped */ /* if wrapped, kill off SA? */
5571+ if (diff >= tdbp->tdb_replaywin) {
5572+ return 0;
5573+ }
5574+ /* this packet already seen */
5575+ if (tdbp->tdb_replaywin_bitmap & (1 << diff))
5576+ return 0;
5577+ return 1; /* out of order but good */
5578+}
5579+
5580+DEBUG_NO_STATIC int
5581+ipsec_updatereplaywindow(struct tdb*tdbp, __u32 seq)
5582+{
5583+ __u32 diff;
5584+
5585+ if (tdbp->tdb_replaywin == 0) /* replay shut off */
5586+ return 1;
5587+ if (seq == 0)
5588+ return 0; /* first == 0 or wrapped */
5589+
5590+ /* new larger sequence number */
5591+ if (seq > tdbp->tdb_replaywin_lastseq) {
5592+ diff = seq - tdbp->tdb_replaywin_lastseq;
5593+
5594+ /* In win, set bit for this pkt */
5595+ if (diff < tdbp->tdb_replaywin)
5596+ tdbp->tdb_replaywin_bitmap =
5597+ (tdbp->tdb_replaywin_bitmap << diff) | 1;
5598+ else
5599+ /* This packet has way larger seq num */
5600+ tdbp->tdb_replaywin_bitmap = 1;
5601+
5602+ if(seq - tdbp->tdb_replaywin_lastseq - 1 > tdbp->tdb_replaywin_maxdiff) {
5603+ tdbp->tdb_replaywin_maxdiff = seq - tdbp->tdb_replaywin_lastseq - 1;
5604+ }
5605+ tdbp->tdb_replaywin_lastseq = seq;
5606+ return 1; /* larger is good */
5607+ }
5608+ diff = tdbp->tdb_replaywin_lastseq - seq;
5609+
5610+ /* too old or wrapped */ /* if wrapped, kill off SA? */
5611+ if (diff >= tdbp->tdb_replaywin) {
5612+/*
5613+ if(seq < 0.25*max && tdbp->tdb_replaywin_lastseq > 0.75*max) {
5614+ deltdbchain(tdbp);
5615+ }
5616+*/
5617+ return 0;
5618+ }
5619+ /* this packet already seen */
5620+ if (tdbp->tdb_replaywin_bitmap & (1 << diff))
5621+ return 0;
5622+ tdbp->tdb_replaywin_bitmap |= (1 << diff); /* mark as seen */
5623+ return 1; /* out of order but good */
5624+}
5625+
5626+int
5627+#ifdef NET_21
5628+ipsec_rcv(struct sk_buff *skb, unsigned short xlen)
5629+#else /* NET_21 */
5630+ipsec_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
5631+ __u32 daddr, unsigned short xlen, __u32 saddr,
5632+ int redo, struct inet_protocol *protocol)
5633+#endif /* NET_21 */
5634+{
5635+#ifdef NET_21
5636+#ifdef CONFIG_IPSEC_DEBUG
5637+ struct device *dev = skb->dev;
5638+#endif /* CONFIG_IPSEC_DEBUG */
5639+#endif /* NET_21 */
5640+ unsigned char protoc;
5641+ struct iphdr *ipp;
5642+ int authlen = 0;
5643+#ifdef CONFIG_IPSEC_ESP
5644+ struct esp *espp = NULL;
5645+ int esphlen = 0;
5646+ __u32 iv[2];
5647+#endif /* !CONFIG_IPSEC_ESP */
5648+#ifdef CONFIG_IPSEC_AH
5649+ struct ah *ahp = NULL;
5650+ int ahhlen = 0;
5651+ struct iphdr ipo;
5652+#endif /* CONFIG_IPSEC_AH */
5653+ unsigned char *authenticator = NULL;
5654+ union {
5655+ MD5_CTX md5;
5656+ SHA1_CTX sha1;
5657+ } tctx;
5658+ __u8 hash[AH_AMAX];
5659+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
5660+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
5661+#ifdef CONFIG_IPSEC_IPCOMP
5662+ struct ipcomphdr*compp = NULL;
5663+#endif /* CONFIG_IPSEC_IPCOMP */
5664+
5665+ int hard_header_len;
5666+ int iphlen;
5667+ unsigned char *dat;
5668+ struct tdb *tdbp = NULL;
5669+ struct sa_id said;
5670+ struct net_device_stats *stats = NULL; /* This device's statistics */
5671+ struct device *ipsecdev = NULL, *prvdev;
5672+ struct ipsecpriv *prv;
5673+ char name[9];
5674+ char sa[SATOA_BUF];
5675+ size_t sa_len;
5676+ char ipaddr_txt[ADDRTOA_BUF];
5677+ int i;
5678+ struct in_addr ipaddr;
5679+ __u8 next_header = 0;
5680+ __u8 proto;
5681+
5682+#ifdef CONFIG_IPSEC_ESP
5683+ int pad = 0, padlen;
5684+#endif /* CONFIG_IPSEC_ESP */
5685+ int ilen, len, replay = 0;
5686+ __u8 *idat;
5687+ struct tdb* tdbprev = NULL;
5688+ struct tdb* tdbnext = NULL;
5689+#ifdef INBOUND_POLICY_CHECK_eroute
5690+ struct sockaddr_encap matcher; /* eroute search key */
5691+ struct eroute *er;
5692+ struct tdb* policy_tdb = NULL;
5693+ struct sa_id policy_said;
5694+ struct sockaddr_encap policy_eaddr;
5695+ struct sockaddr_encap policy_emask;
5696+#endif /* INBOUND_POLICY_CHECK_eroute */
5697+
5698+ /* Don't unlink in the middle of a turnaround */
5699+ MOD_INC_USE_COUNT;
5700+
5701+ if (skb == NULL) {
5702+ KLIPS_PRINT(debug_rcv,
5703+ "klips_debug:ipsec_rcv: "
5704+ "NULL skb passed in.\n");
5705+ goto rcvleave;
5706+ }
5707+
5708+ if (skb->data == NULL) {
5709+ KLIPS_PRINT(debug_rcv,
5710+ "klips_debug:ipsec_rcv: "
5711+ "NULL skb->data passed in, packet is bogus, dropping.\n");
5712+ goto rcvleave;
5713+ }
5714+
5715+ ipp = (struct iphdr *)skb->data;
5716+ iphlen = ipp->ihl << 2;
5717+ /* dev->hard_header_len is unreliable and should not be used */
5718+ hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0;
5719+ if((hard_header_len < 0) || (hard_header_len > skb_headroom(skb)))
5720+ hard_header_len = 0;
5721+
5722+#ifdef NET_21
5723+ /* if skb was cloned (most likely due to a packet sniffer such as
5724+ tcpdump being momentarily attached to the interface), make
5725+ a copy of our own to modify */
5726+ if(skb_cloned(skb)) {
5727+ /* include any mac header while copying.. */
5728+ if(skb_headroom(skb) < hard_header_len) {
5729+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
5730+ "tried to skb_push hhlen=%d, %d available. "
5731+ "This should never happen, please report.\n",
5732+ hard_header_len, skb_headroom(skb));
5733+ goto rcvleave;
5734+ }
5735+ skb_push(skb, hard_header_len);
5736+ if ((skb = skb_cow(skb, skb_headroom(skb))) == NULL) {
5737+ goto rcvleave;
5738+ }
5739+ if(skb->len < hard_header_len) {
5740+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
5741+ "tried to skb_pull hhlen=%d, %d available. "
5742+ "This should never happen, please report.\n",
5743+ hard_header_len, skb->len);
5744+ goto rcvleave;
5745+ }
5746+ skb_pull(skb, hard_header_len);
5747+ }
5748+
5749+#endif /* NET_21 */
5750+
5751+ KLIPS_PRINT(debug_rcv,
5752+ "klips_debug:ipsec_rcv: <<< Info -- ");
5753+ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
5754+ skb->dev->name ? skb->dev->name : "NULL");
5755+ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
5756+ dev->name ? dev->name : "NULL");
5757+ KLIPS_PRINTMORE(debug_rcv, "\n");
5758+
5759+ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
5760+ "klips_debug:ipsec_rcv: Informational -- "
5761+ "**if this happens, find out why** "
5762+ "skb->dev:%s is not equal to dev:%s\n",
5763+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
5764+ dev ? (dev->name ? dev->name : "NULL") : "NULL");
5765+
5766+ protoc = ipp->protocol;
5767+#ifndef NET_21
5768+ if((!protocol) || (protocol->protocol != protoc)) {
5769+ KLIPS_PRINT(debug_rcv & DB_RX_TDB,
5770+ "klips_debug:ipsec_rcv: "
5771+ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
5772+ }
5773+#endif /* !NET_21 */
5774+
5775+ if( (protoc != IPPROTO_AH) &&
5776+#ifdef CONFIG_IPSEC_IPCOMP
5777+ (protoc != IPPROTO_COMP) &&
5778+#endif /* CONFIG_IPSEC_IPCOMP */
5779+ (protoc != IPPROTO_ESP) ) {
5780+ KLIPS_PRINT(debug_rcv & DB_RX_TDB,
5781+ "klips_debug:ipsec_rcv: Why the hell is someone "
5782+ "passing me a non-ipsec packet? -- dropped.\n");
5783+ goto rcvleave;
5784+ }
5785+
5786+ if(skb->dev) {
5787+ for(i = 0; i < IPSEC_NUM_IF; i++) {
5788+ sprintf(name, "ipsec%d", i);
5789+ if(!strcmp(name, skb->dev->name)) {
5790+ prv = (struct ipsecpriv *)(skb->dev->priv);
5791+ if(prv) {
5792+ stats = (struct net_device_stats *) &(prv->mystats);
5793+ }
5794+ ipsecdev = skb->dev;
5795+ KLIPS_PRINT(debug_rcv,
5796+ "klips_debug:ipsec_rcv: Info -- pkt "
5797+ "already proc'ed a group of ipsec headers, "
5798+ "processing next group of ipsec headers.\n");
5799+ break;
5800+ }
5801+ if((ipsecdev = ipsec_dev_get(name)) == NULL) {
5802+ KLIPS_PRINT(debug_rcv,
5803+ "klips_error:ipsec_rcv: device %s does "
5804+ "not exist\n", name);
5805+ }
5806+ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
5807+ prvdev = prv ? (struct device *)(prv->dev) : NULL;
5808+
5809+ KLIPS_PRINT(debug_rcv && prvdev,
5810+ "klips_debug:ipsec_rcv: physical device"
5811+ " for device %s is %s\n",
5812+ name, prvdev->name);
5813+ if(prvdev && skb->dev &&
5814+ !strcmp(prvdev->name, skb->dev->name)) {
5815+ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
5816+ skb->dev = ipsecdev;
5817+ if(stats) {
5818+ stats->rx_packets++;
5819+ }
5820+ break;
5821+ }
5822+ }
5823+ } else {
5824+ KLIPS_PRINT(debug_rcv,
5825+ "klips_debug:ipsec_rcv: device supplied"
5826+ " with skb is NULL\n");
5827+ }
5828+
5829+ if(!stats) {
5830+ ipsecdev = NULL;
5831+ }
5832+ KLIPS_PRINT((debug_rcv && !stats),
5833+ "klips_error:ipsec_rcv: packet received from physical "
5834+ "I/F (%s) not connected to ipsec I/F. Cannot record "
5835+ "stats.\n"
5836+ "klips_error May not have SA for decoding. "
5837+ "Is IPSEC traffic expected on this I/F? "
5838+ "Check routing.\n",
5839+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
5840+
5841+ KLIPS_IP_PRINT(debug_rcv, ipp);
5842+
5843+ /* begin decapsulating loop here */
5844+ do {
5845+ authlen = 0;
5846+#ifdef CONFIG_IPSEC_ESP
5847+ espp = NULL;
5848+ esphlen = 0;
5849+#endif /* !CONFIG_IPSEC_ESP */
5850+#ifdef CONFIG_IPSEC_AH
5851+ ahp = NULL;
5852+ ahhlen = 0;
5853+#endif /* CONFIG_IPSEC_AH */
5854+#ifdef CONFIG_IPSEC_IPCOMP
5855+ compp = NULL;
5856+#endif /* CONFIG_IPSEC_IPCOMP */
5857+
5858+ len = skb->len;
5859+ dat = skb->data;
5860+ ipp = (struct iphdr *)skb->data;
5861+ proto = ipp->protocol;
5862+ ipaddr.s_addr = ipp->saddr;
5863+ addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt));
5864+
5865+ iphlen = ipp->ihl << 2;
5866+ ipp->check = 0; /* we know the sum is good */
5867+
5868+#ifdef CONFIG_IPSEC_ESP
5869+ /* XXX this will need to be 8 for IPv6 */
5870+ if ((proto == IPPROTO_ESP) && ((len - iphlen) % 4)) {
5871+ printk("klips_error:ipsec_rcv: "
5872+ "got packet with content length = %d from %s "
5873+ "-- should be on 4 octet boundary, packet dropped\n",
5874+ len - iphlen, ipaddr_txt);
5875+ if(stats) {
5876+ stats->rx_errors++;
5877+ }
5878+ goto rcvleave;
5879+ }
5880+#endif /* !CONFIG_IPSEC_ESP */
5881+
5882+ /*
5883+ * Find tunnel control block and (indirectly) call the
5884+ * appropriate tranform routine. The resulting sk_buf
5885+ * is a valid IP packet ready to go through input processing.
5886+ */
5887+
5888+ said.dst.s_addr = ipp->daddr;
5889+ switch(proto) {
5890+#ifdef CONFIG_IPSEC_ESP
5891+ case IPPROTO_ESP:
5892+ espp = (struct esp *)(skb->data + iphlen);
5893+ said.spi = espp->esp_spi;
5894+ break;
5895+#endif /* !CONFIG_IPSEC_ESP */
5896+#ifdef CONFIG_IPSEC_AH
5897+ case IPPROTO_AH:
5898+ ahp = (struct ah *)(skb->data + iphlen);
5899+ said.spi = ahp->ah_spi;
5900+ break;
5901+#endif /* CONFIG_IPSEC_AH */
5902+#ifdef CONFIG_IPSEC_IPCOMP
5903+ case IPPROTO_COMP:
5904+ compp = (struct ipcomphdr *)(skb->data + iphlen);
5905+ said.spi = htonl((__u32)ntohs(compp->ipcomp_cpi));
5906+ break;
5907+#endif /* CONFIG_IPSEC_IPCOMP */
5908+ default:
5909+ if(stats) {
5910+ stats->rx_errors++;
5911+ }
5912+ goto rcvleave;
5913+ }
5914+ said.proto = proto;
5915+ sa_len = satoa(said, 0, sa, SATOA_BUF);
5916+
5917+#ifdef CONFIG_IPSEC_AH
5918+ if(proto == IPPROTO_AH) {
5919+ ahhlen = (ahp->ah_hl << 2) +
5920+ ((caddr_t)&(ahp->ah_rpl) - (caddr_t)ahp);
5921+ next_header = ahp->ah_nh;
5922+ if (ahhlen != sizeof(struct ah)) {
5923+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
5924+ "klips_debug:ipsec_rcv: bad "
5925+ "authenticator length %d, expected "
5926+ "%d from %s\n",
5927+ ahhlen - ((caddr_t)(ahp->ah_data) -
5928+ (caddr_t)ahp),
5929+ AHHMAC_HASHLEN,
5930+ ipaddr_txt);
5931+ if(stats) {
5932+ stats->rx_errors++;
5933+ }
5934+ goto rcvleave;
5935+ }
5936+
5937+ }
5938+#endif /* CONFIG_IPSEC_AH */
5939+
5940+ /*
5941+ * The spinlock is to prevent any other process from
5942+ * accessing or deleting the structure while we are
5943+ * using and updating it.
5944+ */
5945+ spin_lock(&tdb_lock);
5946+
5947+#ifdef CONFIG_IPSEC_IPCOMP
5948+ if (proto == IPPROTO_COMP) {
5949+ unsigned int flags = 0;
5950+ if (tdbp == NULL) {
5951+ KLIPS_PRINT(debug_rcv,
5952+ "klips_debug:ipsec_rcv: "
5953+ "Incoming packet with outer IPCOMP "
5954+ "header SA:%s: not yet supported "
5955+ "by KLIPS, dropped\n", sa);
5956+ if(stats) {
5957+ stats->rx_dropped++;
5958+ }
5959+
5960+ spin_unlock(&tdb_lock);
5961+ goto rcvleave;
5962+ }
5963+
5964+ tdbprev = tdbp;
5965+ tdbp = tdbnext;
5966+
5967+ if(sysctl_ipsec_inbound_policy_check
5968+ && ((tdbp == NULL)
5969+ || ((tdbp != NULL)
5970+ && ((ntohl(tdbp->tdb_said.spi) & 0x0000ffff)
5971+ != ntohl(said.spi))))) {
5972+ char sa2[SATOA_BUF];
5973+
5974+ if(tdbp) {
5975+ sa_len = satoa(tdbp->tdb_said, 0, sa2, SATOA_BUF);
5976+ }
5977+ KLIPS_PRINT(debug_rcv,
5978+ "klips_debug:ipsec_rcv: "
5979+ "Incoming packet with SA(IPCA):%s "
5980+ "does not match policy SA(IPCA):%s "
5981+ "cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for "
5982+ "SA grouping, dropped.\n",
5983+ sa,
5984+ tdbp ? sa2 : "NULL",
5985+ ntohs(compp->ipcomp_cpi),
5986+ (__u32)ntohl(said.spi),
5987+ tdbp ? (__u32)ntohl((tdbp->tdb_said.spi)) : 0,
5988+ tdbp ? (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff) : 0);
5989+ if(stats) {
5990+ stats->rx_dropped++;
5991+ }
5992+
5993+ spin_unlock(&tdb_lock);
5994+ goto rcvleave;
5995+ }
5996+
5997+ if (tdbp) {
5998+ tdbp->tdb_comp_ratio_cbytes += ntohs(ipp->tot_len);
5999+ tdbnext = tdbp->tdb_inext;
6000+ }
6001+ next_header = compp->ipcomp_nh;
6002+
6003+ skb = skb_decompress(skb, tdbp, &flags);
6004+ if (!skb || flags) {
6005+ KLIPS_PRINT(debug_rcv,
6006+ "klips_debug:ipsec_rcv: "
6007+ "skb_decompress() returned "
6008+ "error flags=%x, dropped.\n",
6009+ flags);
6010+ if (stats) {
6011+ if (flags)
6012+ stats->rx_errors++;
6013+ else
6014+ stats->rx_dropped++;
6015+ }
6016+
6017+ spin_unlock(&tdb_lock);
6018+ goto rcvleave;
6019+ }
6020+#ifdef NET_21
6021+ ipp = skb->nh.iph;
6022+#else /* NET_21 */
6023+ ipp = skb->ip_hdr;
6024+#endif /* NET_21 */
6025+
6026+ if (tdbp) {
6027+ tdbp->tdb_comp_ratio_dbytes += ntohs(ipp->tot_len);
6028+ }
6029+
6030+ KLIPS_PRINT(debug_rcv,
6031+ "klips_debug:ipsec_rcv: "
6032+ "packet decompressed SA(IPCA):%s "
6033+ "cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
6034+ sa,
6035+ (__u32)ntohl(said.spi),
6036+ tdbp ? (__u32)ntohl((tdbp->tdb_said.spi)) : 0,
6037+ tdbp ? (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff) : 0,
6038+ next_header);
6039+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
6040+
6041+ continue;
6042+ /* Skip rest of stuff and decapsulate next inner
6043+ packet, if any */
6044+ }
6045+#endif /* CONFIG_IPSEC_IPCOMP */
6046+
6047+ tdbp = gettdb(&said);
6048+ if (tdbp == NULL) {
6049+ spin_unlock(&tdb_lock);
6050+ KLIPS_PRINT(debug_rcv,
6051+ "klips_debug:ipsec_rcv: no Tunnel Descriptor "
6052+ "Block for SA:%s: incoming packet with no SA "
6053+ "dropped\n", sa);
6054+ if(stats) {
6055+ stats->rx_dropped++;
6056+ }
6057+ goto rcvleave;
6058+ }
6059+
6060+ if(sysctl_ipsec_inbound_policy_check) {
6061+ if(ipp->saddr != ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr) {
6062+ spin_unlock(&tdb_lock);
6063+ ipaddr.s_addr = ipp->saddr;
6064+ addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt));
6065+ KLIPS_PRINT(debug_rcv,
6066+ "klips_debug:ipsec_rcv: "
6067+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
6068+ sa, ipaddr_txt);
6069+ if(stats) {
6070+ stats->rx_dropped++;
6071+ }
6072+ goto rcvleave;
6073+ }
6074+ {
6075+ ipaddr.s_addr = ipp->saddr;
6076+ addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt));
6077+ KLIPS_PRINT(debug_rcv,
6078+ "klips_debug:ipsec_rcv: "
6079+ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
6080+ sa, ipaddr_txt);
6081+ }
6082+ if(tdbnext) {
6083+ if(tdbnext != tdbp) {
6084+ spin_unlock(&tdb_lock);
6085+ KLIPS_PRINT(debug_rcv,
6086+ "klips_debug:ipsec_rcv: "
6087+ "unexpected SA:%s: does not agree with tdb->inext policy, dropped\n",
6088+ sa);
6089+ if(stats) {
6090+ stats->rx_dropped++;
6091+ }
6092+ goto rcvleave;
6093+ }
6094+ KLIPS_PRINT(debug_rcv,
6095+ "klips_debug:ipsec_rcv: "
6096+ "SA:%s grouping from previous SA is OK.\n",
6097+ sa);
6098+ } else {
6099+ KLIPS_PRINT(debug_rcv,
6100+ "klips_debug:ipsec_rcv: "
6101+ "SA:%s First SA in group.\n",
6102+ sa);
6103+ }
6104+
6105+#if 1
6106+ if(tdbp->tdb_onext) {
6107+ if(tdbprev != tdbp->tdb_onext) {
6108+ spin_unlock(&tdb_lock);
6109+ KLIPS_PRINT(debug_rcv,
6110+ "klips_debug:ipsec_rcv: "
6111+ "unexpected SA:%s: does not agree with tdb->onext policy, dropped.\n",
6112+ sa);
6113+ if(stats) {
6114+ stats->rx_dropped++;
6115+ }
6116+ goto rcvleave;
6117+ } else {
6118+ KLIPS_PRINT(debug_rcv,
6119+ "klips_debug:ipsec_rcv: "
6120+ "SA:%s grouping to previous SA is OK.\n",
6121+ sa);
6122+ }
6123+ } else {
6124+ KLIPS_PRINT(debug_rcv,
6125+ "klips_debug:ipsec_rcv: "
6126+ "SA:%s No previous backlink in group.\n",
6127+ sa);
6128+ }
6129+#endif
6130+ }
6131+
6132+ /* If it is in larval state, drop the packet, we cannot process yet. */
6133+ if(tdbp->tdb_state == SADB_SASTATE_LARVAL) {
6134+ spin_unlock(&tdb_lock);
6135+ KLIPS_PRINT(debug_rcv,
6136+ "klips_debug:ipsec_rcv: "
6137+ "TDB in larval state, cannot be used yet, "
6138+ "dropping packet.\n");
6139+ if(stats) {
6140+ stats->rx_dropped++;
6141+ }
6142+ goto rcvleave;
6143+ }
6144+
6145+ if(tdbp->tdb_state == SADB_SASTATE_DEAD) {
6146+ spin_unlock(&tdb_lock);
6147+ KLIPS_PRINT(debug_rcv,
6148+ "klips_debug:ipsec_rcv: "
6149+ "TDB in dead state, cannot be used any more, "
6150+ "dropping packet.\n");
6151+ if(stats) {
6152+ stats->rx_dropped++;
6153+ }
6154+ goto rcvleave;
6155+ }
6156+
6157+ if(tdbp->tdb_lifetime_bytes_h &&
6158+ (tdbp->tdb_lifetime_bytes_c > tdbp->tdb_lifetime_bytes_h)) {
6159+ pfkey_expire(tdbp, 1);
6160+ deltdbchain(tdbp);
6161+ spin_unlock(&tdb_lock);
6162+ KLIPS_PRINT(debug_rcv,
6163+ "klips_debug:ipsec_rcv: "
6164+ "hard bytes lifetime of SA:%s has been reached, "
6165+ "SA expired, incoming packet dropped.\n", sa);
6166+ if(stats) {
6167+ stats->rx_dropped++;
6168+ }
6169+ goto rcvleave;
6170+ }
6171+ if(tdbp->tdb_lifetime_bytes_s &&
6172+ (tdbp->tdb_lifetime_bytes_c > tdbp->tdb_lifetime_bytes_s)) {
6173+ tdbp->tdb_state = SADB_SASTATE_DYING;
6174+ KLIPS_PRINT(debug_rcv,
6175+ "klips_debug:ipsec_rcv: "
6176+ "soft bytes lifetime of SA:%s has been reached, "
6177+ "SA expiring, soft expire message sent up, "
6178+ "incoming packet still processed.\n", sa);
6179+ pfkey_expire(tdbp, 0);
6180+ }
6181+
6182+ if(tdbp->tdb_lifetime_addtime_h &&
6183+ ((jiffies / HZ) - tdbp->tdb_lifetime_addtime_c >
6184+ tdbp->tdb_lifetime_addtime_h)) {
6185+ pfkey_expire(tdbp, 1);
6186+ deltdbchain(tdbp);
6187+ spin_unlock(&tdb_lock);
6188+ KLIPS_PRINT(debug_rcv,
6189+ "klips_debug:ipsec_rcv: "
6190+ "hard addtime lifetime of SA:%s has been reached, "
6191+ "SA expired, incoming packet dropped.\n", sa);
6192+ if(stats) {
6193+ stats->rx_dropped++;
6194+ }
6195+ goto rcvleave;
6196+ }
6197+ if(tdbp->tdb_lifetime_addtime_s &&
6198+ ((jiffies / HZ) - tdbp->tdb_lifetime_addtime_c >
6199+ tdbp->tdb_lifetime_addtime_s)) {
6200+ tdbp->tdb_state = SADB_SASTATE_DYING;
6201+ KLIPS_PRINT(debug_rcv,
6202+ "klips_debug:ipsec_rcv: "
6203+ "soft addtime lifetime of SA:%s has been reached, "
6204+ "SA expiring, soft expire message sent up, "
6205+ "incoming packet still processed.\n", sa);
6206+ pfkey_expire(tdbp, 0);
6207+ }
6208+
6209+ if(tdbp->tdb_lifetime_usetime_c) {
6210+ if(tdbp->tdb_lifetime_usetime_h &&
6211+ ((jiffies / HZ) - tdbp->tdb_lifetime_usetime_c >
6212+ tdbp->tdb_lifetime_usetime_h)) {
6213+ pfkey_expire(tdbp, 1);
6214+ deltdbchain(tdbp);
6215+ spin_unlock(&tdb_lock);
6216+ KLIPS_PRINT(debug_rcv,
6217+ "klips_debug:ipsec_rcv: "
6218+ "hard usetime lifetime of SA:%s has been reached, "
6219+ "SA expired, incoming packet dropped.\n", sa);
6220+ if(stats) {
6221+ stats->rx_dropped++;
6222+ }
6223+ goto rcvleave;
6224+ }
6225+ if(tdbp->tdb_lifetime_usetime_s &&
6226+ ((jiffies / HZ) - tdbp->tdb_lifetime_usetime_c >
6227+ tdbp->tdb_lifetime_usetime_s)) {
6228+ tdbp->tdb_state = SADB_SASTATE_DYING;
6229+ KLIPS_PRINT(debug_rcv,
6230+ "klips_debug:ipsec_rcv: "
6231+ "soft usetime lifetime of SA:%s has been reached, "
6232+ "SA expiring, soft expire message sent up, "
6233+ "incoming packet still processed.\n", sa);
6234+ pfkey_expire(tdbp, 0);
6235+ }
6236+ }
6237+
6238+ if(tdbp->tdb_lifetime_packets_h &&
6239+ (tdbp->tdb_lifetime_packets_c > tdbp->tdb_lifetime_packets_h)) {
6240+ pfkey_expire(tdbp, 1);
6241+ deltdbchain(tdbp);
6242+ spin_unlock(&tdb_lock);
6243+ KLIPS_PRINT(debug_rcv,
6244+ "klips_debug:ipsec_rcv: "
6245+ "hard packets lifetime of SA:%s has been reached, "
6246+ "SA expired, incoming packet dropped.\n", sa);
6247+ if(stats) {
6248+ stats->rx_dropped++;
6249+ }
6250+ goto rcvleave;
6251+ }
6252+ if(tdbp->tdb_lifetime_packets_s &&
6253+ (tdbp->tdb_lifetime_packets_c > tdbp->tdb_lifetime_packets_s)) {
6254+ tdbp->tdb_state = SADB_SASTATE_DYING;
6255+ KLIPS_PRINT(debug_rcv,
6256+ "klips_debug:ipsec_rcv: "
6257+ "soft packets lifetime of SA:%s has been reached, "
6258+ "SA expiring, soft expire message sent up, "
6259+ "incoming packet still processed.\n", sa);
6260+ pfkey_expire(tdbp, 0);
6261+ }
6262+
6263+ /* authenticate, if required */
6264+ idat = dat + iphlen;
6265+ switch(tdbp->tdb_authalg) {
6266+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
6267+ case AH_MD5:
6268+ authlen = AHHMAC_HASHLEN;
6269+ break;
6270+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
6271+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
6272+ case AH_SHA:
6273+ authlen = AHHMAC_HASHLEN;
6274+ break;
6275+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
6276+ case AH_NONE:
6277+ authlen = 0;
6278+ break;
6279+ default:
6280+ if(stats) {
6281+ stats->rx_errors++;
6282+ }
6283+ tdbp->tdb_alg_errs += 1;
6284+ spin_unlock(&tdb_lock);
6285+ goto rcvleave;
6286+ }
6287+ ilen = len - iphlen - authlen;
6288+
6289+#ifdef CONFIG_IPSEC_ESP
6290+ KLIPS_PRINT(proto == IPPROTO_ESP && debug_rcv,
6291+ "klips_debug:ipsec_rcv: packet from %s received with"
6292+ " seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
6293+ ipaddr_txt,
6294+ (__u32)ntohl(espp->esp_rpl),
6295+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
6296+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
6297+ len, ilen, sa);
6298+#endif /* !CONFIG_IPSEC_ESP */
6299+
6300+ switch(proto) {
6301+#ifdef CONFIG_IPSEC_ESP
6302+ case IPPROTO_ESP:
6303+ replay = ntohl(espp->esp_rpl);
6304+ authenticator = &(dat[len - authlen]);
6305+ break;
6306+#endif /* !CONFIG_IPSEC_ESP */
6307+#ifdef CONFIG_IPSEC_AH
6308+ case IPPROTO_AH:
6309+ replay = ntohl(ahp->ah_rpl);
6310+ authenticator = ahp->ah_data;
6311+ break;
6312+#endif /* CONFIG_IPSEC_AH */
6313+ }
6314+
6315+ /* If the sequence number == 0, expire SA, it had rolled */
6316+ if(tdbp->tdb_replaywin && !replay /* !tdbp->tdb_replaywin_lastseq */) {
6317+ deltdbchain(tdbp);
6318+ spin_unlock(&tdb_lock);
6319+ KLIPS_PRINT(debug_rcv,
6320+ "klips_debug:ipsec_tunnel_start_xmit: "
6321+ "replay window counter rolled, expiring SA.\n");
6322+ if(stats) {
6323+ stats->rx_dropped++;
6324+ }
6325+ goto rcvleave;
6326+ }
6327+
6328+ if (!ipsec_checkreplaywindow(tdbp, replay)) {
6329+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
6330+ "klips_debug:ipsec_rcv: duplicate frame from %s,"
6331+ " packet dropped\n",
6332+ ipaddr_txt);
6333+ if(stats) {
6334+ stats->rx_dropped++;
6335+ }
6336+ tdbp->tdb_replaywin_errs += 1;
6337+ spin_unlock(&tdb_lock);
6338+ goto rcvleave;
6339+ }
6340+
6341+ /*
6342+ * verify authenticator
6343+ */
6344+
6345+ KLIPS_PRINT(debug_rcv,
6346+ "klips_debug:ipsec_rcv: encalg = %d, authalg = %d.\n",
6347+ tdbp->tdb_encalg, tdbp->tdb_authalg);
6348+
6349+ if(tdbp->tdb_authalg) {
6350+ switch(tdbp->tdb_authalg) {
6351+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
6352+ case AH_MD5:
6353+ tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;
6354+ if(proto == IPPROTO_ESP) {
6355+ MD5Update(&tctx.md5, (caddr_t)espp, ilen);
6356+#ifdef CONFIG_IPSEC_AH
6357+ } else {
6358+ ipo = *ipp;
6359+ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
6360+ ipo.frag_off = 0;
6361+ ipo.ttl = 0;
6362+ ipo.check = 0;
6363+
6364+ MD5Update(&tctx.md5, (caddr_t)&ipo,
6365+ sizeof(struct iphdr));
6366+ MD5Update(&tctx.md5, (caddr_t)ahp,
6367+ ahhlen - AHHMAC_HASHLEN);
6368+ MD5Update(&tctx.md5, (caddr_t)zeroes,
6369+ AHHMAC_HASHLEN);
6370+ MD5Update(&tctx.md5,
6371+ (caddr_t)dat + iphlen + ahhlen,
6372+ len - iphlen - ahhlen);
6373+#endif /* CONFIG_IPSEC_AH */
6374+ }
6375+ MD5Final(hash, &tctx.md5);
6376+ tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;
6377+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
6378+ MD5Final(hash, &tctx.md5);
6379+ break;
6380+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
6381+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
6382+ case AH_SHA:
6383+ tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx;
6384+ if(proto == IPPROTO_ESP) {
6385+ SHA1Update(&tctx.sha1, (caddr_t)espp, ilen);
6386+#ifdef CONFIG_IPSEC_AH
6387+ } else {
6388+ ipo = *ipp;
6389+ ipo.tos = 0;
6390+ ipo.frag_off = 0;
6391+ ipo.ttl = 0;
6392+ ipo.check = 0;
6393+
6394+ SHA1Update(&tctx.sha1, (caddr_t)&ipo,
6395+ sizeof(struct iphdr));
6396+ SHA1Update(&tctx.sha1, (caddr_t)ahp,
6397+ ahhlen - AHHMAC_HASHLEN);
6398+ SHA1Update(&tctx.sha1, (caddr_t)zeroes,
6399+ AHHMAC_HASHLEN);
6400+ SHA1Update(&tctx.sha1,
6401+ (caddr_t)dat + iphlen + ahhlen,
6402+ len - iphlen - ahhlen);
6403+#endif /* CONFIG_IPSEC_AH */
6404+ }
6405+ SHA1Final(hash, &tctx.sha1);
6406+ tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
6407+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
6408+ SHA1Final(hash, &tctx.sha1);
6409+ break;
6410+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
6411+ case AH_NONE:
6412+ break;
6413+ }
6414+
6415+ if(!authenticator) {
6416+ if(stats) {
6417+ stats->rx_dropped++;
6418+ }
6419+ tdbp->tdb_auth_errs += 1;
6420+ spin_unlock(&tdb_lock);
6421+ goto rcvleave;
6422+ }
6423+
6424+ if (memcmp(hash, authenticator, authlen)) {
6425+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
6426+ "klips_debug:ipsec_rcv: auth failed on incoming "
6427+ "packet from %s: hash=%08x%08x%08x "
6428+ "auth=%08x%08x%08x, dropped\n", ipaddr_txt,
6429+ *(__u32*)&hash[0],
6430+ *(__u32*)&hash[4],
6431+ *(__u32*)&hash[8],
6432+ *(__u32*)authenticator,
6433+ *((__u32*)authenticator + 1),
6434+ *((__u32*)authenticator + 2));
6435+ if(stats) {
6436+ stats->rx_dropped++;
6437+ }
6438+ tdbp->tdb_auth_errs += 1;
6439+ spin_unlock(&tdb_lock);
6440+ goto rcvleave;
6441+ } else {
6442+ KLIPS_PRINT(debug_rcv,
6443+ "klips_debug:ipsec_rcv: authentication successful.\n");
6444+ }
6445+
6446+ memset((caddr_t)&tctx, 0, sizeof(tctx));
6447+ memset(hash, 0, sizeof(hash));
6448+ }
6449+
6450+ if (!ipsec_updatereplaywindow(tdbp, replay)) {
6451+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
6452+ "klips_debug:ipsec_rcv: duplicate frame from %s,"
6453+ " packet dropped\n",
6454+ ipaddr_txt);
6455+ if(stats) {
6456+ stats->rx_dropped++;
6457+ }
6458+ tdbp->tdb_replaywin_errs += 1;
6459+ spin_unlock(&tdb_lock);
6460+ goto rcvleave;
6461+ }
6462+
6463+ switch(proto) {
6464+#ifdef CONFIG_IPSEC_ESP
6465+ case IPPROTO_ESP:
6466+ switch(tdbp->tdb_encalg) {
6467+ case ESP_3DES:
6468+ iv[0] = *((__u32 *)(espp->esp_iv) );
6469+ iv[1] = *((__u32 *)(espp->esp_iv) + 1);
6470+ esphlen = sizeof(struct esp);
6471+ break;
6472+ case ESP_NULL:
6473+ esphlen = offsetof(struct esp, esp_iv);
6474+ break;
6475+ default:
6476+ if(stats) {
6477+ stats->rx_errors++;
6478+ }
6479+ tdbp->tdb_alg_errs += 1;
6480+ spin_unlock(&tdb_lock);
6481+ goto rcvleave;
6482+ }
6483+ idat += esphlen;
6484+ ilen -= esphlen;
6485+
6486+ switch(tdbp->tdb_encalg) {
6487+ case ESP_3DES:
6488+ if ((ilen) % 8) {
6489+ printk("klips_error:ipsec_rcv: "
6490+ "got packet with esplen = %d from %s "
6491+ "-- should be on 8 octet boundary, packet dropped\n",
6492+ ilen, ipaddr_txt);
6493+ if(stats) {
6494+ stats->rx_errors++;
6495+ }
6496+ tdbp->tdb_encsize_errs += 1;
6497+ spin_unlock(&tdb_lock);
6498+ goto rcvleave;
6499+ }
6500+ des_ede3_cbc_encrypt(idat, idat, ilen,
6501+ tdbp->tdb_key_e,
6502+ tdbp->tdb_key_e + sizeof(struct des_eks),
6503+ tdbp->tdb_key_e + 2 * sizeof(struct des_eks),
6504+ (caddr_t)iv, 0);
6505+ break;
6506+ case ESP_NULL:
6507+ break;
6508+ }
6509+ next_header = idat[ilen - 1];
6510+ padlen = idat[ilen - 2];
6511+ pad = padlen + 2 + authlen;
6512+ {
6513+ int badpad = 0;
6514+
6515+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
6516+ "klips_debug:ipsec_rcv: "
6517+ "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
6518+ padlen);
6519+
6520+ for (i = 1; i <= padlen; i++) {
6521+ if((i % 16) == 1) {
6522+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
6523+ "klips_debug: %02x:",
6524+ i - 1);
6525+ }
6526+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
6527+ " %02x",
6528+ idat[ilen - 2 - padlen + i - 1]);
6529+ if(i != idat[ilen - 2 - padlen + i - 1]) {
6530+ badpad = 1;
6531+ }
6532+ if((i % 16) == 0) {
6533+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
6534+ "\n");
6535+ }
6536+ }
6537+ if((i % 16) != 1) {
6538+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
6539+ "\n");
6540+ }
6541+ if(badpad) {
6542+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
6543+ "klips_debug:ipsec_rcv: "
6544+ "warning, decrypted packet from %s has bad padding\n",
6545+ ipaddr_txt);
6546+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
6547+ "klips_debug:ipsec_rcv: "
6548+ "...may be bad decryption -- not dropped\n");
6549+ tdbp->tdb_encpad_errs += 1;
6550+ }
6551+
6552+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
6553+ "klips_debug:ipsec_rcv: "
6554+ "packet decrypted from %s: next_header = %d, padding = %d\n",
6555+ ipaddr_txt,
6556+ next_header,
6557+ pad - 2 - authlen);
6558+ }
6559+#endif /* !CONFIG_IPSEC_ESP */
6560+#ifdef CONFIG_IPSEC_AH
6561+ case IPPROTO_AH:
6562+ break;
6563+#endif /* CONFIG_IPSEC_AH */
6564+ }
6565+
6566+ /*
6567+ * Discard the original IP header
6568+ */
6569+
6570+ ipp->protocol = next_header;
6571+
6572+ switch(proto) {
6573+#ifdef CONFIG_IPSEC_ESP
6574+ case IPPROTO_ESP:
6575+ ipp->tot_len = htons(ntohs(ipp->tot_len) - (esphlen + pad));
6576+ memmove((void *)(skb->data + esphlen),
6577+ (void *)(skb->data), iphlen);
6578+ if(skb->len < esphlen) {
6579+ spin_unlock(&tdb_lock);
6580+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
6581+ "tried to skb_pull esphlen=%d, %d available. "
6582+ "This should never happen, please report.\n",
6583+ esphlen, (int)(skb->len));
6584+ goto rcvleave;
6585+ }
6586+ skb_pull(skb, esphlen);
6587+
6588+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
6589+ "klips_debug:ipsec_rcv: trimming to %d.\n",
6590+ len - esphlen - pad);
6591+ if(pad + esphlen <= len) {
6592+ skb_trim(skb, len - esphlen - pad);
6593+ } else {
6594+ spin_unlock(&tdb_lock);
6595+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
6596+ "klips_debug:ipsec_rcv: bogus packet, size is zero or negative, dropping.\n");
6597+ goto rcvleave;
6598+ }
6599+ break;
6600+#endif /* !CONFIG_IPSEC_ESP */
6601+#ifdef CONFIG_IPSEC_AH
6602+ case IPPROTO_AH:
6603+ ipp->tot_len = htons(ntohs(ipp->tot_len) - ahhlen);
6604+ memmove((void *)(skb->data + ahhlen),
6605+ (void *)(skb->data), iphlen);
6606+ if(skb->len < ahhlen) {
6607+ spin_unlock(&tdb_lock);
6608+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
6609+ "tried to skb_pull ahhlen=%d, %d available. "
6610+ "This should never happen, please report.\n",
6611+ ahhlen, (int)(skb->len));
6612+ goto rcvleave;
6613+ }
6614+ skb_pull(skb, ahhlen);
6615+ break;
6616+#endif /* CONFIG_IPSEC_AH */
6617+ }
6618+
6619+
6620+ /*
6621+ * Adjust pointers
6622+ */
6623+
6624+ len = skb->len;
6625+ dat = skb->data;
6626+
6627+#ifdef NET_21
6628+/* skb->h.ipiph=(struct iphdr *)skb->data; */
6629+ skb->nh.raw = skb->data;
6630+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
6631+
6632+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
6633+#else /* NET_21 */
6634+ skb->h.iph=(struct iphdr *)skb->data;
6635+ skb->ip_hdr=(struct iphdr *)skb->data;
6636+ memset(skb->proto_priv, 0, sizeof(struct options));
6637+#endif /* NET_21 */
6638+
6639+ ipp = (struct iphdr *)dat;
6640+ ipp->check = 0;
6641+ ipp->check = ip_fast_csum((unsigned char *)dat, iphlen >> 2);
6642+
6643+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
6644+ "klips_debug:ipsec_rcv: after <%s%s%s>, SA:%s:\n",
6645+ TDB_XFORM_NAME(tdbp), sa);
6646+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
6647+
6648+ skb->protocol = htons(ETH_P_IP);
6649+ skb->ip_summed = 0;
6650+
6651+ tdbprev = tdbp;
6652+ tdbnext = tdbp->tdb_inext;
6653+ if(sysctl_ipsec_inbound_policy_check) {
6654+ if(tdbnext) {
6655+ if(tdbnext->tdb_onext != tdbp) {
6656+ spin_unlock(&tdb_lock);
6657+ KLIPS_PRINT(debug_rcv,
6658+ "klips_debug:ipsec_rcv: "
6659+ "SA:%s, backpolicy does not agree with fwdpolicy.\n",
6660+ sa);
6661+ if(stats) {
6662+ stats->rx_dropped++;
6663+ }
6664+ goto rcvleave;
6665+ }
6666+ KLIPS_PRINT(debug_rcv,
6667+ "klips_debug:ipsec_rcv: "
6668+ "SA:%s, backpolicy agrees with fwdpolicy.\n",
6669+ sa);
6670+ if(!( (ipp->protocol == IPPROTO_AH )
6671+ || (ipp->protocol == IPPROTO_ESP )
6672+ || (ipp->protocol == IPPROTO_IPIP)
6673+#ifdef CONFIG_IPSEC_IPCOMP
6674+ || (ipp->protocol == IPPROTO_COMP)
6675+#endif /* CONFIG_IPSEC_IPCOMP */
6676+ )) {
6677+ spin_unlock(&tdb_lock);
6678+ KLIPS_PRINT(debug_rcv,
6679+ "klips_debug:ipsec_rcv: "
6680+ "packet with incomplete policy dropped, last successful SA:%s.\n",
6681+ sa);
6682+ if(stats) {
6683+ stats->rx_dropped++;
6684+ }
6685+ goto rcvleave;
6686+ }
6687+ KLIPS_PRINT(debug_rcv,
6688+ "klips_debug:ipsec_rcv: "
6689+ "SA:%s, Another IPSEC header to process.\n",
6690+ sa);
6691+ } else {
6692+ KLIPS_PRINT(debug_rcv,
6693+ "klips_debug:ipsec_rcv: "
6694+ "No tdb_inext from this SA:%s.\n",
6695+ sa);
6696+ }
6697+ }
6698+
6699+#ifdef CONFIG_IPSEC_IPCOMP
6700+ /* update ipcomp ratio counters, even if no ipcomp packet is present */
6701+ if (tdbnext
6702+ && tdbnext->tdb_said.proto == IPPROTO_COMP
6703+ && ipp->protocol != IPPROTO_COMP) {
6704+ tdbnext->tdb_comp_ratio_cbytes += ntohs(ipp->tot_len);
6705+ tdbnext->tdb_comp_ratio_dbytes += ntohs(ipp->tot_len);
6706+ }
6707+#endif /* CONFIG_IPSEC_IPCOMP */
6708+
6709+ tdbp->tdb_lifetime_bytes_c += len;
6710+ if(!tdbp->tdb_lifetime_usetime_c) {
6711+ tdbp->tdb_lifetime_usetime_c = jiffies / HZ;
6712+ }
6713+ tdbp->tdb_lifetime_usetime_l = jiffies / HZ;
6714+ tdbp->tdb_lifetime_packets_c += 1;
6715+
6716+ /* end decapsulation loop here */
6717+ } while( (ipp->protocol == IPPROTO_ESP )
6718+ || (ipp->protocol == IPPROTO_AH )
6719+#ifdef CONFIG_IPSEC_IPCOMP
6720+ || (ipp->protocol == IPPROTO_COMP)
6721+#endif /* CONFIG_IPSEC_IPCOMP */
6722+ );
6723+
6724+#ifdef CONFIG_IPSEC_IPCOMP
6725+ if(tdbnext && tdbnext->tdb_said.proto == IPPROTO_COMP) {
6726+ tdbprev = tdbp;
6727+ tdbp = tdbnext;
6728+ tdbnext = tdbp->tdb_inext;
6729+ }
6730+#endif /* CONFIG_IPSEC_IPCOMP */
6731+
6732+ /*
6733+ * XXX this needs to be locked from when it was first looked
6734+ * up in the decapsulation loop. Perhaps it is better to put
6735+ * the IPIP decap inside the loop.
6736+ */
6737+ if(tdbnext) {
6738+ tdbp = tdbnext;
6739+ sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
6740+ if(ipp->protocol != IPPROTO_IPIP) {
6741+ spin_unlock(&tdb_lock);
6742+ KLIPS_PRINT(debug_rcv,
6743+ "klips_debug:ipsec_rcv: "
6744+ "SA:%s, Hey! How did this get through? Dropped.\n",
6745+ sa);
6746+ if(stats) {
6747+ stats->rx_dropped++;
6748+ }
6749+ goto rcvleave;
6750+ }
6751+ if(sysctl_ipsec_inbound_policy_check && (tdbnext = tdbp->tdb_inext)) {
6752+ char sa2[SATOA_BUF];
6753+ sa_len = satoa(tdbnext->tdb_said, 0, sa2, SATOA_BUF);
6754+ spin_unlock(&tdb_lock);
6755+ KLIPS_PRINT(debug_rcv,
6756+ "klips_debug:ipsec_rcv: "
6757+ "unexpected SA:%s after IPIP SA:%s\n",
6758+ sa2, sa);
6759+ if(stats) {
6760+ stats->rx_dropped++;
6761+ }
6762+ goto rcvleave;
6763+ }
6764+ }
6765+
6766+#ifdef INBOUND_POLICY_CHECK_eroute
6767+ /*
6768+ Do *not* enable this without thoroughly checking spinlock issues
6769+ first. In particular, nesting an eroute spinlock within a tdb
6770+ spinlock could result in a deadlock. (Well, only on a SMP machine
6771+ under 2.4?)
6772+ */
6773+
6774+ /*
6775+ * First things first -- look us up in the erouting tables.
6776+ */
6777+ matcher.sen_len = sizeof (struct sockaddr_encap);
6778+ matcher.sen_family = AF_ENCAP;
6779+ matcher.sen_type = SENT_IP4;
6780+ if(ipp->protocol == IPPROTO_IPIP) {
6781+ struct iphdr *ipp2;
6782+
6783+ ipp2 = (struct iphdr*) (((char*)ipp) + (ipp->ihl << 2));
6784+ matcher.sen_ip_src.s_addr = ipp2->saddr;
6785+ matcher.sen_ip_dst.s_addr = ipp2->daddr;
6786+ } else {
6787+ matcher.sen_ip_src.s_addr = ipp->saddr;
6788+ matcher.sen_ip_dst.s_addr = ipp->daddr;
6789+ }
6790+
6791+ /*
6792+ * The spinlock is to prevent any other process from accessing or
6793+ * deleting the eroute while we are using and updating it.
6794+ */
6795+ spin_lock(&eroute_lock);
6796+
6797+ er = ipsec_findroute(&matcher);
6798+ if(er) {
6799+ policy_said = er->er_said;
6800+ policy_eaddr = er->er_eaddr;
6801+ policy_emask = er->er_emask;
6802+ }
6803+
6804+ spin_unlock(&eroute_lock);
6805+
6806+ if(er) {
6807+ /*
6808+ * The spinlock is to prevent any other process from
6809+ * accessing or deleting the tdb while we are using and
6810+ * updating it.
6811+ */
6812+ /* spin_lock(&tdb_lock); */
6813+
6814+ policy_tdb = gettdb(&policy_said);
6815+ if (policy_tdb == NULL) {
6816+ /* spin_unlock(&tdb_lock); */
6817+ KLIPS_PRINT(debug_rcv,
6818+ "klips_debug:ipsec_rcv: "
6819+ "no Tunnel Descriptor Block for SA%s: "
6820+ "incoming packet with no policy SA, dropped.\n", sa);
6821+ goto rcvleave;
6822+ }
6823+
6824+ sa_len = satoa(policy_said, 0, sa, SATOA_BUF);
6825+
6826+ KLIPS_PRINT(debug_rcv,
6827+ "klips_debug:ipsec_rcv: "
6828+ "found policy Tunnel Descriptor Block -- SA:%s\n", sa);
6829+ while(1) {
6830+ if(policy_tdb->tdb_inext) {
6831+ policy_tdb = policy_tdb->tdb_inext;
6832+ } else {
6833+ break;
6834+ }
6835+ }
6836+ if(policy_tdb != tdbp) {
6837+ /* spin_unlock(&tdb_lock); */
6838+ KLIPS_PRINT(debug_rcv,
6839+ "klips_debug:ipsec_rcv: "
6840+ " Tunnel Descriptor Block for SA%s: "
6841+ "incoming packet with different policy SA, dropped.\n", sa);
6842+ goto rcvleave;
6843+ }
6844+
6845+ /* spin_unlock(&tdb_lock); */
6846+ }
6847+#endif /* INBOUND_POLICY_CHECK_eroute */
6848+
6849+ if(ipp->protocol == IPPROTO_IPIP) {
6850+ /*
6851+ * XXX this needs to be locked from when it was first looked
6852+ * up in the decapsulation loop. Perhaps it is better to put
6853+ * the IPIP decap inside the loop.
6854+ */
6855+ if(tdbp) {
6856+ tdbp->tdb_lifetime_bytes_c += len;
6857+ if(!tdbp->tdb_lifetime_usetime_c) {
6858+ tdbp->tdb_lifetime_usetime_c = jiffies / HZ;
6859+ }
6860+ tdbp->tdb_lifetime_usetime_l = jiffies / HZ;
6861+ tdbp->tdb_lifetime_packets_c += 1;
6862+ }
6863+
6864+ if(skb->len < iphlen) {
6865+ printk(KERN_WARNING "klips_debug:ipsec_rcv: "
6866+ "tried to skb_pull iphlen=%d, %d available. "
6867+ "This should never happen, please report.\n",
6868+ iphlen, (int)(skb->len));
6869+
6870+ spin_unlock(&tdb_lock);
6871+ goto rcvleave;
6872+ }
6873+ skb_pull(skb, iphlen);
6874+
6875+#ifdef NET_21
6876+ ipp = (struct iphdr *)skb->nh.raw = skb->data;
6877+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
6878+
6879+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
6880+#else /* NET_21 */
6881+ ipp = skb->ip_hdr = skb->h.iph = (struct iphdr *)skb->data;
6882+
6883+ memset(skb->proto_priv, 0, sizeof(struct options));
6884+#endif /* NET_21 */
6885+
6886+ skb->protocol = htons(ETH_P_IP);
6887+ skb->ip_summed = 0;
6888+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
6889+ "klips_debug:ipsec_rcv: IPIP tunnel stripped.\n");
6890+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
6891+ }
6892+
6893+ spin_unlock(&tdb_lock);
6894+
6895+#ifdef NET_21
6896+ if(stats) {
6897+ stats->rx_bytes += skb->len;
6898+ }
6899+ if(skb->dst) {
6900+ dst_release(skb->dst);
6901+ skb->dst = NULL;
6902+ }
6903+ skb->pkt_type = PACKET_HOST;
6904+ if(hard_header_len &&
6905+ (skb->mac.raw != (skb->data - hard_header_len)) &&
6906+ (hard_header_len <= skb_headroom(skb))) {
6907+ /* copy back original MAC header */
6908+ memmove(skb->data - hard_header_len, skb->mac.raw, hard_header_len);
6909+ skb->mac.raw = skb->data - hard_header_len;
6910+ }
6911+#endif /* NET_21 */
6912+
6913+#ifdef CONFIG_IPSEC_IPCOMP
6914+ if(ipp->protocol == IPPROTO_COMP) {
6915+ unsigned int flags = 0;
6916+
6917+ if(sysctl_ipsec_inbound_policy_check) {
6918+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
6919+ "klips_debug:ipsec_rcv: "
6920+ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
6921+ if (stats) {
6922+ stats->rx_errors++;
6923+ }
6924+ goto rcvleave;
6925+ }
6926+ /* XXX need a tdb for updating ratio counters XXX */
6927+ skb = skb_decompress(skb, NULL, &flags);
6928+ if (!skb || flags) {
6929+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
6930+ "klips_debug:ipsec_rcv: "
6931+ "skb_decompress() returned error flags: %d, dropped.\n",
6932+ flags);
6933+ if (stats) {
6934+ stats->rx_errors++;
6935+ }
6936+ goto rcvleave;
6937+ }
6938+#ifdef NET_21
6939+ ipp = skb->nh.iph;
6940+#else /* NET_21 */
6941+ ipp = skb->ip_hdr;
6942+#endif /* NET_21 */
6943+ }
6944+#endif /* CONFIG_IPSEC_IPCOMP */
6945+
6946+#ifdef SKB_RESET_NFCT
6947+ nf_conntrack_put(skb->nfct);
6948+ skb->nfct = NULL;
6949+#ifdef CONFIG_NETFILTER_DEBUG
6950+ skb->nf_debug = 0;
6951+#endif /* CONFIG_NETFILTER_DEBUG */
6952+#endif /* SKB_RESET_NFCT */
6953+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
6954+ "klips_debug:ipsec_rcv: netif_rx() called.\n");
6955+ netif_rx(skb);
6956+
6957+ MOD_DEC_USE_COUNT;
6958+ return(0);
6959+
6960+ rcvleave:
6961+ if(skb) {
6962+#ifdef NET_21
6963+ kfree_skb(skb);
6964+#else /* NET_21 */
6965+ kfree_skb(skb, FREE_WRITE);
6966+#endif /* NET_21 */
6967+ }
6968+
6969+ MOD_DEC_USE_COUNT;
6970+ return(0);
6971+}
6972+
6973+struct inet_protocol ah_protocol =
6974+{
6975+ ipsec_rcv, /* AH handler */
6976+ NULL, /* TUNNEL error control */
6977+ 0, /* next */
6978+ IPPROTO_AH, /* protocol ID */
6979+ 0, /* copy */
6980+ NULL, /* data */
6981+ "AH" /* name */
6982+};
6983+
6984+struct inet_protocol esp_protocol =
6985+{
6986+ ipsec_rcv, /* ESP handler */
6987+ NULL, /* TUNNEL error control */
6988+ 0, /* next */
6989+ IPPROTO_ESP, /* protocol ID */
6990+ 0, /* copy */
6991+ NULL, /* data */
6992+ "ESP" /* name */
6993+};
6994+
6995+#if 0
6996+/* We probably don't want to install a pure IPCOMP protocol handler, but
6997+ only want to handle IPCOMP if it is encapsulated inside an ESP payload
6998+ (which is already handled) */
6999+#ifdef CONFIG_IPSEC_IPCOMP
7000+struct inet_protocol comp_protocol =
7001+{
7002+ ipsec_rcv, /* COMP handler */
7003+ NULL, /* COMP error control */
7004+ 0, /* next */
7005+ IPPROTO_COMP, /* protocol ID */
7006+ 0, /* copy */
7007+ NULL, /* data */
7008+ "COMP" /* name */
7009+};
7010+#endif /* CONFIG_IPSEC_IPCOMP */
7011+#endif
7012+
7013+/*
7014+ * $Log$
7015+ * Revision 1.74 2000/11/25 03:50:36 rgb
7016+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
7017+ *
7018+ * Revision 1.73 2000/11/09 20:52:15 rgb
7019+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
7020+ * include ipcomp and prevent races, renaming some tdb variables that got
7021+ * forgotten, moving some unlocks to include tdbs and adding a missing
7022+ * unlock. Thanks to Svenning for some of these.
7023+ *
7024+ * Revision 1.72 2000/11/09 20:11:22 rgb
7025+ * Minor shuffles to fix non-standard kernel config option selection.
7026+ *
7027+ * Revision 1.71 2000/11/06 04:36:18 rgb
7028+ * Ditched spin_lock_irqsave in favour of spin_lock.
7029+ * Minor initial protocol check rewrite.
7030+ * Clean up debug printing.
7031+ * Clean up tdb handling on ipcomp.
7032+ * Fixed transport mode null pointer de-reference without ipcomp.
7033+ * Add Svenning's adaptive content compression.
7034+ * Disabled registration of ipcomp handler.
7035+ *
7036+ * Revision 1.70 2000/10/30 23:41:43 henry
7037+ * Hans-Joerg Hoexer's null-pointer fix
7038+ *
7039+ * Revision 1.69 2000/10/10 18:54:16 rgb
7040+ * Added a fix for incoming policy check with ipcomp enabled but
7041+ * uncompressible.
7042+ *
7043+ * Revision 1.68 2000/09/22 17:53:12 rgb
7044+ * Fixed ipcomp tdb pointers update for policy checking.
7045+ *
7046+ * Revision 1.67 2000/09/21 03:40:58 rgb
7047+ * Added more debugging to try and track down the cpi outward copy problem.
7048+ *
7049+ * Revision 1.66 2000/09/20 04:00:10 rgb
7050+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for
7051+ * debugging oopsen.
7052+ *
7053+ * Revision 1.65 2000/09/19 07:07:16 rgb
7054+ * Added debugging to inbound policy check for ipcomp.
7055+ * Added missing spin_unlocks (thanks Svenning!).
7056+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
7057+ * Protect ipcomp policy check following ipip decap with sysctl switch.
7058+ *
7059+ * Revision 1.64 2000/09/18 21:27:29 rgb
7060+ * 2.0 fixes.
7061+ *
7062+ * Revision 1.63 2000/09/18 02:35:50 rgb
7063+ * Added policy checking to ipcomp and re-enabled policy checking by
7064+ * default.
7065+ * Optimised satoa calls.
7066+ *
7067+ * Revision 1.62 2000/09/17 21:02:32 rgb
7068+ * Clean up debugging, removing slow timestamp debug code.
7069+ *
7070+ * Revision 1.61 2000/09/16 01:07:55 rgb
7071+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
7072+ *
7073+ * Revision 1.60 2000/09/15 11:37:01 rgb
7074+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
7075+ * IPCOMP zlib deflate code.
7076+ *
7077+ * Revision 1.59 2000/09/15 04:56:20 rgb
7078+ * Remove redundant satoa() call, reformat comment.
7079+ *
7080+ * Revision 1.58 2000/09/13 08:00:52 rgb
7081+ * Flick on inbound policy checking.
7082+ *
7083+ * Revision 1.57 2000/09/12 03:22:19 rgb
7084+ * Converted inbound_policy_check to sysctl.
7085+ * Re-enabled policy backcheck.
7086+ * Moved policy checks to top and within tdb lock.
7087+ *
7088+ * Revision 1.56 2000/09/08 19:12:56 rgb
7089+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
7090+ *
7091+ * Revision 1.55 2000/08/28 18:15:46 rgb
7092+ * Added MB's nf-debug reset patch.
7093+ *
7094+ * Revision 1.54 2000/08/27 01:41:26 rgb
7095+ * More minor tweaks to the bad padding debug code.
7096+ *
7097+ * Revision 1.53 2000/08/24 16:54:16 rgb
7098+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
7099+ * info.
7100+ * Tidied up device reporting at the start of ipsec_rcv.
7101+ * Tidied up bad padding debugging and processing.
7102+ *
7103+ * Revision 1.52 2000/08/20 21:36:03 rgb
7104+ * Activated pfkey_expire() calls.
7105+ * Added a hard/soft expiry parameter to pfkey_expire().
7106+ * Added sanity checking to avoid propagating zero or smaller-length skbs
7107+ * from a bogus decryption.
7108+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
7109+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
7110+ *
7111+ * Revision 1.51 2000/08/18 21:23:30 rgb
7112+ * Improve bad padding warning so that the printk buffer doesn't get
7113+ * trampled.
7114+ *
7115+ * Revision 1.50 2000/08/01 14:51:51 rgb
7116+ * Removed _all_ remaining traces of DES.
7117+ *
7118+ * Revision 1.49 2000/07/28 13:50:53 rgb
7119+ * Changed enet_statistics to net_device_stats and added back compatibility
7120+ * for pre-2.1.19.
7121+ *
7122+ * Revision 1.48 2000/05/10 19:14:40 rgb
7123+ * Only check usetime against soft and hard limits if the tdb has been
7124+ * used.
7125+ * Cast output of ntohl so that the broken prototype doesn't make our
7126+ * compile noisy.
7127+ *
7128+ * Revision 1.47 2000/05/09 17:45:43 rgb
7129+ * Fix replay bitmap corruption bug upon receipt of bogus packet
7130+ * with correct SPI. This was a DoS.
7131+ *
7132+ * Revision 1.46 2000/03/27 02:31:58 rgb
7133+ * Fixed authentication failure printout bug.
7134+ *
7135+ * Revision 1.45 2000/03/22 16:15:37 rgb
7136+ * Fixed renaming of dev_get (MB).
7137+ *
7138+ * Revision 1.44 2000/03/16 08:17:24 rgb
7139+ * Hardcode PF_KEYv2 support.
7140+ * Fixed minor bug checking AH header length.
7141+ *
7142+ * Revision 1.43 2000/03/14 12:26:59 rgb
7143+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
7144+ *
7145+ * Revision 1.42 2000/01/26 10:04:04 rgb
7146+ * Fixed inbound policy checking on transport mode bug.
7147+ * Fixed noisy 2.0 printk arguments.
7148+ *
7149+ * Revision 1.41 2000/01/24 20:58:02 rgb
7150+ * Improve debugging/reporting support for (disabled) inbound
7151+ * policy checking.
7152+ *
7153+ * Revision 1.40 2000/01/22 23:20:10 rgb
7154+ * Fixed up inboud policy checking code.
7155+ * Cleaned out unused crud.
7156+ *
7157+ * Revision 1.39 2000/01/21 06:15:29 rgb
7158+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
7159+ * Fixed cut-and-paste debug_tunnel to debug_rcv.
7160+ * Added inbound policy checking code, disabled.
7161+ * Simplified output code by updating ipp to post-IPIP decapsulation.
7162+ *
7163+ * Revision 1.38 1999/12/22 05:08:36 rgb
7164+ * Checked for null skb, skb->dev, skb->data, skb->dev->name, dev->name,
7165+ * protocol and take appropriate action for sanity.
7166+ * Set ipsecdev to NULL if device could not be determined.
7167+ * Fixed NULL stats access bug if device could not be determined.
7168+ *
7169+ * Revision 1.37 1999/12/14 20:07:59 rgb
7170+ * Added a default switch case to catch bogus encalg values.
7171+ *
7172+ * Revision 1.36 1999/12/07 18:57:57 rgb
7173+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
7174+ *
7175+ * Revision 1.35 1999/12/01 22:15:35 rgb
7176+ * Add checks for LARVAL and DEAD SAs.
7177+ * Change state of SA from MATURE to DYING when a soft lifetime is
7178+ * reached and print debug warning.
7179+ *
7180+ * Revision 1.34 1999/11/23 23:04:03 rgb
7181+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
7182+ * Sort out pfkey and freeswan headers, putting them in a library path.
7183+ *
7184+ * Revision 1.33 1999/11/19 01:10:06 rgb
7185+ * Enable protocol handler structures for static linking.
7186+ *
7187+ * Revision 1.32 1999/11/18 04:09:19 rgb
7188+ * Replaced all kernel version macros to shorter, readable form.
7189+ *
7190+ * Revision 1.31 1999/11/17 15:53:39 rgb
7191+ * Changed all occurrences of #include "../../../lib/freeswan.h"
7192+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
7193+ * klips/net/ipsec/Makefile.
7194+ *
7195+ * Revision 1.30 1999/10/26 15:09:07 rgb
7196+ * Used debug compiler directives to shut up compiler for decl/assign
7197+ * statement.
7198+ *
7199+ * Revision 1.29 1999/10/16 18:25:37 rgb
7200+ * Moved SA lifetime expiry checks before packet processing.
7201+ * Expire SA on replay counter rollover.
7202+ *
7203+ * Revision 1.28 1999/10/16 04:23:07 rgb
7204+ * Add stats for replaywin_errs, replaywin_max_sequence_difference,
7205+ * authentication errors, encryption size errors, encryption padding
7206+ * errors, and time since last packet.
7207+ *
7208+ * Revision 1.27 1999/10/16 00:30:47 rgb
7209+ * Added SA lifetime counting.
7210+ *
7211+ * Revision 1.26 1999/10/15 22:14:37 rgb
7212+ * Add debugging.
7213+ *
7214+ * Revision 1.25 1999/10/08 18:37:34 rgb
7215+ * Fix end-of-line spacing to sate whining PHMs.
7216+ *
7217+ * Revision 1.24 1999/10/03 18:54:51 rgb
7218+ * Spinlock support for 2.3.xx.
7219+ * Don't forget to undo spinlocks on error!
7220+ *
7221+ * Revision 1.23 1999/10/01 15:44:53 rgb
7222+ * Move spinlock header include to 2.1> scope.
7223+ *
7224+ * Revision 1.22 1999/10/01 00:01:54 rgb
7225+ * Added tdb structure locking.
7226+ *
7227+ * Revision 1.21 1999/09/18 11:42:12 rgb
7228+ * Add Marc Boucher's tcpdump cloned packet fix.
7229+ *
7230+ * Revision 1.20 1999/09/17 23:50:25 rgb
7231+ * Add Marc Boucher's hard_header_len patches.
7232+ *
7233+ * Revision 1.19 1999/09/10 05:31:36 henry
7234+ * tentative fix for 2.0.38-crash bug (move chunk of new code into 2.2 #ifdef)
7235+ *
7236+ * Revision 1.18 1999/08/28 08:28:06 rgb
7237+ * Delete redundant sanity check.
7238+ *
7239+ * Revision 1.17 1999/08/28 02:00:58 rgb
7240+ * Add an extra sanity check for null skbs.
7241+ *
7242+ * Revision 1.16 1999/08/27 05:21:38 rgb
7243+ * Clean up skb->data/raw/nh/h manipulation.
7244+ * Add Marc Boucher's mods to aid tcpdump.
7245+ *
7246+ * Revision 1.15 1999/08/25 14:22:40 rgb
7247+ * Require 4-octet boundary check only for ESP.
7248+ *
7249+ * Revision 1.14 1999/08/11 08:36:44 rgb
7250+ * Add compiler directives to allow configuring out AH, ESP or transforms.
7251+ *
7252+ * Revision 1.13 1999/08/03 17:10:49 rgb
7253+ * Cosmetic fixes and clarification to debug output.
7254+ *
7255+ * Revision 1.12 1999/05/09 03:25:36 rgb
7256+ * Fix bug introduced by 2.2 quick-and-dirty patch.
7257+ *
7258+ * Revision 1.11 1999/05/08 21:23:57 rgb
7259+ * Add casting to silence the 2.2.x compile.
7260+ *
7261+ * Revision 1.10 1999/05/05 22:02:31 rgb
7262+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
7263+ *
7264+ * Revision 1.9 1999/04/29 15:18:01 rgb
7265+ * hange debugging to respond only to debug_rcv.
7266+ * Change gettdb parameter to a pointer to reduce stack loading and
7267+ * facilitate parameter sanity checking.
7268+ *
7269+ * Revision 1.8 1999/04/15 15:37:24 rgb
7270+ * Forward check changes from POST1_00 branch.
7271+ *
7272+ * Revision 1.4.2.2 1999/04/13 20:32:45 rgb
7273+ * Move null skb sanity check.
7274+ * Silence debug a bit more when off.
7275+ * Use stats more effectively.
7276+ *
7277+ * Revision 1.4.2.1 1999/03/30 17:10:32 rgb
7278+ * Update AH+ESP bugfix.
7279+ *
7280+ * Revision 1.7 1999/04/11 00:28:59 henry
7281+ * GPL boilerplate
7282+ *
7283+ * Revision 1.6 1999/04/06 04:54:27 rgb
7284+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
7285+ * patch shell fixes.
7286+ *
7287+ * Revision 1.5 1999/03/17 15:39:23 rgb
7288+ * Code clean-up.
7289+ * Bundling bug fix.
7290+ * ESP_NULL esphlen and IV bug fix.
7291+ *
7292+ * Revision 1.4 1999/02/17 16:51:02 rgb
7293+ * Ditch NET_IPIP dependancy.
7294+ * Decapsulate recursively for an entire bundle.
7295+ *
7296+ * Revision 1.3 1999/02/12 21:22:47 rgb
7297+ * Convert debugging printks to KLIPS_PRINT macro.
7298+ * Clean-up cruft.
7299+ * Process IPIP tunnels internally.
7300+ *
7301+ * Revision 1.2 1999/01/26 02:07:36 rgb
7302+ * Clean up debug code when switched off.
7303+ * Remove references to INET_GET_PROTOCOL.
7304+ *
7305+ * Revision 1.1 1999/01/21 20:29:11 rgb
7306+ * Converted from transform switching to algorithm switching.
7307+ *
7308+ *
7309+ * Id: ipsec_esp.c,v 1.16 1998/12/02 03:08:11 rgb Exp $
7310+ *
7311+ * Log: ipsec_esp.c,v $
7312+ * Revision 1.16 1998/12/02 03:08:11 rgb
7313+ * Fix incoming I/F bug in AH and clean up inconsistencies in the I/F
7314+ * discovery routine in both AH and ESP.
7315+ *
7316+ * Revision 1.15 1998/11/30 13:22:51 rgb
7317+ * Rationalised all the klips kernel file headers. They are much shorter
7318+ * now and won't conflict under RH5.2.
7319+ *
7320+ * Revision 1.14 1998/11/10 05:55:37 rgb
7321+ * Add even more detail to 'wrong I/F' debug statement.
7322+ *
7323+ * Revision 1.13 1998/11/10 05:01:30 rgb
7324+ * Clean up debug output to be quiet when disabled.
7325+ * Add more detail to 'wrong I/F' debug statement.
7326+ *
7327+ * Revision 1.12 1998/10/31 06:39:32 rgb
7328+ * Fixed up comments in #endif directives.
7329+ * Tidied up debug printk output.
7330+ * Convert to addrtoa and satoa where possible.
7331+ *
7332+ * Revision 1.11 1998/10/27 00:49:30 rgb
7333+ * AH+ESP bundling bug has been squished.
7334+ * Cosmetic brace fixing in code.
7335+ * Newlines added before calls to ipsec_print_ip.
7336+ * Fix debug output function ID's.
7337+ *
7338+ * Revision 1.10 1998/10/22 06:37:22 rgb
7339+ * Fixed run-on error message to fit 80 columns.
7340+ *
7341+ * Revision 1.9 1998/10/20 02:41:04 rgb
7342+ * Fixed a replay window size sanity test bug.
7343+ *
7344+ * Revision 1.8 1998/10/19 18:55:27 rgb
7345+ * Added inclusion of freeswan.h.
7346+ * sa_id structure implemented and used: now includes protocol.
7347+ * \n bugfix to printk debug message.
7348+ *
7349+ * Revision 1.7 1998/10/09 04:23:03 rgb
7350+ * Fixed possible DoS caused by invalid transform called from an ESP
7351+ * packet. This should not be a problem when protocol is added to the SA.
7352+ * Sanity check added for null xf_input routine. Sanity check added for null
7353+ * socket buffer returned from xf_input routine.
7354+ * Added 'klips_debug' prefix to all klips printk debug statements.
7355+ *
7356+ * Revision 1.6 1998/07/14 15:56:04 rgb
7357+ * Set sdb->dev to virtual ipsec I/F.
7358+ *
7359+ * Revision 1.5 1998/06/30 18:07:46 rgb
7360+ * Change for ah/esp_protocol stuct visible only if module.
7361+ *
7362+ * Revision 1.4 1998/06/30 00:12:46 rgb
7363+ * Clean up a module compile error.
7364+ *
7365+ * Revision 1.3 1998/06/25 19:28:06 rgb
7366+ * Readjust premature unloading of module on packet receipt.
7367+ * Make protocol structure abailable to rest of kernel.
7368+ * Use macro for protocol number.
7369+ *
7370+ * Revision 1.2 1998/06/23 02:49:34 rgb
7371+ * Fix minor #include bug that prevented compiling without debugging.
7372+ * Added code to check for presence of IPIP protocol if an incoming packet
7373+ * is IPIP encapped.
7374+ *
7375+ * Revision 1.1 1998/06/18 21:27:44 henry
7376+ * move sources from klips/src to klips/net/ipsec, to keep stupid
7377+ * kernel-build scripts happier in the presence of symlinks
7378+ *
7379+ * Revision 1.9 1998/06/14 23:48:42 rgb
7380+ * Fix I/F name comparison oops bug.
7381+ *
7382+ * Revision 1.8 1998/06/11 07:20:04 rgb
7383+ * Stats fixed for rx_packets.
7384+ *
7385+ * Revision 1.7 1998/06/11 05:53:34 rgb
7386+ * Added stats for rx error and good packet reporting.
7387+ *
7388+ * Revision 1.6 1998/06/05 02:27:28 rgb
7389+ * Add rx_errors stats.
7390+ * Fix DoS bug: skb's not being freed on dropped packets.
7391+ *
7392+ * Revision 1.5 1998/05/27 21:21:29 rgb
7393+ * Fix DoS potential bug. skb was not being freed if the packet was bad.
7394+ *
7395+ * Revision 1.4 1998/05/18 22:31:37 rgb
7396+ * Minor change in debug output and comments.
7397+ *
7398+ * Revision 1.3 1998/04/21 21:29:02 rgb
7399+ * Rearrange debug switches to change on the fly debug output from user
7400+ * space. Only kernel changes checked in at this time. radij.c was also
7401+ * changed to temporarily remove buggy debugging code in rj_delete causing
7402+ * an OOPS and hence, netlink device open errors.
7403+ *
7404+ * Revision 1.2 1998/04/12 22:03:19 rgb
7405+ * Updated ESP-3DES-HMAC-MD5-96,
7406+ * ESP-DES-HMAC-MD5-96,
7407+ * AH-HMAC-MD5-96,
7408+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
7409+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
7410+ *
7411+ * Fixed eroute references in /proc/net/ipsec*.
7412+ *
7413+ * Started to patch module unloading memory leaks in ipsec_netlink and
7414+ * radij tree unloading.
7415+ *
7416+ * Revision 1.1 1998/04/09 03:05:59 henry
7417+ * sources moved up from linux/net/ipsec
7418+ *
7419+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
7420+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
7421+ *
7422+ * Revision 0.4 1997/01/15 01:28:15 ji
7423+ * Minor cosmetic changes.
7424+ *
7425+ * Revision 0.3 1996/11/20 14:35:48 ji
7426+ * Minor Cleanup.
7427+ * Rationalized debugging code.
7428+ *
7429+ * Revision 0.2 1996/11/02 00:18:33 ji
7430+ * First limited release.
7431+ *
7432+ *
7433+ */
7434diff -druN linux-noipsec/net/ipsec/ipsec_rcv.h linux/net/ipsec/ipsec_rcv.h
7435--- linux-noipsec/net/ipsec/ipsec_rcv.h Thu Jan 1 01:00:00 1970
7436+++ linux/net/ipsec/ipsec_rcv.h Thu Sep 21 06:34:21 2000
7437@@ -0,0 +1,161 @@
7438+/*
7439+ *
7440+ * Copyright (C) 1996, 1997 John Ioannidis.
7441+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
7442+ *
7443+ * This program is free software; you can redistribute it and/or modify it
7444+ * under the terms of the GNU General Public License as published by the
7445+ * Free Software Foundation; either version 2 of the License, or (at your
7446+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
7447+ *
7448+ * This program is distributed in the hope that it will be useful, but
7449+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7450+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7451+ * for more details.
7452+ *
7453+ * RCSID $Id$
7454+ */
7455+
7456+#define DB_RX_PKTRX 0x0001
7457+#define DB_RX_PKTRX2 0x0002
7458+#define DB_RX_DMP 0x0004
7459+#define DB_RX_TDB 0x0010
7460+#define DB_RX_XF 0x0020
7461+#define DB_RX_IPAD 0x0040
7462+#define DB_RX_INAU 0x0080
7463+#define DB_RX_OINFO 0x0100
7464+#define DB_RX_OINFO2 0x0200
7465+#define DB_RX_OH 0x0400
7466+#define DB_RX_REPLAY 0x0800
7467+
7468+#ifdef __KERNEL__
7469+/* struct options; */
7470+
7471+#define __NO_VERSION__
7472+#include <linux/module.h>
7473+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
7474+#include <linux/version.h>
7475+#include <freeswan.h>
7476+
7477+extern int
7478+ipsec_rcv(struct sk_buff *skb,
7479+#ifdef NET_21
7480+ unsigned short xlen);
7481+#else /* NET_21 */
7482+ struct device *dev,
7483+ struct options *opt,
7484+ __u32 daddr,
7485+ unsigned short len,
7486+ __u32 saddr,
7487+ int redo,
7488+ struct inet_protocol *protocol);
7489+#endif /* NET_21 */
7490+
7491+#ifdef CONFIG_IPSEC_DEBUG
7492+extern int debug_rcv;
7493+#endif /* CONFIG_IPSEC_DEBUG */
7494+extern int sysctl_ipsec_inbound_policy_check;
7495+#endif __KERNEL__
7496+
7497+/*
7498+ * $Log$
7499+ * Revision 1.11 2000/09/21 04:34:21 rgb
7500+ * Moved declaration of sysctl_ipsec_inbound_policy_check outside
7501+ * CONFIG_IPSEC_DEBUG. (MB)
7502+ *
7503+ * Revision 1.10 2000/09/18 02:36:10 rgb
7504+ * Exported sysctl_ipsec_inbound_policy_check for skb_decompress().
7505+ *
7506+ * Revision 1.9 2000/09/08 19:12:56 rgb
7507+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
7508+ *
7509+ * Revision 1.8 1999/11/18 04:09:19 rgb
7510+ * Replaced all kernel version macros to shorter, readable form.
7511+ *
7512+ * Revision 1.7 1999/05/25 01:45:37 rgb
7513+ * Fix version macros for 2.0.x as a module.
7514+ *
7515+ * Revision 1.6 1999/05/08 21:24:27 rgb
7516+ * Add includes for 2.2.x include into net/ipv4/protocol.c
7517+ *
7518+ * Revision 1.5 1999/05/05 22:02:32 rgb
7519+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
7520+ *
7521+ * Revision 1.4 1999/04/11 00:28:59 henry
7522+ * GPL boilerplate
7523+ *
7524+ * Revision 1.3 1999/04/06 04:54:27 rgb
7525+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
7526+ * patch shell fixes.
7527+ *
7528+ * Revision 1.2 1999/01/22 20:06:59 rgb
7529+ * Fixed cut-and-paste error from ipsec_esp.h.
7530+ *
7531+ * Revision 1.1 1999/01/21 20:29:12 rgb
7532+ * Converted from transform switching to algorithm switching.
7533+ *
7534+ * Log: ipsec_esp.h,v
7535+ * Revision 1.4 1998/08/12 00:07:32 rgb
7536+ * Added data structures for new xforms: null, {,3}dessha1.
7537+ *
7538+ * Revision 1.3 1998/07/14 15:57:01 rgb
7539+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
7540+ *
7541+ * Revision 1.2 1998/06/25 19:33:46 rgb
7542+ * Add prototype for protocol receive function.
7543+ * Rearrange for more logical layout.
7544+ *
7545+ * Revision 1.1 1998/06/18 21:27:45 henry
7546+ * move sources from klips/src to klips/net/ipsec, to keep stupid
7547+ * kernel-build scripts happier in the presence of symlinks
7548+ *
7549+ * Revision 1.6 1998/06/05 02:28:08 rgb
7550+ * Minor comment fix.
7551+ *
7552+ * Revision 1.5 1998/05/27 22:34:00 rgb
7553+ * Changed structures to accomodate key separation.
7554+ *
7555+ * Revision 1.4 1998/05/18 22:28:43 rgb
7556+ * Disable key printing facilities from /proc/net/ipsec_*.
7557+ *
7558+ * Revision 1.3 1998/04/21 21:29:07 rgb
7559+ * Rearrange debug switches to change on the fly debug output from user
7560+ * space. Only kernel changes checked in at this time. radij.c was also
7561+ * changed to temporarily remove buggy debugging code in rj_delete causing
7562+ * an OOPS and hence, netlink device open errors.
7563+ *
7564+ * Revision 1.2 1998/04/12 22:03:20 rgb
7565+ * Updated ESP-3DES-HMAC-MD5-96,
7566+ * ESP-DES-HMAC-MD5-96,
7567+ * AH-HMAC-MD5-96,
7568+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
7569+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
7570+ *
7571+ * Fixed eroute references in /proc/net/ipsec*.
7572+ *
7573+ * Started to patch module unloading memory leaks in ipsec_netlink and
7574+ * radij tree unloading.
7575+ *
7576+ * Revision 1.1 1998/04/09 03:06:00 henry
7577+ * sources moved up from linux/net/ipsec
7578+ *
7579+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
7580+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
7581+ *
7582+ * Revision 0.5 1997/06/03 04:24:48 ji
7583+ * Added ESP-3DES-MD5-96 transform.
7584+ *
7585+ * Revision 0.4 1997/01/15 01:28:15 ji
7586+ * Added definitions for new ESP transforms.
7587+ *
7588+ * Revision 0.3 1996/11/20 14:35:48 ji
7589+ * Minor Cleanup.
7590+ * Rationalized debugging code.
7591+ *
7592+ * Revision 0.2 1996/11/02 00:18:33 ji
7593+ * First limited release.
7594+ *
7595+ *
7596+ */
7597+
7598+
7599diff -druN linux-noipsec/net/ipsec/ipsec_sha1.c linux/net/ipsec/ipsec_sha1.c
7600--- linux-noipsec/net/ipsec/ipsec_sha1.c Thu Jan 1 01:00:00 1970
7601+++ linux/net/ipsec/ipsec_sha1.c Mon Dec 13 14:59:13 1999
7602@@ -0,0 +1,201 @@
7603+/*
7604+ * RCSID $Id$
7605+ */
7606+
7607+/*
7608+ * The rest of the code is derived from sha1.c by Steve Reid, which is
7609+ * public domain.
7610+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
7611+ */
7612+
7613+#include <asm/byteorder.h>
7614+#include <linux/string.h>
7615+
7616+#include "ipsec_sha1.h"
7617+
7618+#if defined(rol)
7619+#undef rol
7620+#endif
7621+
7622+#define SHA1HANDSOFF
7623+
7624+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
7625+
7626+/* blk0() and blk() perform the initial expand. */
7627+/* I got the idea of expanding during the round function from SSLeay */
7628+#ifdef __LITTLE_ENDIAN
7629+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
7630+ |(rol(block->l[i],8)&0x00FF00FF))
7631+#else
7632+#define blk0(i) block->l[i]
7633+#endif
7634+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
7635+ ^block->l[(i+2)&15]^block->l[i&15],1))
7636+
7637+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
7638+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
7639+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
7640+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
7641+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
7642+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
7643+
7644+
7645+/* Hash a single 512-bit block. This is the core of the algorithm. */
7646+
7647+void SHA1Transform(__u32 state[5], __u8 buffer[64])
7648+{
7649+__u32 a, b, c, d, e;
7650+typedef union {
7651+ unsigned char c[64];
7652+ __u32 l[16];
7653+} CHAR64LONG16;
7654+CHAR64LONG16* block;
7655+#ifdef SHA1HANDSOFF
7656+static unsigned char workspace[64];
7657+ block = (CHAR64LONG16*)workspace;
7658+ memcpy(block, buffer, 64);
7659+#else
7660+ block = (CHAR64LONG16*)buffer;
7661+#endif
7662+ /* Copy context->state[] to working vars */
7663+ a = state[0];
7664+ b = state[1];
7665+ c = state[2];
7666+ d = state[3];
7667+ e = state[4];
7668+ /* 4 rounds of 20 operations each. Loop unrolled. */
7669+ 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);
7670+ 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);
7671+ 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);
7672+ 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);
7673+ 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);
7674+ 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);
7675+ 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);
7676+ 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);
7677+ 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);
7678+ 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);
7679+ 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);
7680+ 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);
7681+ 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);
7682+ 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);
7683+ 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);
7684+ 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);
7685+ 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);
7686+ 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);
7687+ 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);
7688+ 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);
7689+ /* Add the working vars back into context.state[] */
7690+ state[0] += a;
7691+ state[1] += b;
7692+ state[2] += c;
7693+ state[3] += d;
7694+ state[4] += e;
7695+ /* Wipe variables */
7696+ a = b = c = d = e = 0;
7697+}
7698+
7699+
7700+/* SHA1Init - Initialize new context */
7701+
7702+void SHA1Init(SHA1_CTX* context)
7703+{
7704+ /* SHA1 initialization constants */
7705+ context->state[0] = 0x67452301;
7706+ context->state[1] = 0xEFCDAB89;
7707+ context->state[2] = 0x98BADCFE;
7708+ context->state[3] = 0x10325476;
7709+ context->state[4] = 0xC3D2E1F0;
7710+ context->count[0] = context->count[1] = 0;
7711+}
7712+
7713+
7714+/* Run your data through this. */
7715+
7716+void SHA1Update(SHA1_CTX* context, unsigned char* data, __u32 len)
7717+{
7718+__u32 i, j;
7719+
7720+ j = context->count[0];
7721+ if ((context->count[0] += len << 3) < j)
7722+ context->count[1]++;
7723+ context->count[1] += (len>>29);
7724+ j = (j >> 3) & 63;
7725+ if ((j + len) > 63) {
7726+ memcpy(&context->buffer[j], data, (i = 64-j));
7727+ SHA1Transform(context->state, context->buffer);
7728+ for ( ; i + 63 < len; i += 64) {
7729+ SHA1Transform(context->state, &data[i]);
7730+ }
7731+ j = 0;
7732+ }
7733+ else i = 0;
7734+ memcpy(&context->buffer[j], &data[i], len - i);
7735+}
7736+
7737+
7738+/* Add padding and return the message digest. */
7739+
7740+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
7741+{
7742+__u32 i, j;
7743+unsigned char finalcount[8];
7744+
7745+ for (i = 0; i < 8; i++) {
7746+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
7747+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
7748+ }
7749+ SHA1Update(context, (unsigned char *)"\200", 1);
7750+ while ((context->count[0] & 504) != 448) {
7751+ SHA1Update(context, (unsigned char *)"\0", 1);
7752+ }
7753+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
7754+ for (i = 0; i < 20; i++) {
7755+ digest[i] = (unsigned char)
7756+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
7757+ }
7758+ /* Wipe variables */
7759+ i = j = 0;
7760+ memset(context->buffer, 0, 64);
7761+ memset(context->state, 0, 20);
7762+ memset(context->count, 0, 8);
7763+ memset(&finalcount, 0, 8);
7764+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
7765+ SHA1Transform(context->state, context->buffer);
7766+#endif
7767+}
7768+
7769+
7770+/*
7771+ * $Log$
7772+ * Revision 1.5 1999/12/13 13:59:13 rgb
7773+ * Quick fix to argument size to Update bugs.
7774+ *
7775+ * Revision 1.4 1999/04/11 00:29:00 henry
7776+ * GPL boilerplate
7777+ *
7778+ * Revision 1.3 1999/04/06 04:54:27 rgb
7779+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
7780+ * patch shell fixes.
7781+ *
7782+ * Revision 1.2 1999/01/22 06:55:50 rgb
7783+ * 64-bit clean-up.
7784+ *
7785+ * Revision 1.1 1998/06/18 21:27:50 henry
7786+ * move sources from klips/src to klips/net/ipsec, to keep stupid
7787+ * kernel-build scripts happier in the presence of symlinks
7788+ *
7789+ * Revision 1.2 1998/04/23 20:54:04 rgb
7790+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
7791+ * verified.
7792+ *
7793+ * Revision 1.1 1998/04/09 03:06:11 henry
7794+ * sources moved up from linux/net/ipsec
7795+ *
7796+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
7797+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
7798+ *
7799+ * Revision 0.4 1997/01/15 01:28:15 ji
7800+ * New transform
7801+ *
7802+ *
7803+ */
7804diff -druN linux-noipsec/net/ipsec/ipsec_sha1.h linux/net/ipsec/ipsec_sha1.h
7805--- linux-noipsec/net/ipsec/ipsec_sha1.h Thu Jan 1 01:00:00 1970
7806+++ linux/net/ipsec/ipsec_sha1.h Mon Dec 13 14:59:13 1999
7807@@ -0,0 +1,68 @@
7808+/*
7809+ * RCSID $Id$
7810+ */
7811+
7812+/*
7813+ * Here is the original comment from the distribution:
7814+
7815+SHA-1 in C
7816+By Steve Reid <steve@edmweb.com>
7817+100% Public Domain
7818+
7819+ * Adapted for use by the IPSEC code by John Ioannidis
7820+ */
7821+
7822+
7823+#ifndef _IPSEC_SHA1_H_
7824+#define _IPSEC_SHA1_H_
7825+
7826+typedef struct
7827+{
7828+ __u32 state[5];
7829+ __u32 count[2];
7830+ __u8 buffer[64];
7831+} SHA1_CTX;
7832+
7833+void SHA1Transform(__u32 state[5], __u8 buffer[64]);
7834+void SHA1Init(SHA1_CTX *context);
7835+void SHA1Update(SHA1_CTX *context, unsigned char *data, __u32 len);
7836+void SHA1Final(unsigned char digest[20], SHA1_CTX *context);
7837+
7838+
7839+#endif /* _IPSEC_SHA1_H_ */
7840+
7841+/*
7842+ * $Log$
7843+ * Revision 1.5 1999/12/13 13:59:13 rgb
7844+ * Quick fix to argument size to Update bugs.
7845+ *
7846+ * Revision 1.4 1999/12/07 18:16:23 rgb
7847+ * Fixed comments at end of #endif lines.
7848+ *
7849+ * Revision 1.3 1999/04/06 04:54:27 rgb
7850+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
7851+ * patch shell fixes.
7852+ *
7853+ * Revision 1.2 1998/11/30 13:22:54 rgb
7854+ * Rationalised all the klips kernel file headers. They are much shorter
7855+ * now and won't conflict under RH5.2.
7856+ *
7857+ * Revision 1.1 1998/06/18 21:27:50 henry
7858+ * move sources from klips/src to klips/net/ipsec, to keep stupid
7859+ * kernel-build scripts happier in the presence of symlinks
7860+ *
7861+ * Revision 1.2 1998/04/23 20:54:05 rgb
7862+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
7863+ * verified.
7864+ *
7865+ * Revision 1.1 1998/04/09 03:04:21 henry
7866+ * sources moved up from linux/net/ipsec
7867+ * these two include files modified not to include others except in kernel
7868+ *
7869+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
7870+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
7871+ *
7872+ * Revision 0.4 1997/01/15 01:28:15 ji
7873+ * New transform
7874+ *
7875+ */
7876diff -druN linux-noipsec/net/ipsec/ipsec_tunnel.c linux/net/ipsec/ipsec_tunnel.c
7877--- linux-noipsec/net/ipsec/ipsec_tunnel.c Thu Jan 1 01:00:00 1970
7878+++ linux/net/ipsec/ipsec_tunnel.c Thu Nov 9 21:52:15 2000
7879@@ -0,0 +1,3065 @@
7880+/*
7881+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
7882+ * Copyright (C) 1996, 1997 John Ioannidis.
7883+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
7884+ *
7885+ * This program is free software; you can redistribute it and/or modify it
7886+ * under the terms of the GNU General Public License as published by the
7887+ * Free Software Foundation; either version 2 of the License, or (at your
7888+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
7889+ *
7890+ * This program is distributed in the hope that it will be useful, but
7891+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7892+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7893+ * for more details.
7894+ */
7895+
7896+char ipsec_tunnel_c_version[] = "RCSID $Id$";
7897+
7898+#define __NO_VERSION__
7899+#include <linux/module.h>
7900+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
7901+#include <linux/version.h>
7902+
7903+#include <linux/kernel.h> /* printk() */
7904+#include <linux/malloc.h> /* kmalloc() */
7905+#include <linux/errno.h> /* error codes */
7906+#include <linux/types.h> /* size_t */
7907+#include <linux/interrupt.h> /* mark_bh */
7908+
7909+#include <linux/netdevice.h> /* struct device, and other headers */
7910+#include <linux/etherdevice.h> /* eth_type_trans */
7911+#include <linux/ip.h> /* struct iphdr */
7912+#include <linux/tcp.h> /* struct tcphdr */
7913+#include <linux/udp.h> /* struct udphdr */
7914+#include <linux/skbuff.h>
7915+#include <freeswan.h>
7916+#ifdef SPINLOCK
7917+ #ifdef SPINLOCK_23
7918+ #include <linux/spinlock.h> /* *lock* */
7919+ #else /* SPINLOCK_23 */
7920+ #include <asm/spinlock.h> /* *lock* */
7921+ #endif /* SPINLOCK_23 */
7922+#endif /* SPINLOCK */
7923+#ifdef NET_21
7924+ #define MSS_HACK_ /* experimental */
7925+ #include <asm/uaccess.h>
7926+ #include <linux/in6.h>
7927+ #define ip_chk_addr inet_addr_type
7928+ #define IS_MYADDR RTN_LOCAL
7929+ #include <net/dst.h>
7930+ #undef dev_kfree_skb
7931+ #define dev_kfree_skb(a,b) kfree_skb(a)
7932+ #define proto_priv cb
7933+ #define PHYSDEV_TYPE
7934+ #define DEV_QUEUE_XMIT(skb, device, pri) {\
7935+ skb->dev = device; \
7936+ neigh_compat_output(skb); \
7937+ /* skb->dst->output(skb); */ \
7938+ }
7939+ #define ICMP_SEND(skb_in, type, code, info, dev) \
7940+ icmp_send(skb_in, type, code, htonl(info))
7941+ #define IP_SEND(skb, dev) \
7942+ ip_send(skb);
7943+#else /* NET_21 */
7944+ #define DEV_QUEUE_XMIT(skb, device, pri) {\
7945+ dev_queue_xmit(skb, device, pri); \
7946+ }
7947+ #define ICMP_SEND(skb_in, type, code, info, dev) \
7948+ icmp_send(skb_in, type, code, info, dev)
7949+ #define IP_SEND(skb, dev) \
7950+ if(ntohs(iph->tot_len) > physmtu) { \
7951+ ip_fragment(NULL, skb, dev, 0); \
7952+ dev_kfree_skb(skb, FREE_WRITE); \
7953+ } else { \
7954+ dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
7955+ }
7956+#endif /* NET_21 */
7957+#include <asm/checksum.h>
7958+#include <net/icmp.h> /* icmp_send() */
7959+#include <net/ip.h>
7960+#ifdef NETDEV_23
7961+#include <linux/netfilter_ipv4.h>
7962+#endif
7963+
7964+#include "radij.h"
7965+#include "ipsec_encap.h"
7966+#include "ipsec_radij.h"
7967+#include "ipsec_netlink.h"
7968+#include "ipsec_xform.h"
7969+#include "ipsec_tunnel.h"
7970+#include "ipsec_ipe4.h"
7971+#include "ipsec_ah.h"
7972+#include "ipsec_esp.h"
7973+
7974+#ifdef CONFIG_IPSEC_IPCOMP
7975+#include "ipcomp.h"
7976+#endif /* CONFIG_IPSEC_IPCOMP */
7977+
7978+#include <pfkeyv2.h>
7979+#include <pfkey.h>
7980+
7981+#include <net/ip.h>
7982+#include <linux/if_arp.h>
7983+#ifdef MSS_HACK
7984+#include <net/tcp.h> /* TCP options */
7985+#endif /* MSS_HACK */
7986+extern void des_ede3_cbc_encrypt(caddr_t, caddr_t, int, caddr_t, caddr_t, caddr_t, caddr_t, int);
7987+static __u32 zeroes[64];
7988+
7989+#ifdef CONFIG_IPSEC_DEBUG
7990+int debug_tunnel = 0;
7991+int sysctl_ipsec_debug_verbose = 0;
7992+#endif /* CONFIG_IPSEC_DEBUG */
7993+
7994+int sysctl_ipsec_icmp = 0;
7995+int sysctl_ipsec_no_eroute_pass = 0;
7996+int sysctl_ipsec_opportunistic = 0;
7997+int sysctl_ipsec_tos = 0;
7998+
7999+#ifdef CONFIG_IPSEC_DEBUG_
8000+DEBUG_NO_STATIC void
8001+dmp(char *s, caddr_t bb, int len)
8002+{
8003+ int i;
8004+ unsigned char *b = bb;
8005+
8006+ if (debug_tunnel) {
8007+ printk(KERN_INFO "klips_debug:ipsec_tunnel_:at %s, len=%d:", s, len);
8008+ for (i=0; i < len; i++) {
8009+ if(!(i%16)){
8010+ printk("\nklips_debug: ");
8011+ }
8012+ printk(" %02x", *b++);
8013+ }
8014+ printk("\n");
8015+ }
8016+}
8017+#else /* CONFIG_IPSEC_DEBUG */
8018+#define dmp(_x, _y, _z)
8019+#endif /* CONFIG_IPSEC_DEBUG */
8020+
8021+#ifndef SKB_COPY_EXPAND
8022+/*
8023+ * This is mostly skbuff.c:skb_copy().
8024+ */
8025+struct sk_buff *
8026+skb_copy_expand(struct sk_buff *skb, int headroom, int tailroom, int priority)
8027+{
8028+ struct sk_buff *n;
8029+ unsigned long offset;
8030+
8031+ /*
8032+ * Do sanity checking
8033+ */
8034+ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
8035+ printk(KERN_WARNING "klips_error:skb_copy_expand: "
8036+ "Illegal negative head,tailroom %d,%d\n",
8037+ headroom, tailroom);
8038+ return NULL;
8039+ }
8040+ /*
8041+ * Allocate the copy buffer
8042+ */
8043+
8044+#ifndef NET_21
8045+ IS_SKB(skb);
8046+#endif /* !NET_21 */
8047+
8048+
8049+ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
8050+
8051+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8052+ "klips_debug:skb_copy_expand: "
8053+ "head=%p data=%p tail=%p end=%p end-head=%d tail-data=%d\n",
8054+ skb->head,
8055+ skb->data,
8056+ skb->tail,
8057+ skb->end,
8058+ skb->end - skb->head,
8059+ skb->tail - skb->data);
8060+
8061+ if(n==NULL)
8062+ return NULL;
8063+
8064+ /*
8065+ * Shift between the two data areas in bytes
8066+ */
8067+
8068+ /* offset=n->head-skb->head; */ /* moved down a few lines */
8069+
8070+ /* Set the data pointer */
8071+ skb_reserve(n,skb->data-skb->head+headroom);
8072+ /* Set the tail pointer and length */
8073+ if(skb_tailroom(n) < skb->len) {
8074+ printk(KERN_WARNING "klips_error:skb_copy_expand: "
8075+ "tried to skb_put %ld, %d available. "
8076+ "This should never happen, please report.\n",
8077+ (unsigned long int)skb->len, skb_tailroom(n));
8078+ dev_kfree_skb(n, FREE_WRITE);
8079+ return NULL;
8080+ }
8081+ skb_put(n,skb->len);
8082+
8083+ offset=n->head + headroom - skb->head;
8084+
8085+ /* Copy the bytes */
8086+ memcpy(n->head + headroom, skb->head,skb->end-skb->head);
8087+#ifdef NET_21
8088+ n->csum=skb->csum;
8089+ n->priority=skb->priority;
8090+ n->dst=dst_clone(skb->dst);
8091+ if(skb->nh.raw)
8092+ n->nh.raw=skb->nh.raw+offset;
8093+ n->is_clone=0;
8094+ atomic_set(&n->users, 1);
8095+ n->destructor = NULL;
8096+ n->security=skb->security;
8097+#else /* NET_21 */
8098+ n->link3=NULL;
8099+ n->when=skb->when;
8100+ if(skb->ip_hdr)
8101+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
8102+ n->saddr=skb->saddr;
8103+ n->daddr=skb->daddr;
8104+ n->raddr=skb->raddr;
8105+ n->seq=skb->seq;
8106+ n->end_seq=skb->end_seq;
8107+ n->ack_seq=skb->ack_seq;
8108+ n->acked=skb->acked;
8109+ n->free=1;
8110+ n->arp=skb->arp;
8111+ n->tries=0;
8112+ n->lock=0;
8113+ n->users=0;
8114+#endif /* NET_21 */
8115+ n->protocol=skb->protocol;
8116+ n->list=NULL;
8117+ n->sk=NULL;
8118+ n->dev=skb->dev;
8119+ if(skb->h.raw)
8120+ n->h.raw=skb->h.raw+offset;
8121+ if(skb->mac.raw)
8122+ n->mac.raw=skb->mac.raw+offset;
8123+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
8124+ n->used=skb->used;
8125+ n->pkt_type=skb->pkt_type;
8126+ n->stamp=skb->stamp;
8127+
8128+#ifndef NET_21
8129+ IS_SKB(n);
8130+#endif /* !NET_21 */
8131+ return n;
8132+}
8133+#endif /* !SKB_COPY_EXPAND */
8134+
8135+#ifdef CONFIG_IPSEC_DEBUG
8136+void
8137+ipsec_print_ip(struct iphdr *ip)
8138+{
8139+ char buf[ADDRTOA_BUF];
8140+
8141+ printk(KERN_INFO "klips_debug: IP:");
8142+ printk(" ihl:%d", ip->ihl*4);
8143+ printk(" ver:%d", ip->version);
8144+ printk(" tos:%d", ip->tos);
8145+ printk(" tlen:%d", ntohs(ip->tot_len));
8146+ printk(" id:%d", ip->id);
8147+ printk(" frag_off:%d", ip->frag_off);
8148+ printk(" ttl:%d", ip->ttl);
8149+ printk(" proto:%d", ip->protocol);
8150+ printk(" chk:%d", ip->check);
8151+ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
8152+ printk(" saddr:%s", buf);
8153+ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
8154+ printk(" daddr:%s", buf);
8155+ printk("\n");
8156+
8157+ if(sysctl_ipsec_debug_verbose) {
8158+ __u8 *c;
8159+ int i;
8160+
8161+ c = ((__u8*)ip) + ip->ihl*4;
8162+ for(i = 0; i < ntohs(ip->tot_len) - ip->ihl*4; i++ /*, c++*/) {
8163+ if(!(i % 16)) {
8164+ printk(KERN_INFO "klips_debug: @%03x:",
8165+ i);
8166+ }
8167+ printk(" %02x", /***/c[i]);
8168+ if(!((i + 1) % 16)) {
8169+ printk("\n");
8170+ }
8171+ }
8172+ if(i % 16) {
8173+ printk("\n");
8174+ }
8175+ }
8176+}
8177+#endif /* CONFIG_IPSEC_DEBUG */
8178+
8179+#ifdef REAL_LOCKING_P
8180+/*
8181+ * Locking
8182+ */
8183+
8184+DEBUG_NO_STATIC int
8185+ipsec_tunnel_lock(struct ipsecpriv *prv)
8186+{
8187+ unsigned long flags;
8188+ save_flags(flags);
8189+ cli();
8190+ /*
8191+ * Lock in an interrupt may fail
8192+ */
8193+ if(prv->locked && in_interrupt()) {
8194+ restore_flags(flags);
8195+ return 0;
8196+ }
8197+ while(prv->locked)
8198+ sleep_on(&prv->wait_queue);
8199+ prv->locked=1;
8200+ restore_flags(flags);
8201+ return 1;
8202+}
8203+
8204+DEBUG_NO_STATIC void
8205+ipsec_tunnel_unlock(struct ipsecpriv *prv)
8206+{
8207+ prv->locked=0;
8208+ wake_up(&prv->wait_queue);
8209+}
8210+#endif /* REAL_LOCKING_P */
8211+
8212+DEBUG_NO_STATIC int
8213+ipsec_tunnel_open(struct device *dev)
8214+{
8215+ struct ipsecpriv *prv = dev->priv;
8216+
8217+ /*
8218+ * Can't open until attached.
8219+ */
8220+
8221+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
8222+ "klips_debug:ipsec_tunnel_open: "
8223+ "dev = %s, prv->dev = %s\n",
8224+ dev->name, prv->dev?prv->dev->name:"NONE");
8225+
8226+ if (prv->dev == NULL)
8227+ return -ENODEV;
8228+
8229+ MOD_INC_USE_COUNT;
8230+ return 0;
8231+}
8232+
8233+DEBUG_NO_STATIC int
8234+ipsec_tunnel_close(struct device *dev)
8235+{
8236+ MOD_DEC_USE_COUNT;
8237+ return 0;
8238+}
8239+
8240+#ifdef MSS_HACK
8241+/*
8242+ * Issues:
8243+ * 1) Fragments arriving in the tunnel should probably be rejected.
8244+ * 2) How does this affect syncookies, mss_cache, dst cache ?
8245+ * 3) Path MTU discovery handling needs to be reviewed. For example,
8246+ * if we receive an ICMP 'packet too big' message from an intermediate
8247+ * router specifying it's next hop MTU, our stack may process this and
8248+ * adjust the MSS without taking our AH/ESP overheads into account.
8249+ */
8250+
8251+
8252+/*
8253+ * Recaclulate checksum using differences between changed datum,
8254+ * borrowed from netfilter.
8255+ */
8256+DEBUG_NO_STATIC u_int16_t
8257+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
8258+{
8259+ u_int32_t diffs[] = { oldvalinv, newval };
8260+ return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
8261+ oldcheck^0xFFFF));
8262+}
8263+
8264+/*
8265+ * Determine effective MSS.
8266+ *
8267+ * Note that we assume that there is always an MSS option for our own
8268+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
8269+ * This could change, and we should probably parse TCP options instead.
8270+ *
8271+ */
8272+DEBUG_NO_STATIC u_int8_t
8273+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
8274+{
8275+ u_int16_t oldmss, newmss;
8276+ u_int32_t *mssp;
8277+ struct sock *sk = skb->sk;
8278+
8279+ newmss = tcp_sync_mss(sk, mtu);
8280+ printk(KERN_INFO "klips: setting mss to %u\n", newmss);
8281+ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
8282+ oldmss = ntohl(*mssp) & 0x0000FFFF;
8283+ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
8284+ tcph->check = ipsec_fast_csum(htons(~oldmss),
8285+ htons(newmss), tcph->check);
8286+ return 1;
8287+}
8288+#endif /* MSS_HACK */
8289+
8290+#ifdef NETDEV_23
8291+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
8292+{
8293+ return ip_send(skb);
8294+}
8295+#endif
8296+
8297+/*
8298+ * This function assumes it is being called from dev_queue_xmit()
8299+ * and that skb is filled properly by that function.
8300+ */
8301+
8302+int
8303+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev)
8304+{
8305+ struct ipsecpriv *prv; /* Our device' private space */
8306+ struct sk_buff *oskb = NULL; /* Original skb pointer */
8307+ struct net_device_stats *stats; /* This device's statistics */
8308+ struct iphdr *iph; /* Our new IP header */
8309+ __u32 newdst; /* The other SG's IP address */
8310+ __u32 orgdst; /* Original IP destination address */
8311+ __u32 orgedst; /* 1st SG's IP address */
8312+ __u32 newsrc; /* The new source SG's IP address */
8313+ __u32 orgsrc; /* Original IP source address */
8314+ __u32 innersrc; /* Innermost IP source address */
8315+ int iphlen; /* IP header length */
8316+ int pyldsz; /* upper protocol payload size */
8317+ int headroom;
8318+ int tailroom;
8319+ int max_headroom = 0; /* The extra header space needed */
8320+ int max_tailroom = 0; /* The extra stuffing needed */
8321+ int ll_headroom; /* The extra link layer hard_header space needed */
8322+ int tot_headroom = 0; /* The total header space needed */
8323+ int tot_tailroom = 0; /* The totalstuffing needed */
8324+ __u8 *saved_header = NULL; /* saved copy of the hard header */
8325+ int i;
8326+
8327+ struct sockaddr_encap matcher; /* eroute search key */
8328+ struct eroute *er;
8329+ struct tdb *tdbp, *tdbq; /* Tunnel Descriptor Block pointers */
8330+ char sa[SATOA_BUF];
8331+ size_t sa_len;
8332+ int hard_header_stripped = 0; /* has the hard header been removed yet? */
8333+ int hard_header_len = 0;
8334+ struct device *physdev;
8335+/* struct device *virtdev; */
8336+ short physmtu;
8337+ short mtudiff;
8338+#ifdef NET_21
8339+ struct rtable *rt = NULL;
8340+#endif /* NET_21 */
8341+ struct sa_id outgoing_said;
8342+
8343+ /*
8344+ * Return if there is nothing to do. (Does this ever happen?) XXX
8345+ */
8346+ if (skb == NULL) {
8347+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8348+ "klips_error:ipsec_tunnel_start_xmit: "
8349+ "Nothing to do!\n" );
8350+ goto cleanup;
8351+ }
8352+ if (dev == NULL) {
8353+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8354+ "klips_error:ipsec_tunnel_start_xmit: "
8355+ "No device associated with skb!\n" );
8356+ goto cleanup;
8357+ }
8358+
8359+ prv = dev->priv;
8360+ if (prv == NULL) {
8361+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8362+ "klips_error:ipsec_tunnel_start_xmit: "
8363+ "Device has no private structure!\n" );
8364+ goto cleanup;
8365+ }
8366+
8367+ physdev = prv->dev;
8368+ if (physdev == NULL) {
8369+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8370+ "klips_error:ipsec_tunnel_start_xmit: "
8371+ "Device is not attached to physical device!\n" );
8372+ goto cleanup;
8373+ }
8374+
8375+ physmtu = physdev->mtu;
8376+
8377+ stats = (struct net_device_stats *) &(prv->mystats);
8378+
8379+#ifdef NET_21
8380+ /* if skb was cloned (most likely due to a packet sniffer such as
8381+ tcpdump being momentarily attached to the interface), make
8382+ a copy of our own to modify */
8383+ if(skb_cloned(skb)) {
8384+ if ((skb = skb_cow(skb, skb_headroom(skb))) == NULL) {
8385+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8386+ "klips_error:ipsec_tunnel_start_xmit: "
8387+ "skb_cow failed to allocate buffer, dropping.\n" );
8388+ goto cleanup;
8389+ }
8390+ }
8391+#endif /* NET_21 */
8392+
8393+#ifdef NET_21
8394+ iph = skb->nh.iph;
8395+#else /* NET_21 */
8396+ iph = skb->ip_hdr;
8397+#endif /* NET_21 */
8398+
8399+ /* physdev->hard_header_len is unreliable and should not be used */
8400+ hard_header_len = (unsigned char *)iph - skb->data;
8401+
8402+ if(hard_header_len < 0) {
8403+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8404+ "klips_error:ipsec_tunnel_start_xmit: "
8405+ "Negative hard_header_len (%d)?!\n", hard_header_len);
8406+ stats->tx_dropped++;
8407+ goto cleanup;
8408+ }
8409+
8410+ if(hard_header_len == 0) { /* no hard header present */
8411+ hard_header_stripped = 1;
8412+ }
8413+
8414+#ifdef CONFIG_IPSEC_DEBUG
8415+ if (debug_tunnel & DB_TN_XMIT) {
8416+ int i;
8417+ char c;
8418+
8419+ printk(KERN_INFO "klips_debug:ipsec_tunnel_start_xmit: "
8420+ ">>> skb->len=%ld hard_header_len:%d",
8421+ (unsigned long int)skb->len, hard_header_len);
8422+ c = ' ';
8423+ for (i=0; i < hard_header_len; i++) {
8424+ printk("%c%02x", c, skb->data[i]);
8425+ c = ':';
8426+ }
8427+ printk(" \n");
8428+ }
8429+#endif /* CONFIG_IPSEC_DEBUG */
8430+
8431+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph);
8432+
8433+ /*
8434+ * Sanity checks
8435+ */
8436+
8437+ if ((iph->ihl << 2) != sizeof (struct iphdr)) {
8438+ KLIPS_PRINT(debug_tunnel,
8439+ "klips_debug:ipsec_tunnel_start_xmit: "
8440+ "cannot process IP header options yet. "
8441+ "May be mal-formed packet.\n"); /* XXX */
8442+ stats->tx_dropped++;
8443+ goto cleanup;
8444+ }
8445+
8446+#ifndef NET_21
8447+ /* TTL decrement code (on the way out!) borrowed from ip_forward.c */
8448+ if(0) {
8449+ unsigned long checksum = iph->check;
8450+ iph->ttl--;
8451+ /*
8452+ * Re-compute the IP header checksum.
8453+ * This is efficient. We know what has happened to the header
8454+ * and can thus adjust the checksum as Phil Karn does in KA9Q
8455+ * except we do this in "network byte order".
8456+ */
8457+ checksum += htons(0x0100);
8458+ /* carry overflow? */
8459+ checksum += checksum >> 16;
8460+ iph->check = checksum;
8461+ }
8462+ if (iph->ttl <= 0) {
8463+ /* Tell the sender its packet died... */
8464+ ICMP_SEND(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, physdev);
8465+
8466+ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_tunnel_start_xmit: "
8467+ "TTL=0, too many hops!\n");
8468+ stats->tx_dropped++;
8469+ goto cleanup;
8470+ }
8471+#endif /* !NET_21 */
8472+
8473+ /*
8474+ * First things first -- look us up in the erouting tables.
8475+ */
8476+ matcher.sen_len = sizeof (struct sockaddr_encap);
8477+ matcher.sen_family = AF_ENCAP;
8478+ matcher.sen_type = SENT_IP4;
8479+ matcher.sen_ip_src.s_addr = iph->saddr;
8480+ matcher.sen_ip_dst.s_addr = iph->daddr;
8481+
8482+ /*
8483+ * The spinlock is to prevent any other process from accessing or deleting
8484+ * the eroute while we are using and updating it.
8485+ */
8486+ spin_lock(&eroute_lock);
8487+
8488+ er = ipsec_findroute(&matcher);
8489+ if(er) {
8490+ outgoing_said = er->er_said;
8491+ }
8492+
8493+ spin_unlock(&eroute_lock);
8494+
8495+ /*
8496+ * Quick cheat for now...are we udp/500? If so, let it through
8497+ * without interference since it is most likely an IKE packet.
8498+ */
8499+ if((ip_chk_addr((unsigned long)iph->saddr) == IS_MYADDR)
8500+ && ((!er) || (iph->daddr == outgoing_said.dst.s_addr))) {
8501+ if(iph->protocol == IPPROTO_UDP) {
8502+ struct udphdr *udph = (struct udphdr*)((caddr_t)iph + (iph->ihl << 2));
8503+ if(ntohs(udph->dest) == 500) {
8504+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8505+ "klips_debug:ipsec_tunnel_start_xmit: "
8506+ "udp/500 IKE packet, sending unprocessed, "
8507+ "calling dev_queue_xmit\n");
8508+#if 1
8509+ goto bypass;
8510+#else
8511+ DEV_QUEUE_XMIT(skb, physdev, SOPRI_NORMAL);
8512+ /* IP_SEND(skb, physdev); */
8513+ skb = NULL;
8514+ goto cleanup;
8515+#endif
8516+ }
8517+ }
8518+ }
8519+
8520+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8521+ "klips_debug:ipsec_tunnel_start_xmit: "
8522+ "Original head,tailroom: %d,%d\n",
8523+ skb_headroom(skb), skb_tailroom(skb));
8524+
8525+ innersrc = iph->saddr;
8526+ /* start encapsulation loop here XXX */
8527+ do {
8528+ newdst = orgdst = iph->daddr;
8529+ newsrc = orgsrc = iph->saddr;
8530+ orgedst = outgoing_said.dst.s_addr;
8531+ iphlen = iph->ihl << 2;
8532+ pyldsz = ntohs(iph->tot_len) - iphlen;
8533+ max_headroom = max_tailroom = 0;
8534+
8535+ if (er == NULL) {
8536+ if(sysctl_ipsec_no_eroute_pass) {
8537+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8538+ "klips_debug:ipsec_tunnel_start_xmit: "
8539+ "no eroute!: calling dev_queue_xmit\n");
8540+#if 1
8541+ goto bypass;
8542+#else
8543+ DEV_QUEUE_XMIT(skb, physdev, SOPRI_NORMAL);
8544+ /* IP_SEND(skb, physdev); */
8545+ skb = NULL;
8546+#endif
8547+ } else {
8548+ if(sysctl_ipsec_opportunistic && !er) {
8549+ struct tdb tdb;
8550+ struct sockaddr_in src, dst;
8551+#ifdef CONFIG_IPSEC_DEBUG
8552+ char buf[ADDRTOA_BUF];
8553+#endif /* CONFIG_IPSEC_DEBUG */
8554+
8555+ tdb.tdb_said.proto = iph->protocol;
8556+ src.sin_family = AF_INET;
8557+ dst.sin_family = AF_INET;
8558+ src.sin_addr.s_addr = iph->saddr;
8559+ dst.sin_addr.s_addr = iph->daddr;
8560+ src.sin_port =
8561+ (iph->protocol == IPPROTO_UDP
8562+ ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->source
8563+ : (iph->protocol == IPPROTO_TCP
8564+ ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->source
8565+ : 0));
8566+ dst.sin_port =
8567+ (iph->protocol == IPPROTO_UDP
8568+ ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->dest
8569+ : (iph->protocol == IPPROTO_TCP
8570+ ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->dest
8571+ : 0));
8572+ for(i = 0;
8573+ i < sizeof(struct sockaddr_in)
8574+ - offsetof(struct sockaddr_in, sin_zero);
8575+ i++) {
8576+ src.sin_zero[i] = 0;
8577+ dst.sin_zero[i] = 0;
8578+ }
8579+
8580+ tdb.tdb_addr_s = (struct sockaddr*)(&src);
8581+ tdb.tdb_addr_d = (struct sockaddr*)(&dst);
8582+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8583+ "klips_debug:ipsec_tunnel_start_xmit: "
8584+ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
8585+ addrtoa(((struct sockaddr_in*)(tdb.tdb_addr_s))->sin_addr, 0, buf, sizeof(buf)) <= ADDRTOA_BUF ? buf : "BAD_ADDR",
8586+ ((struct sockaddr_in*)(tdb.tdb_addr_s))->sin_port,
8587+ addrtoa(((struct sockaddr_in*)(tdb.tdb_addr_d))->sin_addr, 0, buf, sizeof(buf)) <= ADDRTOA_BUF ? buf : "BAD_ADDR",
8588+ ((struct sockaddr_in*)(tdb.tdb_addr_d))->sin_port,
8589+ tdb.tdb_said.proto);
8590+ pfkey_acquire(&tdb);
8591+ } else {
8592+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8593+ "klips_debug:ipsec_tunnel_start_xmit: "
8594+ "no eroute!: dropping.\n");
8595+ stats->tx_dropped++;
8596+ }
8597+ }
8598+ goto cleanup;
8599+ }
8600+
8601+ /*
8602+ If the packet matches an eroute with an SA.proto of IP
8603+ tunnelling and
8604+ an SA.spi of '0', then forward the packet unprotected.
8605+ XXX -- This should eventually go into an SPD.
8606+ */
8607+ if((outgoing_said.proto == IPPROTO_IPIP) && (outgoing_said.spi == 0)) {
8608+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8609+ "klips_debug:ipsec_tunnel_start_xmit: "
8610+ "passthrough eroute, packet sent.\n");
8611+#if 1
8612+ goto bypass;
8613+#else
8614+ DEV_QUEUE_XMIT(skb, physdev, SOPRI_NORMAL);
8615+ /* IP_SEND(skb, physdev); */
8616+ skb = NULL;
8617+ goto cleanup;
8618+#endif
8619+ }
8620+
8621+ /*
8622+ * The spinlock is to prevent any other process from accessing or deleting
8623+ * the tdb while we are using and updating it.
8624+ */
8625+ spin_lock(&tdb_lock);
8626+
8627+ tdbp = gettdb(&outgoing_said);
8628+ sa_len = satoa(outgoing_said, 0, sa, SATOA_BUF);
8629+
8630+ if (tdbp == NULL) {
8631+ spin_unlock(&tdb_lock);
8632+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8633+ "klips_debug:ipsec_tunnel_start_xmit: "
8634+ "no Tunnel Descriptor Block for SA%s: "
8635+ "outgoing packet with no SA, dropped.\n", sa);
8636+ stats->tx_dropped++;
8637+ goto cleanup;
8638+ }
8639+
8640+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8641+ "klips_debug:ipsec_tunnel_start_xmit: "
8642+ "found Tunnel Descriptor Block -- SA:<%s%s%s> %s\n",
8643+ TDB_XFORM_NAME(tdbp), sa);
8644+
8645+ /*
8646+ * How much headroom do we need to be able to apply
8647+ * all the grouped transforms?
8648+ */
8649+ tdbq = tdbp; /* save the head of the tdb chain */
8650+ while (tdbp) {
8651+ sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
8652+
8653+ /* If it is in larval state, drop the packet, we cannot process yet. */
8654+ if(tdbp->tdb_state == SADB_SASTATE_LARVAL) {
8655+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8656+ "klips_debug:ipsec_tunnel_start_xmit: "
8657+ "TDB in larval state for SA:<%s%s%s> %s, "
8658+ "cannot be used yet, dropping packet.\n",
8659+ TDB_XFORM_NAME(tdbp), sa);
8660+ spin_unlock(&tdb_lock);
8661+ stats->tx_errors++;
8662+ goto cleanup;
8663+ }
8664+
8665+ if(tdbp->tdb_state == SADB_SASTATE_DEAD) {
8666+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8667+ "klips_debug:ipsec_tunnel_start_xmit: "
8668+ "TDB in dead state for SA:<%s%s%s> %s, "
8669+ "can no longer be used, dropping packet.\n",
8670+ TDB_XFORM_NAME(tdbp), sa);
8671+ spin_unlock(&tdb_lock);
8672+ stats->tx_errors++;
8673+ goto cleanup;
8674+ }
8675+
8676+ /* If the replay window counter == -1, expire SA, it will roll */
8677+ if(tdbp->tdb_replaywin && tdbp->tdb_replaywin_lastseq == -1) {
8678+ pfkey_expire(tdbp, 1);
8679+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8680+ "klips_debug:ipsec_tunnel_start_xmit: "
8681+ "replay window counter rolled for SA:<%s%s%s> %s, "
8682+ "packet dropped, expiring SA.\n",
8683+ TDB_XFORM_NAME(tdbp), sa);
8684+ deltdbchain(tdbp);
8685+ spin_unlock(&tdb_lock);
8686+ stats->tx_errors++;
8687+ goto cleanup;
8688+ }
8689+
8690+ /* If any of the lifetime counters have overflowed, expire the SA(s). */
8691+ if(tdbp->tdb_lifetime_bytes_h &&
8692+ (tdbp->tdb_lifetime_bytes_c > tdbp->tdb_lifetime_bytes_h)) {
8693+ pfkey_expire(tdbp, 1);
8694+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8695+ "klips_debug:ipsec_tunnel_start_xmit: "
8696+ "hard bytes lifetime of SA:<%s%s%s> %s has been reached, "
8697+ "SA expired, outgoing packet dropped.\n",
8698+ TDB_XFORM_NAME(tdbp), sa);
8699+ deltdbchain(tdbp);
8700+ spin_unlock(&tdb_lock);
8701+ stats->tx_errors++;
8702+ goto cleanup;
8703+ }
8704+ if(tdbp->tdb_lifetime_bytes_s &&
8705+ (tdbp->tdb_lifetime_bytes_c > tdbp->tdb_lifetime_bytes_s)) {
8706+ pfkey_expire(tdbp, 0);
8707+ tdbp->tdb_state = SADB_SASTATE_DYING;
8708+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8709+ "klips_debug:ipsec_tunnel_start_xmit: "
8710+ "soft bytes lifetime of SA:<%s%s%s> %s has been reached, "
8711+ "SA expiring, soft expire message sent up, "
8712+ "outgoing packet still processed.\n",
8713+ TDB_XFORM_NAME(tdbp), sa);
8714+ }
8715+
8716+ if(tdbp->tdb_lifetime_addtime_h &&
8717+ ((jiffies / HZ) - tdbp->tdb_lifetime_addtime_c >
8718+ tdbp->tdb_lifetime_addtime_h)) {
8719+ pfkey_expire(tdbp, 1);
8720+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8721+ "klips_debug:ipsec_tunnel_start_xmit: "
8722+ "hard addtime lifetime of SA:<%s%s%s> %s has been reached, "
8723+ "SA expired, outgoing packet dropped.\n",
8724+ TDB_XFORM_NAME(tdbp), sa);
8725+ deltdbchain(tdbp);
8726+ spin_unlock(&tdb_lock);
8727+ stats->tx_errors++;
8728+ goto cleanup;
8729+ }
8730+ if(tdbp->tdb_lifetime_addtime_s &&
8731+ ((jiffies / HZ) - tdbp->tdb_lifetime_addtime_c >
8732+ tdbp->tdb_lifetime_addtime_s)) {
8733+ pfkey_expire(tdbp, 0);
8734+ tdbp->tdb_state = SADB_SASTATE_DYING;
8735+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8736+ "klips_debug:ipsec_tunnel_start_xmit: "
8737+ "soft addtime lifetime of SA:<%s%s%s> %s has been reached, "
8738+ "SA expiring, soft expire message sent up, "
8739+ "outgoing packet still processed.\n",
8740+ TDB_XFORM_NAME(tdbp), sa);
8741+ }
8742+
8743+ if(tdbp->tdb_lifetime_usetime_c) {
8744+ if(tdbp->tdb_lifetime_usetime_h &&
8745+ ((jiffies / HZ) - tdbp->tdb_lifetime_usetime_c >
8746+ tdbp->tdb_lifetime_usetime_h)) {
8747+ pfkey_expire(tdbp, 1);
8748+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8749+ "klips_debug:ipsec_tunnel_start_xmit: "
8750+ "hard usetime lifetime of SA:<%s%s%s> %s has been reached, "
8751+ "SA expired, outgoing packet dropped.\n",
8752+ TDB_XFORM_NAME(tdbp), sa);
8753+ deltdbchain(tdbp);
8754+ spin_unlock(&tdb_lock);
8755+ stats->tx_errors++;
8756+ goto cleanup;
8757+ }
8758+ if(tdbp->tdb_lifetime_usetime_s &&
8759+ ((jiffies / HZ) - tdbp->tdb_lifetime_usetime_c >
8760+ tdbp->tdb_lifetime_usetime_s)) {
8761+ pfkey_expire(tdbp, 0);
8762+ tdbp->tdb_state = SADB_SASTATE_DYING;
8763+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8764+ "klips_debug:ipsec_tunnel_start_xmit: "
8765+ "soft usetime lifetime of SA:<%s%s%s> %s has been reached, "
8766+ "SA expiring, soft expire message sent up, "
8767+ "outgoing packet still processed.\n",
8768+ TDB_XFORM_NAME(tdbp), sa);
8769+ }
8770+ }
8771+
8772+ if(tdbp->tdb_lifetime_packets_h &&
8773+ (tdbp->tdb_lifetime_packets_c > tdbp->tdb_lifetime_packets_h)) {
8774+ pfkey_expire(tdbp, 1);
8775+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8776+ "klips_debug:ipsec_tunnel_start_xmit: "
8777+ "hard packets lifetime of SA:<%s%s%s> %s has been reached, "
8778+ "SA expired, outgoing packet dropped.\n",
8779+ TDB_XFORM_NAME(tdbp), sa);
8780+ deltdbchain(tdbp);
8781+ spin_unlock(&tdb_lock);
8782+ stats->tx_errors++;
8783+ goto cleanup;
8784+ }
8785+ if(tdbp->tdb_lifetime_packets_s &&
8786+ (tdbp->tdb_lifetime_packets_c > tdbp->tdb_lifetime_packets_s)) {
8787+ pfkey_expire(tdbp, 0);
8788+ tdbp->tdb_state = SADB_SASTATE_DYING;
8789+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
8790+ "klips_debug:ipsec_tunnel_start_xmit: "
8791+ "soft packets lifetime of SA:<%s%s%s> %s has been reached, "
8792+ "SA expiring, soft expire message sent up, "
8793+ "outgoing packet still processed.\n",
8794+ TDB_XFORM_NAME(tdbp), sa);
8795+ }
8796+
8797+ headroom = tailroom = 0;
8798+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8799+ "klips_debug:ipsec_tunnel_start_xmit: "
8800+ "calling room for <%s%s%s>, SA:%s\n",
8801+ TDB_XFORM_NAME(tdbp), sa);
8802+ switch(tdbp->tdb_said.proto) {
8803+#ifdef CONFIG_IPSEC_AH
8804+ case IPPROTO_AH:
8805+ headroom += sizeof(struct ah);
8806+ break;
8807+#endif /* CONFIG_IPSEC_AH */
8808+#ifdef CONFIG_IPSEC_ESP
8809+ case IPPROTO_ESP:
8810+ switch(tdbp->tdb_encalg) {
8811+#ifdef CONFIG_IPSEC_ENC_3DES
8812+ case ESP_3DES:
8813+ headroom += sizeof(struct esp);
8814+ break;
8815+#endif /* CONFIG_IPSEC_ENC_3DES */
8816+#ifdef CONFIG_IPSEC_ENC_NULL
8817+ case ESP_NULL:
8818+ headroom += offsetof(struct esp, esp_iv);
8819+ break;
8820+#endif /* CONFIG_IPSEC_ENC_NULL */
8821+ default:
8822+ spin_unlock(&tdb_lock);
8823+ stats->tx_errors++;
8824+ goto cleanup;
8825+ }
8826+ switch(tdbp->tdb_authalg) {
8827+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
8828+ case AH_MD5:
8829+ tailroom += AHHMAC_HASHLEN;
8830+ break;
8831+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
8832+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
8833+ case AH_SHA:
8834+ tailroom += AHHMAC_HASHLEN;
8835+ break;
8836+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
8837+ case AH_NONE:
8838+ break;
8839+ default:
8840+ spin_unlock(&tdb_lock);
8841+ stats->tx_errors++;
8842+ goto cleanup;
8843+ }
8844+ tailroom += ((8 - ((pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2;
8845+ break;
8846+#endif /* !CONFIG_IPSEC_ESP */
8847+#ifdef CONFIG_IPSEC_IPIP
8848+ case IPPROTO_IPIP:
8849+ headroom += sizeof(struct iphdr);
8850+ break;
8851+#endif /* !CONFIG_IPSEC_IPIP */
8852+ case IPPROTO_COMP:
8853+#ifdef CONFIG_IPSEC_IPCOMP
8854+ /*
8855+ We can't predict how much the packet will
8856+ shrink without doing the actual compression.
8857+ We could do it here, if we were the first
8858+ encapsulation in the chain. That might save
8859+ us a skb_copy_expand, since we might fit
8860+ into the existing skb then. However, this
8861+ would be a bit unclean (and this hack has
8862+ bit us once), so we better not do it. After
8863+ all, the skb_copy_expand is cheap in
8864+ comparison to the actual compression.
8865+ At least we know the packet will not grow.
8866+ */
8867+ break;
8868+#endif /* CONFIG_IPSEC_IPCOMP */
8869+ default:
8870+ spin_unlock(&tdb_lock);
8871+ stats->tx_errors++;
8872+ goto cleanup;
8873+ }
8874+ tdbp = tdbp->tdb_onext;
8875+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8876+ "klips_debug:ipsec_tunnel_start_xmit: "
8877+ "Required head,tailroom: %d,%d\n",
8878+ headroom, tailroom);
8879+ max_headroom += headroom;
8880+ max_tailroom += tailroom;
8881+ pyldsz += (headroom + tailroom);
8882+ }
8883+ tdbp = tdbq; /* restore the head of the tdb chain */
8884+
8885+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8886+ "klips_debug:ipsec_tunnel_start_xmit: "
8887+ "existing head,tailroom: %d,%d "
8888+ "before applying xforms with head,tailroom: %d,%d .\n",
8889+ skb_headroom(skb), skb_tailroom(skb),
8890+ max_headroom, max_tailroom);
8891+
8892+ tot_headroom += max_headroom;
8893+ tot_tailroom += max_tailroom;
8894+
8895+ mtudiff = prv->mtu + tot_headroom + tot_tailroom - physmtu;
8896+
8897+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8898+ "klips_debug:ipsec_tunnel_start_xmit: mtu:%d physmtu:%d "
8899+ "tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
8900+ prv->mtu, physmtu,
8901+ tot_headroom, tot_tailroom, mtudiff, ntohs(iph->tot_len));
8902+ if(mtudiff > 0) {
8903+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8904+ "klips_info:ipsec_tunnel_start_xmit: "
8905+ "dev %s mtu of %d decreased by %d\n",
8906+ dev->name,
8907+ prv->mtu,
8908+ prv->mtu - (physmtu - tot_headroom - tot_tailroom));
8909+ prv->mtu = physmtu - (tot_headroom + tot_tailroom + 7); /* add some slop? */
8910+#ifdef NET_21
8911+#if 0
8912+ skb->dst->pmtu = prv->mtu; /* RGB */
8913+#endif /* 0 */
8914+#else /* NET_21 */
8915+#if 0
8916+ dev->mtu = prv->mtu; /* RGB */
8917+#endif /* 0 */
8918+#endif /* NET_21 */
8919+ }
8920+
8921+#ifdef MSS_HACK
8922+ /*
8923+ * If this is a transport mode TCP packet with
8924+ * SYN set, determine an effective MSS based on
8925+ * AH/ESP overheads determined above.
8926+ */
8927+ if (iph->protocol == IPPROTO_TCP
8928+ && outgoing_said.proto != IPPROTO_IPIP) {
8929+ struct tcphdr *tcph = skb->h.th;
8930+ if (tcph->syn && !tcph->ack) {
8931+ if(!ipsec_adjust_mss(skb, tcph, prv->mtu)) {
8932+ spin_unlock(&tdb_lock);
8933+ printk(KERN_WARNING "klips: "
8934+ "ipsec_adjust_mss() failed\n");
8935+ stats->tx_errors++;
8936+ goto cleanup;
8937+ }
8938+ }
8939+ }
8940+#endif /* MSS_HACK */
8941+
8942+ if(!hard_header_stripped) {
8943+ if((saved_header = kmalloc(hard_header_len, GFP_ATOMIC)) == NULL) {
8944+ spin_unlock(&tdb_lock);
8945+ printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: Failed, "
8946+ "tried to allocate %d bytes for temp hard_header.\n",
8947+ hard_header_len);
8948+ stats->tx_errors++;
8949+ goto cleanup;
8950+ }
8951+ for (i = 0; i < hard_header_len; i++) {
8952+ saved_header[i] = skb->data[i];
8953+ }
8954+ if(skb->len < hard_header_len) {
8955+ spin_unlock(&tdb_lock);
8956+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
8957+ "tried to skb_pull hhlen=%d, %d available. "
8958+ "This should never happen, please report.\n",
8959+ hard_header_len, (int)(skb->len));
8960+ stats->tx_errors++;
8961+ goto cleanup;
8962+ }
8963+ skb_pull(skb, hard_header_len);
8964+ hard_header_stripped = 1;
8965+
8966+/* iph = (struct iphdr *) (skb->data); */
8967+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8968+ "klips_debug:ipsec_tunnel_start_xmit: "
8969+ "head,tailroom: %d,%d after hard_header stripped.\n",
8970+ skb_headroom(skb), skb_tailroom(skb));
8971+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, iph);
8972+ } else {
8973+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8974+ "klips_debug:ipsec_tunnel_start_xmit: "
8975+ "hard header already stripped.\n");
8976+ }
8977+
8978+ ll_headroom = (hard_header_len + 15) & ~15;
8979+
8980+ if ((skb_headroom(skb) >= max_headroom + 2 * ll_headroom) &&
8981+ (skb_tailroom(skb) >= max_tailroom)
8982+#ifndef NET_21
8983+ && skb->free
8984+#endif /* !NET_21 */
8985+ ) {
8986+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
8987+ "klips_debug:ipsec_tunnel_start_xmit: "
8988+ "data fits in existing skb\n");
8989+ } else {
8990+ struct sk_buff* tskb = skb;
8991+
8992+ if(!oskb) {
8993+ oskb = skb;
8994+ }
8995+
8996+ tskb = skb_copy_expand(skb,
8997+ /* The reason for 2 * link layer length here still baffles me...RGB */
8998+ max_headroom + 2 * ll_headroom,
8999+ max_tailroom,
9000+ GFP_ATOMIC);
9001+#ifdef NET_21
9002+ if(tskb && skb->sk) {
9003+ skb_set_owner_w(tskb, skb->sk);
9004+ }
9005+#endif /* NET_21 */
9006+ if(!(skb == oskb) ) {
9007+ dev_kfree_skb(skb, FREE_WRITE);
9008+ }
9009+ skb = tskb;
9010+ if (!skb) {
9011+ spin_unlock(&tdb_lock);
9012+ printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: Failed, "
9013+ "tried to allocate %d head and %d tailroom\n",
9014+ max_headroom, max_tailroom);
9015+ stats->tx_errors++;
9016+ goto cleanup;
9017+ }
9018+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
9019+ "klips_debug:ipsec_tunnel_start_xmit: "
9020+ "head,tailroom: %d,%d after allocation\n",
9021+ skb_headroom(skb), skb_tailroom(skb));
9022+ }
9023+
9024+ /*
9025+ * Apply grouped transforms to packet
9026+ */
9027+ while (tdbp) {
9028+#ifdef CONFIG_IPSEC_ESP
9029+ struct esp *espp;
9030+ __u32 iv[2];
9031+ unsigned char *idat, *pad;
9032+ int authlen = 0, padlen = 0, i;
9033+#endif /* !CONFIG_IPSEC_ESP */
9034+#ifdef CONFIG_IPSEC_AH
9035+ struct iphdr ipo;
9036+ struct ah *ahp;
9037+#endif /* CONFIG_IPSEC_AH */
9038+#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1)
9039+ union {
9040+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
9041+ MD5_CTX md5;
9042+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
9043+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
9044+ SHA1_CTX sha1;
9045+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
9046+ } tctx;
9047+ __u8 hash[AH_AMAX];
9048+#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */
9049+ int headroom = 0, tailroom = 0, ilen = 0, len = 0;
9050+ unsigned char *dat;
9051+
9052+ iphlen = iph->ihl << 2;
9053+ pyldsz = ntohs(iph->tot_len) - iphlen;
9054+ sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
9055+ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
9056+ "klips_debug:ipsec_tunnel_start_xmit: "
9057+ "calling output for <%s%s%s>, SA:%s\n",
9058+ TDB_XFORM_NAME(tdbp), sa);
9059+
9060+ switch(tdbp->tdb_said.proto) {
9061+#ifdef CONFIG_IPSEC_AH
9062+ case IPPROTO_AH:
9063+ headroom += sizeof(struct ah);
9064+ break;
9065+#endif /* CONFIG_IPSEC_AH */
9066+#ifdef CONFIG_IPSEC_ESP
9067+ case IPPROTO_ESP:
9068+ switch(tdbp->tdb_encalg) {
9069+#ifdef CONFIG_IPSEC_ENC_3DES
9070+ case ESP_3DES:
9071+ headroom += sizeof(struct esp);
9072+ break;
9073+#endif /* CONFIG_IPSEC_ENC_3DES */
9074+#ifdef CONFIG_IPSEC_ENC_NULL
9075+ case ESP_NULL:
9076+ headroom += offsetof(struct esp, esp_iv);
9077+ break;
9078+#endif /* CONFIG_IPSEC_ENC_NULL */
9079+ default:
9080+ spin_unlock(&tdb_lock);
9081+ stats->tx_errors++;
9082+ goto cleanup;
9083+ }
9084+ switch(tdbp->tdb_authalg) {
9085+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
9086+ case AH_MD5:
9087+ authlen = AHHMAC_HASHLEN;
9088+ break;
9089+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
9090+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
9091+ case AH_SHA:
9092+ authlen = AHHMAC_HASHLEN;
9093+ break;
9094+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
9095+ case AH_NONE:
9096+ break;
9097+ default:
9098+ spin_unlock(&tdb_lock);
9099+ stats->tx_errors++;
9100+ goto cleanup;
9101+ }
9102+ tailroom += ((8 - ((pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2;
9103+ tailroom += authlen;
9104+ break;
9105+#endif /* !CONFIG_IPSEC_ESP */
9106+#ifdef CONFIG_IPSEC_IPIP
9107+ case IPPROTO_IPIP:
9108+ headroom += sizeof(struct iphdr);
9109+ break;
9110+#endif /* !CONFIG_IPSEC_IPIP */
9111+#ifdef CONFIG_IPSEC_IPCOMP
9112+ case IPPROTO_COMP:
9113+ break;
9114+#endif /* CONFIG_IPSEC_IPCOMP */
9115+ default:
9116+ spin_unlock(&tdb_lock);
9117+ stats->tx_errors++;
9118+ goto cleanup;
9119+ }
9120+
9121+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
9122+ "klips_debug:ipsec_tunnel_start_xmit: "
9123+ "pushing %d bytes, putting %d, proto %d.\n",
9124+ headroom, tailroom, tdbp->tdb_said.proto);
9125+ if(skb_headroom(skb) < headroom) {
9126+ spin_unlock(&tdb_lock);
9127+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
9128+ "tried to skb_push headroom=%d, %d available. "
9129+ "This should never happen, please report.\n",
9130+ headroom, skb_headroom(skb));
9131+ stats->tx_errors++;
9132+ goto cleanup;
9133+ }
9134+ dat = skb_push(skb, headroom);
9135+ ilen = skb->len - tailroom;
9136+ if(skb_tailroom(skb) < tailroom) {
9137+ spin_unlock(&tdb_lock);
9138+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
9139+ "tried to skb_put %d, %d available. "
9140+ "This should never happen, please report.\n",
9141+ tailroom, skb_tailroom(skb));
9142+ stats->tx_errors++;
9143+ goto cleanup;
9144+ }
9145+ skb_put(skb, tailroom);
9146+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
9147+ "klips_debug:ipsec_tunnel_start_xmit: "
9148+ "head,tailroom: %d,%d before xform.\n",
9149+ skb_headroom(skb), skb_tailroom(skb));
9150+ len = skb->len;
9151+ if(len > 0xfff0) {
9152+ spin_unlock(&tdb_lock);
9153+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
9154+ "tot_len (%d) > 65520. "
9155+ "This should never happen, please report.\n",
9156+ len);
9157+ stats->tx_errors++;
9158+ goto cleanup;
9159+ }
9160+ memmove((void *)dat, (void *)(dat + headroom), iphlen);
9161+ iph = (struct iphdr *)dat;
9162+ iph->tot_len = htons(skb->len);
9163+
9164+ switch(tdbp->tdb_said.proto) {
9165+#ifdef CONFIG_IPSEC_ESP
9166+ case IPPROTO_ESP:
9167+ espp = (struct esp *)(dat + iphlen);
9168+ espp->esp_spi = tdbp->tdb_said.spi;
9169+ espp->esp_rpl = htonl(++(tdbp->tdb_replaywin_lastseq));
9170+
9171+ switch(tdbp->tdb_encalg) {
9172+#if defined(CONFIG_IPSEC_ENC_3DES)
9173+#ifdef CONFIG_IPSEC_ENC_3DES
9174+ case ESP_3DES:
9175+#endif /* CONFIG_IPSEC_ENC_3DES */
9176+ iv[0] = *((__u32*)&(espp->esp_iv) ) =
9177+ ((__u32*)(tdbp->tdb_iv))[0];
9178+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
9179+ ((__u32*)(tdbp->tdb_iv))[1];
9180+ break;
9181+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
9182+#ifdef CONFIG_IPSEC_ENC_NULL
9183+ case ESP_NULL:
9184+ break;
9185+#endif /* CONFIG_IPSEC_ENC_NULL */
9186+ default:
9187+ spin_unlock(&tdb_lock);
9188+ stats->tx_errors++;
9189+ goto cleanup;
9190+ }
9191+
9192+ idat = dat + iphlen + headroom;
9193+ ilen = len - (iphlen + headroom + authlen);
9194+
9195+ /* Self-describing padding */
9196+ pad = &dat[len - tailroom];
9197+ padlen = tailroom - 2 - authlen;
9198+ for (i = 0; i < padlen; i++) {
9199+ pad[i] = i + 1;
9200+ }
9201+ dat[len - authlen - 2] = padlen;
9202+
9203+ dat[len - authlen - 1] = iph->protocol;
9204+ iph->protocol = IPPROTO_ESP;
9205+
9206+ switch(tdbp->tdb_encalg) {
9207+#ifdef CONFIG_IPSEC_ENC_3DES
9208+ case ESP_3DES:
9209+ des_ede3_cbc_encrypt(idat, idat, ilen,
9210+ (caddr_t)(&((struct des_eks*)(tdbp->tdb_key_e))[0]),
9211+ (caddr_t)(&((struct des_eks*)(tdbp->tdb_key_e))[1]),
9212+ (caddr_t)(&((struct des_eks*)(tdbp->tdb_key_e))[2]),
9213+ (caddr_t)iv, 1);
9214+ break;
9215+#endif /* CONFIG_IPSEC_ENC_3DES */
9216+#ifdef CONFIG_IPSEC_ENC_NULL
9217+ case ESP_NULL:
9218+ break;
9219+#endif /* CONFIG_IPSEC_ENC_NULL */
9220+ default:
9221+ spin_unlock(&tdb_lock);
9222+ stats->tx_errors++;
9223+ goto cleanup;
9224+ }
9225+
9226+ switch(tdbp->tdb_encalg) {
9227+#if defined(CONFIG_IPSEC_ENC_3DES)
9228+#ifdef CONFIG_IPSEC_ENC_3DES
9229+ case ESP_3DES:
9230+#endif /* CONFIG_IPSEC_ENC_3DES */
9231+ /* XXX update IV with the last 8 octets of the encryption */
9232+ ((__u32*)(tdbp->tdb_iv))[0] =
9233+ ((__u32 *)(idat))[(ilen >> 2) - 2];
9234+ ((__u32*)(tdbp->tdb_iv))[1] =
9235+ ((__u32 *)(idat))[(ilen >> 2) - 1];
9236+ break;
9237+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
9238+#ifdef CONFIG_IPSEC_ENC_NULL
9239+ case ESP_NULL:
9240+ break;
9241+#endif /* CONFIG_IPSEC_ENC_NULL */
9242+ default:
9243+ spin_unlock(&tdb_lock);
9244+ stats->tx_errors++;
9245+ goto cleanup;
9246+ }
9247+
9248+ switch(tdbp->tdb_authalg) {
9249+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
9250+ case AH_MD5:
9251+ dmp("espp", (char*)espp, len - iphlen - authlen);
9252+ tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;
9253+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
9254+ MD5Update(&tctx.md5, (caddr_t)espp, len - iphlen - authlen);
9255+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
9256+ MD5Final(hash, &tctx.md5);
9257+ dmp("ictx hash", (char*)&hash, sizeof(hash));
9258+ tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;
9259+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
9260+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
9261+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
9262+ MD5Final(hash, &tctx.md5);
9263+ dmp("octx hash", (char*)&hash, sizeof(hash));
9264+ memcpy(&(dat[len - authlen]), hash, authlen);
9265+
9266+ /* paranoid */
9267+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
9268+ memset((caddr_t)hash, 0, sizeof(*hash));
9269+ break;
9270+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
9271+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
9272+ case AH_SHA:
9273+ tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx;
9274+ SHA1Update(&tctx.sha1, (caddr_t)espp, len - iphlen - authlen);
9275+ SHA1Final(hash, &tctx.sha1);
9276+ tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
9277+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
9278+ SHA1Final(hash, &tctx.sha1);
9279+ memcpy(&(dat[len - authlen]), hash, authlen);
9280+
9281+ /* paranoid */
9282+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
9283+ memset((caddr_t)hash, 0, sizeof(*hash));
9284+ break;
9285+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
9286+ case AH_NONE:
9287+ break;
9288+ default:
9289+ spin_unlock(&tdb_lock);
9290+ stats->tx_errors++;
9291+ goto cleanup;
9292+ }
9293+#ifdef NET_21
9294+ skb->h.raw = (unsigned char*)espp;
9295+#endif /* NET_21 */
9296+ break;
9297+#endif /* !CONFIG_IPSEC_ESP */
9298+#ifdef CONFIG_IPSEC_AH
9299+ case IPPROTO_AH:
9300+ ahp = (struct ah *)(dat + iphlen);
9301+ ahp->ah_spi = tdbp->tdb_said.spi;
9302+ ahp->ah_rpl = htonl(++(tdbp->tdb_replaywin_lastseq));
9303+ ahp->ah_rv = 0;
9304+ ahp->ah_nh = iph->protocol;
9305+ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
9306+ iph->protocol = IPPROTO_AH;
9307+ dmp("ahp", (char*)ahp, sizeof(*ahp));
9308+
9309+ ipo = *iph;
9310+ ipo.tos = 0;
9311+ ipo.frag_off = 0;
9312+ ipo.ttl = 0;
9313+ ipo.check = 0;
9314+ dmp("ipo", (char*)&ipo, sizeof(ipo));
9315+
9316+ switch(tdbp->tdb_authalg) {
9317+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
9318+ case AH_MD5:
9319+ tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx;
9320+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
9321+ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
9322+ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
9323+ MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
9324+ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
9325+ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
9326+ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
9327+ MD5Update(&tctx.md5, dat + iphlen + headroom, len - iphlen - headroom);
9328+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
9329+ MD5Final(hash, &tctx.md5);
9330+ dmp("ictx hash", (char*)&hash, sizeof(hash));
9331+ tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx;
9332+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
9333+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
9334+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
9335+ MD5Final(hash, &tctx.md5);
9336+ dmp("octx hash", (char*)&hash, sizeof(hash));
9337+
9338+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
9339+
9340+ /* paranoid */
9341+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
9342+ memset((caddr_t)hash, 0, sizeof(hash));
9343+ break;
9344+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
9345+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
9346+ case AH_SHA:
9347+ tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx;
9348+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
9349+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
9350+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
9351+ SHA1Update(&tctx.sha1, dat + iphlen + headroom, len - iphlen - headroom);
9352+ SHA1Final(hash, &tctx.sha1);
9353+ tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
9354+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
9355+ SHA1Final(hash, &tctx.sha1);
9356+
9357+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
9358+
9359+ /* paranoid */
9360+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
9361+ memset((caddr_t)hash, 0, sizeof(hash));
9362+ break;
9363+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
9364+ default:
9365+ spin_unlock(&tdb_lock);
9366+ stats->tx_errors++;
9367+ goto cleanup;
9368+ }
9369+#ifdef NET_21
9370+ skb->h.raw = (unsigned char*)ahp;
9371+#endif /* NET_21 */
9372+ break;
9373+#endif /* CONFIG_IPSEC_AH */
9374+#ifdef CONFIG_IPSEC_IPIP
9375+ case IPPROTO_IPIP:
9376+ iph->version = 4;
9377+ switch(sysctl_ipsec_tos) {
9378+ case 0:
9379+#ifdef NET_21
9380+ iph->tos = skb->nh.iph->tos;
9381+#else /* NET_21 */
9382+ iph->tos = skb->ip_hdr->tos;
9383+#endif /* NET_21 */
9384+ break;
9385+ case 1:
9386+ iph->tos = 0;
9387+ break;
9388+ default:
9389+ }
9390+#ifdef NET_21
9391+ iph->ttl = ip_statistics.IpDefaultTTL;
9392+#else /* NET_21 */
9393+ iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */
9394+#endif /* NET_21 */
9395+ iph->frag_off = 0;
9396+ iph->saddr = ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr;
9397+ iph->daddr = ((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr.s_addr;
9398+ iph->protocol = IPPROTO_IPIP;
9399+ iph->ihl = sizeof(struct iphdr) >> 2 /* 5 */;
9400+#ifdef IP_SELECT_IDENT
9401+ /* XXX use of skb->dst below is a questionable
9402+ substitute for &rt->u.dst which is only
9403+ available later-on */
9404+ ip_select_ident(iph, skb->dst);
9405+#else
9406+ iph->id = htons(ip_id_count++); /* Race condition here? */
9407+#endif
9408+
9409+ newdst = (__u32)iph->daddr;
9410+ newsrc = (__u32)iph->saddr;
9411+
9412+#ifdef NET_21
9413+ skb->h.ipiph = skb->nh.iph;
9414+#endif /* NET_21 */
9415+ break;
9416+#endif /* !CONFIG_IPSEC_IPIP */
9417+#ifdef CONFIG_IPSEC_IPCOMP
9418+ case IPPROTO_COMP:
9419+ {
9420+ unsigned int flags = 0;
9421+#ifdef CONFIG_IPSEC_DEBUG
9422+ unsigned int old_tot_len = ntohs(iph->tot_len);
9423+#endif
9424+ tdbp->tdb_comp_ratio_dbytes += ntohs(iph->tot_len);
9425+
9426+ skb = skb_compress(skb, tdbp, &flags);
9427+
9428+#ifdef NET_21
9429+ iph = skb->nh.iph;
9430+#else /* NET_21 */
9431+ iph = skb->ip_hdr;
9432+#endif /* NET_21 */
9433+
9434+ tdbp->tdb_comp_ratio_cbytes += ntohs(iph->tot_len);
9435+
9436+#ifdef CONFIG_IPSEC_DEBUG
9437+ if (debug_tunnel & DB_TN_CROUT)
9438+ {
9439+ if (old_tot_len > ntohs(iph->tot_len))
9440+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
9441+ "klips_debug:ipsec_tunnel_start_xmit: "
9442+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
9443+ old_tot_len, ntohs(iph->tot_len),
9444+ ntohs(((struct ipcomphdr*)(((char*)iph) + ((iph->ihl) << 2)))->ipcomp_cpi),
9445+ ntohl(tdbp->tdb_said.spi),
9446+ (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff));
9447+ else
9448+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
9449+ "klips_debug:ipsec_tunnel_start_xmit: "
9450+ "packet did not compress (flags = %d).\n",
9451+ flags);
9452+ }
9453+#endif /* CONFIG_IPSEC_DEBUG */
9454+ }
9455+ break;
9456+#endif /* CONFIG_IPSEC_IPCOMP */
9457+ default:
9458+ spin_unlock(&tdb_lock);
9459+ stats->tx_errors++;
9460+ goto cleanup;
9461+ }
9462+
9463+#ifdef NET_21
9464+ skb->nh.raw = skb->data;
9465+#else /* NET_21 */
9466+ skb->ip_hdr = skb->h.iph = (struct iphdr *) skb->data;
9467+#endif /* NET_21 */
9468+ iph->check = 0;
9469+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
9470+
9471+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
9472+ "klips_debug:ipsec_tunnel_start_xmit: "
9473+ "after <%s%s%s>, SA:%s:\n",
9474+ TDB_XFORM_NAME(tdbp), sa);
9475+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph);
9476+
9477+ tdbp->tdb_lifetime_bytes_c += len;
9478+ if(!tdbp->tdb_lifetime_usetime_c) {
9479+ tdbp->tdb_lifetime_usetime_c = jiffies / HZ;
9480+ }
9481+ tdbp->tdb_lifetime_usetime_l = jiffies / HZ;
9482+ tdbp->tdb_lifetime_packets_c += 1;
9483+
9484+ tdbp = tdbp->tdb_onext;
9485+
9486+ }
9487+ /* end encapsulation loop here XXX */
9488+
9489+ spin_unlock(&tdb_lock);
9490+
9491+ matcher.sen_ip_src.s_addr = iph->saddr;
9492+ matcher.sen_ip_dst.s_addr = iph->daddr;
9493+ spin_lock(&eroute_lock);
9494+ er = ipsec_findroute(&matcher);
9495+ if(er) {
9496+ outgoing_said = er->er_said;
9497+ }
9498+ spin_unlock(&eroute_lock);
9499+ KLIPS_PRINT(/* ((orgdst != newdst) || (orgsrc != newsrc)) */
9500+ (orgedst != outgoing_said.dst.s_addr) &&
9501+ outgoing_said.dst.s_addr &&
9502+ er &&
9503+ (debug_tunnel & DB_TN_XMIT),
9504+ "klips_debug:ipsec_tunnel_start_xmit: We are recursing here.\n");
9505+ } while(/*((orgdst != newdst) || (orgsrc != newsrc))*/
9506+ (orgedst != outgoing_said.dst.s_addr) &&
9507+ outgoing_said.dst.s_addr &&
9508+ er);
9509+
9510+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
9511+ "klips_debug:ipsec_tunnel_start_xmit: "
9512+ "After recursive xforms -- head,tailroom: %d,%d\n",
9513+ skb_headroom(skb), skb_tailroom(skb));
9514+
9515+ if(sysctl_ipsec_icmp && (innersrc != newsrc) && (ntohs(iph->tot_len) > physmtu)) {
9516+ ICMP_SEND(oskb ? oskb : skb,
9517+ ICMP_DEST_UNREACH,
9518+ ICMP_FRAG_NEEDED,
9519+ prv->mtu,
9520+ physdev);
9521+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
9522+ "klips_debug:ipsec_tunnel_start_xmit: "
9523+ "IPSEC tunnel mode packet is larger than MTU, ICMP sent.\n");
9524+ }
9525+
9526+ if(saved_header) {
9527+ if(skb_headroom(skb) < hard_header_len) {
9528+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
9529+ "tried to skb_push hhlen=%d, %d available. "
9530+ "This should never happen, please report.\n",
9531+ hard_header_len, skb_headroom(skb));
9532+ stats->tx_errors++;
9533+ goto cleanup;
9534+ }
9535+ skb_push(skb, hard_header_len);
9536+ for (i = 0; i < hard_header_len; i++) {
9537+ skb->data[i] = saved_header[i];
9538+ }
9539+ }
9540+ bypass:
9541+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
9542+ "klips_debug:ipsec_tunnel_start_xmit: "
9543+ "With hard_header, final head,tailroom: %d,%d\n",
9544+ skb_headroom(skb), skb_tailroom(skb));
9545+
9546+#ifdef NET_21
9547+ /* new route/dst cache code from James Morris */
9548+ skb->dev = physdev;
9549+ /*skb_orphan(skb);*/
9550+ if(ip_route_output(&rt,
9551+ skb->nh.iph->daddr,
9552+ skb->nh.iph->saddr,
9553+ RT_TOS(skb->nh.iph->tos),
9554+ physdev->iflink)) {
9555+ stats->tx_errors++;
9556+ goto cleanup;
9557+ }
9558+ if(dev == rt->u.dst.dev) {
9559+ ip_rt_put(rt);
9560+ /* This is recursion, drop it. */
9561+ stats->tx_errors++;
9562+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
9563+ "klips_debug:ipsec_tunnel_start_xmit: "
9564+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", dev->name);
9565+ goto cleanup;
9566+ }
9567+ dst_release(skb->dst);
9568+ skb->dst = &rt->u.dst;
9569+ stats->tx_bytes += skb->len;
9570+ if(skb->len < skb->nh.raw - skb->data) {
9571+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
9572+ "tried to __skb_pull nh-data=%d, %d available. "
9573+ "This should never happen, please report.\n",
9574+ skb->nh.raw - skb->data, skb->len);
9575+ stats->tx_errors++;
9576+ goto cleanup;
9577+ }
9578+ __skb_pull(skb, skb->nh.raw - skb->data);
9579+#ifdef SKB_RESET_NFCT
9580+ nf_conntrack_put(skb->nfct);
9581+ skb->nfct = NULL;
9582+#ifdef CONFIG_NETFILTER_DEBUG
9583+ skb->nf_debug = 0;
9584+#endif /* CONFIG_NETFILTER_DEBUG */
9585+#endif /* SKB_RESET_NFCT */
9586+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
9587+ "klips_debug:ipsec_tunnel_start_xmit: "
9588+ "...done, calling ip_send()\n");
9589+#ifdef NETDEV_23
9590+ {
9591+ int err;
9592+
9593+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
9594+ ipsec_tunnel_xmit2);
9595+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
9596+ if(net_ratelimit())
9597+ printk(KERN_ERR
9598+ "ipsec_tunnel_start_xmit: ip_send() failed, err=%d\n",
9599+ -err);
9600+ stats->tx_errors++;
9601+ stats->tx_aborted_errors++;
9602+ skb = NULL;
9603+ goto cleanup;
9604+ }
9605+ }
9606+#else
9607+ ip_send(skb);
9608+#endif
9609+#else /* NET_21 */
9610+ skb->arp = 1;
9611+ /* ISDN/ASYNC PPP from Matjaz Godec. */
9612+ /* skb->protocol = htons(ETH_P_IP); */
9613+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
9614+ "klips_debug:ipsec_tunnel_start_xmit: "
9615+ "...done, calling dev_queue_xmit() or ip_fragment().\n");
9616+ IP_SEND(skb, physdev);
9617+#endif /* NET_21 */
9618+ stats->tx_packets++;
9619+
9620+ skb = NULL;
9621+ cleanup:
9622+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
9623+ netif_wake_queue(dev);
9624+#else
9625+ dev->tbusy = 0;
9626+#endif
9627+ if(saved_header)
9628+ kfree(saved_header);
9629+ if(skb) {
9630+ dev_kfree_skb(skb, FREE_WRITE);
9631+ }
9632+ if(oskb)
9633+ dev_kfree_skb(oskb, FREE_WRITE);
9634+ return 0;
9635+}
9636+
9637+DEBUG_NO_STATIC struct net_device_stats *
9638+ipsec_tunnel_get_stats(struct device *dev)
9639+{
9640+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
9641+}
9642+
9643+/*
9644+ * Revectored calls.
9645+ * For each of these calls, a field exists in our private structure.
9646+ */
9647+
9648+DEBUG_NO_STATIC int
9649+ipsec_tunnel_hard_header(struct sk_buff *skb, struct device *dev,
9650+ unsigned short type, void *daddr, void *saddr, unsigned len)
9651+{
9652+ struct ipsecpriv *prv = dev->priv;
9653+ struct device *tmp;
9654+ int ret;
9655+
9656+ if(!prv->hard_header) {
9657+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9658+ "klips_debug:ipsec_tunnel_hard_header: "
9659+ "physical device has been detached, packet dropped "
9660+ "0x%p->0x%p len=%d type=%d dev=%s->NULL ",
9661+ saddr, daddr, len, type, dev->name);
9662+#ifdef NET_21
9663+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
9664+ "ip=%08x->%08x\n",
9665+ (__u32)ntohl(skb->nh.iph->saddr),
9666+ (__u32)ntohl(skb->nh.iph->daddr) );
9667+#else /* NET_21 */
9668+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
9669+ "ip=%08x->%08x\n",
9670+ (__u32)ntohl(skb->ip_hdr->saddr),
9671+ (__u32)ntohl(skb->ip_hdr->daddr) );
9672+#endif /* NET_21 */
9673+ return -ENODEV;
9674+ }
9675+
9676+#define da ((struct device *)(prv->dev))->dev_addr
9677+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9678+ "klips_debug:ipsec_tunnel_hard_header: "
9679+ "Revectored 0x%p->0x%p len=%d type=%d dev=%s->%s "
9680+ "dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
9681+ saddr, daddr, len, type, dev->name, prv->dev->name,
9682+ da[0], da[1], da[2], da[3], da[4], da[5]);
9683+#ifdef NET_21
9684+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9685+ "ip=%08x->%08x\n",
9686+ (__u32)ntohl(skb->nh.iph->saddr),
9687+ (__u32)ntohl(skb->nh.iph->daddr) );
9688+#else /* NET_21 */
9689+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9690+ "ip=%08x->%08x\n",
9691+ (__u32)ntohl(skb->ip_hdr->saddr),
9692+ (__u32)ntohl(skb->ip_hdr->daddr) );
9693+#endif /* NET_21 */
9694+ tmp = skb->dev;
9695+ skb->dev = prv->dev;
9696+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
9697+ skb->dev = tmp;
9698+ return ret;
9699+}
9700+
9701+DEBUG_NO_STATIC int
9702+#ifdef NET_21
9703+ipsec_tunnel_rebuild_header(struct sk_buff *skb)
9704+#else /* NET_21 */
9705+ipsec_tunnel_rebuild_header(void *buff, struct device *dev,
9706+ unsigned long raddr, struct sk_buff *skb)
9707+#endif /* NET_21 */
9708+{
9709+ struct ipsecpriv *prv = skb->dev->priv;
9710+ struct device *tmp;
9711+ int ret;
9712+
9713+ if(!prv->rebuild_header) {
9714+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9715+ "klips_debug:ipsec_tunnel_rebuild_header: "
9716+ "physical device has been detached, packet dropped "
9717+ "skb->dev=%s->NULL ",
9718+ skb->dev->name);
9719+#ifdef NET_21
9720+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9721+ "ip=%08x->%08x\n",
9722+ (__u32)ntohl(skb->nh.iph->saddr),
9723+ (__u32)ntohl(skb->nh.iph->daddr) );
9724+#else /* NET_21 */
9725+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9726+ "ip=%08x->%08x\n",
9727+ (__u32)ntohl(skb->ip_hdr->saddr),
9728+ (__u32)ntohl(skb->ip_hdr->daddr) );
9729+#endif /* NET_21 */
9730+ return -ENODEV;
9731+ }
9732+
9733+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9734+ "klips_debug:ipsec_tunnel: "
9735+ "Revectored rebuild_header dev=%s->%s ",
9736+ skb->dev->name, prv->dev->name);
9737+#ifdef NET_21
9738+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9739+ "ip=%08x->%08x\n",
9740+ (__u32)ntohl(skb->nh.iph->saddr),
9741+ (__u32)ntohl(skb->nh.iph->daddr) );
9742+#else /* NET_21 */
9743+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9744+ "ip=%08x->%08x\n",
9745+ (__u32)ntohl(skb->ip_hdr->saddr),
9746+ (__u32)ntohl(skb->ip_hdr->daddr) );
9747+#endif /* NET_21 */
9748+ tmp = skb->dev;
9749+ skb->dev = prv->dev;
9750+
9751+#ifdef NET_21
9752+ ret = prv->rebuild_header(skb);
9753+#else /* NET_21 */
9754+ ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
9755+#endif /* NET_21 */
9756+ skb->dev = tmp;
9757+ return ret;
9758+}
9759+
9760+DEBUG_NO_STATIC int
9761+ipsec_tunnel_set_mac_address(struct device *dev, void *addr)
9762+{
9763+ struct ipsecpriv *prv = dev->priv;
9764+
9765+ if(!prv->set_mac_address) {
9766+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9767+ "klips_debug:ipsec_tunnel_set_mac_address: "
9768+ "physical device has been detached, cannot set - "
9769+ "skb->dev=%s->NULL\n",
9770+ dev->name);
9771+ return -ENODEV;
9772+ }
9773+
9774+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9775+ "klips_debug:ipsec_tunnel_set_mac_address: "
9776+ "Revectored dev=%s->%s addr=%p\n",
9777+ dev->name, prv->dev->name, addr);
9778+ return prv->set_mac_address(prv->dev, addr);
9779+
9780+}
9781+
9782+#ifndef NET_21
9783+DEBUG_NO_STATIC void
9784+ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct device *dev,
9785+ unsigned short htype, __u32 daddr)
9786+{
9787+ struct ipsecpriv *prv = dev->priv;
9788+
9789+ if(!prv->header_cache_bind) {
9790+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9791+ "klips_debug:ipsec_tunnel_cache_bind: "
9792+ "physical device has been detached, cannot set - "
9793+ "skb->dev=%s->NULL\n",
9794+ dev->name);
9795+ return;
9796+ }
9797+
9798+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9799+ "klips_debug:ipsec_tunnel_cache_bind: "
9800+ "Revectored \n");
9801+ prv->header_cache_bind(hhp, prv->dev, htype, daddr);
9802+ return;
9803+}
9804+#endif /* !NET_21 */
9805+
9806+
9807+DEBUG_NO_STATIC void
9808+ipsec_tunnel_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr)
9809+{
9810+ struct ipsecpriv *prv = dev->priv;
9811+
9812+ if(!prv->header_cache_update) {
9813+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9814+ "klips_debug:ipsec_tunnel_cache_update: "
9815+ "physical device has been detached, cannot set - "
9816+ "skb->dev=%s->NULL\n",
9817+ dev->name);
9818+ return;
9819+ }
9820+
9821+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9822+ "klips_debug:ipsec_tunnel: "
9823+ "Revectored cache_update\n");
9824+ prv->header_cache_update(hh, prv->dev, haddr);
9825+ return;
9826+}
9827+
9828+#ifdef NET_21
9829+DEBUG_NO_STATIC int
9830+ipsec_tunnel_neigh_setup(struct neighbour *n)
9831+{
9832+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9833+ "klips_debug:ipsec_tunnel: "
9834+ "ipsec_tunnel_neigh_setup\n");
9835+
9836+ if (n->nud_state == NUD_NONE) {
9837+ n->ops = &arp_broken_ops;
9838+ n->output = n->ops->output;
9839+ }
9840+ return 0;
9841+}
9842+
9843+DEBUG_NO_STATIC int
9844+ipsec_tunnel_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
9845+{
9846+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
9847+ "klips_debug:ipsec_tunnel: "
9848+ "ipsec_tunnel_neigh_setup_dev\n");
9849+
9850+ if (p->tbl->family == AF_INET) {
9851+ p->neigh_setup = ipsec_tunnel_neigh_setup;
9852+ p->ucast_probes = 0;
9853+ p->mcast_probes = 0;
9854+ }
9855+ return 0;
9856+}
9857+#endif /* NET_21 */
9858+
9859+/*
9860+ * We call the attach routine to attach another device.
9861+ */
9862+
9863+DEBUG_NO_STATIC int
9864+ipsec_tunnel_attach(struct device *tndev, struct ipsecpriv *prv, struct device *dev)
9865+{
9866+ int i;
9867+
9868+ prv->dev = dev;
9869+ prv->hard_start_xmit = dev->hard_start_xmit;
9870+ prv->get_stats = dev->get_stats;
9871+
9872+ if (dev->hard_header) {
9873+ prv->hard_header = dev->hard_header;
9874+ tndev->hard_header = ipsec_tunnel_hard_header;
9875+ } else
9876+ tndev->hard_header = NULL;
9877+
9878+ if (dev->rebuild_header) {
9879+ prv->rebuild_header = dev->rebuild_header;
9880+ tndev->rebuild_header = ipsec_tunnel_rebuild_header;
9881+ } else
9882+ tndev->rebuild_header = NULL;
9883+
9884+ if (dev->set_mac_address) {
9885+ prv->set_mac_address = dev->set_mac_address;
9886+ tndev->set_mac_address = ipsec_tunnel_set_mac_address;
9887+ } else
9888+ tndev->set_mac_address = NULL;
9889+
9890+#ifndef NET_21
9891+ if (dev->header_cache_bind) {
9892+ prv->header_cache_bind = dev->header_cache_bind;
9893+ tndev->header_cache_bind = ipsec_tunnel_cache_bind;
9894+ } else
9895+ tndev->header_cache_bind = NULL;
9896+#endif /* !NET_21 */
9897+
9898+ if (dev->header_cache_update) {
9899+ prv->header_cache_update = dev->header_cache_update;
9900+ tndev->header_cache_update = ipsec_tunnel_cache_update;
9901+ } else
9902+ tndev->header_cache_update = NULL;
9903+
9904+ tndev->hard_header_len = dev->hard_header_len;
9905+
9906+#ifdef NET_21
9907+/* prv->neigh_setup = dev->neigh_setup; */
9908+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
9909+#endif /* NET_21 */
9910+ tndev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
9911+ prv->mtu = dev->mtu;
9912+
9913+#ifdef PHYSDEV_TYPE
9914+ tndev->type = dev->type /* ARPHRD_TUNNEL */; /* initially */
9915+#endif /* PHYSDEV_TYPE */
9916+
9917+ tndev->addr_len = dev->addr_len;
9918+ for (i=0; i<tndev->addr_len; i++) {
9919+ tndev->dev_addr[i] = dev->dev_addr[i];
9920+ }
9921+#ifdef CONFIG_IPSEC_DEBUG
9922+ if(debug_tunnel & DB_TN_INIT) {
9923+ printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
9924+ "physical device %s being attached has HW address: %2x",
9925+ dev->name, dev->dev_addr[0]);
9926+ for (i=1; i < dev->addr_len; i++) {
9927+ printk(":%02x", dev->dev_addr[i]);
9928+ }
9929+ printk("\n");
9930+ }
9931+#endif /* CONFIG_IPSEC_DEBUG */
9932+
9933+ return 0;
9934+}
9935+
9936+/*
9937+ * We call the detach routine to detach the ipsec tunnel from another device.
9938+ */
9939+
9940+DEBUG_NO_STATIC int
9941+ipsec_tunnel_detach(struct device *dev, struct ipsecpriv *prv)
9942+{
9943+ int i;
9944+
9945+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
9946+ "klips_debug:ipsec_tunnel_detach: "
9947+ "physical device %s being detached from virtual device %s\n",
9948+ prv->dev->name, dev->name);
9949+
9950+ prv->dev = NULL;
9951+ prv->hard_start_xmit = NULL;
9952+ prv->get_stats = NULL;
9953+
9954+ prv->hard_header = NULL;
9955+ dev->hard_header = NULL;
9956+
9957+ prv->rebuild_header = NULL;
9958+ dev->rebuild_header = NULL;
9959+
9960+ prv->set_mac_address = NULL;
9961+ dev->set_mac_address = NULL;
9962+
9963+#ifndef NET_21
9964+ prv->header_cache_bind = NULL;
9965+ dev->header_cache_bind = NULL;
9966+#endif /* !NET_21 */
9967+
9968+ prv->header_cache_update = NULL;
9969+ dev->header_cache_update = NULL;
9970+
9971+#ifdef NET_21
9972+/* prv->neigh_setup = NULL; */
9973+ dev->neigh_setup = NULL;
9974+#endif /* NET_21 */
9975+ dev->hard_header_len = 0;
9976+ dev->mtu = 0;
9977+ prv->mtu = 0;
9978+ for (i=0; i<MAX_ADDR_LEN; i++) {
9979+ dev->dev_addr[i] = 0;
9980+ }
9981+ dev->addr_len = 0;
9982+#ifdef PHYSDEV_TYPE
9983+ dev->type = 0;
9984+#endif /* PHYSDEV_TYPE */
9985+
9986+ return 0;
9987+}
9988+
9989+/*
9990+ * We call the clear routine to detach all ipsec tunnels from other devices.
9991+ */
9992+DEBUG_NO_STATIC int
9993+ipsec_tunnel_clear(void)
9994+{
9995+ int i;
9996+ struct device *ipsecdev = NULL, *prvdev;
9997+ struct ipsecpriv *prv;
9998+ char name[9];
9999+ int ret;
10000+
10001+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10002+ "klips_debug:ipsec_tunnel_clear: called.\n");
10003+
10004+ for(i = 0; i < IPSEC_NUM_IF; i++) {
10005+ sprintf(name, "ipsec%d", i);
10006+ if((ipsecdev = ipsec_dev_get(name)) != NULL) {
10007+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
10008+ prvdev = (struct device *)(prv->dev);
10009+ if(prvdev) {
10010+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10011+ "klips_debug:ipsec_tunnel_clear: "
10012+ "physical device for device %s is %s\n",
10013+ name, prvdev->name);
10014+ if((ret = ipsec_tunnel_detach(ipsecdev, prv))) {
10015+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10016+ "klips_debug:ipsec_tunnel_clear: "
10017+ "error %d detatching device %s from device %s.\n",
10018+ ret, name, prvdev->name);
10019+ return ret;
10020+ }
10021+ }
10022+ }
10023+ }
10024+ }
10025+ return 0;
10026+}
10027+
10028+DEBUG_NO_STATIC int
10029+ipsec_tunnel_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
10030+{
10031+ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
10032+ struct ipsecpriv *prv = dev->priv;
10033+ struct device *them; /* physical device */
10034+#ifdef CONFIG_IP_ALIAS
10035+ char *colon;
10036+ char realphysname[IFNAMSIZ];
10037+#endif /* CONFIG_IP_ALIAS */
10038+
10039+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10040+ "klips_debug:ipsec_tunnel_ioctl: "
10041+ "tncfg service call #%d\n", cmd);
10042+ switch (cmd) {
10043+ /* attach a virtual ipsec? device to a physical device */
10044+ case IPSEC_SET_DEV:
10045+#ifdef CONFIG_IP_ALIAS
10046+ /* If this is an IP alias interface, get its real physical name */
10047+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
10048+ realphysname[IFNAMSIZ-1] = 0;
10049+ colon = strchr(realphysname, ':');
10050+ if (colon) *colon = 0;
10051+ them = ipsec_dev_get(realphysname);
10052+#else /* CONFIG_IP_ALIAS */
10053+ them = ipsec_dev_get(cf->cf_name);
10054+#endif /* CONFIG_IP_ALIAS */
10055+
10056+ if (them == NULL) {
10057+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10058+ "klips_debug:ipsec_tunnel_ioctl: "
10059+ "physical device requested is null\n");
10060+
10061+ return -ENXIO;
10062+ }
10063+
10064+ if (prv->dev)
10065+ return -EBUSY;
10066+ return ipsec_tunnel_attach(dev, dev->priv, them);
10067+
10068+ case IPSEC_DEL_DEV:
10069+ if (! prv->dev)
10070+ return -ENODEV;
10071+ return ipsec_tunnel_detach(dev, dev->priv);
10072+
10073+ case IPSEC_CLR_DEV:
10074+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10075+ "klips_debug:ipsec_tunnel_ioctl: "
10076+ "calling ipsec_tunnel_clear.\n");
10077+ return ipsec_tunnel_clear();
10078+
10079+ default:
10080+ return -EOPNOTSUPP;
10081+ }
10082+}
10083+
10084+int
10085+ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
10086+{
10087+ struct device *dev = ptr;
10088+ struct device *ipsec_dev;
10089+ struct ipsecpriv *priv;
10090+ char name[9];
10091+ int i;
10092+
10093+ /* check for loopback devices */
10094+ if (dev->flags & IFF_LOOPBACK)
10095+ return(NOTIFY_DONE);
10096+
10097+ switch (event)
10098+ {
10099+ case NETDEV_DOWN:
10100+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10101+ "ipsec_device_event: NETDEV_DOWN...\n");
10102+ /* find the attached physical device and detach it. */
10103+ for(i = 0; i < IPSEC_NUM_IF; i++) {
10104+ sprintf(name, "ipsec%d", i);
10105+ ipsec_dev = ipsec_dev_get(name);
10106+ if(ipsec_dev) {
10107+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
10108+ if(priv) {
10109+ ;
10110+ if(((struct device *)(priv->dev)) == dev) {
10111+ dev_close(ipsec_dev);
10112+ /* return */ ipsec_tunnel_detach(ipsec_dev, priv);
10113+ return NOTIFY_DONE;
10114+ break;
10115+ }
10116+ } else {
10117+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10118+ "klips_debug:ipsec_device_event: device '%s' has no private data space!\n",
10119+ ipsec_dev->name);
10120+ }
10121+ }
10122+ }
10123+
10124+ break;
10125+ case NETDEV_UP:
10126+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10127+ "ipsec_device_event: NETDEV_UP...\n");
10128+ /* Only handle ethernet ports */
10129+ if(dev->type!=ARPHRD_ETHER && dev->type!=ARPHRD_LOOPBACK)
10130+ return NOTIFY_DONE;
10131+
10132+ break;
10133+#ifdef NET_21
10134+ case NETDEV_UNREGISTER:
10135+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10136+ "ipsec_device_event: NETDEV_UNREGISTER...\n");
10137+
10138+ break;
10139+#endif /* NET_21 */
10140+ }
10141+ return NOTIFY_DONE;
10142+}
10143+
10144+/*
10145+ * Called when an ipsec tunnel device is initialized.
10146+ * The ipsec tunnel device structure is passed to us.
10147+ */
10148+
10149+int
10150+ipsec_tunnel_init(struct device *dev)
10151+{
10152+ int i;
10153+
10154+ printk(KERN_INFO "klips_debug:ipsec_tunnel_init: "
10155+ "initialisation of device: %s\n",
10156+ dev->name ? dev->name : "NULL");
10157+
10158+ /* Add our tunnel functions to the device */
10159+ dev->open = ipsec_tunnel_open;
10160+ dev->stop = ipsec_tunnel_close;
10161+ dev->hard_start_xmit = ipsec_tunnel_start_xmit;
10162+ dev->get_stats = ipsec_tunnel_get_stats;
10163+
10164+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
10165+ if (dev->priv == NULL)
10166+ return -ENOMEM;
10167+ memset(dev->priv, 0, sizeof(struct ipsecpriv));
10168+
10169+ for(i = 0; i < sizeof(zeroes); i++) {
10170+ ((__u8*)(zeroes))[i] = 0;
10171+ }
10172+
10173+#ifndef NET_21
10174+ /* Initialize the tunnel device structure */
10175+ for (i = 0; i < DEV_NUMBUFFS; i++)
10176+ skb_queue_head_init(&dev->buffs[i]);
10177+#endif /* !NET_21 */
10178+
10179+ dev->set_multicast_list = NULL;
10180+ dev->do_ioctl = ipsec_tunnel_ioctl;
10181+ dev->hard_header = NULL;
10182+ dev->rebuild_header = NULL;
10183+ dev->set_mac_address = NULL;
10184+#ifndef NET_21
10185+ dev->header_cache_bind = NULL;
10186+#endif /* !NET_21 */
10187+ dev->header_cache_update= NULL;
10188+
10189+#ifdef NET_21
10190+/* prv->neigh_setup = NULL; */
10191+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
10192+#endif /* NET_21 */
10193+ dev->hard_header_len = 0;
10194+ dev->mtu = 0;
10195+ dev->addr_len = 0;
10196+ dev->type = ARPHRD_TUNNEL; /* 0 */ /* ARPHRD_ETHER; */ /* initially */
10197+ dev->tx_queue_len = 10; /* Small queue */
10198+ memset(dev->broadcast,0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
10199+
10200+ /* New-style flags. */
10201+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
10202+#ifdef NET_21
10203+ dev_init_buffers(dev);
10204+#else /* NET_21 */
10205+ dev->family = AF_INET;
10206+ dev->pa_addr = 0;
10207+ dev->pa_brdaddr = 0;
10208+ dev->pa_mask = 0;
10209+ dev->pa_alen = 4;
10210+#endif /* NET_21 */
10211+
10212+ /* We're done. Have I forgotten anything? */
10213+ return 0;
10214+}
10215+
10216+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10217+/* Module specific interface (but it links with the rest of IPSEC */
10218+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
10219+
10220+int
10221+ipsec_tunnel_probe(struct device *dev)
10222+{
10223+ ipsec_tunnel_init(dev);
10224+ return 0;
10225+}
10226+
10227+static struct device dev_ipsec3 =
10228+{
10229+ "ipsec3\0 ", /* name */
10230+ 0, /* recv memory end */
10231+ 0, /* recv memory start */
10232+ 0, /* memory end */
10233+ 0, /* memory start */
10234+ 0x0, /* base I/O address */
10235+ 0, /* IRQ */
10236+ 0, 0, 0, /* flags */
10237+ NULL, /* next device */
10238+ ipsec_tunnel_probe /* setup */
10239+};
10240+
10241+static struct device dev_ipsec2 =
10242+{
10243+ "ipsec2\0 ", /* name */
10244+ 0, /* recv memory end */
10245+ 0, /* recv memory start */
10246+ 0, /* memory end */
10247+ 0, /* memory start */
10248+ 0x0, /* base I/O address */
10249+ 0, /* IRQ */
10250+ 0, 0, 0, /* flags */
10251+ NULL, /* next device */
10252+ ipsec_tunnel_probe /* setup */
10253+};
10254+
10255+static struct device dev_ipsec1 =
10256+{
10257+ "ipsec1\0 ", /* name */
10258+ 0, /* recv memory end */
10259+ 0, /* recv memory start */
10260+ 0, /* memory end */
10261+ 0, /* memory start */
10262+ 0x0, /* base I/O address */
10263+ 0, /* IRQ */
10264+ 0, 0, 0, /* flags */
10265+ NULL, /* next device */
10266+ ipsec_tunnel_probe /* setup */
10267+};
10268+
10269+static struct device dev_ipsec0 =
10270+{
10271+ "ipsec0\0 ", /* name */
10272+ 0, /* recv memory end */
10273+ 0, /* recv memory start */
10274+ 0, /* memory end */
10275+ 0, /* memory start */
10276+ 0x0, /* base I/O address */
10277+ 0, /* IRQ */
10278+ 0, 0, 0, /* flags */
10279+ NULL, /* next device */
10280+ ipsec_tunnel_probe /* setup */
10281+};
10282+
10283+int
10284+ipsec_tunnel_init_devices(void)
10285+{
10286+#if 0
10287+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10288+ "klips_debug:ipsec_tunnel_init_devices: "
10289+ "registering device %s\n",
10290+ dev_ipsec0.name);
10291+#endif
10292+ if (register_netdev(&dev_ipsec0) != 0)
10293+ return -EIO;
10294+#if 0
10295+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10296+ "klips_debug:ipsec_tunnel_init_devices: "
10297+ "registering device %s\n",
10298+ dev_ipsec1.name);
10299+#endif
10300+ if (register_netdev(&dev_ipsec1) != 0)
10301+ return -EIO;
10302+#if 0
10303+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10304+ "klips_debug:ipsec_tunnel_init_devices: "
10305+ "registering device %s\n",
10306+ dev_ipsec2.name);
10307+#endif
10308+ if (register_netdev(&dev_ipsec2) != 0)
10309+ return -EIO;
10310+#if 0
10311+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
10312+ "klips_debug:ipsec_tunnel_init_devices: "
10313+ "registering device %s\n",
10314+ dev_ipsec3.name);
10315+#endif
10316+ if (register_netdev(&dev_ipsec3) != 0)
10317+ return -EIO;
10318+ return 0;
10319+}
10320+
10321+/* void */
10322+int
10323+ipsec_tunnel_cleanup_devices(void)
10324+{
10325+ int error = 0;
10326+
10327+ unregister_netdev(&dev_ipsec0);
10328+ unregister_netdev(&dev_ipsec1);
10329+ unregister_netdev(&dev_ipsec2);
10330+ unregister_netdev(&dev_ipsec3);
10331+ kfree(dev_ipsec0.priv);
10332+ kfree(dev_ipsec1.priv);
10333+ kfree(dev_ipsec2.priv);
10334+ kfree(dev_ipsec3.priv);
10335+ dev_ipsec0.priv=NULL;
10336+ dev_ipsec1.priv=NULL;
10337+ dev_ipsec2.priv=NULL;
10338+ dev_ipsec3.priv=NULL;
10339+
10340+ return error;
10341+}
10342+
10343+/*
10344+ * $Log$
10345+ * Revision 1.131 2000/11/09 20:52:15 rgb
10346+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
10347+ * include ipcomp and prevent races, renaming some tdb variables that got
10348+ * forgotten, moving some unlocks to include tdbs and adding a missing
10349+ * unlock. Thanks to Svenning for some of these.
10350+ *
10351+ * Revision 1.130 2000/11/09 20:11:22 rgb
10352+ * Minor shuffles to fix non-standard kernel config option selection.
10353+ *
10354+ * Revision 1.129 2000/11/06 04:32:49 rgb
10355+ * Clean up debug printing.
10356+ * Copy skb->protocol for all kernel versions.
10357+ * Ditched spin_lock_irqsave in favour of spin_lock.
10358+ * Disabled TTL decrement, done in ip_forward.
10359+ * Added debug printing before pfkey_acquire().
10360+ * Fixed printk-deltdbchain-spin_lock races (Svenning).
10361+ * Use defaultTTL for 2.1+ kernels.
10362+ * Add Svenning's adaptive content compression.
10363+ * Fix up debug display arguments.
10364+ *
10365+ * Revision 1.128 2000/09/28 00:58:57 rgb
10366+ * Moved the IKE passthrough check after the eroute lookup so we can pass
10367+ * IKE through intermediate tunnels.
10368+ *
10369+ * Revision 1.127 2000/09/22 17:52:11 rgb
10370+ * Fixed misleading ipcomp debug output.
10371+ *
10372+ * Revision 1.126 2000/09/22 04:22:56 rgb
10373+ * Fixed dumb spi->cpi conversion error.
10374+ *
10375+ * Revision 1.125 2000/09/21 04:34:48 rgb
10376+ * A few debug-specific things should be hidden under
10377+ * CONFIG_IPSEC_DEBUG.(MB)
10378+ * Improved ip_send() error handling.(MB)
10379+ *
10380+ * Revision 1.124 2000/09/21 03:40:58 rgb
10381+ * Added more debugging to try and track down the cpi outward copy problem.
10382+ *
10383+ * Revision 1.123 2000/09/19 07:08:49 rgb
10384+ * Added debugging to outgoing compression report.
10385+ *
10386+ * Revision 1.122 2000/09/18 19:21:26 henry
10387+ * RGB-supplied fix for RH5.2 problem
10388+ *
10389+ * Revision 1.121 2000/09/17 21:05:09 rgb
10390+ * Added tdb to skb_compress call to write in cpi.
10391+ *
10392+ * Revision 1.120 2000/09/17 16:57:16 rgb
10393+ * Added Svenning's patch to remove restriction of ipcomp to innermost
10394+ * transform.
10395+ *
10396+ * Revision 1.119 2000/09/15 11:37:01 rgb
10397+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
10398+ * IPCOMP zlib deflate code.
10399+ *
10400+ * Revision 1.118 2000/09/15 04:57:16 rgb
10401+ * Moved debug output after sanity check.
10402+ * Added tos copy sysctl.
10403+ *
10404+ * Revision 1.117 2000/09/12 03:22:51 rgb
10405+ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
10406+ * sysctl.
10407+ *
10408+ * Revision 1.116 2000/09/08 19:18:19 rgb
10409+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
10410+ * Added outgoing opportunistic hook, ifdef'ed out.
10411+ *
10412+ * Revision 1.115 2000/08/30 05:27:29 rgb
10413+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
10414+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
10415+ *
10416+ * Revision 1.114 2000/08/28 18:15:46 rgb
10417+ * Added MB's nf-debug reset patch.
10418+ *
10419+ * Revision 1.113 2000/08/27 02:26:40 rgb
10420+ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
10421+ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
10422+ *
10423+ * Revision 1.112 2000/08/20 21:37:33 rgb
10424+ * Activated pfkey_expire() calls.
10425+ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
10426+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
10427+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
10428+ *
10429+ * Revision 1.111 2000/08/01 14:51:51 rgb
10430+ * Removed _all_ remaining traces of DES.
10431+ *
10432+ * Revision 1.110 2000/07/28 14:58:31 rgb
10433+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
10434+ *
10435+ * Revision 1.109 2000/07/28 13:50:54 rgb
10436+ * Changed enet_statistics to net_device_stats and added back compatibility
10437+ * for pre-2.1.19.
10438+ *
10439+ * Revision 1.108 2000/05/16 03:03:11 rgb
10440+ * Updates for 2.3.99pre8 from MB.
10441+ *
10442+ * Revision 1.107 2000/05/10 23:08:21 rgb
10443+ * Print a debug warning about bogus packets received by the outgoing
10444+ * processing machinery only when klipsdebug is not set to none.
10445+ * Comment out the device initialisation informational messages.
10446+ *
10447+ * Revision 1.106 2000/05/10 19:17:14 rgb
10448+ * Define an IP_SEND macro, intending to have all packet passthroughs
10449+ * use fragmentation. This didn't quite work, but is a step in the
10450+ * right direction.
10451+ * Added buffer allocation debugging statements.
10452+ * Added configure option to shut off no eroute passthrough.
10453+ * Only check usetime against soft and hard limits if the tdb has been
10454+ * used.
10455+ * Cast output of ntohl so that the broken prototype doesn't make our
10456+ * compile noisy.
10457+ *
10458+ * Revision 1.105 2000/03/22 16:15:37 rgb
10459+ * Fixed renaming of dev_get (MB).
10460+ *
10461+ * Revision 1.104 2000/03/16 14:04:15 rgb
10462+ * Indented headers for readability.
10463+ * Fixed debug scope to enable compilation with debug off.
10464+ * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
10465+ *
10466+ * Revision 1.103 2000/03/16 07:11:07 rgb
10467+ * Hardcode PF_KEYv2 support.
10468+ * Fixed bug which allowed UDP/500 packet from another machine
10469+ * through in the clear.
10470+ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
10471+ *
10472+ * Revision 1.102 2000/03/14 12:26:59 rgb
10473+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
10474+ *
10475+ * Revision 1.101 2000/02/14 21:05:22 rgb
10476+ * Added MB's netif_queue fix for kernels 2.3.43+.
10477+ *
10478+ * Revision 1.100 2000/01/26 10:04:57 rgb
10479+ * Fixed noisy 2.0 printk arguments.
10480+ *
10481+ * Revision 1.99 2000/01/21 06:16:25 rgb
10482+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
10483+ * Switched to AF_ENCAP macro.
10484+ * Shortened debug output per packet and re-arranging debug_tunnel
10485+ * bitmap flags, while retaining necessary information to avoid
10486+ * trampling the kernel print ring buffer.
10487+ * Reformatted recursion switch code.
10488+ * Changed all references to tdb_proto to tdb_said.proto for clarity.
10489+ *
10490+ * Revision 1.98 2000/01/13 08:09:31 rgb
10491+ * Shuffled debug_tunnel switches to focus output.
10492+ * Fixed outgoing recursion bug, limiting to recursing only if the remote
10493+ * SG changes and if it is valid, ie. not passthrough.
10494+ * Clarified a number of debug messages.
10495+ *
10496+ * Revision 1.97 2000/01/10 16:37:16 rgb
10497+ * MB support for new ip_select_ident() upon disappearance of
10498+ * ip_id_count in 2.3.36+.
10499+ *
10500+ * Revision 1.96 1999/12/31 14:59:08 rgb
10501+ * MB fix to use new skb_copy_expand in kernel 2.3.35.
10502+ *
10503+ * Revision 1.95 1999/12/29 21:15:44 rgb
10504+ * Fix tncfg to aliased device bug.
10505+ *
10506+ * Revision 1.94 1999/12/22 04:26:06 rgb
10507+ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
10508+ * debugging by providing external labels to all functions with debugging
10509+ * turned on.
10510+ *
10511+ * Revision 1.93 1999/12/13 13:30:14 rgb
10512+ * Changed MTU reports and HW address reporting back to debug only.
10513+ *
10514+ * Revision 1.92 1999/12/07 18:57:56 rgb
10515+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
10516+ *
10517+ * Revision 1.91 1999/12/01 22:15:36 rgb
10518+ * Add checks for LARVAL and DEAD SAs.
10519+ * Change state of SA from MATURE to DYING when a soft lifetime is
10520+ * reached and print debug warning.
10521+ *
10522+ * Revision 1.90 1999/11/23 23:04:04 rgb
10523+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
10524+ * Sort out pfkey and freeswan headers, putting them in a library path.
10525+ *
10526+ * Revision 1.89 1999/11/18 18:50:59 rgb
10527+ * Changed all device registrations for static linking to
10528+ * dynamic to reduce the number and size of patches.
10529+ *
10530+ * Revision 1.88 1999/11/18 04:09:19 rgb
10531+ * Replaced all kernel version macros to shorter, readable form.
10532+ *
10533+ * Revision 1.87 1999/11/17 15:53:40 rgb
10534+ * Changed all occurrences of #include "../../../lib/freeswan.h"
10535+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
10536+ * klips/net/ipsec/Makefile.
10537+ *
10538+ * Revision 1.86 1999/10/16 18:25:37 rgb
10539+ * Moved SA lifetime expiry checks before packet processing.
10540+ * Expire SA on replay counter rollover.
10541+ *
10542+ * Revision 1.85 1999/10/16 04:24:31 rgb
10543+ * Add stats for time since last packet.
10544+ *
10545+ * Revision 1.84 1999/10/16 00:30:47 rgb
10546+ * Added SA lifetime counting.
10547+ *
10548+ * Revision 1.83 1999/10/15 22:15:57 rgb
10549+ * Clean out cruft.
10550+ * Add debugging.
10551+ *
10552+ * Revision 1.82 1999/10/08 18:26:19 rgb
10553+ * Fix 2.0.3x outgoing fragmented packet memory leak.
10554+ *
10555+ * Revision 1.81 1999/10/05 02:38:54 rgb
10556+ * Lower the default mtu of virtual devices to 16260.
10557+ *
10558+ * Revision 1.80 1999/10/03 18:56:41 rgb
10559+ * Spinlock support for 2.3.xx.
10560+ * Don't forget to undo spinlocks on error!
10561+ * Check for valid eroute before copying the structure.
10562+ *
10563+ * Revision 1.79 1999/10/01 15:44:53 rgb
10564+ * Move spinlock header include to 2.1> scope.
10565+ *
10566+ * Revision 1.78 1999/10/01 00:02:43 rgb
10567+ * Added tdb structure locking.
10568+ * Added eroute structure locking.
10569+ *
10570+ * Revision 1.77 1999/09/30 02:52:29 rgb
10571+ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
10572+ *
10573+ * Revision 1.76 1999/09/25 19:31:27 rgb
10574+ * Refine MSS hack to affect SYN, but not SYN+ACK packets.
10575+ *
10576+ * Revision 1.75 1999/09/24 22:52:38 rgb
10577+ * Fix two things broken in 2.0.38 by trying to fix network notifiers.
10578+ *
10579+ * Revision 1.74 1999/09/24 00:30:37 rgb
10580+ * Add test for changed source as well as destination to check for
10581+ * recursion.
10582+ *
10583+ * Revision 1.73 1999/09/23 20:52:24 rgb
10584+ * Add James Morris' MSS hack patch, disabled.
10585+ *
10586+ * Revision 1.72 1999/09/23 20:22:40 rgb
10587+ * Enable, tidy and fix network notifier code.
10588+ *
10589+ * Revision 1.71 1999/09/23 18:09:05 rgb
10590+ * Clean up 2.2.x fragmenting traces.
10591+ * Disable dev->type switching, forcing ARPHRD_TUNNEL.
10592+ *
10593+ * Revision 1.70 1999/09/22 14:14:24 rgb
10594+ * Add sanity checks for revectored calls to prevent calling a downed I/F.
10595+ *
10596+ * Revision 1.69 1999/09/21 15:00:57 rgb
10597+ * Add Marc Boucher's packet size check.
10598+ * Flesh out network device notifier code.
10599+ *
10600+ * Revision 1.68 1999/09/18 11:39:57 rgb
10601+ * Start to add (disabled) netdevice notifier code.
10602+ *
10603+ * Revision 1.67 1999/09/17 23:44:40 rgb
10604+ * Add a comment warning potential code hackers to stay away from mac.raw.
10605+ *
10606+ * Revision 1.66 1999/09/17 18:04:02 rgb
10607+ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
10608+ * Ditch TTL decrement in 2.2 (MB).
10609+ *
10610+ * Revision 1.65 1999/09/15 23:15:35 henry
10611+ * Marc Boucher's PPP fixes
10612+ *
10613+ * Revision 1.64 1999/09/07 13:40:53 rgb
10614+ * Ditch unreliable references to skb->mac.raw.
10615+ *
10616+ * Revision 1.63 1999/08/28 11:33:09 rgb
10617+ * Check for null skb->mac pointer.
10618+ *
10619+ * Revision 1.62 1999/08/28 02:02:30 rgb
10620+ * Add Marc Boucher's fix for properly dealing with skb->sk.
10621+ *
10622+ * Revision 1.61 1999/08/27 05:23:05 rgb
10623+ * Clean up skb->data/raw/nh/h manipulation.
10624+ * Add Marc Boucher's mods to aid tcpdump.
10625+ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
10626+ * Re-order hard_header stripping -- might be able to remove it...
10627+ *
10628+ * Revision 1.60 1999/08/26 20:01:02 rgb
10629+ * Tidy up compiler directives and macros.
10630+ * Re-enable ICMP for tunnels where inner_dst != outer_dst.
10631+ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
10632+ *
10633+ * Revision 1.59 1999/08/25 15:44:41 rgb
10634+ * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
10635+ *
10636+ * Revision 1.58 1999/08/25 15:00:54 rgb
10637+ * Add dst cache code for 2.2.xx.
10638+ * Add sanity check for skb packet header pointers.
10639+ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
10640+ * *_rebuild_header.
10641+ * Add neigh_* cache code.
10642+ * Change dev->type back to ARPHRD_TUNNEL.
10643+ *
10644+ * Revision 1.57 1999/08/17 21:50:23 rgb
10645+ * Fixed minor debug output bugs.
10646+ * Regrouped error recovery exit code.
10647+ * Added compiler directives to remove unwanted code and symbols.
10648+ * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
10649+ * Add debugging code for output function addresses.
10650+ * Fix minor bug in (possibly unused) header_cache_bind function.
10651+ * Add device neighbour caching code.
10652+ * Change dev->type from ARPHRD_TUNNEL to physdev->type.
10653+ *
10654+ * Revision 1.56 1999/08/03 17:22:56 rgb
10655+ * Debug output clarification using KERN_* macros. Other inactive changes
10656+ * added.
10657+ *
10658+ * Revision 1.55 1999/08/03 16:58:46 rgb
10659+ * Fix skb_copy_expand size bug. Was getting incorrect size.
10660+ *
10661+ * Revision 1.54 1999/07/14 19:32:38 rgb
10662+ * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
10663+ *
10664+ * Revision 1.53 1999/06/10 15:44:02 rgb
10665+ * Minor reformatting and clean-up.
10666+ *
10667+ * Revision 1.52 1999/05/09 03:25:36 rgb
10668+ * Fix bug introduced by 2.2 quick-and-dirty patch.
10669+ *
10670+ * Revision 1.51 1999/05/08 21:24:59 rgb
10671+ * Add casting to silence the 2.2.x compile.
10672+ *
10673+ * Revision 1.50 1999/05/05 22:02:32 rgb
10674+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
10675+ *
10676+ * Revision 1.49 1999/04/29 15:18:52 rgb
10677+ * Change gettdb parameter to a pointer to reduce stack loading and
10678+ * facilitate parameter sanity checking.
10679+ * Fix undetected bug that might have tried to access a null pointer.
10680+ * Eliminate unnessessary usage of tdb_xform member to further switch
10681+ * away from the transform switch to the algorithm switch.
10682+ * Add return values to init and cleanup functions.
10683+ *
10684+ * Revision 1.48 1999/04/16 15:38:00 rgb
10685+ * Minor rearrangement of freeing code to avoid memory leaks with impossible or
10686+ * rare situations.
10687+ *
10688+ * Revision 1.47 1999/04/15 15:37:25 rgb
10689+ * Forward check changes from POST1_00 branch.
10690+ *
10691+ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb
10692+ * Ditch 'things I wish I had known before...'.
10693+ *
10694+ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb
10695+ * Free skb after fragmentation.
10696+ * Use stats more effectively.
10697+ * Add I/F to mtu notch-down reporting.
10698+ *
10699+ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb
10700+ * Backcheck from HEAD, pre1.0.
10701+ *
10702+ * Revision 1.46 1999/04/11 00:29:00 henry
10703+ * GPL boilerplate
10704+ *
10705+ * Revision 1.45 1999/04/07 15:42:01 rgb
10706+ * Fix mtu/ping bug AGAIN!
10707+ *
10708+ * Revision 1.44 1999/04/06 04:54:27 rgb
10709+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
10710+ * patch shell fixes.
10711+ *
10712+ * Revision 1.43 1999/04/04 03:57:07 rgb
10713+ * ip_fragment() doesn't free the supplied skb. Freed.
10714+ *
10715+ * Revision 1.42 1999/04/01 23:27:15 rgb
10716+ * Preload size of virtual mtu.
10717+ *
10718+ * Revision 1.41 1999/04/01 09:31:23 rgb
10719+ * Invert meaning of ICMP PMTUD config option and clarify.
10720+ * Code clean-up.
10721+ *
10722+ * Revision 1.40 1999/04/01 04:37:17 rgb
10723+ * SSH stalling bug fix.
10724+ *
10725+ * Revision 1.39 1999/03/31 23:44:28 rgb
10726+ * Don't send ICMP on DF and frag_off.
10727+ *
10728+ * Revision 1.38 1999/03/31 15:20:10 rgb
10729+ * Quiet down debugging.
10730+ *
10731+ * Revision 1.37 1999/03/31 08:30:31 rgb
10732+ * Add switch to shut off ICMP PMTUD packets.
10733+ *
10734+ * Revision 1.36 1999/03/31 05:44:47 rgb
10735+ * Keep PMTU reduction private.
10736+ *
10737+ * Revision 1.35 1999/03/27 15:13:02 rgb
10738+ * PMTU/fragmentation bug fix.
10739+ *
10740+ * Revision 1.34 1999/03/17 21:19:26 rgb
10741+ * Fix kmalloc nonatomic bug.
10742+ *
10743+ * Revision 1.33 1999/03/17 15:38:42 rgb
10744+ * Code clean-up.
10745+ * ESP_NULL IV bug fix.
10746+ *
10747+ * Revision 1.32 1999/03/01 20:44:25 rgb
10748+ * Code clean-up.
10749+ * Memory leak bug fix.
10750+ *
10751+ * Revision 1.31 1999/02/27 00:02:09 rgb
10752+ * Tune to report the MTU reduction once, rather than after every recursion
10753+ * through the encapsulating code, preventing tcp stream stalling.
10754+ *
10755+ * Revision 1.30 1999/02/24 20:21:01 rgb
10756+ * Reformat debug printk's.
10757+ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
10758+ * Clean-up.
10759+ *
10760+ * Revision 1.29 1999/02/22 17:08:14 rgb
10761+ * Fix recursive encapsulation code.
10762+ *
10763+ * Revision 1.28 1999/02/19 18:27:02 rgb
10764+ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
10765+ *
10766+ * Revision 1.27 1999/02/17 16:51:37 rgb
10767+ * Clean out unused cruft.
10768+ * Temporarily tone down volume of debug output.
10769+ * Temporarily shut off fragment rejection.
10770+ * Disabled temporary failed recursive encapsulation loop.
10771+ *
10772+ * Revision 1.26 1999/02/12 21:21:26 rgb
10773+ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
10774+ *
10775+ * Revision 1.25 1999/02/11 19:38:27 rgb
10776+ * More clean-up.
10777+ * Add sanity checking for skb_copy_expand() to prevent kernel panics on
10778+ * skb_put() values out of range.
10779+ * Fix head/tailroom calculation causing skb_put() out-of-range values.
10780+ * Fix return values to prevent 'nonatomic alloc_skb' warnings.
10781+ * Allocate new skb iff needed.
10782+ * Added more debug statements.
10783+ * Make headroom depend on structure, not hard-coded values.
10784+ *
10785+ * Revision 1.24 1999/02/10 23:20:33 rgb
10786+ * Shut up annoying 'statement has no effect' compiler warnings with
10787+ * debugging compiled out.
10788+ *
10789+ * Revision 1.23 1999/02/10 22:36:30 rgb
10790+ * Clean-up obsolete, unused and messy code.
10791+ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
10792+ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
10793+ * original ipsec_tunnel_start_xmit.
10794+ * Send all packet with different inner and outer destinations directly to
10795+ * the attached physical device, rather than back through ip_forward,
10796+ * preventing disappearing routes problems.
10797+ * Do sanity checking before investing too much CPU in allocating new
10798+ * structures.
10799+ * Fail on IP header options: We cannot process them yet.
10800+ * Add some helpful comments.
10801+ * Use virtual device for parameters instead of physical device.
10802+ *
10803+ * Revision 1.22 1999/02/10 03:03:02 rgb
10804+ * Duh. Fixed the TTL bug: forgot to update the checksum.
10805+ *
10806+ * Revision 1.21 1999/02/09 23:17:53 rgb
10807+ * Add structure members to ipsec_print_ip debug function.
10808+ * Temporarily fix TTL bug preventing tunnel mode from functioning.
10809+ *
10810+ * Revision 1.20 1999/02/09 00:14:25 rgb
10811+ * Add KLIPSPRINT macro. (Not used yet, though.)
10812+ * Delete old ip_tunnel code (BADCODE).
10813+ * Decrement TTL in outgoing packet.
10814+ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
10815+ * Delete ethernet only feature and fix hard-coded hard_header_len.
10816+ *
10817+ * Revision 1.19 1999/01/29 17:56:22 rgb
10818+ * 64-bit re-fix submitted by Peter Onion.
10819+ *
10820+ * Revision 1.18 1999/01/28 22:43:24 rgb
10821+ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
10822+ *
10823+ * Revision 1.17 1999/01/26 02:08:16 rgb
10824+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
10825+ * Removed dead code.
10826+ *
10827+ * Revision 1.16 1999/01/22 06:25:26 rgb
10828+ * Cruft clean-out.
10829+ * Added algorithm switch code.
10830+ * 64-bit clean-up.
10831+ * Passthrough on IPIP protocol, spi 0x0 fix.
10832+ * Enhanced debugging.
10833+ *
10834+ * Revision 1.15 1998/12/01 13:22:04 rgb
10835+ * Added support for debug printing of version info.
10836+ *
10837+ * Revision 1.14 1998/11/30 13:22:55 rgb
10838+ * Rationalised all the klips kernel file headers. They are much shorter
10839+ * now and won't conflict under RH5.2.
10840+ *
10841+ * Revision 1.13 1998/11/17 21:13:52 rgb
10842+ * Put IKE port bypass debug output in user-switched debug statements.
10843+ *
10844+ * Revision 1.12 1998/11/13 13:20:25 rgb
10845+ * Fixed ntohs bug in udp/500 hole for IKE.
10846+ *
10847+ * Revision 1.11 1998/11/10 08:01:19 rgb
10848+ * Kill tcp/500 hole, keep udp/500 hole.
10849+ *
10850+ * Revision 1.10 1998/11/09 21:29:26 rgb
10851+ * If no eroute is found, discard packet and incr. tx_error.
10852+ *
10853+ * Revision 1.9 1998/10/31 06:50:00 rgb
10854+ * Add tcp/udp/500 bypass.
10855+ * Fixed up comments in #endif directives.
10856+ *
10857+ * Revision 1.8 1998/10/27 00:34:31 rgb
10858+ * Reformat debug output of IP headers.
10859+ * Newlines added before calls to ipsec_print_ip.
10860+ *
10861+ * Revision 1.7 1998/10/19 14:44:28 rgb
10862+ * Added inclusion of freeswan.h.
10863+ * sa_id structure implemented and used: now includes protocol.
10864+ *
10865+ * Revision 1.6 1998/10/09 04:31:35 rgb
10866+ * Added 'klips_debug' prefix to all klips printk debug statements.
10867+ *
10868+ * Revision 1.5 1998/08/28 03:09:51 rgb
10869+ * Prevent kernel log spam with default route through ipsec.
10870+ *
10871+ * Revision 1.4 1998/08/05 22:23:09 rgb
10872+ * Change setdev return code to ENXIO for a non-existant physical device.
10873+ *
10874+ * Revision 1.3 1998/07/29 20:41:11 rgb
10875+ * Add ipsec_tunnel_clear to clear all tunnel attachments.
10876+ *
10877+ * Revision 1.2 1998/06/25 20:00:33 rgb
10878+ * Clean up #endif comments.
10879+ * Rename dev_ipsec to dev_ipsec0 for consistency.
10880+ * Document ipsec device fields.
10881+ * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
10882+ * Get debugging report for *every* ipsec device initialisation.
10883+ * Comment out redundant code.
10884+ *
10885+ * Revision 1.1 1998/06/18 21:27:50 henry
10886+ * move sources from klips/src to klips/net/ipsec, to keep stupid
10887+ * kernel-build scripts happier in the presence of symlinks
10888+ *
10889+ * Revision 1.8 1998/06/14 23:49:40 rgb
10890+ * Clarify version reporting on module loading.
10891+ *
10892+ * Revision 1.7 1998/05/27 23:19:20 rgb
10893+ * Added version reporting.
10894+ *
10895+ * Revision 1.6 1998/05/18 21:56:23 rgb
10896+ * Clean up for numerical consistency of output and cleaning up debug code.
10897+ *
10898+ * Revision 1.5 1998/05/12 02:44:23 rgb
10899+ * Clarifying 'no e-route to host' message.
10900+ *
10901+ * Revision 1.4 1998/04/30 15:34:35 rgb
10902+ * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
10903+ *
10904+ * Revision 1.3 1998/04/21 21:28:54 rgb
10905+ * Rearrange debug switches to change on the fly debug output from user
10906+ * space. Only kernel changes checked in at this time. radij.c was also
10907+ * changed to temporarily remove buggy debugging code in rj_delete causing
10908+ * an OOPS and hence, netlink device open errors.
10909+ *
10910+ * Revision 1.2 1998/04/12 22:03:24 rgb
10911+ * Updated ESP-3DES-HMAC-MD5-96,
10912+ * ESP-DES-HMAC-MD5-96,
10913+ * AH-HMAC-MD5-96,
10914+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
10915+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
10916+ *
10917+ * Fixed eroute references in /proc/net/ipsec*.
10918+ *
10919+ * Started to patch module unloading memory leaks in ipsec_netlink and
10920+ * radij tree unloading.
10921+ *
10922+ * Revision 1.1 1998/04/09 03:06:12 henry
10923+ * sources moved up from linux/net/ipsec
10924+ *
10925+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
10926+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
10927+ *
10928+ * Revision 0.5 1997/06/03 04:24:48 ji
10929+ * Added transport mode.
10930+ * Changed the way routing is done.
10931+ * Lots of bug fixes.
10932+ *
10933+ * Revision 0.4 1997/01/15 01:28:15 ji
10934+ * No changes.
10935+ *
10936+ * Revision 0.3 1996/11/20 14:39:04 ji
10937+ * Minor cleanups.
10938+ * Rationalized debugging code.
10939+ *
10940+ * Revision 0.2 1996/11/02 00:18:33 ji
10941+ * First limited release.
10942+ *
10943+ *
10944+ */
10945diff -druN linux-noipsec/net/ipsec/ipsec_tunnel.h linux/net/ipsec/ipsec_tunnel.h
10946--- linux-noipsec/net/ipsec/ipsec_tunnel.h Thu Jan 1 01:00:00 1970
10947+++ linux/net/ipsec/ipsec_tunnel.h Fri Sep 15 13:37:02 2000
10948@@ -0,0 +1,206 @@
10949+/*
10950+ * IPSEC tunneling code
10951+ * Copyright (C) 1996, 1997 John Ioannidis.
10952+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
10953+ *
10954+ * This program is free software; you can redistribute it and/or modify it
10955+ * under the terms of the GNU General Public License as published by the
10956+ * Free Software Foundation; either version 2 of the License, or (at your
10957+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10958+ *
10959+ * This program is distributed in the hope that it will be useful, but
10960+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10961+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10962+ * for more details.
10963+ *
10964+ * RCSID $Id$
10965+ */
10966+
10967+/*
10968+ * Heavily based on drivers/net/new_tunnel.c. Lots
10969+ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
10970+ */
10971+
10972+struct ipsectunnelconf
10973+{
10974+ __u32 cf_cmd;
10975+ union
10976+ {
10977+ char cfu_name[12];
10978+ } cf_u;
10979+#define cf_name cf_u.cfu_name
10980+};
10981+
10982+#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
10983+#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
10984+#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
10985+
10986+#ifdef __KERNEL__
10987+#include <linux/version.h>
10988+#ifndef KERNEL_VERSION
10989+# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
10990+#endif
10991+struct ipsecpriv
10992+{
10993+ struct sk_buff_head sendq;
10994+ struct device *dev;
10995+ struct wait_queue *wait_queue;
10996+ char locked;
10997+ int (*hard_start_xmit) (struct sk_buff *skb,
10998+ struct device *dev);
10999+ int (*hard_header) (struct sk_buff *skb,
11000+ struct device *dev,
11001+ unsigned short type,
11002+ void *daddr,
11003+ void *saddr,
11004+ unsigned len);
11005+#ifdef NET_21
11006+ int (*rebuild_header)(struct sk_buff *skb);
11007+#else /* NET_21 */
11008+ int (*rebuild_header)(void *buff, struct device *dev,
11009+ unsigned long raddr, struct sk_buff *skb);
11010+#endif /* NET_21 */
11011+ int (*set_mac_address)(struct device *dev, void *addr);
11012+#ifndef NET_21
11013+ void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev,
11014+ unsigned short htype, __u32 daddr);
11015+#endif /* !NET_21 */
11016+ void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr);
11017+ struct net_device_stats *(*get_stats)(struct device *dev);
11018+ struct net_device_stats mystats;
11019+ int mtu; /* What is the desired MTU? */
11020+};
11021+
11022+#define IPSEC_NUM_IF 4
11023+
11024+extern char ipsec_tunnel_c_version[];
11025+
11026+int ipsec_tunnel_init_devices(void);
11027+
11028+/* void */ int ipsec_tunnel_cleanup_devices(void);
11029+
11030+extern /* void */ int ipsec_init(void);
11031+
11032+#ifdef CONFIG_IPSEC_DEBUG
11033+extern int debug_tunnel;
11034+extern int sysctl_ipsec_debug_verbose;
11035+#endif /* CONFIG_IPSEC_DEBUG */
11036+#endif /* __KERNEL__ */
11037+
11038+#ifdef CONFIG_IPSEC_DEBUG
11039+#define DB_TN_INIT 0x0001
11040+#define DB_TN_PROCFS 0x0002
11041+#define DB_TN_XMIT 0x0010
11042+#define DB_TN_OHDR 0x0020
11043+#define DB_TN_CROUT 0x0040
11044+#define DB_TN_OXFS 0x0080
11045+#define DB_TN_REVEC 0x0100
11046+#endif /* CONFIG_IPSEC_DEBUG */
11047+
11048+/*
11049+ * $Log$
11050+ * Revision 1.20 2000/09/15 11:37:02 rgb
11051+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
11052+ * IPCOMP zlib deflate code.
11053+ *
11054+ * Revision 1.19 2000/09/08 19:12:56 rgb
11055+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
11056+ *
11057+ * Revision 1.18 2000/07/28 13:50:54 rgb
11058+ * Changed enet_statistics to net_device_stats and added back compatibility
11059+ * for pre-2.1.19.
11060+ *
11061+ * Revision 1.17 1999/11/19 01:12:15 rgb
11062+ * Purge unneeded proc_info prototypes, now that static linking uses
11063+ * dynamic proc_info registration.
11064+ *
11065+ * Revision 1.16 1999/11/18 18:51:00 rgb
11066+ * Changed all device registrations for static linking to
11067+ * dynamic to reduce the number and size of patches.
11068+ *
11069+ * Revision 1.15 1999/11/18 04:14:21 rgb
11070+ * Replaced all kernel version macros to shorter, readable form.
11071+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
11072+ * Added Marc Boucher's 2.3.25 proc patches.
11073+ *
11074+ * Revision 1.14 1999/05/25 02:50:10 rgb
11075+ * Fix kernel version macros for 2.0.x static linking.
11076+ *
11077+ * Revision 1.13 1999/05/25 02:41:06 rgb
11078+ * Add ipsec_klipsdebug support for static linking.
11079+ *
11080+ * Revision 1.12 1999/05/05 22:02:32 rgb
11081+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
11082+ *
11083+ * Revision 1.11 1999/04/29 15:19:50 rgb
11084+ * Add return values to init and cleanup functions.
11085+ *
11086+ * Revision 1.10 1999/04/16 16:02:39 rgb
11087+ * Bump up macro to 4 ipsec I/Fs.
11088+ *
11089+ * Revision 1.9 1999/04/15 15:37:25 rgb
11090+ * Forward check changes from POST1_00 branch.
11091+ *
11092+ * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
11093+ * Backcheck from HEAD, pre1.0.
11094+ *
11095+ * Revision 1.8 1999/04/11 00:29:01 henry
11096+ * GPL boilerplate
11097+ *
11098+ * Revision 1.7 1999/04/06 04:54:28 rgb
11099+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
11100+ * patch shell fixes.
11101+ *
11102+ * Revision 1.6 1999/03/31 05:44:48 rgb
11103+ * Keep PMTU reduction private.
11104+ *
11105+ * Revision 1.5 1999/02/10 22:31:20 rgb
11106+ * Change rebuild_header member to reflect generality of link layer.
11107+ *
11108+ * Revision 1.4 1998/12/01 13:22:04 rgb
11109+ * Added support for debug printing of version info.
11110+ *
11111+ * Revision 1.3 1998/07/29 20:42:46 rgb
11112+ * Add a macro for clearing all tunnel devices.
11113+ * Rearrange structures and declarations for sharing with userspace.
11114+ *
11115+ * Revision 1.2 1998/06/25 20:01:45 rgb
11116+ * Make prototypes available for ipsec_init and ipsec proc_dir_entries
11117+ * for static linking.
11118+ *
11119+ * Revision 1.1 1998/06/18 21:27:50 henry
11120+ * move sources from klips/src to klips/net/ipsec, to keep stupid
11121+ * kernel-build scripts happier in the presence of symlinks
11122+ *
11123+ * Revision 1.3 1998/05/18 21:51:50 rgb
11124+ * Added macros for num of I/F's and a procfs debug switch.
11125+ *
11126+ * Revision 1.2 1998/04/21 21:29:09 rgb
11127+ * Rearrange debug switches to change on the fly debug output from user
11128+ * space. Only kernel changes checked in at this time. radij.c was also
11129+ * changed to temporarily remove buggy debugging code in rj_delete causing
11130+ * an OOPS and hence, netlink device open errors.
11131+ *
11132+ * Revision 1.1 1998/04/09 03:06:13 henry
11133+ * sources moved up from linux/net/ipsec
11134+ *
11135+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
11136+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
11137+ *
11138+ * Revision 0.5 1997/06/03 04:24:48 ji
11139+ * Added transport mode.
11140+ * Changed the way routing is done.
11141+ * Lots of bug fixes.
11142+ *
11143+ * Revision 0.4 1997/01/15 01:28:15 ji
11144+ * No changes.
11145+ *
11146+ * Revision 0.3 1996/11/20 14:39:04 ji
11147+ * Minor cleanups.
11148+ * Rationalized debugging code.
11149+ *
11150+ * Revision 0.2 1996/11/02 00:18:33 ji
11151+ * First limited release.
11152+ *
11153+ *
11154+ */
11155diff -druN linux-noipsec/net/ipsec/ipsec_xform.c linux/net/ipsec/ipsec_xform.c
11156--- linux-noipsec/net/ipsec/ipsec_xform.c Thu Jan 1 01:00:00 1970
11157+++ linux/net/ipsec/ipsec_xform.c Mon Nov 6 05:32:08 2000
11158@@ -0,0 +1,1178 @@
11159+/*
11160+ * Common routines for IPSEC transformations.
11161+ * Copyright (C) 1996, 1997 John Ioannidis.
11162+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
11163+ *
11164+ * This program is free software; you can redistribute it and/or modify it
11165+ * under the terms of the GNU General Public License as published by the
11166+ * Free Software Foundation; either version 2 of the License, or (at your
11167+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11168+ *
11169+ * This program is distributed in the hope that it will be useful, but
11170+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11171+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11172+ * for more details.
11173+ *
11174+ * RCSID $Id$
11175+ */
11176+
11177+#include <linux/config.h>
11178+#include <linux/version.h>
11179+
11180+#include <linux/kernel.h> /* printk() */
11181+#include <linux/malloc.h> /* kmalloc() */
11182+#include <linux/errno.h> /* error codes */
11183+#include <linux/types.h> /* size_t */
11184+#include <linux/interrupt.h> /* mark_bh */
11185+
11186+#include <linux/netdevice.h> /* struct device, and other headers */
11187+#include <linux/etherdevice.h> /* eth_type_trans */
11188+#include <linux/ip.h> /* struct iphdr */
11189+#include <linux/skbuff.h>
11190+#include <linux/random.h> /* get_random_bytes() */
11191+#include <freeswan.h>
11192+#ifdef SPINLOCK
11193+#ifdef SPINLOCK_23
11194+#include <linux/spinlock.h> /* *lock* */
11195+#else /* SPINLOCK_23 */
11196+#include <asm/spinlock.h> /* *lock* */
11197+#endif /* SPINLOCK_23 */
11198+#endif /* SPINLOCK */
11199+#ifdef NET_21
11200+#include <asm/uaccess.h>
11201+#include <linux/in6.h>
11202+#endif
11203+#include <asm/checksum.h>
11204+#include <net/ip.h>
11205+
11206+#include "radij.h"
11207+#include "ipsec_encap.h"
11208+#include "ipsec_radij.h"
11209+#include "ipsec_netlink.h"
11210+#include "ipsec_xform.h"
11211+#include "ipsec_ipe4.h"
11212+#include "ipsec_ah.h"
11213+#include "ipsec_esp.h"
11214+
11215+#include <pfkeyv2.h>
11216+#include <pfkey.h>
11217+
11218+#ifdef CONFIG_IPSEC_DEBUG
11219+int debug_xform = 0;
11220+#endif /* CONFIG_IPSEC_DEBUG */
11221+
11222+#define SENDERR(_x) do { len = -(_x); goto errlab; } while (0)
11223+
11224+extern int des_set_key(caddr_t, caddr_t);
11225+
11226+struct xformsw xformsw[] = {
11227+{ XF_IP4, 0, "IPv4_Encapsulation"},
11228+{ XF_AHHMACMD5, XFT_AUTH, "HMAC_MD5_Authentication"},
11229+{ XF_AHHMACSHA1, XFT_AUTH, "HMAC_SHA-1_Authentication"},
11230+{ XF_ESP3DES, XFT_CONF, "3DES_Encryption"},
11231+{ XF_ESP3DESMD596, XFT_CONF, "3DES-MD5-96_Encryption"},
11232+{ XF_ESP3DESSHA196, XFT_CONF, "3DES-SHA1-96_Encryption"},
11233+{ XF_ESPNULLMD596, XFT_CONF, "NULL-MD5-96_ESP_*Plaintext*"},
11234+{ XF_ESPNULLSHA196, XFT_CONF, "NULL-SHA1-96_ESP_*Plaintext*"},
11235+};
11236+
11237+struct tdb *tdbh[TDB_HASHMOD];
11238+#ifdef SPINLOCK
11239+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
11240+#else /* SPINLOCK */
11241+spinlock_t tdb_lock;
11242+#endif /* SPINLOCK */
11243+struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])];
11244+
11245+int
11246+ipsec_tdbinit(void)
11247+{
11248+ int i;
11249+
11250+ for(i = 1; i < TDB_HASHMOD; i++) {
11251+ tdbh[i] = NULL;
11252+ }
11253+ return 0;
11254+}
11255+
11256+struct tdb *
11257+gettdb(struct sa_id *said)
11258+{
11259+ int hashval;
11260+ struct tdb *tdbp;
11261+ char sa[SATOA_BUF];
11262+
11263+ if(!said) {
11264+ KLIPS_PRINT(debug_xform,
11265+ "klips_error:gettdb: null pointer passed in!\n");
11266+ return NULL;
11267+ }
11268+
11269+ satoa(*said, 0, sa, SATOA_BUF);
11270+
11271+ hashval = (said->spi+said->dst.s_addr+said->proto) % TDB_HASHMOD;
11272+
11273+ KLIPS_PRINT(debug_xform,
11274+ "klips_debug:gettdb: linked entry in tdb table for hash=%d of SA:%s requested.\n",
11275+ hashval, sa);
11276+
11277+ if(!(tdbp = tdbh[hashval])) {
11278+ KLIPS_PRINT(debug_xform,
11279+ "klips_debug:gettdb: no entries in tdb table for hash=%d of SA:%s.\n",
11280+ hashval, sa);
11281+ return NULL;
11282+ }
11283+
11284+ for (; tdbp; tdbp = tdbp->tdb_hnext) {
11285+ if ((tdbp->tdb_said.spi == said->spi) &&
11286+ (tdbp->tdb_said.dst.s_addr == said->dst.s_addr) &&
11287+ (tdbp->tdb_said.proto == said->proto)) {
11288+ return tdbp;
11289+ }
11290+ }
11291+
11292+ KLIPS_PRINT(debug_xform,
11293+ "klips_debug:gettdb: no entry in linked list for hash=%d of SA:%s.\n",
11294+ hashval, sa);
11295+ return NULL;
11296+}
11297+
11298+/* void */
11299+int
11300+puttdb(struct tdb *tdbp)
11301+{
11302+ int error = 0;
11303+ unsigned int hashval;
11304+
11305+ if(!tdbp) {
11306+ KLIPS_PRINT(debug_xform,
11307+ "klips_error:puttdb: null pointer passed in!\n");
11308+ return -ENODATA;
11309+ }
11310+ hashval = ((tdbp->tdb_said.spi + tdbp->tdb_said.dst.s_addr + tdbp->tdb_said.proto) % TDB_HASHMOD);
11311+
11312+ spin_lock_bh(&tdb_lock);
11313+
11314+ tdbp->tdb_hnext = tdbh[hashval];
11315+ tdbh[hashval] = tdbp;
11316+
11317+ spin_unlock_bh(&tdb_lock);
11318+
11319+ return error;
11320+}
11321+
11322+/* This tdb better be locked before it is handed in, or races might
11323+ * happen */
11324+
11325+/* void */
11326+int
11327+deltdb(struct tdb *tdbp)
11328+{
11329+ unsigned int hashval;
11330+ struct tdb *tdbtp;
11331+ char sa[SATOA_BUF];
11332+
11333+ if(!tdbp) {
11334+ KLIPS_PRINT(debug_xform,
11335+ "klips_error:deltdb: null pointer passed in!\n");
11336+ return -ENODATA;
11337+ }
11338+
11339+ satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
11340+ if(tdbp->tdb_inext || tdbp->tdb_onext) {
11341+ KLIPS_PRINT(debug_xform,
11342+ "klips_error:deltdb: SA:%s still linked!\n",
11343+ sa);
11344+ return -EMLINK;
11345+ }
11346+
11347+ hashval = ((tdbp->tdb_said.spi + tdbp->tdb_said.dst.s_addr + tdbp->tdb_said.proto) % TDB_HASHMOD);
11348+
11349+ KLIPS_PRINT(debug_xform,
11350+ "klips_debug:deltdb: deleting SA:%s, hashval=%d.\n",
11351+ sa, hashval);
11352+ if(!tdbh[hashval]) {
11353+ KLIPS_PRINT(debug_xform,
11354+ "klips_debug:deltdb: no entries in tdb table for hash=%d of SA:%s.\n",
11355+ hashval, sa);
11356+ return -ENOENT;
11357+ }
11358+
11359+ if (tdbp == tdbh[hashval]) {
11360+ tdbh[hashval] = tdbh[hashval]->tdb_hnext;
11361+ tdbp->tdb_hnext = NULL;
11362+ KLIPS_PRINT(debug_xform,
11363+ "klips_debug:deltdb: successfully deleted first tdb in chain.\n");
11364+ return 0;
11365+ } else {
11366+ for (tdbtp = tdbh[hashval]; tdbtp; tdbtp = tdbtp->tdb_hnext) {
11367+ if (tdbtp->tdb_hnext == tdbp) {
11368+ tdbtp->tdb_hnext = tdbp->tdb_hnext;
11369+ tdbp->tdb_hnext = NULL;
11370+ KLIPS_PRINT(debug_xform,
11371+ "klips_debug:deltdb: successfully "
11372+ "deleted link in tdb chain.\n");
11373+ return 0;
11374+ }
11375+ }
11376+ }
11377+
11378+ KLIPS_PRINT(debug_xform,
11379+ "klips_debug:deltdb: no entries in linked list for hash=%d of SA:%s.\n",
11380+ hashval, sa);
11381+ return -ENOENT;
11382+}
11383+
11384+/* This tdb better be locked before it is handed in, or races might
11385+ * happen */
11386+
11387+int
11388+deltdbchain(struct tdb *tdbp)
11389+{
11390+ struct tdb *tdbdel;
11391+ int error = 0;
11392+ char sa[SATOA_BUF];
11393+
11394+ if(!tdbp) {
11395+ KLIPS_PRINT(debug_xform,
11396+ "klips_error:deltdbchain: null pointer passed in!\n");
11397+ return -ENODATA;
11398+ }
11399+
11400+ satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
11401+ KLIPS_PRINT(debug_xform,
11402+ "klips_debug:deltdbchain: passed SA:%s\n", sa);
11403+ while(tdbp->tdb_onext) {
11404+ tdbp = tdbp->tdb_onext;
11405+ }
11406+
11407+ while(tdbp) {
11408+ /* XXX send a pfkey message up to advise of deleted TDB */
11409+ satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
11410+ KLIPS_PRINT(debug_xform,
11411+ "klips_debug:deltdbchain: unlinking and delting SA:%s", sa);
11412+ tdbdel = tdbp;
11413+ tdbp = tdbp->tdb_inext;
11414+ if(tdbp) {
11415+ satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
11416+ KLIPS_PRINT(debug_xform,
11417+ ", inext=%s", sa);
11418+ tdbdel->tdb_inext = NULL;
11419+ tdbp->tdb_onext = NULL;
11420+ }
11421+ KLIPS_PRINT(debug_xform,
11422+ ".\n");
11423+ if((error = deltdb(tdbdel))) {
11424+ KLIPS_PRINT(debug_xform,
11425+ "klips_debug:deltdbchain: "
11426+ "deltdb returned error %d.\n", -error);
11427+ return error;
11428+ }
11429+ if((error = ipsec_tdbwipe(tdbdel))) {
11430+ KLIPS_PRINT(debug_xform,
11431+ "klips_debug:deltdbchain: "
11432+ "ipsec_tdbwipe returned error %d.\n", -error);
11433+ return error;
11434+ }
11435+ }
11436+ return error;
11437+}
11438+
11439+#if 0
11440+int
11441+tdb_init(struct tdb *tdbp, struct encap_msghdr *em)
11442+{
11443+ int alg;
11444+ struct xformsw *xsp;
11445+ int len;
11446+ int i;
11447+#if defined(CONFIG_IPSEC_ENC_3DES)
11448+ int error;
11449+#endif /* CONFIG_IPSEC_ENC_3DES */
11450+
11451+ char sa[SATOA_BUF];
11452+ size_t sa_len;
11453+
11454+ if(!tdbp || !em) {
11455+ KLIPS_PRINT(debug_xform,
11456+ "klips_error:tdb_init: null pointer passed in!\n");
11457+ SENDERR(ENODATA);
11458+ }
11459+
11460+ sa_len = satoa(em->em_said, 0, sa, SATOA_BUF);
11461+
11462+ KLIPS_PRINT(debug_esp,
11463+ "klips_debug:tdb_init: (algo_switch defined) called for SA:%s\n", sa);
11464+ alg = em->em_alg;
11465+
11466+ for (xsp = xformsw; xsp < xformswNXFORMSW; xsp++) {
11467+ if (xsp->xf_type == alg) {
11468+ KLIPS_PRINT(debug_netlink,
11469+ "klips_debug:tdb_init: called with tdbp=0x%p, xsp=0x%p, em=0x%p\n",
11470+ tdbp, xsp, em);
11471+ KLIPS_PRINT(debug_netlink,
11472+ "klips_debug:tdb_init: calling init routine of %s\n",
11473+ xsp->xf_name);
11474+ tdbp->tdb_xform = xsp;
11475+ tdbp->tdb_replaywin_lastseq = 0;
11476+ tdbp->tdb_replaywin_bitmap = 0;
11477+ /* check size of message here XXX */
11478+ switch(alg) {
11479+#ifdef CONFIG_IPSEC_IPIP
11480+ case XF_IP4: {
11481+ struct ipe4_xdata *xd;
11482+ xd = (struct ipe4_xdata *)(em->em_dat);
11483+
11484+ tdbp->tdb_authalg = AH_NONE;
11485+ tdbp->tdb_encalg = ESP_NONE;
11486+
11487+ if((tdbp->tdb_addr_s = (struct sockaddr*)
11488+ kmalloc((tdbp->tdb_addr_s_size = sizeof(struct sockaddr_in)),
11489+ GFP_ATOMIC)) == NULL) {
11490+ SENDERR(ENOMEM);
11491+ }
11492+ if((tdbp->tdb_addr_d = (struct sockaddr*)
11493+ kmalloc((tdbp->tdb_addr_d_size = sizeof(struct sockaddr_in)),
11494+ GFP_ATOMIC)) == NULL) {
11495+ SENDERR(ENOMEM);
11496+ }
11497+
11498+ /* might want to use a different structure here, or set sin_family and sin_port */
11499+ ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr = xd->i4_src;
11500+ ((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr = xd->i4_dst;
11501+ }
11502+ break;
11503+#endif /* !CONFIG_IPSEC_IPIP */
11504+
11505+#ifdef CONFIG_IPSEC_AH
11506+
11507+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
11508+ case XF_AHHMACMD5: {
11509+ struct ahhmacmd5_edata *ed;
11510+ unsigned char kb[AHMD596_BLKLEN];
11511+ MD5_CTX *ictx;
11512+ MD5_CTX *octx;
11513+
11514+ ed = (struct ahhmacmd5_edata *)em->em_dat;
11515+
11516+ tdbp->tdb_authalg = AH_MD5;
11517+ tdbp->tdb_encalg = ESP_NONE;
11518+
11519+ if (em->em_msglen - EMT_SETSPI_FLEN > sizeof (struct ahhmacmd5_edata))
11520+ SENDERR(EINVAL);
11521+
11522+ if (ed->ame_klen != AHMD596_KLEN) {
11523+ KLIPS_PRINT(debug_ah,
11524+ "klips_debug:tdb_init: incorrect key size: %d"
11525+ "-- must be %d octets (bytes)\n",
11526+ ed->ame_klen, AHMD596_KLEN);
11527+ SENDERR(EINVAL);
11528+ }
11529+
11530+ if (ed->ame_alen != AHMD596_ALEN) {
11531+ KLIPS_PRINT(debug_ah,
11532+ "klips_debug:tdb_init: authenticator size: %d"
11533+ " -- must be %d octets (bytes)\n",
11534+ ed->ame_alen, AHMD596_ALEN);
11535+ SENDERR(EINVAL);
11536+ }
11537+
11538+ KLIPS_PRINT(debug_ah,
11539+ "klips_debug:tdb_init: hmac md5-96 key is 0x%08x %08x %08x %08x\n",
11540+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+0)),
11541+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+1)),
11542+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+2)),
11543+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+3)));
11544+
11545+ tdbp->tdb_key_bits_a = ed->ame_klen;
11546+ tdbp->tdb_auth_bits = ed->ame_alen * 8;
11547+
11548+ if(ed->ame_ooowin > 64) {
11549+ KLIPS_PRINT(debug_ah,
11550+ "klips_debug:tdb_init: replay window size: %d"
11551+ " -- must be 0 <= size <= 64\n",
11552+ ed->ame_ooowin);
11553+ SENDERR(EINVAL);
11554+ }
11555+ tdbp->tdb_replaywin = ed->ame_ooowin;
11556+ tdbp->tdb_replaywin_lastseq = tdbp->tdb_replaywin_bitmap = 0;
11557+
11558+ if((tdbp->tdb_key_a = (caddr_t)
11559+ kmalloc((tdbp->tdb_key_a_size = sizeof(struct md5_ctx)),
11560+ GFP_ATOMIC)) == NULL) {
11561+ SENDERR(ENOMEM);
11562+ }
11563+
11564+ for (i = 0; i < ed->ame_klen; i++) {
11565+ kb[i] = ed->ame_key[i] ^ HMAC_IPAD;
11566+ }
11567+ for (; i < AHMD596_BLKLEN; i++) {
11568+ kb[i] = HMAC_IPAD;
11569+ }
11570+
11571+ ictx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->ictx);
11572+ MD5Init(ictx);
11573+ MD5Update(ictx, kb, AHMD596_BLKLEN);
11574+
11575+ for (i = 0; i < AHMD596_BLKLEN; i++)
11576+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
11577+
11578+ octx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->octx);
11579+ MD5Init(octx);
11580+ MD5Update(octx, kb, AHMD596_BLKLEN);
11581+
11582+ KLIPS_PRINT(debug_ah,
11583+ "klips_debug:tdb_init: MD5 ictx=0x%08x %08x %08x %08x"
11584+ " octx=0x%08x %08x %08x %08x\n",
11585+ ((__u32*)ictx)[0],
11586+ ((__u32*)ictx)[1],
11587+ ((__u32*)ictx)[2],
11588+ ((__u32*)ictx)[3],
11589+ ((__u32*)octx)[0],
11590+ ((__u32*)octx)[1],
11591+ ((__u32*)octx)[2],
11592+ ((__u32*)octx)[3] );
11593+
11594+ /* zero key buffer -- paranoid */
11595+ memset(kb, 0, sizeof(kb));
11596+ memset((caddr_t)&(ed->ame_key), 0, ed->ame_klen);
11597+ }
11598+ break;
11599+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
11600+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
11601+ case XF_AHHMACSHA1: {
11602+ struct ahhmacsha1_edata *ed;
11603+ unsigned char kb[AHSHA196_BLKLEN];
11604+ SHA1_CTX *ictx;
11605+ SHA1_CTX *octx;
11606+
11607+ ed = (struct ahhmacsha1_edata *)em->em_dat;
11608+
11609+ tdbp->tdb_authalg = AH_SHA;
11610+ tdbp->tdb_encalg = ESP_NONE;
11611+
11612+ if (em->em_msglen - EMT_SETSPI_FLEN > sizeof (struct ahhmacsha1_edata))
11613+ SENDERR(EINVAL);
11614+
11615+ if (ed->ame_klen != AHSHA196_KLEN) {
11616+ KLIPS_PRINT(debug_ah,
11617+ "klips_debug:tdb_init: incorrect key size: %d"
11618+ "-- must be %d octets (bytes)\n",
11619+ ed->ame_klen, AHSHA196_KLEN);
11620+ SENDERR(EINVAL);
11621+ }
11622+
11623+ if (ed->ame_alen != AHSHA196_ALEN) {
11624+ KLIPS_PRINT(debug_ah,
11625+ "klips_debug:tdb_init: authenticator size: %d"
11626+ " -- must be %d octets (bytes)\n",
11627+ ed->ame_alen, AHSHA196_ALEN);
11628+ SENDERR(EINVAL);
11629+ }
11630+
11631+ KLIPS_PRINT(debug_ah,
11632+ "klips_debug:tdb_init: hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
11633+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+0)),
11634+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+1)),
11635+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+2)),
11636+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+3)));
11637+
11638+ tdbp->tdb_key_bits_a = ed->ame_klen;
11639+ tdbp->tdb_auth_bits = ed->ame_alen * 8;
11640+
11641+ if(ed->ame_ooowin > 64) {
11642+ KLIPS_PRINT(debug_ah,
11643+ "klips_debug:tdb_init: replay window size: %d"
11644+ " -- must be 0 <= size <= 64\n",
11645+ ed->ame_ooowin);
11646+ SENDERR(EINVAL);
11647+ }
11648+ tdbp->tdb_replaywin = ed->ame_ooowin;
11649+ tdbp->tdb_replaywin_lastseq = tdbp->tdb_replaywin_bitmap = 0;
11650+
11651+ if((tdbp->tdb_key_a = (caddr_t)
11652+ kmalloc((tdbp->tdb_key_a_size = (__u16)sizeof(struct sha1_ctx)),
11653+ GFP_ATOMIC)) == NULL) {
11654+ SENDERR(ENOMEM);
11655+ }
11656+
11657+ for (i = 0; i < ed->ame_klen; i++)
11658+ kb[i] = ed->ame_key[i] ^ HMAC_IPAD;
11659+ for (; i < AHSHA196_BLKLEN; i++)
11660+ kb[i] = HMAC_IPAD;
11661+
11662+ ictx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx);
11663+ SHA1Init(ictx);
11664+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
11665+
11666+ for (i = 0; i < AHSHA196_BLKLEN; i++)
11667+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
11668+
11669+ octx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->octx);
11670+ SHA1Init(octx);
11671+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
11672+
11673+ KLIPS_PRINT(debug_ah,
11674+ "klips_debug:tdb_init: SHA1 ictx=0x%08x %08x %08x %08x"
11675+ " octx=0x%08x %08x %08x %08x\n",
11676+ ((__u32*)ictx)[0],
11677+ ((__u32*)ictx)[1],
11678+ ((__u32*)ictx)[2],
11679+ ((__u32*)ictx)[3],
11680+ ((__u32*)octx)[0],
11681+ ((__u32*)octx)[1],
11682+ ((__u32*)octx)[2],
11683+ ((__u32*)octx)[3] );
11684+
11685+ /* zero key buffer -- paranoid */
11686+ memset(kb, 0, sizeof(kb));
11687+ memset((caddr_t)&(ed->ame_key), 0, ed->ame_klen);
11688+ }
11689+ break;
11690+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
11691+
11692+#endif /* CONFIG_IPSEC_AH */
11693+
11694+#ifdef CONFIG_IPSEC_ESP
11695+#ifdef CONFIG_IPSEC_ENC_3DES
11696+ case XF_ESP3DES:
11697+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
11698+ case XF_ESP3DESMD596:
11699+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
11700+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
11701+ case XF_ESP3DESSHA196:
11702+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
11703+#endif /* CONFIG_IPSEC_ENC_3DES */
11704+#ifdef CONFIG_IPSEC_ENC_NULL
11705+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
11706+ case XF_ESPNULLMD596:
11707+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
11708+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
11709+ case XF_ESPNULLSHA196:
11710+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
11711+#endif /* CONFIG_IPSEC_ENC_NULL */
11712+ {
11713+ struct espblkrply_edata *ed;
11714+ unsigned char kb[AHMD596_BLKLEN];
11715+ ed = (struct espblkrply_edata *)em->em_dat;
11716+
11717+ KLIPS_PRINT(debug_esp,
11718+ "klips_debug:tdb_init: "
11719+ "netlink data:"
11720+ " eklen=%d"
11721+ " aklen=%d"
11722+ " flags=%d"
11723+ " ooowin=%d.\n",
11724+ ed->eme_klen,
11725+ ed->ame_klen,
11726+ ed->eme_flags,
11727+ ed->eme_ooowin);
11728+
11729+ if(ed->eme_ooowin > 64) {
11730+ KLIPS_PRINT(debug_esp,
11731+ "klips_debug:tdb_init: replay window size: %d"
11732+ "-- must be 0 <= size <= 64\n",
11733+ ed->eme_ooowin);
11734+ SENDERR(EINVAL);
11735+ }
11736+ tdbp->tdb_replaywin = ed->eme_ooowin;
11737+
11738+ switch(alg) {
11739+ case XF_ESP3DES:
11740+ case XF_ESP3DESMD596:
11741+ case XF_ESP3DESSHA196:
11742+ if((tdbp->tdb_iv = (caddr_t)
11743+ kmalloc((tdbp->tdb_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) {
11744+ SENDERR(ENOMEM);
11745+ }
11746+ get_random_bytes((void *)tdbp->tdb_iv, EMT_ESPDES_IV_SZ);
11747+ tdbp->tdb_iv_bits = tdbp->tdb_iv_size * 8;
11748+ break;
11749+ default:
11750+ }
11751+
11752+ switch(alg) {
11753+#ifdef CONFIG_IPSEC_ENC_3DES
11754+ case XF_ESP3DES:
11755+ case XF_ESP3DESMD596:
11756+ case XF_ESP3DESSHA196:
11757+ tdbp->tdb_encalg = ESP_3DES;
11758+
11759+ if (ed->eme_klen != EMT_ESP3DES_KEY_SZ) {
11760+ KLIPS_PRINT(debug_esp,
11761+ "klips_debug:tdb_init: incorrect encryption "
11762+ "key size: %d -- must be %d octets (bytes)\n",
11763+ ed->eme_klen, EMT_ESP3DES_KEY_SZ);
11764+ SENDERR(EINVAL);
11765+ }
11766+
11767+ tdbp->tdb_key_bits_e = ed->eme_klen;
11768+
11769+ if((tdbp->tdb_key_e = (caddr_t)
11770+ kmalloc((tdbp->tdb_key_e_size = 3 * sizeof(struct des_eks)),
11771+ GFP_ATOMIC)) == NULL) {
11772+ SENDERR(ENOMEM);
11773+ }
11774+
11775+ for(i = 0; i < 3; i++) {
11776+#if 0
11777+ KLIPS_PRINT(debug_esp,
11778+ "klips_debug:tdb_init: 3des key %d/3 is 0x%08lx%08lx\n",
11779+ i + 1,
11780+ ntohl(*((__u32 *)ed->eme_key + i * 2)),
11781+ ntohl(*((__u32 *)ed->eme_key + i * 2 + 1)));
11782+#endif
11783+ error = des_set_key((caddr_t)(ed->eme_key) + EMT_ESPDES_KEY_SZ * i,
11784+ (caddr_t)&((struct des_eks*)(tdbp->tdb_key_e))[i]);
11785+ if (error == -1)
11786+ printk("klips_debug:tdb_init: parity error in des key %d/3\n", i + 1);
11787+ else if (error == -2)
11788+ printk("klips_debug:tdb_init: illegal weak des key %d/3\n", i + 1);
11789+ if (error) {
11790+ memset(tdbp->tdb_key_e, 0, 3 * sizeof(struct des_eks));
11791+ kfree(tdbp->tdb_key_e);
11792+ SENDERR(EINVAL);
11793+ }
11794+ }
11795+
11796+ break;
11797+#endif /* CONFIG_IPSEC_ENC_3DES */
11798+ default:
11799+ tdbp->tdb_encalg = ESP_NULL;
11800+ }
11801+
11802+ switch(alg) {
11803+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
11804+ case XF_ESP3DESMD596:
11805+ case XF_ESPNULLMD596:
11806+ {
11807+ MD5_CTX *ictx;
11808+ MD5_CTX *octx;
11809+
11810+ tdbp->tdb_authalg = AH_MD5;
11811+
11812+ if (ed->ame_klen != AHMD596_KLEN) {
11813+ KLIPS_PRINT(debug_esp,
11814+ "klips_debug:tdb_init: incorrect authorisation "
11815+ " key size: %d -- must be %d octets (bytes)\n",
11816+ ed->ame_klen, AHMD596_KLEN);
11817+ SENDERR(EINVAL);
11818+ }
11819+
11820+ tdbp->tdb_key_bits_a = ed->ame_klen;
11821+ tdbp->tdb_auth_bits = ed->ame_klen * 8;
11822+
11823+
11824+ if((tdbp->tdb_key_a = (caddr_t)
11825+ kmalloc((tdbp->tdb_key_a_size = sizeof(struct md5_ctx)),
11826+ GFP_ATOMIC)) == NULL) {
11827+ SENDERR(ENOMEM);
11828+ }
11829+ KLIPS_PRINT(debug_esp,
11830+ "klips_debug:tdb_init: hmac md5-96 key is 0x%08x %08x %08x %08x\n",
11831+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+0)),
11832+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+1)),
11833+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+2)),
11834+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+3)));
11835+
11836+ for (i=0; i< AHMD596_KLEN; i++)
11837+ kb[i] = (*(((unsigned char *)(ed->ame_key)) + i)) ^ HMAC_IPAD;
11838+ /*
11839+ * HMAC_key is now contained in the first 128 bits of kb.
11840+ * Pad with zeroes and XOR with HMAC_IPAD to create the inner context
11841+ */
11842+ for (; i<AHMD596_BLKLEN; i++) {
11843+ kb[i] = HMAC_IPAD;
11844+ }
11845+
11846+ ictx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->ictx);
11847+ MD5Init(ictx);
11848+ MD5Update(ictx, kb, AHMD596_BLKLEN);
11849+
11850+ for (i=0; i<AHMD596_BLKLEN; i++) {
11851+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
11852+ }
11853+
11854+ octx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->octx);
11855+ MD5Init(octx);
11856+ MD5Update(octx, kb, AHMD596_BLKLEN);
11857+
11858+ KLIPS_PRINT(debug_esp,
11859+ "klips_debug:tdb_init: MD5 ictx=0x%08x %08x %08x %08x"
11860+ " octx=0x%08x %08x %08x %08x\n",
11861+ ((__u32*)ictx)[0],
11862+ ((__u32*)ictx)[1],
11863+ ((__u32*)ictx)[2],
11864+ ((__u32*)ictx)[3],
11865+ ((__u32*)octx)[0],
11866+ ((__u32*)octx)[1],
11867+ ((__u32*)octx)[2],
11868+ ((__u32*)octx)[3] );
11869+
11870+ memset(kb, 0, sizeof(kb)); /* paranoid */
11871+ memset((caddr_t)&(ed->eme_key), 0, ed->eme_klen);
11872+ memset((caddr_t)&(ed->ame_key), 0, ed->ame_klen);
11873+ break;
11874+ }
11875+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
11876+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
11877+ case XF_ESPNULLSHA196:
11878+ case XF_ESP3DESSHA196:
11879+ {
11880+ SHA1_CTX *ictx;
11881+ SHA1_CTX *octx;
11882+
11883+ tdbp->tdb_authalg = AH_SHA;
11884+
11885+ if (ed->ame_klen != AHSHA196_KLEN) {
11886+ KLIPS_PRINT(debug_esp,
11887+ "klips_debug:tdb_init: incorrect authorisation "
11888+ " key size: %d -- must be %d octets (bytes)\n",
11889+ ed->ame_klen, AHSHA196_KLEN);
11890+ SENDERR(EINVAL);
11891+ }
11892+
11893+ tdbp->tdb_key_bits_a = ed->ame_klen;
11894+ tdbp->tdb_auth_bits = ed->ame_klen * 8;
11895+
11896+ if((tdbp->tdb_key_a = (caddr_t)
11897+ kmalloc((tdbp->tdb_key_a_size = sizeof(struct sha1_ctx)),
11898+ GFP_ATOMIC)) == NULL) {
11899+ SENDERR(ENOMEM);
11900+ }
11901+ KLIPS_PRINT(debug_esp,
11902+ "klips_debug:tdb_init: hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
11903+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+0)),
11904+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+1)),
11905+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+2)),
11906+ (__u32)ntohl(*(((__u32 *)ed->ame_key)+3)));
11907+
11908+ for (i=0; i< AHSHA196_KLEN; i++)
11909+ kb[i] = (*(((unsigned char *)(ed->ame_key)) + i)) ^ HMAC_IPAD;
11910+ /*
11911+ * HMAC_key is now contained in the first 128 bits of kb.
11912+ * Pad with zeroes and XOR with HMAC_IPAD to create the inner context
11913+ */
11914+ for (; i<AHSHA196_BLKLEN; i++)
11915+ kb[i] = HMAC_IPAD;
11916+
11917+ ictx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx);
11918+ SHA1Init(ictx);
11919+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
11920+
11921+ for (i=0; i<AHSHA196_BLKLEN; i++)
11922+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
11923+
11924+ octx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->octx);
11925+ SHA1Init(octx);
11926+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
11927+
11928+ KLIPS_PRINT(debug_esp,
11929+ "klips_debug:tdb_init: SHA1 ictx=0x%08x %08x %08x %08x"
11930+ " octx=0x%08x %08x %08x %08x\n",
11931+ ((__u32*)ictx)[0],
11932+ ((__u32*)ictx)[1],
11933+ ((__u32*)ictx)[2],
11934+ ((__u32*)ictx)[3],
11935+ ((__u32*)octx)[0],
11936+ ((__u32*)octx)[1],
11937+ ((__u32*)octx)[2],
11938+ ((__u32*)octx)[3] );
11939+
11940+ memset(kb, 0, sizeof(kb)); /* paranoid */
11941+ memset((caddr_t)&(ed->eme_key), 0, ed->eme_klen);
11942+ memset((caddr_t)&(ed->ame_key), 0, ed->ame_klen);
11943+ break;
11944+ }
11945+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
11946+ case XF_ESP3DES:
11947+ tdbp->tdb_authalg = AH_NONE;
11948+ break;
11949+ default:
11950+ }
11951+ }
11952+ break;
11953+#endif /* !CONFIG_IPSEC_ESP */
11954+ default:
11955+ KLIPS_PRINT(debug_xform,
11956+ "klips_debug:tdb_init: alg=%d not configured\n", alg);
11957+ SENDERR(ESOCKTNOSUPPORT);
11958+ }
11959+ SENDERR(0);
11960+ }
11961+ }
11962+ KLIPS_PRINT(debug_xform & DB_XF_INIT,
11963+ "klips_debug:tdb_init: unregistered algorithm %d requested\n"
11964+ "klips_debug: trying to setup SA:%s\n", alg, sa);
11965+ SENDERR(EINVAL);
11966+errlab:
11967+ return len;
11968+}
11969+#endif
11970+
11971+int
11972+ipsec_tdbcleanup(__u8 proto)
11973+{
11974+ int i;
11975+ int error = 0;
11976+ struct tdb *tdbp, **tdbprev, *tdbdel;
11977+ char sa[SATOA_BUF];
11978+
11979+ KLIPS_PRINT(debug_xform,
11980+ "klips_debug:ipsec_tdbcleanup: cleaning up proto=%d.\n", proto);
11981+
11982+ spin_lock_bh(&tdb_lock);
11983+
11984+ for (i = 0; i < TDB_HASHMOD; i++) {
11985+ tdbprev = &(tdbh[i]);
11986+ tdbp = tdbh[i];
11987+ for(; tdbp;) {
11988+ satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
11989+ KLIPS_PRINT(debug_xform,
11990+ "klips_debug:ipsec_tdbcleanup: checking SA:%s, hash=%d",
11991+ sa, i);
11992+ tdbdel = tdbp;
11993+ tdbp = tdbdel->tdb_hnext;
11994+ if(tdbp) {
11995+ satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
11996+ KLIPS_PRINT(debug_xform,
11997+ ", hnext=%s", sa);
11998+ }
11999+ if(*tdbprev) {
12000+ satoa((*tdbprev)->tdb_said, 0, sa, SATOA_BUF);
12001+ KLIPS_PRINT(debug_xform,
12002+ ", *tdbprev=%s", sa);
12003+ if((*tdbprev)->tdb_hnext) {
12004+ satoa((*tdbprev)->tdb_hnext->tdb_said, 0, sa, SATOA_BUF);
12005+ KLIPS_PRINT(debug_xform,
12006+ ", *tdbprev->tdb_hnext=%s", sa);
12007+ }
12008+ }
12009+ KLIPS_PRINT(debug_xform,
12010+ ".\n");
12011+ if(!proto || (proto == tdbdel->tdb_said.proto)) {
12012+ satoa(tdbdel->tdb_said, 0, sa, SATOA_BUF);
12013+ KLIPS_PRINT(debug_xform,
12014+ "klips_debug:ipsec_tdbcleanup: deleting SA chain:%s.\n",
12015+ sa);
12016+ /* *tdbprev = tdbdel->tdb_hnext; */
12017+ if((error = deltdbchain(tdbdel))) {
12018+ goto errlab;
12019+ }
12020+ tdbprev = &(tdbh[i]);
12021+ tdbp = tdbh[i];
12022+
12023+ KLIPS_PRINT(debug_xform,
12024+ "klips_debug:ipsec_tdbcleanup: deleted SA chain:%s", sa);
12025+ if(tdbp) {
12026+ satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
12027+ KLIPS_PRINT(debug_xform,
12028+ ", tdbh[%d]=%s", i, sa);
12029+ }
12030+ if(*tdbprev) {
12031+ satoa((*tdbprev)->tdb_said, 0, sa, SATOA_BUF);
12032+ KLIPS_PRINT(debug_xform,
12033+ ", *tdbprev=%s", sa);
12034+ if((*tdbprev)->tdb_hnext) {
12035+ satoa((*tdbprev)->tdb_hnext->tdb_said, 0, sa, SATOA_BUF);
12036+ KLIPS_PRINT(debug_xform,
12037+ ", *tdbprev->tdb_hnext=%s", sa);
12038+ }
12039+ }
12040+ KLIPS_PRINT(debug_xform,
12041+ ".\n");
12042+ } else {
12043+ tdbprev = &tdbdel;
12044+ }
12045+ }
12046+ }
12047+ errlab:
12048+
12049+ spin_unlock_bh(&tdb_lock);
12050+
12051+ return(-error);
12052+}
12053+
12054+int
12055+ipsec_tdbwipe(struct tdb *tdbp)
12056+{
12057+ if(!tdbp) {
12058+ return -1;
12059+ }
12060+
12061+ if(tdbp->tdb_addr_s) {
12062+ memset((caddr_t)(tdbp->tdb_addr_s), 0, tdbp->tdb_addr_s_size);
12063+ kfree(tdbp->tdb_addr_s);
12064+ }
12065+ tdbp->tdb_addr_s = NULL;
12066+
12067+ if(tdbp->tdb_addr_d) {
12068+ memset((caddr_t)(tdbp->tdb_addr_d), 0, tdbp->tdb_addr_d_size);
12069+ kfree(tdbp->tdb_addr_d);
12070+ }
12071+ tdbp->tdb_addr_d = NULL;
12072+
12073+ if(tdbp->tdb_addr_p) {
12074+ memset((caddr_t)(tdbp->tdb_addr_p), 0, tdbp->tdb_addr_p_size);
12075+ kfree(tdbp->tdb_addr_p);
12076+ }
12077+ tdbp->tdb_addr_p = NULL;
12078+
12079+ if(tdbp->tdb_key_a) {
12080+ memset((caddr_t)(tdbp->tdb_key_a), 0, tdbp->tdb_key_a_size);
12081+ kfree(tdbp->tdb_key_a);
12082+ }
12083+ tdbp->tdb_key_a = NULL;
12084+
12085+ if(tdbp->tdb_key_e) {
12086+ memset((caddr_t)(tdbp->tdb_key_e), 0, tdbp->tdb_key_e_size);
12087+ kfree(tdbp->tdb_key_e);
12088+ }
12089+ tdbp->tdb_key_e = NULL;
12090+
12091+ if(tdbp->tdb_iv) {
12092+ memset((caddr_t)(tdbp->tdb_iv), 0, tdbp->tdb_iv_size);
12093+ kfree(tdbp->tdb_iv);
12094+ }
12095+ tdbp->tdb_iv = NULL;
12096+
12097+ if(tdbp->tdb_ident_data_s) {
12098+ memset((caddr_t)(tdbp->tdb_ident_data_s),
12099+ 0,
12100+ tdbp->tdb_ident_len_s * IPSEC_PFKEYv2_ALIGN);
12101+ kfree(tdbp->tdb_ident_data_s);
12102+ }
12103+ tdbp->tdb_ident_data_s = NULL;
12104+
12105+ if(tdbp->tdb_ident_data_d) {
12106+ memset((caddr_t)(tdbp->tdb_ident_data_d),
12107+ 0,
12108+ tdbp->tdb_ident_len_d * IPSEC_PFKEYv2_ALIGN);
12109+ kfree(tdbp->tdb_ident_data_d);
12110+ }
12111+ tdbp->tdb_ident_data_d = NULL;
12112+
12113+ memset((caddr_t)tdbp, 0, sizeof(*tdbp));
12114+ kfree(tdbp);
12115+ tdbp = NULL;
12116+
12117+ return 0;
12118+}
12119+
12120+/*
12121+ * $Log$
12122+ * Revision 1.47 2000/11/06 04:32:08 rgb
12123+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
12124+ *
12125+ * Revision 1.46 2000/09/20 16:21:57 rgb
12126+ * Cleaned up ident string alloc/free.
12127+ *
12128+ * Revision 1.45 2000/09/08 19:16:51 rgb
12129+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
12130+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
12131+ *
12132+ * Revision 1.44 2000/08/30 05:29:04 rgb
12133+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
12134+ *
12135+ * Revision 1.43 2000/08/18 21:30:41 rgb
12136+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
12137+ *
12138+ * Revision 1.42 2000/08/01 14:51:51 rgb
12139+ * Removed _all_ remaining traces of DES.
12140+ *
12141+ * Revision 1.41 2000/07/28 14:58:31 rgb
12142+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
12143+ *
12144+ * Revision 1.40 2000/06/28 05:50:11 rgb
12145+ * Actually set iv_bits.
12146+ *
12147+ * Revision 1.39 2000/05/10 23:11:09 rgb
12148+ * Added netlink debugging output.
12149+ * Added a cast to quiet down the ntohl bug.
12150+ *
12151+ * Revision 1.38 2000/05/10 19:18:42 rgb
12152+ * Cast output of ntohl so that the broken prototype doesn't make our
12153+ * compile noisy.
12154+ *
12155+ * Revision 1.37 2000/03/16 14:04:59 rgb
12156+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
12157+ *
12158+ * Revision 1.36 2000/01/26 10:11:28 rgb
12159+ * Fixed spacing in error text causing run-in words.
12160+ *
12161+ * Revision 1.35 2000/01/21 06:17:16 rgb
12162+ * Tidied up compiler directive indentation for readability.
12163+ * Added ictx,octx vars for simplification.(kravietz)
12164+ * Added macros for HMAC padding magic numbers.(kravietz)
12165+ * Fixed missing key length reporting bug.
12166+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
12167+ *
12168+ * Revision 1.34 1999/12/08 00:04:19 rgb
12169+ * Fixed SA direction overwriting bug for netlink users.
12170+ *
12171+ * Revision 1.33 1999/12/01 22:16:44 rgb
12172+ * Minor formatting changes in ESP MD5 initialisation.
12173+ *
12174+ * Revision 1.32 1999/11/25 09:06:36 rgb
12175+ * Fixed error return messages, should be returning negative numbers.
12176+ * Implemented SENDERR macro for propagating error codes.
12177+ * Added debug message and separate error code for algorithms not compiled
12178+ * in.
12179+ *
12180+ * Revision 1.31 1999/11/23 23:06:26 rgb
12181+ * Sort out pfkey and freeswan headers, putting them in a library path.
12182+ *
12183+ * Revision 1.30 1999/11/18 04:09:20 rgb
12184+ * Replaced all kernel version macros to shorter, readable form.
12185+ *
12186+ * Revision 1.29 1999/11/17 15:53:40 rgb
12187+ * Changed all occurrences of #include "../../../lib/freeswan.h"
12188+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
12189+ * klips/net/ipsec/Makefile.
12190+ *
12191+ * Revision 1.28 1999/10/18 20:04:01 rgb
12192+ * Clean-out unused cruft.
12193+ *
12194+ * Revision 1.27 1999/10/03 19:01:03 rgb
12195+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
12196+ *
12197+ * Revision 1.26 1999/10/01 16:22:24 rgb
12198+ * Switch from assignment init. to functional init. of spinlocks.
12199+ *
12200+ * Revision 1.25 1999/10/01 15:44:54 rgb
12201+ * Move spinlock header include to 2.1> scope.
12202+ *
12203+ * Revision 1.24 1999/10/01 00:03:46 rgb
12204+ * Added tdb structure locking.
12205+ * Minor formatting changes.
12206+ * Add function to initialize tdb hash table.
12207+ *
12208+ * Revision 1.23 1999/05/25 22:42:12 rgb
12209+ * Add deltdbchain() debugging.
12210+ *
12211+ * Revision 1.22 1999/05/25 21:24:31 rgb
12212+ * Add debugging statements to deltdbchain().
12213+ *
12214+ * Revision 1.21 1999/05/25 03:51:48 rgb
12215+ * Refix error return code.
12216+ *
12217+ * Revision 1.20 1999/05/25 03:34:07 rgb
12218+ * Fix error return for flush.
12219+ *
12220+ * Revision 1.19 1999/05/09 03:25:37 rgb
12221+ * Fix bug introduced by 2.2 quick-and-dirty patch.
12222+ *
12223+ * Revision 1.18 1999/05/05 22:02:32 rgb
12224+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
12225+ *
12226+ * Revision 1.17 1999/04/29 15:20:16 rgb
12227+ * Change gettdb parameter to a pointer to reduce stack loading and
12228+ * facilitate parameter sanity checking.
12229+ * Add sanity checking for null pointer arguments.
12230+ * Add debugging instrumentation.
12231+ * Add function deltdbchain() which will take care of unlinking,
12232+ * zeroing and deleting a chain of tdbs.
12233+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
12234+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
12235+ * structures.
12236+ *
12237+ * Revision 1.16 1999/04/16 15:36:29 rgb
12238+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
12239+ *
12240+ * Revision 1.15 1999/04/11 00:29:01 henry
12241+ * GPL boilerplate
12242+ *
12243+ * Revision 1.14 1999/04/06 04:54:28 rgb
12244+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
12245+ * patch shell fixes.
12246+ *
12247+ * Revision 1.13 1999/02/19 18:23:01 rgb
12248+ * Nix debug off compile warning.
12249+ *
12250+ * Revision 1.12 1999/02/17 16:52:16 rgb
12251+ * Consolidate satoa()s for space and speed efficiency.
12252+ * Convert DEBUG_IPSEC to KLIPS_PRINT
12253+ * Clean out unused cruft.
12254+ * Ditch NET_IPIP dependancy.
12255+ * Loop for 3des key setting.
12256+ *
12257+ * Revision 1.11 1999/01/26 02:09:05 rgb
12258+ * Remove ah/esp/IPIP switching on include files.
12259+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
12260+ * Removed dead code.
12261+ * Clean up debug code when switched off.
12262+ * Remove references to INET_GET_PROTOCOL.
12263+ * Added code exclusion macros to reduce code from unused algorithms.
12264+ *
12265+ * Revision 1.10 1999/01/22 06:28:55 rgb
12266+ * Cruft clean-out.
12267+ * Put random IV generation in kernel.
12268+ * Added algorithm switch code.
12269+ * Enhanced debugging.
12270+ * 64-bit clean-up.
12271+ *
12272+ * Revision 1.9 1998/11/30 13:22:55 rgb
12273+ * Rationalised all the klips kernel file headers. They are much shorter
12274+ * now and won't conflict under RH5.2.
12275+ *
12276+ * Revision 1.8 1998/11/25 04:59:06 rgb
12277+ * Add conditionals for no IPIP tunnel code.
12278+ * Delete commented out code.
12279+ *
12280+ * Revision 1.7 1998/10/31 06:50:41 rgb
12281+ * Convert xform ASCII names to no spaces.
12282+ * Fixed up comments in #endif directives.
12283+ *
12284+ * Revision 1.6 1998/10/19 14:44:28 rgb
12285+ * Added inclusion of freeswan.h.
12286+ * sa_id structure implemented and used: now includes protocol.
12287+ *
12288+ * Revision 1.5 1998/10/09 04:32:19 rgb
12289+ * Added 'klips_debug' prefix to all klips printk debug statements.
12290+ *
12291+ * Revision 1.4 1998/08/12 00:11:31 rgb
12292+ * Added new xform functions to the xform table.
12293+ * Fixed minor debug output spelling error.
12294+ *
12295+ * Revision 1.3 1998/07/09 17:45:31 rgb
12296+ * Clarify algorithm not available message.
12297+ *
12298+ * Revision 1.2 1998/06/23 03:00:51 rgb
12299+ * Check for presence of IPIP protocol if it is setup one way (we don't
12300+ * know what has been set up the other way and can only assume it will be
12301+ * symmetrical with the exception of keys).
12302+ *
12303+ * Revision 1.1 1998/06/18 21:27:51 henry
12304+ * move sources from klips/src to klips/net/ipsec, to keep stupid
12305+ * kernel-build scripts happier in the presence of symlinks
12306+ *
12307+ * Revision 1.3 1998/06/11 05:54:59 rgb
12308+ * Added transform version string pointer to xformsw initialisations.
12309+ *
12310+ * Revision 1.2 1998/04/21 21:28:57 rgb
12311+ * Rearrange debug switches to change on the fly debug output from user
12312+ * space. Only kernel changes checked in at this time. radij.c was also
12313+ * changed to temporarily remove buggy debugging code in rj_delete causing
12314+ * an OOPS and hence, netlink device open errors.
12315+ *
12316+ * Revision 1.1 1998/04/09 03:06:13 henry
12317+ * sources moved up from linux/net/ipsec
12318+ *
12319+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
12320+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
12321+ *
12322+ * Revision 0.5 1997/06/03 04:24:48 ji
12323+ * Added ESP-3DES-MD5-96
12324+ *
12325+ * Revision 0.4 1997/01/15 01:28:15 ji
12326+ * Added new transforms.
12327+ *
12328+ * Revision 0.3 1996/11/20 14:39:04 ji
12329+ * Minor cleanups.
12330+ * Rationalized debugging code.
12331+ *
12332+ * Revision 0.2 1996/11/02 00:18:33 ji
12333+ * First limited release.
12334+ *
12335+ *
12336+ */
12337diff -druN linux-noipsec/net/ipsec/ipsec_xform.h linux/net/ipsec/ipsec_xform.h
12338--- linux-noipsec/net/ipsec/ipsec_xform.h Thu Jan 1 01:00:00 1970
12339+++ linux/net/ipsec/ipsec_xform.h Mon Nov 6 05:30:40 2000
12340@@ -0,0 +1,359 @@
12341+/*
12342+ * Definitions relevant to IPSEC transformations
12343+ * Copyright (C) 1996, 1997 John Ioannidis.
12344+ * Copyright (C) 1998, 1999 Richard Guy Briggs.
12345+ *
12346+ * This program is free software; you can redistribute it and/or modify it
12347+ * under the terms of the GNU General Public License as published by the
12348+ * Free Software Foundation; either version 2 of the License, or (at your
12349+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12350+ *
12351+ * This program is distributed in the hope that it will be useful, but
12352+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12353+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12354+ * for more details.
12355+ *
12356+ * RCSID $Id$
12357+ */
12358+
12359+#include <freeswan.h>
12360+
12361+#define XF_NONE 0 /* No transform set */
12362+#define XF_IP4 1 /* IPv4 inside IPv4 */
12363+#define XF_AHMD5 2 /* AH MD5 */
12364+#define XF_AHSHA 3 /* AH SHA */
12365+#define XF_ESP3DES 5 /* ESP DES3-CBC */
12366+#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
12367+#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
12368+#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
12369+#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
12370+#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
12371+#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
12372+#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
12373+#define XF_IP6 15 /* IPv6 inside IPv6 */
12374+#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
12375+
12376+#define XF_CLR 126 /* Clear SA table */
12377+#define XF_DEL 127 /* Delete SA */
12378+
12379+/* IPsec AH transform values
12380+ * RFC 2407
12381+ * draft-ietf-ipsec-doi-tc-mib-02.txt
12382+ */
12383+
12384+#define AH_NONE 0
12385+#define AH_MD5 2
12386+#define AH_SHA 3
12387+
12388+/* IPsec ESP transform values */
12389+
12390+#define ESP_NONE 0
12391+#define ESP_3DES 3
12392+#define ESP_RC5 4
12393+#define ESP_IDEA 5
12394+#define ESP_CAST 6
12395+#define ESP_BLOWFISH 7
12396+#define ESP_3IDEA 8
12397+#define ESP_RC4 10
12398+#define ESP_NULL 11
12399+
12400+/* IPCOMP transform values */
12401+
12402+#define IPCOMP_NONE 0
12403+#define IPCOMP_OUI 1
12404+#define IPCOMP_DEFLAT 2
12405+#define IPCOMP_LZS 3
12406+#define IPCOMP_V42BIS 4
12407+
12408+#define XFT_AUTH 0x0001
12409+#define XFT_CONF 0x0100
12410+
12411+#ifdef CONFIG_IPSEC_DEBUG
12412+#define DB_XF_INIT 0x0001
12413+#endif /* CONFIG_IPSEC_DEBUG */
12414+
12415+#ifdef __KERNEL__
12416+/* 'struct tdb' should really be 64bit aligned... XXX */
12417+struct tdb /* tunnel descriptor block */
12418+{
12419+ struct tdb *tdb_hnext; /* next in hash chain */
12420+ struct tdb *tdb_onext; /* next in output */
12421+ struct tdb *tdb_inext; /* next in input (prev!) */
12422+ struct ifnet *tdb_rcvif; /* related rcv encap interface */
12423+ struct sa_id tdb_said; /* SA ID */
12424+ __u32 tdb_seq; /* seq num of msg that set this SA */
12425+ __u32 tdb_pid; /* PID of process that set this SA */
12426+ __u8 tdb_authalg; /* auth algorithm for this SA */
12427+ __u8 tdb_encalg; /* enc algorithm for this SA */
12428+
12429+ __u32 tdb_alg_errs; /* number of algorithm errors */
12430+ __u32 tdb_auth_errs; /* number of authentication errors */
12431+ __u32 tdb_encsize_errs; /* number of encryption size errors */
12432+ __u32 tdb_encpad_errs; /* number of encryption size errors */
12433+ __u32 tdb_replaywin_errs; /* number of pkt sequence errors */
12434+
12435+ __u8 tdb_replaywin; /* replay window size */
12436+ __u8 tdb_state; /* state of SA */
12437+ __u32 tdb_replaywin_lastseq; /* last pkt sequence num */
12438+ __u64 tdb_replaywin_bitmap; /* bitmap of received pkts */
12439+ __u32 tdb_replaywin_maxdiff; /* maximum pkt sequence difference */
12440+
12441+ __u32 tdb_flags; /* generic xform flags */
12442+
12443+ __u32 tdb_lifetime_allocations_c; /* see rfc2367 */
12444+ __u32 tdb_lifetime_allocations_s;
12445+ __u32 tdb_lifetime_allocations_h;
12446+ __u64 tdb_lifetime_bytes_c;
12447+ __u64 tdb_lifetime_bytes_s;
12448+ __u64 tdb_lifetime_bytes_h;
12449+ __u64 tdb_lifetime_addtime_c;
12450+ __u64 tdb_lifetime_addtime_s;
12451+ __u64 tdb_lifetime_addtime_h;
12452+ __u64 tdb_lifetime_usetime_c;
12453+ __u64 tdb_lifetime_usetime_s;
12454+ __u64 tdb_lifetime_usetime_h;
12455+ __u64 tdb_lifetime_packets_c;
12456+ __u64 tdb_lifetime_packets_s;
12457+ __u64 tdb_lifetime_packets_h;
12458+ __u64 tdb_lifetime_usetime_l; /* last time transform was used */
12459+ struct sockaddr *tdb_addr_s; /* src sockaddr */
12460+ struct sockaddr *tdb_addr_d; /* dst sockaddr */
12461+ struct sockaddr *tdb_addr_p; /* proxy sockaddr */
12462+ __u16 tdb_addr_s_size;
12463+ __u16 tdb_addr_d_size;
12464+ __u16 tdb_addr_p_size;
12465+ __u16 tdb_key_bits_a; /* size of authkey in bits */
12466+ __u16 tdb_auth_bits; /* size of authenticator in bits */
12467+ __u16 tdb_key_bits_e; /* size of enckey in bits */
12468+ __u16 tdb_iv_bits; /* size of IV in bits */
12469+
12470+ __u8 tdb_iv_size;
12471+ __u16 tdb_key_a_size;
12472+ __u16 tdb_key_e_size;
12473+ caddr_t tdb_key_a; /* authentication key */
12474+ caddr_t tdb_key_e; /* encryption key */
12475+ caddr_t tdb_iv; /* Initialisation Vector */
12476+ __u16 tdb_ident_type_s; /* src identity type */
12477+ __u16 tdb_ident_type_d; /* dst identity type */
12478+ __u64 tdb_ident_id_s; /* src identity id */
12479+ __u64 tdb_ident_id_d; /* dst identity id */
12480+ __u8 tdb_ident_len_s; /* src identity type */
12481+ __u8 tdb_ident_len_d; /* dst identity type */
12482+ caddr_t tdb_ident_data_s; /* src identity data */
12483+ caddr_t tdb_ident_data_d; /* dst identity data */
12484+#ifdef CONFIG_IPSEC_IPCOMP
12485+ __u16 tdb_comp_adapt_tries; /* ipcomp self-adaption tries */
12486+ __u16 tdb_comp_adapt_skip; /* ipcomp self-adaption to-skip */
12487+ __u64 tdb_comp_ratio_cbytes; /* compressed bytes */
12488+ __u64 tdb_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
12489+#endif /* CONFIG_IPSEC_IPCOMP */
12490+#if 0
12491+ __u32 tdb_sens_dpd;
12492+ __u8 tdb_sens_sens_level;
12493+ __u8 tdb_sens_sens_len;
12494+ __u64* tdb_sens_sens_bitmap;
12495+ __u8 tdb_sens_integ_level;
12496+ __u8 tdb_sens_integ_len;
12497+ __u64* tdb_sens_integ_bitmap;
12498+#endif
12499+};
12500+
12501+#define PROTO2TXT(x) \
12502+ (x) == IPPROTO_AH ? "AH" : \
12503+ (x) == IPPROTO_ESP ? "ESP" : \
12504+ (x) == IPPROTO_IPIP ? "IPIP" : \
12505+ (x) == IPPROTO_COMP ? "COMP" : \
12506+ "UNKNOWN_proto"
12507+
12508+#if 0
12509+ (x)->tdb_said.proto == IPPROTO_AH ? "AH" : \
12510+ (x)->tdb_said.proto == IPPROTO_ESP ? "ESP" : \
12511+ (x)->tdb_said.proto == IPPROTO_IPIP ? "IPIP" : \
12512+ (x)->tdb_said.proto == IPPROTO_COMP ? "COMP" : \
12513+ "UNKNOWN_proto", \
12514+
12515+#endif
12516+#define TDB_XFORM_NAME(x) \
12517+ PROTO2TXT((x)->tdb_said.proto), \
12518+ (x)->tdb_said.proto == IPPROTO_COMP ? \
12519+ ((x)->tdb_encalg == SADB_X_CALG_DEFLATE ? \
12520+ "_DEFLATE" : "_UNKNOWN_comp") : \
12521+ (x)->tdb_encalg == ESP_NONE ? "" : \
12522+ (x)->tdb_encalg == ESP_3DES ? "_3DES" : \
12523+ (x)->tdb_encalg == ESP_NULL ? "_NULL_encr" : \
12524+ "_UNKNOWN_encr", \
12525+ (x)->tdb_authalg == AH_NONE ? "" : \
12526+ (x)->tdb_authalg == AH_MD5 ? "_HMAC_MD5" : \
12527+ (x)->tdb_authalg == AH_SHA ? "_HMAC_SHA1" : \
12528+ "_UNKNOWN_auth" \
12529+
12530+#define TDB_HASHMOD 257
12531+
12532+struct xformsw
12533+{
12534+ u_short xf_type; /* Unique ID of xform */
12535+ u_short xf_flags; /* secondary type reall) */
12536+ char *xf_name; /* human-readable name */
12537+};
12538+
12539+extern struct tdb *tdbh[TDB_HASHMOD];
12540+extern spinlock_t tdb_lock;
12541+extern struct xformsw xformsw[], *xformswNXFORMSW;
12542+
12543+extern int ipsec_tdbinit(void);
12544+extern struct tdb *gettdb(struct sa_id*);
12545+extern /* void */ int deltdb(struct tdb *);
12546+extern /* void */ int deltdbchain(struct tdb *);
12547+extern /* void */ int puttdb(struct tdb *);
12548+extern int tdb_init(struct tdb *, struct encap_msghdr *);
12549+extern int ipsec_tdbcleanup(__u8);
12550+extern int ipsec_tdbwipe(struct tdb *);
12551+
12552+#ifdef CONFIG_IPSEC_DEBUG
12553+extern int debug_xform;
12554+#endif /* CONFIG_IPSEC_DEBUG */
12555+#endif /* __KERNEL__ */
12556+
12557+/*
12558+ * $Log$
12559+ * Revision 1.28 2000/11/06 04:30:40 rgb
12560+ * Add Svenning's adaptive content compression.
12561+ *
12562+ * Revision 1.27 2000/09/19 00:38:25 rgb
12563+ * Fixed algorithm name bugs introduced for ipcomp.
12564+ *
12565+ * Revision 1.26 2000/09/17 21:36:48 rgb
12566+ * Added proto2txt macro.
12567+ *
12568+ * Revision 1.25 2000/09/17 18:56:47 rgb
12569+ * Added IPCOMP support.
12570+ *
12571+ * Revision 1.24 2000/09/12 19:34:12 rgb
12572+ * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
12573+ *
12574+ * Revision 1.23 2000/09/12 03:23:14 rgb
12575+ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
12576+ *
12577+ * Revision 1.22 2000/09/08 19:12:56 rgb
12578+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
12579+ *
12580+ * Revision 1.21 2000/09/01 18:32:43 rgb
12581+ * Added (disabled) sensitivity members to tdb struct.
12582+ *
12583+ * Revision 1.20 2000/08/30 05:31:01 rgb
12584+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
12585+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
12586+ *
12587+ * Revision 1.19 2000/08/01 14:51:52 rgb
12588+ * Removed _all_ remaining traces of DES.
12589+ *
12590+ * Revision 1.18 2000/01/21 06:17:45 rgb
12591+ * Tidied up spacing.
12592+ *
12593+ * Revision 1.17 1999/11/17 15:53:40 rgb
12594+ * Changed all occurrences of #include "../../../lib/freeswan.h"
12595+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
12596+ * klips/net/ipsec/Makefile.
12597+ *
12598+ * Revision 1.16 1999/10/16 04:23:07 rgb
12599+ * Add stats for replaywin_errs, replaywin_max_sequence_difference,
12600+ * authentication errors, encryption size errors, encryption padding
12601+ * errors, and time since last packet.
12602+ *
12603+ * Revision 1.15 1999/10/16 00:29:11 rgb
12604+ * Added SA lifetime packet counting variables.
12605+ *
12606+ * Revision 1.14 1999/10/01 00:04:14 rgb
12607+ * Added tdb structure locking.
12608+ * Add function to initialize tdb hash table.
12609+ *
12610+ * Revision 1.13 1999/04/29 15:20:57 rgb
12611+ * dd return values to init and cleanup functions.
12612+ * Eliminate unnessessary usage of tdb_xform member to further switch
12613+ * away from the transform switch to the algorithm switch.
12614+ * Change gettdb parameter to a pointer to reduce stack loading and
12615+ * facilitate parameter sanity checking.
12616+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
12617+ *
12618+ * Revision 1.12 1999/04/15 15:37:25 rgb
12619+ * Forward check changes from POST1_00 branch.
12620+ *
12621+ * Revision 1.9.2.2 1999/04/13 20:35:57 rgb
12622+ * Fix spelling mistake in comment.
12623+ *
12624+ * Revision 1.9.2.1 1999/03/30 17:13:52 rgb
12625+ * Extend struct tdb to support pfkey.
12626+ *
12627+ * Revision 1.11 1999/04/11 00:29:01 henry
12628+ * GPL boilerplate
12629+ *
12630+ * Revision 1.10 1999/04/06 04:54:28 rgb
12631+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
12632+ * patch shell fixes.
12633+ *
12634+ * Revision 1.9 1999/01/26 02:09:31 rgb
12635+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
12636+ * Removed dead code.
12637+ *
12638+ * Revision 1.8 1999/01/22 06:29:35 rgb
12639+ * Added algorithm switch code.
12640+ * Cruft clean-out.
12641+ *
12642+ * Revision 1.7 1998/11/10 05:37:35 rgb
12643+ * Add support for SA direction flag.
12644+ *
12645+ * Revision 1.6 1998/10/19 14:44:29 rgb
12646+ * Added inclusion of freeswan.h.
12647+ * sa_id structure implemented and used: now includes protocol.
12648+ *
12649+ * Revision 1.5 1998/08/12 00:12:30 rgb
12650+ * Added macros for new xforms. Added prototypes for new xforms.
12651+ *
12652+ * Revision 1.4 1998/07/28 00:04:20 rgb
12653+ * Add macro for clearing the SA table.
12654+ *
12655+ * Revision 1.3 1998/07/14 18:06:46 rgb
12656+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
12657+ *
12658+ * Revision 1.2 1998/06/23 03:02:19 rgb
12659+ * Created a prototype for ipsec_tdbcleanup when it was moved from
12660+ * ipsec_init.c.
12661+ *
12662+ * Revision 1.1 1998/06/18 21:27:51 henry
12663+ * move sources from klips/src to klips/net/ipsec, to keep stupid
12664+ * kernel-build scripts happier in the presence of symlinks
12665+ *
12666+ * Revision 1.4 1998/06/11 05:55:31 rgb
12667+ * Added transform version string pointer to xformsw structure definition.
12668+ * Added extern declarations for transform version strings.
12669+ *
12670+ * Revision 1.3 1998/05/18 22:02:54 rgb
12671+ * Modify the *_zeroize function prototypes to include one parameter.
12672+ *
12673+ * Revision 1.2 1998/04/21 21:29:08 rgb
12674+ * Rearrange debug switches to change on the fly debug output from user
12675+ * space. Only kernel changes checked in at this time. radij.c was also
12676+ * changed to temporarily remove buggy debugging code in rj_delete causing
12677+ * an OOPS and hence, netlink device open errors.
12678+ *
12679+ * Revision 1.1 1998/04/09 03:06:14 henry
12680+ * sources moved up from linux/net/ipsec
12681+ *
12682+ * Revision 1.1.1.1 1998/04/08 05:35:06 henry
12683+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
12684+ *
12685+ * Revision 0.5 1997/06/03 04:24:48 ji
12686+ * Added ESP-3DES-MD5-96
12687+ *
12688+ * Revision 0.4 1997/01/15 01:28:15 ji
12689+ * Added new transforms.
12690+ *
12691+ * Revision 0.3 1996/11/20 14:39:04 ji
12692+ * Minor cleanups.
12693+ * Rationalized debugging code.
12694+ *
12695+ * Revision 0.2 1996/11/02 00:18:33 ji
12696+ * First limited release.
12697+ *
12698+ *
12699+ */
12700diff -druN linux-noipsec/net/ipsec/libdes/Makefile linux/net/ipsec/libdes/Makefile
12701--- linux-noipsec/net/ipsec/libdes/Makefile Thu Jan 1 01:00:00 1970
12702+++ linux/net/ipsec/libdes/Makefile Fri Dec 15 15:02:26 2000
12703@@ -0,0 +1,246 @@
12704+# You must select the correct terminal control system to be used to
12705+# turn character echo off when reading passwords. There a 5 systems
12706+# SGTTY - the old BSD system
12707+# TERMIO - most system V boxes
12708+# TERMIOS - SGI (ala IRIX).
12709+# VMS - the DEC operating system
12710+# MSDOS - we all know what it is :-)
12711+# read_pwd.c makes a reasonable guess at what is correct.
12712+
12713+# Targets
12714+# make - twidle the options yourself :-)
12715+# make cc - standard cc options
12716+# make gcc - standard gcc options
12717+# make x86-elf - linux-elf etc
12718+# make x86-out - linux-a.out, FreeBSD etc
12719+# make x86-solaris
12720+# make x86-bdsi
12721+
12722+# If you are on a DEC Alpha, edit des.h and change the DES_LONG
12723+# define to 'unsigned int'. I have seen this give a %20 speedup.
12724+
12725+OPTS0= -DLIBDES_LIT -DRAND -DTERMIO #-DNOCONST
12726+
12727+# Version 1.94 has changed the strings_to_key function so that it is
12728+# now compatible with MITs when the string is longer than 8 characters.
12729+# If you wish to keep the old version, uncomment the following line.
12730+# This will affect the -E/-D options on des(1).
12731+#OPTS1= -DOLD_STR_TO_KEY
12732+
12733+# There are 4 possible performance options
12734+# -DDES_PTR
12735+# -DDES_RISC1
12736+# -DDES_RISC2 (only one of DES_RISC1 and DES_RISC2)
12737+# -DDES_UNROLL
12738+# after the initial build, run 'des_opts' to see which options are best
12739+# for your platform. There are some listed in options.txt
12740+#OPTS2= -DDES_PTR
12741+#OPTS3= -DDES_RISC1 # or DES_RISC2
12742+#OPTS4= -DDES_UNROLL
12743+
12744+OPTS= $(OPTS0) $(OPTS1) $(OPTS2) $(OPTS3) $(OPTS4)
12745+
12746+MAKE=make -f Makefile
12747+#CC=cc
12748+#CFLAG= -O
12749+
12750+#CC=gcc
12751+#CFLAG= -O4 -funroll-loops -fomit-frame-pointer
12752+CFLAG=-fomit-frame-pointer
12753+
12754+CFLAGS=$(OPT_FLAGS) $(CFLAG)
12755+CPP=$(CC) -E
12756+AS=as
12757+
12758+# Assember version of des_encrypt*().
12759+DES_ENC=des_enc.o fcrypt_b.o # normal C version
12760+#DES_ENC=asm/dx86-elf.o asm/yx86-elf.o # elf format x86
12761+#DES_ENC=asm/dx86-out.o asm/yx86-out.o # a.out format x86
12762+#DES_ENC=asm/dx86-sol.o asm/yx86-sol.o # solaris format x86
12763+#DES_ENC=asm/dx86bsdi.o asm/yx86basi.o # bsdi format x86
12764+
12765+LIBDIR=/usr/lib
12766+BINDIR=/usr/bin
12767+INCDIR=/usr/include
12768+MANDIR=/usr/share/man
12769+MAN1=1
12770+MAN3=3
12771+SHELL=/bin/sh
12772+OBJ_LIT=cbc_enc.o ecb_enc.o $(DES_ENC) fcrypt.o set_key.o
12773+OBJ_FULL=cbc_cksm.o $(OBJ_LIT) pcbc_enc.o \
12774+ xcbc_enc.o qud_cksm.o \
12775+ cfb64ede.o cfb64enc.o cfb_enc.o ecb3_enc.o \
12776+ enc_read.o enc_writ.o ofb64ede.o ofb64enc.o ofb_enc.o \
12777+ rand_key.o read_pwd.o read2pwd.o rpc_enc.o str2key.o supp.o
12778+
12779+GENERAL_LIT=COPYRIGHT INSTALL README VERSION Makefile des_crypt.man \
12780+ des.doc options.txt asm
12781+GENERAL_FULL=$(GENERAL_LIT) FILES Imakefile times vms.com KERBEROS MODES.DES \
12782+ des.man DES.pm DES.pod DES.xs Makefile.PL dess.cpp des3s.cpp \
12783+ Makefile.uni typemap t Makefile.ssl makefile.bc Makefile.lit \
12784+ des.org des_locl.org
12785+TESTING_LIT= destest speed des_opts
12786+TESTING_FULL= rpw $(TESTING_LIT)
12787+TESTING_SRC_LIT=destest.c speed.c des_opts.c
12788+TESTING_SRC_FULL=rpw.c $(TESTING_SRC_LIT)
12789+HEADERS_LIT=des_ver.h des.h des_locl.h podd.h sk.h spr.h
12790+HEADERS_FULL= $(HEADERS_LIT) rpc_des.h
12791+LIBDES_LIT=cbc_enc.c ecb_enc.c fcrypt.c set_key.c des_enc.c fcrypt_b.c
12792+LIBDES_FULL= cbc_cksm.c pcbc_enc.c qud_cksm.c \
12793+ cfb64ede.c cfb64enc.c cfb_enc.c ecb3_enc.c \
12794+ enc_read.c enc_writ.c ofb64ede.c ofb64enc.c ofb_enc.c \
12795+ rand_key.c rpc_enc.c str2key.c supp.c \
12796+ xcbc_enc.c $(LIBDES_LIT) read_pwd.c read2pwd.c
12797+
12798+PERL= des.pl testdes.pl doIP doPC1 doPC2 PC1 PC2 shifts.pl
12799+
12800+OBJ= $(OBJ_LIT)
12801+GENERAL=$(GENERAL_LIT)
12802+TESTING=$(TESTING_LIT)
12803+TESTING_SRC=$(TESTING_SRC_LIT)
12804+HEADERS=$(HEADERS_LIT)
12805+LIBDES= $(LIBDES_LIT)
12806+
12807+ALL= $(GENERAL) $(TESTING_SRC) $(LIBDES) $(PERL) $(HEADERS)
12808+
12809+DLIB= libdes.a
12810+
12811+all: $(DLIB) $(TESTING)
12812+
12813+cc:
12814+ $(MAKE) CC=cc CFLAGS="-O $(OPTS) $(CFLAG)" all
12815+
12816+gcc:
12817+ $(MAKE) CC=gcc CFLAGS="-O3 -fomit-frame-pointer $(OPTS) $(CFLAG)" all
12818+
12819+x86-elf:
12820+ $(MAKE) DES_ENC='asm/dx86-elf.o asm/yx86-elf.o' CC='$(CC)' CFLAGS="-DELF $(OPTS) $(CFLAG)" all
12821+
12822+x86-out:
12823+ $(MAKE) DES_ENC='asm/dx86-out.o asm/yx86-out.o' CC='$(CC)' CFLAGS="-DOUT $(OPTS) $(CFLAG)" all
12824+
12825+x86-solaris:
12826+ $(MAKE) DES_ENC='asm/dx86-sol.o asm/yx86-sol.o' CC='$(CC)' CFLAGS="-DSOL $(OPTS) $(CFLAG)" all
12827+
12828+x86-bsdi:
12829+ $(MAKE) DES_ENC='asm/dx86bsdi.o asm/yx86bsdi.o' CC='$(CC)' CFLAGS="-DBSDI $(OPTS) $(CFLAG)" all
12830+
12831+# elf
12832+asm/dx86-elf.o: asm/dx86unix.cpp
12833+ $(CPP) -DELF asm/dx86unix.cpp | $(AS) -o asm/dx86-elf.o
12834+
12835+asm/yx86-elf.o: asm/yx86unix.cpp
12836+ $(CPP) -DELF asm/yx86unix.cpp | $(AS) -o asm/yx86-elf.o
12837+
12838+# solaris
12839+asm/dx86-sol.o: asm/dx86unix.cpp
12840+ $(CC) -E -DSOL asm/dx86unix.cpp | sed 's/^#.*//' > asm/dx86-sol.s
12841+ as -o asm/dx86-sol.o asm/dx86-sol.s
12842+ rm -f asm/dx86-sol.s
12843+
12844+asm/yx86-sol.o: asm/yx86unix.cpp
12845+ $(CC) -E -DSOL asm/yx86unix.cpp | sed 's/^#.*//' > asm/yx86-sol.s
12846+ as -o asm/yx86-sol.o asm/yx86-sol.s
12847+ rm -f asm/yx86-sol.s
12848+
12849+# a.out
12850+asm/dx86-out.o: asm/dx86unix.cpp
12851+ $(CPP) -DOUT asm/dx86unix.cpp | $(AS) -o asm/dx86-out.o
12852+
12853+asm/yx86-out.o: asm/yx86unix.cpp
12854+ $(CPP) -DOUT asm/yx86unix.cpp | $(AS) -o asm/yx86-out.o
12855+
12856+# bsdi
12857+asm/dx86bsdi.o: asm/dx86unix.cpp
12858+ $(CPP) -DBSDI asm/dx86unix.cpp | $(AS) -o asm/dx86bsdi.o
12859+
12860+asm/yx86bsdi.o: asm/yx86unix.cpp
12861+ $(CPP) -DBSDI asm/yx86unix.cpp | $(AS) -o asm/yx86bsdi.o
12862+
12863+asm/dx86unix.cpp:
12864+ (cd asm; perl des-586.pl cpp >dx86unix.cpp)
12865+
12866+asm/yx86unix.cpp:
12867+ (cd asm; perl crypt586.pl cpp >yx86unix.cpp)
12868+
12869+test: all
12870+ ./destest
12871+
12872+$(DLIB): $(OBJ)
12873+ /bin/rm -f $(DLIB)
12874+ ar cr $(DLIB) $(OBJ)
12875+ -if test -s /bin/ranlib; then /bin/ranlib $(DLIB); \
12876+ else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(DLIB); \
12877+ else exit 0; fi; fi
12878+
12879+des_opts: des_opts.o $(DLIB)
12880+ $(CC) $(CFLAGS) -o des_opts des_opts.o $(DLIB)
12881+
12882+destest: destest.o $(DLIB)
12883+ $(CC) $(CFLAGS) -o destest destest.o $(DLIB)
12884+
12885+rpw: rpw.o $(DLIB)
12886+ $(CC) $(CFLAGS) -o rpw rpw.o $(DLIB)
12887+
12888+speed: speed.o $(DLIB)
12889+ $(CC) $(CFLAGS) -o speed speed.o $(DLIB)
12890+
12891+des: des.o $(DLIB)
12892+ $(CC) $(CFLAGS) -o des des.o $(DLIB)
12893+
12894+tags:
12895+ ctags $(TESTING_SRC) $(LIBDES)
12896+
12897+tar_lit:
12898+ /bin/mv Makefile Makefile.tmp
12899+ /bin/cp Makefile.lit Makefile
12900+ tar chf libdes-l.tar $(LIBDES_LIT) $(HEADERS_LIT) \
12901+ $(GENERAL_LIT) $(TESTING_SRC_LIT)
12902+ /bin/rm -f Makefile
12903+ /bin/mv Makefile.tmp Makefile
12904+
12905+tar:
12906+ tar chf libdes.tar $(ALL)
12907+
12908+shar:
12909+ shar $(ALL) >libdes.shar
12910+
12911+depend:
12912+ makedepend $(LIBDES) $(TESTING_SRC)
12913+
12914+clean:
12915+ /bin/rm -f *.o tags core $(TESTING) $(DLIB) .nfs* *.old *.bak asm/*.o
12916+
12917+dclean:
12918+ sed -e '/^# DO NOT DELETE THIS LINE/ q' Makefile >Makefile.new
12919+ mv -f Makefile.new Makefile
12920+
12921+# Eric is probably going to choke when he next looks at this --tjh
12922+install:
12923+ if test $(INSTALLTOP); then \
12924+ echo SSL style install; \
12925+ cp $(DLIB) $(INSTALLTOP)/lib; \
12926+ if test -s /bin/ranlib; then \
12927+ /bin/ranlib $(INSTALLTOP)/lib/$(DLIB); \
12928+ else \
12929+ if test -s /usr/bin/ranlib; then \
12930+ /usr/bin/ranlib $(INSTALLTOP)/lib/$(DLIB); \
12931+ fi; fi; \
12932+ chmod 644 $(INSTALLTOP)/lib/$(DLIB); \
12933+ cp des.h $(INSTALLTOP)/include; \
12934+ chmod 644 $(INSTALLTOP)/include/des.h; \
12935+ else \
12936+ echo Standalone install; \
12937+ cp $(DLIB) $(DESTDIR)$(LIBDIR)/$(DLIB); \
12938+ if test -s /bin/ranlib; then \
12939+ /bin/ranlib $(DESTDIR)$(LIBDIR)/$(DLIB); \
12940+ else \
12941+ if test -s /usr/bin/ranlib; then \
12942+ /usr/bin/ranlib $(LIBDIR)/$(DLIB); \
12943+ fi; \
12944+ fi; \
12945+ cp des_crypt.man $(DESTDIR)$(MANDIR)/man$(MAN3)/des_crypt.$(MAN3); \
12946+ cp des.man $(DESTDIR)$(MANDIR)/man$(MAN1)/des.$(MAN1); \
12947+ cp des.h $(DESTDIR)$(INCDIR)/des.h; \
12948+ fi
12949+# DO NOT DELETE THIS LINE -- make depend depends on it.
12950diff -druN linux-noipsec/net/ipsec/libdes/asm/crypt586.pl linux/net/ipsec/libdes/asm/crypt586.pl
12951--- linux-noipsec/net/ipsec/libdes/asm/crypt586.pl Thu Jan 1 01:00:00 1970
12952+++ linux/net/ipsec/libdes/asm/crypt586.pl Thu Feb 18 17:41:30 1999
12953@@ -0,0 +1,204 @@
12954+#!/usr/local/bin/perl
12955+#
12956+# The inner loop instruction sequence and the IP/FP modifications are from
12957+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
12958+# I've added the stuff needed for crypt() but I've not worried about making
12959+# things perfect.
12960+#
12961+
12962+push(@INC,"perlasm","../../perlasm");
12963+require "x86asm.pl";
12964+
12965+&asm_init($ARGV[0],"crypt586.pl");
12966+
12967+$L="edi";
12968+$R="esi";
12969+
12970+&external_label("des_SPtrans");
12971+&fcrypt_body("fcrypt_body");
12972+&asm_finish();
12973+
12974+sub fcrypt_body
12975+ {
12976+ local($name,$do_ip)=@_;
12977+
12978+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
12979+
12980+ &comment("");
12981+ &comment("Load the 2 words");
12982+ $ks="ebp";
12983+
12984+ &xor( $L, $L);
12985+ &xor( $R, $R);
12986+ &mov($ks,&wparam(1));
12987+
12988+ &push(25); # add a variable
12989+
12990+ &set_label("start");
12991+ for ($i=0; $i<16; $i+=2)
12992+ {
12993+ &comment("");
12994+ &comment("Round $i");
12995+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
12996+
12997+ &comment("");
12998+ &comment("Round ".sprintf("%d",$i+1));
12999+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
13000+ }
13001+ &mov("ebx", &swtmp(0));
13002+ &mov("eax", $L);
13003+ &dec("ebx");
13004+ &mov($L, $R);
13005+ &mov($R, "eax");
13006+ &mov(&swtmp(0), "ebx");
13007+ &jnz(&label("start"));
13008+
13009+ &comment("");
13010+ &comment("FP");
13011+ &mov("edx",&wparam(0));
13012+
13013+ &FP_new($R,$L,"eax",3);
13014+ &mov(&DWP(0,"edx","",0),"eax");
13015+ &mov(&DWP(4,"edx","",0),$L);
13016+
13017+ &pop("ecx"); # remove variable
13018+
13019+ &function_end($name);
13020+ }
13021+
13022+sub D_ENCRYPT
13023+ {
13024+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
13025+
13026+ &mov( $u, &wparam(2)); # 2
13027+ &mov( $t, $R);
13028+ &shr( $t, 16); # 1
13029+ &mov( $tmp2, &wparam(3)); # 2
13030+ &xor( $t, $R); # 1
13031+
13032+ &and( $u, $t); # 2
13033+ &and( $t, $tmp2); # 2
13034+
13035+ &mov( $tmp1, $u);
13036+ &shl( $tmp1, 16); # 1
13037+ &mov( $tmp2, $t);
13038+ &shl( $tmp2, 16); # 1
13039+ &xor( $u, $tmp1); # 2
13040+ &xor( $t, $tmp2); # 2
13041+ &mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2
13042+ &xor( $u, $tmp1);
13043+ &mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2
13044+ &xor( $u, $R);
13045+ &xor( $t, $R);
13046+ &xor( $t, $tmp2);
13047+
13048+ &and( $u, "0xfcfcfcfc" ); # 2
13049+ &xor( $tmp1, $tmp1); # 1
13050+ &and( $t, "0xcfcfcfcf" ); # 2
13051+ &xor( $tmp2, $tmp2);
13052+ &movb( &LB($tmp1), &LB($u) );
13053+ &movb( &LB($tmp2), &HB($u) );
13054+ &rotr( $t, 4 );
13055+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
13056+ &movb( &LB($tmp1), &LB($t) );
13057+ &xor( $L, $ks);
13058+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
13059+ &xor( $L, $ks);
13060+ &movb( &LB($tmp2), &HB($t) );
13061+ &shr( $u, 16);
13062+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
13063+ &xor( $L, $ks);
13064+ &movb( &LB($tmp1), &HB($u) );
13065+ &shr( $t, 16);
13066+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
13067+ &xor( $L, $ks);
13068+ &mov( $ks, &wparam(1));
13069+ &movb( &LB($tmp2), &HB($t) );
13070+ &and( $u, "0xff" );
13071+ &and( $t, "0xff" );
13072+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
13073+ &xor( $L, $tmp1);
13074+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
13075+ &xor( $L, $tmp1);
13076+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
13077+ &xor( $L, $tmp1);
13078+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
13079+ &xor( $L, $tmp1);
13080+ }
13081+
13082+sub n2a
13083+ {
13084+ sprintf("%d",$_[0]);
13085+ }
13086+
13087+# now has a side affect of rotating $a by $shift
13088+sub R_PERM_OP
13089+ {
13090+ local($a,$b,$tt,$shift,$mask,$last)=@_;
13091+
13092+ &rotl( $a, $shift ) if ($shift != 0);
13093+ &mov( $tt, $a );
13094+ &xor( $a, $b );
13095+ &and( $a, $mask );
13096+ if ($notlast eq $b)
13097+ {
13098+ &xor( $b, $a );
13099+ &xor( $tt, $a );
13100+ }
13101+ else
13102+ {
13103+ &xor( $tt, $a );
13104+ &xor( $b, $a );
13105+ }
13106+ &comment("");
13107+ }
13108+
13109+sub IP_new
13110+ {
13111+ local($l,$r,$tt,$lr)=@_;
13112+
13113+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
13114+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
13115+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
13116+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
13117+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
13118+
13119+ if ($lr != 3)
13120+ {
13121+ if (($lr-3) < 0)
13122+ { &rotr($tt, 3-$lr); }
13123+ else { &rotl($tt, $lr-3); }
13124+ }
13125+ if ($lr != 2)
13126+ {
13127+ if (($lr-2) < 0)
13128+ { &rotr($r, 2-$lr); }
13129+ else { &rotl($r, $lr-2); }
13130+ }
13131+ }
13132+
13133+sub FP_new
13134+ {
13135+ local($l,$r,$tt,$lr)=@_;
13136+
13137+ if ($lr != 2)
13138+ {
13139+ if (($lr-2) < 0)
13140+ { &rotl($r, 2-$lr); }
13141+ else { &rotr($r, $lr-2); }
13142+ }
13143+ if ($lr != 3)
13144+ {
13145+ if (($lr-3) < 0)
13146+ { &rotl($l, 3-$lr); }
13147+ else { &rotr($l, $lr-3); }
13148+ }
13149+
13150+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
13151+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
13152+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
13153+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
13154+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
13155+ &rotr($tt , 4);
13156+ }
13157+
13158diff -druN linux-noipsec/net/ipsec/libdes/asm/des-586.pl linux/net/ipsec/libdes/asm/des-586.pl
13159--- linux-noipsec/net/ipsec/libdes/asm/des-586.pl Thu Jan 1 01:00:00 1970
13160+++ linux/net/ipsec/libdes/asm/des-586.pl Thu Feb 18 17:41:31 1999
13161@@ -0,0 +1,251 @@
13162+#!/usr/local/bin/perl
13163+#
13164+# The inner loop instruction sequence and the IP/FP modifications are from
13165+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
13166+#
13167+
13168+push(@INC,"perlasm","../../perlasm");
13169+require "x86asm.pl";
13170+require "cbc.pl";
13171+require "desboth.pl";
13172+
13173+# base code is in microsft
13174+# op dest, source
13175+# format.
13176+#
13177+
13178+&asm_init($ARGV[0],"des-586.pl");
13179+
13180+$L="edi";
13181+$R="esi";
13182+
13183+&external_label("des_SPtrans");
13184+&des_encrypt("des_encrypt",1);
13185+&des_encrypt("des_encrypt2",0);
13186+&des_encrypt3("des_encrypt3",1);
13187+&des_encrypt3("des_decrypt3",0);
13188+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
13189+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
13190+
13191+&asm_finish();
13192+
13193+sub des_encrypt
13194+ {
13195+ local($name,$do_ip)=@_;
13196+
13197+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
13198+
13199+ &push("esi");
13200+ &push("edi");
13201+
13202+ &comment("");
13203+ &comment("Load the 2 words");
13204+ $ks="ebp";
13205+
13206+ if ($do_ip)
13207+ {
13208+ &mov($R,&wparam(0));
13209+ &xor( "ecx", "ecx" );
13210+
13211+ &push("ebx");
13212+ &push("ebp");
13213+
13214+ &mov("eax",&DWP(0,$R,"",0));
13215+ &mov("ebx",&wparam(2)); # get encrypt flag
13216+ &mov($L,&DWP(4,$R,"",0));
13217+ &comment("");
13218+ &comment("IP");
13219+ &IP_new("eax",$L,$R,3);
13220+ }
13221+ else
13222+ {
13223+ &mov("eax",&wparam(0));
13224+ &xor( "ecx", "ecx" );
13225+
13226+ &push("ebx");
13227+ &push("ebp");
13228+
13229+ &mov($R,&DWP(0,"eax","",0));
13230+ &mov("ebx",&wparam(2)); # get encrypt flag
13231+ &rotl($R,3);
13232+ &mov($L,&DWP(4,"eax","",0));
13233+ &rotl($L,3);
13234+ }
13235+
13236+ &mov( $ks, &wparam(1) );
13237+ &cmp("ebx","0");
13238+ &je(&label("start_decrypt"));
13239+
13240+ for ($i=0; $i<16; $i+=2)
13241+ {
13242+ &comment("");
13243+ &comment("Round $i");
13244+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
13245+
13246+ &comment("");
13247+ &comment("Round ".sprintf("%d",$i+1));
13248+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
13249+ }
13250+ &jmp(&label("end"));
13251+
13252+ &set_label("start_decrypt");
13253+
13254+ for ($i=15; $i>0; $i-=2)
13255+ {
13256+ &comment("");
13257+ &comment("Round $i");
13258+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
13259+ &comment("");
13260+ &comment("Round ".sprintf("%d",$i-1));
13261+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
13262+ }
13263+
13264+ &set_label("end");
13265+
13266+ if ($do_ip)
13267+ {
13268+ &comment("");
13269+ &comment("FP");
13270+ &mov("edx",&wparam(0));
13271+ &FP_new($L,$R,"eax",3);
13272+
13273+ &mov(&DWP(0,"edx","",0),"eax");
13274+ &mov(&DWP(4,"edx","",0),$R);
13275+ }
13276+ else
13277+ {
13278+ &comment("");
13279+ &comment("Fixup");
13280+ &rotr($L,3); # r
13281+ &mov("eax",&wparam(0));
13282+ &rotr($R,3); # l
13283+ &mov(&DWP(0,"eax","",0),$L);
13284+ &mov(&DWP(4,"eax","",0),$R);
13285+ }
13286+
13287+ &pop("ebp");
13288+ &pop("ebx");
13289+ &pop("edi");
13290+ &pop("esi");
13291+ &ret();
13292+
13293+ &function_end_B($name);
13294+ }
13295+
13296+sub D_ENCRYPT
13297+ {
13298+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
13299+
13300+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
13301+ &xor( $tmp1, $tmp1);
13302+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
13303+ &xor( $u, $R);
13304+ &xor( $t, $R);
13305+ &and( $u, "0xfcfcfcfc" );
13306+ &and( $t, "0xcfcfcfcf" );
13307+ &movb( &LB($tmp1), &LB($u) );
13308+ &movb( &LB($tmp2), &HB($u) );
13309+ &rotr( $t, 4 );
13310+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
13311+ &movb( &LB($tmp1), &LB($t) );
13312+ &xor( $L, $ks);
13313+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
13314+ &xor( $L, $ks); ######
13315+ &movb( &LB($tmp2), &HB($t) );
13316+ &shr( $u, 16);
13317+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
13318+ &xor( $L, $ks); ######
13319+ &movb( &LB($tmp1), &HB($u) );
13320+ &shr( $t, 16);
13321+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
13322+ &xor( $L, $ks);
13323+ &mov( $ks, &wparam(1) );
13324+ &movb( &LB($tmp2), &HB($t) );
13325+ &and( $u, "0xff" );
13326+ &and( $t, "0xff" );
13327+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
13328+ &xor( $L, $tmp1);
13329+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
13330+ &xor( $L, $tmp1);
13331+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
13332+ &xor( $L, $tmp1);
13333+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
13334+ &xor( $L, $tmp1);
13335+ }
13336+
13337+sub n2a
13338+ {
13339+ sprintf("%d",$_[0]);
13340+ }
13341+
13342+# now has a side affect of rotating $a by $shift
13343+sub R_PERM_OP
13344+ {
13345+ local($a,$b,$tt,$shift,$mask,$last)=@_;
13346+
13347+ &rotl( $a, $shift ) if ($shift != 0);
13348+ &mov( $tt, $a );
13349+ &xor( $a, $b );
13350+ &and( $a, $mask );
13351+ if (!$last eq $b)
13352+ {
13353+ &xor( $b, $a );
13354+ &xor( $tt, $a );
13355+ }
13356+ else
13357+ {
13358+ &xor( $tt, $a );
13359+ &xor( $b, $a );
13360+ }
13361+ &comment("");
13362+ }
13363+
13364+sub IP_new
13365+ {
13366+ local($l,$r,$tt,$lr)=@_;
13367+
13368+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
13369+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
13370+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
13371+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
13372+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
13373+
13374+ if ($lr != 3)
13375+ {
13376+ if (($lr-3) < 0)
13377+ { &rotr($tt, 3-$lr); }
13378+ else { &rotl($tt, $lr-3); }
13379+ }
13380+ if ($lr != 2)
13381+ {
13382+ if (($lr-2) < 0)
13383+ { &rotr($r, 2-$lr); }
13384+ else { &rotl($r, $lr-2); }
13385+ }
13386+ }
13387+
13388+sub FP_new
13389+ {
13390+ local($l,$r,$tt,$lr)=@_;
13391+
13392+ if ($lr != 2)
13393+ {
13394+ if (($lr-2) < 0)
13395+ { &rotl($r, 2-$lr); }
13396+ else { &rotr($r, $lr-2); }
13397+ }
13398+ if ($lr != 3)
13399+ {
13400+ if (($lr-3) < 0)
13401+ { &rotl($l, 3-$lr); }
13402+ else { &rotr($l, $lr-3); }
13403+ }
13404+
13405+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
13406+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
13407+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
13408+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
13409+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
13410+ &rotr($tt , 4);
13411+ }
13412+
13413diff -druN linux-noipsec/net/ipsec/libdes/asm/des686.pl linux/net/ipsec/libdes/asm/des686.pl
13414--- linux-noipsec/net/ipsec/libdes/asm/des686.pl Thu Jan 1 01:00:00 1970
13415+++ linux/net/ipsec/libdes/asm/des686.pl Thu Feb 18 17:41:32 1999
13416@@ -0,0 +1,230 @@
13417+#!/usr/local/bin/perl
13418+
13419+$prog="des686.pl";
13420+
13421+# base code is in microsft
13422+# op dest, source
13423+# format.
13424+#
13425+
13426+# WILL NOT WORK ANYMORE WITH desboth.pl
13427+require "desboth.pl";
13428+
13429+if ( ($ARGV[0] eq "elf"))
13430+ { require "x86unix.pl"; }
13431+elsif ( ($ARGV[0] eq "a.out"))
13432+ { $aout=1; require "x86unix.pl"; }
13433+elsif ( ($ARGV[0] eq "sol"))
13434+ { $sol=1; require "x86unix.pl"; }
13435+elsif ( ($ARGV[0] eq "cpp"))
13436+ { $cpp=1; require "x86unix.pl"; }
13437+elsif ( ($ARGV[0] eq "win32"))
13438+ { require "x86ms.pl"; }
13439+else
13440+ {
13441+ print STDERR <<"EOF";
13442+Pick one target type from
13443+ elf - linux, FreeBSD etc
13444+ a.out - old linux
13445+ sol - x86 solaris
13446+ cpp - format so x86unix.cpp can be used
13447+ win32 - Windows 95/Windows NT
13448+EOF
13449+ exit(1);
13450+ }
13451+
13452+&comment("Don't even think of reading this code");
13453+&comment("It was automatically generated by $prog");
13454+&comment("Which is a perl program used to generate the x86 assember for");
13455+&comment("any of elf, a.out, Win32, or Solaris");
13456+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
13457+&comment("eric <eay\@cryptsoft.com>");
13458+&comment("");
13459+
13460+&file("dx86xxxx");
13461+
13462+$L="edi";
13463+$R="esi";
13464+
13465+&des_encrypt("des_encrypt",1);
13466+&des_encrypt("des_encrypt2",0);
13467+
13468+&des_encrypt3("des_encrypt3",1);
13469+&des_encrypt3("des_decrypt3",0);
13470+
13471+&file_end();
13472+
13473+sub des_encrypt
13474+ {
13475+ local($name,$do_ip)=@_;
13476+
13477+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
13478+
13479+ &comment("");
13480+ &comment("Load the 2 words");
13481+ &mov("eax",&wparam(0));
13482+ &mov($L,&DWP(0,"eax","",0));
13483+ &mov($R,&DWP(4,"eax","",0));
13484+
13485+ $ksp=&wparam(1);
13486+
13487+ if ($do_ip)
13488+ {
13489+ &comment("");
13490+ &comment("IP");
13491+ &IP_new($L,$R,"eax");
13492+ }
13493+
13494+ &comment("");
13495+ &comment("fixup rotate");
13496+ &rotl($R,3);
13497+ &rotl($L,3);
13498+ &exch($L,$R);
13499+
13500+ &comment("");
13501+ &comment("load counter, key_schedule and enc flag");
13502+ &mov("eax",&wparam(2)); # get encrypt flag
13503+ &mov("ebp",&wparam(1)); # get ks
13504+ &cmp("eax","0");
13505+ &je(&label("start_decrypt"));
13506+
13507+ # encrypting part
13508+
13509+ for ($i=0; $i<16; $i+=2)
13510+ {
13511+ &comment("");
13512+ &comment("Round $i");
13513+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
13514+
13515+ &comment("");
13516+ &comment("Round ".sprintf("%d",$i+1));
13517+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
13518+ }
13519+ &jmp(&label("end"));
13520+
13521+ &set_label("start_decrypt");
13522+
13523+ for ($i=15; $i>0; $i-=2)
13524+ {
13525+ &comment("");
13526+ &comment("Round $i");
13527+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
13528+ &comment("");
13529+ &comment("Round ".sprintf("%d",$i-1));
13530+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
13531+ }
13532+
13533+ &set_label("end");
13534+
13535+ &comment("");
13536+ &comment("Fixup");
13537+ &rotr($L,3); # r
13538+ &rotr($R,3); # l
13539+
13540+ if ($do_ip)
13541+ {
13542+ &comment("");
13543+ &comment("FP");
13544+ &FP_new($R,$L,"eax");
13545+ }
13546+
13547+ &mov("eax",&wparam(0));
13548+ &mov(&DWP(0,"eax","",0),$L);
13549+ &mov(&DWP(4,"eax","",0),$R);
13550+
13551+ &function_end($name);
13552+ }
13553+
13554+
13555+# The logic is to load R into 2 registers and operate on both at the same time.
13556+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
13557+# while also masking the other copy and doing a lookup. We then also accumulate the
13558+# L value in 2 registers then combine them at the end.
13559+sub D_ENCRYPT
13560+ {
13561+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
13562+
13563+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
13564+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
13565+ &xor( $u, $R );
13566+ &xor( $t, $R );
13567+ &rotr( $t, 4 );
13568+
13569+ # the numbers at the end of the line are origional instruction order
13570+ &mov( $tmp2, $u ); # 1 2
13571+ &mov( $tmp1, $t ); # 1 1
13572+ &and( $tmp2, "0xfc" ); # 1 4
13573+ &and( $tmp1, "0xfc" ); # 1 3
13574+ &shr( $t, 8 ); # 1 5
13575+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
13576+ &shr( $u, 8 ); # 1 6
13577+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
13578+
13579+ &mov( $tmp2, $u ); # 2 2
13580+ &xor( $L, $tmp1 ); # 1 9
13581+ &and( $tmp2, "0xfc" ); # 2 4
13582+ &mov( $tmp1, $t ); # 2 1
13583+ &and( $tmp1, "0xfc" ); # 2 3
13584+ &shr( $t, 8 ); # 2 5
13585+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
13586+ &shr( $u, 8 ); # 2 6
13587+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
13588+ &mov( $tmp2, $u ); # 3 2
13589+
13590+ &xor( $L, $tmp1 ); # 2 9
13591+ &and( $tmp2, "0xfc" ); # 3 4
13592+
13593+ &mov( $tmp1, $t ); # 3 1
13594+ &shr( $u, 8 ); # 3 6
13595+ &and( $tmp1, "0xfc" ); # 3 3
13596+ &shr( $t, 8 ); # 3 5
13597+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
13598+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
13599+
13600+ &and( $t, "0xfc" ); # 4 1
13601+ &xor( $L, $tmp1 ); # 3 9
13602+
13603+ &and( $u, "0xfc" ); # 4 2
13604+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
13605+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
13606+ }
13607+
13608+sub PERM_OP
13609+ {
13610+ local($a,$b,$tt,$shift,$mask)=@_;
13611+
13612+ &mov( $tt, $a );
13613+ &shr( $tt, $shift );
13614+ &xor( $tt, $b );
13615+ &and( $tt, $mask );
13616+ &xor( $b, $tt );
13617+ &shl( $tt, $shift );
13618+ &xor( $a, $tt );
13619+ }
13620+
13621+sub IP_new
13622+ {
13623+ local($l,$r,$tt)=@_;
13624+
13625+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
13626+ &PERM_OP($l,$r,$tt,16,"0x0000ffff");
13627+ &PERM_OP($r,$l,$tt, 2,"0x33333333");
13628+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
13629+ &PERM_OP($r,$l,$tt, 1,"0x55555555");
13630+ }
13631+
13632+sub FP_new
13633+ {
13634+ local($l,$r,$tt)=@_;
13635+
13636+ &PERM_OP($l,$r,$tt, 1,"0x55555555");
13637+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
13638+ &PERM_OP($l,$r,$tt, 2,"0x33333333");
13639+ &PERM_OP($r,$l,$tt,16,"0x0000ffff");
13640+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
13641+ }
13642+
13643+sub n2a
13644+ {
13645+ sprintf("%d",$_[0]);
13646+ }
13647diff -druN linux-noipsec/net/ipsec/libdes/asm/desboth.pl linux/net/ipsec/libdes/asm/desboth.pl
13648--- linux-noipsec/net/ipsec/libdes/asm/desboth.pl Thu Jan 1 01:00:00 1970
13649+++ linux/net/ipsec/libdes/asm/desboth.pl Thu Feb 18 17:41:32 1999
13650@@ -0,0 +1,79 @@
13651+#!/usr/local/bin/perl
13652+
13653+$L="edi";
13654+$R="esi";
13655+
13656+sub des_encrypt3
13657+ {
13658+ local($name,$enc)=@_;
13659+
13660+ &function_begin_B($name,"");
13661+ &push("ebx");
13662+ &mov("ebx",&wparam(0));
13663+
13664+ &push("ebp");
13665+ &push("esi");
13666+
13667+ &push("edi");
13668+
13669+ &comment("");
13670+ &comment("Load the data words");
13671+ &mov($L,&DWP(0,"ebx","",0));
13672+ &mov($R,&DWP(4,"ebx","",0));
13673+ &stack_push(3);
13674+
13675+ &comment("");
13676+ &comment("IP");
13677+ &IP_new($L,$R,"edx",0);
13678+
13679+ # put them back
13680+
13681+ if ($enc)
13682+ {
13683+ &mov(&DWP(4,"ebx","",0),$R);
13684+ &mov("eax",&wparam(1));
13685+ &mov(&DWP(0,"ebx","",0),"edx");
13686+ &mov("edi",&wparam(2));
13687+ &mov("esi",&wparam(3));
13688+ }
13689+ else
13690+ {
13691+ &mov(&DWP(4,"ebx","",0),$R);
13692+ &mov("esi",&wparam(1));
13693+ &mov(&DWP(0,"ebx","",0),"edx");
13694+ &mov("edi",&wparam(2));
13695+ &mov("eax",&wparam(3));
13696+ }
13697+ &mov(&swtmp(2), (($enc)?"1":"0"));
13698+ &mov(&swtmp(1), "eax");
13699+ &mov(&swtmp(0), "ebx");
13700+ &call("des_encrypt2");
13701+ &mov(&swtmp(2), (($enc)?"0":"1"));
13702+ &mov(&swtmp(1), "edi");
13703+ &mov(&swtmp(0), "ebx");
13704+ &call("des_encrypt2");
13705+ &mov(&swtmp(2), (($enc)?"1":"0"));
13706+ &mov(&swtmp(1), "esi");
13707+ &mov(&swtmp(0), "ebx");
13708+ &call("des_encrypt2");
13709+
13710+ &stack_pop(3);
13711+ &mov($L,&DWP(0,"ebx","",0));
13712+ &mov($R,&DWP(4,"ebx","",0));
13713+
13714+ &comment("");
13715+ &comment("FP");
13716+ &FP_new($L,$R,"eax",0);
13717+
13718+ &mov(&DWP(0,"ebx","",0),"eax");
13719+ &mov(&DWP(4,"ebx","",0),$R);
13720+
13721+ &pop("edi");
13722+ &pop("esi");
13723+ &pop("ebp");
13724+ &pop("ebx");
13725+ &ret();
13726+ &function_end_B($name);
13727+ }
13728+
13729+
13730diff -druN linux-noipsec/net/ipsec/libdes/asm/perlasm/cbc.pl linux/net/ipsec/libdes/asm/perlasm/cbc.pl
13731--- linux-noipsec/net/ipsec/libdes/asm/perlasm/cbc.pl Thu Jan 1 01:00:00 1970
13732+++ linux/net/ipsec/libdes/asm/perlasm/cbc.pl Thu Feb 18 17:41:34 1999
13733@@ -0,0 +1,342 @@
13734+#!/usr/local/bin/perl
13735+
13736+# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
13737+# des_cblock (*input);
13738+# des_cblock (*output);
13739+# long length;
13740+# des_key_schedule schedule;
13741+# des_cblock (*ivec);
13742+# int enc;
13743+#
13744+# calls
13745+# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
13746+#
13747+
13748+#&cbc("des_ncbc_encrypt","des_encrypt",0);
13749+#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
13750+# 1,4,5,3,5,-1);
13751+#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
13752+# 0,4,5,3,5,-1);
13753+#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
13754+# 0,6,7,3,4,5);
13755+#
13756+# When doing a cipher that needs bigendian order,
13757+# for encrypt, the iv is kept in bigendian form,
13758+# while for decrypt, it is kept in little endian.
13759+sub cbc
13760+ {
13761+ local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
13762+ # name is the function name
13763+ # enc_func and dec_func and the functions to call for encrypt/decrypt
13764+ # swap is true if byte order needs to be reversed
13765+ # iv_off is parameter number for the iv
13766+ # enc_off is parameter number for the encrypt/decrypt flag
13767+ # p1,p2,p3 are the offsets for parameters to be passed to the
13768+ # underlying calls.
13769+
13770+ &function_begin_B($name,"");
13771+ &comment("");
13772+
13773+ $in="esi";
13774+ $out="edi";
13775+ $count="ebp";
13776+
13777+ &push("ebp");
13778+ &push("ebx");
13779+ &push("esi");
13780+ &push("edi");
13781+
13782+ $data_off=4;
13783+ $data_off+=4 if ($p1 > 0);
13784+ $data_off+=4 if ($p2 > 0);
13785+ $data_off+=4 if ($p3 > 0);
13786+
13787+ &mov($count, &wparam(2)); # length
13788+
13789+ &comment("getting iv ptr from parameter $iv_off");
13790+ &mov("ebx", &wparam($iv_off)); # Get iv ptr
13791+
13792+ &mov($in, &DWP(0,"ebx","",0));# iv[0]
13793+ &mov($out, &DWP(4,"ebx","",0));# iv[1]
13794+
13795+ &push($out);
13796+ &push($in);
13797+ &push($out); # used in decrypt for iv[1]
13798+ &push($in); # used in decrypt for iv[0]
13799+
13800+ &mov("ebx", "esp"); # This is the address of tin[2]
13801+
13802+ &mov($in, &wparam(0)); # in
13803+ &mov($out, &wparam(1)); # out
13804+
13805+ # We have loaded them all, how lets push things
13806+ &comment("getting encrypt flag from parameter $enc_off");
13807+ &mov("ecx", &wparam($enc_off)); # Get enc flag
13808+ if ($p3 > 0)
13809+ {
13810+ &comment("get and push parameter $p3");
13811+ if ($enc_off != $p3)
13812+ { &mov("eax", &wparam($p3)); &push("eax"); }
13813+ else { &push("ecx"); }
13814+ }
13815+ if ($p2 > 0)
13816+ {
13817+ &comment("get and push parameter $p2");
13818+ if ($enc_off != $p2)
13819+ { &mov("eax", &wparam($p2)); &push("eax"); }
13820+ else { &push("ecx"); }
13821+ }
13822+ if ($p1 > 0)
13823+ {
13824+ &comment("get and push parameter $p1");
13825+ if ($enc_off != $p1)
13826+ { &mov("eax", &wparam($p1)); &push("eax"); }
13827+ else { &push("ecx"); }
13828+ }
13829+ &push("ebx"); # push data/iv
13830+
13831+ &cmp("ecx",0);
13832+ &jz(&label("decrypt"));
13833+
13834+ &and($count,0xfffffff8);
13835+ &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0]
13836+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1]
13837+
13838+ &jz(&label("encrypt_finish"));
13839+
13840+ #############################################################
13841+
13842+ &set_label("encrypt_loop");
13843+ # encrypt start
13844+ # "eax" and "ebx" hold iv (or the last cipher text)
13845+
13846+ &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes
13847+ &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes
13848+
13849+ &xor("eax", "ecx");
13850+ &xor("ebx", "edx");
13851+
13852+ &bswap("eax") if $swap;
13853+ &bswap("ebx") if $swap;
13854+
13855+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
13856+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
13857+
13858+ &call($enc_func);
13859+
13860+ &mov("eax", &DWP($data_off,"esp","",0));
13861+ &mov("ebx", &DWP($data_off+4,"esp","",0));
13862+
13863+ &bswap("eax") if $swap;
13864+ &bswap("ebx") if $swap;
13865+
13866+ &mov(&DWP(0,$out,"",0),"eax");
13867+ &mov(&DWP(4,$out,"",0),"ebx");
13868+
13869+ # eax and ebx are the next iv.
13870+
13871+ &add($in, 8);
13872+ &add($out, 8);
13873+
13874+ &sub($count, 8);
13875+ &jnz(&label("encrypt_loop"));
13876+
13877+###################################################################3
13878+ &set_label("encrypt_finish");
13879+ &mov($count, &wparam(2)); # length
13880+ &and($count, 7);
13881+ &jz(&label("finish"));
13882+ &xor("ecx","ecx");
13883+ &xor("edx","edx");
13884+ &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
13885+ &jmp_ptr($count);
13886+
13887+&set_label("ej7");
13888+ &xor("edx", "edx") if $ppro; # ppro friendly
13889+ &movb(&HB("edx"), &BP(6,$in,"",0));
13890+ &shl("edx",8);
13891+&set_label("ej6");
13892+ &movb(&HB("edx"), &BP(5,$in,"",0));
13893+&set_label("ej5");
13894+ &movb(&LB("edx"), &BP(4,$in,"",0));
13895+&set_label("ej4");
13896+ &mov("ecx", &DWP(0,$in,"",0));
13897+ &jmp(&label("ejend"));
13898+&set_label("ej3");
13899+ &movb(&HB("ecx"), &BP(2,$in,"",0));
13900+ &xor("ecx", "ecx") if $ppro; # ppro friendly
13901+ &shl("ecx",8);
13902+&set_label("ej2");
13903+ &movb(&HB("ecx"), &BP(1,$in,"",0));
13904+&set_label("ej1");
13905+ &movb(&LB("ecx"), &BP(0,$in,"",0));
13906+&set_label("ejend");
13907+
13908+ &xor("eax", "ecx");
13909+ &xor("ebx", "edx");
13910+
13911+ &bswap("eax") if $swap;
13912+ &bswap("ebx") if $swap;
13913+
13914+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
13915+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
13916+
13917+ &call($enc_func);
13918+
13919+ &mov("eax", &DWP($data_off,"esp","",0));
13920+ &mov("ebx", &DWP($data_off+4,"esp","",0));
13921+
13922+ &bswap("eax") if $swap;
13923+ &bswap("ebx") if $swap;
13924+
13925+ &mov(&DWP(0,$out,"",0),"eax");
13926+ &mov(&DWP(4,$out,"",0),"ebx");
13927+
13928+ &jmp(&label("finish"));
13929+
13930+ #############################################################
13931+ #############################################################
13932+ &set_label("decrypt",1);
13933+ # decrypt start
13934+ &and($count,0xfffffff8);
13935+ # The next 2 instructions are only for if the jz is taken
13936+ &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0]
13937+ &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1]
13938+ &jz(&label("decrypt_finish"));
13939+
13940+ &set_label("decrypt_loop");
13941+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
13942+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
13943+
13944+ &bswap("eax") if $swap;
13945+ &bswap("ebx") if $swap;
13946+
13947+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
13948+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
13949+
13950+ &call($dec_func);
13951+
13952+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
13953+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
13954+
13955+ &bswap("eax") if $swap;
13956+ &bswap("ebx") if $swap;
13957+
13958+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
13959+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
13960+
13961+ &xor("ecx", "eax");
13962+ &xor("edx", "ebx");
13963+
13964+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
13965+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
13966+
13967+ &mov(&DWP(0,$out,"",0),"ecx");
13968+ &mov(&DWP(4,$out,"",0),"edx");
13969+
13970+ &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv
13971+ &mov(&DWP($data_off+12,"esp","",0), "ebx"); #
13972+
13973+ &add($in, 8);
13974+ &add($out, 8);
13975+
13976+ &sub($count, 8);
13977+ &jnz(&label("decrypt_loop"));
13978+############################ ENDIT #######################3
13979+ &set_label("decrypt_finish");
13980+ &mov($count, &wparam(2)); # length
13981+ &and($count, 7);
13982+ &jz(&label("finish"));
13983+
13984+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
13985+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
13986+
13987+ &bswap("eax") if $swap;
13988+ &bswap("ebx") if $swap;
13989+
13990+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
13991+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
13992+
13993+ &call($dec_func);
13994+
13995+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
13996+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
13997+
13998+ &bswap("eax") if $swap;
13999+ &bswap("ebx") if $swap;
14000+
14001+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
14002+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
14003+
14004+ &xor("ecx", "eax");
14005+ &xor("edx", "ebx");
14006+
14007+ # this is for when we exit
14008+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
14009+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
14010+
14011+&set_label("dj7");
14012+ &rotr("edx", 16);
14013+ &movb(&BP(6,$out,"",0), &LB("edx"));
14014+ &shr("edx",16);
14015+&set_label("dj6");
14016+ &movb(&BP(5,$out,"",0), &HB("edx"));
14017+&set_label("dj5");
14018+ &movb(&BP(4,$out,"",0), &LB("edx"));
14019+&set_label("dj4");
14020+ &mov(&DWP(0,$out,"",0), "ecx");
14021+ &jmp(&label("djend"));
14022+&set_label("dj3");
14023+ &rotr("ecx", 16);
14024+ &movb(&BP(2,$out,"",0), &LB("ecx"));
14025+ &shl("ecx",16);
14026+&set_label("dj2");
14027+ &movb(&BP(1,$in,"",0), &HB("ecx"));
14028+&set_label("dj1");
14029+ &movb(&BP(0,$in,"",0), &LB("ecx"));
14030+&set_label("djend");
14031+
14032+ # final iv is still in eax:ebx
14033+ &jmp(&label("finish"));
14034+
14035+
14036+############################ FINISH #######################3
14037+ &set_label("finish",1);
14038+ &mov("ecx", &wparam($iv_off)); # Get iv ptr
14039+
14040+ #################################################
14041+ $total=16+4;
14042+ $total+=4 if ($p1 > 0);
14043+ $total+=4 if ($p2 > 0);
14044+ $total+=4 if ($p3 > 0);
14045+ &add("esp",$total);
14046+
14047+ &mov(&DWP(0,"ecx","",0), "eax"); # save iv
14048+ &mov(&DWP(4,"ecx","",0), "ebx"); # save iv
14049+
14050+ &function_end_A($name);
14051+
14052+ &set_label("cbc_enc_jmp_table",1);
14053+ &data_word("0");
14054+ &data_word(&label("ej1"));
14055+ &data_word(&label("ej2"));
14056+ &data_word(&label("ej3"));
14057+ &data_word(&label("ej4"));
14058+ &data_word(&label("ej5"));
14059+ &data_word(&label("ej6"));
14060+ &data_word(&label("ej7"));
14061+ &set_label("cbc_dec_jmp_table",1);
14062+ &data_word("0");
14063+ &data_word(&label("dj1"));
14064+ &data_word(&label("dj2"));
14065+ &data_word(&label("dj3"));
14066+ &data_word(&label("dj4"));
14067+ &data_word(&label("dj5"));
14068+ &data_word(&label("dj6"));
14069+ &data_word(&label("dj7"));
14070+
14071+ &function_end_B($name);
14072+
14073+ }
14074+
14075+1;
14076diff -druN linux-noipsec/net/ipsec/libdes/asm/perlasm/readme linux/net/ipsec/libdes/asm/perlasm/readme
14077--- linux-noipsec/net/ipsec/libdes/asm/perlasm/readme Thu Jan 1 01:00:00 1970
14078+++ linux/net/ipsec/libdes/asm/perlasm/readme Thu Feb 18 17:41:35 1999
14079@@ -0,0 +1,124 @@
14080+The perl scripts in this directory are my 'hack' to generate
14081+multiple different assembler formats via the one origional script.
14082+
14083+The way to use this library is to start with adding the path to this directory
14084+and then include it.
14085+
14086+push(@INC,"perlasm","../../perlasm");
14087+require "x86asm.pl";
14088+
14089+The first thing we do is setup the file and type of assember
14090+
14091+&asm_init($ARGV[0],$0);
14092+
14093+The first argument is the 'type'. Currently
14094+'cpp', 'sol', 'a.out', 'elf' or 'win32'.
14095+Argument 2 is the file name.
14096+
14097+The reciprocal function is
14098+&asm_finish() which should be called at the end.
14099+
14100+There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
14101+and x86unix.pl which is the unix (gas) version.
14102+
14103+Functions of interest are:
14104+&external_label("des_SPtrans"); declare and external variable
14105+&LB(reg); Low byte for a register
14106+&HB(reg); High byte for a register
14107+&BP(off,base,index,scale) Byte pointer addressing
14108+&DWP(off,base,index,scale) Word pointer addressing
14109+&stack_push(num) Basically a 'sub esp, num*4' with extra
14110+&stack_pop(num) inverse of stack_push
14111+&function_begin(name,extra) Start a function with pushing of
14112+ edi, esi, ebx and ebp. extra is extra win32
14113+ external info that may be required.
14114+&function_begin_B(name,extra) Same as norma function_begin but no pushing.
14115+&function_end(name) Call at end of function.
14116+&function_end_A(name) Standard pop and ret, for use inside functions
14117+&function_end_B(name) Call at end but with poping or 'ret'.
14118+&swtmp(num) Address on stack temp word.
14119+&wparam(num) Parameter number num, that was push
14120+ in C convention. This all works over pushes
14121+ and pops.
14122+&comment("hello there") Put in a comment.
14123+&label("loop") Refer to a label, normally a jmp target.
14124+&set_label("loop") Set a label at this point.
14125+&data_word(word) Put in a word of data.
14126+
14127+So how does this all hold together? Given
14128+
14129+int calc(int len, int *data)
14130+ {
14131+ int i,j=0;
14132+
14133+ for (i=0; i<len; i++)
14134+ {
14135+ j+=other(data[i]);
14136+ }
14137+ }
14138+
14139+So a very simple version of this function could be coded as
14140+
14141+ push(@INC,"perlasm","../../perlasm");
14142+ require "x86asm.pl";
14143+
14144+ &asm_init($ARGV[0],"cacl.pl");
14145+
14146+ &external_label("other");
14147+
14148+ $tmp1= "eax";
14149+ $j= "edi";
14150+ $data= "esi";
14151+ $i= "ebp";
14152+
14153+ &comment("a simple function");
14154+ &function_begin("calc");
14155+ &mov( $data, &wparam(1)); # data
14156+ &xor( $j, $j);
14157+ &xor( $i, $i);
14158+
14159+ &set_label("loop");
14160+ &cmp( $i, &wparam(0));
14161+ &jge( &label("end"));
14162+
14163+ &mov( $tmp1, &DWP(0,$data,$i,4));
14164+ &push( $tmp1);
14165+ &call( "other");
14166+ &add( $j, "eax");
14167+ &pop( $tmp1);
14168+ &inc( $i);
14169+ &jmp( &label("loop"));
14170+
14171+ &set_label("end");
14172+ &mov( "eax", $j);
14173+
14174+ &function_end("calc");
14175+
14176+ &asm_finish();
14177+
14178+The above example is very very unoptimised but gives an idea of how
14179+things work.
14180+
14181+There is also a cbc mode function generator in cbc.pl
14182+
14183+&cbc( $name,
14184+ $encrypt_function_name,
14185+ $decrypt_function_name,
14186+ $true_if_byte_swap_needed,
14187+ $parameter_number_for_iv,
14188+ $parameter_number_for_encrypt_flag,
14189+ $first_parameter_to_pass,
14190+ $second_parameter_to_pass,
14191+ $third_parameter_to_pass);
14192+
14193+So for example, given
14194+void BF_encrypt(BF_LONG *data,BF_KEY *key);
14195+void BF_decrypt(BF_LONG *data,BF_KEY *key);
14196+void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
14197+ BF_KEY *ks, unsigned char *iv, int enc);
14198+
14199+&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
14200+
14201+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
14202+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
14203+
14204diff -druN linux-noipsec/net/ipsec/libdes/asm/perlasm/x86asm.pl linux/net/ipsec/libdes/asm/perlasm/x86asm.pl
14205--- linux-noipsec/net/ipsec/libdes/asm/perlasm/x86asm.pl Thu Jan 1 01:00:00 1970
14206+++ linux/net/ipsec/libdes/asm/perlasm/x86asm.pl Thu Feb 18 17:41:35 1999
14207@@ -0,0 +1,111 @@
14208+#!/usr/local/bin/perl
14209+
14210+# require 'x86asm.pl';
14211+# &asm_init("cpp","des-586.pl");
14212+# XXX
14213+# XXX
14214+# main'asm_finish
14215+
14216+sub main'asm_finish
14217+ {
14218+ &file_end();
14219+ &asm_finish_cpp() if $cpp;
14220+ print &asm_get_output();
14221+ }
14222+
14223+sub main'asm_init
14224+ {
14225+ ($type,$fn)=@_;
14226+ $filename=$fn;
14227+
14228+ $cpp=$sol=$aout=$win32=0;
14229+ if ( ($type eq "elf"))
14230+ { require "x86unix.pl"; }
14231+ elsif ( ($type eq "a.out"))
14232+ { $aout=1; require "x86unix.pl"; }
14233+ elsif ( ($type eq "sol"))
14234+ { $sol=1; require "x86unix.pl"; }
14235+ elsif ( ($type eq "cpp"))
14236+ { $cpp=1; require "x86unix.pl"; }
14237+ elsif ( ($type eq "win32"))
14238+ { $win32=1; require "x86ms.pl"; }
14239+ else
14240+ {
14241+ print STDERR <<"EOF";
14242+Pick one target type from
14243+ elf - linux, FreeBSD etc
14244+ a.out - old linux
14245+ sol - x86 solaris
14246+ cpp - format so x86unix.cpp can be used
14247+ win32 - Windows 95/Windows NT
14248+EOF
14249+ exit(1);
14250+ }
14251+
14252+ &asm_init_output();
14253+
14254+&comment("Don't even think of reading this code");
14255+&comment("It was automatically generated by $filename");
14256+&comment("Which is a perl program used to generate the x86 assember for");
14257+&comment("any of elf, a.out, BSDI,Win32, or Solaris");
14258+&comment("eric <eay\@cryptsoft.com>");
14259+&comment("");
14260+
14261+ $filename =~ s/\.pl$//;
14262+ &file($filename);
14263+ }
14264+
14265+sub asm_finish_cpp
14266+ {
14267+ return unless $cpp;
14268+
14269+ local($tmp,$i);
14270+ foreach $i (&get_labels())
14271+ {
14272+ $tmp.="#define $i _$i\n";
14273+ }
14274+ print <<"EOF";
14275+/* Run the C pre-processor over this file with one of the following defined
14276+ * ELF - elf object files,
14277+ * OUT - a.out object files,
14278+ * BSDI - BSDI style a.out object files
14279+ * SOL - Solaris style elf
14280+ */
14281+
14282+#define TYPE(a,b) .type a,b
14283+#define SIZE(a,b) .size a,b
14284+
14285+#if defined(OUT) || defined(BSDI)
14286+$tmp
14287+#endif
14288+
14289+#ifdef OUT
14290+#define OK 1
14291+#define ALIGN 4
14292+#endif
14293+
14294+#ifdef BSDI
14295+#define OK 1
14296+#define ALIGN 4
14297+#undef SIZE
14298+#undef TYPE
14299+#endif
14300+
14301+#if defined(ELF) || defined(SOL)
14302+#define OK 1
14303+#define ALIGN 16
14304+#endif
14305+
14306+#ifndef OK
14307+You need to define one of
14308+ELF - elf systems - linux-elf, NetBSD and DG-UX
14309+OUT - a.out systems - linux-a.out and FreeBSD
14310+SOL - solaris systems, which are elf with strange comment lines
14311+BSDI - a.out with a very primative version of as.
14312+#endif
14313+
14314+/* Let the Assembler begin :-) */
14315+EOF
14316+ }
14317+
14318+1;
14319diff -druN linux-noipsec/net/ipsec/libdes/asm/perlasm/x86ms.pl linux/net/ipsec/libdes/asm/perlasm/x86ms.pl
14320--- linux-noipsec/net/ipsec/libdes/asm/perlasm/x86ms.pl Thu Jan 1 01:00:00 1970
14321+++ linux/net/ipsec/libdes/asm/perlasm/x86ms.pl Thu Feb 18 17:41:35 1999
14322@@ -0,0 +1,345 @@
14323+#!/usr/local/bin/perl
14324+
14325+package x86ms;
14326+
14327+$label="L000";
14328+
14329+%lb=( 'eax', 'al',
14330+ 'ebx', 'bl',
14331+ 'ecx', 'cl',
14332+ 'edx', 'dl',
14333+ 'ax', 'al',
14334+ 'bx', 'bl',
14335+ 'cx', 'cl',
14336+ 'dx', 'dl',
14337+ );
14338+
14339+%hb=( 'eax', 'ah',
14340+ 'ebx', 'bh',
14341+ 'ecx', 'ch',
14342+ 'edx', 'dh',
14343+ 'ax', 'ah',
14344+ 'bx', 'bh',
14345+ 'cx', 'ch',
14346+ 'dx', 'dh',
14347+ );
14348+
14349+sub main'asm_init_output { @out=(); }
14350+sub main'asm_get_output { return(@out); }
14351+sub main'get_labels { return(@labels); }
14352+sub main'external_label { push(@labels,@_); }
14353+
14354+sub main'LB
14355+ {
14356+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
14357+ return($lb{$_[0]});
14358+ }
14359+
14360+sub main'HB
14361+ {
14362+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
14363+ return($hb{$_[0]});
14364+ }
14365+
14366+sub main'BP
14367+ {
14368+ &get_mem("BYTE",@_);
14369+ }
14370+
14371+sub main'DWP
14372+ {
14373+ &get_mem("DWORD",@_);
14374+ }
14375+
14376+sub main'stack_push
14377+ {
14378+ local($num)=@_;
14379+ $stack+=$num*4;
14380+ &main'sub("esp",$num*4);
14381+ }
14382+
14383+sub main'stack_pop
14384+ {
14385+ local($num)=@_;
14386+ $stack-=$num*4;
14387+ &main'add("esp",$num*4);
14388+ }
14389+
14390+sub get_mem
14391+ {
14392+ local($size,$addr,$reg1,$reg2,$idx)=@_;
14393+ local($t,$post);
14394+ local($ret)="$size PTR ";
14395+
14396+ $addr =~ s/^\s+//;
14397+ if ($addr =~ /^(.+)\+(.+)$/)
14398+ {
14399+ $reg2=&conv($1);
14400+ $addr="_$2";
14401+ }
14402+ elsif ($addr =~ /^[_a-zA-Z]/)
14403+ {
14404+ $addr="_$addr";
14405+ }
14406+
14407+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
14408+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
14409+ if (($addr ne "") && ($addr ne 0))
14410+ {
14411+ if ($addr !~ /^-/)
14412+ { $ret.=$addr; }
14413+ else { $post=$addr; }
14414+ }
14415+ if ($reg2 ne "")
14416+ {
14417+ $t="";
14418+ $t="*$idx" if ($idx != 0);
14419+ $reg1="+".$reg1 if ("$reg1$post" ne "");
14420+ $ret.="[$reg2$t$reg1$post]";
14421+ }
14422+ else
14423+ {
14424+ $ret.="[$reg1$post]"
14425+ }
14426+ return($ret);
14427+ }
14428+
14429+sub main'mov { &out2("mov",@_); }
14430+sub main'movb { &out2("mov",@_); }
14431+sub main'and { &out2("and",@_); }
14432+sub main'or { &out2("or",@_); }
14433+sub main'shl { &out2("shl",@_); }
14434+sub main'shr { &out2("shr",@_); }
14435+sub main'xor { &out2("xor",@_); }
14436+sub main'xorb { &out2("xor",@_); }
14437+sub main'add { &out2("add",@_); }
14438+sub main'adc { &out2("adc",@_); }
14439+sub main'sub { &out2("sub",@_); }
14440+sub main'rotl { &out2("rol",@_); }
14441+sub main'rotr { &out2("ror",@_); }
14442+sub main'exch { &out2("xchg",@_); }
14443+sub main'cmp { &out2("cmp",@_); }
14444+sub main'lea { &out2("lea",@_); }
14445+sub main'mul { &out1("mul",@_); }
14446+sub main'div { &out1("div",@_); }
14447+sub main'dec { &out1("dec",@_); }
14448+sub main'inc { &out1("inc",@_); }
14449+sub main'jmp { &out1("jmp",@_); }
14450+sub main'jmp_ptr { &out1p("jmp",@_); }
14451+sub main'je { &out1("je",@_); }
14452+sub main'jle { &out1("jle",@_); }
14453+sub main'jz { &out1("jz",@_); }
14454+sub main'jge { &out1("jge",@_); }
14455+sub main'jl { &out1("jl",@_); }
14456+sub main'jb { &out1("jb",@_); }
14457+sub main'jnz { &out1("jnz",@_); }
14458+sub main'jne { &out1("jne",@_); }
14459+sub main'push { &out1("push",@_); $stack+=4; }
14460+sub main'pop { &out1("pop",@_); $stack-=4; }
14461+sub main'bswap { &out1("bswap",@_); &using486(); }
14462+sub main'not { &out1("not",@_); }
14463+sub main'call { &out1("call",'_'.$_[0]); }
14464+sub main'ret { &out0("ret"); }
14465+sub main'nop { &out0("nop"); }
14466+
14467+sub out2
14468+ {
14469+ local($name,$p1,$p2)=@_;
14470+ local($l,$t);
14471+
14472+ push(@out,"\t$name\t");
14473+ $t=&conv($p1).",";
14474+ $l=length($t);
14475+ push(@out,$t);
14476+ $l=4-($l+9)/8;
14477+ push(@out,"\t" x $l);
14478+ push(@out,&conv($p2));
14479+ push(@out,"\n");
14480+ }
14481+
14482+sub out0
14483+ {
14484+ local($name)=@_;
14485+
14486+ push(@out,"\t$name\n");
14487+ }
14488+
14489+sub out1
14490+ {
14491+ local($name,$p1)=@_;
14492+ local($l,$t);
14493+
14494+ push(@out,"\t$name\t".&conv($p1)."\n");
14495+ }
14496+
14497+sub conv
14498+ {
14499+ local($p)=@_;
14500+
14501+ $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
14502+ return $p;
14503+ }
14504+
14505+sub using486
14506+ {
14507+ return if $using486;
14508+ $using486++;
14509+ grep(s/\.386/\.486/,@out);
14510+ }
14511+
14512+sub main'file
14513+ {
14514+ local($file)=@_;
14515+
14516+ local($tmp)=<<"EOF";
14517+ TITLE $file.asm
14518+ .386
14519+.model FLAT
14520+EOF
14521+ push(@out,$tmp);
14522+ }
14523+
14524+sub main'function_begin
14525+ {
14526+ local($func,$extra)=@_;
14527+
14528+ push(@labels,$func);
14529+
14530+ local($tmp)=<<"EOF";
14531+_TEXT SEGMENT
14532+PUBLIC _$func
14533+$extra
14534+_$func PROC NEAR
14535+ push ebp
14536+ push ebx
14537+ push esi
14538+ push edi
14539+EOF
14540+ push(@out,$tmp);
14541+ $stack=20;
14542+ }
14543+
14544+sub main'function_begin_B
14545+ {
14546+ local($func,$extra)=@_;
14547+
14548+ local($tmp)=<<"EOF";
14549+_TEXT SEGMENT
14550+PUBLIC _$func
14551+$extra
14552+_$func PROC NEAR
14553+EOF
14554+ push(@out,$tmp);
14555+ $stack=4;
14556+ }
14557+
14558+sub main'function_end
14559+ {
14560+ local($func)=@_;
14561+
14562+ local($tmp)=<<"EOF";
14563+ pop edi
14564+ pop esi
14565+ pop ebx
14566+ pop ebp
14567+ ret
14568+_$func ENDP
14569+_TEXT ENDS
14570+EOF
14571+ push(@out,$tmp);
14572+ $stack=0;
14573+ %label=();
14574+ }
14575+
14576+sub main'function_end_B
14577+ {
14578+ local($func)=@_;
14579+
14580+ local($tmp)=<<"EOF";
14581+_$func ENDP
14582+_TEXT ENDS
14583+EOF
14584+ push(@out,$tmp);
14585+ $stack=0;
14586+ %label=();
14587+ }
14588+
14589+sub main'function_end_A
14590+ {
14591+ local($func)=@_;
14592+
14593+ local($tmp)=<<"EOF";
14594+ pop edi
14595+ pop esi
14596+ pop ebx
14597+ pop ebp
14598+ ret
14599+EOF
14600+ push(@out,$tmp);
14601+ }
14602+
14603+sub main'file_end
14604+ {
14605+ push(@out,"END\n");
14606+ }
14607+
14608+sub main'wparam
14609+ {
14610+ local($num)=@_;
14611+
14612+ return(&main'DWP($stack+$num*4,"esp","",0));
14613+ }
14614+
14615+sub main'swtmp
14616+ {
14617+ return(&main'DWP($_[0]*4,"esp","",0));
14618+ }
14619+
14620+# Should use swtmp, which is above esp. Linix can trash the stack above esp
14621+#sub main'wtmp
14622+# {
14623+# local($num)=@_;
14624+#
14625+# return(&main'DWP(-(($num+1)*4),"esp","",0));
14626+# }
14627+
14628+sub main'comment
14629+ {
14630+ foreach (@_)
14631+ {
14632+ push(@out,"\t; $_\n");
14633+ }
14634+ }
14635+
14636+sub main'label
14637+ {
14638+ if (!defined($label{$_[0]}))
14639+ {
14640+ $label{$_[0]}="\$${label}${_[0]}";
14641+ $label++;
14642+ }
14643+ return($label{$_[0]});
14644+ }
14645+
14646+sub main'set_label
14647+ {
14648+ if (!defined($label{$_[0]}))
14649+ {
14650+ $label{$_[0]}="${label}${_[0]}";
14651+ $label++;
14652+ }
14653+ push(@out,"$label{$_[0]}:\n");
14654+ }
14655+
14656+sub main'data_word
14657+ {
14658+ push(@out,"\tDD\t$_[0]\n");
14659+ }
14660+
14661+sub out1p
14662+ {
14663+ local($name,$p1)=@_;
14664+ local($l,$t);
14665+
14666+ push(@out,"\t$name\t ".&conv($p1)."\n");
14667+ }
14668diff -druN linux-noipsec/net/ipsec/libdes/asm/perlasm/x86unix.pl linux/net/ipsec/libdes/asm/perlasm/x86unix.pl
14669--- linux-noipsec/net/ipsec/libdes/asm/perlasm/x86unix.pl Thu Jan 1 01:00:00 1970
14670+++ linux/net/ipsec/libdes/asm/perlasm/x86unix.pl Thu Feb 18 17:41:36 1999
14671@@ -0,0 +1,403 @@
14672+#!/usr/local/bin/perl
14673+
14674+package x86unix;
14675+
14676+$label="L000";
14677+
14678+$align=($main'aout)?"4":"16";
14679+$under=($main'aout)?"_":"";
14680+$com_start=($main'sol)?"/":"#";
14681+
14682+sub main'asm_init_output { @out=(); }
14683+sub main'asm_get_output { return(@out); }
14684+sub main'get_labels { return(@labels); }
14685+sub main'external_label { push(@labels,@_); }
14686+
14687+if ($main'cpp)
14688+ {
14689+ $align="ALIGN";
14690+ $under="";
14691+ $com_start='/*';
14692+ $com_end='*/';
14693+ }
14694+
14695+%lb=( 'eax', '%al',
14696+ 'ebx', '%bl',
14697+ 'ecx', '%cl',
14698+ 'edx', '%dl',
14699+ 'ax', '%al',
14700+ 'bx', '%bl',
14701+ 'cx', '%cl',
14702+ 'dx', '%dl',
14703+ );
14704+
14705+%hb=( 'eax', '%ah',
14706+ 'ebx', '%bh',
14707+ 'ecx', '%ch',
14708+ 'edx', '%dh',
14709+ 'ax', '%ah',
14710+ 'bx', '%bh',
14711+ 'cx', '%ch',
14712+ 'dx', '%dh',
14713+ );
14714+
14715+%regs=( 'eax', '%eax',
14716+ 'ebx', '%ebx',
14717+ 'ecx', '%ecx',
14718+ 'edx', '%edx',
14719+ 'esi', '%esi',
14720+ 'edi', '%edi',
14721+ 'ebp', '%ebp',
14722+ 'esp', '%esp',
14723+ );
14724+
14725+%reg_val=(
14726+ 'eax', 0x00,
14727+ 'ebx', 0x03,
14728+ 'ecx', 0x01,
14729+ 'edx', 0x02,
14730+ 'esi', 0x06,
14731+ 'edi', 0x07,
14732+ 'ebp', 0x05,
14733+ 'esp', 0x04,
14734+ );
14735+
14736+sub main'LB
14737+ {
14738+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
14739+ return($lb{$_[0]});
14740+ }
14741+
14742+sub main'HB
14743+ {
14744+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
14745+ return($hb{$_[0]});
14746+ }
14747+
14748+sub main'DWP
14749+ {
14750+ local($addr,$reg1,$reg2,$idx)=@_;
14751+
14752+ $ret="";
14753+ $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
14754+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
14755+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
14756+ $ret.=$addr if ($addr ne "") && ($addr ne 0);
14757+ if ($reg2 ne "")
14758+ { $ret.="($reg1,$reg2,$idx)"; }
14759+ else
14760+ { $ret.="($reg1)" }
14761+ return($ret);
14762+ }
14763+
14764+sub main'BP
14765+ {
14766+ return(&main'DWP(@_));
14767+ }
14768+
14769+#sub main'BP
14770+# {
14771+# local($addr,$reg1,$reg2,$idx)=@_;
14772+#
14773+# $ret="";
14774+#
14775+# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
14776+# $reg1="$regs{$reg1}" if defined($regs{$reg1});
14777+# $reg2="$regs{$reg2}" if defined($regs{$reg2});
14778+# $ret.=$addr if ($addr ne "") && ($addr ne 0);
14779+# if ($reg2 ne "")
14780+# { $ret.="($reg1,$reg2,$idx)"; }
14781+# else
14782+# { $ret.="($reg1)" }
14783+# return($ret);
14784+# }
14785+
14786+sub main'mov { &out2("movl",@_); }
14787+sub main'movb { &out2("movb",@_); }
14788+sub main'and { &out2("andl",@_); }
14789+sub main'or { &out2("orl",@_); }
14790+sub main'shl { &out2("sall",@_); }
14791+sub main'shr { &out2("shrl",@_); }
14792+sub main'xor { &out2("xorl",@_); }
14793+sub main'xorb { &out2("xorb",@_); }
14794+sub main'add { &out2("addl",@_); }
14795+sub main'adc { &out2("adcl",@_); }
14796+sub main'sub { &out2("subl",@_); }
14797+sub main'rotl { &out2("roll",@_); }
14798+sub main'rotr { &out2("rorl",@_); }
14799+sub main'exch { &out2("xchg",@_); }
14800+sub main'cmp { &out2("cmpl",@_); }
14801+sub main'lea { &out2("leal",@_); }
14802+sub main'mul { &out1("mull",@_); }
14803+sub main'div { &out1("divl",@_); }
14804+sub main'jmp { &out1("jmp",@_); }
14805+sub main'jmp_ptr { &out1p("jmp",@_); }
14806+sub main'je { &out1("je",@_); }
14807+sub main'jle { &out1("jle",@_); }
14808+sub main'jne { &out1("jne",@_); }
14809+sub main'jnz { &out1("jnz",@_); }
14810+sub main'jz { &out1("jz",@_); }
14811+sub main'jge { &out1("jge",@_); }
14812+sub main'jl { &out1("jl",@_); }
14813+sub main'jb { &out1("jb",@_); }
14814+sub main'dec { &out1("decl",@_); }
14815+sub main'inc { &out1("incl",@_); }
14816+sub main'push { &out1("pushl",@_); $stack+=4; }
14817+sub main'pop { &out1("popl",@_); $stack-=4; }
14818+sub main'bswap { &out1("bswapl",@_); }
14819+sub main'not { &out1("notl",@_); }
14820+sub main'call { &out1("call",$under.$_[0]); }
14821+sub main'ret { &out0("ret"); }
14822+sub main'nop { &out0("nop"); }
14823+
14824+sub out2
14825+ {
14826+ local($name,$p1,$p2)=@_;
14827+ local($l,$ll,$t);
14828+ local(%special)=( "roll",0xD1C0,"rorl",0xD1C8,
14829+ "rcll",0xD1D0,"rcrl",0xD1D8,
14830+ "shll",0xD1E0,"shrl",0xD1E8,
14831+ "sarl",0xD1F8);
14832+
14833+ if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1))
14834+ {
14835+ $op=$special{$name}|$reg_val{$p1};
14836+ $tmp1=sprintf ".byte %d\n",($op>>8)&0xff;
14837+ $tmp2=sprintf ".byte %d\t",$op &0xff;
14838+ push(@out,$tmp1);
14839+ push(@out,$tmp2);
14840+
14841+ $p2=&conv($p2);
14842+ $p1=&conv($p1);
14843+ &main'comment("$name $p2 $p1");
14844+ return;
14845+ }
14846+
14847+ push(@out,"\t$name\t");
14848+ $t=&conv($p2).",";
14849+ $l=length($t);
14850+ push(@out,$t);
14851+ $ll=4-($l+9)/8;
14852+ $tmp1=sprintf "\t" x $ll;
14853+ push(@out,$tmp1);
14854+ push(@out,&conv($p1)."\n");
14855+ }
14856+
14857+sub out1
14858+ {
14859+ local($name,$p1)=@_;
14860+ local($l,$t);
14861+
14862+ push(@out,"\t$name\t".&conv($p1)."\n");
14863+ }
14864+
14865+sub out1p
14866+ {
14867+ local($name,$p1)=@_;
14868+ local($l,$t);
14869+
14870+ push(@out,"\t$name\t*".&conv($p1)."\n");
14871+ }
14872+
14873+sub out0
14874+ {
14875+ push(@out,"\t$_[0]\n");
14876+ }
14877+
14878+sub conv
14879+ {
14880+ local($p)=@_;
14881+
14882+# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
14883+
14884+ $p=$regs{$p} if (defined($regs{$p}));
14885+
14886+ $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/;
14887+ $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
14888+ return $p;
14889+ }
14890+
14891+sub main'file
14892+ {
14893+ local($file)=@_;
14894+
14895+ local($tmp)=<<"EOF";
14896+ .file "$file.s"
14897+ .version "01.01"
14898+gcc2_compiled.:
14899+EOF
14900+ push(@out,$tmp);
14901+ }
14902+
14903+sub main'function_begin
14904+ {
14905+ local($func)=@_;
14906+
14907+ $func=$under.$func;
14908+
14909+ local($tmp)=<<"EOF";
14910+.text
14911+ .align $align
14912+.globl $func
14913+EOF
14914+ push(@out,$tmp);
14915+ if ($main'cpp)
14916+ { $tmp=push(@out,"\tTYPE($func,\@function)\n"); }
14917+ else { $tmp=push(@out,"\t.type\t$func,\@function\n"); }
14918+ push(@out,"$func:\n");
14919+ $tmp=<<"EOF";
14920+ pushl %ebp
14921+ pushl %ebx
14922+ pushl %esi
14923+ pushl %edi
14924+
14925+EOF
14926+ push(@out,$tmp);
14927+ $stack=20;
14928+ }
14929+
14930+sub main'function_begin_B
14931+ {
14932+ local($func,$extra)=@_;
14933+
14934+ $func=$under.$func;
14935+
14936+ local($tmp)=<<"EOF";
14937+.text
14938+ .align $align
14939+.globl $func
14940+EOF
14941+ push(@out,$tmp);
14942+ if ($main'cpp)
14943+ { push(@out,"\tTYPE($func,\@function)\n"); }
14944+ else { push(@out,"\t.type $func,\@function\n"); }
14945+ push(@out,"$func:\n");
14946+ $stack=4;
14947+ }
14948+
14949+sub main'function_end
14950+ {
14951+ local($func)=@_;
14952+
14953+ $func=$under.$func;
14954+
14955+ local($tmp)=<<"EOF";
14956+ popl %edi
14957+ popl %esi
14958+ popl %ebx
14959+ popl %ebp
14960+ ret
14961+.${func}_end:
14962+EOF
14963+ push(@out,$tmp);
14964+ if ($main'cpp)
14965+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
14966+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
14967+ push(@out,".ident \"$func\"\n");
14968+ $stack=0;
14969+ %label=();
14970+ }
14971+
14972+sub main'function_end_A
14973+ {
14974+ local($func)=@_;
14975+
14976+ local($tmp)=<<"EOF";
14977+ popl %edi
14978+ popl %esi
14979+ popl %ebx
14980+ popl %ebp
14981+ ret
14982+EOF
14983+ push(@out,$tmp);
14984+ }
14985+
14986+sub main'function_end_B
14987+ {
14988+ local($func)=@_;
14989+
14990+ $func=$under.$func;
14991+
14992+ push(@out,".${func}_end:\n");
14993+ if ($main'cpp)
14994+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
14995+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
14996+ push(@out,".ident \"desasm.pl\"\n");
14997+ $stack=0;
14998+ %label=();
14999+ }
15000+
15001+sub main'wparam
15002+ {
15003+ local($num)=@_;
15004+
15005+ return(&main'DWP($stack+$num*4,"esp","",0));
15006+ }
15007+
15008+sub main'stack_push
15009+ {
15010+ local($num)=@_;
15011+ $stack+=$num*4;
15012+ &main'sub("esp",$num*4);
15013+ }
15014+
15015+sub main'stack_pop
15016+ {
15017+ local($num)=@_;
15018+ $stack-=$num*4;
15019+ &main'add("esp",$num*4);
15020+ }
15021+
15022+sub main'swtmp
15023+ {
15024+ return(&main'DWP($_[0]*4,"esp","",0));
15025+ }
15026+
15027+# Should use swtmp, which is above esp. Linix can trash the stack above esp
15028+#sub main'wtmp
15029+# {
15030+# local($num)=@_;
15031+#
15032+# return(&main'DWP(-($num+1)*4,"esp","",0));
15033+# }
15034+
15035+sub main'comment
15036+ {
15037+ foreach (@_)
15038+ {
15039+ if (/^\s*$/)
15040+ { push(@out,"\n"); }
15041+ else
15042+ { push(@out,"\t$com_start $_ $com_end\n"); }
15043+ }
15044+ }
15045+
15046+sub main'label
15047+ {
15048+ if (!defined($label{$_[0]}))
15049+ {
15050+ $label{$_[0]}=".${label}${_[0]}";
15051+ $label++;
15052+ }
15053+ return($label{$_[0]});
15054+ }
15055+
15056+sub main'set_label
15057+ {
15058+ if (!defined($label{$_[0]}))
15059+ {
15060+ $label{$_[0]}=".${label}${_[0]}";
15061+ $label++;
15062+ }
15063+ push(@out,".align $align\n") if ($_[1] != 0);
15064+ push(@out,"$label{$_[0]}:\n");
15065+ }
15066+
15067+sub main'file_end
15068+ {
15069+ }
15070+
15071+sub main'data_word
15072+ {
15073+ push(@out,"\t.long $_[0]\n");
15074+ }
15075diff -druN linux-noipsec/net/ipsec/libdes/cbc_enc.c linux/net/ipsec/libdes/cbc_enc.c
15076--- linux-noipsec/net/ipsec/libdes/cbc_enc.c Thu Jan 1 01:00:00 1970
15077+++ linux/net/ipsec/libdes/cbc_enc.c Thu Feb 18 17:41:10 1999
15078@@ -0,0 +1,135 @@
15079+/* crypto/des/cbc_enc.c */
15080+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
15081+ * All rights reserved.
15082+ *
15083+ * This package is an SSL implementation written
15084+ * by Eric Young (eay@cryptsoft.com).
15085+ * The implementation was written so as to conform with Netscapes SSL.
15086+ *
15087+ * This library is free for commercial and non-commercial use as long as
15088+ * the following conditions are aheared to. The following conditions
15089+ * apply to all code found in this distribution, be it the RC4, RSA,
15090+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
15091+ * included with this distribution is covered by the same copyright terms
15092+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15093+ *
15094+ * Copyright remains Eric Young's, and as such any Copyright notices in
15095+ * the code are not to be removed.
15096+ * If this package is used in a product, Eric Young should be given attribution
15097+ * as the author of the parts of the library used.
15098+ * This can be in the form of a textual message at program startup or
15099+ * in documentation (online or textual) provided with the package.
15100+ *
15101+ * Redistribution and use in source and binary forms, with or without
15102+ * modification, are permitted provided that the following conditions
15103+ * are met:
15104+ * 1. Redistributions of source code must retain the copyright
15105+ * notice, this list of conditions and the following disclaimer.
15106+ * 2. Redistributions in binary form must reproduce the above copyright
15107+ * notice, this list of conditions and the following disclaimer in the
15108+ * documentation and/or other materials provided with the distribution.
15109+ * 3. All advertising materials mentioning features or use of this software
15110+ * must display the following acknowledgement:
15111+ * "This product includes cryptographic software written by
15112+ * Eric Young (eay@cryptsoft.com)"
15113+ * The word 'cryptographic' can be left out if the rouines from the library
15114+ * being used are not cryptographic related :-).
15115+ * 4. If you include any Windows specific code (or a derivative thereof) from
15116+ * the apps directory (application code) you must include an acknowledgement:
15117+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
15118+ *
15119+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
15120+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15121+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15122+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15123+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15124+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
15125+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15126+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
15127+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15128+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
15129+ * SUCH DAMAGE.
15130+ *
15131+ * The licence and distribution terms for any publically available version or
15132+ * derivative of this code cannot be changed. i.e. this code cannot simply be
15133+ * copied and put under another distribution licence
15134+ * [including the GNU Public Licence.]
15135+ */
15136+
15137+#include "des_locl.h"
15138+
15139+void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
15140+des_cblock (*input);
15141+des_cblock (*output);
15142+long length;
15143+des_key_schedule schedule;
15144+des_cblock (*ivec);
15145+int enc;
15146+ {
15147+ register DES_LONG tin0,tin1;
15148+ register DES_LONG tout0,tout1,xor0,xor1;
15149+ register unsigned char *in,*out;
15150+ register long l=length;
15151+ DES_LONG tin[2];
15152+ unsigned char *iv;
15153+
15154+ in=(unsigned char *)input;
15155+ out=(unsigned char *)output;
15156+ iv=(unsigned char *)ivec;
15157+
15158+ if (enc)
15159+ {
15160+ c2l(iv,tout0);
15161+ c2l(iv,tout1);
15162+ for (l-=8; l>=0; l-=8)
15163+ {
15164+ c2l(in,tin0);
15165+ c2l(in,tin1);
15166+ tin0^=tout0; tin[0]=tin0;
15167+ tin1^=tout1; tin[1]=tin1;
15168+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
15169+ tout0=tin[0]; l2c(tout0,out);
15170+ tout1=tin[1]; l2c(tout1,out);
15171+ }
15172+ if (l != -8)
15173+ {
15174+ c2ln(in,tin0,tin1,l+8);
15175+ tin0^=tout0; tin[0]=tin0;
15176+ tin1^=tout1; tin[1]=tin1;
15177+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
15178+ tout0=tin[0]; l2c(tout0,out);
15179+ tout1=tin[1]; l2c(tout1,out);
15180+ }
15181+ }
15182+ else
15183+ {
15184+ c2l(iv,xor0);
15185+ c2l(iv,xor1);
15186+ for (l-=8; l>=0; l-=8)
15187+ {
15188+ c2l(in,tin0); tin[0]=tin0;
15189+ c2l(in,tin1); tin[1]=tin1;
15190+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
15191+ tout0=tin[0]^xor0;
15192+ tout1=tin[1]^xor1;
15193+ l2c(tout0,out);
15194+ l2c(tout1,out);
15195+ xor0=tin0;
15196+ xor1=tin1;
15197+ }
15198+ if (l != -8)
15199+ {
15200+ c2l(in,tin0); tin[0]=tin0;
15201+ c2l(in,tin1); tin[1]=tin1;
15202+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
15203+ tout0=tin[0]^xor0;
15204+ tout1=tin[1]^xor1;
15205+ l2cn(tout0,tout1,out,l+8);
15206+ /* xor0=tin0;
15207+ xor1=tin1; */
15208+ }
15209+ }
15210+ tin0=tin1=tout0=tout1=xor0=xor1=0;
15211+ tin[0]=tin[1]=0;
15212+ }
15213+
15214diff -druN linux-noipsec/net/ipsec/libdes/des.h linux/net/ipsec/libdes/des.h
15215--- linux-noipsec/net/ipsec/libdes/des.h Thu Jan 1 01:00:00 1970
15216+++ linux/net/ipsec/libdes/des.h Wed Oct 4 16:54:10 2000
15217@@ -0,0 +1,303 @@
15218+/* crypto/des/des.org */
15219+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
15220+ * All rights reserved.
15221+ *
15222+ * This package is an SSL implementation written
15223+ * by Eric Young (eay@cryptsoft.com).
15224+ * The implementation was written so as to conform with Netscapes SSL.
15225+ *
15226+ * This library is free for commercial and non-commercial use as long as
15227+ * the following conditions are aheared to. The following conditions
15228+ * apply to all code found in this distribution, be it the RC4, RSA,
15229+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
15230+ * included with this distribution is covered by the same copyright terms
15231+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15232+ *
15233+ * Copyright remains Eric Young's, and as such any Copyright notices in
15234+ * the code are not to be removed.
15235+ * If this package is used in a product, Eric Young should be given attribution
15236+ * as the author of the parts of the library used.
15237+ * This can be in the form of a textual message at program startup or
15238+ * in documentation (online or textual) provided with the package.
15239+ *
15240+ * Redistribution and use in source and binary forms, with or without
15241+ * modification, are permitted provided that the following conditions
15242+ * are met:
15243+ * 1. Redistributions of source code must retain the copyright
15244+ * notice, this list of conditions and the following disclaimer.
15245+ * 2. Redistributions in binary form must reproduce the above copyright
15246+ * notice, this list of conditions and the following disclaimer in the
15247+ * documentation and/or other materials provided with the distribution.
15248+ * 3. All advertising materials mentioning features or use of this software
15249+ * must display the following acknowledgement:
15250+ * "This product includes cryptographic software written by
15251+ * Eric Young (eay@cryptsoft.com)"
15252+ * The word 'cryptographic' can be left out if the rouines from the library
15253+ * being used are not cryptographic related :-).
15254+ * 4. If you include any Windows specific code (or a derivative thereof) from
15255+ * the apps directory (application code) you must include an acknowledgement:
15256+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
15257+ *
15258+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
15259+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15260+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15261+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15262+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15263+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
15264+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15265+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
15266+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15267+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
15268+ * SUCH DAMAGE.
15269+ *
15270+ * The licence and distribution terms for any publically available version or
15271+ * derivative of this code cannot be changed. i.e. this code cannot simply be
15272+ * copied and put under another distribution licence
15273+ * [including the GNU Public Licence.]
15274+ */
15275+
15276+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
15277+ *
15278+ * Always modify des.org since des.h is automatically generated from
15279+ * it during SSLeay configuration.
15280+ *
15281+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
15282+ */
15283+
15284+#ifndef HEADER_DES_H
15285+#define HEADER_DES_H
15286+
15287+#ifdef __cplusplus
15288+extern "C" {
15289+#endif
15290+
15291+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
15292+ * %20 speed up (longs are 8 bytes, int's are 4). */
15293+#ifndef DES_LONG
15294+/* RCSID $Id$ */
15295+/* This conditional for FreeS/WAN project. */
15296+#ifdef __alpha
15297+#define DES_LONG unsigned int
15298+#else
15299+#define DES_LONG unsigned long
15300+#endif
15301+#endif
15302+
15303+typedef unsigned char des_cblock[8];
15304+typedef struct des_ks_struct
15305+ {
15306+ union {
15307+ des_cblock _;
15308+ /* make sure things are correct size on machines with
15309+ * 8 byte longs */
15310+ DES_LONG pad[2];
15311+ } ks;
15312+#undef _
15313+#define _ ks._
15314+ } des_key_schedule[16];
15315+
15316+#define DES_KEY_SZ (sizeof(des_cblock))
15317+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
15318+
15319+#define DES_ENCRYPT 1
15320+#define DES_DECRYPT 0
15321+
15322+#define DES_CBC_MODE 0
15323+#define DES_PCBC_MODE 1
15324+
15325+#define des_ecb2_encrypt(i,o,k1,k2,e) \
15326+ des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
15327+
15328+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
15329+ des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
15330+
15331+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
15332+ des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
15333+
15334+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
15335+ des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
15336+
15337+#define C_Block des_cblock
15338+#define Key_schedule des_key_schedule
15339+#ifdef KERBEROS
15340+#define ENCRYPT DES_ENCRYPT
15341+#define DECRYPT DES_DECRYPT
15342+#endif
15343+#define KEY_SZ DES_KEY_SZ
15344+#define string_to_key des_string_to_key
15345+#define read_pw_string des_read_pw_string
15346+#define random_key des_random_key
15347+#define pcbc_encrypt des_pcbc_encrypt
15348+#define set_key des_set_key
15349+#define key_sched des_key_sched
15350+#define ecb_encrypt des_ecb_encrypt
15351+#define cbc_encrypt des_cbc_encrypt
15352+#define ncbc_encrypt des_ncbc_encrypt
15353+#define xcbc_encrypt des_xcbc_encrypt
15354+#define cbc_cksum des_cbc_cksum
15355+#define quad_cksum des_quad_cksum
15356+
15357+/* For compatibility with the MIT lib - eay 20/05/92 */
15358+typedef des_key_schedule bit_64;
15359+#define des_fixup_key_parity des_set_odd_parity
15360+#define des_check_key_parity check_parity
15361+
15362+extern int des_check_key; /* defaults to false */
15363+extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
15364+
15365+/* The next line is used to disable full ANSI prototypes, if your
15366+ * compiler has problems with the prototypes, make sure this line always
15367+ * evaluates to true :-) */
15368+#if defined(MSDOS) || defined(__STDC__)
15369+#undef NOPROTO
15370+#endif
15371+#ifndef NOPROTO
15372+char *des_options(void);
15373+void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
15374+ des_key_schedule ks1,des_key_schedule ks2,
15375+ des_key_schedule ks3, int enc);
15376+DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
15377+ long length,des_key_schedule schedule,des_cblock *ivec);
15378+void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
15379+ des_key_schedule schedule,des_cblock *ivec,int enc);
15380+void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
15381+ des_key_schedule schedule,des_cblock *ivec,int enc);
15382+void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
15383+ des_key_schedule schedule,des_cblock *ivec,
15384+ des_cblock *inw,des_cblock *outw,int enc);
15385+void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
15386+ long length,des_key_schedule schedule,des_cblock *ivec,int enc);
15387+void des_ecb_encrypt(des_cblock *input,des_cblock *output,
15388+ des_key_schedule ks,int enc);
15389+void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
15390+void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
15391+void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
15392+ des_key_schedule ks2, des_key_schedule ks3);
15393+void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
15394+ des_key_schedule ks2, des_key_schedule ks3);
15395+void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
15396+ long length, des_key_schedule ks1, des_key_schedule ks2,
15397+ des_key_schedule ks3, des_cblock *ivec, int enc);
15398+void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
15399+ long length, des_key_schedule ks1, des_key_schedule ks2,
15400+ des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
15401+void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
15402+ long length, des_key_schedule ks1, des_key_schedule ks2,
15403+ des_key_schedule ks3, des_cblock *ivec, int *num);
15404+
15405+void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
15406+ des_cblock (*out_white));
15407+
15408+int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
15409+ des_cblock *iv);
15410+int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
15411+ des_cblock *iv);
15412+char *des_fcrypt(const char *buf,const char *salt, char *ret);
15413+#ifdef PERL5
15414+char *des_crypt(const char *buf,const char *salt);
15415+#else
15416+/* some stupid compilers complain because I have declared char instead
15417+ * of const char */
15418+#ifdef HEADER_DES_LOCL_H
15419+char *crypt(const char *buf,const char *salt);
15420+#else
15421+char *crypt();
15422+#endif
15423+#endif
15424+void des_ofb_encrypt(unsigned char *in,unsigned char *out,
15425+ int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
15426+void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
15427+ des_key_schedule schedule,des_cblock *ivec,int enc);
15428+DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
15429+ long length,int out_count,des_cblock *seed);
15430+void des_random_seed(des_cblock key);
15431+void des_random_key(des_cblock ret);
15432+int des_read_password(des_cblock *key,char *prompt,int verify);
15433+int des_read_2passwords(des_cblock *key1,des_cblock *key2,
15434+ char *prompt,int verify);
15435+int des_read_pw_string(char *buf,int length,char *prompt,int verify);
15436+void des_set_odd_parity(des_cblock *key);
15437+int des_is_weak_key(des_cblock *key);
15438+int des_set_key(des_cblock *key,des_key_schedule schedule);
15439+int des_key_sched(des_cblock *key,des_key_schedule schedule);
15440+void des_string_to_key(char *str,des_cblock *key);
15441+void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
15442+void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
15443+ des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
15444+void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
15445+ des_key_schedule schedule, des_cblock *ivec, int *num);
15446+int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
15447+
15448+/* Extra functions from Mark Murray <mark@grondar.za> */
15449+/* The following functions are not in the normal unix build or the
15450+ * SSLeay build. When using the SSLeay build, use RAND_seed()
15451+ * and RAND_bytes() instead. */
15452+int des_new_random_key(des_cblock *key);
15453+void des_init_random_number_generator(des_cblock *key);
15454+void des_set_random_generator_seed(des_cblock *key);
15455+void des_set_sequence_number(des_cblock new_sequence_number);
15456+void des_generate_random_block(des_cblock *block);
15457+
15458+#else
15459+
15460+char *des_options();
15461+void des_ecb3_encrypt();
15462+DES_LONG des_cbc_cksum();
15463+void des_cbc_encrypt();
15464+void des_ncbc_encrypt();
15465+void des_xcbc_encrypt();
15466+void des_cfb_encrypt();
15467+void des_ede3_cfb64_encrypt();
15468+void des_ede3_ofb64_encrypt();
15469+void des_ecb_encrypt();
15470+void des_encrypt();
15471+void des_encrypt2();
15472+void des_encrypt3();
15473+void des_decrypt3();
15474+void des_ede3_cbc_encrypt();
15475+int des_enc_read();
15476+int des_enc_write();
15477+char *des_fcrypt();
15478+#ifdef PERL5
15479+char *des_crypt();
15480+#else
15481+char *crypt();
15482+#endif
15483+void des_ofb_encrypt();
15484+void des_pcbc_encrypt();
15485+DES_LONG des_quad_cksum();
15486+void des_random_seed();
15487+void des_random_key();
15488+int des_read_password();
15489+int des_read_2passwords();
15490+int des_read_pw_string();
15491+void des_set_odd_parity();
15492+int des_is_weak_key();
15493+int des_set_key();
15494+int des_key_sched();
15495+void des_string_to_key();
15496+void des_string_to_2keys();
15497+void des_cfb64_encrypt();
15498+void des_ofb64_encrypt();
15499+int des_read_pw();
15500+void des_xwhite_in2out();
15501+
15502+/* Extra functions from Mark Murray <mark@grondar.za> */
15503+/* The following functions are not in the normal unix build or the
15504+ * SSLeay build. When using the SSLeay build, use RAND_seed()
15505+ * and RAND_bytes() instead. */
15506+#ifdef FreeBSD
15507+int des_new_random_key();
15508+void des_init_random_number_generator();
15509+void des_set_random_generator_seed();
15510+void des_set_sequence_number();
15511+void des_generate_random_block();
15512+#endif
15513+
15514+#endif
15515+
15516+#ifdef __cplusplus
15517+}
15518+#endif
15519+
15520+#endif
15521diff -druN linux-noipsec/net/ipsec/libdes/des_enc.c linux/net/ipsec/libdes/des_enc.c
15522--- linux-noipsec/net/ipsec/libdes/des_enc.c Thu Jan 1 01:00:00 1970
15523+++ linux/net/ipsec/libdes/des_enc.c Thu Feb 18 17:41:12 1999
15524@@ -0,0 +1,502 @@
15525+/* crypto/des/des_enc.c */
15526+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
15527+ * All rights reserved.
15528+ *
15529+ * This package is an SSL implementation written
15530+ * by Eric Young (eay@cryptsoft.com).
15531+ * The implementation was written so as to conform with Netscapes SSL.
15532+ *
15533+ * This library is free for commercial and non-commercial use as long as
15534+ * the following conditions are aheared to. The following conditions
15535+ * apply to all code found in this distribution, be it the RC4, RSA,
15536+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
15537+ * included with this distribution is covered by the same copyright terms
15538+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15539+ *
15540+ * Copyright remains Eric Young's, and as such any Copyright notices in
15541+ * the code are not to be removed.
15542+ * If this package is used in a product, Eric Young should be given attribution
15543+ * as the author of the parts of the library used.
15544+ * This can be in the form of a textual message at program startup or
15545+ * in documentation (online or textual) provided with the package.
15546+ *
15547+ * Redistribution and use in source and binary forms, with or without
15548+ * modification, are permitted provided that the following conditions
15549+ * are met:
15550+ * 1. Redistributions of source code must retain the copyright
15551+ * notice, this list of conditions and the following disclaimer.
15552+ * 2. Redistributions in binary form must reproduce the above copyright
15553+ * notice, this list of conditions and the following disclaimer in the
15554+ * documentation and/or other materials provided with the distribution.
15555+ * 3. All advertising materials mentioning features or use of this software
15556+ * must display the following acknowledgement:
15557+ * "This product includes cryptographic software written by
15558+ * Eric Young (eay@cryptsoft.com)"
15559+ * The word 'cryptographic' can be left out if the rouines from the library
15560+ * being used are not cryptographic related :-).
15561+ * 4. If you include any Windows specific code (or a derivative thereof) from
15562+ * the apps directory (application code) you must include an acknowledgement:
15563+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
15564+ *
15565+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
15566+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15567+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15568+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15569+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
15570+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
15571+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15572+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
15573+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15574+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
15575+ * SUCH DAMAGE.
15576+ *
15577+ * The licence and distribution terms for any publically available version or
15578+ * derivative of this code cannot be changed. i.e. this code cannot simply be
15579+ * copied and put under another distribution licence
15580+ * [including the GNU Public Licence.]
15581+ */
15582+
15583+#include "des_locl.h"
15584+
15585+void des_encrypt(data, ks, enc)
15586+DES_LONG *data;
15587+des_key_schedule ks;
15588+int enc;
15589+ {
15590+ register DES_LONG l,r,t,u;
15591+#ifdef DES_PTR
15592+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
15593+#endif
15594+#ifndef DES_UNROLL
15595+ register int i;
15596+#endif
15597+ register DES_LONG *s;
15598+
15599+ r=data[0];
15600+ l=data[1];
15601+
15602+ IP(r,l);
15603+ /* Things have been modified so that the initial rotate is
15604+ * done outside the loop. This required the
15605+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
15606+ * One perl script later and things have a 5% speed up on a sparc2.
15607+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
15608+ * for pointing this out. */
15609+ /* clear the top bits on machines with 8byte longs */
15610+ /* shift left by 2 */
15611+ r=ROTATE(r,29)&0xffffffffL;
15612+ l=ROTATE(l,29)&0xffffffffL;
15613+
15614+ s=(DES_LONG *)ks;
15615+ /* I don't know if it is worth the effort of loop unrolling the
15616+ * inner loop */
15617+ if (enc)
15618+ {
15619+#ifdef DES_UNROLL
15620+ D_ENCRYPT(l,r, 0); /* 1 */
15621+ D_ENCRYPT(r,l, 2); /* 2 */
15622+ D_ENCRYPT(l,r, 4); /* 3 */
15623+ D_ENCRYPT(r,l, 6); /* 4 */
15624+ D_ENCRYPT(l,r, 8); /* 5 */
15625+ D_ENCRYPT(r,l,10); /* 6 */
15626+ D_ENCRYPT(l,r,12); /* 7 */
15627+ D_ENCRYPT(r,l,14); /* 8 */
15628+ D_ENCRYPT(l,r,16); /* 9 */
15629+ D_ENCRYPT(r,l,18); /* 10 */
15630+ D_ENCRYPT(l,r,20); /* 11 */
15631+ D_ENCRYPT(r,l,22); /* 12 */
15632+ D_ENCRYPT(l,r,24); /* 13 */
15633+ D_ENCRYPT(r,l,26); /* 14 */
15634+ D_ENCRYPT(l,r,28); /* 15 */
15635+ D_ENCRYPT(r,l,30); /* 16 */
15636+#else
15637+ for (i=0; i<32; i+=8)
15638+ {
15639+ D_ENCRYPT(l,r,i+0); /* 1 */
15640+ D_ENCRYPT(r,l,i+2); /* 2 */
15641+ D_ENCRYPT(l,r,i+4); /* 3 */
15642+ D_ENCRYPT(r,l,i+6); /* 4 */
15643+ }
15644+#endif
15645+ }
15646+ else
15647+ {
15648+#ifdef DES_UNROLL
15649+ D_ENCRYPT(l,r,30); /* 16 */
15650+ D_ENCRYPT(r,l,28); /* 15 */
15651+ D_ENCRYPT(l,r,26); /* 14 */
15652+ D_ENCRYPT(r,l,24); /* 13 */
15653+ D_ENCRYPT(l,r,22); /* 12 */
15654+ D_ENCRYPT(r,l,20); /* 11 */
15655+ D_ENCRYPT(l,r,18); /* 10 */
15656+ D_ENCRYPT(r,l,16); /* 9 */
15657+ D_ENCRYPT(l,r,14); /* 8 */
15658+ D_ENCRYPT(r,l,12); /* 7 */
15659+ D_ENCRYPT(l,r,10); /* 6 */
15660+ D_ENCRYPT(r,l, 8); /* 5 */
15661+ D_ENCRYPT(l,r, 6); /* 4 */
15662+ D_ENCRYPT(r,l, 4); /* 3 */
15663+ D_ENCRYPT(l,r, 2); /* 2 */
15664+ D_ENCRYPT(r,l, 0); /* 1 */
15665+#else
15666+ for (i=30; i>0; i-=8)
15667+ {
15668+ D_ENCRYPT(l,r,i-0); /* 16 */
15669+ D_ENCRYPT(r,l,i-2); /* 15 */
15670+ D_ENCRYPT(l,r,i-4); /* 14 */
15671+ D_ENCRYPT(r,l,i-6); /* 13 */
15672+ }
15673+#endif
15674+ }
15675+
15676+ /* rotate and clear the top bits on machines with 8byte longs */
15677+ l=ROTATE(l,3)&0xffffffffL;
15678+ r=ROTATE(r,3)&0xffffffffL;
15679+
15680+ FP(r,l);
15681+ data[0]=l;
15682+ data[1]=r;
15683+ l=r=t=u=0;
15684+ }
15685+
15686+void des_encrypt2(data, ks, enc)
15687+DES_LONG *data;
15688+des_key_schedule ks;
15689+int enc;
15690+ {
15691+ register DES_LONG l,r,t,u;
15692+#ifdef DES_PTR
15693+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
15694+#endif
15695+#ifndef DES_UNROLL
15696+ register int i;
15697+#endif
15698+ register DES_LONG *s;
15699+
15700+ r=data[0];
15701+ l=data[1];
15702+
15703+ /* Things have been modified so that the initial rotate is
15704+ * done outside the loop. This required the
15705+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
15706+ * One perl script later and things have a 5% speed up on a sparc2.
15707+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
15708+ * for pointing this out. */
15709+ /* clear the top bits on machines with 8byte longs */
15710+ r=ROTATE(r,29)&0xffffffffL;
15711+ l=ROTATE(l,29)&0xffffffffL;
15712+
15713+ s=(DES_LONG *)ks;
15714+ /* I don't know if it is worth the effort of loop unrolling the
15715+ * inner loop */
15716+ if (enc)
15717+ {
15718+#ifdef DES_UNROLL
15719+ D_ENCRYPT(l,r, 0); /* 1 */
15720+ D_ENCRYPT(r,l, 2); /* 2 */
15721+ D_ENCRYPT(l,r, 4); /* 3 */
15722+ D_ENCRYPT(r,l, 6); /* 4 */
15723+ D_ENCRYPT(l,r, 8); /* 5 */
15724+ D_ENCRYPT(r,l,10); /* 6 */
15725+ D_ENCRYPT(l,r,12); /* 7 */
15726+ D_ENCRYPT(r,l,14); /* 8 */
15727+ D_ENCRYPT(l,r,16); /* 9 */
15728+ D_ENCRYPT(r,l,18); /* 10 */
15729+ D_ENCRYPT(l,r,20); /* 11 */
15730+ D_ENCRYPT(r,l,22); /* 12 */
15731+ D_ENCRYPT(l,r,24); /* 13 */
15732+ D_ENCRYPT(r,l,26); /* 14 */
15733+ D_ENCRYPT(l,r,28); /* 15 */
15734+ D_ENCRYPT(r,l,30); /* 16 */
15735+#else
15736+ for (i=0; i<32; i+=8)
15737+ {
15738+ D_ENCRYPT(l,r,i+0); /* 1 */
15739+ D_ENCRYPT(r,l,i+2); /* 2 */
15740+ D_ENCRYPT(l,r,i+4); /* 3 */
15741+ D_ENCRYPT(r,l,i+6); /* 4 */
15742+ }
15743+#endif
15744+ }
15745+ else
15746+ {
15747+#ifdef DES_UNROLL
15748+ D_ENCRYPT(l,r,30); /* 16 */
15749+ D_ENCRYPT(r,l,28); /* 15 */
15750+ D_ENCRYPT(l,r,26); /* 14 */
15751+ D_ENCRYPT(r,l,24); /* 13 */
15752+ D_ENCRYPT(l,r,22); /* 12 */
15753+ D_ENCRYPT(r,l,20); /* 11 */
15754+ D_ENCRYPT(l,r,18); /* 10 */
15755+ D_ENCRYPT(r,l,16); /* 9 */
15756+ D_ENCRYPT(l,r,14); /* 8 */
15757+ D_ENCRYPT(r,l,12); /* 7 */
15758+ D_ENCRYPT(l,r,10); /* 6 */
15759+ D_ENCRYPT(r,l, 8); /* 5 */
15760+ D_ENCRYPT(l,r, 6); /* 4 */
15761+ D_ENCRYPT(r,l, 4); /* 3 */
15762+ D_ENCRYPT(l,r, 2); /* 2 */
15763+ D_ENCRYPT(r,l, 0); /* 1 */
15764+#else
15765+ for (i=30; i>0; i-=8)
15766+ {
15767+ D_ENCRYPT(l,r,i-0); /* 16 */
15768+ D_ENCRYPT(r,l,i-2); /* 15 */
15769+ D_ENCRYPT(l,r,i-4); /* 14 */
15770+ D_ENCRYPT(r,l,i-6); /* 13 */
15771+ }
15772+#endif
15773+ }
15774+ /* rotate and clear the top bits on machines with 8byte longs */
15775+ data[0]=ROTATE(l,3)&0xffffffffL;
15776+ data[1]=ROTATE(r,3)&0xffffffffL;
15777+ l=r=t=u=0;
15778+ }
15779+
15780+void des_encrypt3(data,ks1,ks2,ks3)
15781+DES_LONG *data;
15782+des_key_schedule ks1;
15783+des_key_schedule ks2;
15784+des_key_schedule ks3;
15785+ {
15786+ register DES_LONG l,r;
15787+
15788+ l=data[0];
15789+ r=data[1];
15790+ IP(l,r);
15791+ data[0]=l;
15792+ data[1]=r;
15793+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
15794+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
15795+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
15796+ l=data[0];
15797+ r=data[1];
15798+ FP(r,l);
15799+ data[0]=l;
15800+ data[1]=r;
15801+ }
15802+
15803+void des_decrypt3(data,ks1,ks2,ks3)
15804+DES_LONG *data;
15805+des_key_schedule ks1;
15806+des_key_schedule ks2;
15807+des_key_schedule ks3;
15808+ {
15809+ register DES_LONG l,r;
15810+
15811+ l=data[0];
15812+ r=data[1];
15813+ IP(l,r);
15814+ data[0]=l;
15815+ data[1]=r;
15816+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
15817+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
15818+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
15819+ l=data[0];
15820+ r=data[1];
15821+ FP(r,l);
15822+ data[0]=l;
15823+ data[1]=r;
15824+ }
15825+
15826+#ifndef DES_DEFAULT_OPTIONS
15827+
15828+void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
15829+des_cblock (*input);
15830+des_cblock (*output);
15831+long length;
15832+des_key_schedule schedule;
15833+des_cblock (*ivec);
15834+int enc;
15835+ {
15836+ register DES_LONG tin0,tin1;
15837+ register DES_LONG tout0,tout1,xor0,xor1;
15838+ register unsigned char *in,*out;
15839+ register long l=length;
15840+ DES_LONG tin[2];
15841+ unsigned char *iv;
15842+
15843+ in=(unsigned char *)input;
15844+ out=(unsigned char *)output;
15845+ iv=(unsigned char *)ivec;
15846+
15847+ if (enc)
15848+ {
15849+ c2l(iv,tout0);
15850+ c2l(iv,tout1);
15851+ for (l-=8; l>=0; l-=8)
15852+ {
15853+ c2l(in,tin0);
15854+ c2l(in,tin1);
15855+ tin0^=tout0; tin[0]=tin0;
15856+ tin1^=tout1; tin[1]=tin1;
15857+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
15858+ tout0=tin[0]; l2c(tout0,out);
15859+ tout1=tin[1]; l2c(tout1,out);
15860+ }
15861+ if (l != -8)
15862+ {
15863+ c2ln(in,tin0,tin1,l+8);
15864+ tin0^=tout0; tin[0]=tin0;
15865+ tin1^=tout1; tin[1]=tin1;
15866+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
15867+ tout0=tin[0]; l2c(tout0,out);
15868+ tout1=tin[1]; l2c(tout1,out);
15869+ }
15870+ iv=(unsigned char *)ivec;
15871+ l2c(tout0,iv);
15872+ l2c(tout1,iv);
15873+ }
15874+ else
15875+ {
15876+ c2l(iv,xor0);
15877+ c2l(iv,xor1);
15878+ for (l-=8; l>=0; l-=8)
15879+ {
15880+ c2l(in,tin0); tin[0]=tin0;
15881+ c2l(in,tin1); tin[1]=tin1;
15882+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
15883+ tout0=tin[0]^xor0;
15884+ tout1=tin[1]^xor1;
15885+ l2c(tout0,out);
15886+ l2c(tout1,out);
15887+ xor0=tin0;
15888+ xor1=tin1;
15889+ }
15890+ if (l != -8)
15891+ {
15892+ c2l(in,tin0); tin[0]=tin0;
15893+ c2l(in,tin1); tin[1]=tin1;
15894+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
15895+ tout0=tin[0]^xor0;
15896+ tout1=tin[1]^xor1;
15897+ l2cn(tout0,tout1,out,l+8);
15898+ xor0=tin0;
15899+ xor1=tin1;
15900+ }
15901+
15902+ iv=(unsigned char *)ivec;
15903+ l2c(xor0,iv);
15904+ l2c(xor1,iv);
15905+ }
15906+ tin0=tin1=tout0=tout1=xor0=xor1=0;
15907+ tin[0]=tin[1]=0;
15908+ }
15909+
15910+void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
15911+des_cblock (*input);
15912+des_cblock (*output);
15913+long length;
15914+des_key_schedule ks1;
15915+des_key_schedule ks2;
15916+des_key_schedule ks3;
15917+des_cblock (*ivec);
15918+int enc;
15919+ {
15920+ register DES_LONG tin0,tin1;
15921+ register DES_LONG tout0,tout1,xor0,xor1;
15922+ register unsigned char *in,*out;
15923+ register long l=length;
15924+ DES_LONG tin[2];
15925+ unsigned char *iv;
15926+
15927+ in=(unsigned char *)input;
15928+ out=(unsigned char *)output;
15929+ iv=(unsigned char *)ivec;
15930+
15931+ if (enc)
15932+ {
15933+ c2l(iv,tout0);
15934+ c2l(iv,tout1);
15935+ for (l-=8; l>=0; l-=8)
15936+ {
15937+ c2l(in,tin0);
15938+ c2l(in,tin1);
15939+ tin0^=tout0;
15940+ tin1^=tout1;
15941+
15942+ tin[0]=tin0;
15943+ tin[1]=tin1;
15944+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
15945+ tout0=tin[0];
15946+ tout1=tin[1];
15947+
15948+ l2c(tout0,out);
15949+ l2c(tout1,out);
15950+ }
15951+ if (l != -8)
15952+ {
15953+ c2ln(in,tin0,tin1,l+8);
15954+ tin0^=tout0;
15955+ tin1^=tout1;
15956+
15957+ tin[0]=tin0;
15958+ tin[1]=tin1;
15959+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
15960+ tout0=tin[0];
15961+ tout1=tin[1];
15962+
15963+ l2c(tout0,out);
15964+ l2c(tout1,out);
15965+ }
15966+ iv=(unsigned char *)ivec;
15967+ l2c(tout0,iv);
15968+ l2c(tout1,iv);
15969+ }
15970+ else
15971+ {
15972+ register DES_LONG t0,t1;
15973+
15974+ c2l(iv,xor0);
15975+ c2l(iv,xor1);
15976+ for (l-=8; l>=0; l-=8)
15977+ {
15978+ c2l(in,tin0);
15979+ c2l(in,tin1);
15980+
15981+ t0=tin0;
15982+ t1=tin1;
15983+
15984+ tin[0]=tin0;
15985+ tin[1]=tin1;
15986+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
15987+ tout0=tin[0];
15988+ tout1=tin[1];
15989+
15990+ tout0^=xor0;
15991+ tout1^=xor1;
15992+ l2c(tout0,out);
15993+ l2c(tout1,out);
15994+ xor0=t0;
15995+ xor1=t1;
15996+ }
15997+ if (l != -8)
15998+ {
15999+ c2l(in,tin0);
16000+ c2l(in,tin1);
16001+
16002+ t0=tin0;
16003+ t1=tin1;
16004+
16005+ tin[0]=tin0;
16006+ tin[1]=tin1;
16007+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
16008+ tout0=tin[0];
16009+ tout1=tin[1];
16010+
16011+ tout0^=xor0;
16012+ tout1^=xor1;
16013+ l2cn(tout0,tout1,out,l+8);
16014+ xor0=t0;
16015+ xor1=t1;
16016+ }
16017+
16018+ iv=(unsigned char *)ivec;
16019+ l2c(xor0,iv);
16020+ l2c(xor1,iv);
16021+ }
16022+ tin0=tin1=tout0=tout1=xor0=xor1=0;
16023+ tin[0]=tin[1]=0;
16024+ }
16025+
16026+#endif /* DES_DEFAULT_OPTIONS */
16027diff -druN linux-noipsec/net/ipsec/libdes/des_locl.h linux/net/ipsec/libdes/des_locl.h
16028--- linux-noipsec/net/ipsec/libdes/des_locl.h Thu Jan 1 01:00:00 1970
16029+++ linux/net/ipsec/libdes/des_locl.h Wed Oct 4 16:54:10 2000
16030@@ -0,0 +1,511 @@
16031+/* crypto/des/des_locl.org */
16032+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
16033+ * All rights reserved.
16034+ *
16035+ * This package is an SSL implementation written
16036+ * by Eric Young (eay@cryptsoft.com).
16037+ * The implementation was written so as to conform with Netscapes SSL.
16038+ *
16039+ * This library is free for commercial and non-commercial use as long as
16040+ * the following conditions are aheared to. The following conditions
16041+ * apply to all code found in this distribution, be it the RC4, RSA,
16042+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
16043+ * included with this distribution is covered by the same copyright terms
16044+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
16045+ *
16046+ * Copyright remains Eric Young's, and as such any Copyright notices in
16047+ * the code are not to be removed.
16048+ * If this package is used in a product, Eric Young should be given attribution
16049+ * as the author of the parts of the library used.
16050+ * This can be in the form of a textual message at program startup or
16051+ * in documentation (online or textual) provided with the package.
16052+ *
16053+ * Redistribution and use in source and binary forms, with or without
16054+ * modification, are permitted provided that the following conditions
16055+ * are met:
16056+ * 1. Redistributions of source code must retain the copyright
16057+ * notice, this list of conditions and the following disclaimer.
16058+ * 2. Redistributions in binary form must reproduce the above copyright
16059+ * notice, this list of conditions and the following disclaimer in the
16060+ * documentation and/or other materials provided with the distribution.
16061+ * 3. All advertising materials mentioning features or use of this software
16062+ * must display the following acknowledgement:
16063+ * "This product includes cryptographic software written by
16064+ * Eric Young (eay@cryptsoft.com)"
16065+ * The word 'cryptographic' can be left out if the rouines from the library
16066+ * being used are not cryptographic related :-).
16067+ * 4. If you include any Windows specific code (or a derivative thereof) from
16068+ * the apps directory (application code) you must include an acknowledgement:
16069+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
16070+ *
16071+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
16072+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16073+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16074+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16075+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16076+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16077+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16078+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16079+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16080+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16081+ * SUCH DAMAGE.
16082+ *
16083+ * The licence and distribution terms for any publically available version or
16084+ * derivative of this code cannot be changed. i.e. this code cannot simply be
16085+ * copied and put under another distribution licence
16086+ * [including the GNU Public Licence.]
16087+ */
16088+
16089+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
16090+ *
16091+ * Always modify des_locl.org since des_locl.h is automatically generated from
16092+ * it during SSLeay configuration.
16093+ *
16094+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
16095+ */
16096+
16097+#ifndef HEADER_DES_LOCL_H
16098+#define HEADER_DES_LOCL_H
16099+
16100+#if defined(WIN32) || defined(WIN16)
16101+#ifndef MSDOS
16102+#define MSDOS
16103+#endif
16104+#endif
16105+
16106+#include "des.h"
16107+
16108+#ifndef DES_DEFAULT_OPTIONS
16109+/* the following is tweaked from a config script, that is why it is a
16110+ * protected undef/define */
16111+#ifndef DES_PTR
16112+#define DES_PTR
16113+#endif
16114+
16115+/* This helps C compiler generate the correct code for multiple functional
16116+ * units. It reduces register dependancies at the expense of 2 more
16117+ * registers */
16118+#ifndef DES_RISC1
16119+#define DES_RISC1
16120+#endif
16121+
16122+#ifndef DES_RISC2
16123+#undef DES_RISC2
16124+#endif
16125+
16126+#if defined(DES_RISC1) && defined(DES_RISC2)
16127+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
16128+#endif
16129+
16130+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
16131+ * Very mucy CPU dependant */
16132+#ifndef DES_UNROLL
16133+#define DES_UNROLL
16134+#endif
16135+
16136+/* These default values were supplied by
16137+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
16138+ * They are only used if nothing else has been defined */
16139+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
16140+/* Special defines which change the way the code is built depending on the
16141+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
16142+ even newer MIPS CPU's, but at the moment one size fits all for
16143+ optimization options. Older Sparc's work better with only UNROLL, but
16144+ there's no way to tell at compile time what it is you're running on */
16145+
16146+#if defined( sun ) /* Newer Sparc's */
16147+ #define DES_PTR
16148+ #define DES_RISC1
16149+ #define DES_UNROLL
16150+#elif defined( __ultrix ) /* Older MIPS */
16151+ #define DES_PTR
16152+ #define DES_RISC2
16153+ #define DES_UNROLL
16154+#elif defined( __osf1__ ) /* Alpha */
16155+ #define DES_PTR
16156+ #define DES_RISC2
16157+#elif defined ( _AIX ) /* RS6000 */
16158+ /* Unknown */
16159+#elif defined( __hpux ) /* HP-PA */
16160+ /* Unknown */
16161+#elif defined( __aux ) /* 68K */
16162+ /* Unknown */
16163+#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
16164+ #define DES_UNROLL
16165+#elif defined( __sgi ) /* Newer MIPS */
16166+ #define DES_PTR
16167+ #define DES_RISC2
16168+ #define DES_UNROLL
16169+#elif defined( i386 ) /* x86 boxes, should be gcc */
16170+ #define DES_PTR
16171+ #define DES_RISC1
16172+ #define DES_UNROLL
16173+#endif /* Systems-specific speed defines */
16174+#endif
16175+
16176+#endif /* DES_DEFAULT_OPTIONS */
16177+
16178+#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
16179+#include <stdlib.h>
16180+#include <errno.h>
16181+#include <time.h>
16182+#include <io.h>
16183+#ifndef RAND
16184+#define RAND
16185+#endif
16186+#undef NOPROTO
16187+#endif
16188+
16189+#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
16190+#include <string.h>
16191+#endif
16192+
16193+#ifndef RAND
16194+#define RAND
16195+#endif
16196+
16197+#ifdef linux
16198+#undef RAND
16199+#endif
16200+
16201+#ifdef MSDOS
16202+#define getpid() 2
16203+#define RAND
16204+#undef NOPROTO
16205+#endif
16206+
16207+#if defined(NOCONST)
16208+#define const
16209+#endif
16210+
16211+#ifdef __STDC__
16212+#undef NOPROTO
16213+#endif
16214+
16215+#ifdef RAND
16216+#define srandom(s) srand(s)
16217+#define random rand
16218+#endif
16219+
16220+#define ITERATIONS 16
16221+#define HALF_ITERATIONS 8
16222+
16223+/* used in des_read and des_write */
16224+#define MAXWRITE (1024*16)
16225+#define BSIZE (MAXWRITE+4)
16226+
16227+#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
16228+ l|=((DES_LONG)(*((c)++)))<< 8L, \
16229+ l|=((DES_LONG)(*((c)++)))<<16L, \
16230+ l|=((DES_LONG)(*((c)++)))<<24L)
16231+
16232+/* NOTE - c is not incremented as per c2l */
16233+#define c2ln(c,l1,l2,n) { \
16234+ c+=n; \
16235+ l1=l2=0; \
16236+ switch (n) { \
16237+ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
16238+ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
16239+ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
16240+ case 5: l2|=((DES_LONG)(*(--(c)))); \
16241+ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
16242+ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
16243+ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
16244+ case 1: l1|=((DES_LONG)(*(--(c)))); \
16245+ } \
16246+ }
16247+
16248+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
16249+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
16250+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
16251+ *((c)++)=(unsigned char)(((l)>>24L)&0xff))
16252+
16253+/* replacements for htonl and ntohl since I have no idea what to do
16254+ * when faced with machines with 8 byte longs. */
16255+#define HDRSIZE 4
16256+
16257+#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
16258+ l|=((DES_LONG)(*((c)++)))<<16L, \
16259+ l|=((DES_LONG)(*((c)++)))<< 8L, \
16260+ l|=((DES_LONG)(*((c)++))))
16261+
16262+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
16263+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
16264+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
16265+ *((c)++)=(unsigned char)(((l) )&0xff))
16266+
16267+/* NOTE - c is not incremented as per l2c */
16268+#define l2cn(l1,l2,c,n) { \
16269+ c+=n; \
16270+ switch (n) { \
16271+ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
16272+ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
16273+ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
16274+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
16275+ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
16276+ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
16277+ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
16278+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
16279+ } \
16280+ }
16281+
16282+#if defined(WIN32)
16283+#define ROTATE(a,n) (_lrotr(a,n))
16284+#else
16285+#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
16286+#endif
16287+
16288+/* Don't worry about the LOAD_DATA() stuff, that is used by
16289+ * fcrypt() to add it's little bit to the front */
16290+
16291+#ifdef DES_FCRYPT
16292+
16293+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
16294+ { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
16295+
16296+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
16297+ t=R^(R>>16L); \
16298+ u=t&E0; t&=E1; \
16299+ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
16300+ tmp=(t<<16); t^=R^s[S+1]; t^=tmp
16301+#else
16302+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
16303+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
16304+ u=R^s[S ]; \
16305+ t=R^s[S+1]
16306+#endif
16307+
16308+/* The changes to this macro may help or hinder, depending on the
16309+ * compiler and the achitecture. gcc2 always seems to do well :-).
16310+ * Inspired by Dana How <how@isl.stanford.edu>
16311+ * DO NOT use the alternative version on machines with 8 byte longs.
16312+ * It does not seem to work on the Alpha, even when DES_LONG is 4
16313+ * bytes, probably an issue of accessing non-word aligned objects :-( */
16314+#ifdef DES_PTR
16315+
16316+/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
16317+ * is no reason to not xor all the sub items together. This potentially
16318+ * saves a register since things can be xored directly into L */
16319+
16320+#if defined(DES_RISC1) || defined(DES_RISC2)
16321+#ifdef DES_RISC1
16322+#define D_ENCRYPT(LL,R,S) { \
16323+ unsigned int u1,u2,u3; \
16324+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
16325+ u2=(int)u>>8L; \
16326+ u1=(int)u&0xfc; \
16327+ u2&=0xfc; \
16328+ t=ROTATE(t,4); \
16329+ u>>=16L; \
16330+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
16331+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
16332+ u3=(int)(u>>8L); \
16333+ u1=(int)u&0xfc; \
16334+ u3&=0xfc; \
16335+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
16336+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
16337+ u2=(int)t>>8L; \
16338+ u1=(int)t&0xfc; \
16339+ u2&=0xfc; \
16340+ t>>=16L; \
16341+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
16342+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
16343+ u3=(int)t>>8L; \
16344+ u1=(int)t&0xfc; \
16345+ u3&=0xfc; \
16346+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
16347+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
16348+#endif
16349+#ifdef DES_RISC2
16350+#define D_ENCRYPT(LL,R,S) { \
16351+ unsigned int u1,u2,s1,s2; \
16352+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
16353+ u2=(int)u>>8L; \
16354+ u1=(int)u&0xfc; \
16355+ u2&=0xfc; \
16356+ t=ROTATE(t,4); \
16357+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
16358+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
16359+ s1=(int)(u>>16L); \
16360+ s2=(int)(u>>24L); \
16361+ s1&=0xfc; \
16362+ s2&=0xfc; \
16363+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
16364+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
16365+ u2=(int)t>>8L; \
16366+ u1=(int)t&0xfc; \
16367+ u2&=0xfc; \
16368+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
16369+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
16370+ s1=(int)(t>>16L); \
16371+ s2=(int)(t>>24L); \
16372+ s1&=0xfc; \
16373+ s2&=0xfc; \
16374+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
16375+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
16376+#endif
16377+#else
16378+#define D_ENCRYPT(LL,R,S) { \
16379+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
16380+ t=ROTATE(t,4); \
16381+ LL^= \
16382+ *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
16383+ *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
16384+ *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
16385+ *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
16386+ *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
16387+ *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
16388+ *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
16389+ *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
16390+#endif
16391+
16392+#else /* original version */
16393+
16394+#if defined(DES_RISC1) || defined(DES_RISC2)
16395+#ifdef DES_RISC1
16396+#define D_ENCRYPT(LL,R,S) {\
16397+ unsigned int u1,u2,u3; \
16398+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
16399+ u>>=2L; \
16400+ t=ROTATE(t,6); \
16401+ u2=(int)u>>8L; \
16402+ u1=(int)u&0x3f; \
16403+ u2&=0x3f; \
16404+ u>>=16L; \
16405+ LL^=des_SPtrans[0][u1]; \
16406+ LL^=des_SPtrans[2][u2]; \
16407+ u3=(int)u>>8L; \
16408+ u1=(int)u&0x3f; \
16409+ u3&=0x3f; \
16410+ LL^=des_SPtrans[4][u1]; \
16411+ LL^=des_SPtrans[6][u3]; \
16412+ u2=(int)t>>8L; \
16413+ u1=(int)t&0x3f; \
16414+ u2&=0x3f; \
16415+ t>>=16L; \
16416+ LL^=des_SPtrans[1][u1]; \
16417+ LL^=des_SPtrans[3][u2]; \
16418+ u3=(int)t>>8L; \
16419+ u1=(int)t&0x3f; \
16420+ u3&=0x3f; \
16421+ LL^=des_SPtrans[5][u1]; \
16422+ LL^=des_SPtrans[7][u3]; }
16423+#endif
16424+#ifdef DES_RISC2
16425+#define D_ENCRYPT(LL,R,S) {\
16426+ unsigned int u1,u2,s1,s2; \
16427+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
16428+ u>>=2L; \
16429+ t=ROTATE(t,6); \
16430+ u2=(int)u>>8L; \
16431+ u1=(int)u&0x3f; \
16432+ u2&=0x3f; \
16433+ LL^=des_SPtrans[0][u1]; \
16434+ LL^=des_SPtrans[2][u2]; \
16435+ s1=(int)u>>16L; \
16436+ s2=(int)u>>24L; \
16437+ s1&=0x3f; \
16438+ s2&=0x3f; \
16439+ LL^=des_SPtrans[4][s1]; \
16440+ LL^=des_SPtrans[6][s2]; \
16441+ u2=(int)t>>8L; \
16442+ u1=(int)t&0x3f; \
16443+ u2&=0x3f; \
16444+ LL^=des_SPtrans[1][u1]; \
16445+ LL^=des_SPtrans[3][u2]; \
16446+ s1=(int)t>>16; \
16447+ s2=(int)t>>24L; \
16448+ s1&=0x3f; \
16449+ s2&=0x3f; \
16450+ LL^=des_SPtrans[5][s1]; \
16451+ LL^=des_SPtrans[7][s2]; }
16452+#endif
16453+
16454+#else
16455+
16456+#define D_ENCRYPT(LL,R,S) {\
16457+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
16458+ t=ROTATE(t,4); \
16459+ LL^=\
16460+ des_SPtrans[0][(u>> 2L)&0x3f]^ \
16461+ des_SPtrans[2][(u>>10L)&0x3f]^ \
16462+ des_SPtrans[4][(u>>18L)&0x3f]^ \
16463+ des_SPtrans[6][(u>>26L)&0x3f]^ \
16464+ des_SPtrans[1][(t>> 2L)&0x3f]^ \
16465+ des_SPtrans[3][(t>>10L)&0x3f]^ \
16466+ des_SPtrans[5][(t>>18L)&0x3f]^ \
16467+ des_SPtrans[7][(t>>26L)&0x3f]; }
16468+#endif
16469+#endif
16470+
16471+ /* IP and FP
16472+ * The problem is more of a geometric problem that random bit fiddling.
16473+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
16474+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
16475+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
16476+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
16477+
16478+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
16479+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
16480+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
16481+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
16482+
16483+ The output has been subject to swaps of the form
16484+ 0 1 -> 3 1 but the odd and even bits have been put into
16485+ 2 3 2 0
16486+ different words. The main trick is to remember that
16487+ t=((l>>size)^r)&(mask);
16488+ r^=t;
16489+ l^=(t<<size);
16490+ can be used to swap and move bits between words.
16491+
16492+ So l = 0 1 2 3 r = 16 17 18 19
16493+ 4 5 6 7 20 21 22 23
16494+ 8 9 10 11 24 25 26 27
16495+ 12 13 14 15 28 29 30 31
16496+ becomes (for size == 2 and mask == 0x3333)
16497+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
16498+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
16499+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
16500+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
16501+
16502+ Thanks for hints from Richard Outerbridge - he told me IP&FP
16503+ could be done in 15 xor, 10 shifts and 5 ands.
16504+ When I finally started to think of the problem in 2D
16505+ I first got ~42 operations without xors. When I remembered
16506+ how to use xors :-) I got it to its final state.
16507+ */
16508+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
16509+ (b)^=(t),\
16510+ (a)^=((t)<<(n)))
16511+
16512+#define IP(l,r) \
16513+ { \
16514+ register DES_LONG tt; \
16515+ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
16516+ PERM_OP(l,r,tt,16,0x0000ffffL); \
16517+ PERM_OP(r,l,tt, 2,0x33333333L); \
16518+ PERM_OP(l,r,tt, 8,0x00ff00ffL); \
16519+ PERM_OP(r,l,tt, 1,0x55555555L); \
16520+ }
16521+
16522+#define FP(l,r) \
16523+ { \
16524+ register DES_LONG tt; \
16525+ PERM_OP(l,r,tt, 1,0x55555555L); \
16526+ PERM_OP(r,l,tt, 8,0x00ff00ffL); \
16527+ PERM_OP(l,r,tt, 2,0x33333333L); \
16528+ PERM_OP(r,l,tt,16,0x0000ffffL); \
16529+ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
16530+ }
16531+
16532+extern const DES_LONG des_SPtrans[8][64];
16533+
16534+#ifndef NOPROTO
16535+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
16536+ DES_LONG Eswap0, DES_LONG Eswap1);
16537+#else
16538+void fcrypt_body();
16539+#endif
16540+
16541+#endif
16542diff -druN linux-noipsec/net/ipsec/libdes/des_opts.c linux/net/ipsec/libdes/des_opts.c
16543--- linux-noipsec/net/ipsec/libdes/des_opts.c Thu Jan 1 01:00:00 1970
16544+++ linux/net/ipsec/libdes/des_opts.c Thu Feb 18 17:41:13 1999
16545@@ -0,0 +1,620 @@
16546+/* crypto/des/des_opts.c */
16547+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
16548+ * All rights reserved.
16549+ *
16550+ * This package is an SSL implementation written
16551+ * by Eric Young (eay@cryptsoft.com).
16552+ * The implementation was written so as to conform with Netscapes SSL.
16553+ *
16554+ * This library is free for commercial and non-commercial use as long as
16555+ * the following conditions are aheared to. The following conditions
16556+ * apply to all code found in this distribution, be it the RC4, RSA,
16557+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
16558+ * included with this distribution is covered by the same copyright terms
16559+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
16560+ *
16561+ * Copyright remains Eric Young's, and as such any Copyright notices in
16562+ * the code are not to be removed.
16563+ * If this package is used in a product, Eric Young should be given attribution
16564+ * as the author of the parts of the library used.
16565+ * This can be in the form of a textual message at program startup or
16566+ * in documentation (online or textual) provided with the package.
16567+ *
16568+ * Redistribution and use in source and binary forms, with or without
16569+ * modification, are permitted provided that the following conditions
16570+ * are met:
16571+ * 1. Redistributions of source code must retain the copyright
16572+ * notice, this list of conditions and the following disclaimer.
16573+ * 2. Redistributions in binary form must reproduce the above copyright
16574+ * notice, this list of conditions and the following disclaimer in the
16575+ * documentation and/or other materials provided with the distribution.
16576+ * 3. All advertising materials mentioning features or use of this software
16577+ * must display the following acknowledgement:
16578+ * "This product includes cryptographic software written by
16579+ * Eric Young (eay@cryptsoft.com)"
16580+ * The word 'cryptographic' can be left out if the rouines from the library
16581+ * being used are not cryptographic related :-).
16582+ * 4. If you include any Windows specific code (or a derivative thereof) from
16583+ * the apps directory (application code) you must include an acknowledgement:
16584+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
16585+ *
16586+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
16587+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16588+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16589+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16590+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16591+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16592+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16593+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16594+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16595+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16596+ * SUCH DAMAGE.
16597+ *
16598+ * The licence and distribution terms for any publically available version or
16599+ * derivative of this code cannot be changed. i.e. this code cannot simply be
16600+ * copied and put under another distribution licence
16601+ * [including the GNU Public Licence.]
16602+ */
16603+
16604+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
16605+ * This is for machines with 64k code segment size restrictions. */
16606+
16607+#ifndef MSDOS
16608+#define TIMES
16609+#endif
16610+
16611+#include <stdio.h>
16612+#ifndef MSDOS
16613+#include <unistd.h>
16614+#else
16615+#include <io.h>
16616+extern void exit();
16617+#endif
16618+#include <signal.h>
16619+#ifndef VMS
16620+#ifndef _IRIX
16621+#include <time.h>
16622+#endif
16623+#ifdef TIMES
16624+#include <sys/types.h>
16625+#include <sys/times.h>
16626+#endif
16627+#else /* VMS */
16628+#include <types.h>
16629+struct tms {
16630+ time_t tms_utime;
16631+ time_t tms_stime;
16632+ time_t tms_uchild; /* I dunno... */
16633+ time_t tms_uchildsys; /* so these names are a guess :-) */
16634+ }
16635+#endif
16636+#ifndef TIMES
16637+#include <sys/timeb.h>
16638+#endif
16639+
16640+#ifdef sun
16641+#include <limits.h>
16642+#include <sys/param.h>
16643+#endif
16644+
16645+#include "des.h"
16646+#include "spr.h"
16647+
16648+#define DES_DEFAULT_OPTIONS
16649+
16650+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
16651+#define PART1
16652+#define PART2
16653+#define PART3
16654+#define PART4
16655+#endif
16656+
16657+#ifdef PART1
16658+
16659+#undef DES_UNROLL
16660+#undef DES_RISC1
16661+#undef DES_RISC2
16662+#undef DES_PTR
16663+#undef D_ENCRYPT
16664+#define des_encrypt des_encrypt_u4_cisc_idx
16665+#define des_encrypt2 des_encrypt2_u4_cisc_idx
16666+#define des_encrypt3 des_encrypt3_u4_cisc_idx
16667+#define des_decrypt3 des_decrypt3_u4_cisc_idx
16668+#undef HEADER_DES_LOCL_H
16669+#include "des_enc.c"
16670+
16671+#define DES_UNROLL
16672+#undef DES_RISC1
16673+#undef DES_RISC2
16674+#undef DES_PTR
16675+#undef D_ENCRYPT
16676+#undef des_encrypt
16677+#undef des_encrypt2
16678+#undef des_encrypt3
16679+#undef des_decrypt3
16680+#define des_encrypt des_encrypt_u16_cisc_idx
16681+#define des_encrypt2 des_encrypt2_u16_cisc_idx
16682+#define des_encrypt3 des_encrypt3_u16_cisc_idx
16683+#define des_decrypt3 des_decrypt3_u16_cisc_idx
16684+#undef HEADER_DES_LOCL_H
16685+#include "des_enc.c"
16686+
16687+#undef DES_UNROLL
16688+#define DES_RISC1
16689+#undef DES_RISC2
16690+#undef DES_PTR
16691+#undef D_ENCRYPT
16692+#undef des_encrypt
16693+#undef des_encrypt2
16694+#undef des_encrypt3
16695+#undef des_decrypt3
16696+#define des_encrypt des_encrypt_u4_risc1_idx
16697+#define des_encrypt2 des_encrypt2_u4_risc1_idx
16698+#define des_encrypt3 des_encrypt3_u4_risc1_idx
16699+#define des_decrypt3 des_decrypt3_u4_risc1_idx
16700+#undef HEADER_DES_LOCL_H
16701+#include "des_enc.c"
16702+
16703+#endif
16704+
16705+#ifdef PART2
16706+
16707+#undef DES_UNROLL
16708+#undef DES_RISC1
16709+#define DES_RISC2
16710+#undef DES_PTR
16711+#undef D_ENCRYPT
16712+#undef des_encrypt
16713+#undef des_encrypt2
16714+#undef des_encrypt3
16715+#undef des_decrypt3
16716+#define des_encrypt des_encrypt_u4_risc2_idx
16717+#define des_encrypt2 des_encrypt2_u4_risc2_idx
16718+#define des_encrypt3 des_encrypt3_u4_risc2_idx
16719+#define des_decrypt3 des_decrypt3_u4_risc2_idx
16720+#undef HEADER_DES_LOCL_H
16721+#include "des_enc.c"
16722+
16723+#define DES_UNROLL
16724+#define DES_RISC1
16725+#undef DES_RISC2
16726+#undef DES_PTR
16727+#undef D_ENCRYPT
16728+#undef des_encrypt
16729+#undef des_encrypt2
16730+#undef des_encrypt3
16731+#undef des_decrypt3
16732+#define des_encrypt des_encrypt_u16_risc1_idx
16733+#define des_encrypt2 des_encrypt2_u16_risc1_idx
16734+#define des_encrypt3 des_encrypt3_u16_risc1_idx
16735+#define des_decrypt3 des_decrypt3_u16_risc1_idx
16736+#undef HEADER_DES_LOCL_H
16737+#include "des_enc.c"
16738+
16739+#define DES_UNROLL
16740+#undef DES_RISC1
16741+#define DES_RISC2
16742+#undef DES_PTR
16743+#undef D_ENCRYPT
16744+#undef des_encrypt
16745+#undef des_encrypt2
16746+#undef des_encrypt3
16747+#undef des_decrypt3
16748+#define des_encrypt des_encrypt_u16_risc2_idx
16749+#define des_encrypt2 des_encrypt2_u16_risc2_idx
16750+#define des_encrypt3 des_encrypt3_u16_risc2_idx
16751+#define des_decrypt3 des_decrypt3_u16_risc2_idx
16752+#undef HEADER_DES_LOCL_H
16753+#include "des_enc.c"
16754+
16755+#endif
16756+
16757+#ifdef PART3
16758+
16759+#undef DES_UNROLL
16760+#undef DES_RISC1
16761+#undef DES_RISC2
16762+#define DES_PTR
16763+#undef D_ENCRYPT
16764+#undef des_encrypt
16765+#undef des_encrypt2
16766+#undef des_encrypt3
16767+#undef des_decrypt3
16768+#define des_encrypt des_encrypt_u4_cisc_ptr
16769+#define des_encrypt2 des_encrypt2_u4_cisc_ptr
16770+#define des_encrypt3 des_encrypt3_u4_cisc_ptr
16771+#define des_decrypt3 des_decrypt3_u4_cisc_ptr
16772+#undef HEADER_DES_LOCL_H
16773+#include "des_enc.c"
16774+
16775+#define DES_UNROLL
16776+#undef DES_RISC1
16777+#undef DES_RISC2
16778+#define DES_PTR
16779+#undef D_ENCRYPT
16780+#undef des_encrypt
16781+#undef des_encrypt2
16782+#undef des_encrypt3
16783+#undef des_decrypt3
16784+#define des_encrypt des_encrypt_u16_cisc_ptr
16785+#define des_encrypt2 des_encrypt2_u16_cisc_ptr
16786+#define des_encrypt3 des_encrypt3_u16_cisc_ptr
16787+#define des_decrypt3 des_decrypt3_u16_cisc_ptr
16788+#undef HEADER_DES_LOCL_H
16789+#include "des_enc.c"
16790+
16791+#undef DES_UNROLL
16792+#define DES_RISC1
16793+#undef DES_RISC2
16794+#define DES_PTR
16795+#undef D_ENCRYPT
16796+#undef des_encrypt
16797+#undef des_encrypt2
16798+#undef des_encrypt3
16799+#undef des_decrypt3
16800+#define des_encrypt des_encrypt_u4_risc1_ptr
16801+#define des_encrypt2 des_encrypt2_u4_risc1_ptr
16802+#define des_encrypt3 des_encrypt3_u4_risc1_ptr
16803+#define des_decrypt3 des_decrypt3_u4_risc1_ptr
16804+#undef HEADER_DES_LOCL_H
16805+#include "des_enc.c"
16806+
16807+#endif
16808+
16809+#ifdef PART4
16810+
16811+#undef DES_UNROLL
16812+#undef DES_RISC1
16813+#define DES_RISC2
16814+#define DES_PTR
16815+#undef D_ENCRYPT
16816+#undef des_encrypt
16817+#undef des_encrypt2
16818+#undef des_encrypt3
16819+#undef des_decrypt3
16820+#define des_encrypt des_encrypt_u4_risc2_ptr
16821+#define des_encrypt2 des_encrypt2_u4_risc2_ptr
16822+#define des_encrypt3 des_encrypt3_u4_risc2_ptr
16823+#define des_decrypt3 des_decrypt3_u4_risc2_ptr
16824+#undef HEADER_DES_LOCL_H
16825+#include "des_enc.c"
16826+
16827+#define DES_UNROLL
16828+#define DES_RISC1
16829+#undef DES_RISC2
16830+#define DES_PTR
16831+#undef D_ENCRYPT
16832+#undef des_encrypt
16833+#undef des_encrypt2
16834+#undef des_encrypt3
16835+#undef des_decrypt3
16836+#define des_encrypt des_encrypt_u16_risc1_ptr
16837+#define des_encrypt2 des_encrypt2_u16_risc1_ptr
16838+#define des_encrypt3 des_encrypt3_u16_risc1_ptr
16839+#define des_decrypt3 des_decrypt3_u16_risc1_ptr
16840+#undef HEADER_DES_LOCL_H
16841+#include "des_enc.c"
16842+
16843+#define DES_UNROLL
16844+#undef DES_RISC1
16845+#define DES_RISC2
16846+#define DES_PTR
16847+#undef D_ENCRYPT
16848+#undef des_encrypt
16849+#undef des_encrypt2
16850+#undef des_encrypt3
16851+#undef des_decrypt3
16852+#define des_encrypt des_encrypt_u16_risc2_ptr
16853+#define des_encrypt2 des_encrypt2_u16_risc2_ptr
16854+#define des_encrypt3 des_encrypt3_u16_risc2_ptr
16855+#define des_decrypt3 des_decrypt3_u16_risc2_ptr
16856+#undef HEADER_DES_LOCL_H
16857+#include "des_enc.c"
16858+
16859+#endif
16860+
16861+/* The following if from times(3) man page. It may need to be changed */
16862+#ifndef HZ
16863+# ifndef CLK_TCK
16864+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
16865+# ifndef VMS
16866+# define HZ 100.0
16867+# else /* VMS */
16868+# define HZ 100.0
16869+# endif
16870+# else /* _BSD_CLK_TCK_ */
16871+# define HZ ((double)_BSD_CLK_TCK_)
16872+# endif
16873+# else /* CLK_TCK */
16874+# define HZ ((double)CLK_TCK)
16875+# endif
16876+#endif
16877+
16878+#define BUFSIZE ((long)1024)
16879+long run=0;
16880+
16881+#ifndef NOPROTO
16882+double Time_F(int s);
16883+#else
16884+double Time_F();
16885+#endif
16886+
16887+#ifdef SIGALRM
16888+#if defined(__STDC__) || defined(sgi)
16889+#define SIGRETTYPE void
16890+#else
16891+#define SIGRETTYPE int
16892+#endif
16893+
16894+#ifndef NOPROTO
16895+SIGRETTYPE sig_done(int sig);
16896+#else
16897+SIGRETTYPE sig_done();
16898+#endif
16899+
16900+SIGRETTYPE sig_done(sig)
16901+int sig;
16902+ {
16903+ signal(SIGALRM,sig_done);
16904+ run=0;
16905+#ifdef LINT
16906+ sig=sig;
16907+#endif
16908+ }
16909+#endif
16910+
16911+#define START 0
16912+#define STOP 1
16913+
16914+double Time_F(s)
16915+int s;
16916+ {
16917+ double ret;
16918+#ifdef TIMES
16919+ static struct tms tstart,tend;
16920+
16921+ if (s == START)
16922+ {
16923+ times(&tstart);
16924+ return(0);
16925+ }
16926+ else
16927+ {
16928+ times(&tend);
16929+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
16930+ return((ret == 0.0)?1e-6:ret);
16931+ }
16932+#else /* !times() */
16933+ static struct timeb tstart,tend;
16934+ long i;
16935+
16936+ if (s == START)
16937+ {
16938+ ftime(&tstart);
16939+ return(0);
16940+ }
16941+ else
16942+ {
16943+ ftime(&tend);
16944+ i=(long)tend.millitm-(long)tstart.millitm;
16945+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
16946+ return((ret == 0.0)?1e-6:ret);
16947+ }
16948+#endif
16949+ }
16950+
16951+#ifdef SIGALRM
16952+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
16953+#else
16954+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
16955+#endif
16956+
16957+#define time_it(func,name,index) \
16958+ print_name(name); \
16959+ Time_F(START); \
16960+ for (count=0,run=1; COND(cb); count++) \
16961+ { \
16962+ unsigned long d[2]; \
16963+ func(d,&(sch[0]),DES_ENCRYPT); \
16964+ } \
16965+ tm[index]=Time_F(STOP); \
16966+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
16967+ tm[index]=((double)COUNT(cb))/tm[index];
16968+
16969+#define print_it(name,index) \
16970+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
16971+ tm[index]*8,1.0e6/tm[index]);
16972+
16973+int main(argc,argv)
16974+int argc;
16975+char **argv;
16976+ {
16977+ long count;
16978+ static unsigned char buf[BUFSIZE];
16979+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
16980+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
16981+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
16982+ des_key_schedule sch,sch2,sch3;
16983+ double d,tm[16],max=0;
16984+ int rank[16];
16985+ char *str[16];
16986+ int max_idx=0,i,num=0,j;
16987+#ifndef SIGALARM
16988+ long ca,cb,cc,cd,ce;
16989+#endif
16990+
16991+ for (i=0; i<12; i++)
16992+ {
16993+ tm[i]=0.0;
16994+ rank[i]=0;
16995+ }
16996+
16997+#ifndef TIMES
16998+ fprintf(stderr,"To get the most acurate results, try to run this\n");
16999+ fprintf(stderr,"program when this computer is idle.\n");
17000+#endif
17001+
17002+ des_set_key((C_Block *)key,sch);
17003+ des_set_key((C_Block *)key2,sch2);
17004+ des_set_key((C_Block *)key3,sch3);
17005+
17006+#ifndef SIGALRM
17007+ fprintf(stderr,"First we calculate the approximate speed ...\n");
17008+ des_set_key((C_Block *)key,sch);
17009+ count=10;
17010+ do {
17011+ long i;
17012+ unsigned long data[2];
17013+
17014+ count*=2;
17015+ Time_F(START);
17016+ for (i=count; i; i--)
17017+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
17018+ d=Time_F(STOP);
17019+ } while (d < 3.0);
17020+ ca=count;
17021+ cb=count*3;
17022+ cc=count*3*8/BUFSIZE+1;
17023+ cd=count*8/BUFSIZE+1;
17024+
17025+ ce=count/20+1;
17026+#define COND(d) (count != (d))
17027+#define COUNT(d) (d)
17028+#else
17029+#define COND(c) (run)
17030+#define COUNT(d) (count)
17031+ signal(SIGALRM,sig_done);
17032+ alarm(10);
17033+#endif
17034+
17035+#ifdef PART1
17036+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
17037+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
17038+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
17039+ num+=3;
17040+#endif
17041+#ifdef PART2
17042+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
17043+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
17044+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
17045+ num+=3;
17046+#endif
17047+#ifdef PART3
17048+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
17049+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
17050+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
17051+ num+=3;
17052+#endif
17053+#ifdef PART4
17054+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
17055+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
17056+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
17057+ num+=3;
17058+#endif
17059+
17060+#ifdef PART1
17061+ str[0]=" 4 c i";
17062+ print_it("des_encrypt_u4_cisc_idx ",0);
17063+ max=tm[0];
17064+ max_idx=0;
17065+ str[1]="16 c i";
17066+ print_it("des_encrypt_u16_cisc_idx ",1);
17067+ if (max < tm[1]) { max=tm[1]; max_idx=1; }
17068+ str[2]=" 4 r1 i";
17069+ print_it("des_encrypt_u4_risc1_idx ",2);
17070+ if (max < tm[2]) { max=tm[2]; max_idx=2; }
17071+#endif
17072+#ifdef PART2
17073+ str[3]="16 r1 i";
17074+ print_it("des_encrypt_u16_risc1_idx",3);
17075+ if (max < tm[3]) { max=tm[3]; max_idx=3; }
17076+ str[4]=" 4 r2 i";
17077+ print_it("des_encrypt_u4_risc2_idx ",4);
17078+ if (max < tm[4]) { max=tm[4]; max_idx=4; }
17079+ str[5]="16 r2 i";
17080+ print_it("des_encrypt_u16_risc2_idx",5);
17081+ if (max < tm[5]) { max=tm[5]; max_idx=5; }
17082+#endif
17083+#ifdef PART3
17084+ str[6]=" 4 c p";
17085+ print_it("des_encrypt_u4_cisc_ptr ",6);
17086+ if (max < tm[6]) { max=tm[6]; max_idx=6; }
17087+ str[7]="16 c p";
17088+ print_it("des_encrypt_u16_cisc_ptr ",7);
17089+ if (max < tm[7]) { max=tm[7]; max_idx=7; }
17090+ str[8]=" 4 r1 p";
17091+ print_it("des_encrypt_u4_risc1_ptr ",8);
17092+ if (max < tm[8]) { max=tm[8]; max_idx=8; }
17093+#endif
17094+#ifdef PART4
17095+ str[9]="16 r1 p";
17096+ print_it("des_encrypt_u16_risc1_ptr",9);
17097+ if (max < tm[9]) { max=tm[9]; max_idx=9; }
17098+ str[10]=" 4 r2 p";
17099+ print_it("des_encrypt_u4_risc2_ptr ",10);
17100+ if (max < tm[10]) { max=tm[10]; max_idx=10; }
17101+ str[11]="16 r2 p";
17102+ print_it("des_encrypt_u16_risc2_ptr",11);
17103+ if (max < tm[11]) { max=tm[11]; max_idx=11; }
17104+#endif
17105+ printf("options des ecb/s\n");
17106+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
17107+ d=tm[max_idx];
17108+ tm[max_idx]= -2.0;
17109+ max= -1.0;
17110+ for (;;)
17111+ {
17112+ for (i=0; i<12; i++)
17113+ {
17114+ if (max < tm[i]) { max=tm[i]; j=i; }
17115+ }
17116+ if (max < 0.0) break;
17117+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
17118+ tm[j]= -2.0;
17119+ max= -1.0;
17120+ }
17121+
17122+ switch (max_idx)
17123+ {
17124+ case 0:
17125+ printf("-DDES_DEFAULT_OPTIONS\n");
17126+ break;
17127+ case 1:
17128+ printf("-DDES_UNROLL\n");
17129+ break;
17130+ case 2:
17131+ printf("-DDES_RISC1\n");
17132+ break;
17133+ case 3:
17134+ printf("-DDES_UNROLL -DDES_RISC1\n");
17135+ break;
17136+ case 4:
17137+ printf("-DDES_RISC2\n");
17138+ break;
17139+ case 5:
17140+ printf("-DDES_UNROLL -DDES_RISC2\n");
17141+ break;
17142+ case 6:
17143+ printf("-DDES_PTR\n");
17144+ break;
17145+ case 7:
17146+ printf("-DDES_UNROLL -DDES_PTR\n");
17147+ break;
17148+ case 8:
17149+ printf("-DDES_RISC1 -DDES_PTR\n");
17150+ break;
17151+ case 9:
17152+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
17153+ break;
17154+ case 10:
17155+ printf("-DDES_RISC2 -DDES_PTR\n");
17156+ break;
17157+ case 11:
17158+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
17159+ break;
17160+ }
17161+ exit(0);
17162+#if defined(LINT) || defined(MSDOS)
17163+ return(0);
17164+#endif
17165+ }
17166diff -druN linux-noipsec/net/ipsec/libdes/des_ver.h linux/net/ipsec/libdes/des_ver.h
17167--- linux-noipsec/net/ipsec/libdes/des_ver.h Thu Jan 1 01:00:00 1970
17168+++ linux/net/ipsec/libdes/des_ver.h Thu Feb 18 17:41:13 1999
17169@@ -0,0 +1,60 @@
17170+/* crypto/des/des_ver.h */
17171+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
17172+ * All rights reserved.
17173+ *
17174+ * This package is an SSL implementation written
17175+ * by Eric Young (eay@cryptsoft.com).
17176+ * The implementation was written so as to conform with Netscapes SSL.
17177+ *
17178+ * This library is free for commercial and non-commercial use as long as
17179+ * the following conditions are aheared to. The following conditions
17180+ * apply to all code found in this distribution, be it the RC4, RSA,
17181+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
17182+ * included with this distribution is covered by the same copyright terms
17183+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
17184+ *
17185+ * Copyright remains Eric Young's, and as such any Copyright notices in
17186+ * the code are not to be removed.
17187+ * If this package is used in a product, Eric Young should be given attribution
17188+ * as the author of the parts of the library used.
17189+ * This can be in the form of a textual message at program startup or
17190+ * in documentation (online or textual) provided with the package.
17191+ *
17192+ * Redistribution and use in source and binary forms, with or without
17193+ * modification, are permitted provided that the following conditions
17194+ * are met:
17195+ * 1. Redistributions of source code must retain the copyright
17196+ * notice, this list of conditions and the following disclaimer.
17197+ * 2. Redistributions in binary form must reproduce the above copyright
17198+ * notice, this list of conditions and the following disclaimer in the
17199+ * documentation and/or other materials provided with the distribution.
17200+ * 3. All advertising materials mentioning features or use of this software
17201+ * must display the following acknowledgement:
17202+ * "This product includes cryptographic software written by
17203+ * Eric Young (eay@cryptsoft.com)"
17204+ * The word 'cryptographic' can be left out if the rouines from the library
17205+ * being used are not cryptographic related :-).
17206+ * 4. If you include any Windows specific code (or a derivative thereof) from
17207+ * the apps directory (application code) you must include an acknowledgement:
17208+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
17209+ *
17210+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
17211+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17212+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17213+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17214+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17215+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
17216+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17217+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
17218+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
17219+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
17220+ * SUCH DAMAGE.
17221+ *
17222+ * The licence and distribution terms for any publically available version or
17223+ * derivative of this code cannot be changed. i.e. this code cannot simply be
17224+ * copied and put under another distribution licence
17225+ * [including the GNU Public Licence.]
17226+ */
17227+
17228+extern char *DES_version; /* SSLeay version string */
17229+extern char *libdes_version; /* old libdes version string */
17230diff -druN linux-noipsec/net/ipsec/libdes/destest.c linux/net/ipsec/libdes/destest.c
17231--- linux-noipsec/net/ipsec/libdes/destest.c Thu Jan 1 01:00:00 1970
17232+++ linux/net/ipsec/libdes/destest.c Thu Feb 18 17:41:13 1999
17233@@ -0,0 +1,871 @@
17234+/* crypto/des/destest.c */
17235+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
17236+ * All rights reserved.
17237+ *
17238+ * This package is an SSL implementation written
17239+ * by Eric Young (eay@cryptsoft.com).
17240+ * The implementation was written so as to conform with Netscapes SSL.
17241+ *
17242+ * This library is free for commercial and non-commercial use as long as
17243+ * the following conditions are aheared to. The following conditions
17244+ * apply to all code found in this distribution, be it the RC4, RSA,
17245+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
17246+ * included with this distribution is covered by the same copyright terms
17247+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
17248+ *
17249+ * Copyright remains Eric Young's, and as such any Copyright notices in
17250+ * the code are not to be removed.
17251+ * If this package is used in a product, Eric Young should be given attribution
17252+ * as the author of the parts of the library used.
17253+ * This can be in the form of a textual message at program startup or
17254+ * in documentation (online or textual) provided with the package.
17255+ *
17256+ * Redistribution and use in source and binary forms, with or without
17257+ * modification, are permitted provided that the following conditions
17258+ * are met:
17259+ * 1. Redistributions of source code must retain the copyright
17260+ * notice, this list of conditions and the following disclaimer.
17261+ * 2. Redistributions in binary form must reproduce the above copyright
17262+ * notice, this list of conditions and the following disclaimer in the
17263+ * documentation and/or other materials provided with the distribution.
17264+ * 3. All advertising materials mentioning features or use of this software
17265+ * must display the following acknowledgement:
17266+ * "This product includes cryptographic software written by
17267+ * Eric Young (eay@cryptsoft.com)"
17268+ * The word 'cryptographic' can be left out if the rouines from the library
17269+ * being used are not cryptographic related :-).
17270+ * 4. If you include any Windows specific code (or a derivative thereof) from
17271+ * the apps directory (application code) you must include an acknowledgement:
17272+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
17273+ *
17274+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
17275+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17276+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17277+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17278+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17279+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
17280+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17281+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
17282+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
17283+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
17284+ * SUCH DAMAGE.
17285+ *
17286+ * The licence and distribution terms for any publically available version or
17287+ * derivative of this code cannot be changed. i.e. this code cannot simply be
17288+ * copied and put under another distribution licence
17289+ * [including the GNU Public Licence.]
17290+ */
17291+
17292+#if defined(WIN32) || defined(WIN16) || defined(WINDOWS)
17293+#ifndef MSDOS
17294+#define MSDOS
17295+#endif
17296+#endif
17297+
17298+#include <stdio.h>
17299+#include <stdlib.h>
17300+#ifndef MSDOS
17301+#include <unistd.h>
17302+#else
17303+#include <io.h>
17304+#endif
17305+#include <string.h>
17306+#include "des.h"
17307+
17308+/* tisk tisk - the test keys don't all have odd parity :-( */
17309+/* test data */
17310+#define NUM_TESTS 34
17311+static unsigned char key_data[NUM_TESTS][8]={
17312+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
17313+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
17314+ {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
17315+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
17316+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
17317+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
17318+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
17319+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
17320+ {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
17321+ {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
17322+ {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
17323+ {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
17324+ {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
17325+ {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
17326+ {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
17327+ {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
17328+ {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
17329+ {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
17330+ {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
17331+ {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
17332+ {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
17333+ {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
17334+ {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
17335+ {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
17336+ {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
17337+ {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
17338+ {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
17339+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
17340+ {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
17341+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
17342+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
17343+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
17344+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
17345+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
17346+
17347+static unsigned char plain_data[NUM_TESTS][8]={
17348+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
17349+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
17350+ {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
17351+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
17352+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
17353+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
17354+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
17355+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
17356+ {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
17357+ {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
17358+ {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
17359+ {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
17360+ {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
17361+ {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
17362+ {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
17363+ {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
17364+ {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
17365+ {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
17366+ {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
17367+ {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
17368+ {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
17369+ {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
17370+ {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
17371+ {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
17372+ {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
17373+ {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
17374+ {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
17375+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
17376+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
17377+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
17378+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
17379+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
17380+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
17381+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
17382+
17383+static unsigned char cipher_data[NUM_TESTS][8]={
17384+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
17385+ {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
17386+ {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
17387+ {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
17388+ {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
17389+ {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
17390+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
17391+ {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
17392+ {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
17393+ {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
17394+ {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
17395+ {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
17396+ {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
17397+ {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
17398+ {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
17399+ {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
17400+ {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
17401+ {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
17402+ {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
17403+ {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
17404+ {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
17405+ {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
17406+ {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
17407+ {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
17408+ {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
17409+ {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
17410+ {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
17411+ {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
17412+ {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
17413+ {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
17414+ {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
17415+ {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
17416+ {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
17417+ {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
17418+
17419+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
17420+ {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
17421+ {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
17422+ {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
17423+ {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
17424+ {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
17425+ {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
17426+ {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
17427+ {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
17428+ {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
17429+ {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
17430+ {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
17431+ {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
17432+ {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
17433+ {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
17434+ {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
17435+ {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
17436+ {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
17437+ {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
17438+ {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
17439+ {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
17440+ {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
17441+ {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
17442+ {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
17443+ {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
17444+ {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
17445+ {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
17446+ {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
17447+ {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
17448+ {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
17449+ {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
17450+ {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
17451+ {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
17452+ {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
17453+
17454+static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
17455+static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
17456+static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
17457+static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
17458+static char cbc_data[40]="7654321 Now is the time for \0001";
17459+
17460+static unsigned char cbc_ok[32]={
17461+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
17462+ 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
17463+ 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
17464+ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
17465+
17466+static unsigned char xcbc_ok[32]={
17467+ 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
17468+ 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
17469+ 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
17470+ 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
17471+ };
17472+
17473+static unsigned char cbc3_ok[32]={
17474+ 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
17475+ 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
17476+ 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
17477+ 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
17478+
17479+static unsigned char pcbc_ok[32]={
17480+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
17481+ 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
17482+ 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
17483+ 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
17484+
17485+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
17486+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
17487+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
17488+static unsigned char plain[24]=
17489+ {
17490+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
17491+ 0x20,0x74,0x68,0x65,0x20,0x74,
17492+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
17493+ 0x72,0x20,0x61,0x6c,0x6c,0x20
17494+ };
17495+static unsigned char cfb_cipher8[24]= {
17496+ 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
17497+ 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
17498+static unsigned char cfb_cipher16[24]={
17499+ 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
17500+ 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
17501+static unsigned char cfb_cipher32[24]={
17502+ 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
17503+ 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
17504+static unsigned char cfb_cipher48[24]={
17505+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
17506+ 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
17507+static unsigned char cfb_cipher64[24]={
17508+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
17509+ 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
17510+
17511+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
17512+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
17513+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
17514+static unsigned char ofb_cipher[24]=
17515+ {
17516+ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
17517+ 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
17518+ 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
17519+ };
17520+
17521+DES_LONG cbc_cksum_ret=0xB462FEF7L;
17522+unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
17523+
17524+#ifndef NOPROTO
17525+static char *pt(unsigned char *p);
17526+static int cfb_test(int bits, unsigned char *cfb_cipher);
17527+static int cfb64_test(unsigned char *cfb_cipher);
17528+static int ede_cfb64_test(unsigned char *cfb_cipher);
17529+#else
17530+static char *pt();
17531+static int cfb_test();
17532+static int cfb64_test();
17533+static int ede_cfb64_test();
17534+#endif
17535+
17536+int main(argc,argv)
17537+int argc;
17538+char *argv[];
17539+ {
17540+ int i,j,err=0;
17541+ des_cblock in,out,outin,iv3;
17542+ des_key_schedule ks,ks2,ks3;
17543+ unsigned char cbc_in[40];
17544+ unsigned char cbc_out[40];
17545+ DES_LONG cs;
17546+ unsigned char qret[4][4],cret[8];
17547+ DES_LONG lqret[4];
17548+ int num;
17549+ char *str;
17550+
17551+ printf("Doing ecb\n");
17552+ for (i=0; i<NUM_TESTS; i++)
17553+ {
17554+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
17555+ {
17556+ printf("Key error %2d:%d\n",i+1,j);
17557+ err=1;
17558+ }
17559+ memcpy(in,plain_data[i],8);
17560+ memset(out,0,8);
17561+ memset(outin,0,8);
17562+ des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT);
17563+ des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT);
17564+
17565+ if (memcmp(out,cipher_data[i],8) != 0)
17566+ {
17567+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
17568+ i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
17569+ pt(out));
17570+ err=1;
17571+ }
17572+ if (memcmp(in,outin,8) != 0)
17573+ {
17574+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
17575+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
17576+ err=1;
17577+ }
17578+ }
17579+
17580+#ifndef LIBDES_LIT
17581+ printf("Doing ede ecb\n");
17582+ for (i=0; i<(NUM_TESTS-1); i++)
17583+ {
17584+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
17585+ {
17586+ err=1;
17587+ printf("Key error %2d:%d\n",i+1,j);
17588+ }
17589+ if ((j=des_key_sched((C_Block *)(key_data[i+1]),ks2)) != 0)
17590+ {
17591+ printf("Key error %2d:%d\n",i+2,j);
17592+ err=1;
17593+ }
17594+ if ((j=des_key_sched((C_Block *)(key_data[i+2]),ks3)) != 0)
17595+ {
17596+ printf("Key error %2d:%d\n",i+3,j);
17597+ err=1;
17598+ }
17599+ memcpy(in,plain_data[i],8);
17600+ memset(out,0,8);
17601+ memset(outin,0,8);
17602+ des_ecb2_encrypt((C_Block *)in,(C_Block *)out,ks,ks2,
17603+ DES_ENCRYPT);
17604+ des_ecb2_encrypt((C_Block *)out,(C_Block *)outin,ks,ks2,
17605+ DES_DECRYPT);
17606+
17607+ if (memcmp(out,cipher_ecb2[i],8) != 0)
17608+ {
17609+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
17610+ i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
17611+ pt(out));
17612+ err=1;
17613+ }
17614+ if (memcmp(in,outin,8) != 0)
17615+ {
17616+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
17617+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
17618+ err=1;
17619+ }
17620+ }
17621+#endif
17622+
17623+ printf("Doing cbc\n");
17624+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
17625+ {
17626+ printf("Key error %d\n",j);
17627+ err=1;
17628+ }
17629+ memset(cbc_out,0,40);
17630+ memset(cbc_in,0,40);
17631+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
17632+ des_ncbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
17633+ (long)strlen((char *)cbc_data)+1,ks,
17634+ (C_Block *)iv3,DES_ENCRYPT);
17635+ if (memcmp(cbc_out,cbc_ok,32) != 0)
17636+ printf("cbc_encrypt encrypt error\n");
17637+
17638+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
17639+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
17640+ (long)strlen((char *)cbc_data)+1,ks,
17641+ (C_Block *)iv3,DES_DECRYPT);
17642+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
17643+ {
17644+ printf("cbc_encrypt decrypt error\n");
17645+ err=1;
17646+ }
17647+
17648+#ifndef LIBDES_LIT
17649+ printf("Doing desx cbc\n");
17650+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
17651+ {
17652+ printf("Key error %d\n",j);
17653+ err=1;
17654+ }
17655+ memset(cbc_out,0,40);
17656+ memset(cbc_in,0,40);
17657+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
17658+ des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
17659+ (long)strlen((char *)cbc_data)+1,ks,
17660+ (C_Block *)iv3,
17661+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT);
17662+ if (memcmp(cbc_out,xcbc_ok,32) != 0)
17663+ {
17664+ printf("des_xcbc_encrypt encrypt error\n");
17665+ }
17666+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
17667+ des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
17668+ (long)strlen((char *)cbc_data)+1,ks,
17669+ (C_Block *)iv3,
17670+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT);
17671+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
17672+ {
17673+ printf("des_xcbc_encrypt decrypt error\n");
17674+ err=1;
17675+ }
17676+#endif
17677+
17678+ printf("Doing ede cbc\n");
17679+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
17680+ {
17681+ printf("Key error %d\n",j);
17682+ err=1;
17683+ }
17684+ if ((j=des_key_sched((C_Block *)cbc2_key,ks2)) != 0)
17685+ {
17686+ printf("Key error %d\n",j);
17687+ err=1;
17688+ }
17689+ if ((j=des_key_sched((C_Block *)cbc3_key,ks3)) != 0)
17690+ {
17691+ printf("Key error %d\n",j);
17692+ err=1;
17693+ }
17694+ memset(cbc_out,0,40);
17695+ memset(cbc_in,0,40);
17696+ i=strlen((char *)cbc_data)+1;
17697+ /* i=((i+7)/8)*8; */
17698+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
17699+
17700+ des_ede3_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
17701+ 16L,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
17702+ des_ede3_cbc_encrypt((C_Block *)&(cbc_data[16]),
17703+ (C_Block *)&(cbc_out[16]),
17704+ (long)i-16,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
17705+ if (memcmp(cbc_out,cbc3_ok,
17706+ (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
17707+ {
17708+ printf("des_ede3_cbc_encrypt encrypt error\n");
17709+ err=1;
17710+ }
17711+
17712+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
17713+ des_ede3_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
17714+ (long)i,ks,ks2,ks3,(C_Block *)iv3,DES_DECRYPT);
17715+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
17716+ {
17717+ printf("des_ede3_cbc_encrypt decrypt error\n");
17718+ err=1;
17719+ }
17720+
17721+#ifndef LIBDES_LIT
17722+ printf("Doing pcbc\n");
17723+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
17724+ {
17725+ printf("Key error %d\n",j);
17726+ err=1;
17727+ }
17728+ memset(cbc_out,0,40);
17729+ memset(cbc_in,0,40);
17730+ des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
17731+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_ENCRYPT);
17732+ if (memcmp(cbc_out,pcbc_ok,32) != 0)
17733+ {
17734+ printf("pcbc_encrypt encrypt error\n");
17735+ err=1;
17736+ }
17737+ des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
17738+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_DECRYPT);
17739+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
17740+ {
17741+ printf("pcbc_encrypt decrypt error\n");
17742+ err=1;
17743+ }
17744+
17745+ printf("Doing ");
17746+ printf("cfb8 ");
17747+ err+=cfb_test(8,cfb_cipher8);
17748+ printf("cfb16 ");
17749+ err+=cfb_test(16,cfb_cipher16);
17750+ printf("cfb32 ");
17751+ err+=cfb_test(32,cfb_cipher32);
17752+ printf("cfb48 ");
17753+ err+=cfb_test(48,cfb_cipher48);
17754+ printf("cfb64 ");
17755+ err+=cfb_test(64,cfb_cipher64);
17756+
17757+ printf("cfb64() ");
17758+ err+=cfb64_test(cfb_cipher64);
17759+
17760+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
17761+ for (i=0; i<sizeof(plain); i++)
17762+ des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
17763+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
17764+ if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
17765+ {
17766+ printf("cfb_encrypt small encrypt error\n");
17767+ err=1;
17768+ }
17769+
17770+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
17771+ for (i=0; i<sizeof(plain); i++)
17772+ des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
17773+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
17774+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
17775+ {
17776+ printf("cfb_encrypt small decrypt error\n");
17777+ err=1;
17778+ }
17779+
17780+ printf("ede_cfb64() ");
17781+ err+=ede_cfb64_test(cfb_cipher64);
17782+
17783+ printf("done\n");
17784+
17785+ printf("Doing ofb\n");
17786+ des_key_sched((C_Block *)ofb_key,ks);
17787+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
17788+ des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks,
17789+ (C_Block *)ofb_tmp);
17790+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
17791+ {
17792+ printf("ofb_encrypt encrypt error\n");
17793+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
17794+ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
17795+ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
17796+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
17797+ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
17798+ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
17799+ err=1;
17800+ }
17801+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
17802+ des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
17803+ (C_Block *)ofb_tmp);
17804+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
17805+ {
17806+ printf("ofb_encrypt decrypt error\n");
17807+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
17808+ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
17809+ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
17810+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
17811+plain[8+0], plain[8+1], plain[8+2], plain[8+3],
17812+plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
17813+ err=1;
17814+ }
17815+
17816+ printf("Doing ofb64\n");
17817+ des_key_sched((C_Block *)ofb_key,ks);
17818+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
17819+ memset(ofb_buf1,0,sizeof(ofb_buf1));
17820+ memset(ofb_buf2,0,sizeof(ofb_buf1));
17821+ num=0;
17822+ for (i=0; i<sizeof(plain); i++)
17823+ {
17824+ des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,
17825+ (C_Block *)ofb_tmp,&num);
17826+ }
17827+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
17828+ {
17829+ printf("ofb64_encrypt encrypt error\n");
17830+ err=1;
17831+ }
17832+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
17833+ num=0;
17834+ des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
17835+ (C_Block *)ofb_tmp,&num);
17836+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
17837+ {
17838+ printf("ofb64_encrypt decrypt error\n");
17839+ err=1;
17840+ }
17841+
17842+ printf("Doing ede_ofb64\n");
17843+ des_key_sched((C_Block *)ofb_key,ks);
17844+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
17845+ memset(ofb_buf1,0,sizeof(ofb_buf1));
17846+ memset(ofb_buf2,0,sizeof(ofb_buf1));
17847+ num=0;
17848+ for (i=0; i<sizeof(plain); i++)
17849+ {
17850+ des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
17851+ (C_Block *)ofb_tmp,&num);
17852+ }
17853+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
17854+ {
17855+ printf("ede_ofb64_encrypt encrypt error\n");
17856+ err=1;
17857+ }
17858+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
17859+ num=0;
17860+ des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
17861+ ks,ks,(C_Block *)ofb_tmp,&num);
17862+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
17863+ {
17864+ printf("ede_ofb64_encrypt decrypt error\n");
17865+ err=1;
17866+ }
17867+
17868+ printf("Doing cbc_cksum\n");
17869+ des_key_sched((C_Block *)cbc_key,ks);
17870+ cs=des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cret,
17871+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv);
17872+ if (cs != cbc_cksum_ret)
17873+ {
17874+ printf("bad return value (%08lX), should be %08lX\n",
17875+ (unsigned long)cs,(unsigned long)cbc_cksum_ret);
17876+ err=1;
17877+ }
17878+ if (memcmp(cret,cbc_cksum_data,8) != 0)
17879+ {
17880+ printf("bad cbc_cksum block returned\n");
17881+ err=1;
17882+ }
17883+
17884+ printf("Doing quad_cksum\n");
17885+ cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret,
17886+ (long)strlen(cbc_data),2,(C_Block *)cbc_iv);
17887+ for (i=0; i<4; i++)
17888+ {
17889+ lqret[i]=0;
17890+ memcpy(&(lqret[i]),&(qret[i][0]),4);
17891+ }
17892+ { /* Big-endian fix */
17893+ static DES_LONG l=1;
17894+ static unsigned char *c=(unsigned char *)&l;
17895+ DES_LONG ll;
17896+
17897+ if (!c[0])
17898+ {
17899+ ll=lqret[0]^lqret[3];
17900+ lqret[0]^=ll;
17901+ lqret[3]^=ll;
17902+ ll=lqret[1]^lqret[2];
17903+ lqret[1]^=ll;
17904+ lqret[2]^=ll;
17905+ }
17906+ }
17907+ if (cs != 0x70d7a63aL)
17908+ {
17909+ printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
17910+ (unsigned long)cs);
17911+ err=1;
17912+ }
17913+ if (lqret[0] != 0x327eba8dL)
17914+ {
17915+ printf("quad_cksum error, out[0] %08lx is not %08lx\n",
17916+ (unsigned long)lqret[0],0x327eba8dL);
17917+ err=1;
17918+ }
17919+ if (lqret[1] != 0x201a49ccL)
17920+ {
17921+ printf("quad_cksum error, out[1] %08lx is not %08lx\n",
17922+ (unsigned long)lqret[1],0x201a49ccL);
17923+ err=1;
17924+ }
17925+ if (lqret[2] != 0x70d7a63aL)
17926+ {
17927+ printf("quad_cksum error, out[2] %08lx is not %08lx\n",
17928+ (unsigned long)lqret[2],0x70d7a63aL);
17929+ err=1;
17930+ }
17931+ if (lqret[3] != 0x501c2c26L)
17932+ {
17933+ printf("quad_cksum error, out[3] %08lx is not %08lx\n",
17934+ (unsigned long)lqret[3],0x501c2c26L);
17935+ err=1;
17936+ }
17937+#endif
17938+
17939+ printf("input word alignment test");
17940+ for (i=0; i<4; i++)
17941+ {
17942+ printf(" %d",i);
17943+ des_ncbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in,
17944+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
17945+ DES_ENCRYPT);
17946+ }
17947+ printf("\noutput word alignment test");
17948+ for (i=0; i<4; i++)
17949+ {
17950+ printf(" %d",i);
17951+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]),
17952+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
17953+ DES_ENCRYPT);
17954+ }
17955+ printf("\n");
17956+ printf("fast crypt test ");
17957+ str=crypt("testing","ef");
17958+ if (strcmp("efGnQx2725bI2",str) != 0)
17959+ {
17960+ printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
17961+ err=1;
17962+ }
17963+ str=crypt("bca76;23","yA");
17964+ if (strcmp("yA1Rp/1hZXIJk",str) != 0)
17965+ {
17966+ printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
17967+ err=1;
17968+ }
17969+ printf("\n");
17970+ exit(err);
17971+ return(0);
17972+ }
17973+
17974+static char *pt(p)
17975+unsigned char *p;
17976+ {
17977+ static char bufs[10][20];
17978+ static int bnum=0;
17979+ char *ret;
17980+ int i;
17981+ static char *f="0123456789ABCDEF";
17982+
17983+ ret= &(bufs[bnum++][0]);
17984+ bnum%=10;
17985+ for (i=0; i<8; i++)
17986+ {
17987+ ret[i*2]=f[(p[i]>>4)&0xf];
17988+ ret[i*2+1]=f[p[i]&0xf];
17989+ }
17990+ ret[16]='\0';
17991+ return(ret);
17992+ }
17993+
17994+#ifndef LIBDES_LIT
17995+
17996+static int cfb_test(bits, cfb_cipher)
17997+int bits;
17998+unsigned char *cfb_cipher;
17999+ {
18000+ des_key_schedule ks;
18001+ int i,err=0;
18002+
18003+ des_key_sched((C_Block *)cfb_key,ks);
18004+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
18005+ des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks,
18006+ (C_Block *)cfb_tmp,DES_ENCRYPT);
18007+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
18008+ {
18009+ err=1;
18010+ printf("cfb_encrypt encrypt error\n");
18011+ for (i=0; i<24; i+=8)
18012+ printf("%s\n",pt(&(cfb_buf1[i])));
18013+ }
18014+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
18015+ des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks,
18016+ (C_Block *)cfb_tmp,DES_DECRYPT);
18017+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
18018+ {
18019+ err=1;
18020+ printf("cfb_encrypt decrypt error\n");
18021+ for (i=0; i<24; i+=8)
18022+ printf("%s\n",pt(&(cfb_buf1[i])));
18023+ }
18024+ return(err);
18025+ }
18026+
18027+static int cfb64_test(cfb_cipher)
18028+unsigned char *cfb_cipher;
18029+ {
18030+ des_key_schedule ks;
18031+ int err=0,i,n;
18032+
18033+ des_key_sched((C_Block *)cfb_key,ks);
18034+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
18035+ n=0;
18036+ des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,
18037+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
18038+ des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
18039+ (long)sizeof(plain)-12,ks,
18040+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
18041+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
18042+ {
18043+ err=1;
18044+ printf("cfb_encrypt encrypt error\n");
18045+ for (i=0; i<24; i+=8)
18046+ printf("%s\n",pt(&(cfb_buf1[i])));
18047+ }
18048+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
18049+ n=0;
18050+ des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,
18051+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
18052+ des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
18053+ (long)sizeof(plain)-17,ks,
18054+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
18055+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
18056+ {
18057+ err=1;
18058+ printf("cfb_encrypt decrypt error\n");
18059+ for (i=0; i<24; i+=8)
18060+ printf("%s\n",pt(&(cfb_buf2[i])));
18061+ }
18062+ return(err);
18063+ }
18064+
18065+static int ede_cfb64_test(cfb_cipher)
18066+unsigned char *cfb_cipher;
18067+ {
18068+ des_key_schedule ks;
18069+ int err=0,i,n;
18070+
18071+ des_key_sched((C_Block *)cfb_key,ks);
18072+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
18073+ n=0;
18074+ des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks,
18075+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
18076+ des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
18077+ (long)sizeof(plain)-12,ks,ks,ks,
18078+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
18079+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
18080+ {
18081+ err=1;
18082+ printf("ede_cfb_encrypt encrypt error\n");
18083+ for (i=0; i<24; i+=8)
18084+ printf("%s\n",pt(&(cfb_buf1[i])));
18085+ }
18086+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
18087+ n=0;
18088+ des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
18089+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
18090+ des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
18091+ (long)sizeof(plain)-17,ks,ks,ks,
18092+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
18093+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
18094+ {
18095+ err=1;
18096+ printf("ede_cfb_encrypt decrypt error\n");
18097+ for (i=0; i<24; i+=8)
18098+ printf("%s\n",pt(&(cfb_buf2[i])));
18099+ }
18100+ return(err);
18101+ }
18102+
18103+#endif
18104+
18105diff -druN linux-noipsec/net/ipsec/libdes/ecb_enc.c linux/net/ipsec/libdes/ecb_enc.c
18106--- linux-noipsec/net/ipsec/libdes/ecb_enc.c Thu Jan 1 01:00:00 1970
18107+++ linux/net/ipsec/libdes/ecb_enc.c Tue Apr 6 00:02:01 1999
18108@@ -0,0 +1,128 @@
18109+/* crypto/des/ecb_enc.c */
18110+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18111+ * All rights reserved.
18112+ *
18113+ * This package is an SSL implementation written
18114+ * by Eric Young (eay@cryptsoft.com).
18115+ * The implementation was written so as to conform with Netscapes SSL.
18116+ *
18117+ * This library is free for commercial and non-commercial use as long as
18118+ * the following conditions are aheared to. The following conditions
18119+ * apply to all code found in this distribution, be it the RC4, RSA,
18120+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18121+ * included with this distribution is covered by the same copyright terms
18122+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18123+ *
18124+ * Copyright remains Eric Young's, and as such any Copyright notices in
18125+ * the code are not to be removed.
18126+ * If this package is used in a product, Eric Young should be given attribution
18127+ * as the author of the parts of the library used.
18128+ * This can be in the form of a textual message at program startup or
18129+ * in documentation (online or textual) provided with the package.
18130+ *
18131+ * Redistribution and use in source and binary forms, with or without
18132+ * modification, are permitted provided that the following conditions
18133+ * are met:
18134+ * 1. Redistributions of source code must retain the copyright
18135+ * notice, this list of conditions and the following disclaimer.
18136+ * 2. Redistributions in binary form must reproduce the above copyright
18137+ * notice, this list of conditions and the following disclaimer in the
18138+ * documentation and/or other materials provided with the distribution.
18139+ * 3. All advertising materials mentioning features or use of this software
18140+ * must display the following acknowledgement:
18141+ * "This product includes cryptographic software written by
18142+ * Eric Young (eay@cryptsoft.com)"
18143+ * The word 'cryptographic' can be left out if the rouines from the library
18144+ * being used are not cryptographic related :-).
18145+ * 4. If you include any Windows specific code (or a derivative thereof) from
18146+ * the apps directory (application code) you must include an acknowledgement:
18147+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18148+ *
18149+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18150+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18151+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18152+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18153+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18154+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18155+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18156+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18157+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18158+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18159+ * SUCH DAMAGE.
18160+ *
18161+ * The licence and distribution terms for any publically available version or
18162+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18163+ * copied and put under another distribution licence
18164+ * [including the GNU Public Licence.]
18165+ */
18166+
18167+#include "des_locl.h"
18168+#include "spr.h"
18169+
18170+char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
18171+char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
18172+
18173+/* RCSID $Id$ */
18174+/* This function ifdef'ed out for FreeS/WAN project. */
18175+#ifdef notdef
18176+char *des_options()
18177+ {
18178+ static int init=1;
18179+ static char buf[32];
18180+
18181+ if (init)
18182+ {
18183+ char *ptr,*unroll,*risc,*size;
18184+
18185+ init=0;
18186+#ifdef DES_PTR
18187+ ptr="ptr";
18188+#else
18189+ ptr="idx";
18190+#endif
18191+#if defined(DES_RISC1) || defined(DES_RISC2)
18192+#ifdef DES_RISC1
18193+ risc="risc1";
18194+#endif
18195+#ifdef DES_RISC2
18196+ risc="risc2";
18197+#endif
18198+#else
18199+ risc="cisc";
18200+#endif
18201+#ifdef DES_UNROLL
18202+ unroll="16";
18203+#else
18204+ unroll="4";
18205+#endif
18206+ if (sizeof(DES_LONG) != sizeof(long))
18207+ size="int";
18208+ else
18209+ size="long";
18210+ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
18211+ }
18212+ return(buf);
18213+ }
18214+#endif
18215+
18216+
18217+void des_ecb_encrypt(input, output, ks, enc)
18218+des_cblock (*input);
18219+des_cblock (*output);
18220+des_key_schedule ks;
18221+int enc;
18222+ {
18223+ register DES_LONG l;
18224+ register unsigned char *in,*out;
18225+ DES_LONG ll[2];
18226+
18227+ in=(unsigned char *)input;
18228+ out=(unsigned char *)output;
18229+ c2l(in,l); ll[0]=l;
18230+ c2l(in,l); ll[1]=l;
18231+ des_encrypt(ll,ks,enc);
18232+ l=ll[0]; l2c(l,out);
18233+ l=ll[1]; l2c(l,out);
18234+ l=ll[0]=ll[1]=0;
18235+ }
18236+
18237diff -druN linux-noipsec/net/ipsec/libdes/fcrypt.c linux/net/ipsec/libdes/fcrypt.c
18238--- linux-noipsec/net/ipsec/libdes/fcrypt.c Thu Jan 1 01:00:00 1970
18239+++ linux/net/ipsec/libdes/fcrypt.c Wed Oct 4 16:54:11 2000
18240@@ -0,0 +1,152 @@
18241+/* NOCW */
18242+
18243+/* This version of crypt has been developed from my MIT compatable
18244+ * DES library.
18245+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
18246+ * Eric Young (eay@cryptsoft.com)
18247+ */
18248+
18249+/* Modification by Jens Kupferschmidt (Cu)
18250+ * I have included directive PARA for shared memory computers.
18251+ * I have included a directive LONGCRYPT to using this routine to cipher
18252+ * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN
18253+ * definition is the maximum of lenght of password and can changed. I have
18254+ * defined 24.
18255+ */
18256+
18257+#include "des_locl.h"
18258+
18259+/* Added more values to handle illegal salt values the way normal
18260+ * crypt() implementations do. The patch was sent by
18261+ * Bjorn Gronvall <bg@sics.se>
18262+ */
18263+static unsigned const char con_salt[128]={
18264+0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
18265+0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
18266+0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
18267+0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
18268+0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
18269+0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
18270+0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
18271+0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
18272+0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
18273+0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
18274+0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
18275+0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
18276+0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
18277+0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
18278+0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
18279+0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
18280+};
18281+
18282+static unsigned const char cov_2char[64]={
18283+0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
18284+0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
18285+0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
18286+0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
18287+0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
18288+0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
18289+0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
18290+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
18291+};
18292+
18293+#ifndef NOPROTO
18294+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
18295+ DES_LONG Eswap0, DES_LONG Eswap1);
18296+
18297+#ifdef PERL5
18298+char *des_crypt(const char *buf,const char *salt);
18299+#else
18300+char *crypt(const char *buf,const char *salt);
18301+#endif
18302+#else
18303+void fcrypt_body();
18304+#ifdef PERL5
18305+char *des_crypt();
18306+#else
18307+char *crypt();
18308+#endif
18309+#endif
18310+
18311+#ifdef PERL5
18312+char *des_crypt(buf,salt)
18313+#else
18314+char *crypt(buf,salt)
18315+#endif
18316+const char *buf;
18317+const char *salt;
18318+ {
18319+ static char buff[14];
18320+
18321+ return(des_fcrypt(buf,salt,buff));
18322+ }
18323+
18324+
18325+char *des_fcrypt(buf,salt,ret)
18326+const char *buf;
18327+const char *salt;
18328+char *ret;
18329+ {
18330+ unsigned int i,j,x,y;
18331+ DES_LONG Eswap0,Eswap1;
18332+ DES_LONG out[2],ll;
18333+ des_cblock key;
18334+ des_key_schedule ks;
18335+ unsigned char bb[9];
18336+ unsigned char *b=bb;
18337+ unsigned char c,u;
18338+
18339+ /* eay 25/08/92
18340+ * If you call crypt("pwd","*") as often happens when you
18341+ * have * as the pwd field in /etc/passwd, the function
18342+ * returns *\0XXXXXXXXX
18343+ * The \0 makes the string look like * so the pwd "*" would
18344+ * crypt to "*". This was found when replacing the crypt in
18345+ * our shared libraries. People found that the disbled
18346+ * accounts effectivly had no passwd :-(. */
18347+ x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
18348+ Eswap0=con_salt[x]<<2;
18349+ x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
18350+ Eswap1=con_salt[x]<<6;
18351+
18352+/* EAY
18353+r=strlen(buf);
18354+r=(r+7)/8;
18355+*/
18356+ for (i=0; i<8; i++)
18357+ {
18358+ c= *(buf++);
18359+ if (!c) break;
18360+ key[i]=(c<<1);
18361+ }
18362+ for (; i<8; i++)
18363+ key[i]=0;
18364+
18365+ des_set_key((des_cblock *)(key),ks);
18366+ fcrypt_body(&(out[0]),ks,Eswap0,Eswap1);
18367+
18368+ ll=out[0]; l2c(ll,b);
18369+ ll=out[1]; l2c(ll,b);
18370+ y=0;
18371+ u=0x80;
18372+ bb[8]=0;
18373+ for (i=2; i<13; i++)
18374+ {
18375+ c=0;
18376+ for (j=0; j<6; j++)
18377+ {
18378+ c<<=1;
18379+ if (bb[y] & u) c|=1;
18380+ u>>=1;
18381+ if (!u)
18382+ {
18383+ y++;
18384+ u=0x80;
18385+ }
18386+ }
18387+ ret[i]=cov_2char[c];
18388+ }
18389+ ret[13]='\0';
18390+ return(ret);
18391+ }
18392+
18393diff -druN linux-noipsec/net/ipsec/libdes/fcrypt_b.c linux/net/ipsec/libdes/fcrypt_b.c
18394--- linux-noipsec/net/ipsec/libdes/fcrypt_b.c Thu Jan 1 01:00:00 1970
18395+++ linux/net/ipsec/libdes/fcrypt_b.c Thu Feb 18 17:41:14 1999
18396@@ -0,0 +1,148 @@
18397+/* crypto/des/fcrypt_b.c */
18398+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18399+ * All rights reserved.
18400+ *
18401+ * This package is an SSL implementation written
18402+ * by Eric Young (eay@cryptsoft.com).
18403+ * The implementation was written so as to conform with Netscapes SSL.
18404+ *
18405+ * This library is free for commercial and non-commercial use as long as
18406+ * the following conditions are aheared to. The following conditions
18407+ * apply to all code found in this distribution, be it the RC4, RSA,
18408+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18409+ * included with this distribution is covered by the same copyright terms
18410+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18411+ *
18412+ * Copyright remains Eric Young's, and as such any Copyright notices in
18413+ * the code are not to be removed.
18414+ * If this package is used in a product, Eric Young should be given attribution
18415+ * as the author of the parts of the library used.
18416+ * This can be in the form of a textual message at program startup or
18417+ * in documentation (online or textual) provided with the package.
18418+ *
18419+ * Redistribution and use in source and binary forms, with or without
18420+ * modification, are permitted provided that the following conditions
18421+ * are met:
18422+ * 1. Redistributions of source code must retain the copyright
18423+ * notice, this list of conditions and the following disclaimer.
18424+ * 2. Redistributions in binary form must reproduce the above copyright
18425+ * notice, this list of conditions and the following disclaimer in the
18426+ * documentation and/or other materials provided with the distribution.
18427+ * 3. All advertising materials mentioning features or use of this software
18428+ * must display the following acknowledgement:
18429+ * "This product includes cryptographic software written by
18430+ * Eric Young (eay@cryptsoft.com)"
18431+ * The word 'cryptographic' can be left out if the rouines from the library
18432+ * being used are not cryptographic related :-).
18433+ * 4. If you include any Windows specific code (or a derivative thereof) from
18434+ * the apps directory (application code) you must include an acknowledgement:
18435+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18436+ *
18437+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18438+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18439+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18440+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18441+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18442+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18443+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18444+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18445+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18446+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18447+ * SUCH DAMAGE.
18448+ *
18449+ * The licence and distribution terms for any publically available version or
18450+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18451+ * copied and put under another distribution licence
18452+ * [including the GNU Public Licence.]
18453+ */
18454+
18455+#include <stdio.h>
18456+
18457+/* This version of crypt has been developed from my MIT compatable
18458+ * DES library.
18459+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
18460+ * Eric Young (eay@cryptsoft.com)
18461+ */
18462+
18463+#define DES_FCRYPT
18464+#include "des_locl.h"
18465+#undef DES_FCRYPT
18466+
18467+#undef PERM_OP
18468+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
18469+ (b)^=(t),\
18470+ (a)^=((t)<<(n)))
18471+
18472+#undef HPERM_OP
18473+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
18474+ (a)=(a)^(t)^(t>>(16-(n))))\
18475+
18476+void fcrypt_body(out, ks, Eswap0, Eswap1)
18477+DES_LONG *out;
18478+des_key_schedule ks;
18479+DES_LONG Eswap0;
18480+DES_LONG Eswap1;
18481+ {
18482+ register DES_LONG l,r,t,u;
18483+#ifdef DES_PTR
18484+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18485+#endif
18486+ register DES_LONG *s;
18487+ register int j;
18488+ register DES_LONG E0,E1;
18489+
18490+ l=0;
18491+ r=0;
18492+
18493+ s=(DES_LONG *)ks;
18494+ E0=Eswap0;
18495+ E1=Eswap1;
18496+
18497+ for (j=0; j<25; j++)
18498+ {
18499+#ifdef DES_UNROLL
18500+ register int i;
18501+
18502+ for (i=0; i<32; i+=8)
18503+ {
18504+ D_ENCRYPT(l,r,i+0); /* 1 */
18505+ D_ENCRYPT(r,l,i+2); /* 2 */
18506+ D_ENCRYPT(l,r,i+4); /* 1 */
18507+ D_ENCRYPT(r,l,i+6); /* 2 */
18508+ }
18509+#else
18510+ D_ENCRYPT(l,r, 0); /* 1 */
18511+ D_ENCRYPT(r,l, 2); /* 2 */
18512+ D_ENCRYPT(l,r, 4); /* 3 */
18513+ D_ENCRYPT(r,l, 6); /* 4 */
18514+ D_ENCRYPT(l,r, 8); /* 5 */
18515+ D_ENCRYPT(r,l,10); /* 6 */
18516+ D_ENCRYPT(l,r,12); /* 7 */
18517+ D_ENCRYPT(r,l,14); /* 8 */
18518+ D_ENCRYPT(l,r,16); /* 9 */
18519+ D_ENCRYPT(r,l,18); /* 10 */
18520+ D_ENCRYPT(l,r,20); /* 11 */
18521+ D_ENCRYPT(r,l,22); /* 12 */
18522+ D_ENCRYPT(l,r,24); /* 13 */
18523+ D_ENCRYPT(r,l,26); /* 14 */
18524+ D_ENCRYPT(l,r,28); /* 15 */
18525+ D_ENCRYPT(r,l,30); /* 16 */
18526+#endif
18527+
18528+ t=l;
18529+ l=r;
18530+ r=t;
18531+ }
18532+ l=ROTATE(l,3)&0xffffffffL;
18533+ r=ROTATE(r,3)&0xffffffffL;
18534+
18535+ PERM_OP(l,r,t, 1,0x55555555L);
18536+ PERM_OP(r,l,t, 8,0x00ff00ffL);
18537+ PERM_OP(l,r,t, 2,0x33333333L);
18538+ PERM_OP(r,l,t,16,0x0000ffffL);
18539+ PERM_OP(l,r,t, 4,0x0f0f0f0fL);
18540+
18541+ out[0]=r;
18542+ out[1]=l;
18543+ }
18544+
18545diff -druN linux-noipsec/net/ipsec/libdes/podd.h linux/net/ipsec/libdes/podd.h
18546--- linux-noipsec/net/ipsec/libdes/podd.h Thu Jan 1 01:00:00 1970
18547+++ linux/net/ipsec/libdes/podd.h Thu Feb 18 17:41:15 1999
18548@@ -0,0 +1,75 @@
18549+/* crypto/des/podd.h */
18550+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18551+ * All rights reserved.
18552+ *
18553+ * This package is an SSL implementation written
18554+ * by Eric Young (eay@cryptsoft.com).
18555+ * The implementation was written so as to conform with Netscapes SSL.
18556+ *
18557+ * This library is free for commercial and non-commercial use as long as
18558+ * the following conditions are aheared to. The following conditions
18559+ * apply to all code found in this distribution, be it the RC4, RSA,
18560+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18561+ * included with this distribution is covered by the same copyright terms
18562+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18563+ *
18564+ * Copyright remains Eric Young's, and as such any Copyright notices in
18565+ * the code are not to be removed.
18566+ * If this package is used in a product, Eric Young should be given attribution
18567+ * as the author of the parts of the library used.
18568+ * This can be in the form of a textual message at program startup or
18569+ * in documentation (online or textual) provided with the package.
18570+ *
18571+ * Redistribution and use in source and binary forms, with or without
18572+ * modification, are permitted provided that the following conditions
18573+ * are met:
18574+ * 1. Redistributions of source code must retain the copyright
18575+ * notice, this list of conditions and the following disclaimer.
18576+ * 2. Redistributions in binary form must reproduce the above copyright
18577+ * notice, this list of conditions and the following disclaimer in the
18578+ * documentation and/or other materials provided with the distribution.
18579+ * 3. All advertising materials mentioning features or use of this software
18580+ * must display the following acknowledgement:
18581+ * "This product includes cryptographic software written by
18582+ * Eric Young (eay@cryptsoft.com)"
18583+ * The word 'cryptographic' can be left out if the rouines from the library
18584+ * being used are not cryptographic related :-).
18585+ * 4. If you include any Windows specific code (or a derivative thereof) from
18586+ * the apps directory (application code) you must include an acknowledgement:
18587+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18588+ *
18589+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18590+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18591+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18592+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18593+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18594+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18595+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18596+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18597+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18598+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18599+ * SUCH DAMAGE.
18600+ *
18601+ * The licence and distribution terms for any publically available version or
18602+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18603+ * copied and put under another distribution licence
18604+ * [including the GNU Public Licence.]
18605+ */
18606+
18607+static const unsigned char odd_parity[256]={
18608+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
18609+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
18610+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
18611+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
18612+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
18613+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
18614+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
18615+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
18616+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
18617+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
18618+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
18619+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
18620+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
18621+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
18622+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
18623+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
18624diff -druN linux-noipsec/net/ipsec/libdes/set_key.c linux/net/ipsec/libdes/set_key.c
18625--- linux-noipsec/net/ipsec/libdes/set_key.c Thu Jan 1 01:00:00 1970
18626+++ linux/net/ipsec/libdes/set_key.c Thu Feb 18 17:41:15 1999
18627@@ -0,0 +1,246 @@
18628+/* crypto/des/set_key.c */
18629+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18630+ * All rights reserved.
18631+ *
18632+ * This package is an SSL implementation written
18633+ * by Eric Young (eay@cryptsoft.com).
18634+ * The implementation was written so as to conform with Netscapes SSL.
18635+ *
18636+ * This library is free for commercial and non-commercial use as long as
18637+ * the following conditions are aheared to. The following conditions
18638+ * apply to all code found in this distribution, be it the RC4, RSA,
18639+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18640+ * included with this distribution is covered by the same copyright terms
18641+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18642+ *
18643+ * Copyright remains Eric Young's, and as such any Copyright notices in
18644+ * the code are not to be removed.
18645+ * If this package is used in a product, Eric Young should be given attribution
18646+ * as the author of the parts of the library used.
18647+ * This can be in the form of a textual message at program startup or
18648+ * in documentation (online or textual) provided with the package.
18649+ *
18650+ * Redistribution and use in source and binary forms, with or without
18651+ * modification, are permitted provided that the following conditions
18652+ * are met:
18653+ * 1. Redistributions of source code must retain the copyright
18654+ * notice, this list of conditions and the following disclaimer.
18655+ * 2. Redistributions in binary form must reproduce the above copyright
18656+ * notice, this list of conditions and the following disclaimer in the
18657+ * documentation and/or other materials provided with the distribution.
18658+ * 3. All advertising materials mentioning features or use of this software
18659+ * must display the following acknowledgement:
18660+ * "This product includes cryptographic software written by
18661+ * Eric Young (eay@cryptsoft.com)"
18662+ * The word 'cryptographic' can be left out if the rouines from the library
18663+ * being used are not cryptographic related :-).
18664+ * 4. If you include any Windows specific code (or a derivative thereof) from
18665+ * the apps directory (application code) you must include an acknowledgement:
18666+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18667+ *
18668+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18669+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18670+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18671+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18672+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18673+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18674+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18675+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18676+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18677+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18678+ * SUCH DAMAGE.
18679+ *
18680+ * The licence and distribution terms for any publically available version or
18681+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18682+ * copied and put under another distribution licence
18683+ * [including the GNU Public Licence.]
18684+ */
18685+
18686+/* set_key.c v 1.4 eay 24/9/91
18687+ * 1.4 Speed up by 400% :-)
18688+ * 1.3 added register declarations.
18689+ * 1.2 unrolled make_key_sched a bit more
18690+ * 1.1 added norm_expand_bits
18691+ * 1.0 First working version
18692+ */
18693+#include "des_locl.h"
18694+#include "podd.h"
18695+#include "sk.h"
18696+
18697+#ifndef NOPROTO
18698+static int check_parity(des_cblock (*key));
18699+#else
18700+static int check_parity();
18701+#endif
18702+
18703+int des_check_key=0;
18704+
18705+void des_set_odd_parity(key)
18706+des_cblock (*key);
18707+ {
18708+ int i;
18709+
18710+ for (i=0; i<DES_KEY_SZ; i++)
18711+ (*key)[i]=odd_parity[(*key)[i]];
18712+ }
18713+
18714+static int check_parity(key)
18715+des_cblock (*key);
18716+ {
18717+ int i;
18718+
18719+ for (i=0; i<DES_KEY_SZ; i++)
18720+ {
18721+ if ((*key)[i] != odd_parity[(*key)[i]])
18722+ return(0);
18723+ }
18724+ return(1);
18725+ }
18726+
18727+/* Weak and semi week keys as take from
18728+ * %A D.W. Davies
18729+ * %A W.L. Price
18730+ * %T Security for Computer Networks
18731+ * %I John Wiley & Sons
18732+ * %D 1984
18733+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
18734+ * (and actual cblock values).
18735+ */
18736+#define NUM_WEAK_KEY 16
18737+static des_cblock weak_keys[NUM_WEAK_KEY]={
18738+ /* weak keys */
18739+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
18740+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
18741+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
18742+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
18743+ /* semi-weak keys */
18744+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
18745+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
18746+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
18747+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
18748+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
18749+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
18750+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
18751+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
18752+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
18753+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
18754+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
18755+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
18756+
18757+int des_is_weak_key(key)
18758+des_cblock (*key);
18759+ {
18760+ int i;
18761+
18762+ for (i=0; i<NUM_WEAK_KEY; i++)
18763+ /* Added == 0 to comparision, I obviously don't run
18764+ * this section very often :-(, thanks to
18765+ * engineering@MorningStar.Com for the fix
18766+ * eay 93/06/29
18767+ * Another problem, I was comparing only the first 4
18768+ * bytes, 97/03/18 */
18769+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
18770+ return(0);
18771+ }
18772+
18773+/* NOW DEFINED IN des_local.h
18774+ * See ecb_encrypt.c for a pseudo description of these macros.
18775+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
18776+ * (b)^=(t),\
18777+ * (a)=((a)^((t)<<(n))))
18778+ */
18779+
18780+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
18781+ (a)=(a)^(t)^(t>>(16-(n))))
18782+
18783+/* return 0 if key parity is odd (correct),
18784+ * return -1 if key parity error,
18785+ * return -2 if illegal weak key.
18786+ */
18787+int des_set_key(key, schedule)
18788+des_cblock (*key);
18789+des_key_schedule schedule;
18790+ {
18791+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
18792+ register DES_LONG c,d,t,s,t2;
18793+ register unsigned char *in;
18794+ register DES_LONG *k;
18795+ register int i;
18796+
18797+ if (des_check_key)
18798+ {
18799+ if (!check_parity(key))
18800+ return(-1);
18801+
18802+ if (des_is_weak_key(key))
18803+ return(-2);
18804+ }
18805+
18806+ k=(DES_LONG *)schedule;
18807+ in=(unsigned char *)key;
18808+
18809+ c2l(in,c);
18810+ c2l(in,d);
18811+
18812+ /* do PC1 in 60 simple operations */
18813+/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
18814+ HPERM_OP(c,t,-2, 0xcccc0000L);
18815+ HPERM_OP(c,t,-1, 0xaaaa0000L);
18816+ HPERM_OP(c,t, 8, 0x00ff0000L);
18817+ HPERM_OP(c,t,-1, 0xaaaa0000L);
18818+ HPERM_OP(d,t,-8, 0xff000000L);
18819+ HPERM_OP(d,t, 8, 0x00ff0000L);
18820+ HPERM_OP(d,t, 2, 0x33330000L);
18821+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
18822+ d=(d>>8)|((c&0xf0000000L)>>4);
18823+ c&=0x0fffffffL; */
18824+
18825+ /* I now do it in 47 simple operations :-)
18826+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
18827+ * for the inspiration. :-) */
18828+ PERM_OP (d,c,t,4,0x0f0f0f0fL);
18829+ HPERM_OP(c,t,-2,0xcccc0000L);
18830+ HPERM_OP(d,t,-2,0xcccc0000L);
18831+ PERM_OP (d,c,t,1,0x55555555L);
18832+ PERM_OP (c,d,t,8,0x00ff00ffL);
18833+ PERM_OP (d,c,t,1,0x55555555L);
18834+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
18835+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
18836+ c&=0x0fffffffL;
18837+
18838+ for (i=0; i<ITERATIONS; i++)
18839+ {
18840+ if (shifts2[i])
18841+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
18842+ else
18843+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
18844+ c&=0x0fffffffL;
18845+ d&=0x0fffffffL;
18846+ /* could be a few less shifts but I am to lazy at this
18847+ * point in time to investigate */
18848+ s= des_skb[0][ (c )&0x3f ]|
18849+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
18850+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
18851+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
18852+ ((c>>22L)&0x38)];
18853+ t= des_skb[4][ (d )&0x3f ]|
18854+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
18855+ des_skb[6][ (d>>15L)&0x3f ]|
18856+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
18857+
18858+ /* table contained 0213 4657 */
18859+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
18860+ *(k++)=ROTATE(t2,30)&0xffffffffL;
18861+
18862+ t2=((s>>16L)|(t&0xffff0000L));
18863+ *(k++)=ROTATE(t2,26)&0xffffffffL;
18864+ }
18865+ return(0);
18866+ }
18867+
18868+int des_key_sched(key, schedule)
18869+des_cblock (*key);
18870+des_key_schedule schedule;
18871+ {
18872+ return(des_set_key(key,schedule));
18873+ }
18874diff -druN linux-noipsec/net/ipsec/libdes/sk.h linux/net/ipsec/libdes/sk.h
18875--- linux-noipsec/net/ipsec/libdes/sk.h Thu Jan 1 01:00:00 1970
18876+++ linux/net/ipsec/libdes/sk.h Thu Feb 18 17:41:16 1999
18877@@ -0,0 +1,204 @@
18878+/* crypto/des/sk.h */
18879+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18880+ * All rights reserved.
18881+ *
18882+ * This package is an SSL implementation written
18883+ * by Eric Young (eay@cryptsoft.com).
18884+ * The implementation was written so as to conform with Netscapes SSL.
18885+ *
18886+ * This library is free for commercial and non-commercial use as long as
18887+ * the following conditions are aheared to. The following conditions
18888+ * apply to all code found in this distribution, be it the RC4, RSA,
18889+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18890+ * included with this distribution is covered by the same copyright terms
18891+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18892+ *
18893+ * Copyright remains Eric Young's, and as such any Copyright notices in
18894+ * the code are not to be removed.
18895+ * If this package is used in a product, Eric Young should be given attribution
18896+ * as the author of the parts of the library used.
18897+ * This can be in the form of a textual message at program startup or
18898+ * in documentation (online or textual) provided with the package.
18899+ *
18900+ * Redistribution and use in source and binary forms, with or without
18901+ * modification, are permitted provided that the following conditions
18902+ * are met:
18903+ * 1. Redistributions of source code must retain the copyright
18904+ * notice, this list of conditions and the following disclaimer.
18905+ * 2. Redistributions in binary form must reproduce the above copyright
18906+ * notice, this list of conditions and the following disclaimer in the
18907+ * documentation and/or other materials provided with the distribution.
18908+ * 3. All advertising materials mentioning features or use of this software
18909+ * must display the following acknowledgement:
18910+ * "This product includes cryptographic software written by
18911+ * Eric Young (eay@cryptsoft.com)"
18912+ * The word 'cryptographic' can be left out if the rouines from the library
18913+ * being used are not cryptographic related :-).
18914+ * 4. If you include any Windows specific code (or a derivative thereof) from
18915+ * the apps directory (application code) you must include an acknowledgement:
18916+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18917+ *
18918+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18919+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18920+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18921+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18922+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18923+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18924+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18925+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18926+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18927+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18928+ * SUCH DAMAGE.
18929+ *
18930+ * The licence and distribution terms for any publically available version or
18931+ * derivative of this code cannot be changed. i.e. this code cannot simply be
18932+ * copied and put under another distribution licence
18933+ * [including the GNU Public Licence.]
18934+ */
18935+
18936+static const DES_LONG des_skb[8][64]={
18937+{
18938+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
18939+0x00000000L,0x00000010L,0x20000000L,0x20000010L,
18940+0x00010000L,0x00010010L,0x20010000L,0x20010010L,
18941+0x00000800L,0x00000810L,0x20000800L,0x20000810L,
18942+0x00010800L,0x00010810L,0x20010800L,0x20010810L,
18943+0x00000020L,0x00000030L,0x20000020L,0x20000030L,
18944+0x00010020L,0x00010030L,0x20010020L,0x20010030L,
18945+0x00000820L,0x00000830L,0x20000820L,0x20000830L,
18946+0x00010820L,0x00010830L,0x20010820L,0x20010830L,
18947+0x00080000L,0x00080010L,0x20080000L,0x20080010L,
18948+0x00090000L,0x00090010L,0x20090000L,0x20090010L,
18949+0x00080800L,0x00080810L,0x20080800L,0x20080810L,
18950+0x00090800L,0x00090810L,0x20090800L,0x20090810L,
18951+0x00080020L,0x00080030L,0x20080020L,0x20080030L,
18952+0x00090020L,0x00090030L,0x20090020L,0x20090030L,
18953+0x00080820L,0x00080830L,0x20080820L,0x20080830L,
18954+0x00090820L,0x00090830L,0x20090820L,0x20090830L,
18955+},{
18956+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
18957+0x00000000L,0x02000000L,0x00002000L,0x02002000L,
18958+0x00200000L,0x02200000L,0x00202000L,0x02202000L,
18959+0x00000004L,0x02000004L,0x00002004L,0x02002004L,
18960+0x00200004L,0x02200004L,0x00202004L,0x02202004L,
18961+0x00000400L,0x02000400L,0x00002400L,0x02002400L,
18962+0x00200400L,0x02200400L,0x00202400L,0x02202400L,
18963+0x00000404L,0x02000404L,0x00002404L,0x02002404L,
18964+0x00200404L,0x02200404L,0x00202404L,0x02202404L,
18965+0x10000000L,0x12000000L,0x10002000L,0x12002000L,
18966+0x10200000L,0x12200000L,0x10202000L,0x12202000L,
18967+0x10000004L,0x12000004L,0x10002004L,0x12002004L,
18968+0x10200004L,0x12200004L,0x10202004L,0x12202004L,
18969+0x10000400L,0x12000400L,0x10002400L,0x12002400L,
18970+0x10200400L,0x12200400L,0x10202400L,0x12202400L,
18971+0x10000404L,0x12000404L,0x10002404L,0x12002404L,
18972+0x10200404L,0x12200404L,0x10202404L,0x12202404L,
18973+},{
18974+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
18975+0x00000000L,0x00000001L,0x00040000L,0x00040001L,
18976+0x01000000L,0x01000001L,0x01040000L,0x01040001L,
18977+0x00000002L,0x00000003L,0x00040002L,0x00040003L,
18978+0x01000002L,0x01000003L,0x01040002L,0x01040003L,
18979+0x00000200L,0x00000201L,0x00040200L,0x00040201L,
18980+0x01000200L,0x01000201L,0x01040200L,0x01040201L,
18981+0x00000202L,0x00000203L,0x00040202L,0x00040203L,
18982+0x01000202L,0x01000203L,0x01040202L,0x01040203L,
18983+0x08000000L,0x08000001L,0x08040000L,0x08040001L,
18984+0x09000000L,0x09000001L,0x09040000L,0x09040001L,
18985+0x08000002L,0x08000003L,0x08040002L,0x08040003L,
18986+0x09000002L,0x09000003L,0x09040002L,0x09040003L,
18987+0x08000200L,0x08000201L,0x08040200L,0x08040201L,
18988+0x09000200L,0x09000201L,0x09040200L,0x09040201L,
18989+0x08000202L,0x08000203L,0x08040202L,0x08040203L,
18990+0x09000202L,0x09000203L,0x09040202L,0x09040203L,
18991+},{
18992+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
18993+0x00000000L,0x00100000L,0x00000100L,0x00100100L,
18994+0x00000008L,0x00100008L,0x00000108L,0x00100108L,
18995+0x00001000L,0x00101000L,0x00001100L,0x00101100L,
18996+0x00001008L,0x00101008L,0x00001108L,0x00101108L,
18997+0x04000000L,0x04100000L,0x04000100L,0x04100100L,
18998+0x04000008L,0x04100008L,0x04000108L,0x04100108L,
18999+0x04001000L,0x04101000L,0x04001100L,0x04101100L,
19000+0x04001008L,0x04101008L,0x04001108L,0x04101108L,
19001+0x00020000L,0x00120000L,0x00020100L,0x00120100L,
19002+0x00020008L,0x00120008L,0x00020108L,0x00120108L,
19003+0x00021000L,0x00121000L,0x00021100L,0x00121100L,
19004+0x00021008L,0x00121008L,0x00021108L,0x00121108L,
19005+0x04020000L,0x04120000L,0x04020100L,0x04120100L,
19006+0x04020008L,0x04120008L,0x04020108L,0x04120108L,
19007+0x04021000L,0x04121000L,0x04021100L,0x04121100L,
19008+0x04021008L,0x04121008L,0x04021108L,0x04121108L,
19009+},{
19010+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
19011+0x00000000L,0x10000000L,0x00010000L,0x10010000L,
19012+0x00000004L,0x10000004L,0x00010004L,0x10010004L,
19013+0x20000000L,0x30000000L,0x20010000L,0x30010000L,
19014+0x20000004L,0x30000004L,0x20010004L,0x30010004L,
19015+0x00100000L,0x10100000L,0x00110000L,0x10110000L,
19016+0x00100004L,0x10100004L,0x00110004L,0x10110004L,
19017+0x20100000L,0x30100000L,0x20110000L,0x30110000L,
19018+0x20100004L,0x30100004L,0x20110004L,0x30110004L,
19019+0x00001000L,0x10001000L,0x00011000L,0x10011000L,
19020+0x00001004L,0x10001004L,0x00011004L,0x10011004L,
19021+0x20001000L,0x30001000L,0x20011000L,0x30011000L,
19022+0x20001004L,0x30001004L,0x20011004L,0x30011004L,
19023+0x00101000L,0x10101000L,0x00111000L,0x10111000L,
19024+0x00101004L,0x10101004L,0x00111004L,0x10111004L,
19025+0x20101000L,0x30101000L,0x20111000L,0x30111000L,
19026+0x20101004L,0x30101004L,0x20111004L,0x30111004L,
19027+},{
19028+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
19029+0x00000000L,0x08000000L,0x00000008L,0x08000008L,
19030+0x00000400L,0x08000400L,0x00000408L,0x08000408L,
19031+0x00020000L,0x08020000L,0x00020008L,0x08020008L,
19032+0x00020400L,0x08020400L,0x00020408L,0x08020408L,
19033+0x00000001L,0x08000001L,0x00000009L,0x08000009L,
19034+0x00000401L,0x08000401L,0x00000409L,0x08000409L,
19035+0x00020001L,0x08020001L,0x00020009L,0x08020009L,
19036+0x00020401L,0x08020401L,0x00020409L,0x08020409L,
19037+0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
19038+0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
19039+0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
19040+0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
19041+0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
19042+0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
19043+0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
19044+0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
19045+},{
19046+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
19047+0x00000000L,0x00000100L,0x00080000L,0x00080100L,
19048+0x01000000L,0x01000100L,0x01080000L,0x01080100L,
19049+0x00000010L,0x00000110L,0x00080010L,0x00080110L,
19050+0x01000010L,0x01000110L,0x01080010L,0x01080110L,
19051+0x00200000L,0x00200100L,0x00280000L,0x00280100L,
19052+0x01200000L,0x01200100L,0x01280000L,0x01280100L,
19053+0x00200010L,0x00200110L,0x00280010L,0x00280110L,
19054+0x01200010L,0x01200110L,0x01280010L,0x01280110L,
19055+0x00000200L,0x00000300L,0x00080200L,0x00080300L,
19056+0x01000200L,0x01000300L,0x01080200L,0x01080300L,
19057+0x00000210L,0x00000310L,0x00080210L,0x00080310L,
19058+0x01000210L,0x01000310L,0x01080210L,0x01080310L,
19059+0x00200200L,0x00200300L,0x00280200L,0x00280300L,
19060+0x01200200L,0x01200300L,0x01280200L,0x01280300L,
19061+0x00200210L,0x00200310L,0x00280210L,0x00280310L,
19062+0x01200210L,0x01200310L,0x01280210L,0x01280310L,
19063+},{
19064+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
19065+0x00000000L,0x04000000L,0x00040000L,0x04040000L,
19066+0x00000002L,0x04000002L,0x00040002L,0x04040002L,
19067+0x00002000L,0x04002000L,0x00042000L,0x04042000L,
19068+0x00002002L,0x04002002L,0x00042002L,0x04042002L,
19069+0x00000020L,0x04000020L,0x00040020L,0x04040020L,
19070+0x00000022L,0x04000022L,0x00040022L,0x04040022L,
19071+0x00002020L,0x04002020L,0x00042020L,0x04042020L,
19072+0x00002022L,0x04002022L,0x00042022L,0x04042022L,
19073+0x00000800L,0x04000800L,0x00040800L,0x04040800L,
19074+0x00000802L,0x04000802L,0x00040802L,0x04040802L,
19075+0x00002800L,0x04002800L,0x00042800L,0x04042800L,
19076+0x00002802L,0x04002802L,0x00042802L,0x04042802L,
19077+0x00000820L,0x04000820L,0x00040820L,0x04040820L,
19078+0x00000822L,0x04000822L,0x00040822L,0x04040822L,
19079+0x00002820L,0x04002820L,0x00042820L,0x04042820L,
19080+0x00002822L,0x04002822L,0x00042822L,0x04042822L,
19081+}};
19082diff -druN linux-noipsec/net/ipsec/libdes/speed.c linux/net/ipsec/libdes/speed.c
19083--- linux-noipsec/net/ipsec/libdes/speed.c Thu Jan 1 01:00:00 1970
19084+++ linux/net/ipsec/libdes/speed.c Thu Feb 18 17:41:16 1999
19085@@ -0,0 +1,329 @@
19086+/* crypto/des/speed.c */
19087+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
19088+ * All rights reserved.
19089+ *
19090+ * This package is an SSL implementation written
19091+ * by Eric Young (eay@cryptsoft.com).
19092+ * The implementation was written so as to conform with Netscapes SSL.
19093+ *
19094+ * This library is free for commercial and non-commercial use as long as
19095+ * the following conditions are aheared to. The following conditions
19096+ * apply to all code found in this distribution, be it the RC4, RSA,
19097+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
19098+ * included with this distribution is covered by the same copyright terms
19099+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
19100+ *
19101+ * Copyright remains Eric Young's, and as such any Copyright notices in
19102+ * the code are not to be removed.
19103+ * If this package is used in a product, Eric Young should be given attribution
19104+ * as the author of the parts of the library used.
19105+ * This can be in the form of a textual message at program startup or
19106+ * in documentation (online or textual) provided with the package.
19107+ *
19108+ * Redistribution and use in source and binary forms, with or without
19109+ * modification, are permitted provided that the following conditions
19110+ * are met:
19111+ * 1. Redistributions of source code must retain the copyright
19112+ * notice, this list of conditions and the following disclaimer.
19113+ * 2. Redistributions in binary form must reproduce the above copyright
19114+ * notice, this list of conditions and the following disclaimer in the
19115+ * documentation and/or other materials provided with the distribution.
19116+ * 3. All advertising materials mentioning features or use of this software
19117+ * must display the following acknowledgement:
19118+ * "This product includes cryptographic software written by
19119+ * Eric Young (eay@cryptsoft.com)"
19120+ * The word 'cryptographic' can be left out if the rouines from the library
19121+ * being used are not cryptographic related :-).
19122+ * 4. If you include any Windows specific code (or a derivative thereof) from
19123+ * the apps directory (application code) you must include an acknowledgement:
19124+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
19125+ *
19126+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
19127+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19128+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19129+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19130+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19131+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19132+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19133+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19134+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19135+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
19136+ * SUCH DAMAGE.
19137+ *
19138+ * The licence and distribution terms for any publically available version or
19139+ * derivative of this code cannot be changed. i.e. this code cannot simply be
19140+ * copied and put under another distribution licence
19141+ * [including the GNU Public Licence.]
19142+ */
19143+
19144+/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */
19145+/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */
19146+
19147+#ifndef MSDOS
19148+#define TIMES
19149+#endif
19150+
19151+#include <stdio.h>
19152+#ifndef MSDOS
19153+#include <unistd.h>
19154+#else
19155+#include <io.h>
19156+extern int exit();
19157+#endif
19158+#include <signal.h>
19159+#ifndef VMS
19160+#ifndef _IRIX
19161+#include <time.h>
19162+#endif
19163+#ifdef TIMES
19164+#include <sys/types.h>
19165+#include <sys/times.h>
19166+#endif
19167+#else /* VMS */
19168+#include <types.h>
19169+struct tms {
19170+ time_t tms_utime;
19171+ time_t tms_stime;
19172+ time_t tms_uchild; /* I dunno... */
19173+ time_t tms_uchildsys; /* so these names are a guess :-) */
19174+ }
19175+#endif
19176+#ifndef TIMES
19177+#include <sys/timeb.h>
19178+#endif
19179+
19180+#ifdef sun
19181+#include <limits.h>
19182+#include <sys/param.h>
19183+#endif
19184+
19185+#include "des.h"
19186+
19187+/* The following if from times(3) man page. It may need to be changed */
19188+#ifndef HZ
19189+# ifndef CLK_TCK
19190+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
19191+# ifndef VMS
19192+# define HZ 100.0
19193+# else /* VMS */
19194+# define HZ 100.0
19195+# endif
19196+# else /* _BSD_CLK_TCK_ */
19197+# define HZ ((double)_BSD_CLK_TCK_)
19198+# endif
19199+# else /* CLK_TCK */
19200+# define HZ ((double)CLK_TCK)
19201+# endif
19202+#endif
19203+
19204+#define BUFSIZE ((long)1024)
19205+long run=0;
19206+
19207+#ifndef NOPROTO
19208+double Time_F(int s);
19209+#else
19210+double Time_F();
19211+#endif
19212+
19213+#ifdef SIGALRM
19214+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
19215+#define SIGRETTYPE void
19216+#else
19217+#define SIGRETTYPE int
19218+#endif
19219+
19220+#ifndef NOPROTO
19221+SIGRETTYPE sig_done(int sig);
19222+#else
19223+SIGRETTYPE sig_done();
19224+#endif
19225+
19226+SIGRETTYPE sig_done(sig)
19227+int sig;
19228+ {
19229+ signal(SIGALRM,sig_done);
19230+ run=0;
19231+#ifdef LINT
19232+ sig=sig;
19233+#endif
19234+ }
19235+#endif
19236+
19237+#define START 0
19238+#define STOP 1
19239+
19240+double Time_F(s)
19241+int s;
19242+ {
19243+ double ret;
19244+#ifdef TIMES
19245+ static struct tms tstart,tend;
19246+
19247+ if (s == START)
19248+ {
19249+ times(&tstart);
19250+ return(0);
19251+ }
19252+ else
19253+ {
19254+ times(&tend);
19255+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
19256+ return((ret == 0.0)?1e-6:ret);
19257+ }
19258+#else /* !times() */
19259+ static struct timeb tstart,tend;
19260+ long i;
19261+
19262+ if (s == START)
19263+ {
19264+ ftime(&tstart);
19265+ return(0);
19266+ }
19267+ else
19268+ {
19269+ ftime(&tend);
19270+ i=(long)tend.millitm-(long)tstart.millitm;
19271+ ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
19272+ return((ret == 0.0)?1e-6:ret);
19273+ }
19274+#endif
19275+ }
19276+
19277+int main(argc,argv)
19278+int argc;
19279+char **argv;
19280+ {
19281+ long count;
19282+ static unsigned char buf[BUFSIZE];
19283+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
19284+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
19285+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
19286+ des_key_schedule sch,sch2,sch3;
19287+ double a,b,c,d,e;
19288+#ifndef SIGALRM
19289+ long ca,cb,cc,cd,ce;
19290+#endif
19291+
19292+#ifndef TIMES
19293+ printf("To get the most acurate results, try to run this\n");
19294+ printf("program when this computer is idle.\n");
19295+#endif
19296+
19297+ des_set_key((C_Block *)key2,sch2);
19298+ des_set_key((C_Block *)key3,sch3);
19299+
19300+#ifndef SIGALRM
19301+ printf("First we calculate the approximate speed ...\n");
19302+ des_set_key((C_Block *)key,sch);
19303+ count=10;
19304+ do {
19305+ long i;
19306+ DES_LONG data[2];
19307+
19308+ count*=2;
19309+ Time_F(START);
19310+ for (i=count; i; i--)
19311+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
19312+ d=Time_F(STOP);
19313+ } while (d < 3.0);
19314+ ca=count;
19315+ cb=count*3;
19316+ cc=count*3*8/BUFSIZE+1;
19317+ cd=count*8/BUFSIZE+1;
19318+ ce=count/20+1;
19319+ printf("Doing set_key %ld times\n",ca);
19320+#define COND(d) (count != (d))
19321+#define COUNT(d) (d)
19322+#else
19323+#define COND(c) (run)
19324+#define COUNT(d) (count)
19325+ signal(SIGALRM,sig_done);
19326+ printf("Doing set_key for 10 seconds\n");
19327+ alarm(10);
19328+#endif
19329+
19330+ Time_F(START);
19331+ for (count=0,run=1; COND(ca); count++)
19332+ des_set_key((C_Block *)key,sch);
19333+ d=Time_F(STOP);
19334+ printf("%ld set_key's in %.2f seconds\n",count,d);
19335+ a=((double)COUNT(ca))/d;
19336+
19337+#ifdef SIGALRM
19338+ printf("Doing des_encrypt's for 10 seconds\n");
19339+ alarm(10);
19340+#else
19341+ printf("Doing des_encrypt %ld times\n",cb);
19342+#endif
19343+ Time_F(START);
19344+ for (count=0,run=1; COND(cb); count++)
19345+ {
19346+ DES_LONG data[2];
19347+
19348+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
19349+ }
19350+ d=Time_F(STOP);
19351+ printf("%ld des_encrypt's in %.2f second\n",count,d);
19352+ b=((double)COUNT(cb)*8)/d;
19353+
19354+#ifdef SIGALRM
19355+ printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n",
19356+ BUFSIZE);
19357+ alarm(10);
19358+#else
19359+ printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc,
19360+ BUFSIZE);
19361+#endif
19362+ Time_F(START);
19363+ for (count=0,run=1; COND(cc); count++)
19364+ des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]),
19365+ (C_Block *)&(key[0]),DES_ENCRYPT);
19366+ d=Time_F(STOP);
19367+ printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n",
19368+ count,BUFSIZE,d);
19369+ c=((double)COUNT(cc)*BUFSIZE)/d;
19370+
19371+#ifdef SIGALRM
19372+ printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n",
19373+ BUFSIZE);
19374+ alarm(10);
19375+#else
19376+ printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd,
19377+ BUFSIZE);
19378+#endif
19379+ Time_F(START);
19380+ for (count=0,run=1; COND(cd); count++)
19381+ des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,
19382+ &(sch[0]),
19383+ &(sch2[0]),
19384+ &(sch3[0]),
19385+ (C_Block *)&(key[0]),
19386+ DES_ENCRYPT);
19387+ d=Time_F(STOP);
19388+ printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n",
19389+ count,BUFSIZE,d);
19390+ d=((double)COUNT(cd)*BUFSIZE)/d;
19391+
19392+#ifdef SIGALRM
19393+ printf("Doing crypt for 10 seconds\n");
19394+ alarm(10);
19395+#else
19396+ printf("Doing crypt %ld times\n",ce);
19397+#endif
19398+ Time_F(START);
19399+ for (count=0,run=1; COND(ce); count++)
19400+ crypt("testing1","ef");
19401+ e=Time_F(STOP);
19402+ printf("%ld crypts in %.2f second\n",count,e);
19403+ e=((double)COUNT(ce))/e;
19404+
19405+ printf("set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
19406+ printf("DES raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
19407+ printf("DES cbc bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
19408+ printf("DES ede cbc bytes per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d);
19409+ printf("crypt per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e);
19410+ exit(0);
19411+#if defined(LINT) || defined(MSDOS)
19412+ return(0);
19413+#endif
19414+ }
19415diff -druN linux-noipsec/net/ipsec/libdes/spr.h linux/net/ipsec/libdes/spr.h
19416--- linux-noipsec/net/ipsec/libdes/spr.h Thu Jan 1 01:00:00 1970
19417+++ linux/net/ipsec/libdes/spr.h Thu Feb 18 17:41:16 1999
19418@@ -0,0 +1,204 @@
19419+/* crypto/des/spr.h */
19420+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
19421+ * All rights reserved.
19422+ *
19423+ * This package is an SSL implementation written
19424+ * by Eric Young (eay@cryptsoft.com).
19425+ * The implementation was written so as to conform with Netscapes SSL.
19426+ *
19427+ * This library is free for commercial and non-commercial use as long as
19428+ * the following conditions are aheared to. The following conditions
19429+ * apply to all code found in this distribution, be it the RC4, RSA,
19430+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
19431+ * included with this distribution is covered by the same copyright terms
19432+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
19433+ *
19434+ * Copyright remains Eric Young's, and as such any Copyright notices in
19435+ * the code are not to be removed.
19436+ * If this package is used in a product, Eric Young should be given attribution
19437+ * as the author of the parts of the library used.
19438+ * This can be in the form of a textual message at program startup or
19439+ * in documentation (online or textual) provided with the package.
19440+ *
19441+ * Redistribution and use in source and binary forms, with or without
19442+ * modification, are permitted provided that the following conditions
19443+ * are met:
19444+ * 1. Redistributions of source code must retain the copyright
19445+ * notice, this list of conditions and the following disclaimer.
19446+ * 2. Redistributions in binary form must reproduce the above copyright
19447+ * notice, this list of conditions and the following disclaimer in the
19448+ * documentation and/or other materials provided with the distribution.
19449+ * 3. All advertising materials mentioning features or use of this software
19450+ * must display the following acknowledgement:
19451+ * "This product includes cryptographic software written by
19452+ * Eric Young (eay@cryptsoft.com)"
19453+ * The word 'cryptographic' can be left out if the rouines from the library
19454+ * being used are not cryptographic related :-).
19455+ * 4. If you include any Windows specific code (or a derivative thereof) from
19456+ * the apps directory (application code) you must include an acknowledgement:
19457+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
19458+ *
19459+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
19460+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19461+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19462+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19463+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19464+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19465+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19466+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19467+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19468+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
19469+ * SUCH DAMAGE.
19470+ *
19471+ * The licence and distribution terms for any publically available version or
19472+ * derivative of this code cannot be changed. i.e. this code cannot simply be
19473+ * copied and put under another distribution licence
19474+ * [including the GNU Public Licence.]
19475+ */
19476+
19477+const DES_LONG des_SPtrans[8][64]={
19478+{
19479+/* nibble 0 */
19480+0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
19481+0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
19482+0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
19483+0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
19484+0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
19485+0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
19486+0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
19487+0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
19488+0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
19489+0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
19490+0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
19491+0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
19492+0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
19493+0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
19494+0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
19495+0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
19496+},{
19497+/* nibble 1 */
19498+0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
19499+0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
19500+0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
19501+0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
19502+0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
19503+0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
19504+0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
19505+0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
19506+0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
19507+0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
19508+0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
19509+0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
19510+0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
19511+0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
19512+0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
19513+0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
19514+},{
19515+/* nibble 2 */
19516+0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
19517+0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
19518+0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
19519+0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
19520+0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
19521+0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
19522+0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
19523+0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
19524+0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
19525+0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
19526+0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
19527+0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
19528+0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
19529+0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
19530+0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
19531+0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
19532+},{
19533+/* nibble 3 */
19534+0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
19535+0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
19536+0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
19537+0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
19538+0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
19539+0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
19540+0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
19541+0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
19542+0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
19543+0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
19544+0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
19545+0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
19546+0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
19547+0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
19548+0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
19549+0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
19550+},{
19551+/* nibble 4 */
19552+0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
19553+0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
19554+0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
19555+0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
19556+0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
19557+0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
19558+0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
19559+0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
19560+0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
19561+0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
19562+0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
19563+0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
19564+0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
19565+0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
19566+0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
19567+0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
19568+},{
19569+/* nibble 5 */
19570+0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
19571+0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
19572+0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
19573+0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
19574+0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
19575+0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
19576+0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
19577+0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
19578+0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
19579+0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
19580+0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
19581+0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
19582+0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
19583+0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
19584+0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
19585+0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
19586+},{
19587+/* nibble 6 */
19588+0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
19589+0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
19590+0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
19591+0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
19592+0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
19593+0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
19594+0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
19595+0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
19596+0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
19597+0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
19598+0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
19599+0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
19600+0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
19601+0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
19602+0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
19603+0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
19604+},{
19605+/* nibble 7 */
19606+0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
19607+0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
19608+0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
19609+0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
19610+0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
19611+0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
19612+0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
19613+0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
19614+0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
19615+0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
19616+0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
19617+0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
19618+0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
19619+0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
19620+0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
19621+0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
19622+}};
19623diff -druN linux-noipsec/net/ipsec/libfreeswan/Makefile linux/net/ipsec/libfreeswan/Makefile
19624--- linux-noipsec/net/ipsec/libfreeswan/Makefile Thu Jan 1 01:00:00 1970
19625+++ linux/net/ipsec/libfreeswan/Makefile Fri Sep 8 21:12:57 2000
19626@@ -0,0 +1,53 @@
19627+# FreeS/WAN library
19628+# Copyright (C) 1998, 1999, 2000 Henry Spencer.
19629+#
19630+# This program is free software; you can redistribute it and/or modify it
19631+# under the terms of the GNU General Public License as published by the
19632+# Free Software Foundation; either version 2 of the License, or (at your
19633+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
19634+#
19635+# This program is distributed in the hope that it will be useful, but
19636+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19637+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19638+# for more details.
19639+#
19640+# RCSID $Id$
19641+
19642+ifndef TOPDIR
19643+TOPDIR := /usr/src/linux
19644+endif
19645+
19646+L_TARGET := libkernel.a
19647+
19648+L_OBJS := ultoa.o addrtoa.o subnettoa.o subnetof.o goodmask.o datatot.o \
19649+ rangetoa.o satoa.o pfkey_v2_parse.o pfkey_v2_build.o pfkey_v2_ext_bits.o
19650+
19651+HDRS=freeswan.h internal.h
19652+
19653+override CFLAGS += -I.
19654+
19655+ifeq ($(CONFIG_IPSEC_DEBUG),y)
19656+override CFLAGS += -g
19657+endif
19658+
19659+override CFLAGS += -Wall
19660+#override CFLAGS += -Wconversion
19661+#override CFLAGS += -Wmissing-prototypes
19662+override CFLAGS += -Wpointer-arith
19663+#override CFLAGS += -Wcast-qual
19664+#override CFLAGS += -Wmissing-declarations
19665+override CFLAGS += -Wstrict-prototypes
19666+#override CFLAGS += -pedantic
19667+#override CFLAGS += -O3
19668+#override CFLAGS += -W
19669+#override CFLAGS += -Wwrite-strings
19670+override CFLAGS += -Wbad-function-cast
19671+
19672+include $(TOPDIR)/Rules.make
19673+
19674+$(L_OBJS): $(HDRS)
19675+
19676+clean:
19677+ rm -f $(L_TARGET) *.o try* core *.core
19678+ ( cd des && $(MAKE) clean )
19679+
19680diff -druN linux-noipsec/net/ipsec/libfreeswan/addrtoa.c linux/net/ipsec/libfreeswan/addrtoa.c
19681--- linux-noipsec/net/ipsec/libfreeswan/addrtoa.c Thu Jan 1 01:00:00 1970
19682+++ linux/net/ipsec/libfreeswan/addrtoa.c Sun Apr 11 01:19:36 1999
19683@@ -0,0 +1,68 @@
19684+/*
19685+ * addresses to ASCII
19686+ * Copyright (C) 1998, 1999 Henry Spencer.
19687+ *
19688+ * This library is free software; you can redistribute it and/or modify it
19689+ * under the terms of the GNU Library General Public License as published by
19690+ * the Free Software Foundation; either version 2 of the License, or (at your
19691+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
19692+ *
19693+ * This library is distributed in the hope that it will be useful, but
19694+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19695+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
19696+ * License for more details.
19697+ *
19698+ * RCSID $Id$
19699+ */
19700+#include "internal.h"
19701+#include "freeswan.h"
19702+
19703+#define NBYTES 4 /* bytes in an address */
19704+#define PERBYTE 4 /* three digits plus a dot or NUL */
19705+#define BUFLEN (NBYTES*PERBYTE)
19706+
19707+#if BUFLEN != ADDRTOA_BUF
19708+#error "ADDRTOA_BUF in freeswan.h inconsistent with addrtoa() code"
19709+#endif
19710+
19711+/*
19712+ - addrtoa - convert binary address to ASCII dotted decimal
19713+ */
19714+size_t /* space needed for full conversion */
19715+addrtoa(addr, format, dst, dstlen)
19716+struct in_addr addr;
19717+int format; /* character */
19718+char *dst; /* need not be valid if dstlen is 0 */
19719+size_t dstlen;
19720+{
19721+ unsigned long a = ntohl(addr.s_addr);
19722+ int i;
19723+ size_t n;
19724+ unsigned long byte;
19725+ char buf[BUFLEN];
19726+ char *p;
19727+
19728+ switch (format) {
19729+ case 0:
19730+ break;
19731+ default:
19732+ return 0;
19733+ break;
19734+ }
19735+
19736+ p = buf;
19737+ for (i = NBYTES-1; i >= 0; i--) {
19738+ byte = (a >> (i*8)) & 0xff;
19739+ p += ultoa(byte, 10, p, PERBYTE);
19740+ if (i != 0)
19741+ *(p-1) = '.';
19742+ }
19743+ n = p - buf;
19744+
19745+ if (dstlen > 0) {
19746+ if (n > dstlen)
19747+ buf[dstlen - 1] = '\0';
19748+ strcpy(dst, buf);
19749+ }
19750+ return n;
19751+}
19752diff -druN linux-noipsec/net/ipsec/libfreeswan/addrtot.c linux/net/ipsec/libfreeswan/addrtot.c
19753--- linux-noipsec/net/ipsec/libfreeswan/addrtot.c Thu Jan 1 01:00:00 1970
19754+++ linux/net/ipsec/libfreeswan/addrtot.c Tue Sep 12 06:56:39 2000
19755@@ -0,0 +1,230 @@
19756+/*
19757+ * addresses to text
19758+ * Copyright (C) 2000 Henry Spencer.
19759+ *
19760+ * This library is free software; you can redistribute it and/or modify it
19761+ * under the terms of the GNU Library General Public License as published by
19762+ * the Free Software Foundation; either version 2 of the License, or (at your
19763+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
19764+ *
19765+ * This library is distributed in the hope that it will be useful, but
19766+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19767+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
19768+ * License for more details.
19769+ *
19770+ * RCSID $Id$
19771+ */
19772+#include "internal.h"
19773+#include "freeswan.h"
19774+
19775+#define IP4BYTES 4 /* bytes in an IPv4 address */
19776+#define PERBYTE 4 /* three digits plus a dot or NUL */
19777+#define IP6BYTES 16 /* bytes in an IPv6 address */
19778+
19779+/* forwards */
19780+static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
19781+static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp);
19782+static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
19783+static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
19784+static size_t reverse62(const unsigned char *s, size_t len, char *b, char **dp);
19785+
19786+/*
19787+ - addrtot - convert binary address to text (dotted decimal or IPv6 string)
19788+ */
19789+size_t /* space needed for full conversion */
19790+addrtot(src, format, dst, dstlen)
19791+const ip_address *src;
19792+int format; /* character */
19793+char *dst; /* need not be valid if dstlen is 0 */
19794+size_t dstlen;
19795+{
19796+ const unsigned char *b;
19797+ size_t n;
19798+ char buf[1+ADDRTOT_BUF+1]; /* :address: */
19799+ char *p;
19800+ int t = addrtypeof(src);
19801+# define TF(t, f) (((t)<<8) | (f))
19802+
19803+ n = addrbytesptr(src, &b);
19804+ if (n == 0)
19805+ return 0;
19806+
19807+ switch (TF(t, format)) {
19808+ case TF(AF_INET, 0):
19809+ n = normal4(b, n, buf, &p);
19810+ break;
19811+ case TF(AF_INET6, 0):
19812+ n = normal6(b, n, buf, &p);
19813+ break;
19814+ case TF(AF_INET, 'r'):
19815+ n = reverse4(b, n, buf, &p);
19816+ break;
19817+ case TF(AF_INET6, 'r'):
19818+ n = reverse6(b, n, buf, &p);
19819+ break;
19820+ case TF(AF_INET6, 'R'):
19821+ n = reverse62(b, n, buf, &p);
19822+ break;
19823+ default: /* including (AF_INET, 'R') */
19824+ return 0;
19825+ break;
19826+ }
19827+
19828+ if (dstlen > 0) {
19829+ if (dstlen < n)
19830+ p[dstlen - 1] = '\0';
19831+ strcpy(dst, p);
19832+ }
19833+ return n;
19834+}
19835+
19836+/*
19837+ - normal4 - normal IPv4 address-text conversion
19838+ */
19839+static size_t /* size of text, including NUL */
19840+normal4(srcp, srclen, buf, dstp)
19841+const unsigned char *srcp;
19842+size_t srclen;
19843+char *buf; /* guaranteed large enough */
19844+char **dstp; /* where to put result pointer */
19845+{
19846+ int i;
19847+ char *p;
19848+
19849+ if (srclen != IP4BYTES) /* "can't happen" */
19850+ return 0;
19851+ p = buf;
19852+ for (i = 0; i < IP4BYTES; i++) {
19853+ p += ultot(srcp[i], 10, p, PERBYTE);
19854+ if (i != IP4BYTES - 1)
19855+ *(p-1) = '.'; /* overwrites the NUL */
19856+ }
19857+ *dstp = buf;
19858+ return p - buf;
19859+}
19860+
19861+/*
19862+ - normal6 - normal IPv6 address-text conversion
19863+ */
19864+static size_t /* size of text, including NUL */
19865+normal6(srcp, srclen, buf, dstp)
19866+const unsigned char *srcp;
19867+size_t srclen;
19868+char *buf; /* guaranteed large enough, plus 2 */
19869+char **dstp; /* where to put result pointer */
19870+{
19871+ int i;
19872+ unsigned long piece;
19873+ char *p;
19874+ char *q;
19875+
19876+ if (srclen != IP6BYTES) /* "can't happen" */
19877+ return 0;
19878+ p = buf;
19879+ *p++ = ':';
19880+ for (i = 0; i < IP6BYTES/2; i++) {
19881+ piece = (srcp[2*i] << 8) + srcp[2*i + 1];
19882+ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
19883+ *(p-1) = ':'; /* overwrites the NUL */
19884+ }
19885+ *p = '\0';
19886+ q = strstr(buf, ":0:0:");
19887+ if (q != NULL) { /* zero squishing is possible */
19888+ p = q + 1;
19889+ while (*p == '0' && *(p+1) == ':')
19890+ p += 2;
19891+ q++;
19892+ *q++ = ':'; /* overwrite first 0 */
19893+ while (*p != '\0')
19894+ *q++ = *p++;
19895+ *q = '\0';
19896+ if (!(*(q-1) == ':' && *(q-2) == ':'))
19897+ *--q = '\0'; /* strip final : unless :: */
19898+ p = buf;
19899+ if (!(*p == ':' && *(p+1) == ':'))
19900+ p++; /* skip initial : unless :: */
19901+ } else {
19902+ q = p;
19903+ *--q = '\0'; /* strip final : */
19904+ p = buf + 1; /* skip initial : */
19905+ }
19906+ *dstp = p;
19907+ return q - p + 1;
19908+}
19909+
19910+/*
19911+ - reverse4 - IPv4 reverse-lookup conversion
19912+ */
19913+static size_t /* size of text, including NUL */
19914+reverse4(srcp, srclen, buf, dstp)
19915+const unsigned char *srcp;
19916+size_t srclen;
19917+char *buf; /* guaranteed large enough */
19918+char **dstp; /* where to put result pointer */
19919+{
19920+ int i;
19921+ char *p;
19922+
19923+ if (srclen != IP4BYTES) /* "can't happen" */
19924+ return 0;
19925+ p = buf;
19926+ for (i = IP4BYTES-1; i >= 0; i--) {
19927+ p += ultot(srcp[i], 10, p, PERBYTE);
19928+ *(p-1) = '.'; /* overwrites the NUL */
19929+ }
19930+ strcpy(p, "IN-ADDR.ARPA.");
19931+ *dstp = buf;
19932+ return strlen(buf) + 1;
19933+}
19934+
19935+/*
19936+ - reverse62 - obsolete IPv6 reverse-lookup conversion (RFC 1886)
19937+ * A trifle inefficient, really shouldn't use ultot...
19938+ */
19939+static size_t /* size of text, including NUL */
19940+reverse62(srcp, srclen, buf, dstp)
19941+const unsigned char *srcp;
19942+size_t srclen;
19943+char *buf; /* guaranteed large enough */
19944+char **dstp; /* where to put result pointer */
19945+{
19946+ int i;
19947+ unsigned long piece;
19948+ char *p;
19949+
19950+ if (srclen != IP6BYTES) /* "can't happen" */
19951+ return 0;
19952+ p = buf;
19953+ for (i = IP6BYTES-1; i >= 0; i--) {
19954+ piece = srcp[i];
19955+ p += ultot(piece&0xf, 16, p, 2);
19956+ *(p-1) = '.';
19957+ p += ultot(piece>>4, 16, p, 2);
19958+ *(p-1) = '.';
19959+ }
19960+ strcpy(p, "IP6.INT.");
19961+ *dstp = buf;
19962+ return strlen(buf) + 1;
19963+}
19964+
19965+/*
19966+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
19967+ */
19968+static size_t /* size of text, including NUL */
19969+reverse6(srcp, srclen, buf, dstp)
19970+const unsigned char *srcp;
19971+size_t srclen;
19972+char *buf; /* guaranteed large enough */
19973+char **dstp; /* where to put result pointer */
19974+{
19975+ char *p;
19976+
19977+ if (srclen != IP6BYTES) /* "can't happen" */
19978+ return 0;
19979+ strcpy(buf, "\\[x");
19980+ p = buf + strlen(buf);
19981+ (void) datatot((const char *)srcp, srclen, 16, p, IP6BYTES*2 + 1);
19982+ strcat(buf, "].IP6.ARPA."); /* leave count implicit */
19983+ *dstp = buf;
19984+ return strlen(buf) + 1;
19985+}
19986diff -druN linux-noipsec/net/ipsec/libfreeswan/addrtypeof.c linux/net/ipsec/libfreeswan/addrtypeof.c
19987--- linux-noipsec/net/ipsec/libfreeswan/addrtypeof.c Thu Jan 1 01:00:00 1970
19988+++ linux/net/ipsec/libfreeswan/addrtypeof.c Fri Sep 8 20:03:44 2000
19989@@ -0,0 +1,94 @@
19990+/*
19991+ * extract parts of an ip_address
19992+ * Copyright (C) 2000 Henry Spencer.
19993+ *
19994+ * This library is free software; you can redistribute it and/or modify it
19995+ * under the terms of the GNU Library General Public License as published by
19996+ * the Free Software Foundation; either version 2 of the License, or (at your
19997+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
19998+ *
19999+ * This library is distributed in the hope that it will be useful, but
20000+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20001+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20002+ * License for more details.
20003+ *
20004+ * RCSID $Id$
20005+ */
20006+#include "internal.h"
20007+#include "freeswan.h"
20008+
20009+/*
20010+ - addrtypeof - get the type of an ip_address
20011+ */
20012+int
20013+addrtypeof(src)
20014+const ip_address *src;
20015+{
20016+ return src->u.v4.sin_family;
20017+}
20018+
20019+/*
20020+ - addrbytesptr - get pointer to the address bytes of an ip_address
20021+ */
20022+size_t /* 0 for error */
20023+addrbytesptr(src, dstp)
20024+const ip_address *src;
20025+const unsigned char **dstp; /* NULL means just a size query */
20026+{
20027+ const unsigned char *p;
20028+ size_t n;
20029+
20030+ switch (src->u.v4.sin_family) {
20031+ case AF_INET:
20032+ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
20033+ n = 4;
20034+ break;
20035+ case AF_INET6:
20036+ p = (const unsigned char *)&src->u.v6.sin6_addr;
20037+ n = 16;
20038+ break;
20039+ default:
20040+ return 0;
20041+ break;
20042+ }
20043+
20044+ if (dstp != NULL)
20045+ *dstp = p;
20046+ return n;
20047+}
20048+
20049+/*
20050+ - addrlenof - get length of the address bytes of an ip_address
20051+ */
20052+size_t /* 0 for error */
20053+addrlenof(src)
20054+const ip_address *src;
20055+{
20056+ return addrbytesptr(src, NULL);
20057+}
20058+
20059+/*
20060+ - addrbytesof - get the address bytes of an ip_address
20061+ */
20062+size_t /* 0 for error */
20063+addrbytesof(src, dst, dstlen)
20064+const ip_address *src;
20065+unsigned char *dst;
20066+size_t dstlen;
20067+{
20068+ const unsigned char *p;
20069+ size_t n;
20070+ size_t ncopy;
20071+
20072+ n = addrbytesptr(src, &p);
20073+ if (n == 0)
20074+ return 0;
20075+
20076+ if (dstlen > 0) {
20077+ ncopy = n;
20078+ if (ncopy > dstlen)
20079+ ncopy = dstlen;
20080+ memcpy(dst, p, ncopy);
20081+ }
20082+ return n;
20083+}
20084diff -druN linux-noipsec/net/ipsec/libfreeswan/anyaddr.c linux/net/ipsec/libfreeswan/anyaddr.c
20085--- linux-noipsec/net/ipsec/libfreeswan/anyaddr.c Thu Jan 1 01:00:00 1970
20086+++ linux/net/ipsec/libfreeswan/anyaddr.c Tue Sep 19 09:09:32 2000
20087@@ -0,0 +1,146 @@
20088+/*
20089+ * special addresses
20090+ * Copyright (C) 2000 Henry Spencer.
20091+ *
20092+ * This library is free software; you can redistribute it and/or modify it
20093+ * under the terms of the GNU Library General Public License as published by
20094+ * the Free Software Foundation; either version 2 of the License, or (at your
20095+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
20096+ *
20097+ * This library is distributed in the hope that it will be useful, but
20098+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20099+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20100+ * License for more details.
20101+ *
20102+ * RCSID $Id$
20103+ */
20104+#include "internal.h"
20105+#include "freeswan.h"
20106+
20107+/* these are mostly fallbacks for the no-IPv6-support-in-library case */
20108+#ifndef IN6ADDR_ANY_INIT
20109+#define IN6ADDR_ANY_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}
20110+#endif
20111+#ifndef IN6ADDR_LOOPBACK_INIT
20112+#define IN6ADDR_LOOPBACK_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}
20113+#endif
20114+
20115+static struct in6_addr v6any = IN6ADDR_ANY_INIT;
20116+static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
20117+
20118+/*
20119+ - anyaddr - initialize to the any-address value
20120+ */
20121+err_t /* NULL for success, else string literal */
20122+anyaddr(af, dst)
20123+int af; /* address family */
20124+ip_address *dst;
20125+{
20126+ uint32_t v4any = htonl(INADDR_ANY);
20127+
20128+ switch (af) {
20129+ case AF_INET:
20130+ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
20131+ break;
20132+ case AF_INET6:
20133+ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
20134+ break;
20135+ default:
20136+ return "unknown address family in anyaddr/unspecaddr";
20137+ break;
20138+ }
20139+}
20140+
20141+/*
20142+ - unspecaddr - initialize to the unspecified-address value
20143+ */
20144+err_t /* NULL for success, else string literal */
20145+unspecaddr(af, dst)
20146+int af; /* address family */
20147+ip_address *dst;
20148+{
20149+ return anyaddr(af, dst);
20150+}
20151+
20152+/*
20153+ - loopbackaddr - initialize to the loopback-address value
20154+ */
20155+err_t /* NULL for success, else string literal */
20156+loopbackaddr(af, dst)
20157+int af; /* address family */
20158+ip_address *dst;
20159+{
20160+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
20161+
20162+ switch (af) {
20163+ case AF_INET:
20164+ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
20165+ break;
20166+ case AF_INET6:
20167+ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
20168+ break;
20169+ default:
20170+ return "unknown address family in loopbackaddr";
20171+ break;
20172+ }
20173+}
20174+
20175+/*
20176+ - isanyaddr - test for the any-address value
20177+ */
20178+int
20179+isanyaddr(src)
20180+const ip_address *src;
20181+{
20182+ uint32_t v4any = htonl(INADDR_ANY);
20183+ int cmp;
20184+
20185+ switch (src->u.v4.sin_family) {
20186+ case AF_INET:
20187+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
20188+ break;
20189+ case AF_INET6:
20190+ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
20191+ break;
20192+ default:
20193+ return 0;
20194+ break;
20195+ }
20196+
20197+ return (cmp == 0) ? 1 : 0;
20198+}
20199+
20200+/*
20201+ - isunspecaddr - test for the unspecified-address value
20202+ */
20203+int
20204+isunspecaddr(src)
20205+const ip_address *src;
20206+{
20207+ return isanyaddr(src);
20208+}
20209+
20210+/*
20211+ - isloopbackaddr - test for the loopback-address value
20212+ */
20213+int
20214+isloopbackaddr(src)
20215+const ip_address *src;
20216+{
20217+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
20218+ int cmp;
20219+
20220+ switch (src->u.v4.sin_family) {
20221+ case AF_INET:
20222+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
20223+ break;
20224+ case AF_INET6:
20225+ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
20226+ break;
20227+ default:
20228+ return 0;
20229+ break;
20230+ }
20231+
20232+ return (cmp == 0) ? 1 : 0;
20233+}
20234diff -druN linux-noipsec/net/ipsec/libfreeswan/atoaddr.c linux/net/ipsec/libfreeswan/atoaddr.c
20235--- linux-noipsec/net/ipsec/libfreeswan/atoaddr.c Thu Jan 1 01:00:00 1970
20236+++ linux/net/ipsec/libfreeswan/atoaddr.c Sat Jan 22 03:17:22 2000
20237@@ -0,0 +1,238 @@
20238+/*
20239+ * conversion from ASCII forms of addresses to internal ones
20240+ * Copyright (C) 1998, 1999 Henry Spencer.
20241+ *
20242+ * This library is free software; you can redistribute it and/or modify it
20243+ * under the terms of the GNU Library General Public License as published by
20244+ * the Free Software Foundation; either version 2 of the License, or (at your
20245+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
20246+ *
20247+ * This library is distributed in the hope that it will be useful, but
20248+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20249+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20250+ * License for more details.
20251+ *
20252+ * RCSID $Id$
20253+ */
20254+#include "internal.h"
20255+#include "freeswan.h"
20256+
20257+/*
20258+ * Define NOLEADINGZEROS to interpret 032 as an error, not as 32. There
20259+ * is deliberately no way to interpret it as 26 (i.e., as octal).
20260+ */
20261+
20262+/*
20263+ * Legal characters in a domain name. Underscore technically is not,
20264+ * but is a common misunderstanding.
20265+ */
20266+static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789"
20267+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
20268+
20269+static const char *try8hex(const char *, size_t, struct in_addr *);
20270+static const char *try8hosthex(const char *, size_t, struct in_addr *);
20271+static const char *trydotted(const char *, size_t, struct in_addr *);
20272+static const char *getbyte(const char **, const char *, int *);
20273+
20274+/*
20275+ - atoaddr - convert ASCII name or dotted-decimal address to binary address
20276+ */
20277+const char * /* NULL for success, else string literal */
20278+atoaddr(src, srclen, addrp)
20279+const char *src;
20280+size_t srclen; /* 0 means "apply strlen" */
20281+struct in_addr *addrp;
20282+{
20283+ struct hostent *h;
20284+ struct netent *ne = NULL;
20285+ const char *oops;
20286+# define HEXLEN 10 /* strlen("0x11223344") */
20287+# ifndef ATOADDRBUF
20288+# define ATOADDRBUF 100
20289+# endif
20290+ char namebuf[ATOADDRBUF];
20291+ char *p = namebuf;
20292+ char *q;
20293+
20294+ if (srclen == 0)
20295+ srclen = strlen(src);
20296+ if (srclen == 0)
20297+ return "empty string";
20298+
20299+ /* might it be hex? */
20300+ if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'x'))
20301+ return try8hex(src+2, srclen-2, addrp);
20302+ if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'h'))
20303+ return try8hosthex(src+2, srclen-2, addrp);
20304+
20305+ /* try it as dotted decimal */
20306+ oops = trydotted(src, srclen, addrp);
20307+ if (oops == NULL)
20308+ return NULL; /* it worked */
20309+ if (*oops != '?')
20310+ return oops; /* it *was* probably meant as a d.q. */
20311+
20312+ /* try it as a name -- first, NUL-terminate it */
20313+ if (srclen > sizeof(namebuf)-1) {
20314+ p = (char *) MALLOC(srclen+1);
20315+ if (p == NULL)
20316+ return "unable to allocate temporary space for name";
20317+ }
20318+ p[0] = '\0';
20319+ strncat(p, src, srclen);
20320+
20321+ /* next, check that it's a vaguely legal name */
20322+ for (q = p; *q != '\0'; q++)
20323+ if (!isprint(*q))
20324+ return "unprintable character in name";
20325+ if (strspn(p, namechars) != srclen)
20326+ return "illegal (non-DNS-name) character in name";
20327+
20328+ /* try as host name, failing that as /etc/networks network name */
20329+ h = gethostbyname(p);
20330+ if (h == NULL)
20331+ ne = getnetbyname(p);
20332+ if (p != namebuf)
20333+ FREE(p);
20334+ if (h == NULL && ne == NULL)
20335+ return "name lookup failed";
20336+
20337+ if (h != NULL)
20338+ memcpy(&addrp->s_addr, h->h_addr, sizeof(addrp->s_addr));
20339+ else
20340+ addrp->s_addr = htonl(ne->n_net);
20341+ return NULL;
20342+}
20343+
20344+/*
20345+ - try8hosthex - try conversion as an eight-digit host-order hex number
20346+ */
20347+const char * /* NULL for success, else string literal */
20348+try8hosthex(src, srclen, addrp)
20349+const char *src;
20350+size_t srclen; /* should be 8 */
20351+struct in_addr *addrp;
20352+{
20353+ const char *oops;
20354+ unsigned long addr;
20355+
20356+ if (srclen != 8)
20357+ return "internal error, try8hex called with bad length";
20358+
20359+ oops = atoul(src, srclen, 16, &addr);
20360+ if (oops != NULL)
20361+ return oops;
20362+
20363+ addrp->s_addr = addr;
20364+ return NULL;
20365+}
20366+
20367+/*
20368+ - try8hex - try conversion as an eight-digit network-order hex number
20369+ */
20370+const char * /* NULL for success, else string literal */
20371+try8hex(src, srclen, addrp)
20372+const char *src;
20373+size_t srclen; /* should be 8 */
20374+struct in_addr *addrp;
20375+{
20376+ const char *oops;
20377+
20378+ oops = try8hosthex(src, srclen, addrp);
20379+ if (oops != NULL)
20380+ return oops;
20381+
20382+ addrp->s_addr = htonl(addrp->s_addr);
20383+ return NULL;
20384+}
20385+
20386+/*
20387+ - trydotted - try conversion as dotted decimal
20388+ *
20389+ * If the first char of a complaint is '?', that means "didn't look like
20390+ * dotted decimal at all".
20391+ */
20392+const char * /* NULL for success, else string literal */
20393+trydotted(src, srclen, addrp)
20394+const char *src;
20395+size_t srclen;
20396+struct in_addr *addrp;
20397+{
20398+ const char *stop = src + srclen; /* just past end */
20399+ int byte;
20400+ const char *oops;
20401+ unsigned long addr;
20402+ int i;
20403+# define NBYTES 4
20404+# define BYTE 8
20405+
20406+ addr = 0;
20407+ for (i = 0; i < NBYTES && src < stop; i++) {
20408+ oops = getbyte(&src, stop, &byte);
20409+ if (oops != NULL) {
20410+ if (*oops != '?')
20411+ return oops; /* bad number */
20412+ if (i > 1)
20413+ return oops+1; /* failed number */
20414+ return oops; /* with leading '?' */
20415+ }
20416+ addr = (addr << BYTE) | byte;
20417+ if (i < 3 && src < stop && *src++ != '.') {
20418+ if (i == 0)
20419+ return "?syntax error in dotted-decimal address";
20420+ else
20421+ return "syntax error in dotted-decimal address";
20422+ }
20423+ }
20424+ addr <<= (NBYTES - i) * BYTE;
20425+ if (src != stop)
20426+ return "extra garbage on end of dotted-decimal address";
20427+
20428+ addrp->s_addr = htonl(addr);
20429+ return NULL;
20430+}
20431+
20432+/*
20433+ - getbyte - try to scan a byte in dotted decimal
20434+ * A subtlety here is that all this arithmetic on ASCII digits really is
20435+ * highly portable -- ANSI C guarantees that digits 0-9 are contiguous.
20436+ * It's easier to just do it ourselves than set up for a call to atoul().
20437+ *
20438+ * If the first char of a complaint is '?', that means "didn't look like a
20439+ * number at all".
20440+ */
20441+const char * /* NULL for success, else string literal */
20442+getbyte(srcp, stop, retp)
20443+const char **srcp; /* *srcp is updated */
20444+const char *stop; /* first untouchable char */
20445+int *retp; /* return-value pointer */
20446+{
20447+ char c;
20448+ const char *p;
20449+ int no;
20450+
20451+ if (*srcp >= stop)
20452+ return "?empty number in dotted-decimal address";
20453+
20454+ if (stop - *srcp >= 3 && **srcp == '0' && CIEQ(*(*srcp+1), 'x'))
20455+ return "hex numbers not supported in dotted-decimal addresses";
20456+#ifdef NOLEADINGZEROS
20457+ if (stop - *srcp >= 2 && **srcp == '0' && isdigit(*(*srcp+1)))
20458+ return "octal numbers not supported in dotted-decimal addresses";
20459+#endif /* NOLEADINGZEROS */
20460+
20461+ /* must be decimal, if it's numeric at all */
20462+ no = 0;
20463+ p = *srcp;
20464+ while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') {
20465+ no = no*10 + (c - '0');
20466+ p++;
20467+ }
20468+ if (p == *srcp)
20469+ return "?non-numeric component in dotted-decimal address";
20470+ *srcp = p;
20471+ if (no > 255)
20472+ return "byte overflow in dotted-decimal address";
20473+ *retp = no;
20474+ return NULL;
20475+}
20476diff -druN linux-noipsec/net/ipsec/libfreeswan/atoasr.c linux/net/ipsec/libfreeswan/atoasr.c
20477--- linux-noipsec/net/ipsec/libfreeswan/atoasr.c Thu Jan 1 01:00:00 1970
20478+++ linux/net/ipsec/libfreeswan/atoasr.c Tue Dec 7 06:00:51 1999
20479@@ -0,0 +1,212 @@
20480+/*
20481+ * convert from ASCII form of address/subnet/range to binary
20482+ * Copyright (C) 1998, 1999 Henry Spencer.
20483+ *
20484+ * This library is free software; you can redistribute it and/or modify it
20485+ * under the terms of the GNU Library General Public License as published by
20486+ * the Free Software Foundation; either version 2 of the License, or (at your
20487+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
20488+ *
20489+ * This library is distributed in the hope that it will be useful, but
20490+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20491+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20492+ * License for more details.
20493+ *
20494+ * RCSID $Id$
20495+ */
20496+#include "internal.h"
20497+#include "freeswan.h"
20498+
20499+/*
20500+ - atoasr - convert ASCII to address, subnet, or range
20501+ */
20502+const char * /* NULL for success, else string literal */
20503+atoasr(src, srclen, typep, addrsp)
20504+const char *src;
20505+size_t srclen; /* 0 means "apply strlen" */
20506+char *typep; /* return type code: 'a', 's', 'r' */
20507+struct in_addr addrsp[2];
20508+{
20509+ const char *punct;
20510+ const char *stop;
20511+ const char *oops;
20512+
20513+ if (srclen == 0)
20514+ srclen = strlen(src);
20515+ if (srclen == 0)
20516+ return "empty string";
20517+
20518+ /* subnet is easy to spot */
20519+ punct = memchr(src, '/', srclen);
20520+ if (punct != NULL) {
20521+ *typep = 's';
20522+ return atosubnet(src, srclen, &addrsp[0], &addrsp[1]);
20523+ }
20524+
20525+ /* try for a range */
20526+ stop = src + srclen;
20527+ for (punct = src; (punct = memchr(punct, '.', stop - punct)) != NULL;
20528+ punct++)
20529+ if (stop - punct > 3 && *(punct+1) == '.' && *(punct+2) == '.')
20530+ break; /* NOTE BREAK OUT */
20531+ if (punct == NULL) {
20532+ /* didn't find the range delimiter, must be plain address */
20533+ *typep = 'a';
20534+ return atoaddr(src, srclen, &addrsp[0]);
20535+ }
20536+
20537+ /* looks like a range */
20538+ *typep = 'r';
20539+ if (stop - punct > 4 && *(punct+3) == '.')
20540+ punct++; /* first dot is trailing dot of name */
20541+ oops = atoaddr(src, punct - src, &addrsp[0]);
20542+ if (oops != NULL)
20543+ return oops;
20544+ oops = atoaddr(punct+3, stop - (punct+3), &addrsp[1]);
20545+ if (oops != NULL)
20546+ return oops;
20547+ if (ntohl(addrsp[0].s_addr) > ntohl(addrsp[1].s_addr))
20548+ return "invalid range, begin > end";
20549+ return NULL;
20550+}
20551+
20552+
20553+
20554+#ifdef ATOASR_MAIN
20555+
20556+#include <stdio.h>
20557+
20558+void regress();
20559+
20560+int
20561+main(argc, argv)
20562+int argc;
20563+char *argv[];
20564+{
20565+ struct in_addr a[2];
20566+ char buf[100];
20567+ const char *oops;
20568+ size_t n;
20569+ char type;
20570+
20571+ if (argc < 2) {
20572+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
20573+ argv[0]);
20574+ exit(2);
20575+ }
20576+
20577+ if (strcmp(argv[1], "-r") == 0) {
20578+ regress();
20579+ fprintf(stderr, "regress() returned?!?\n");
20580+ exit(1);
20581+ }
20582+
20583+ oops = atoasr(argv[1], 0, &type, a);
20584+ if (oops != NULL) {
20585+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
20586+ exit(1);
20587+ }
20588+ switch (type) {
20589+ case 'a':
20590+ n = addrtoa(a[0], 0, buf, sizeof(buf));
20591+ break;
20592+ case 's':
20593+ n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
20594+ break;
20595+ case 'r':
20596+ n = rangetoa(a, 0, buf, sizeof(buf));
20597+ break;
20598+ default:
20599+ fprintf(stderr, "%s: unknown type '%c'\n", argv[0], type);
20600+ exit(1);
20601+ break;
20602+ }
20603+ if (n > sizeof(buf)) {
20604+ fprintf(stderr, "%s: reverse conversion of ", argv[0]);
20605+ fprintf(stderr, "%s ", inet_ntoa(a[0]));
20606+ fprintf(stderr, "%s", inet_ntoa(a[1]));
20607+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
20608+ (long)n, (long)sizeof(buf));
20609+ exit(1);
20610+ }
20611+ printf("%s\n", buf);
20612+
20613+ exit(0);
20614+}
20615+
20616+struct rtab {
20617+ char *input;
20618+ char *output; /* NULL means error expected */
20619+} rtab[] = {
20620+ "1.2.3.0", "1.2.3.0",
20621+ "1.2.3.0/255.255.255.0", "1.2.3.0/24",
20622+ "1.2.3.0...1.2.3.5", "1.2.3.0...1.2.3.5",
20623+ "1.2.3.4.5", NULL,
20624+ "1.2.3.4/", NULL,
20625+ "1.2.3.4...", NULL,
20626+ "1.2.3.4....", NULL,
20627+ "localhost./32", "127.0.0.1/32",
20628+ "localhost....127.0.0.3", "127.0.0.1...127.0.0.3",
20629+ "127.0.0.0...localhost.", "127.0.0.0...127.0.0.1",
20630+ "127.0.0.3...localhost.", NULL,
20631+ NULL, NULL
20632+};
20633+
20634+void
20635+regress()
20636+{
20637+ struct rtab *r;
20638+ int status = 0;
20639+ struct in_addr a[2];
20640+ struct in_addr m;
20641+ char in[100];
20642+ char buf[100];
20643+ const char *oops;
20644+ size_t n;
20645+ char type;
20646+
20647+ for (r = rtab; r->input != NULL; r++) {
20648+ strcpy(in, r->input);
20649+ oops = atoasr(in, 0, &type, a);
20650+ if (oops != NULL && r->output == NULL)
20651+ {} /* okay, error expected */
20652+ else if (oops != NULL) {
20653+ printf("`%s' atoasr failed: %s\n", r->input, oops);
20654+ status = 1;
20655+ } else if (r->output == NULL) {
20656+ printf("`%s' atoasr succeeded unexpectedly '%c'\n",
20657+ r->input, type);
20658+ status = 1;
20659+ } else {
20660+ switch (type) {
20661+ case 'a':
20662+ n = addrtoa(a[0], 0, buf, sizeof(buf));
20663+ break;
20664+ case 's':
20665+ n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
20666+ break;
20667+ case 'r':
20668+ n = rangetoa(a, 0, buf, sizeof(buf));
20669+ break;
20670+ default:
20671+ fprintf(stderr, "`%s' unknown type '%c'\n",
20672+ r->input, type);
20673+ n = 0;
20674+ status = 1;
20675+ break;
20676+ }
20677+ if (n > sizeof(buf)) {
20678+ printf("`%s' '%c' reverse failed: need %ld\n",
20679+ r->input, type, (long)n);
20680+ status = 1;
20681+ } else if (n > 0 && strcmp(r->output, buf) != 0) {
20682+ printf("`%s' '%c' gave `%s', expected `%s'\n",
20683+ r->input, type, buf, r->output);
20684+ status = 1;
20685+ }
20686+ }
20687+ }
20688+ exit(status);
20689+}
20690+
20691+#endif /* ATOASR_MAIN */
20692diff -druN linux-noipsec/net/ipsec/libfreeswan/atosa.c linux/net/ipsec/libfreeswan/atosa.c
20693--- linux-noipsec/net/ipsec/libfreeswan/atosa.c Thu Jan 1 01:00:00 1970
20694+++ linux/net/ipsec/libfreeswan/atosa.c Sun Sep 17 20:55:37 2000
20695@@ -0,0 +1,199 @@
20696+/*
20697+ * convert from ASCII form of SA ID to binary
20698+ * Copyright (C) 1998, 1999 Henry Spencer.
20699+ *
20700+ * This library is free software; you can redistribute it and/or modify it
20701+ * under the terms of the GNU Library General Public License as published by
20702+ * the Free Software Foundation; either version 2 of the License, or (at your
20703+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
20704+ *
20705+ * This library is distributed in the hope that it will be useful, but
20706+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20707+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20708+ * License for more details.
20709+ *
20710+ * RCSID $Id$
20711+ */
20712+#include "internal.h"
20713+#include "freeswan.h"
20714+
20715+static struct satype {
20716+ char *prefix;
20717+ size_t prelen; /* strlen(prefix) */
20718+ int proto;
20719+} satypes[] = {
20720+ { "ah", 2, SA_AH },
20721+ { "esp", 3, SA_ESP },
20722+ { "tun", 3, SA_IPIP },
20723+ { "comp", 4, SA_COMP },
20724+ { NULL, 0, 0, }
20725+};
20726+
20727+/*
20728+ - atosa - convert ASCII "ah507@10.0.0.1" to SA identifier
20729+ */
20730+const char * /* NULL for success, else string literal */
20731+atosa(src, srclen, sa)
20732+const char *src;
20733+size_t srclen; /* 0 means "apply strlen" */
20734+struct sa_id *sa;
20735+{
20736+ const char *at;
20737+ const char *addr;
20738+ const char *spi = NULL;
20739+ struct satype *sat;
20740+ unsigned long ul;
20741+ const char *oops;
20742+# define MINLEN 5 /* ah0@0 is as short as it can get */
20743+ static char ptname[] = PASSTHROUGHNAME;
20744+# define PTNLEN (sizeof(ptname)-1) /* -1 for NUL */
20745+
20746+ if (srclen == 0)
20747+ srclen = strlen(src);
20748+ if (srclen == 0)
20749+ return "empty string";
20750+ if (srclen < MINLEN)
20751+ return "string too short to be SA specifier";
20752+ if (srclen == PTNLEN && memcmp(src, ptname, PTNLEN) == 0) {
20753+ src = PASSTHROUGHIS;
20754+ srclen = strlen(src);
20755+ }
20756+
20757+ at = memchr(src, '@', srclen);
20758+ if (at == NULL)
20759+ return "no @ in SA specifier";
20760+
20761+ for (sat = satypes; sat->prefix != NULL; sat++)
20762+ if (sat->prelen < srclen &&
20763+ strncmp(src, sat->prefix, sat->prelen) == 0) {
20764+ sa->proto = sat->proto;
20765+ spi = src + sat->prelen;
20766+ break; /* NOTE BREAK OUT */
20767+ }
20768+ if (sat->prefix == NULL)
20769+ return "SA specifier lacks valid protocol prefix";
20770+
20771+ if (spi >= at)
20772+ return "no SPI in SA specifier";
20773+ oops = atoul(spi, at - spi, 13, &ul);
20774+ if (oops != NULL)
20775+ return oops;
20776+ sa->spi = htonl(ul);
20777+
20778+ addr = at + 1;
20779+ oops = atoaddr(addr, srclen - (addr - src), &sa->dst);
20780+ if (oops != NULL)
20781+ return oops;
20782+
20783+ return NULL;
20784+}
20785+
20786+
20787+
20788+#ifdef ATOSA_MAIN
20789+
20790+#include <stdio.h>
20791+
20792+void regress();
20793+
20794+int
20795+main(argc, argv)
20796+int argc;
20797+char *argv[];
20798+{
20799+ struct sa_id sa;
20800+ char buf[100];
20801+ const char *oops;
20802+ size_t n;
20803+
20804+ if (argc < 2) {
20805+ fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
20806+ exit(2);
20807+ }
20808+
20809+ if (strcmp(argv[1], "-r") == 0) {
20810+ regress();
20811+ fprintf(stderr, "regress() returned?!?\n");
20812+ exit(1);
20813+ }
20814+
20815+ oops = atosa(argv[1], 0, &sa);
20816+ if (oops != NULL) {
20817+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
20818+ exit(1);
20819+ }
20820+ n = satoa(sa, 0, buf, sizeof(buf));
20821+ if (n > sizeof(buf)) {
20822+ fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto);
20823+ fprintf(stderr, "%lu@", sa.spi);
20824+ fprintf(stderr, "%s", inet_ntoa(sa.dst));
20825+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
20826+ (long)n, (long)sizeof(buf));
20827+ exit(1);
20828+ }
20829+ printf("%s\n", buf);
20830+
20831+ exit(0);
20832+}
20833+
20834+struct rtab {
20835+ char *input;
20836+ char *output; /* NULL means error expected */
20837+} rtab[] = {
20838+ "esp257@1.2.3.0", "esp257@1.2.3.0",
20839+ "ah0x20@1.2.3.4", "ah32@1.2.3.4",
20840+ "tun011@111.2.3.99", "tun11@111.2.3.99",
20841+ "", NULL,
20842+ "_", NULL,
20843+ "ah2.2", NULL,
20844+ "goo2@1.2.3.4", NULL,
20845+ "esp9@1.2.3.4", "esp9@1.2.3.4",
20846+ "espp9@1.2.3.4", NULL,
20847+ "es9@1.2.3.4", NULL,
20848+ "ah@1.2.3.4", NULL,
20849+ "esp7x7@1.2.3.4", NULL,
20850+ "esp77@1.0x2.3.4", NULL,
20851+ PASSTHROUGHNAME, PASSTHROUGHNAME,
20852+ NULL, NULL
20853+};
20854+
20855+void
20856+regress()
20857+{
20858+ struct rtab *r;
20859+ int status = 0;
20860+ struct sa_id sa;
20861+ char in[100];
20862+ char buf[100];
20863+ const char *oops;
20864+ size_t n;
20865+
20866+ for (r = rtab; r->input != NULL; r++) {
20867+ strcpy(in, r->input);
20868+ oops = atosa(in, 0, &sa);
20869+ if (oops != NULL && r->output == NULL)
20870+ {} /* okay, error expected */
20871+ else if (oops != NULL) {
20872+ printf("`%s' atosa failed: %s\n", r->input, oops);
20873+ status = 1;
20874+ } else if (r->output == NULL) {
20875+ printf("`%s' atosa succeeded unexpectedly\n",
20876+ r->input);
20877+ status = 1;
20878+ } else {
20879+ n = satoa(sa, 'd', buf, sizeof(buf));
20880+ if (n > sizeof(buf)) {
20881+ printf("`%s' satoa failed: need %ld\n",
20882+ r->input, (long)n);
20883+ status = 1;
20884+ } else if (strcmp(r->output, buf) != 0) {
20885+ printf("`%s' gave `%s', expected `%s'\n",
20886+ r->input, buf, r->output);
20887+ status = 1;
20888+ }
20889+ }
20890+ }
20891+ exit(status);
20892+}
20893+
20894+#endif /* ATOSA_MAIN */
20895diff -druN linux-noipsec/net/ipsec/libfreeswan/atosubnet.c linux/net/ipsec/libfreeswan/atosubnet.c
20896--- linux-noipsec/net/ipsec/libfreeswan/atosubnet.c Thu Jan 1 01:00:00 1970
20897+++ linux/net/ipsec/libfreeswan/atosubnet.c Wed Feb 16 19:59:08 2000
20898@@ -0,0 +1,215 @@
20899+/*
20900+ * convert from ASCII form of subnet specification to binary
20901+ * Copyright (C) 1998, 1999 Henry Spencer.
20902+ *
20903+ * This library is free software; you can redistribute it and/or modify it
20904+ * under the terms of the GNU Library General Public License as published by
20905+ * the Free Software Foundation; either version 2 of the License, or (at your
20906+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
20907+ *
20908+ * This library is distributed in the hope that it will be useful, but
20909+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20910+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20911+ * License for more details.
20912+ *
20913+ * RCSID $Id$
20914+ */
20915+#include "internal.h"
20916+#include "freeswan.h"
20917+
20918+#ifndef DEFAULTSUBNET
20919+#define DEFAULTSUBNET "%default"
20920+#endif
20921+
20922+/*
20923+ - atosubnet - convert ASCII "addr/mask" to address and mask
20924+ * Mask can be integer bit count.
20925+ */
20926+const char * /* NULL for success, else string literal */
20927+atosubnet(src, srclen, addrp, maskp)
20928+const char *src;
20929+size_t srclen; /* 0 means "apply strlen" */
20930+struct in_addr *addrp;
20931+struct in_addr *maskp;
20932+{
20933+ const char *slash;
20934+ const char *mask;
20935+ size_t mlen;
20936+ const char *oops;
20937+ unsigned long bc;
20938+ static char def[] = DEFAULTSUBNET;
20939+# define DEFLEN (sizeof(def) - 1) /* -1 for NUL */
20940+ static char defis[] = "0/0";
20941+# define DEFILEN (sizeof(defis) - 1)
20942+
20943+ if (srclen == 0)
20944+ srclen = strlen(src);
20945+ if (srclen == 0)
20946+ return "empty string";
20947+
20948+ if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) {
20949+ src = defis;
20950+ srclen = DEFILEN;
20951+ }
20952+
20953+ slash = memchr(src, '/', srclen);
20954+ if (slash == NULL)
20955+ return "no / in subnet specification";
20956+ mask = slash + 1;
20957+ mlen = srclen - (mask - src);
20958+
20959+ oops = atoaddr(src, slash-src, addrp);
20960+ if (oops != NULL)
20961+ return oops;
20962+
20963+ oops = atoul(mask, mlen, 10, &bc);
20964+ if (oops == NULL) {
20965+ /* atoul succeeded, it's a bit-count mask */
20966+ if (bc > ABITS)
20967+ return "bit-count mask too large";
20968+#ifdef NOLEADINGZEROS
20969+ if (mlen > 1 && *mask == '0')
20970+ return "octal not allowed in mask";
20971+#endif /* NOLEADINGZEROS */
20972+ *maskp = bitstomask((int)bc);
20973+ } else {
20974+ oops = atoaddr(mask, mlen, maskp);
20975+ if (oops != NULL)
20976+ return oops;
20977+ if (!goodmask(*maskp))
20978+ return "non-contiguous mask";
20979+ }
20980+
20981+ addrp->s_addr &= maskp->s_addr;
20982+ return NULL;
20983+}
20984+
20985+
20986+
20987+#ifdef ATOSUBNET_MAIN
20988+
20989+#include <stdio.h>
20990+
20991+void regress();
20992+
20993+int
20994+main(argc, argv)
20995+int argc;
20996+char *argv[];
20997+{
20998+ struct in_addr a;
20999+ struct in_addr m;
21000+ char buf[100];
21001+ const char *oops;
21002+ size_t n;
21003+
21004+ if (argc < 2) {
21005+ fprintf(stderr, "Usage: %s {addr/mask|-r}\n", argv[0]);
21006+ exit(2);
21007+ }
21008+
21009+ if (strcmp(argv[1], "-r") == 0) {
21010+ regress();
21011+ fprintf(stderr, "regress() returned?!?\n");
21012+ exit(1);
21013+ }
21014+
21015+ oops = atosubnet(argv[1], 0, &a, &m);
21016+ if (oops != NULL) {
21017+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
21018+ exit(1);
21019+ }
21020+ n = subnettoa(a, m, 0, buf, sizeof(buf));
21021+ if (n > sizeof(buf)) {
21022+ fprintf(stderr, "%s: reverse conversion of ", argv[0]);
21023+ fprintf(stderr, "%s/", inet_ntoa(a));
21024+ fprintf(stderr, "%s", inet_ntoa(m));
21025+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
21026+ (long)n, (long)sizeof(buf));
21027+ exit(1);
21028+ }
21029+ printf("%s\n", buf);
21030+
21031+ exit(0);
21032+}
21033+
21034+struct rtab {
21035+ char *input;
21036+ char *output; /* NULL means error expected */
21037+} rtab[] = {
21038+ "1.2.3.0/255.255.255.0", "1.2.3.0/24",
21039+ "1.2.3.0/24", "1.2.3.0/24",
21040+ "1.2.3.1/255.255.255.240", "1.2.3.0/28",
21041+ "1.2.3.1/32", "1.2.3.1/32",
21042+ "1.2.3.1/0", "0.0.0.0/0",
21043+/* "1.2.3.1/255.255.127.0", "1.2.3.0/255.255.127.0", */
21044+ "1.2.3.1/255.255.127.0", NULL,
21045+ "128.009.000.032/32", "128.9.0.32/32",
21046+ "128.0x9.0.32/32", NULL,
21047+ "0x80090020/32", "128.9.0.32/32",
21048+ "0x800x0020/32", NULL,
21049+ "128.9.0.32/0xffFF0000", "128.9.0.0/16",
21050+ "128.9.0.32/0xff0000FF", NULL,
21051+ "128.9.0.32/0x0000ffFF", NULL,
21052+ "128.9.0.32/0x00ffFF0000", NULL,
21053+ "128.9.0.32/0xffFF", NULL,
21054+ "128.9.0.32.27/32", NULL,
21055+ "128.9.0k32/32", NULL,
21056+ "328.9.0.32/32", NULL,
21057+ "128.9..32/32", NULL,
21058+ "10/8", "10.0.0.0/8",
21059+ "10.0/8", "10.0.0.0/8",
21060+ "10.0.0/8", "10.0.0.0/8",
21061+ "10.0.1/24", "10.0.1.0/24",
21062+ "_", NULL,
21063+ "_/_", NULL,
21064+ "1.2.3.1", NULL,
21065+ "1.2.3.1/_", NULL,
21066+ "1.2.3.1/24._", NULL,
21067+ "1.2.3.1/99", NULL,
21068+ "localhost./32", "127.0.0.1/32",
21069+ "%default", "0.0.0.0/0",
21070+ NULL, NULL
21071+};
21072+
21073+void
21074+regress()
21075+{
21076+ struct rtab *r;
21077+ int status = 0;
21078+ struct in_addr a;
21079+ struct in_addr m;
21080+ char in[100];
21081+ char buf[100];
21082+ const char *oops;
21083+ size_t n;
21084+
21085+ for (r = rtab; r->input != NULL; r++) {
21086+ strcpy(in, r->input);
21087+ oops = atosubnet(in, 0, &a, &m);
21088+ if (oops != NULL && r->output == NULL)
21089+ {} /* okay, error expected */
21090+ else if (oops != NULL) {
21091+ printf("`%s' atosubnet failed: %s\n", r->input, oops);
21092+ status = 1;
21093+ } else if (r->output == NULL) {
21094+ printf("`%s' atosubnet succeeded unexpectedly\n",
21095+ r->input);
21096+ status = 1;
21097+ } else {
21098+ n = subnettoa(a, m, 0, buf, sizeof(buf));
21099+ if (n > sizeof(buf)) {
21100+ printf("`%s' subnettoa failed: need %ld\n",
21101+ r->input, (long)n);
21102+ status = 1;
21103+ } else if (strcmp(r->output, buf) != 0) {
21104+ printf("`%s' gave `%s', expected `%s'\n",
21105+ r->input, buf, r->output);
21106+ status = 1;
21107+ }
21108+ }
21109+ }
21110+ exit(status);
21111+}
21112+
21113+#endif /* ATOSUBNET_MAIN */
21114diff -druN linux-noipsec/net/ipsec/libfreeswan/atoul.c linux/net/ipsec/libfreeswan/atoul.c
21115--- linux-noipsec/net/ipsec/libfreeswan/atoul.c Thu Jan 1 01:00:00 1970
21116+++ linux/net/ipsec/libfreeswan/atoul.c Tue Dec 7 06:00:52 1999
21117@@ -0,0 +1,90 @@
21118+/*
21119+ * convert from ASCII form of unsigned long to binary
21120+ * Copyright (C) 1998, 1999 Henry Spencer.
21121+ *
21122+ * This library is free software; you can redistribute it and/or modify it
21123+ * under the terms of the GNU Library General Public License as published by
21124+ * the Free Software Foundation; either version 2 of the License, or (at your
21125+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
21126+ *
21127+ * This library is distributed in the hope that it will be useful, but
21128+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21129+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
21130+ * License for more details.
21131+ *
21132+ * RCSID $Id$
21133+ */
21134+#include "internal.h"
21135+#include "freeswan.h"
21136+
21137+/*
21138+ - atoul - convert ASCII substring to unsigned long number
21139+ */
21140+const char * /* NULL for success, else string literal */
21141+atoul(src, srclen, base, resultp)
21142+const char *src;
21143+size_t srclen; /* 0 means strlen(src) */
21144+int base; /* 0 means figure it out */
21145+unsigned long *resultp;
21146+{
21147+ const char *stop;
21148+ static char hex[] = "0123456789abcdef";
21149+ static char uchex[] = "0123456789ABCDEF";
21150+ int d;
21151+ char c;
21152+ char *p;
21153+ unsigned long r;
21154+ unsigned long rlimit;
21155+ int dlimit;
21156+
21157+ if (srclen == 0)
21158+ srclen = strlen(src);
21159+ if (srclen == 0)
21160+ return "empty string";
21161+
21162+ if (base == 0 || base == 13) {
21163+ if (srclen > 2 && *src == '0' && CIEQ(*(src+1), 'x'))
21164+ return atoul(src+2, srclen-2, 16, resultp);
21165+ if (srclen > 1 && *src == '0' && base != 13)
21166+ return atoul(src+1, srclen-1, 8, resultp);
21167+ return atoul(src, srclen, 10, resultp);
21168+ }
21169+ if (base != 8 && base != 10 && base != 16)
21170+ return "unsupported number base";
21171+
21172+ r = 0;
21173+ stop = src + srclen;
21174+ if (base == 16) {
21175+ while (src < stop) {
21176+ c = *src++;
21177+ p = strchr(hex, c);
21178+ if (p != NULL)
21179+ d = p - hex;
21180+ else {
21181+ p = strchr(uchex, c);
21182+ if (p == NULL)
21183+ return "non-hex-digit in hex number";
21184+ d = p - uchex;
21185+ }
21186+ r = (r << 4) | d;
21187+ }
21188+ /* defer length check to catch invalid digits first */
21189+ if (srclen > sizeof(unsigned long) * 2)
21190+ return "hex number too long";
21191+ } else {
21192+ rlimit = ULONG_MAX / base;
21193+ dlimit = (int)(ULONG_MAX - rlimit*base);
21194+ while (src < stop) {
21195+ c = *src++;
21196+ d = c - '0';
21197+ if (d < 0 || d >= base)
21198+ return "non-digit in number";
21199+ if (r > rlimit || (r == rlimit && d > dlimit))
21200+ return "unsigned-long overflow";
21201+ r = r*base + d;
21202+ }
21203+ }
21204+
21205+ *resultp = r;
21206+ return NULL;
21207+}
21208diff -druN linux-noipsec/net/ipsec/libfreeswan/datatot.c linux/net/ipsec/libfreeswan/datatot.c
21209--- linux-noipsec/net/ipsec/libfreeswan/datatot.c Thu Jan 1 01:00:00 1970
21210+++ linux/net/ipsec/libfreeswan/datatot.c Fri Aug 18 17:09:07 2000
21211@@ -0,0 +1,225 @@
21212+/*
21213+ * convert from binary data (e.g. key) to text form
21214+ * Copyright (C) 2000 Henry Spencer.
21215+ *
21216+ * This library is free software; you can redistribute it and/or modify it
21217+ * under the terms of the GNU Library General Public License as published by
21218+ * the Free Software Foundation; either version 2 of the License, or (at your
21219+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
21220+ *
21221+ * This library is distributed in the hope that it will be useful, but
21222+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21223+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
21224+ * License for more details.
21225+ *
21226+ * RCSID $Id$
21227+ */
21228+#include "internal.h"
21229+#include "freeswan.h"
21230+
21231+static void convert(const char *src, size_t nreal, int format, char *out);
21232+
21233+/*
21234+ - datatot - convert data bytes to text
21235+ */
21236+size_t /* true length (with NUL) for success */
21237+datatot(src, srclen, format, dst, dstlen)
21238+const char *src;
21239+size_t srclen;
21240+int format; /* character indicating what format */
21241+char *dst; /* need not be valid if dstlen is 0 */
21242+size_t dstlen;
21243+{
21244+ size_t inblocksize; /* process this many bytes at a time */
21245+ size_t outblocksize; /* producing this many */
21246+ size_t breakevery; /* add a _ every this many (0 means don't) */
21247+ size_t sincebreak; /* output bytes since last _ */
21248+ char inblock[10]; /* enough for any format */
21249+ char outblock[10]; /* enough for any format */
21250+ char fake[1]; /* fake output area for dstlen == 0 */
21251+ size_t needed; /* return value */
21252+ char *stop; /* where the terminating NUL will go */
21253+ size_t ntodo; /* remaining input */
21254+ size_t nreal;
21255+ char *out;
21256+ char *prefix;
21257+
21258+ breakevery = 0;
21259+ switch (format) {
21260+ case 0:
21261+ case 'h':
21262+ format = 'x';
21263+ breakevery = 8;
21264+ /* FALLTHROUGH */
21265+ case 'x':
21266+ inblocksize = 1;
21267+ outblocksize = 2;
21268+ prefix = "0x";
21269+ break;
21270+ case 16:
21271+ inblocksize = 1;
21272+ outblocksize = 2;
21273+ prefix = "";
21274+ format = 'x';
21275+ break;
21276+ case 's':
21277+ inblocksize = 3;
21278+ outblocksize = 4;
21279+ prefix = "0s";
21280+ break;
21281+ case 64: /* beware, equals ' ' */
21282+ inblocksize = 3;
21283+ outblocksize = 4;
21284+ prefix = "";
21285+ format = 's';
21286+ break;
21287+ default:
21288+ return 0;
21289+ break;
21290+ }
21291+ assert(inblocksize < sizeof(inblock));
21292+ assert(outblocksize < sizeof(outblock));
21293+ assert(breakevery % outblocksize == 0);
21294+
21295+ if (srclen == 0)
21296+ return 0;
21297+ ntodo = srclen;
21298+
21299+ if (dstlen == 0) { /* dispose of awkward special case */
21300+ dst = fake;
21301+ dstlen = 1;
21302+ }
21303+ stop = dst + dstlen - 1;
21304+
21305+ nreal = strlen(prefix);
21306+ needed = nreal; /* for starters */
21307+ if (dstlen <= nreal) { /* prefix won't fit */
21308+ strncpy(dst, prefix, dstlen - 1);
21309+ dst += dstlen - 1;
21310+ } else {
21311+ strcpy(dst, prefix);
21312+ dst += nreal;
21313+ }
21314+ assert(dst <= stop);
21315+ sincebreak = 0;
21316+
21317+ while (ntodo > 0) {
21318+ if (ntodo < inblocksize) { /* incomplete input */
21319+ memset(inblock, 0, sizeof(inblock));
21320+ memcpy(inblock, src, ntodo);
21321+ src = inblock;
21322+ nreal = ntodo;
21323+ ntodo = inblocksize;
21324+ } else
21325+ nreal = inblocksize;
21326+ out = (outblocksize > stop - dst) ? outblock : dst;
21327+
21328+ convert(src, nreal, format, out);
21329+ needed += outblocksize;
21330+ sincebreak += outblocksize;
21331+ if (dst < stop) {
21332+ if (out != dst) {
21333+ assert(outblocksize > stop - dst);
21334+ memcpy(dst, out, stop - dst);
21335+ dst = stop;
21336+ } else
21337+ dst += outblocksize;
21338+ }
21339+
21340+ src += inblocksize;
21341+ ntodo -= inblocksize;
21342+ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
21343+ if (dst < stop)
21344+ *dst++ = '_';
21345+ needed++;
21346+ sincebreak = 0;
21347+ }
21348+ }
21349+
21350+ assert(dst <= stop);
21351+ *dst++ = '\0';
21352+ needed++;
21353+
21354+ return needed;
21355+}
21356+
21357+/*
21358+ - convert - convert one input block to one output block
21359+ */
21360+static void
21361+convert(src, nreal, format, out)
21362+const char *src;
21363+size_t nreal; /* how much of the input block is real */
21364+int format;
21365+char *out;
21366+{
21367+ static char hex[] = "0123456789abcdef";
21368+ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
21369+ "abcdefghijklmnopqrstuvwxyz"
21370+ "0123456789+/";
21371+ unsigned char c;
21372+ unsigned char c1, c2, c3;
21373+
21374+ assert(nreal > 0);
21375+ switch (format) {
21376+ case 'x':
21377+ assert(nreal == 1);
21378+ c = (unsigned char)*src;
21379+ *out++ = hex[c >> 4];
21380+ *out++ = hex[c & 0xf];
21381+ break;
21382+ case 's':
21383+ c1 = (unsigned char)*src++;
21384+ c2 = (unsigned char)*src++;
21385+ c3 = (unsigned char)*src++;
21386+ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
21387+ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
21388+ c |= c2 >> 4; /* ...top 4 of c2 */
21389+ *out++ = base64[c];
21390+ if (nreal == 1)
21391+ *out++ = '=';
21392+ else {
21393+ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
21394+ c |= c3 >> 6; /* ...top 2 of c3 */
21395+ *out++ = base64[c];
21396+ }
21397+ if (nreal <= 2)
21398+ *out++ = '=';
21399+ else
21400+ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
21401+ break;
21402+ default:
21403+ assert(nreal == 0); /* unknown format */
21404+ break;
21405+ }
21406+}
21407+
21408+/*
21409+ - datatoa - convert data to ASCII
21410+ * backward-compatibility synonym for datatot
21411+ */
21412+size_t /* true length (with NUL) for success */
21413+datatoa(src, srclen, format, dst, dstlen)
21414+const char *src;
21415+size_t srclen;
21416+int format; /* character indicating what format */
21417+char *dst; /* need not be valid if dstlen is 0 */
21418+size_t dstlen;
21419+{
21420+ return datatot(src, srclen, format, dst, dstlen);
21421+}
21422+
21423+/*
21424+ - bytestoa - convert data bytes to ASCII
21425+ * backward-compatibility synonym for datatot
21426+ */
21427+size_t /* true length (with NUL) for success */
21428+bytestoa(src, srclen, format, dst, dstlen)
21429+const char *src;
21430+size_t srclen;
21431+int format; /* character indicating what format */
21432+char *dst; /* need not be valid if dstlen is 0 */
21433+size_t dstlen;
21434+{
21435+ return datatot(src, srclen, format, dst, dstlen);
21436+}
21437diff -druN linux-noipsec/net/ipsec/libfreeswan/freeswan.h linux/net/ipsec/libfreeswan/freeswan.h
21438--- linux-noipsec/net/ipsec/libfreeswan/freeswan.h Thu Jan 1 01:00:00 1970
21439+++ linux/net/ipsec/libfreeswan/freeswan.h Mon Nov 6 05:37:12 2000
21440@@ -0,0 +1,474 @@
21441+#ifndef _FREESWAN_H
21442+/*
21443+ * header file for FreeS/WAN library functions
21444+ * Copyright (C) 1998, 1999, 2000 Henry Spencer.
21445+ *
21446+ * This library is free software; you can redistribute it and/or modify it
21447+ * under the terms of the GNU Library General Public License as published by
21448+ * the Free Software Foundation; either version 2 of the License, or (at your
21449+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
21450+ *
21451+ * This library is distributed in the hope that it will be useful, but
21452+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21453+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
21454+ * License for more details.
21455+ *
21456+ * RCSID $Id$
21457+ */
21458+#define _FREESWAN_H /* seen it, no need to see it again */
21459+
21460+
21461+
21462+/*
21463+ * First, assorted kernel-version-dependent trickery.
21464+ */
21465+#include <linux/version.h>
21466+#ifndef KERNEL_VERSION
21467+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
21468+#endif
21469+
21470+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
21471+#define HEADER_CACHE_BIND_21
21472+#endif
21473+
21474+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
21475+#define SPINLOCK
21476+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
21477+# define SPINLOCK_23
21478+# endif
21479+#endif
21480+
21481+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
21482+#define PROC_FS_2325
21483+#else
21484+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
21485+# define PROC_FS_21
21486+# endif
21487+#endif
21488+
21489+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
21490+#define NETDEV_23
21491+#endif
21492+
21493+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
21494+#define NETLINK_SOCK
21495+#define NET_21
21496+#endif
21497+
21498+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
21499+#define PROC_NO_DUMMY
21500+#endif
21501+
21502+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
21503+#define SKB_COPY_EXPAND
21504+#endif
21505+
21506+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
21507+#define IP_SELECT_IDENT
21508+#endif
21509+
21510+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
21511+#define SKB_RESET_NFCT
21512+#endif
21513+
21514+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
21515+#define net_device_stats enet_statistics
21516+#endif
21517+
21518+
21519+
21520+/*
21521+ * We've just got to have some datatypes defined... And annoyingly, just
21522+ * where we get them depends on whether we're in userland or not.
21523+ */
21524+#ifdef __KERNEL__
21525+
21526+# include <linux/types.h>
21527+# include <linux/in.h>
21528+
21529+# ifdef NET_21
21530+# include <linux/in6.h>
21531+# else
21532+ /* old kernel in.h has some IPv6 stuff, but not quite enough */
21533+# define s6_addr16 s6_addr
21534+# define AF_INET6 10
21535+# define uint8_t __u8
21536+# define uint16_t __u16
21537+# define uint32_t __u32
21538+# define uint64_t __u64
21539+# endif
21540+
21541+# ifndef SPINLOCK
21542+# include <linux/bios32.h>
21543+ /* simulate spin locks and read/write locks */
21544+ typedef struct {
21545+ volatile char lock;
21546+ } spinlock_t;
21547+
21548+ typedef struct {
21549+ volatile unsigned int lock;
21550+ } rwlock_t;
21551+
21552+# define spin_lock_init(x) { (x)->lock = 0;}
21553+# define rw_lock_init(x) { (x)->lock = 0; }
21554+
21555+# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
21556+# define spin_lock_irq(x) { cli(); spin_lock(x);}
21557+# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
21558+
21559+# define spin_unlock(x) { (x)->lock=0;}
21560+# define spin_unlock_irq(x) { spin_unlock(x); sti();}
21561+# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
21562+
21563+# define read_lock(x) spin_lock(x)
21564+# define read_lock_irq(x) spin_lock_irq(x)
21565+# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
21566+
21567+# define read_unlock(x) spin_unlock(x)
21568+# define read_unlock_irq(x) spin_unlock_irq(x)
21569+# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
21570+
21571+# define write_lock(x) spin_lock(x)
21572+# define write_lock_irq(x) spin_lock_irq(x)
21573+# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
21574+
21575+# define write_unlock(x) spin_unlock(x)
21576+# define write_unlock_irq(x) spin_unlock_irq(x)
21577+# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
21578+# endif /* !SPINLOCK */
21579+
21580+# ifndef SPINLOCK_23
21581+# define spin_lock_bh(x) spin_lock_irq(x)
21582+# define spin_unlock_bh(x) spin_unlock_irq(x)
21583+
21584+# define read_lock_bh(x) read_lock_irq(x)
21585+# define read_unlock_bh(x) read_unlock_irq(x)
21586+
21587+# define write_lock_bh(x) write_lock_irq(x)
21588+# define write_unlock_bh(x) write_unlock_irq(x)
21589+# endif /* !SPINLOCK_23 */
21590+
21591+#ifndef IPPROTO_COMP
21592+#define IPPROTO_COMP 108
21593+#endif /* !IPPROTO_COMP */
21594+
21595+#ifdef CONFIG_IPSEC_DEBUG
21596+#define DEBUG_NO_STATIC
21597+#else /* CONFIG_IPSEC_DEBUG */
21598+#define DEBUG_NO_STATIC static
21599+#endif /* CONFIG_IPSEC_DEBUG */
21600+
21601+#else /* __KERNEL__ */
21602+
21603+# include <stdio.h>
21604+# include <netinet/in.h>
21605+
21606+# define uint8_t u_int8_t
21607+# define uint16_t u_int16_t
21608+# define uint32_t u_int32_t
21609+# define uint64_t u_int64_t
21610+
21611+#define DEBUG_NO_STATIC static
21612+
21613+#endif /* __KERNEL__ */
21614+
21615+
21616+
21617+/*
21618+ * Basic data types for the address-handling functions.
21619+ * ip_address and ip_subnet are supposed to be opaque types; do not
21620+ * use their definitions directly, they are subject to change!
21621+ */
21622+
21623+/* first, some quick fakes in case we're on an old system with no IPv6 */
21624+#ifndef __KERNEL__
21625+#ifndef IN6ADDR_ANY_INIT
21626+struct in6_addr {
21627+ unsigned char s6_addr16[16];
21628+};
21629+struct sockaddr_in6 {
21630+ unsigned short sin6_family;
21631+ unsigned short sin6_port;
21632+ unsigned long sin6_flowinfo;
21633+ struct {
21634+ unsigned char s6_addr16[16];
21635+ } sin6_addr;
21636+};
21637+#endif /* !IN6ADDR_ANY_INIT */
21638+#endif /* !__KERNEL__ */
21639+
21640+/* then the main types */
21641+typedef struct {
21642+ union {
21643+ struct sockaddr_in v4;
21644+ struct sockaddr_in6 v6;
21645+ } u;
21646+} ip_address;
21647+typedef struct {
21648+ ip_address addr;
21649+ int maskbits;
21650+} ip_subnet;
21651+
21652+/* and the SA ID stuff */
21653+#ifdef __KERNEL__
21654+typedef __u32 ipsec_spi_t;
21655+#else
21656+typedef u_int32_t ipsec_spi_t;
21657+#endif
21658+typedef struct { /* to identify an SA, we need: */
21659+ ip_address dst; /* A. destination host */
21660+ ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
21661+ int proto; /* C. protocol */
21662+# define SA_ESP 50 /* IPPROTO_ESP */
21663+# define SA_AH 51 /* IPPROTO_AH */
21664+# define SA_IPIP 4 /* IPPROTO_IPIP */
21665+# define SA_COMP 108 /* IPPROTO_COMP */
21666+} ip_said;
21667+struct sa_id { /* old v4-only version */
21668+ struct in_addr dst;
21669+ ipsec_spi_t spi;
21670+ int proto;
21671+};
21672+
21673+/* misc */
21674+typedef const char *err_t; /* error message, or NULL for success */
21675+
21676+
21677+
21678+/*
21679+ * new IPv6-compatible functions
21680+ */
21681+
21682+/* text conversions */
21683+err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
21684+size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
21685+#define ULTOT_BUF (22+1) /* holds 64 bits in octal */
21686+err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
21687+err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
21688+size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
21689+/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
21690+#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1)
21691+err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
21692+size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
21693+#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3)
21694+err_t ttosa(const char *src, size_t srclen, ip_said *dst);
21695+size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
21696+#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
21697+err_t ttodata(const char *src, size_t srclen, int base, char *buf,
21698+ size_t buflen, size_t *needed);
21699+size_t datatot(const char *src, size_t srclen, int format, char *buf,
21700+ size_t buflen);
21701+
21702+/* initializations */
21703+void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
21704+err_t loopbackaddr(int af, ip_address *dst);
21705+err_t unspecaddr(int af, ip_address *dst);
21706+err_t anyaddr(int af, ip_address *dst);
21707+err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
21708+err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
21709+
21710+/* misc. conversions and related */
21711+err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
21712+int addrtypeof(const ip_address *src);
21713+int subnettypeof(const ip_subnet *src);
21714+size_t addrlenof(const ip_address *src);
21715+size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
21716+size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
21717+int masktocount(const ip_address *src);
21718+void networkof(const ip_subnet *src, ip_address *dst);
21719+void maskof(const ip_subnet *src, ip_address *dst);
21720+
21721+/* tests */
21722+int sameaddr(const ip_address *a, const ip_address *b);
21723+int addrcmp(const ip_address *a, const ip_address *b);
21724+int samesubnet(const ip_subnet *a, const ip_subnet *b);
21725+int addrinsubnet(const ip_address *a, const ip_subnet *s);
21726+int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
21727+int subnetishost(const ip_subnet *s);
21728+int samesaid(const ip_said *a, const ip_said *b);
21729+int sameaddrtype(const ip_address *a, const ip_address *b);
21730+int samesubnettype(const ip_subnet *a, const ip_subnet *b);
21731+int isanyaddr(const ip_address *src);
21732+int isunspecaddr(const ip_address *src);
21733+int isloopbackaddr(const ip_address *src);
21734+
21735+/* low-level grot */
21736+int portof(const ip_address *src);
21737+void setportof(int port, ip_address *dst);
21738+struct sockaddr *sockaddrof(ip_address *src);
21739+size_t sockaddrlenof(const ip_address *src);
21740+
21741+
21742+
21743+/*
21744+ * old functions, to be deleted eventually
21745+ */
21746+
21747+/* unsigned long */
21748+const char * /* NULL for success, else string literal */
21749+atoul(
21750+ const char *src,
21751+ size_t srclen, /* 0 means strlen(src) */
21752+ int base, /* 0 means figure it out */
21753+ unsigned long *resultp
21754+);
21755+size_t /* space needed for full conversion */
21756+ultoa(
21757+ unsigned long n,
21758+ int base,
21759+ char *dst,
21760+ size_t dstlen
21761+);
21762+#define ULTOA_BUF 21 /* just large enough for largest result, */
21763+ /* assuming 64-bit unsigned long! */
21764+
21765+/* Internet addresses */
21766+const char * /* NULL for success, else string literal */
21767+atoaddr(
21768+ const char *src,
21769+ size_t srclen, /* 0 means strlen(src) */
21770+ struct in_addr *addr
21771+);
21772+size_t /* space needed for full conversion */
21773+addrtoa(
21774+ struct in_addr addr,
21775+ int format, /* character; 0 means default */
21776+ char *dst,
21777+ size_t dstlen
21778+);
21779+#define ADDRTOA_BUF 16 /* just large enough for largest result */
21780+
21781+/* subnets */
21782+const char * /* NULL for success, else string literal */
21783+atosubnet(
21784+ const char *src,
21785+ size_t srclen, /* 0 means strlen(src) */
21786+ struct in_addr *addr,
21787+ struct in_addr *mask
21788+);
21789+size_t /* space needed for full conversion */
21790+subnettoa(
21791+ struct in_addr addr,
21792+ struct in_addr mask,
21793+ int format, /* character; 0 means default */
21794+ char *dst,
21795+ size_t dstlen
21796+);
21797+#define SUBNETTOA_BUF 32 /* large enough for worst case result */
21798+
21799+/* ranges */
21800+const char * /* NULL for success, else string literal */
21801+atoasr(
21802+ const char *src,
21803+ size_t srclen, /* 0 means strlen(src) */
21804+ char *type, /* 'a', 's', 'r' */
21805+ struct in_addr *addrs /* two-element array */
21806+);
21807+size_t /* space needed for full conversion */
21808+rangetoa(
21809+ struct in_addr *addrs, /* two-element array */
21810+ int format, /* character; 0 means default */
21811+ char *dst,
21812+ size_t dstlen
21813+);
21814+#define RANGETOA_BUF 34 /* large enough for worst case result */
21815+
21816+/* data types for SA conversion functions */
21817+
21818+/* SAs */
21819+const char * /* NULL for success, else string literal */
21820+atosa(
21821+ const char *src,
21822+ size_t srclen, /* 0 means strlen(src) */
21823+ struct sa_id *sa
21824+);
21825+size_t /* space needed for full conversion */
21826+satoa(
21827+ struct sa_id sa,
21828+ int format, /* character; 0 means default */
21829+ char *dst,
21830+ size_t dstlen
21831+);
21832+#define SATOA_BUF (3+ULTOA_BUF+ADDRTOA_BUF)
21833+
21834+/* generic data, e.g. keys */
21835+const char * /* NULL for success, else string literal */
21836+atobytes(
21837+ const char *src,
21838+ size_t srclen, /* 0 means strlen(src) */
21839+ char *dst,
21840+ size_t dstlen,
21841+ size_t *lenp /* NULL means don't bother telling me */
21842+);
21843+size_t /* 0 failure, else true size */
21844+bytestoa(
21845+ const char *src,
21846+ size_t srclen,
21847+ int format, /* character; 0 means default */
21848+ char *dst,
21849+ size_t dstlen
21850+);
21851+
21852+/* old versions of generic-data functions; deprecated */
21853+size_t /* 0 failure, else true size */
21854+atodata(
21855+ const char *src,
21856+ size_t srclen, /* 0 means strlen(src) */
21857+ char *dst,
21858+ size_t dstlen
21859+);
21860+size_t /* 0 failure, else true size */
21861+datatoa(
21862+ const char *src,
21863+ size_t srclen,
21864+ int format, /* character; 0 means default */
21865+ char *dst,
21866+ size_t dstlen
21867+);
21868+
21869+/* part extraction and special addresses */
21870+struct in_addr
21871+subnetof(
21872+ struct in_addr addr,
21873+ struct in_addr mask
21874+);
21875+struct in_addr
21876+hostof(
21877+ struct in_addr addr,
21878+ struct in_addr mask
21879+);
21880+struct in_addr
21881+broadcastof(
21882+ struct in_addr addr,
21883+ struct in_addr mask
21884+);
21885+
21886+/* mask handling */
21887+int
21888+goodmask(
21889+ struct in_addr mask
21890+);
21891+int
21892+masktobits(
21893+ struct in_addr mask
21894+);
21895+struct in_addr
21896+bitstomask(
21897+ int n
21898+);
21899+
21900+
21901+
21902+/*
21903+ * general utilities
21904+ */
21905+
21906+#ifndef __KERNEL__
21907+/* option pickup from files (userland only because of use of FILE) */
21908+const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
21909+ int optind, FILE *errorreport);
21910+#endif
21911+
21912+
21913+
21914+#endif /* _FREESWAN_H */
21915diff -druN linux-noipsec/net/ipsec/libfreeswan/goodmask.c linux/net/ipsec/libfreeswan/goodmask.c
21916--- linux-noipsec/net/ipsec/libfreeswan/goodmask.c Thu Jan 1 01:00:00 1970
21917+++ linux/net/ipsec/libfreeswan/goodmask.c Wed Feb 16 19:54:24 2000
21918@@ -0,0 +1,97 @@
21919+/*
21920+ * minor utilities for subnet-mask manipulation
21921+ * Copyright (C) 1998, 1999 Henry Spencer.
21922+ *
21923+ * This library is free software; you can redistribute it and/or modify it
21924+ * under the terms of the GNU Library General Public License as published by
21925+ * the Free Software Foundation; either version 2 of the License, or (at your
21926+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
21927+ *
21928+ * This library is distributed in the hope that it will be useful, but
21929+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21930+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
21931+ * License for more details.
21932+ *
21933+ * RCSID $Id$
21934+ */
21935+#include "internal.h"
21936+#include "freeswan.h"
21937+
21938+/*
21939+ - goodmask - is this a good (^1*0*$) subnet mask?
21940+ * You are not expected to understand this. See Henry S. Warren Jr,
21941+ * "Functions realizable with word-parallel logical and two's-complement
21942+ * addition instructions", CACM 20.6 (June 1977), p.439.
21943+ */
21944+int /* predicate */
21945+goodmask(mask)
21946+struct in_addr mask;
21947+{
21948+ unsigned long x = ntohl(mask.s_addr);
21949+ /* clear rightmost contiguous string of 1-bits */
21950+# define CRCS1B(x) (((x|(x-1))+1)&x)
21951+# define TOPBIT (1UL << 31)
21952+
21953+ /* either zero, or has one string of 1-bits which is left-justified */
21954+ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
21955+ return 1;
21956+ return 0;
21957+}
21958+
21959+/*
21960+ - masktobits - how many bits in this mask?
21961+ * The algorithm is essentially a binary search, but highly optimized
21962+ * for this particular task.
21963+ */
21964+int /* -1 means !goodmask() */
21965+masktobits(mask)
21966+struct in_addr mask;
21967+{
21968+ unsigned long m = ntohl(mask.s_addr);
21969+ int masklen;
21970+
21971+ if (!goodmask(mask))
21972+ return -1;
21973+
21974+ if (m&0x00000001UL)
21975+ return 32;
21976+ masklen = 0;
21977+ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
21978+ masklen |= 0x10;
21979+ m <<= 16;
21980+ }
21981+ if (m&(0x00ff0000UL<<1)) {
21982+ masklen |= 0x08;
21983+ m <<= 8;
21984+ }
21985+ if (m&(0x0f000000UL<<1)) {
21986+ masklen |= 0x04;
21987+ m <<= 4;
21988+ }
21989+ if (m&(0x30000000UL<<1)) {
21990+ masklen |= 0x02;
21991+ m <<= 2;
21992+ }
21993+ if (m&(0x40000000UL<<1))
21994+ masklen |= 0x01;
21995+
21996+ return masklen;
21997+}
21998+
21999+/*
22000+ - bitstomask - return a mask with this many high bits on
22001+ */
22002+struct in_addr
22003+bitstomask(n)
22004+int n;
22005+{
22006+ struct in_addr result;
22007+
22008+ if (n > 0 && n <= ABITS)
22009+ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
22010+ else if (n == 0)
22011+ result.s_addr = 0;
22012+ else
22013+ result.s_addr = 0; /* best error report we can do */
22014+ return result;
22015+}
22016diff -druN linux-noipsec/net/ipsec/libfreeswan/initaddr.c linux/net/ipsec/libfreeswan/initaddr.c
22017--- linux-noipsec/net/ipsec/libfreeswan/initaddr.c Thu Jan 1 01:00:00 1970
22018+++ linux/net/ipsec/libfreeswan/initaddr.c Fri Aug 25 16:40:05 2000
22019@@ -0,0 +1,51 @@
22020+/*
22021+ * initialize address structure
22022+ * Copyright (C) 2000 Henry Spencer.
22023+ *
22024+ * This library is free software; you can redistribute it and/or modify it
22025+ * under the terms of the GNU Library General Public License as published by
22026+ * the Free Software Foundation; either version 2 of the License, or (at your
22027+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
22028+ *
22029+ * This library is distributed in the hope that it will be useful, but
22030+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22031+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
22032+ * License for more details.
22033+ *
22034+ * RCSID $Id$
22035+ */
22036+#include "internal.h"
22037+#include "freeswan.h"
22038+
22039+/*
22040+ - initaddr - initialize ip_address from bytes
22041+ */
22042+err_t /* NULL for success, else string literal */
22043+initaddr(src, srclen, af, dst)
22044+const unsigned char *src;
22045+size_t srclen;
22046+int af; /* address family */
22047+ip_address *dst;
22048+{
22049+ switch (af) {
22050+ case AF_INET:
22051+ if (srclen != 4)
22052+ return "IPv4 address must be exactly 4 bytes";
22053+ dst->u.v4.sin_family = af;
22054+ dst->u.v4.sin_port = 0; /* unused */
22055+ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
22056+ break;
22057+ case AF_INET6:
22058+ if (srclen != 16)
22059+ return "IPv6 address must be exactly 16 bytes";
22060+ dst->u.v6.sin6_family = af;
22061+ dst->u.v6.sin6_flowinfo = 0; /* unused */
22062+ dst->u.v6.sin6_port = 0; /* unused */
22063+ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
22064+ break;
22065+ default:
22066+ return "unknown address family in initaddr";
22067+ break;
22068+ }
22069+ return NULL;
22070+}
22071diff -druN linux-noipsec/net/ipsec/libfreeswan/initsaid.c linux/net/ipsec/libfreeswan/initsaid.c
22072--- linux-noipsec/net/ipsec/libfreeswan/initsaid.c Thu Jan 1 01:00:00 1970
22073+++ linux/net/ipsec/libfreeswan/initsaid.c Fri Sep 8 20:03:45 2000
22074@@ -0,0 +1,33 @@
22075+/*
22076+ * initialize SA ID structure
22077+ * Copyright (C) 2000 Henry Spencer.
22078+ *
22079+ * This library is free software; you can redistribute it and/or modify it
22080+ * under the terms of the GNU Library General Public License as published by
22081+ * the Free Software Foundation; either version 2 of the License, or (at your
22082+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
22083+ *
22084+ * This library is distributed in the hope that it will be useful, but
22085+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22086+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
22087+ * License for more details.
22088+ *
22089+ * RCSID $Id$
22090+ */
22091+#include "internal.h"
22092+#include "freeswan.h"
22093+
22094+/*
22095+ - initsaid - initialize SA ID from bits
22096+ */
22097+void
22098+initsaid(addr, spi, proto, dst)
22099+const ip_address *addr;
22100+ipsec_spi_t spi;
22101+int proto;
22102+ip_said *dst;
22103+{
22104+ dst->dst = *addr;
22105+ dst->spi = spi;
22106+ dst->proto = proto;
22107+}
22108diff -druN linux-noipsec/net/ipsec/libfreeswan/initsubnet.c linux/net/ipsec/libfreeswan/initsubnet.c
22109--- linux-noipsec/net/ipsec/libfreeswan/initsubnet.c Thu Jan 1 01:00:00 1970
22110+++ linux/net/ipsec/libfreeswan/initsubnet.c Fri Sep 8 20:03:45 2000
22111@@ -0,0 +1,77 @@
22112+/*
22113+ * initialize subnet structure
22114+ * Copyright (C) 2000 Henry Spencer.
22115+ *
22116+ * This library is free software; you can redistribute it and/or modify it
22117+ * under the terms of the GNU Library General Public License as published by
22118+ * the Free Software Foundation; either version 2 of the License, or (at your
22119+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
22120+ *
22121+ * This library is distributed in the hope that it will be useful, but
22122+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22123+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
22124+ * License for more details.
22125+ *
22126+ * RCSID $Id$
22127+ */
22128+#include "internal.h"
22129+#include "freeswan.h"
22130+
22131+/*
22132+ - initsubnet - initialize ip_subnet from address and count
22133+ *
22134+ * The only hard part is checking for host-part bits turned on.
22135+ */
22136+err_t /* NULL for success, else string literal */
22137+initsubnet(addr, count, clash, dst)
22138+const ip_address *addr;
22139+int count;
22140+int clash; /* '0' zero host-part bits, 'x' die on them */
22141+ip_subnet *dst;
22142+{
22143+ unsigned char *p;
22144+ int n;
22145+ int c;
22146+ unsigned m;
22147+ int die;
22148+
22149+ dst->addr = *addr;
22150+ n = addrbytesptr(&dst->addr, (const unsigned char **)&p);
22151+ if (n == 0)
22152+ return "unknown address family";
22153+
22154+ switch (clash) {
22155+ case '0':
22156+ die = 0;
22157+ break;
22158+ case 'x':
22159+ die = 1;
22160+ break;
22161+ default:
22162+ return "unknown clash-control value in initsubnet";
22163+ break;
22164+ }
22165+
22166+ c = count / 8;
22167+ if (c > n)
22168+ return "impossible mask count";
22169+ p += c;
22170+ n -= c;
22171+
22172+ m = 0xff;
22173+ c = count % 8;
22174+ if (n > 0 && c != 0) /* partial byte */
22175+ m >>= c;
22176+ for (; n > 0; n--) {
22177+ if ((*p & m) != 0) {
22178+ if (die)
22179+ return "improper subnet, host-part bits on";
22180+ *p &= ~m;
22181+ }
22182+ m = 0xff;
22183+ p++;
22184+ }
22185+
22186+ dst->maskbits = count;
22187+ return NULL;
22188+}
22189diff -druN linux-noipsec/net/ipsec/libfreeswan/internal.h linux/net/ipsec/libfreeswan/internal.h
22190--- linux-noipsec/net/ipsec/libfreeswan/internal.h Thu Jan 1 01:00:00 1970
22191+++ linux/net/ipsec/libfreeswan/internal.h Tue Aug 8 04:34:15 2000
22192@@ -0,0 +1,81 @@
22193+/*
22194+ * internal definitions for use within the library; do not export!
22195+ * Copyright (C) 1998, 1999 Henry Spencer.
22196+ *
22197+ * This library is free software; you can redistribute it and/or modify it
22198+ * under the terms of the GNU Library General Public License as published by
22199+ * the Free Software Foundation; either version 2 of the License, or (at your
22200+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
22201+ *
22202+ * This library is distributed in the hope that it will be useful, but
22203+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22204+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
22205+ * License for more details.
22206+ *
22207+ * RCSID $Id$
22208+ */
22209+
22210+#ifndef ABITS
22211+#define ABITS 32 /* bits in an IPv4 address */
22212+#endif
22213+
22214+/* case-independent ASCII character equality comparison */
22215+#define CIEQ(c1, c2) ( ((c1)&~040) == ((c2)&~040) )
22216+
22217+/* syntax for passthrough SA */
22218+#ifndef PASSTHROUGHNAME
22219+#define PASSTHROUGHNAME "%passthrough"
22220+#define PASSTHROUGH4NAME "%passthrough4"
22221+#define PASSTHROUGH6NAME "%passthrough6"
22222+#define PASSTHROUGHIS "tun0@0.0.0.0"
22223+#define PASSTHROUGH4IS "tun0@0.0.0.0"
22224+#define PASSTHROUGH6IS "tun0@::"
22225+#define PASSTHROUGHTYPE "tun"
22226+#define PASSTHROUGHSPI 0
22227+#define PASSTHROUGHDST 0
22228+#endif
22229+
22230+/*
22231+ * Headers, greatly complicated by stupid and unnecessary inconsistencies
22232+ * between the user environment and the kernel environment. These are done
22233+ * here so that this mess need exist in only one place.
22234+ *
22235+ * It may seem like a -I or two could avoid most of this, but on closer
22236+ * inspection it is not quite that easy.
22237+ */
22238+
22239+/* things that need to come from one place or the other, depending */
22240+#ifdef __KERNEL__
22241+#include <linux/types.h>
22242+#include <linux/socket.h>
22243+#include <linux/in.h>
22244+#include <linux/string.h>
22245+#include <linux/ctype.h>
22246+#define assert(foo) /* nothing */
22247+#else
22248+#include <sys/types.h>
22249+#include <netinet/in.h>
22250+#include <string.h>
22251+#include <ctype.h>
22252+#include <assert.h>
22253+#endif
22254+
22255+/* things that exist only in userland */
22256+#ifndef __KERNEL__
22257+
22258+/* You'd think this would be okay in the kernel too -- it's just a */
22259+/* bunch of constants -- but no, in RH5.1 it screws up other things. */
22260+/* (Credit: Mike Warfield tracked this problem down. Thanks Mike!) */
22261+/* Fortunately, we don't need it in the kernel subset of the library. */
22262+#include <limits.h>
22263+
22264+/* header files for things that should never be called in kernel */
22265+#include <netdb.h>
22266+
22267+/* memory allocation, currently user-only, macro-ized just in case */
22268+#include <stdlib.h>
22269+#define MALLOC(n) malloc(n)
22270+#define FREE(p) free(p)
22271+
22272+#endif /* __KERNEL__ */
22273+
22274diff -druN linux-noipsec/net/ipsec/libfreeswan/optionsfrom.c linux/net/ipsec/libfreeswan/optionsfrom.c
22275--- linux-noipsec/net/ipsec/libfreeswan/optionsfrom.c Thu Jan 1 01:00:00 1970
22276+++ linux/net/ipsec/libfreeswan/optionsfrom.c Sun Apr 11 01:24:21 1999
22277@@ -0,0 +1,301 @@
22278+/*
22279+ * pick up more options from a file, in the middle of an option scan
22280+ * Copyright (C) 1998, 1999 Henry Spencer.
22281+ *
22282+ * This library is free software; you can redistribute it and/or modify it
22283+ * under the terms of the GNU Library General Public License as published by
22284+ * the Free Software Foundation; either version 2 of the License, or (at your
22285+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
22286+ *
22287+ * This library is distributed in the hope that it will be useful, but
22288+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22289+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
22290+ * License for more details.
22291+ *
22292+ * RCSID $Id$
22293+ */
22294+#include "internal.h"
22295+#include "freeswan.h"
22296+
22297+#include <stdio.h>
22298+
22299+#define MAX 100 /* loop-detection limit */
22300+
22301+/* internal work area */
22302+struct work {
22303+# define LOTS 1024
22304+ char buf[LOTS];
22305+ char *line;
22306+ char *pending;
22307+};
22308+
22309+static const char *dowork(const char *, int *, char ***, int);
22310+static const char *getanarg(FILE *, struct work *, char **);
22311+static char *getline(FILE *, char *, size_t);
22312+
22313+/*
22314+ - optionsfrom - add some options, taken from a file, to argc/argv
22315+ * If errsto is non-NULL, does not return in event of error.
22316+ */
22317+const char * /* NULL for success, else string literal */
22318+optionsfrom(filename, argcp, argvp, optind, errsto)
22319+const char *filename;
22320+int *argcp; /* pointer to argc */
22321+char ***argvp; /* pointer to argv */
22322+int optind; /* current optind, number of next argument */
22323+FILE *errsto; /* where to report errors (NULL means return) */
22324+{
22325+ const char *e;
22326+ static int nuses = 0;
22327+
22328+ if (errsto != NULL) {
22329+ nuses++;
22330+ if (nuses >= MAX) {
22331+ fprintf(errsto,
22332+ "%s: optionsfrom called %d times, looping?\n",
22333+ (*argvp)[0], nuses);
22334+ exit(2);
22335+ }
22336+ } else
22337+ nuses = 0;
22338+
22339+ e = dowork(filename, argcp, argvp, optind);
22340+ if (e != NULL && errsto != NULL) {
22341+ fprintf(errsto, "%s: optionsfrom failed: %s\n", (*argvp)[0], e);
22342+ exit(2);
22343+ }
22344+ return e;
22345+}
22346+
22347+/*
22348+ - dowork - do all the real work of optionsfrom
22349+ * Does not alter the existing arguments, but does relocate and alter
22350+ * the argv pointer vector.
22351+ */
22352+static const char * /* NULL for success, else string literal */
22353+dowork(filename, argcp, argvp, optind)
22354+const char *filename;
22355+int *argcp; /* pointer to argc */
22356+char ***argvp; /* pointer to argv */
22357+int optind; /* current optind, number of next argument */
22358+{
22359+ char **newargv;
22360+ char **tmp;
22361+ int newargc;
22362+ int next; /* place for next argument */
22363+ int room; /* how many more new arguments we can hold */
22364+# define SOME 10 /* first guess at how many we'll need */
22365+ FILE *f;
22366+ int i;
22367+ const char *p;
22368+ struct work wa; /* for getanarg() */
22369+
22370+ f = fopen(filename, "r");
22371+ if (f == NULL)
22372+ return "unable to open file";
22373+
22374+ newargc = *argcp + SOME;
22375+ newargv = malloc((newargc+1) * sizeof(char *));
22376+ if (newargv == NULL)
22377+ return "unable to allocate memory";
22378+ memcpy(newargv, *argvp, optind * sizeof(char *));
22379+ room = SOME;
22380+ next = optind;
22381+
22382+ newargv[next] = NULL;
22383+ wa.pending = NULL;
22384+ while ((p = getanarg(f, &wa, &newargv[next])) == NULL) {
22385+ if (room == 0) {
22386+ newargc += SOME;
22387+ tmp = realloc(newargv, (newargc+1) * sizeof(char *));
22388+ if (tmp == NULL) {
22389+ p = "out of space for new argv";
22390+ break; /* NOTE BREAK OUT */
22391+ }
22392+ newargv = tmp;
22393+ room += SOME;
22394+ }
22395+ next++;
22396+ room--;
22397+ }
22398+ if (p != NULL && !feof(f)) { /* error of some kind */
22399+ for (i = optind+1; i <= next; i++)
22400+ if (newargv[i] != NULL)
22401+ free(newargv[i]);
22402+ free(newargv);
22403+ fclose(f);
22404+ return p;
22405+ }
22406+
22407+ fclose(f);
22408+ memcpy(newargv + next, *argvp + optind,
22409+ (*argcp+1-optind) * sizeof(char *));
22410+ *argcp += next - optind;
22411+ *argvp = newargv;
22412+ return NULL;
22413+}
22414+
22415+/*
22416+ - getanarg - get a malloced argument from the file
22417+ */
22418+static const char * /* NULL for success, else string literal */
22419+getanarg(f, w, linep)
22420+FILE *f;
22421+struct work *w;
22422+char **linep; /* where to store pointer if successful */
22423+{
22424+ size_t len;
22425+ char *p;
22426+ char *endp;
22427+
22428+ while (w->pending == NULL) { /* no pending line */
22429+ if ((w->line = getline(f, w->buf, sizeof(w->buf))) == NULL)
22430+ return "error in line read"; /* caller checks EOF */
22431+ if (w->line[0] != '#' &&
22432+ *(w->line + strspn(w->line, " \t")) != '\0')
22433+ w->pending = w->line;
22434+ }
22435+
22436+ if (w->pending == w->line && w->line[0] != '-') {
22437+ /* fresh plain line */
22438+ w->pending = NULL;
22439+ p = w->line;
22440+ endp = p + strlen(p);
22441+ if (*p == '"' && endp > p+1 && *(endp-1) == '"') {
22442+ p++;
22443+ endp--;
22444+ *endp = '\0';
22445+ }
22446+ if (w->line == w->buf) {
22447+ *linep = malloc(endp - p + 1);
22448+ if (*linep == NULL)
22449+ return "out of memory for new line";
22450+ strcpy(*linep, p);
22451+ } else /* getline already malloced it */
22452+ *linep = p;
22453+ return NULL;
22454+ }
22455+
22456+ /* chip off a piece of a pending line */
22457+ p = w->pending;
22458+ p += strspn(p, " \t");
22459+ endp = p + strcspn(p, " \t");
22460+ len = endp - p;
22461+ if (*endp != '\0') {
22462+ *endp++ = '\0';
22463+ endp += strspn(endp, " \t");
22464+ }
22465+ /* endp now points to next real character, or to line-end NUL */
22466+ *linep = malloc(len + 1);
22467+ if (*linep == NULL) {
22468+ if (w->line != w->buf)
22469+ free(w->line);
22470+ return "out of memory for new argument";
22471+ }
22472+ strcpy(*linep, p);
22473+ if (*endp == '\0') {
22474+ w->pending = NULL;
22475+ if (w->line != w->buf)
22476+ free(w->line);
22477+ } else
22478+ w->pending = endp;
22479+ return NULL;
22480+}
22481+
22482+/*
22483+ - getline - read a line from the file, trim newline off
22484+ */
22485+static char * /* pointer to line, NULL for eof/error */
22486+getline(f, buf, bufsize)
22487+FILE *f;
22488+char *buf; /* buffer to use, if convenient */
22489+size_t bufsize; /* size of buf */
22490+{
22491+ size_t len;
22492+
22493+ if (fgets(buf, bufsize, f) == NULL)
22494+ return NULL;
22495+ len = strlen(buf);
22496+
22497+ if (len < bufsize-1 || buf[bufsize-1] == '\n') {
22498+ /* it fit */
22499+ buf[len-1] = '\0';
22500+ return buf;
22501+ }
22502+
22503+ /* oh crud, buffer overflow */
22504+ /* for now, to hell with it */
22505+ return NULL;
22506+}
22507+
22508+
22509+
22510+#ifdef TEST
22511+
22512+#include <getopt.h>
22513+
22514+char usage[] = "Usage: tester [--foo] [--bar] [--optionsfrom file] arg ...";
22515+struct option opts[] = {
22516+ "foo", 0, NULL, 'f',
22517+ "bar", 0, NULL, 'b',
22518+ "builtin", 0, NULL, 'B',
22519+ "optionsfrom", 1, NULL, '+',
22520+ "help", 0, NULL, 'h',
22521+ "version", 0, NULL, 'v',
22522+ 0, 0, NULL, 0,
22523+};
22524+
22525+int
22526+main(argc, argv)
22527+int argc;
22528+char *argv[];
22529+{
22530+ int opt;
22531+ extern char *optarg;
22532+ extern int optind;
22533+ int errflg = 0;
22534+ const char *p;
22535+ int i;
22536+ FILE *errs = NULL;
22537+
22538+ while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
22539+ switch (opt) {
22540+ case 'f':
22541+ case 'b':
22542+ break;
22543+ case 'B':
22544+ errs = stderr;
22545+ break;
22546+ case '+': /* optionsfrom */
22547+ p = optionsfrom(optarg, &argc, &argv, optind, errs);
22548+ if (p != NULL) {
22549+ fprintf(stderr, "%s: optionsfrom error: %s\n",
22550+ argv[0], p);
22551+ exit(1);
22552+ }
22553+ break;
22554+ case 'h': /* help */
22555+ printf("%s\n", usage);
22556+ exit(0);
22557+ break;
22558+ case 'v': /* version */
22559+ printf("1\n");
22560+ exit(0);
22561+ break;
22562+ case '?':
22563+ default:
22564+ errflg = 1;
22565+ break;
22566+ }
22567+ if (errflg) {
22568+ fprintf(stderr, "%s\n", usage);
22569+ exit(2);
22570+ }
22571+
22572+ for (i = 1; i < argc; i++)
22573+ printf("%d: `%s'\n", i, argv[i]);
22574+ exit(0);
22575+}
22576+
22577+
22578+#endif /* TEST */
22579diff -druN linux-noipsec/net/ipsec/libfreeswan/pfkey.h linux/net/ipsec/libfreeswan/pfkey.h
22580--- linux-noipsec/net/ipsec/libfreeswan/pfkey.h Thu Jan 1 01:00:00 1970
22581+++ linux/net/ipsec/libfreeswan/pfkey.h Tue Oct 10 22:10:19 2000
22582@@ -0,0 +1,340 @@
22583+/*
22584+ * FreeS/WAN specific PF_KEY headers
22585+ * Copyright (C) 1999 Richard Guy Briggs.
22586+ *
22587+ * This program is free software; you can redistribute it and/or modify it
22588+ * under the terms of the GNU General Public License as published by the
22589+ * Free Software Foundation; either version 2 of the License, or (at your
22590+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
22591+ *
22592+ * This program is distributed in the hope that it will be useful, but
22593+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22594+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22595+ * for more details.
22596+ *
22597+ * RCSID $Id$
22598+ */
22599+
22600+#ifndef __NET_IPSEC_PF_KEY_H
22601+#define __NET_IPSEC_PF_KEY_H
22602+#ifdef __KERNEL__
22603+extern void pfkey_proto_init(struct net_proto *pro);
22604+extern struct proto_ops pfkey_proto_ops;
22605+typedef struct sock pfkey_sock;
22606+extern int debug_pfkey;
22607+
22608+extern /* void */ int pfkey_init(void);
22609+extern /* void */ int pfkey_cleanup(void);
22610+
22611+extern struct sock *pfkey_sock_list;
22612+struct socket_list
22613+{
22614+ struct socket *socketp;
22615+ struct socket_list *next;
22616+};
22617+extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
22618+extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
22619+extern struct socket_list *pfkey_open_sockets;
22620+extern struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
22621+
22622+struct supported
22623+{
22624+ uint16_t supported_alg_exttype;
22625+ uint8_t supported_alg_id;
22626+ uint8_t supported_alg_ivlen;
22627+ uint16_t supported_alg_minbits;
22628+ uint16_t supported_alg_maxbits;
22629+};
22630+
22631+extern struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
22632+struct supported_list
22633+{
22634+ struct supported *supportedp;
22635+ struct supported_list *next;
22636+};
22637+extern int pfkey_list_insert_supported(struct supported*, struct supported_list**);
22638+extern int pfkey_list_remove_supported(struct supported*, struct supported_list**);
22639+
22640+extern uint8_t sadb_satype2proto[];
22641+
22642+/*
22643+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
22644+ */
22645+struct sockaddr_key
22646+{
22647+ uint16_t key_family; /* PF_KEY */
22648+ uint16_t key_pad; /* not used */
22649+ uint32_t key_pid; /* process ID */
22650+};
22651+/*
22652+#endif */ /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
22653+ */
22654+
22655+struct pfkey_extracted_data
22656+{
22657+ struct tdb* tdb;
22658+ struct tdb* tdb2;
22659+ struct eroute *eroute;
22660+};
22661+
22662+extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
22663+extern int pfkey_expire(struct tdb *, int);
22664+extern int pfkey_acquire(struct tdb *);
22665+#endif /* __KERNEL__ */
22666+
22667+extern uint8_t satype2proto(uint8_t satype);
22668+extern uint8_t proto2satype(uint8_t proto);
22669+extern char* proto2name(uint8_t proto);
22670+
22671+struct key_opt
22672+{
22673+ uint32_t key_pid; /* process ID */
22674+ struct sock *sk;
22675+};
22676+
22677+#define key_pid(sk) ((struct key_opt*)&((sk)->protinfo))->key_pid
22678+
22679+#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
22680+#define BITS_PER_OCTET 8
22681+#define OCTETBITS 8
22682+#define PFKEYBITS 64
22683+#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
22684+#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
22685+
22686+#define PFKEYv2_MAX_MSGSIZE 4096
22687+
22688+/*
22689+ * PF_KEYv2 permitted and required extensions in and out bitmaps
22690+ */
22691+
22692+extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/];
22693+#define EXT_BITS_IN 0
22694+#define EXT_BITS_OUT 1
22695+#define EXT_BITS_PERM 0
22696+#define EXT_BITS_REQ 1
22697+
22698+extern void pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
22699+extern void pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
22700+extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
22701+
22702+extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
22703+ int (*ext_parsers[])(struct sadb_ext* ),
22704+ struct sadb_ext **extensions,
22705+ int dir);
22706+
22707+/*
22708+ * PF_KEYv2 build function prototypes
22709+ */
22710+
22711+int
22712+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
22713+ uint8_t msg_type,
22714+ uint8_t satype,
22715+ uint8_t msg_errno,
22716+ uint32_t seq,
22717+ uint32_t pid);
22718+
22719+int
22720+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
22721+ uint16_t exttype,
22722+ uint32_t spi, /* in network order */
22723+ uint8_t replay_window,
22724+ uint8_t sa_state,
22725+ uint8_t auth,
22726+ uint8_t encrypt,
22727+ uint32_t flags);
22728+
22729+int
22730+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
22731+ uint16_t exttype,
22732+ uint32_t allocations,
22733+ uint64_t bytes,
22734+ uint64_t addtime,
22735+ uint64_t usetime);
22736+
22737+int
22738+pfkey_address_build(struct sadb_ext** pfkey_ext,
22739+ uint16_t exttype,
22740+ uint8_t proto,
22741+ uint8_t prefixlen,
22742+ struct sockaddr* address);
22743+
22744+int
22745+pfkey_key_build(struct sadb_ext** pfkey_ext,
22746+ uint16_t exttype,
22747+ uint16_t key_bits,
22748+ char* key);
22749+
22750+int
22751+pfkey_ident_build(struct sadb_ext** pfkey_ext,
22752+ uint16_t exttype,
22753+ uint16_t ident_type,
22754+ uint64_t ident_id,
22755+ char* ident_string);
22756+
22757+int
22758+pfkey_sens_build(struct sadb_ext** pfkey_ext,
22759+ uint32_t dpd,
22760+ uint8_t sens_level,
22761+ uint8_t sens_len,
22762+ uint64_t* sens_bitmap,
22763+ uint8_t integ_level,
22764+ uint8_t integ_len,
22765+ uint64_t* integ_bitmap);
22766+
22767+int
22768+pfkey_prop_build(struct sadb_ext** pfkey_ext,
22769+ uint8_t replay,
22770+ unsigned int comb_num,
22771+ struct sadb_comb* comb);
22772+
22773+int
22774+pfkey_supported_build(struct sadb_ext** pfkey_ext,
22775+ uint16_t exttype,
22776+ unsigned int alg_num,
22777+ struct sadb_alg* alg);
22778+
22779+int
22780+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
22781+ uint16_t exttype,
22782+ uint32_t min,
22783+ uint32_t max);
22784+
22785+int
22786+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
22787+
22788+int
22789+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
22790+ uint8_t satype);
22791+
22792+int
22793+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
22794+ uint32_t tunnel,
22795+ uint32_t netlink,
22796+ uint32_t xform,
22797+ uint32_t eroute,
22798+ uint32_t spi,
22799+ uint32_t radij,
22800+ uint32_t esp,
22801+ uint32_t ah,
22802+ uint32_t rcv,
22803+ uint32_t pfkey,
22804+ uint32_t ipcomp,
22805+ uint32_t verbose);
22806+
22807+int
22808+pfkey_msg_build(struct sadb_msg** pfkey_msg,
22809+ struct sadb_ext* extensions[],
22810+ int dir);
22811+
22812+#endif /* __NET_IPSEC_PF_KEY_H */
22813+
22814+/*
22815+ * $Log$
22816+ * Revision 1.28 2000/10/10 20:10:19 rgb
22817+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
22818+ *
22819+ * Revision 1.27 2000/09/21 04:20:45 rgb
22820+ * Fixed array size off-by-one error. (Thanks Svenning!)
22821+ *
22822+ * Revision 1.26 2000/09/12 03:26:05 rgb
22823+ * Added pfkey_acquire prototype.
22824+ *
22825+ * Revision 1.25 2000/09/08 19:21:28 rgb
22826+ * Fix pfkey_prop_build() parameter to be only single indirection.
22827+ *
22828+ * Revision 1.24 2000/09/01 18:46:42 rgb
22829+ * Added a supported algorithms array lists, one per satype and registered
22830+ * existing algorithms.
22831+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
22832+ * list.
22833+ *
22834+ * Revision 1.23 2000/08/27 01:55:26 rgb
22835+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
22836+ *
22837+ * Revision 1.22 2000/08/20 21:39:23 rgb
22838+ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
22839+ * pfkey_expire().
22840+ *
22841+ * Revision 1.21 2000/08/15 17:29:23 rgb
22842+ * Fixes from SZI to untested pfkey_prop_build().
22843+ *
22844+ * Revision 1.20 2000/05/10 20:14:19 rgb
22845+ * Fleshed out sensitivity, proposal and supported extensions.
22846+ *
22847+ * Revision 1.19 2000/03/16 14:07:23 rgb
22848+ * Renamed ALIGN macro to avoid fighting with others in kernel.
22849+ *
22850+ * Revision 1.18 2000/01/22 23:24:06 rgb
22851+ * Added prototypes for proto2satype(), satype2proto() and proto2name().
22852+ *
22853+ * Revision 1.17 2000/01/21 06:26:59 rgb
22854+ * Converted from double tdb arguments to one structure (extr)
22855+ * containing pointers to all temporary information structures.
22856+ * Added klipsdebug switching capability.
22857+ * Dropped unused argument to pfkey_x_satype_build().
22858+ *
22859+ * Revision 1.16 1999/12/29 21:17:41 rgb
22860+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
22861+ * parameter for cleaner manipulation of extensions[] and to guard
22862+ * against potential memory leaks.
22863+ * Changed the I/F to pfkey_msg_free() for the same reason.
22864+ *
22865+ * Revision 1.15 1999/12/09 23:12:54 rgb
22866+ * Added macro for BITS_PER_OCTET.
22867+ * Added argument to pfkey_sa_build() to do eroutes.
22868+ *
22869+ * Revision 1.14 1999/12/08 20:33:25 rgb
22870+ * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
22871+ *
22872+ * Revision 1.13 1999/12/07 19:53:40 rgb
22873+ * Removed unused first argument from extension parsers.
22874+ * Changed __u* types to uint* to avoid use of asm/types.h and
22875+ * sys/types.h in userspace code.
22876+ * Added function prototypes for pfkey message and extensions
22877+ * initialisation and cleanup.
22878+ *
22879+ * Revision 1.12 1999/12/01 22:19:38 rgb
22880+ * Change pfkey_sa_build to accept an SPI in network byte order.
22881+ *
22882+ * Revision 1.11 1999/11/27 11:55:26 rgb
22883+ * Added extern sadb_satype2proto to enable moving protocol lookup table
22884+ * to lib/pfkey_v2_parse.c.
22885+ * Delete unused, moved typedefs.
22886+ * Add argument to pfkey_msg_parse() for direction.
22887+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
22888+ *
22889+ * Revision 1.10 1999/11/23 22:29:21 rgb
22890+ * This file has been moved in the distribution from klips/net/ipsec to
22891+ * lib.
22892+ * Add macros for dealing with alignment and rounding up more opaquely.
22893+ * The uint<n>_t type defines have been moved to freeswan.h to avoid
22894+ * chicken-and-egg problems.
22895+ * Add macros for dealing with alignment and rounding up more opaque.
22896+ * Added prototypes for using extention header bitmaps.
22897+ * Added prototypes of all the build functions.
22898+ *
22899+ * Revision 1.9 1999/11/20 21:59:48 rgb
22900+ * Moved socketlist type declarations and prototypes for shared use.
22901+ * Slightly modified scope of sockaddr_key declaration.
22902+ *
22903+ * Revision 1.8 1999/11/17 14:34:25 rgb
22904+ * Protect sa_family_t from being used in userspace with GLIBC<2.
22905+ *
22906+ * Revision 1.7 1999/10/27 19:40:35 rgb
22907+ * Add a maximum PFKEY packet size macro.
22908+ *
22909+ * Revision 1.6 1999/10/26 16:58:58 rgb
22910+ * Created a sockaddr_key and key_opt socket extension structures.
22911+ *
22912+ * Revision 1.5 1999/06/10 05:24:41 rgb
22913+ * Renamed variables to reduce confusion.
22914+ *
22915+ * Revision 1.4 1999/04/29 15:21:11 rgb
22916+ * Add pfkey support to debugging.
22917+ * Add return values to init and cleanup functions.
22918+ *
22919+ * Revision 1.3 1999/04/15 17:58:07 rgb
22920+ * Add RCSID labels.
22921+ *
22922+ */
22923diff -druN linux-noipsec/net/ipsec/libfreeswan/pfkey_v2_build.c linux/net/ipsec/libfreeswan/pfkey_v2_build.c
22924--- linux-noipsec/net/ipsec/libfreeswan/pfkey_v2_build.c Thu Jan 1 01:00:00 1970
22925+++ linux/net/ipsec/libfreeswan/pfkey_v2_build.c Fri Nov 17 19:10:30 2000
22926@@ -0,0 +1,1265 @@
22927+/*
22928+ * RFC2367 PF_KEYv2 Key management API message parser
22929+ * Copyright (C) 1999 Richard Guy Briggs.
22930+ *
22931+ * This program is free software; you can redistribute it and/or modify it
22932+ * under the terms of the GNU General Public License as published by the
22933+ * Free Software Foundation; either version 2 of the License, or (at your
22934+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
22935+ *
22936+ * This program is distributed in the hope that it will be useful, but
22937+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22938+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22939+ * for more details.
22940+ *
22941+ * RCSID $Id$
22942+ */
22943+
22944+/*
22945+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
22946+ */
22947+
22948+char pfkey_v2_build_c_version[] = "$Id$";
22949+
22950+/*
22951+ * Some ugly stuff to allow consistent debugging code for use in the
22952+ * kernel and in user space
22953+*/
22954+
22955+#ifdef __KERNEL__
22956+
22957+# include <linux/kernel.h> /* for printk */
22958+
22959+# include <linux/malloc.h> /* kmalloc() */
22960+# include <linux/errno.h> /* error codes */
22961+# include <linux/types.h> /* size_t */
22962+# include <linux/interrupt.h> /* mark_bh */
22963+
22964+# include <linux/netdevice.h> /* struct device, and other headers */
22965+# include <linux/etherdevice.h> /* eth_type_trans */
22966+# include <linux/ip.h> /* struct iphdr */
22967+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
22968+# include <linux/ipv6.h> /* struct ipv6hdr */
22969+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
22970+extern int debug_pfkey;
22971+
22972+# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
22973+# define FREE(obj) kfree(obj)
22974+#else /* __KERNEL__ */
22975+
22976+# include <sys/types.h>
22977+# include <linux/types.h>
22978+# include <linux/errno.h>
22979+# include <malloc.h>
22980+# include <string.h> /* memset */
22981+
22982+# include "../pluto/constants.h"
22983+# include "../pluto/defs.h" /* for PRINTF_LIKE */
22984+# include "../pluto/log.h" /* for debugging and DBG_log */
22985+
22986+extern unsigned int debugging; /* bits selecting what to report */
22987+unsigned int pfkey_lib_debug = 0;
22988+
22989+/* #define PLUTO */
22990+
22991+# ifdef PLUTO
22992+# define DEBUGGING(args...) { DBG_log("pfkey_lib_debug:" args); }
22993+# else
22994+# define DEBUGGING(args...) if(pfkey_lib_debug) { printf("pfkey_lib_debug:" args); } else { ; }
22995+# endif
22996+# define MALLOC(size) malloc(size)
22997+# define FREE(obj) free(obj)
22998+#endif /* __KERNEL__ */
22999+
23000+#include <freeswan.h>
23001+#include <pfkeyv2.h>
23002+#include <pfkey.h>
23003+
23004+#ifdef __KERNEL__
23005+# include "../radij.h" /* rd_nodes */
23006+# include "../ipsec_encap.h" /* sockaddr_encap */
23007+# include "../ipsec_netlink.h" /* KLIPS_PRINT */
23008+# define DEBUGGING(args...) \
23009+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
23010+/* ((debug_pfkey) ? printk(KERN_INFO "klips_debug:" format , ## args) : 0) */
23011+#endif /* __KERNEL__ */
23012+
23013+
23014+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
23015+
23016+void
23017+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
23018+{
23019+ int i;
23020+
23021+ for (i = 0; i != SADB_EXT_MAX + 1; i++) {
23022+ extensions[i] = NULL;
23023+ }
23024+}
23025+
23026+void
23027+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
23028+{
23029+ int i;
23030+
23031+ if(!extensions) {
23032+ return;
23033+ }
23034+
23035+ if(extensions[0]) {
23036+ memset(extensions[0], 0, sizeof(struct sadb_msg));
23037+ FREE(extensions[0]);
23038+ extensions[0] = NULL;
23039+ }
23040+
23041+ for (i = 1; i != SADB_EXT_MAX + 1; i++) {
23042+ if(extensions[i]) {
23043+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
23044+ FREE(extensions[i]);
23045+ extensions[i] = NULL;
23046+ }
23047+ }
23048+}
23049+
23050+void
23051+pfkey_msg_free(struct sadb_msg **pfkey_msg)
23052+{
23053+ if(*pfkey_msg) {
23054+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
23055+ FREE(*pfkey_msg);
23056+ *pfkey_msg = NULL;
23057+ }
23058+}
23059+
23060+/* Default extension builders taken from the KLIPS code */
23061+
23062+int
23063+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
23064+ uint8_t msg_type,
23065+ uint8_t satype,
23066+ uint8_t msg_errno,
23067+ uint32_t seq,
23068+ uint32_t pid)
23069+{
23070+ int error = 0;
23071+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
23072+
23073+ DEBUGGING(
23074+ "pfkey_msg_hdr_build:\n");
23075+ DEBUGGING(
23076+ "pfkey_msg_hdr_build: on_entry &pfkey_ext=%p pfkey_ext=%p *pfkey_ext=%p.\n",
23077+ &pfkey_ext,
23078+ pfkey_ext,
23079+ *pfkey_ext);
23080+ /* sanity checks... */
23081+ if(pfkey_msg) {
23082+ DEBUGGING(
23083+ "pfkey_msg_hdr_build:why is pfkey_msg already pointing to something?\n");
23084+ SENDERR(EINVAL);
23085+ }
23086+
23087+ if(!msg_type) {
23088+ DEBUGGING(
23089+ "pfkey_msg_hdr_build: msg type not set, must be non-zero..\n");
23090+ SENDERR(EINVAL);
23091+ }
23092+
23093+ if(msg_type > SADB_MAX) {
23094+ DEBUGGING(
23095+ "pfkey_msg_hdr_build: msg type too large:%d.\n",
23096+ msg_type);
23097+ SENDERR(EINVAL);
23098+ }
23099+
23100+ if(satype > SADB_SATYPE_MAX) {
23101+ DEBUGGING(
23102+ "pfkey_msg_hdr_build: satype %d > max %d\n",
23103+ satype, SADB_SATYPE_MAX);
23104+ SENDERR(EINVAL);
23105+ }
23106+
23107+ if(!(*pfkey_ext = (struct sadb_ext*)
23108+ pfkey_msg = (struct sadb_msg*)
23109+ MALLOC(sizeof(struct sadb_msg)))) {
23110+ DEBUGGING(
23111+ "pfkey_msg_hdr_build: memory allocation failed\n");
23112+ SENDERR(ENOMEM);
23113+ }
23114+ memset(pfkey_msg, 0, sizeof(struct sadb_msg));
23115+
23116+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
23117+
23118+ pfkey_msg->sadb_msg_type = msg_type;
23119+ pfkey_msg->sadb_msg_satype = satype;
23120+
23121+ pfkey_msg->sadb_msg_version = PF_KEY_V2;
23122+ pfkey_msg->sadb_msg_errno = msg_errno;
23123+ pfkey_msg->sadb_msg_reserved = 0;
23124+ pfkey_msg->sadb_msg_seq = seq;
23125+ pfkey_msg->sadb_msg_pid = pid;
23126+ DEBUGGING(
23127+ "pfkey_msg_hdr_build: on_exit &pfkey_ext=%p pfkey_ext=%p *pfkey_ext=%p.\n",
23128+ &pfkey_ext,
23129+ pfkey_ext,
23130+ *pfkey_ext);
23131+errlab:
23132+ return error;
23133+}
23134+
23135+int
23136+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
23137+ uint16_t exttype,
23138+ uint32_t spi, /* in network order */
23139+ uint8_t replay_window,
23140+ uint8_t sa_state,
23141+ uint8_t auth,
23142+ uint8_t encrypt,
23143+ uint32_t flags)
23144+{
23145+ int error = 0;
23146+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
23147+
23148+ DEBUGGING(
23149+ "pfkey_sa_build: spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
23150+ ntohl(spi), /* in network order */
23151+ replay_window,
23152+ sa_state,
23153+ auth,
23154+ encrypt,
23155+ flags);
23156+ /* sanity checks... */
23157+ if(pfkey_sa) {
23158+ DEBUGGING(
23159+ "pfkey_sa_build:why is pfkey_sa already pointing to something?\n");
23160+ SENDERR(EINVAL);
23161+ }
23162+
23163+ if(exttype != SADB_EXT_SA &&
23164+ exttype != SADB_X_EXT_SA2) {
23165+ DEBUGGING(
23166+ "pfkey_sa_build: invalid exttype=%d.\n",
23167+ exttype);
23168+ SENDERR(EINVAL);
23169+ }
23170+
23171+ if(replay_window > 64) {
23172+ DEBUGGING(
23173+ "pfkey_sa_build: replay window size: %d"
23174+ " -- must be 0 <= size <= 64\n",
23175+ replay_window);
23176+ SENDERR(EINVAL);
23177+ }
23178+
23179+ if(auth > SADB_AALG_MAX) {
23180+ DEBUGGING(
23181+ "pfkey_sa_build: auth=%d > SADB_AALG_MAX=%d.\n",
23182+ auth,
23183+ SADB_AALG_MAX);
23184+ SENDERR(EINVAL);
23185+ }
23186+
23187+ if(encrypt > SADB_EALG_MAX) {
23188+ DEBUGGING(
23189+ "pfkey_sa_build: encrypt=%d > SADB_EALG_MAX=%d.\n",
23190+ encrypt,
23191+ SADB_EALG_MAX);
23192+ SENDERR(EINVAL);
23193+ }
23194+
23195+ if(sa_state > SADB_SASTATE_MAX) {
23196+ DEBUGGING(
23197+ "pfkey_sa_build: sa_state=%d exceeds MAX=%d.\n",
23198+ sa_state,
23199+ SADB_SASTATE_MAX);
23200+ SENDERR(EINVAL);
23201+ }
23202+
23203+ if(sa_state == SADB_SASTATE_DEAD) {
23204+ DEBUGGING(
23205+ "pfkey_sa_build: sa_state=%d is DEAD=%d is not allowed.\n",
23206+ sa_state,
23207+ SADB_SASTATE_DEAD);
23208+ SENDERR(EINVAL);
23209+ }
23210+
23211+ if(!(*pfkey_ext = (struct sadb_ext*)
23212+ pfkey_sa = (struct sadb_sa*)
23213+ MALLOC(sizeof(struct sadb_sa)))) {
23214+ DEBUGGING(
23215+ "pfkey_sa_build: memory allocation failed\n");
23216+ SENDERR(ENOMEM);
23217+ }
23218+ memset(pfkey_sa, 0, sizeof(struct sadb_sa));
23219+
23220+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
23221+ pfkey_sa->sadb_sa_exttype = exttype;
23222+ pfkey_sa->sadb_sa_spi = spi;
23223+ pfkey_sa->sadb_sa_replay = replay_window;
23224+ pfkey_sa->sadb_sa_state = sa_state;
23225+ pfkey_sa->sadb_sa_auth = auth;
23226+ pfkey_sa->sadb_sa_encrypt = encrypt;
23227+ pfkey_sa->sadb_sa_flags = flags;
23228+
23229+errlab:
23230+ return error;
23231+}
23232+
23233+int
23234+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
23235+ uint16_t exttype,
23236+ uint32_t allocations,
23237+ uint64_t bytes,
23238+ uint64_t addtime,
23239+ uint64_t usetime)
23240+{
23241+ int error = 0;
23242+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
23243+
23244+ DEBUGGING(
23245+ "pfkey_lifetime_build:\n");
23246+ /* sanity checks... */
23247+ if(pfkey_lifetime) {
23248+ DEBUGGING(
23249+ "pfkey_lifetime_build:why is pfkey_lifetime already pointing to something?\n");
23250+ SENDERR(EINVAL);
23251+ }
23252+
23253+ if(exttype != SADB_EXT_LIFETIME_CURRENT &&
23254+ exttype != SADB_EXT_LIFETIME_HARD &&
23255+ exttype != SADB_EXT_LIFETIME_SOFT) {
23256+ DEBUGGING(
23257+ "pfkey_lifetime_build: invalid exttype=%d.\n",
23258+ exttype);
23259+ SENDERR(EINVAL);
23260+ }
23261+
23262+ if(!(*pfkey_ext = (struct sadb_ext*)
23263+ pfkey_lifetime = (struct sadb_lifetime*)
23264+ MALLOC(sizeof(struct sadb_lifetime)))) {
23265+ DEBUGGING(
23266+ "pfkey_lifetime_build: memory allocation failed\n");
23267+ SENDERR(ENOMEM);
23268+ }
23269+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
23270+
23271+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
23272+ pfkey_lifetime->sadb_lifetime_exttype = exttype;
23273+ pfkey_lifetime->sadb_lifetime_allocations = allocations;
23274+ pfkey_lifetime->sadb_lifetime_bytes = bytes;
23275+ pfkey_lifetime->sadb_lifetime_addtime = addtime;
23276+ pfkey_lifetime->sadb_lifetime_usetime = usetime;
23277+
23278+errlab:
23279+ return error;
23280+}
23281+
23282+int
23283+pfkey_address_build(struct sadb_ext** pfkey_ext,
23284+ uint16_t exttype,
23285+ uint8_t proto,
23286+ uint8_t prefixlen,
23287+ struct sockaddr* address)
23288+{
23289+ int error = 0;
23290+ int saddr_len = 0;
23291+ char ipaddr_txt[ADDRTOT_BUF];
23292+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
23293+
23294+ DEBUGGING(
23295+ "pfkey_address_build: exttype=%d proto=%d prefixlen=%d\n", exttype, proto, prefixlen);
23296+ /* sanity checks... */
23297+ if(pfkey_address) {
23298+ DEBUGGING(
23299+ "pfkey_address_build:why is pfkey_address already pointing to something?\n");
23300+ SENDERR(EINVAL);
23301+ }
23302+
23303+ if (!address) {
23304+ DEBUGGING("pfkey_address_build: address is NULL\n");
23305+ SENDERR(EINVAL);
23306+ }
23307+
23308+ switch(exttype) {
23309+ case SADB_EXT_ADDRESS_SRC:
23310+ case SADB_EXT_ADDRESS_DST:
23311+ case SADB_EXT_ADDRESS_PROXY:
23312+ case SADB_X_EXT_ADDRESS_DST2:
23313+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
23314+ case SADB_X_EXT_ADDRESS_DST_FLOW:
23315+ case SADB_X_EXT_ADDRESS_SRC_MASK:
23316+ case SADB_X_EXT_ADDRESS_DST_MASK:
23317+ break;
23318+ default:
23319+ DEBUGGING(
23320+ "pfkey_address_build: unrecognised ext_type=%d.\n",
23321+ exttype);
23322+ SENDERR(EINVAL);
23323+ }
23324+
23325+ switch(address->sa_family) {
23326+ case AF_INET:
23327+ DEBUGGING(
23328+ "pfkey_address_build: found address family AF_INET.\n");
23329+ saddr_len = sizeof(struct sockaddr_in);
23330+ sprintf(ipaddr_txt, "%d.%d.%d.%d"
23331+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
23332+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
23333+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
23334+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF);
23335+ break;
23336+ case AF_INET6:
23337+ DEBUGGING(
23338+ "pfkey_address_build: found address family AF_INET6.\n");
23339+ saddr_len = sizeof(struct sockaddr_in6);
23340+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
23341+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
23342+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
23343+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
23344+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
23345+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
23346+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
23347+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
23348+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7]));
23349+ break;
23350+ default:
23351+ DEBUGGING(
23352+ "pfkey_address_build: address->sa_family=%d not supported.\n",
23353+ address->sa_family);
23354+ SENDERR(EPFNOSUPPORT);
23355+ }
23356+
23357+ DEBUGGING(
23358+ "pfkey_address_build: found address=%s.\n",
23359+ ipaddr_txt);
23360+ if(prefixlen != 0) {
23361+ DEBUGGING(
23362+ "pfkey_address_build: address prefixes not supported yet.\n");
23363+ SENDERR(EAFNOSUPPORT); /* not supported yet */
23364+ }
23365+
23366+ if(!(*pfkey_ext = (struct sadb_ext*)
23367+ pfkey_address = (struct sadb_address*)
23368+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN) ))) {
23369+ DEBUGGING(
23370+ "pfkey_lifetime_build: memory allocation failed\n");
23371+ SENDERR(ENOMEM);
23372+ }
23373+ memset(pfkey_address,
23374+ 0,
23375+ ALIGN_N(sizeof(struct sadb_address) + saddr_len,
23376+ IPSEC_PFKEYv2_ALIGN));
23377+
23378+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
23379+ IPSEC_PFKEYv2_ALIGN);
23380+
23381+ pfkey_address->sadb_address_exttype = exttype;
23382+ pfkey_address->sadb_address_proto = proto;
23383+ pfkey_address->sadb_address_prefixlen = prefixlen;
23384+ pfkey_address->sadb_address_reserved = 0;
23385+
23386+ memcpy((char*)pfkey_address + sizeof(struct sadb_address),
23387+ address,
23388+ saddr_len);
23389+
23390+#if 0
23391+ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
23392+ pfkey_address_s_ska.sin_zero[i] = 0;
23393+ }
23394+#endif
23395+ DEBUGGING(
23396+ "pfkey_address_build: successful.\n");
23397+
23398+ errlab:
23399+ return error;
23400+}
23401+
23402+int
23403+pfkey_key_build(struct sadb_ext** pfkey_ext,
23404+ uint16_t exttype,
23405+ uint16_t key_bits,
23406+ char* key)
23407+{
23408+ int error = 0;
23409+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
23410+
23411+ DEBUGGING(
23412+ "pfkey_key_build:\n");
23413+ /* sanity checks... */
23414+ if(pfkey_key) {
23415+ DEBUGGING(
23416+ "pfkey_key_build:why is pfkey_key already pointing to something?\n");
23417+ SENDERR(EINVAL);
23418+ }
23419+
23420+ if(!key_bits) {
23421+ DEBUGGING(
23422+ "pfkey_key_build: key_bits is zero, it must be non-zero.\n");
23423+ SENDERR(EINVAL);
23424+ }
23425+
23426+ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
23427+ DEBUGGING(
23428+ "pfkey_key_build: unsupported extension type=%d.\n",
23429+ exttype);
23430+ SENDERR(EINVAL);
23431+ }
23432+
23433+ if(!(*pfkey_ext = (struct sadb_ext*)
23434+ pfkey_key = (struct sadb_key*)
23435+ MALLOC(sizeof(struct sadb_key) +
23436+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN))) {
23437+ DEBUGGING(
23438+ "pfkey_key_build: memory allocation failed\n");
23439+ SENDERR(ENOMEM);
23440+ }
23441+ memset(pfkey_key,
23442+ 0,
23443+ sizeof(struct sadb_key) +
23444+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
23445+
23446+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
23447+ 64);
23448+ pfkey_key->sadb_key_exttype = exttype;
23449+ pfkey_key->sadb_key_bits = key_bits;
23450+ pfkey_key->sadb_key_reserved = 0;
23451+ memcpy((char*)pfkey_key + sizeof(struct sadb_key),
23452+ key,
23453+ DIVUP(key_bits, 8));
23454+
23455+errlab:
23456+ return error;
23457+}
23458+
23459+int
23460+pfkey_ident_build(struct sadb_ext** pfkey_ext,
23461+ uint16_t exttype,
23462+ uint16_t ident_type,
23463+ uint64_t ident_id,
23464+ char* ident_string)
23465+{
23466+ int error = 0;
23467+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
23468+
23469+ DEBUGGING(
23470+ "pfkey_ident_build:\n");
23471+ /* sanity checks... */
23472+ if(pfkey_ident) {
23473+ DEBUGGING(
23474+ "pfkey_ident_build:why is pfkey_ident already pointing to something?\n");
23475+ SENDERR(EINVAL);
23476+ }
23477+
23478+ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
23479+ (exttype == SADB_EXT_IDENTITY_DST))) {
23480+ DEBUGGING(
23481+ "pfkey_ident_build: unsupported extension type=%d.\n",
23482+ exttype);
23483+ SENDERR(EINVAL);
23484+ }
23485+
23486+ if((ident_type == SADB_IDENTTYPE_RESERVED)) {
23487+ DEBUGGING(
23488+ "pfkey_ident_build: ident_type must be non-zero.\n");
23489+ SENDERR(EINVAL);
23490+ }
23491+
23492+ if(ident_type > SADB_IDENTTYPE_MAX) {
23493+ DEBUGGING(
23494+ "pfkey_ident_build: identtype=%d out of range.\n",
23495+ ident_type);
23496+ SENDERR(EINVAL);
23497+ }
23498+
23499+ if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
23500+ (ident_type == SADB_IDENTTYPE_FQDN)) &&
23501+ !ident_string) {
23502+ DEBUGGING(
23503+ "pfkey_ident_build: string required to allocate size of extension.\n");
23504+ SENDERR(EINVAL);
23505+ }
23506+
23507+#if 0
23508+ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
23509+ }
23510+#endif
23511+
23512+ if(!(*pfkey_ext = (struct sadb_ext*)
23513+ pfkey_ident = (struct sadb_ident*)
23514+ MALLOC(ALIGN_N(sizeof(struct sadb_key) + strlen(ident_string), IPSEC_PFKEYv2_ALIGN)))) {
23515+ DEBUGGING(
23516+ "pfkey_ident_build: memory allocation failed\n");
23517+ SENDERR(ENOMEM);
23518+ }
23519+ memset(pfkey_ident,
23520+ 0,
23521+ ALIGN_N(sizeof(struct sadb_ident) + strlen(ident_string),
23522+ IPSEC_PFKEYv2_ALIGN));
23523+
23524+ pfkey_ident->sadb_ident_len = DIVUP(sizeof(struct sadb_ident) + strlen(ident_string),
23525+ IPSEC_PFKEYv2_ALIGN);
23526+
23527+ pfkey_ident->sadb_ident_exttype = exttype;
23528+ pfkey_ident->sadb_ident_type = ident_type;
23529+ pfkey_ident->sadb_ident_reserved = 0;
23530+ pfkey_ident->sadb_ident_id = ident_id;
23531+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
23532+ ident_string,
23533+ strlen(ident_string));
23534+
23535+ /* string terminator/padding must be zero */
23536+ /* Which one is better, I don't know... */
23537+#if 0
23538+ for(i = strlen(ident_string);
23539+ i < ALIGN_N(sizeof(struct sadb_ident) + strlen(ident_string), IPSEC_PFKEYv2_ALIGN);
23540+ i++) {
23541+ ((char*)pfkey_ident)[i] = 0;
23542+ }
23543+#else
23544+ memset(((char*)pfkey_ident) + sizeof(struct sadb_ident) + strlen(ident_string),
23545+ 0,
23546+ ALIGN_N(sizeof(struct sadb_ident) + strlen(ident_string), IPSEC_PFKEYv2_ALIGN) -
23547+ sizeof(struct sadb_ident) + strlen(ident_string));
23548+#endif
23549+
23550+errlab:
23551+ return error;
23552+}
23553+
23554+int
23555+pfkey_sens_build(struct sadb_ext** pfkey_ext,
23556+ uint32_t dpd,
23557+ uint8_t sens_level,
23558+ uint8_t sens_len,
23559+ uint64_t* sens_bitmap,
23560+ uint8_t integ_level,
23561+ uint8_t integ_len,
23562+ uint64_t* integ_bitmap)
23563+{
23564+ int error = 0;
23565+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
23566+ int i;
23567+ uint64_t* bitmap;
23568+
23569+ DEBUGGING(
23570+ "pfkey_sens_build:\n");
23571+ /* sanity checks... */
23572+ if(pfkey_sens) {
23573+ DEBUGGING(
23574+ "pfkey_sens_build:why is pfkey_sens already pointing to something?\n");
23575+ SENDERR(EINVAL);
23576+ }
23577+
23578+ DEBUGGING(
23579+ "pfkey_sens_build: Sorry, I can't build exttype=%d yet.\n",
23580+ (*pfkey_ext)->sadb_ext_type);
23581+ SENDERR(EINVAL); /* don't process these yet */
23582+
23583+ if(!(*pfkey_ext = (struct sadb_ext*)
23584+ pfkey_sens = (struct sadb_sens*)
23585+ MALLOC(sizeof(struct sadb_sens) +
23586+ (sens_len + integ_len) * sizeof(uint64_t)))) {
23587+ DEBUGGING(
23588+ "pfkey_sens_build: memory allocation failed\n");
23589+ SENDERR(ENOMEM);
23590+ }
23591+ memset(pfkey_sens,
23592+ 0,
23593+ sizeof(struct sadb_sens) +
23594+ (sens_len + integ_len) * sizeof(uint64_t));
23595+
23596+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
23597+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
23598+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
23599+ pfkey_sens->sadb_sens_dpd = dpd;
23600+ pfkey_sens->sadb_sens_sens_level = sens_level;
23601+ pfkey_sens->sadb_sens_sens_len = sens_len;
23602+ pfkey_sens->sadb_sens_integ_level = integ_level;
23603+ pfkey_sens->sadb_sens_integ_len = integ_len;
23604+ pfkey_sens->sadb_sens_reserved = 0;
23605+
23606+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
23607+ for(i = 0; i < sens_len; i++) {
23608+ *bitmap = sens_bitmap[i];
23609+ bitmap++;
23610+ }
23611+ for(i = 0; i < integ_len; i++) {
23612+ *bitmap = integ_bitmap[i];
23613+ bitmap++;
23614+ }
23615+
23616+errlab:
23617+ return error;
23618+}
23619+
23620+int
23621+pfkey_prop_build(struct sadb_ext** pfkey_ext,
23622+ uint8_t replay,
23623+ unsigned int comb_num,
23624+ struct sadb_comb* comb)
23625+{
23626+ int error = 0;
23627+ int i;
23628+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
23629+ struct sadb_comb *combp;
23630+
23631+ DEBUGGING(
23632+ "pfkey_prop_build:\n");
23633+ /* sanity checks... */
23634+ if(pfkey_prop) {
23635+ DEBUGGING(
23636+ "pfkey_prop_build:why is pfkey_prop already pointing to something?\n");
23637+ SENDERR(EINVAL);
23638+ }
23639+
23640+ if(!(*pfkey_ext = (struct sadb_ext*)
23641+ pfkey_prop = (struct sadb_prop*)
23642+ MALLOC(sizeof(struct sadb_prop) +
23643+ comb_num * sizeof(struct sadb_comb)))) {
23644+ DEBUGGING(
23645+ "pfkey_prop_build: memory allocation failed\n");
23646+ SENDERR(ENOMEM);
23647+ }
23648+ memset(pfkey_prop,
23649+ 0,
23650+ sizeof(struct sadb_prop) +
23651+ comb_num * sizeof(struct sadb_comb));
23652+
23653+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
23654+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
23655+
23656+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
23657+ pfkey_prop->sadb_prop_replay = replay;
23658+
23659+ for(i=0; i<3; i++) {
23660+ pfkey_prop->sadb_prop_reserved[i] = 0;
23661+ }
23662+
23663+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
23664+ for(i = 0; i < comb_num; i++) {
23665+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
23666+ combp++;
23667+ }
23668+
23669+#if 0
23670+ uint8_t sadb_comb_auth;
23671+ uint8_t sadb_comb_encrypt;
23672+ uint16_t sadb_comb_flags;
23673+ uint16_t sadb_comb_auth_minbits;
23674+ uint16_t sadb_comb_auth_maxbits;
23675+ uint16_t sadb_comb_encrypt_minbits;
23676+ uint16_t sadb_comb_encrypt_maxbits;
23677+ uint32_t sadb_comb_reserved;
23678+ uint32_t sadb_comb_soft_allocations;
23679+ uint32_t sadb_comb_hard_allocations;
23680+ uint64_t sadb_comb_soft_bytes;
23681+ uint64_t sadb_comb_hard_bytes;
23682+ uint64_t sadb_comb_soft_addtime;
23683+ uint64_t sadb_comb_hard_addtime;
23684+ uint64_t sadb_comb_soft_usetime;
23685+ uint64_t sadb_comb_hard_usetime;
23686+#endif
23687+errlab:
23688+ return error;
23689+}
23690+
23691+int
23692+pfkey_supported_build(struct sadb_ext** pfkey_ext,
23693+ uint16_t exttype,
23694+ unsigned int alg_num,
23695+ struct sadb_alg* alg)
23696+{
23697+ int error = 0;
23698+ unsigned int i;
23699+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
23700+ struct sadb_alg *pfkey_alg;
23701+
23702+ /* sanity checks... */
23703+ if(pfkey_supported) {
23704+ DEBUGGING(
23705+ "pfkey_supported_build:why is pfkey_supported already pointing to something?\n");
23706+ SENDERR(EINVAL);
23707+ }
23708+
23709+ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
23710+ DEBUGGING(
23711+ "pfkey_supported_build: unsupported extension type=%d.\n",
23712+ exttype);
23713+ SENDERR(EINVAL);
23714+ }
23715+
23716+ if(!(*pfkey_ext = (struct sadb_ext*)
23717+ pfkey_supported = (struct sadb_supported*)
23718+ MALLOC(sizeof(struct sadb_supported) +
23719+ alg_num *
23720+ sizeof(struct sadb_alg)))) {
23721+ DEBUGGING(
23722+ "pfkey_supported_build: memory allocation failed\n");
23723+ SENDERR(ENOMEM);
23724+ }
23725+ memset(pfkey_supported,
23726+ 0,
23727+ sizeof(struct sadb_supported) +
23728+ alg_num *
23729+ sizeof(struct sadb_alg));
23730+
23731+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
23732+ alg_num *
23733+ sizeof(struct sadb_alg)) /
23734+ IPSEC_PFKEYv2_ALIGN;
23735+ pfkey_supported->sadb_supported_exttype = exttype;
23736+ pfkey_supported->sadb_supported_reserved = 0;
23737+
23738+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
23739+ for(i = 0; i < alg_num; i++) {
23740+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
23741+ pfkey_alg->sadb_alg_reserved = 0;
23742+ pfkey_alg++;
23743+ }
23744+
23745+#if 0
23746+ DEBUGGING(
23747+ "pfkey_supported_build: Sorry, I can't build exttype=%d yet.\n",
23748+ (*pfkey_ext)->sadb_ext_type);
23749+ SENDERR(EINVAL); /* don't process these yet */
23750+
23751+ uint8_t sadb_alg_id;
23752+ uint8_t sadb_alg_ivlen;
23753+ uint16_t sadb_alg_minbits;
23754+ uint16_t sadb_alg_maxbits;
23755+ uint16_t sadb_alg_reserved;
23756+#endif
23757+errlab:
23758+ return error;
23759+}
23760+
23761+int
23762+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
23763+ uint16_t exttype,
23764+ uint32_t min, /* in network order */
23765+ uint32_t max) /* in network order */
23766+{
23767+ int error = 0;
23768+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
23769+
23770+ /* sanity checks... */
23771+ if(pfkey_spirange) {
23772+ DEBUGGING(
23773+ "pfkey_spirange_build:why is pfkey_spirange already pointing to something?\n");
23774+ SENDERR(EINVAL);
23775+ }
23776+
23777+ if(ntohl(max) < ntohl(min)) {
23778+ DEBUGGING(
23779+ "pfkey_spirange_build: minspi=%08x must be < maxspi=%08x.\n",
23780+ ntohl(min),
23781+ ntohl(max));
23782+ SENDERR(EINVAL);
23783+ }
23784+
23785+ if(ntohl(min) <= 255) {
23786+ DEBUGGING(
23787+ "pfkey_spirange_build: minspi=%08x must be > 255.\n",
23788+ ntohl(min));
23789+ SENDERR(EEXIST);
23790+ }
23791+
23792+ if(!(*pfkey_ext = (struct sadb_ext*)
23793+ pfkey_spirange = (struct sadb_spirange*)
23794+ MALLOC(sizeof(struct sadb_spirange)))) {
23795+ DEBUGGING(
23796+ "pfkey_spirange_build: memory allocation failed\n");
23797+ SENDERR(ENOMEM);
23798+ }
23799+ memset(pfkey_spirange,
23800+ 0,
23801+ sizeof(struct sadb_spirange));
23802+
23803+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
23804+
23805+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
23806+ pfkey_spirange->sadb_spirange_min = min;
23807+ pfkey_spirange->sadb_spirange_max = max;
23808+ pfkey_spirange->sadb_spirange_reserved = 0;
23809+ errlab:
23810+ return error;
23811+}
23812+
23813+int
23814+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
23815+{
23816+ int error = 0;
23817+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
23818+
23819+ /* sanity checks... */
23820+ if(pfkey_x_kmprivate) {
23821+ DEBUGGING(
23822+ "pfkey_x_kmprivate_build:why is pfkey_x_kmprivate already pointing to something?\n");
23823+ SENDERR(EINVAL);
23824+ }
23825+
23826+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
23827+
23828+ DEBUGGING(
23829+ "pfkey_x_kmprivate_build: Sorry, I can't build exttype=%d yet.\n",
23830+ (*pfkey_ext)->sadb_ext_type);
23831+ SENDERR(EINVAL); /* don't process these yet */
23832+
23833+ if(!(*pfkey_ext = (struct sadb_ext*)
23834+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
23835+ MALLOC(sizeof(struct sadb_x_kmprivate)))) {
23836+ DEBUGGING(
23837+ "pfkey_x_kmprivate_build: memory allocation failed\n");
23838+ SENDERR(ENOMEM);
23839+ }
23840+ memset(pfkey_x_kmprivate,
23841+ 0,
23842+ sizeof(struct sadb_x_kmprivate));
23843+
23844+ pfkey_x_kmprivate->sadb_x_kmprivate_len =
23845+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
23846+
23847+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
23848+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
23849+errlab:
23850+ return error;
23851+}
23852+
23853+int
23854+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
23855+ uint8_t satype)
23856+{
23857+ int error = 0;
23858+ int i;
23859+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
23860+
23861+ DEBUGGING(
23862+ "pfkey_x_satype_build:\n");
23863+ /* sanity checks... */
23864+ if(pfkey_x_satype) {
23865+ DEBUGGING(
23866+ "pfkey_x_satype_build:why is pfkey_x_satype already pointing to something?\n");
23867+ SENDERR(EINVAL);
23868+ }
23869+
23870+ if(!satype) {
23871+ DEBUGGING(
23872+ "pfkey_x_satype_build: SA type not set, must be non-zero.\n");
23873+ SENDERR(EINVAL);
23874+ }
23875+
23876+ if(satype > SADB_SATYPE_MAX) {
23877+ DEBUGGING(
23878+ "pfkey_x_satype_build: satype %d > max %d\n",
23879+ satype, SADB_SATYPE_MAX);
23880+ SENDERR(EINVAL);
23881+ }
23882+
23883+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_satype = (struct sadb_x_satype*)
23884+ MALLOC(sizeof(struct sadb_x_satype)))) {
23885+ DEBUGGING(
23886+ "pfkey_x_satype_build: memory allocation failed\n");
23887+ SENDERR(ENOMEM);
23888+ }
23889+ memset(pfkey_x_satype,
23890+ 0,
23891+ sizeof(struct sadb_x_satype));
23892+
23893+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
23894+
23895+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
23896+ pfkey_x_satype->sadb_x_satype_satype = satype;
23897+ for(i=0; i<3; i++) {
23898+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
23899+ }
23900+
23901+errlab:
23902+ return error;
23903+}
23904+
23905+int
23906+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
23907+ uint32_t tunnel,
23908+ uint32_t netlink,
23909+ uint32_t xform,
23910+ uint32_t eroute,
23911+ uint32_t spi,
23912+ uint32_t radij,
23913+ uint32_t esp,
23914+ uint32_t ah,
23915+ uint32_t rcv,
23916+ uint32_t pfkey,
23917+ uint32_t ipcomp,
23918+ uint32_t verbose)
23919+{
23920+ int error = 0;
23921+ int i;
23922+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
23923+
23924+ DEBUGGING(
23925+ "pfkey_x_debug_build:\n");
23926+ /* sanity checks... */
23927+ if(pfkey_x_debug) {
23928+ DEBUGGING(
23929+ "pfkey_x_debug_build:why is pfkey_x_debug already pointing to something?\n");
23930+ SENDERR(EINVAL);
23931+ }
23932+
23933+ DEBUGGING(
23934+ "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",
23935+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
23936+
23937+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_debug = (struct sadb_x_debug*)
23938+ MALLOC(sizeof(struct sadb_x_debug)))) {
23939+ DEBUGGING(
23940+ "pfkey_x_debug_build: memory allocation failed\n");
23941+ SENDERR(ENOMEM);
23942+ }
23943+#if 0
23944+ memset(pfkey_x_debug,
23945+ 0,
23946+ sizeof(struct sadb_x_debug));
23947+#endif
23948+
23949+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
23950+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
23951+
23952+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
23953+ pfkey_x_debug->sadb_x_debug_netlink = netlink;
23954+ pfkey_x_debug->sadb_x_debug_xform = xform;
23955+ pfkey_x_debug->sadb_x_debug_eroute = eroute;
23956+ pfkey_x_debug->sadb_x_debug_spi = spi;
23957+ pfkey_x_debug->sadb_x_debug_radij = radij;
23958+ pfkey_x_debug->sadb_x_debug_esp = esp;
23959+ pfkey_x_debug->sadb_x_debug_ah = ah;
23960+ pfkey_x_debug->sadb_x_debug_rcv = rcv;
23961+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
23962+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
23963+ pfkey_x_debug->sadb_x_debug_verbose = verbose;
23964+
23965+ for(i=0; i<4; i++) {
23966+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
23967+ }
23968+
23969+errlab:
23970+ return error;
23971+}
23972+
23973+#if I_DONT_THINK_THIS_WILL_BE_USEFUL
23974+int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*)
23975+ =
23976+{
23977+ NULL, /* pfkey_msg_build, */
23978+ pfkey_sa_build,
23979+ pfkey_lifetime_build,
23980+ pfkey_lifetime_build,
23981+ pfkey_lifetime_build,
23982+ pfkey_address_build,
23983+ pfkey_address_build,
23984+ pfkey_address_build,
23985+ pfkey_key_build,
23986+ pfkey_key_build,
23987+ pfkey_ident_build,
23988+ pfkey_ident_build,
23989+ pfkey_sens_build,
23990+ pfkey_prop_build,
23991+ pfkey_supported_build,
23992+ pfkey_supported_build,
23993+ pfkey_spirange_build,
23994+ pfkey_x_kmprivate_build,
23995+ pfkey_x_satype_build,
23996+ pfkey_sa_build,
23997+ pfkey_address_build,
23998+ pfkey_address_build,
23999+ pfkey_address_build,
24000+ pfkey_address_build,
24001+ pfkey_address_build,
24002+ pfkey_x_ext_debug_build
24003+};
24004+#endif
24005+
24006+int
24007+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
24008+{
24009+ int error = 0;
24010+ int ext;
24011+ int total_size;
24012+ struct sadb_ext *pfkey_ext;
24013+ int extensions_seen = 0;
24014+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
24015+
24016+ if(!extensions[0]) {
24017+ DEBUGGING(
24018+ "pfkey_msg_build: extensions[0] must be specified (struct sadb_msg).\n");
24019+ SENDERR(EINVAL);
24020+ }
24021+
24022+ total_size = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
24023+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
24024+ if(extensions[ext]) {
24025+ total_size += (extensions[ext])->sadb_ext_len;
24026+ }
24027+ }
24028+
24029+ if(!(*pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN))) {
24030+ DEBUGGING(
24031+ "pfkey_msg_build: memory allocation failed\n");
24032+ SENDERR(ENOMEM);
24033+ }
24034+
24035+ DEBUGGING(
24036+ "pfkey_msg_build: pfkey_msg=%p allocated %d bytes, &(extensions[0])=%p\n",
24037+ *pfkey_msg,
24038+ total_size * IPSEC_PFKEYv2_ALIGN,
24039+ &(extensions[0]));
24040+ memcpy(*pfkey_msg,
24041+ extensions[0],
24042+ sizeof(struct sadb_msg));
24043+ (*pfkey_msg)->sadb_msg_len = total_size;
24044+ (*pfkey_msg)->sadb_msg_reserved = 0;
24045+ extensions_seen = 1 ;
24046+
24047+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
24048+
24049+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
24050+ /* copy from extension[ext] to buffer */
24051+ if(extensions[ext]) {
24052+ /* Is this type of extension permitted for this type of message? */
24053+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
24054+ 1<<ext)) {
24055+ DEBUGGING(
24056+ "pfkey_msg_build: "
24057+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
24058+ ext,
24059+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
24060+ 1<<ext);
24061+ SENDERR(EINVAL);
24062+ }
24063+ DEBUGGING(
24064+ "pfkey_msg_build: copying %d bytes from extensions[%d]=%p to=%p\n",
24065+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN,
24066+ ext,
24067+ (extensions[ext]),
24068+ pfkey_ext);
24069+ memcpy(pfkey_ext,
24070+ extensions[ext],
24071+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
24072+ ((char*)pfkey_ext) += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
24073+ /* Mark that we have seen this extension and remember the header location */
24074+ extensions_seen |= ( 1 << ext );
24075+ }
24076+ }
24077+
24078+ /* check required extensions */
24079+ DEBUGGING(
24080+ "pfkey_msg_build: extensions "
24081+ "permitted=%08x, seen=%08x, required=%08x.\n",
24082+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
24083+ extensions_seen,
24084+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
24085+
24086+ if((extensions_seen &
24087+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
24088+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
24089+ DEBUGGING(
24090+ "pfkey_msg_build: required extensions missing:%08x.\n",
24091+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
24092+ (extensions_seen &
24093+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
24094+ SENDERR(EINVAL);
24095+ }
24096+
24097+ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
24098+ DEBUGGING(
24099+ "pfkey_msg_build: Trouble parsing newly built pfkey message, error=%d.\n",
24100+ error);
24101+ SENDERR(-error);
24102+ }
24103+
24104+errlab:
24105+
24106+ return error;
24107+}
24108+
24109+/*
24110+ * $Log$
24111+ * Revision 1.21 2000/11/17 18:10:30 rgb
24112+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
24113+ * network byte order since this is the way PF_KEYv2 stored spis.
24114+ *
24115+ * Revision 1.20 2000/10/12 00:02:39 rgb
24116+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
24117+ *
24118+ * Revision 1.19 2000/10/10 20:10:20 rgb
24119+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
24120+ *
24121+ * Revision 1.18 2000/09/12 18:59:54 rgb
24122+ * Added Gerhard's IPv6 support to pfkey parts of libfreeswan.
24123+ *
24124+ * Revision 1.17 2000/09/12 03:27:00 rgb
24125+ * Moved DEBUGGING definition to compile kernel with debug off.
24126+ *
24127+ * Revision 1.16 2000/09/08 19:22:12 rgb
24128+ * Fixed pfkey_prop_build() parameter to be only single indirection.
24129+ * Fixed struct alg copy.
24130+ *
24131+ * Revision 1.15 2000/08/20 21:40:01 rgb
24132+ * Added an address parameter sanity check to pfkey_address_build().
24133+ *
24134+ * Revision 1.14 2000/08/15 17:29:23 rgb
24135+ * Fixes from SZI to untested pfkey_prop_build().
24136+ *
24137+ * Revision 1.13 2000/06/02 22:54:14 rgb
24138+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
24139+ *
24140+ * Revision 1.12 2000/05/10 19:24:01 rgb
24141+ * Fleshed out sensitivity, proposal and supported extensions.
24142+ *
24143+ * Revision 1.11 2000/03/16 14:07:23 rgb
24144+ * Renamed ALIGN macro to avoid fighting with others in kernel.
24145+ *
24146+ * Revision 1.10 2000/01/24 21:14:35 rgb
24147+ * Added disabled pluto pfkey lib debug flag.
24148+ *
24149+ * Revision 1.9 2000/01/21 06:27:32 rgb
24150+ * Added address cases for eroute flows.
24151+ * Removed unused code.
24152+ * Dropped unused argument to pfkey_x_satype_build().
24153+ * Indented compiler directives for readability.
24154+ * Added klipsdebug switching capability.
24155+ * Fixed SADB_EXT_MAX bug not permitting last extension access.
24156+ *
24157+ * Revision 1.8 1999/12/29 21:17:41 rgb
24158+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
24159+ * parameter for cleaner manipulation of extensions[] and to guard
24160+ * against potential memory leaks.
24161+ * Changed the I/F to pfkey_msg_free() for the same reason.
24162+ *
24163+ * Revision 1.7 1999/12/09 23:12:20 rgb
24164+ * Removed unused cruft.
24165+ * Added argument to pfkey_sa_build() to do eroutes.
24166+ * Fixed exttype check in as yet unused pfkey_lifetime_build().
24167+ *
24168+ * Revision 1.6 1999/12/07 19:54:29 rgb
24169+ * Removed static pluto debug flag.
24170+ * Added functions for pfkey message and extensions initialisation
24171+ * and cleanup.
24172+ *
24173+ * Revision 1.5 1999/12/01 22:20:06 rgb
24174+ * Changed pfkey_sa_build to accept an SPI in network byte order.
24175+ * Added <string.h> to quiet userspace compiler.
24176+ * Moved pfkey_lib_debug variable into the library.
24177+ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
24178+ * Added extension assembly debugging.
24179+ * Isolated assignment with brackets to be sure of scope.
24180+ *
24181+ * Revision 1.4 1999/11/27 11:57:35 rgb
24182+ * Added ipv6 headers.
24183+ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
24184+ * Debugging error messages added.
24185+ * Fixed missing auth and encrypt assignment bug.
24186+ * Add argument to pfkey_msg_parse() for direction.
24187+ * Move parse-after-build check inside pfkey_msg_build().
24188+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
24189+ * Add CVS log entry to bottom of file.
24190+ *
24191+ */
24192diff -druN linux-noipsec/net/ipsec/libfreeswan/pfkey_v2_ext_bits.c linux/net/ipsec/libfreeswan/pfkey_v2_ext_bits.c
24193--- linux-noipsec/net/ipsec/libfreeswan/pfkey_v2_ext_bits.c Thu Jan 1 01:00:00 1970
24194+++ linux/net/ipsec/libfreeswan/pfkey_v2_ext_bits.c Wed Sep 13 00:35:37 2000
24195@@ -0,0 +1,696 @@
24196+/*
24197+ * RFC2367 PF_KEYv2 Key management API message parser
24198+ * Copyright (C) 1999 Richard Guy Briggs.
24199+ *
24200+ * This program is free software; you can redistribute it and/or modify it
24201+ * under the terms of the GNU General Public License as published by the
24202+ * Free Software Foundation; either version 2 of the License, or (at your
24203+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
24204+ *
24205+ * This program is distributed in the hope that it will be useful, but
24206+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24207+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24208+ * for more details.
24209+ *
24210+ * RCSID $Id$
24211+ */
24212+
24213+/*
24214+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
24215+ */
24216+
24217+char pfkey_v2_ext_bits_c_version[] = "$Id$";
24218+
24219+/*
24220+ * Some ugly stuff to allow consistent debugging code for use in the
24221+ * kernel and in user space
24222+*/
24223+
24224+#ifdef __KERNEL__
24225+
24226+#include <linux/kernel.h> /* for printk */
24227+
24228+#include <linux/malloc.h> /* kmalloc() */
24229+#include <linux/errno.h> /* error codes */
24230+#include <linux/types.h> /* size_t */
24231+#include <linux/interrupt.h> /* mark_bh */
24232+
24233+#include <linux/netdevice.h> /* struct device, and other headers */
24234+#include <linux/etherdevice.h> /* eth_type_trans */
24235+#include <linux/ip.h> /* struct iphdr */
24236+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
24237+#include <linux/ipv6.h>
24238+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
24239+
24240+#else /* __KERNEL__ */
24241+
24242+#include <sys/types.h>
24243+#include <linux/types.h>
24244+#include <linux/errno.h>
24245+#endif
24246+
24247+#include <freeswan.h>
24248+#include <pfkeyv2.h>
24249+#include <pfkey.h>
24250+
24251+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = {
24252+
24253+/* INBOUND EXTENSIONS */
24254+{
24255+
24256+/* PERMITTED IN */
24257+{
24258+/* SADB_RESERVED */
24259+0
24260+,
24261+/* SADB_GETSPI */
24262+1<<SADB_EXT_RESERVED
24263+| 1<<SADB_EXT_ADDRESS_SRC
24264+| 1<<SADB_EXT_ADDRESS_DST
24265+| 1<<SADB_EXT_ADDRESS_PROXY
24266+| 1<<SADB_EXT_SPIRANGE
24267+,
24268+/* SADB_UPDATE */
24269+1<<SADB_EXT_RESERVED
24270+| 1<<SADB_EXT_SA
24271+| 1<<SADB_EXT_LIFETIME_CURRENT
24272+| 1<<SADB_EXT_LIFETIME_HARD
24273+| 1<<SADB_EXT_LIFETIME_SOFT
24274+| 1<<SADB_EXT_ADDRESS_SRC
24275+| 1<<SADB_EXT_ADDRESS_DST
24276+| 1<<SADB_EXT_ADDRESS_PROXY
24277+| 1<<SADB_EXT_KEY_AUTH
24278+| 1<<SADB_EXT_KEY_ENCRYPT
24279+| 1<<SADB_EXT_IDENTITY_SRC
24280+| 1<<SADB_EXT_IDENTITY_DST
24281+| 1<<SADB_EXT_SENSITIVITY
24282+,
24283+/* SADB_ADD */
24284+1<<SADB_EXT_RESERVED
24285+| 1<<SADB_EXT_SA
24286+| 1<<SADB_EXT_LIFETIME_HARD
24287+| 1<<SADB_EXT_LIFETIME_SOFT
24288+| 1<<SADB_EXT_ADDRESS_SRC
24289+| 1<<SADB_EXT_ADDRESS_DST
24290+| 1<<SADB_EXT_ADDRESS_PROXY
24291+| 1<<SADB_EXT_KEY_AUTH
24292+| 1<<SADB_EXT_KEY_ENCRYPT
24293+| 1<<SADB_EXT_IDENTITY_SRC
24294+| 1<<SADB_EXT_IDENTITY_DST
24295+| 1<<SADB_EXT_SENSITIVITY
24296+,
24297+/* SADB_DELETE */
24298+1<<SADB_EXT_RESERVED
24299+| 1<<SADB_EXT_SA
24300+| 1<<SADB_EXT_ADDRESS_SRC
24301+| 1<<SADB_EXT_ADDRESS_DST
24302+,
24303+/* SADB_GET */
24304+1<<SADB_EXT_RESERVED
24305+| 1<<SADB_EXT_SA
24306+| 1<<SADB_EXT_ADDRESS_SRC
24307+| 1<<SADB_EXT_ADDRESS_DST
24308+,
24309+/* SADB_ACQUIRE */
24310+1<<SADB_EXT_RESERVED
24311+| 1<<SADB_EXT_ADDRESS_SRC
24312+| 1<<SADB_EXT_ADDRESS_DST
24313+| 1<<SADB_EXT_ADDRESS_PROXY
24314+| 1<<SADB_EXT_IDENTITY_SRC
24315+| 1<<SADB_EXT_IDENTITY_DST
24316+| 1<<SADB_EXT_SENSITIVITY
24317+| 1<<SADB_EXT_PROPOSAL
24318+,
24319+/* SADB_REGISTER */
24320+1<<SADB_EXT_RESERVED
24321+,
24322+/* SADB_EXPIRE */
24323+0
24324+,
24325+/* SADB_FLUSH */
24326+1<<SADB_EXT_RESERVED
24327+,
24328+/* SADB_DUMP */
24329+1<<SADB_EXT_RESERVED
24330+,
24331+/* SADB_X_PROMISC */
24332+1<<SADB_EXT_RESERVED
24333+| 1<<SADB_EXT_SA
24334+| 1<<SADB_EXT_LIFETIME_CURRENT
24335+| 1<<SADB_EXT_LIFETIME_HARD
24336+| 1<<SADB_EXT_LIFETIME_SOFT
24337+| 1<<SADB_EXT_ADDRESS_SRC
24338+| 1<<SADB_EXT_ADDRESS_DST
24339+| 1<<SADB_EXT_ADDRESS_PROXY
24340+| 1<<SADB_EXT_KEY_AUTH
24341+| 1<<SADB_EXT_KEY_ENCRYPT
24342+| 1<<SADB_EXT_IDENTITY_SRC
24343+| 1<<SADB_EXT_IDENTITY_DST
24344+| 1<<SADB_EXT_SENSITIVITY
24345+| 1<<SADB_EXT_PROPOSAL
24346+| 1<<SADB_EXT_SUPPORTED_AUTH
24347+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
24348+| 1<<SADB_EXT_SPIRANGE
24349+| 1<<SADB_X_EXT_KMPRIVATE
24350+| 1<<SADB_X_EXT_SATYPE2
24351+| 1<<SADB_X_EXT_SA2
24352+| 1<<SADB_X_EXT_ADDRESS_DST2
24353+,
24354+/* SADB_X_PCHANGE */
24355+1<<SADB_EXT_RESERVED
24356+| 1<<SADB_EXT_SA
24357+| 1<<SADB_EXT_LIFETIME_CURRENT
24358+| 1<<SADB_EXT_LIFETIME_HARD
24359+| 1<<SADB_EXT_LIFETIME_SOFT
24360+| 1<<SADB_EXT_ADDRESS_SRC
24361+| 1<<SADB_EXT_ADDRESS_DST
24362+| 1<<SADB_EXT_ADDRESS_PROXY
24363+| 1<<SADB_EXT_KEY_AUTH
24364+| 1<<SADB_EXT_KEY_ENCRYPT
24365+| 1<<SADB_EXT_IDENTITY_SRC
24366+| 1<<SADB_EXT_IDENTITY_DST
24367+| 1<<SADB_EXT_SENSITIVITY
24368+| 1<<SADB_EXT_PROPOSAL
24369+| 1<<SADB_EXT_SUPPORTED_AUTH
24370+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
24371+| 1<<SADB_EXT_SPIRANGE
24372+| 1<<SADB_X_EXT_KMPRIVATE
24373+| 1<<SADB_X_EXT_SATYPE2
24374+| 1<<SADB_X_EXT_SA2
24375+| 1<<SADB_X_EXT_ADDRESS_DST2
24376+,
24377+/* SADB_X_GRPSA */
24378+1<<SADB_EXT_RESERVED
24379+| 1<<SADB_EXT_SA
24380+| 1<<SADB_EXT_ADDRESS_DST
24381+| 1<<SADB_X_EXT_SATYPE2
24382+| 1<<SADB_X_EXT_SA2
24383+| 1<<SADB_X_EXT_ADDRESS_DST2
24384+,
24385+/* SADB_X_ADDFLOW */
24386+1<<SADB_EXT_RESERVED
24387+| 1<<SADB_EXT_SA
24388+| 1<<SADB_EXT_ADDRESS_SRC
24389+| 1<<SADB_EXT_ADDRESS_DST
24390+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
24391+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
24392+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
24393+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
24394+,
24395+/* SADB_X_DELFLOW */
24396+1<<SADB_EXT_RESERVED
24397+| 1<<SADB_EXT_SA
24398+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
24399+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
24400+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
24401+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
24402+,
24403+/* SADB_X_DEBUG */
24404+1<<SADB_EXT_RESERVED
24405+| 1<<SADB_X_EXT_DEBUG
24406+},
24407+
24408+/* REQUIRED IN */
24409+{
24410+/* SADB_RESERVED */
24411+0
24412+,
24413+/* SADB_GETSPI */
24414+1<<SADB_EXT_RESERVED
24415+| 1<<SADB_EXT_ADDRESS_SRC
24416+| 1<<SADB_EXT_ADDRESS_DST
24417+| 1<<SADB_EXT_SPIRANGE
24418+,
24419+/* SADB_UPDATE */
24420+1<<SADB_EXT_RESERVED
24421+| 1<<SADB_EXT_SA
24422+| 1<<SADB_EXT_ADDRESS_SRC
24423+| 1<<SADB_EXT_ADDRESS_DST
24424+| 1<<SADB_EXT_KEY_AUTH
24425+| 1<<SADB_EXT_KEY_ENCRYPT
24426+,
24427+/* SADB_ADD */
24428+1<<SADB_EXT_RESERVED
24429+| 1<<SADB_EXT_SA
24430+| 1<<SADB_EXT_ADDRESS_SRC
24431+| 1<<SADB_EXT_ADDRESS_DST
24432+/*| 1<<SADB_EXT_KEY_AUTH*/
24433+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
24434+,
24435+/* SADB_DELETE */
24436+1<<SADB_EXT_RESERVED
24437+| 1<<SADB_EXT_SA
24438+| 1<<SADB_EXT_ADDRESS_SRC
24439+| 1<<SADB_EXT_ADDRESS_DST
24440+,
24441+/* SADB_GET */
24442+1<<SADB_EXT_RESERVED
24443+| 1<<SADB_EXT_SA
24444+| 1<<SADB_EXT_ADDRESS_SRC
24445+| 1<<SADB_EXT_ADDRESS_DST
24446+,
24447+/* SADB_ACQUIRE */
24448+1<<SADB_EXT_RESERVED
24449+| 1<<SADB_EXT_ADDRESS_SRC
24450+| 1<<SADB_EXT_ADDRESS_DST
24451+| 1<<SADB_EXT_PROPOSAL
24452+,
24453+/* SADB_REGISTER */
24454+1<<SADB_EXT_RESERVED
24455+,
24456+/* SADB_EXPIRE */
24457+0
24458+,
24459+/* SADB_FLUSH */
24460+1<<SADB_EXT_RESERVED
24461+,
24462+/* SADB_DUMP */
24463+1<<SADB_EXT_RESERVED
24464+,
24465+/* SADB_X_PROMISC */
24466+1<<SADB_EXT_RESERVED
24467+| 1<<SADB_EXT_SA
24468+| 1<<SADB_EXT_LIFETIME_CURRENT
24469+| 1<<SADB_EXT_LIFETIME_HARD
24470+| 1<<SADB_EXT_LIFETIME_SOFT
24471+| 1<<SADB_EXT_ADDRESS_SRC
24472+| 1<<SADB_EXT_ADDRESS_DST
24473+| 1<<SADB_EXT_ADDRESS_PROXY
24474+| 1<<SADB_EXT_KEY_AUTH
24475+| 1<<SADB_EXT_KEY_ENCRYPT
24476+| 1<<SADB_EXT_IDENTITY_SRC
24477+| 1<<SADB_EXT_IDENTITY_DST
24478+| 1<<SADB_EXT_SENSITIVITY
24479+| 1<<SADB_EXT_PROPOSAL
24480+| 1<<SADB_EXT_SUPPORTED_AUTH
24481+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
24482+| 1<<SADB_EXT_SPIRANGE
24483+| 1<<SADB_X_EXT_KMPRIVATE
24484+| 1<<SADB_X_EXT_SATYPE2
24485+| 1<<SADB_X_EXT_SA2
24486+| 1<<SADB_X_EXT_ADDRESS_DST2
24487+,
24488+/* SADB_X_PCHANGE */
24489+1<<SADB_EXT_RESERVED
24490+| 1<<SADB_EXT_SA
24491+| 1<<SADB_EXT_LIFETIME_CURRENT
24492+| 1<<SADB_EXT_LIFETIME_HARD
24493+| 1<<SADB_EXT_LIFETIME_SOFT
24494+| 1<<SADB_EXT_ADDRESS_SRC
24495+| 1<<SADB_EXT_ADDRESS_DST
24496+| 1<<SADB_EXT_ADDRESS_PROXY
24497+| 1<<SADB_EXT_KEY_AUTH
24498+| 1<<SADB_EXT_KEY_ENCRYPT
24499+| 1<<SADB_EXT_IDENTITY_SRC
24500+| 1<<SADB_EXT_IDENTITY_DST
24501+| 1<<SADB_EXT_SENSITIVITY
24502+| 1<<SADB_EXT_PROPOSAL
24503+| 1<<SADB_EXT_SUPPORTED_AUTH
24504+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
24505+| 1<<SADB_EXT_SPIRANGE
24506+| 1<<SADB_X_EXT_KMPRIVATE
24507+| 1<<SADB_X_EXT_SATYPE2
24508+| 1<<SADB_X_EXT_SA2
24509+| 1<<SADB_X_EXT_ADDRESS_DST2
24510+,
24511+/* SADB_X_GRPSA */
24512+1<<SADB_EXT_RESERVED
24513+| 1<<SADB_EXT_SA
24514+| 1<<SADB_EXT_ADDRESS_DST
24515+/*| 1<<SADB_X_EXT_SATYPE2*/
24516+/*| 1<<SADB_X_EXT_SA2*/
24517+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
24518+,
24519+/* SADB_X_ADDFLOW */
24520+1<<SADB_EXT_RESERVED
24521+| 1<<SADB_EXT_SA
24522+| 1<<SADB_EXT_ADDRESS_DST
24523+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
24524+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
24525+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
24526+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
24527+,
24528+/* SADB_X_DELFLOW */
24529+1<<SADB_EXT_RESERVED
24530+/*| 1<<SADB_EXT_SA*/
24531+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
24532+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
24533+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
24534+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
24535+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
24536+#endif
24537+,
24538+/* SADB_X_DEBUG */
24539+1<<SADB_EXT_RESERVED
24540+| 1<<SADB_X_EXT_DEBUG
24541+}
24542+
24543+},
24544+
24545+/* OUTBOUND EXTENSIONS */
24546+{
24547+
24548+/* PERMITTED OUT */
24549+{
24550+/* SADB_RESERVED */
24551+0
24552+,
24553+/* SADB_GETSPI */
24554+1<<SADB_EXT_RESERVED
24555+| 1<<SADB_EXT_SA
24556+| 1<<SADB_EXT_ADDRESS_SRC
24557+| 1<<SADB_EXT_ADDRESS_DST
24558+,
24559+/* SADB_UPDATE */
24560+1<<SADB_EXT_RESERVED
24561+| 1<<SADB_EXT_SA
24562+| 1<<SADB_EXT_LIFETIME_CURRENT
24563+| 1<<SADB_EXT_LIFETIME_HARD
24564+| 1<<SADB_EXT_LIFETIME_SOFT
24565+| 1<<SADB_EXT_ADDRESS_SRC
24566+| 1<<SADB_EXT_ADDRESS_DST
24567+| 1<<SADB_EXT_ADDRESS_PROXY
24568+| 1<<SADB_EXT_IDENTITY_SRC
24569+| 1<<SADB_EXT_IDENTITY_DST
24570+| 1<<SADB_EXT_SENSITIVITY
24571+,
24572+/* SADB_ADD */
24573+1<<SADB_EXT_RESERVED
24574+| 1<<SADB_EXT_SA
24575+| 1<<SADB_EXT_LIFETIME_HARD
24576+| 1<<SADB_EXT_LIFETIME_SOFT
24577+| 1<<SADB_EXT_ADDRESS_SRC
24578+| 1<<SADB_EXT_ADDRESS_DST
24579+| 1<<SADB_EXT_IDENTITY_SRC
24580+| 1<<SADB_EXT_IDENTITY_DST
24581+| 1<<SADB_EXT_SENSITIVITY
24582+,
24583+/* SADB_DELETE */
24584+1<<SADB_EXT_RESERVED
24585+| 1<<SADB_EXT_SA
24586+| 1<<SADB_EXT_ADDRESS_SRC
24587+| 1<<SADB_EXT_ADDRESS_DST
24588+,
24589+/* SADB_GET */
24590+1<<SADB_EXT_RESERVED
24591+| 1<<SADB_EXT_SA
24592+| 1<<SADB_EXT_LIFETIME_CURRENT
24593+| 1<<SADB_EXT_LIFETIME_HARD
24594+| 1<<SADB_EXT_LIFETIME_SOFT
24595+| 1<<SADB_EXT_ADDRESS_SRC
24596+| 1<<SADB_EXT_ADDRESS_DST
24597+| 1<<SADB_EXT_ADDRESS_PROXY
24598+| 1<<SADB_EXT_KEY_AUTH
24599+| 1<<SADB_EXT_KEY_ENCRYPT
24600+| 1<<SADB_EXT_IDENTITY_SRC
24601+| 1<<SADB_EXT_IDENTITY_DST
24602+| 1<<SADB_EXT_SENSITIVITY
24603+,
24604+/* SADB_ACQUIRE */
24605+1<<SADB_EXT_RESERVED
24606+| 1<<SADB_EXT_ADDRESS_SRC
24607+| 1<<SADB_EXT_ADDRESS_DST
24608+| 1<<SADB_EXT_ADDRESS_PROXY
24609+| 1<<SADB_EXT_IDENTITY_SRC
24610+| 1<<SADB_EXT_IDENTITY_DST
24611+| 1<<SADB_EXT_SENSITIVITY
24612+| 1<<SADB_EXT_PROPOSAL
24613+,
24614+/* SADB_REGISTER */
24615+1<<SADB_EXT_RESERVED
24616+| 1<<SADB_EXT_SUPPORTED_AUTH
24617+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
24618+,
24619+/* SADB_EXPIRE */
24620+1<<SADB_EXT_RESERVED
24621+| 1<<SADB_EXT_SA
24622+| 1<<SADB_EXT_LIFETIME_CURRENT
24623+| 1<<SADB_EXT_LIFETIME_HARD
24624+| 1<<SADB_EXT_LIFETIME_SOFT
24625+| 1<<SADB_EXT_ADDRESS_SRC
24626+| 1<<SADB_EXT_ADDRESS_DST
24627+,
24628+/* SADB_FLUSH */
24629+1<<SADB_EXT_RESERVED
24630+,
24631+/* SADB_DUMP */
24632+1<<SADB_EXT_RESERVED
24633+| 1<<SADB_EXT_SA
24634+| 1<<SADB_EXT_LIFETIME_CURRENT
24635+| 1<<SADB_EXT_LIFETIME_HARD
24636+| 1<<SADB_EXT_LIFETIME_SOFT
24637+| 1<<SADB_EXT_ADDRESS_SRC
24638+| 1<<SADB_EXT_ADDRESS_DST
24639+| 1<<SADB_EXT_ADDRESS_PROXY
24640+| 1<<SADB_EXT_KEY_AUTH
24641+| 1<<SADB_EXT_KEY_ENCRYPT
24642+| 1<<SADB_EXT_IDENTITY_SRC
24643+| 1<<SADB_EXT_IDENTITY_DST
24644+| 1<<SADB_EXT_SENSITIVITY
24645+,
24646+/* SADB_X_PROMISC */
24647+1<<SADB_EXT_RESERVED
24648+| 1<<SADB_EXT_SA
24649+| 1<<SADB_EXT_LIFETIME_CURRENT
24650+| 1<<SADB_EXT_LIFETIME_HARD
24651+| 1<<SADB_EXT_LIFETIME_SOFT
24652+| 1<<SADB_EXT_ADDRESS_SRC
24653+| 1<<SADB_EXT_ADDRESS_DST
24654+| 1<<SADB_EXT_ADDRESS_PROXY
24655+| 1<<SADB_EXT_KEY_AUTH
24656+| 1<<SADB_EXT_KEY_ENCRYPT
24657+| 1<<SADB_EXT_IDENTITY_SRC
24658+| 1<<SADB_EXT_IDENTITY_DST
24659+| 1<<SADB_EXT_SENSITIVITY
24660+| 1<<SADB_EXT_PROPOSAL
24661+| 1<<SADB_EXT_SUPPORTED_AUTH
24662+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
24663+| 1<<SADB_EXT_SPIRANGE
24664+| 1<<SADB_X_EXT_KMPRIVATE
24665+| 1<<SADB_X_EXT_SATYPE2
24666+| 1<<SADB_X_EXT_SA2
24667+| 1<<SADB_X_EXT_ADDRESS_DST2
24668+,
24669+/* SADB_X_PCHANGE */
24670+1<<SADB_EXT_RESERVED
24671+| 1<<SADB_EXT_SA
24672+| 1<<SADB_EXT_LIFETIME_CURRENT
24673+| 1<<SADB_EXT_LIFETIME_HARD
24674+| 1<<SADB_EXT_LIFETIME_SOFT
24675+| 1<<SADB_EXT_ADDRESS_SRC
24676+| 1<<SADB_EXT_ADDRESS_DST
24677+| 1<<SADB_EXT_ADDRESS_PROXY
24678+| 1<<SADB_EXT_KEY_AUTH
24679+| 1<<SADB_EXT_KEY_ENCRYPT
24680+| 1<<SADB_EXT_IDENTITY_SRC
24681+| 1<<SADB_EXT_IDENTITY_DST
24682+| 1<<SADB_EXT_SENSITIVITY
24683+| 1<<SADB_EXT_PROPOSAL
24684+| 1<<SADB_EXT_SUPPORTED_AUTH
24685+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
24686+| 1<<SADB_EXT_SPIRANGE
24687+| 1<<SADB_X_EXT_KMPRIVATE
24688+| 1<<SADB_X_EXT_SATYPE2
24689+| 1<<SADB_X_EXT_SA2
24690+| 1<<SADB_X_EXT_ADDRESS_DST2
24691+,
24692+/* SADB_X_GRPSA */
24693+1<<SADB_EXT_RESERVED
24694+| 1<<SADB_EXT_SA
24695+| 1<<SADB_EXT_ADDRESS_DST
24696+| 1<<SADB_X_EXT_SATYPE2
24697+| 1<<SADB_X_EXT_SA2
24698+| 1<<SADB_X_EXT_ADDRESS_DST2
24699+,
24700+/* SADB_X_ADDFLOW */
24701+1<<SADB_EXT_RESERVED
24702+| 1<<SADB_EXT_SA
24703+| 1<<SADB_EXT_ADDRESS_SRC
24704+| 1<<SADB_EXT_ADDRESS_DST
24705+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
24706+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
24707+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
24708+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
24709+,
24710+/* SADB_X_DELFLOW */
24711+1<<SADB_EXT_RESERVED
24712+| 1<<SADB_EXT_SA
24713+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
24714+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
24715+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
24716+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
24717+,
24718+/* SADB_X_DEBUG */
24719+1<<SADB_EXT_RESERVED
24720+| 1<<SADB_X_EXT_DEBUG
24721+},
24722+
24723+/* REQUIRED OUT */
24724+{
24725+/* SADB_RESERVED */
24726+0
24727+,
24728+/* SADB_GETSPI */
24729+1<<SADB_EXT_RESERVED
24730+| 1<<SADB_EXT_SA
24731+| 1<<SADB_EXT_ADDRESS_SRC
24732+| 1<<SADB_EXT_ADDRESS_DST
24733+,
24734+/* SADB_UPDATE */
24735+1<<SADB_EXT_RESERVED
24736+| 1<<SADB_EXT_SA
24737+| 1<<SADB_EXT_ADDRESS_SRC
24738+| 1<<SADB_EXT_ADDRESS_DST
24739+,
24740+/* SADB_ADD */
24741+1<<SADB_EXT_RESERVED
24742+| 1<<SADB_EXT_SA
24743+| 1<<SADB_EXT_ADDRESS_SRC
24744+| 1<<SADB_EXT_ADDRESS_DST
24745+,
24746+/* SADB_DELETE */
24747+1<<SADB_EXT_RESERVED
24748+| 1<<SADB_EXT_SA
24749+| 1<<SADB_EXT_ADDRESS_SRC
24750+| 1<<SADB_EXT_ADDRESS_DST
24751+,
24752+/* SADB_GET */
24753+1<<SADB_EXT_RESERVED
24754+| 1<<SADB_EXT_SA
24755+| 1<<SADB_EXT_ADDRESS_SRC
24756+| 1<<SADB_EXT_ADDRESS_DST
24757+| 1<<SADB_EXT_KEY_AUTH
24758+| 1<<SADB_EXT_KEY_ENCRYPT
24759+,
24760+/* SADB_ACQUIRE */
24761+1<<SADB_EXT_RESERVED
24762+| 1<<SADB_EXT_ADDRESS_SRC
24763+| 1<<SADB_EXT_ADDRESS_DST
24764+| 1<<SADB_EXT_PROPOSAL
24765+,
24766+/* SADB_REGISTER */
24767+1<<SADB_EXT_RESERVED
24768+/* | 1<<SADB_EXT_SUPPORTED_AUTH
24769+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
24770+,
24771+/* SADB_EXPIRE */
24772+1<<SADB_EXT_RESERVED
24773+| 1<<SADB_EXT_SA
24774+| 1<<SADB_EXT_LIFETIME_CURRENT
24775+/* | 1<<SADB_EXT_LIFETIME_HARD
24776+ | 1<<SADB_EXT_LIFETIME_SOFT */
24777+| 1<<SADB_EXT_ADDRESS_SRC
24778+| 1<<SADB_EXT_ADDRESS_DST
24779+,
24780+/* SADB_FLUSH */
24781+1<<SADB_EXT_RESERVED
24782+,
24783+/* SADB_DUMP */
24784+1<<SADB_EXT_RESERVED
24785+| 1<<SADB_EXT_SA
24786+| 1<<SADB_EXT_ADDRESS_SRC
24787+| 1<<SADB_EXT_ADDRESS_DST
24788+| 1<<SADB_EXT_KEY_AUTH
24789+| 1<<SADB_EXT_KEY_ENCRYPT
24790+,
24791+/* SADB_X_PROMISC */
24792+1<<SADB_EXT_RESERVED
24793+| 1<<SADB_EXT_SA
24794+| 1<<SADB_EXT_LIFETIME_CURRENT
24795+| 1<<SADB_EXT_LIFETIME_HARD
24796+| 1<<SADB_EXT_LIFETIME_SOFT
24797+| 1<<SADB_EXT_ADDRESS_SRC
24798+| 1<<SADB_EXT_ADDRESS_DST
24799+| 1<<SADB_EXT_ADDRESS_PROXY
24800+| 1<<SADB_EXT_KEY_AUTH
24801+| 1<<SADB_EXT_KEY_ENCRYPT
24802+| 1<<SADB_EXT_IDENTITY_SRC
24803+| 1<<SADB_EXT_IDENTITY_DST
24804+| 1<<SADB_EXT_SENSITIVITY
24805+| 1<<SADB_EXT_PROPOSAL
24806+| 1<<SADB_EXT_SUPPORTED_AUTH
24807+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
24808+| 1<<SADB_EXT_SPIRANGE
24809+| 1<<SADB_X_EXT_KMPRIVATE
24810+| 1<<SADB_X_EXT_SATYPE2
24811+| 1<<SADB_X_EXT_SA2
24812+| 1<<SADB_X_EXT_ADDRESS_DST2
24813+,
24814+/* SADB_X_PCHANGE */
24815+1<<SADB_EXT_RESERVED
24816+| 1<<SADB_EXT_SA
24817+| 1<<SADB_EXT_LIFETIME_CURRENT
24818+| 1<<SADB_EXT_LIFETIME_HARD
24819+| 1<<SADB_EXT_LIFETIME_SOFT
24820+| 1<<SADB_EXT_ADDRESS_SRC
24821+| 1<<SADB_EXT_ADDRESS_DST
24822+| 1<<SADB_EXT_ADDRESS_PROXY
24823+| 1<<SADB_EXT_KEY_AUTH
24824+| 1<<SADB_EXT_KEY_ENCRYPT
24825+| 1<<SADB_EXT_IDENTITY_SRC
24826+| 1<<SADB_EXT_IDENTITY_DST
24827+| 1<<SADB_EXT_SENSITIVITY
24828+| 1<<SADB_EXT_PROPOSAL
24829+| 1<<SADB_EXT_SUPPORTED_AUTH
24830+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
24831+| 1<<SADB_EXT_SPIRANGE
24832+| 1<<SADB_X_EXT_KMPRIVATE
24833+| 1<<SADB_X_EXT_SATYPE2
24834+| 1<<SADB_X_EXT_SA2
24835+| 1<<SADB_X_EXT_ADDRESS_DST2
24836+,
24837+/* SADB_X_GRPSA */
24838+1<<SADB_EXT_RESERVED
24839+| 1<<SADB_EXT_SA
24840+| 1<<SADB_EXT_ADDRESS_DST
24841+,
24842+/* SADB_X_ADDFLOW */
24843+1<<SADB_EXT_RESERVED
24844+| 1<<SADB_EXT_SA
24845+| 1<<SADB_EXT_ADDRESS_DST
24846+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
24847+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
24848+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
24849+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
24850+,
24851+/* SADB_X_DELFLOW */
24852+1<<SADB_EXT_RESERVED
24853+/*| 1<<SADB_EXT_SA*/
24854+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
24855+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
24856+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
24857+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
24858+,
24859+/* SADB_X_DEBUG */
24860+1<<SADB_EXT_RESERVED
24861+| 1<<SADB_X_EXT_DEBUG
24862+}
24863+}
24864+};
24865+
24866+/*
24867+ * $Log$
24868+ * Revision 1.7 2000/09/12 22:35:37 rgb
24869+ * Restructured to remove unused extensions from CLEARFLOW messages.
24870+ *
24871+ * Revision 1.6 2000/09/09 06:39:01 rgb
24872+ * Added comments for clarity.
24873+ *
24874+ * Revision 1.5 2000/06/02 22:54:14 rgb
24875+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
24876+ *
24877+ * Revision 1.4 2000/01/21 06:27:56 rgb
24878+ * Added address cases for eroute flows.
24879+ * Added comments for each message type.
24880+ * Added klipsdebug switching capability.
24881+ * Fixed GRPSA bitfields.
24882+ *
24883+ * Revision 1.3 1999/12/01 22:20:27 rgb
24884+ * Remove requirement for a proxy address in an incoming getspi message.
24885+ *
24886+ * Revision 1.2 1999/11/27 11:57:06 rgb
24887+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
24888+ * Add CVS log entry to bottom of file.
24889+ * Cleaned out unused bits.
24890+ *
24891+ */
24892diff -druN linux-noipsec/net/ipsec/libfreeswan/pfkey_v2_parse.c linux/net/ipsec/libfreeswan/pfkey_v2_parse.c
24893--- linux-noipsec/net/ipsec/libfreeswan/pfkey_v2_parse.c Thu Jan 1 01:00:00 1970
24894+++ linux/net/ipsec/libfreeswan/pfkey_v2_parse.c Fri Nov 17 19:10:30 2000
24895@@ -0,0 +1,1428 @@
24896+/*
24897+ * RFC2367 PF_KEYv2 Key management API message parser
24898+ * Copyright (C) 1999 Richard Guy Briggs.
24899+ *
24900+ * This program is free software; you can redistribute it and/or modify it
24901+ * under the terms of the GNU General Public License as published by the
24902+ * Free Software Foundation; either version 2 of the License, or (at your
24903+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
24904+ *
24905+ * This program is distributed in the hope that it will be useful, but
24906+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24907+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24908+ * for more details.
24909+ *
24910+ * RCSID $Id$
24911+ */
24912+
24913+/*
24914+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
24915+ */
24916+
24917+char pfkey_v2_parse_c_version[] = "$Id$";
24918+
24919+/*
24920+ * Some ugly stuff to allow consistent debugging code for use in the
24921+ * kernel and in user space
24922+*/
24923+
24924+#ifdef __KERNEL__
24925+
24926+# include <linux/kernel.h> /* for printk */
24927+
24928+# include <linux/malloc.h> /* kmalloc() */
24929+# include <linux/errno.h> /* error codes */
24930+# include <linux/types.h> /* size_t */
24931+# include <linux/interrupt.h> /* mark_bh */
24932+
24933+# include <linux/netdevice.h> /* struct device, and other headers */
24934+# include <linux/etherdevice.h> /* eth_type_trans */
24935+# include <linux/ip.h> /* struct iphdr */
24936+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
24937+# include <linux/ipv6.h> /* struct ipv6hdr */
24938+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
24939+extern int debug_pfkey;
24940+
24941+#else /* __KERNEL__ */
24942+
24943+# include <sys/types.h>
24944+# include <linux/types.h>
24945+# include <linux/errno.h>
24946+
24947+# include "../pluto/constants.h"
24948+# include "../pluto/defs.h" /* for PRINTF_LIKE */
24949+# include "../pluto/log.h" /* for debugging and DBG_log */
24950+
24951+extern unsigned int pfkey_lib_debug; /* bits selecting what to report */
24952+
24953+/* #define PLUTO */
24954+
24955+# ifdef PLUTO
24956+# define DEBUGGING(args...) { DBG_log("pfkey_lib_debug:" args); }
24957+# else
24958+# define DEBUGGING(args...) if(pfkey_lib_debug) { printf("pfkey_lib_debug:" args); } else { ; }
24959+# endif
24960+
24961+#endif /* __KERNEL__ */
24962+
24963+
24964+#include <freeswan.h>
24965+#include <pfkeyv2.h>
24966+#include <pfkey.h>
24967+
24968+#ifdef __KERNEL__
24969+# include "../radij.h" /* rd_nodes */
24970+# include "../ipsec_encap.h" /* sockaddr_encap */
24971+# include "../ipsec_netlink.h" /* KLIPS_PRINT */
24972+# define DEBUGGING(args...) \
24973+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
24974+/* ((debug_pfkey) ? printk(KERN_INFO "klips_debug:" format , ## args) : 0) */
24975+#endif /* __KERNEL__ */
24976+
24977+
24978+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
24979+
24980+struct satype_tbl {
24981+ uint8_t proto;
24982+ uint8_t satype;
24983+ char* name;
24984+} static satype_tbl[] = {
24985+#ifdef __KERNEL__
24986+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
24987+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
24988+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
24989+#ifdef CONFIG_IPSEC_IPCOMP
24990+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
24991+#endif /* CONFIG_IPSEC_IPCOMP */
24992+#else /* __KERNEL__ */
24993+ { SA_ESP, SADB_SATYPE_ESP, "ESP" },
24994+ { SA_AH, SADB_SATYPE_AH, "AH" },
24995+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
24996+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
24997+#endif /* __KERNEL__ */
24998+ { 0, 0 }
24999+};
25000+
25001+uint8_t satype2proto(uint8_t satype) {
25002+ int i =0;
25003+
25004+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
25005+ i++;
25006+ }
25007+ return satype_tbl[i].proto;
25008+}
25009+
25010+uint8_t proto2satype(uint8_t proto) {
25011+ int i = 0;
25012+
25013+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
25014+ i++;
25015+ }
25016+ return satype_tbl[i].satype;
25017+}
25018+
25019+char* proto2name(uint8_t proto) {
25020+ int i = 0;
25021+
25022+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
25023+ i++;
25024+ }
25025+ return satype_tbl[i].name;
25026+}
25027+
25028+uint8_t sadb_satype2proto[] = {
25029+#ifdef __KERNEL__
25030+ 0,
25031+ 0,
25032+ IPPROTO_AH,
25033+ IPPROTO_ESP,
25034+ 0,
25035+ 0,
25036+ 0,
25037+ 0,
25038+ 0,
25039+ IPPROTO_IPIP,
25040+ IPPROTO_COMP
25041+#else /* __KERNEL__ */
25042+ 0,
25043+ 0,
25044+ SA_AH,
25045+ SA_ESP,
25046+ 0,
25047+ 0,
25048+ 0,
25049+ 0,
25050+ 0,
25051+ SA_IPIP,
25052+ SA_COMP
25053+#endif /* __KERNEL__ */
25054+};
25055+
25056+/* Default extension parsers taken from the KLIPS code */
25057+
25058+DEBUG_NO_STATIC int
25059+pfkey_sa_parse(struct sadb_ext *pfkey_ext)
25060+{
25061+ int error = 0;
25062+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
25063+
25064+ DEBUGGING(
25065+ "pfkey_sa_parse:\n");
25066+ /* sanity checks... */
25067+ if(!pfkey_sa) {
25068+ DEBUGGING(
25069+ "pfkey_sa_parse: NULL pointer passed in.\n");
25070+ SENDERR(EINVAL);
25071+ }
25072+
25073+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
25074+ DEBUGGING(
25075+ "pfkey_sa_parse: length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
25076+ pfkey_sa->sadb_sa_len,
25077+ sizeof(struct sadb_sa));
25078+ SENDERR(EINVAL);
25079+ }
25080+
25081+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
25082+ DEBUGGING(
25083+ "pfkey_sa_parse: pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
25084+ pfkey_sa->sadb_sa_encrypt,
25085+ SADB_EALG_MAX);
25086+ SENDERR(EINVAL);
25087+ }
25088+
25089+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
25090+ DEBUGGING(
25091+ "pfkey_sa_parse: pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
25092+ pfkey_sa->sadb_sa_auth,
25093+ SADB_AALG_MAX);
25094+ SENDERR(EINVAL);
25095+ }
25096+
25097+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
25098+ DEBUGGING(
25099+ "pfkey_sa_parse: state=%d exceeds MAX=%d.\n",
25100+ pfkey_sa->sadb_sa_state,
25101+ SADB_SASTATE_MAX);
25102+ SENDERR(EINVAL);
25103+ }
25104+
25105+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
25106+ DEBUGGING(
25107+ "pfkey_sa_parse: state=%d is DEAD=%d.\n",
25108+ pfkey_sa->sadb_sa_state,
25109+ SADB_SASTATE_DEAD);
25110+ SENDERR(EINVAL);
25111+ }
25112+
25113+ if(pfkey_sa->sadb_sa_replay > 64) {
25114+ DEBUGGING(
25115+ "pfkey_sa_parse: replay window size: %d"
25116+ " -- must be 0 <= size <= 64\n",
25117+ pfkey_sa->sadb_sa_replay);
25118+ SENDERR(EINVAL);
25119+ }
25120+
25121+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
25122+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
25123+ {
25124+ DEBUGGING(
25125+ "pfkey_sa_parse: unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
25126+ pfkey_sa->sadb_sa_exttype,
25127+ SADB_EXT_SA,
25128+ SADB_X_EXT_SA2);
25129+ SENDERR(EINVAL);
25130+ }
25131+ DEBUGGING(
25132+ "pfkey_sa_parse: successfully found len=%d exttype=%d spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d.\n",
25133+ pfkey_sa->sadb_sa_len,
25134+ pfkey_sa->sadb_sa_exttype,
25135+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
25136+ pfkey_sa->sadb_sa_replay,
25137+ pfkey_sa->sadb_sa_state,
25138+ pfkey_sa->sadb_sa_auth,
25139+ pfkey_sa->sadb_sa_encrypt,
25140+ pfkey_sa->sadb_sa_flags);
25141+
25142+ errlab:
25143+ return error;
25144+}
25145+
25146+DEBUG_NO_STATIC int
25147+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
25148+{
25149+ int error = 0;
25150+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
25151+
25152+ DEBUGGING(
25153+ "pfkey_lifetime_parse:\n");
25154+ /* sanity checks... */
25155+ if(!pfkey_lifetime) {
25156+ DEBUGGING(
25157+ "pfkey_lifetime_parse: NULL pointer passed in.\n");
25158+ SENDERR(EINVAL);
25159+ }
25160+
25161+ if(pfkey_lifetime->sadb_lifetime_len !=
25162+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
25163+ DEBUGGING(
25164+ "pfkey_lifetime_parse: length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
25165+ pfkey_lifetime->sadb_lifetime_len,
25166+ sizeof(struct sadb_lifetime));
25167+ SENDERR(EINVAL);
25168+ }
25169+
25170+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
25171+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
25172+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
25173+ DEBUGGING(
25174+ "pfkey_lifetime_parse: unexpected ext_type=%d.\n",
25175+ pfkey_lifetime->sadb_lifetime_exttype);
25176+ SENDERR(EINVAL);
25177+ }
25178+
25179+errlab:
25180+ return error;
25181+}
25182+
25183+DEBUG_NO_STATIC int
25184+pfkey_address_parse(struct sadb_ext *pfkey_ext)
25185+{
25186+ int error = 0;
25187+ int saddr_len = 0;
25188+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
25189+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
25190+ char ipaddr_txt[ADDRTOT_BUF];
25191+
25192+ DEBUGGING(
25193+ "pfkey_address_parse:\n");
25194+ /* sanity checks... */
25195+ if(!pfkey_address) {
25196+ DEBUGGING(
25197+ "pfkey_address_parse: NULL pointer passed in.\n");
25198+ SENDERR(EINVAL);
25199+ }
25200+
25201+ if(pfkey_address->sadb_address_len <
25202+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
25203+ IPSEC_PFKEYv2_ALIGN) {
25204+ DEBUGGING(
25205+ "pfkey_address_parse: size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
25206+ pfkey_address->sadb_address_len,
25207+ sizeof(struct sadb_address),
25208+ sizeof(struct sockaddr));
25209+ SENDERR(EINVAL);
25210+ }
25211+
25212+ if(pfkey_address->sadb_address_reserved) {
25213+ DEBUGGING(
25214+ "pfkey_address_parse: res=%d, must be zero.\n",
25215+ pfkey_address->sadb_address_reserved);
25216+ SENDERR(EINVAL);
25217+ }
25218+
25219+ switch(pfkey_address->sadb_address_exttype) {
25220+ case SADB_EXT_ADDRESS_SRC:
25221+ case SADB_EXT_ADDRESS_DST:
25222+ case SADB_EXT_ADDRESS_PROXY:
25223+ case SADB_X_EXT_ADDRESS_DST2:
25224+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
25225+ case SADB_X_EXT_ADDRESS_DST_FLOW:
25226+ case SADB_X_EXT_ADDRESS_SRC_MASK:
25227+ case SADB_X_EXT_ADDRESS_DST_MASK:
25228+ break;
25229+ default:
25230+ DEBUGGING(
25231+ "pfkey_address_parse: unexpected ext_type=%d.\n",
25232+ pfkey_address->sadb_address_exttype);
25233+ SENDERR(EINVAL);
25234+ }
25235+
25236+ switch(s->sa_family) {
25237+ case AF_INET:
25238+ DEBUGGING(
25239+ "pfkey_address_parse: found address family=%d, AF_INET.\n",
25240+ s->sa_family);
25241+ saddr_len = sizeof(struct sockaddr_in);
25242+ sprintf(ipaddr_txt, "%d.%d.%d.%d"
25243+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
25244+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
25245+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
25246+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
25247+ DEBUGGING(
25248+ "pfkey_address_parse: found address=%s.\n",
25249+ ipaddr_txt);
25250+ break;
25251+ case AF_INET6:
25252+ DEBUGGING(
25253+ "pfkey_address_parse: found address family=%d, AF_INET6.\n",
25254+ s->sa_family);
25255+ saddr_len = sizeof(struct sockaddr_in6);
25256+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
25257+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
25258+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
25259+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
25260+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
25261+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
25262+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
25263+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
25264+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
25265+ DEBUGGING(
25266+ "pfkey_address_parse: found address=%s.\n",
25267+ ipaddr_txt);
25268+ break;
25269+ default:
25270+ DEBUGGING(
25271+ "pfkey_address_parse: s->sa_family=%d not supported.\n",
25272+ s->sa_family);
25273+ SENDERR(EPFNOSUPPORT);
25274+ }
25275+
25276+ if(pfkey_address->sadb_address_len !=
25277+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
25278+ DEBUGGING(
25279+ "pfkey_address_parse: size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
25280+ pfkey_address->sadb_address_len,
25281+ sizeof(struct sadb_address),
25282+ saddr_len);
25283+ SENDERR(EINVAL);
25284+ }
25285+
25286+ if(pfkey_address->sadb_address_prefixlen != 0) {
25287+ DEBUGGING(
25288+ "pfkey_address_parse: address prefixes not supported yet.\n");
25289+ SENDERR(EAFNOSUPPORT); /* not supported yet */
25290+ }
25291+
25292+ /* XXX check if port!=0 */
25293+
25294+ DEBUGGING(
25295+ "pfkey_address_parse: successful.\n");
25296+ errlab:
25297+ return error;
25298+}
25299+
25300+DEBUG_NO_STATIC int
25301+pfkey_key_parse(struct sadb_ext *pfkey_ext)
25302+{
25303+ int error = 0;
25304+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
25305+
25306+ DEBUGGING(
25307+ "pfkey_key_parse:\n");
25308+ /* sanity checks... */
25309+
25310+ if(!pfkey_key) {
25311+ DEBUGGING(
25312+ "pfkey_key_parse: NULL pointer passed in.\n");
25313+ SENDERR(EINVAL);
25314+ }
25315+
25316+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
25317+ DEBUGGING(
25318+ "pfkey_key_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
25319+ pfkey_key->sadb_key_len,
25320+ sizeof(struct sadb_key));
25321+ SENDERR(EINVAL);
25322+ }
25323+
25324+ if(!pfkey_key->sadb_key_bits) {
25325+ DEBUGGING(
25326+ "pfkey_key_parse: key length set to zero, must be non-zero.\n");
25327+ SENDERR(EINVAL);
25328+ }
25329+
25330+ if(pfkey_key->sadb_key_len !=
25331+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
25332+ PFKEYBITS)) {
25333+ DEBUGGING(
25334+ "pfkey_key_parse: key length=%d does not agree with extension length=%d.\n",
25335+ pfkey_key->sadb_key_bits,
25336+ pfkey_key->sadb_key_len);
25337+ SENDERR(EINVAL);
25338+ }
25339+
25340+ if(pfkey_key->sadb_key_reserved) {
25341+ DEBUGGING(
25342+ "pfkey_key_parse: res=%d, must be zero.\n",
25343+ pfkey_key->sadb_key_reserved);
25344+ SENDERR(EINVAL);
25345+ }
25346+
25347+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
25348+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
25349+ DEBUGGING(
25350+ "pfkey_key_parse: expecting extension type AUTH or ENCRYPT, got %d.\n",
25351+ pfkey_key->sadb_key_exttype);
25352+ SENDERR(EINVAL);
25353+ }
25354+
25355+ DEBUGGING(
25356+ "pfkey_key_parse: success, found len=%d exttype=%d bits=%d reserved=%d.\n",
25357+ pfkey_key->sadb_key_len,
25358+ pfkey_key->sadb_key_exttype,
25359+ pfkey_key->sadb_key_bits,
25360+ pfkey_key->sadb_key_reserved);
25361+
25362+errlab:
25363+ return error;
25364+}
25365+
25366+DEBUG_NO_STATIC int
25367+pfkey_ident_parse(struct sadb_ext *pfkey_ext)
25368+{
25369+ int error = 0;
25370+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
25371+
25372+ /* sanity checks... */
25373+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
25374+ DEBUGGING(
25375+ "pfkey_ident_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
25376+ pfkey_ident->sadb_ident_len,
25377+ sizeof(struct sadb_ident));
25378+ SENDERR(EINVAL);
25379+ }
25380+
25381+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
25382+ DEBUGGING(
25383+ "pfkey_ident_parse: ident_type=%d out of range, must be less than %d.\n",
25384+ pfkey_ident->sadb_ident_type,
25385+ SADB_IDENTTYPE_MAX);
25386+ SENDERR(EINVAL);
25387+ }
25388+
25389+ if(pfkey_ident->sadb_ident_reserved) {
25390+ DEBUGGING(
25391+ "pfkey_ident_parse: res=%d, must be zero.\n",
25392+ pfkey_ident->sadb_ident_reserved);
25393+ SENDERR(EINVAL);
25394+ }
25395+
25396+ /* string terminator/padding must be zero */
25397+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
25398+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
25399+ DEBUGGING(
25400+ "pfkey_ident_parse: string padding must be zero, last is 0x%02x.\n",
25401+ *((char*)pfkey_ident +
25402+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
25403+ SENDERR(EINVAL);
25404+ }
25405+ }
25406+
25407+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
25408+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
25409+ DEBUGGING(
25410+ "pfkey_key_parse: expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
25411+ pfkey_ident->sadb_ident_exttype);
25412+ SENDERR(EINVAL);
25413+ }
25414+
25415+errlab:
25416+ return error;
25417+}
25418+
25419+DEBUG_NO_STATIC int
25420+pfkey_sens_parse(struct sadb_ext *pfkey_ext)
25421+{
25422+ int error = 0;
25423+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
25424+
25425+ /* sanity checks... */
25426+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
25427+ DEBUGGING(
25428+ "pfkey_sens_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
25429+ pfkey_sens->sadb_sens_len,
25430+ sizeof(struct sadb_sens));
25431+ SENDERR(EINVAL);
25432+ }
25433+
25434+ DEBUGGING(
25435+ "pfkey_sens_parse: Sorry, I can't parse exttype=%d yet.\n",
25436+ pfkey_ext->sadb_ext_type);
25437+#if 0
25438+ SENDERR(EINVAL); /* don't process these yet */
25439+#endif
25440+
25441+errlab:
25442+ return error;
25443+}
25444+
25445+DEBUG_NO_STATIC int
25446+pfkey_prop_parse(struct sadb_ext *pfkey_ext)
25447+{
25448+ int error = 0;
25449+ int i, num_comb;
25450+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
25451+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
25452+
25453+ /* sanity checks... */
25454+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
25455+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
25456+ DEBUGGING(
25457+ "pfkey_prop_parse: size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
25458+ pfkey_prop->sadb_prop_len,
25459+ sizeof(struct sadb_prop),
25460+ sizeof(struct sadb_comb));
25461+ SENDERR(EINVAL);
25462+ }
25463+
25464+ if(pfkey_prop->sadb_prop_replay > 64) {
25465+ DEBUGGING(
25466+ "pfkey_prop_parse: replay window size: %d"
25467+ " -- must be 0 <= size <= 64\n",
25468+ pfkey_prop->sadb_prop_replay);
25469+ SENDERR(EINVAL);
25470+ }
25471+
25472+ for(i=0; i<3; i++) {
25473+ if(pfkey_prop->sadb_prop_reserved[i]) {
25474+ DEBUGGING(
25475+ "pfkey_prop_parse: res[%d]=%d, must be zero.\n",
25476+ i, pfkey_prop->sadb_prop_reserved[i]);
25477+ SENDERR(EINVAL);
25478+ }
25479+ }
25480+
25481+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
25482+
25483+ for(i = 0; i < num_comb; i++) {
25484+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
25485+ DEBUGGING(
25486+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
25487+ i,
25488+ pfkey_comb->sadb_comb_auth,
25489+ SADB_AALG_MAX);
25490+ SENDERR(EINVAL);
25491+ }
25492+
25493+ if(pfkey_comb->sadb_comb_auth) {
25494+ if(!pfkey_comb->sadb_comb_auth_minbits) {
25495+ DEBUGGING(
25496+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
25497+ i);
25498+ SENDERR(EINVAL);
25499+ }
25500+ if(!pfkey_comb->sadb_comb_auth_maxbits) {
25501+ DEBUGGING(
25502+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
25503+ i);
25504+ SENDERR(EINVAL);
25505+ }
25506+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
25507+ DEBUGGING(
25508+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
25509+ i,
25510+ pfkey_comb->sadb_comb_auth_minbits,
25511+ pfkey_comb->sadb_comb_auth_maxbits);
25512+ SENDERR(EINVAL);
25513+ }
25514+ } else {
25515+ if(pfkey_comb->sadb_comb_auth_minbits) {
25516+ DEBUGGING(
25517+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
25518+ i,
25519+ pfkey_comb->sadb_comb_auth_minbits);
25520+ SENDERR(EINVAL);
25521+ }
25522+ if(pfkey_comb->sadb_comb_auth_maxbits) {
25523+ DEBUGGING(
25524+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
25525+ i,
25526+ pfkey_comb->sadb_comb_auth_maxbits);
25527+ SENDERR(EINVAL);
25528+ }
25529+ }
25530+
25531+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
25532+ DEBUGGING(
25533+ "pfkey_comb_parse: pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
25534+ i,
25535+ pfkey_comb->sadb_comb_encrypt,
25536+ SADB_EALG_MAX);
25537+ SENDERR(EINVAL);
25538+ }
25539+
25540+ if(pfkey_comb->sadb_comb_encrypt) {
25541+ if(!pfkey_comb->sadb_comb_encrypt_minbits) {
25542+ DEBUGGING(
25543+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
25544+ i);
25545+ SENDERR(EINVAL);
25546+ }
25547+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
25548+ DEBUGGING(
25549+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
25550+ i);
25551+ SENDERR(EINVAL);
25552+ }
25553+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
25554+ DEBUGGING(
25555+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
25556+ i,
25557+ pfkey_comb->sadb_comb_encrypt_minbits,
25558+ pfkey_comb->sadb_comb_encrypt_maxbits);
25559+ SENDERR(EINVAL);
25560+ }
25561+ } else {
25562+ if(pfkey_comb->sadb_comb_encrypt_minbits) {
25563+ DEBUGGING(
25564+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
25565+ i,
25566+ pfkey_comb->sadb_comb_encrypt_minbits);
25567+ SENDERR(EINVAL);
25568+ }
25569+ if(pfkey_comb->sadb_comb_encrypt_maxbits) {
25570+ DEBUGGING(
25571+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
25572+ i,
25573+ pfkey_comb->sadb_comb_encrypt_maxbits);
25574+ SENDERR(EINVAL);
25575+ }
25576+ }
25577+
25578+ /* XXX do sanity check on flags */
25579+
25580+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
25581+ DEBUGGING(
25582+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
25583+ i,
25584+ pfkey_comb->sadb_comb_soft_allocations,
25585+ pfkey_comb->sadb_comb_hard_allocations);
25586+ SENDERR(EINVAL);
25587+ }
25588+
25589+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
25590+ DEBUGGING(
25591+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
25592+ i,
25593+ pfkey_comb->sadb_comb_soft_bytes,
25594+ pfkey_comb->sadb_comb_hard_bytes);
25595+ SENDERR(EINVAL);
25596+ }
25597+
25598+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
25599+ DEBUGGING(
25600+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
25601+ i,
25602+ pfkey_comb->sadb_comb_soft_addtime,
25603+ pfkey_comb->sadb_comb_hard_addtime);
25604+ SENDERR(EINVAL);
25605+ }
25606+
25607+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
25608+ DEBUGGING(
25609+ "pfkey_prop_parse: pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
25610+ i,
25611+ pfkey_comb->sadb_comb_soft_usetime,
25612+ pfkey_comb->sadb_comb_hard_usetime);
25613+ SENDERR(EINVAL);
25614+ }
25615+
25616+ if(pfkey_comb->sadb_comb_reserved) {
25617+ DEBUGGING(
25618+ "pfkey_prop_parse: comb[%d].res=%d, must be zero.\n",
25619+ i,
25620+ pfkey_comb->sadb_comb_reserved);
25621+ SENDERR(EINVAL);
25622+ }
25623+ pfkey_comb++;
25624+ }
25625+
25626+errlab:
25627+ return error;
25628+}
25629+
25630+DEBUG_NO_STATIC int
25631+pfkey_supported_parse(struct sadb_ext *pfkey_ext)
25632+{
25633+ int error = 0;
25634+ unsigned int i, num_alg;
25635+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
25636+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
25637+
25638+ /* sanity checks... */
25639+ if((pfkey_supported->sadb_supported_len <
25640+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
25641+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
25642+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
25643+
25644+ DEBUGGING(
25645+ "pfkey_supported_parse: size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
25646+ pfkey_supported->sadb_supported_len,
25647+ sizeof(struct sadb_supported),
25648+ sizeof(struct sadb_alg));
25649+ SENDERR(EINVAL);
25650+ }
25651+
25652+ if(pfkey_supported->sadb_supported_reserved) {
25653+ DEBUGGING(
25654+ "pfkey_supported_parse: res=%d, must be zero.\n",
25655+ pfkey_supported->sadb_supported_reserved);
25656+ SENDERR(EINVAL);
25657+ }
25658+
25659+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
25660+
25661+ for(i = 0; i < num_alg; i++) {
25662+ /* process algo description */
25663+ if(pfkey_alg->sadb_alg_reserved) {
25664+ DEBUGGING(
25665+ "pfkey_supported_parse: alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
25666+ i,
25667+ pfkey_alg->sadb_alg_id,
25668+ pfkey_alg->sadb_alg_ivlen,
25669+ pfkey_alg->sadb_alg_minbits,
25670+ pfkey_alg->sadb_alg_maxbits,
25671+ pfkey_alg->sadb_alg_reserved);
25672+ SENDERR(EINVAL);
25673+ }
25674+
25675+ /* XXX can alg_id auth/enc be determined from info given?
25676+ Yes, but OpenBSD's method does not iteroperate with rfc2367.
25677+ rgb, 2000-04-06 */
25678+
25679+ switch(pfkey_supported->sadb_supported_exttype) {
25680+ case SADB_EXT_SUPPORTED_AUTH:
25681+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
25682+ DEBUGGING(
25683+ "pfkey_supported_parse: alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
25684+ i,
25685+ pfkey_alg->sadb_alg_id,
25686+ SADB_AALG_MAX);
25687+ SENDERR(EINVAL);
25688+ }
25689+ break;
25690+ case SADB_EXT_SUPPORTED_ENCRYPT:
25691+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
25692+ DEBUGGING(
25693+ "pfkey_supported_parse: alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
25694+ i,
25695+ pfkey_alg->sadb_alg_id,
25696+ SADB_EALG_MAX);
25697+ SENDERR(EINVAL);
25698+ }
25699+ break;
25700+ default:
25701+ DEBUGGING(
25702+ "pfkey_supported_parse: alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
25703+ i,
25704+ pfkey_alg->sadb_alg_id,
25705+ SADB_EALG_MAX);
25706+ SENDERR(EINVAL);
25707+ }
25708+ pfkey_alg++;
25709+ }
25710+
25711+ errlab:
25712+ return error;
25713+}
25714+
25715+DEBUG_NO_STATIC int
25716+pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
25717+{
25718+ int error = 0;
25719+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
25720+
25721+ /* sanity checks... */
25722+ if(pfkey_spirange->sadb_spirange_len !=
25723+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
25724+ DEBUGGING(
25725+ "pfkey_spirange_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
25726+ pfkey_spirange->sadb_spirange_len,
25727+ sizeof(struct sadb_spirange));
25728+ SENDERR(EINVAL);
25729+ }
25730+
25731+ if(pfkey_spirange->sadb_spirange_reserved) {
25732+ DEBUGGING(
25733+ " pfkey_spirange_parse: reserved=%d must be set to zero.\n",
25734+ pfkey_spirange->sadb_spirange_reserved);
25735+ SENDERR(EINVAL);
25736+ }
25737+
25738+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
25739+ DEBUGGING(
25740+ " pfkey_spirange_parse: minspi=%08x must be < maxspi=%08x.\n",
25741+ ntohl(pfkey_spirange->sadb_spirange_min),
25742+ ntohl(pfkey_spirange->sadb_spirange_max));
25743+ SENDERR(EINVAL);
25744+ }
25745+
25746+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
25747+ DEBUGGING(
25748+ " pfkey_spirange_parse: minspi=%08x must be > 255.\n",
25749+ ntohl(pfkey_spirange->sadb_spirange_min));
25750+ SENDERR(EEXIST);
25751+ }
25752+
25753+ errlab:
25754+ return error;
25755+}
25756+
25757+DEBUG_NO_STATIC int
25758+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
25759+{
25760+ int error = 0;
25761+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
25762+
25763+ /* sanity checks... */
25764+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
25765+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
25766+ DEBUGGING(
25767+ "pfkey_x_kmprivate_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
25768+ pfkey_x_kmprivate->sadb_x_kmprivate_len,
25769+ sizeof(struct sadb_x_kmprivate));
25770+ SENDERR(EINVAL);
25771+ }
25772+
25773+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
25774+ DEBUGGING(
25775+ " pfkey_x_kmprivate_parse: reserved=%d must be set to zero.\n",
25776+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
25777+ SENDERR(EINVAL);
25778+ }
25779+
25780+ DEBUGGING(
25781+ "pfkey_x_kmprivate_parse: Sorry, I can't parse exttype=%d yet.\n",
25782+ pfkey_ext->sadb_ext_type);
25783+ SENDERR(EINVAL); /* don't process these yet */
25784+
25785+errlab:
25786+ return error;
25787+}
25788+
25789+DEBUG_NO_STATIC int
25790+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
25791+{
25792+ int error = 0;
25793+ int i;
25794+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
25795+
25796+ DEBUGGING(
25797+ "pfkey_x_satype_parse:\n");
25798+ /* sanity checks... */
25799+ if(pfkey_x_satype->sadb_x_satype_len !=
25800+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
25801+ DEBUGGING(
25802+ "pfkey_x_satype_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
25803+ pfkey_x_satype->sadb_x_satype_len,
25804+ sizeof(struct sadb_x_satype));
25805+ SENDERR(EINVAL);
25806+ }
25807+
25808+ if(!pfkey_x_satype->sadb_x_satype_satype) {
25809+ DEBUGGING(
25810+ "pfkey_x_satype_parse: satype is zero, must be non-zero.\n");
25811+ SENDERR(EINVAL);
25812+ }
25813+
25814+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
25815+ DEBUGGING(
25816+ "pfkey_x_satype_parse: satype %d > max %d\n",
25817+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
25818+ SENDERR(EINVAL);
25819+ }
25820+
25821+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
25822+ DEBUGGING(
25823+ "pfkey_x_satype_parse: proto lookup from satype=%d failed.\n",
25824+ pfkey_x_satype->sadb_x_satype_satype);
25825+ SENDERR(EINVAL);
25826+ }
25827+
25828+ for(i = 0; i < 3; i++) {
25829+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
25830+ DEBUGGING(
25831+ " pfkey_x_satype_parse: reserved[%d]=%d must be set to zero.\n",
25832+ i, pfkey_x_satype->sadb_x_satype_reserved[i]);
25833+ SENDERR(EINVAL);
25834+ }
25835+ }
25836+
25837+errlab:
25838+ return error;
25839+}
25840+
25841+DEBUG_NO_STATIC int
25842+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
25843+{
25844+ int error = 0;
25845+ int i;
25846+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
25847+
25848+ DEBUGGING(
25849+ "pfkey_x_debug_parse:\n");
25850+ /* sanity checks... */
25851+ if(pfkey_x_debug->sadb_x_debug_len !=
25852+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
25853+ DEBUGGING(
25854+ "pfkey_x_debug_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
25855+ pfkey_x_debug->sadb_x_debug_len,
25856+ sizeof(struct sadb_x_debug));
25857+ SENDERR(EINVAL);
25858+ }
25859+
25860+ for(i = 0; i < 4; i++) {
25861+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
25862+ DEBUGGING(
25863+ " pfkey_x_debug_parse: reserved[%d]=%d must be set to zero.\n",
25864+ i, pfkey_x_debug->sadb_x_debug_reserved[i]);
25865+ SENDERR(EINVAL);
25866+ }
25867+ }
25868+
25869+errlab:
25870+ return error;
25871+}
25872+
25873+int (*ext_default_parsers[SADB_EXT_MAX +1])(struct sadb_ext*) =
25874+{
25875+ NULL, /* pfkey_msg_parse, */
25876+ pfkey_sa_parse,
25877+ pfkey_lifetime_parse,
25878+ pfkey_lifetime_parse,
25879+ pfkey_lifetime_parse,
25880+ pfkey_address_parse,
25881+ pfkey_address_parse,
25882+ pfkey_address_parse,
25883+ pfkey_key_parse,
25884+ pfkey_key_parse,
25885+ pfkey_ident_parse,
25886+ pfkey_ident_parse,
25887+ pfkey_sens_parse,
25888+ pfkey_prop_parse,
25889+ pfkey_supported_parse,
25890+ pfkey_supported_parse,
25891+ pfkey_spirange_parse,
25892+ pfkey_x_kmprivate_parse,
25893+ pfkey_x_satype_parse,
25894+ pfkey_sa_parse,
25895+ pfkey_address_parse,
25896+ pfkey_address_parse,
25897+ pfkey_address_parse,
25898+ pfkey_address_parse,
25899+ pfkey_address_parse,
25900+ pfkey_x_ext_debug_parse
25901+};
25902+
25903+int
25904+pfkey_msg_parse(struct sadb_msg *pfkey_msg,
25905+ int (*ext_parsers[])(struct sadb_ext*),
25906+ struct sadb_ext *extensions[],
25907+ int dir)
25908+{
25909+ int error = 0;
25910+ int remain;
25911+ struct sadb_ext *pfkey_ext;
25912+ int extensions_seen = 0;
25913+
25914+ DEBUGGING(
25915+ "pfkey_msg_parse: parsing message "
25916+ "ver=%d, type=%d, errno=%d, satype=%d, len=%d, res=%d, seq=%d, pid=%d.\n",
25917+ pfkey_msg->sadb_msg_version,
25918+ pfkey_msg->sadb_msg_type,
25919+ pfkey_msg->sadb_msg_errno,
25920+ pfkey_msg->sadb_msg_satype,
25921+ pfkey_msg->sadb_msg_len,
25922+ pfkey_msg->sadb_msg_reserved,
25923+ pfkey_msg->sadb_msg_seq,
25924+ pfkey_msg->sadb_msg_pid);
25925+
25926+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
25927+
25928+ pfkey_extensions_init(extensions);
25929+
25930+ remain = pfkey_msg->sadb_msg_len;
25931+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
25932+
25933+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
25934+ sizeof(struct sadb_msg));
25935+
25936+ extensions[0] = (struct sadb_ext *) pfkey_msg;
25937+
25938+
25939+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
25940+ DEBUGGING(
25941+ "pfkey_msg_parse: "
25942+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
25943+ pfkey_msg->sadb_msg_version,
25944+ PF_KEY_V2);
25945+ SENDERR(EINVAL);
25946+ }
25947+
25948+ if(!pfkey_msg->sadb_msg_type) {
25949+ DEBUGGING(
25950+ "pfkey_msg_parse: msg type not set, must be non-zero..\n");
25951+ SENDERR(EINVAL);
25952+ }
25953+
25954+ if(pfkey_msg->sadb_msg_type > SADB_MAX) {
25955+ DEBUGGING(
25956+ "pfkey_msg_parse: msg type=%d > max=%d.\n",
25957+ pfkey_msg->sadb_msg_type,
25958+ SADB_MAX);
25959+ SENDERR(EINVAL);
25960+ }
25961+
25962+ switch(pfkey_msg->sadb_msg_type) {
25963+ case SADB_GETSPI:
25964+ case SADB_UPDATE:
25965+ case SADB_ADD:
25966+ case SADB_DELETE:
25967+ case SADB_GET:
25968+ case SADB_ACQUIRE:
25969+ case SADB_REGISTER:
25970+ case SADB_EXPIRE:
25971+#if 0
25972+ case SADB_X_PROMISC:
25973+ case SADB_X_PCHANGE:
25974+#endif
25975+ case SADB_X_GRPSA:
25976+ if(!pfkey_msg->sadb_msg_satype) {
25977+ DEBUGGING(
25978+ "pfkey_msg_parse: satype is zero, must be non-zero for msg_type %d.\n", pfkey_msg->sadb_msg_type);
25979+ SENDERR(EINVAL);
25980+ }
25981+ switch(pfkey_msg->sadb_msg_satype) {
25982+ case SADB_SATYPE_ESP:
25983+ case SADB_SATYPE_AH:
25984+ case SADB_X_SATYPE_IPIP:
25985+ case SADB_X_SATYPE_COMP:
25986+ break;
25987+ default:
25988+ DEBUGGING(
25989+ "pfkey_msg_parse: "
25990+ "satype=%d is not supported yet.\n",
25991+ pfkey_msg->sadb_msg_satype);
25992+ SENDERR(EINVAL);
25993+ }
25994+ break;
25995+ default:
25996+ }
25997+
25998+ /* errno must not be set in downward messages */
25999+ /* this is not entirely true... a response to an ACQUIRE could return an error */
26000+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
26001+ DEBUGGING(
26002+ "pfkey_msg_parse: "
26003+ "errno set to %d.\n",
26004+ pfkey_msg->sadb_msg_errno);
26005+ SENDERR(EINVAL);
26006+ }
26007+
26008+ DEBUGGING(
26009+ "pfkey_msg_parse: remain=%d, ext_type=%d, ext_len=%d.\n",
26010+ remain, pfkey_ext->sadb_ext_type, pfkey_ext->sadb_ext_len);
26011+
26012+ DEBUGGING(
26013+ "pfkey_msg_parse: extensions "
26014+ "permitted=%08x, required=%08x.\n",
26015+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
26016+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
26017+
26018+ extensions_seen = 1;
26019+
26020+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
26021+ /* Is there enough message left to support another extension header? */
26022+ if(remain < pfkey_ext->sadb_ext_len) {
26023+ DEBUGGING(
26024+ "pfkey_msg_parse: remain %d less than ext len %d.\n",
26025+ remain, pfkey_ext->sadb_ext_len);
26026+ SENDERR(EINVAL);
26027+ }
26028+
26029+ DEBUGGING(
26030+ "pfkey_msg_parse: parsing ext type=%d remain=%d.\n",
26031+ pfkey_ext->sadb_ext_type,
26032+ remain);
26033+
26034+ /* Is the extension header type valid? */
26035+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
26036+ DEBUGGING(
26037+ "pfkey_msg_parse: ext type %d invalid, SADB_EXT_MAX=%d.\n",
26038+ pfkey_ext->sadb_ext_type, SADB_EXT_MAX);
26039+ SENDERR(EINVAL);
26040+ }
26041+
26042+ /* Have we already seen this type of extension? */
26043+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
26044+ {
26045+ DEBUGGING(
26046+ "pfkey_msg_parse: ext type %d already seen.\n",
26047+ pfkey_ext->sadb_ext_type);
26048+ SENDERR(EINVAL);
26049+ }
26050+
26051+ /* Do I even know about this type of extension? */
26052+ if(!(ext_parsers[pfkey_ext->sadb_ext_type])) {
26053+ DEBUGGING(
26054+ "pfkey_msg_parse: ext type %d unknown, ignoring.\n",
26055+ pfkey_ext->sadb_ext_type);
26056+ goto next_ext;
26057+ }
26058+
26059+ /* Is this type of extension permitted for this type of message? */
26060+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
26061+ 1<<pfkey_ext->sadb_ext_type)) {
26062+ DEBUGGING(
26063+ "pfkey_msg_parse: ext type %d not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
26064+ pfkey_ext->sadb_ext_type,
26065+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
26066+ 1<<pfkey_ext->sadb_ext_type);
26067+ SENDERR(EINVAL);
26068+ }
26069+
26070+ DEBUGGING(
26071+ "pfkey_msg_parse: About to parse extension %d %p with parser %p.\n",
26072+ pfkey_ext->sadb_ext_type,
26073+ pfkey_ext,
26074+ ext_parsers[pfkey_ext->sadb_ext_type]);
26075+ /* Parse the extension */
26076+ if((error = ext_parsers[pfkey_ext->sadb_ext_type](pfkey_ext))) {
26077+ DEBUGGING(
26078+ "pfkey_msg_parse: extension parsing for type %d failed with error %d.\n",
26079+ pfkey_ext->sadb_ext_type, error);
26080+ SENDERR(-error);
26081+ }
26082+ DEBUGGING(
26083+ "pfkey_msg_parse: Extension %d parsed.\n",
26084+ pfkey_ext->sadb_ext_type);
26085+
26086+ /* Mark that we have seen this extension and remember the header location */
26087+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
26088+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
26089+
26090+ next_ext:
26091+ /* Calculate how much message remains */
26092+ remain -= pfkey_ext->sadb_ext_len;
26093+
26094+ if(!remain) {
26095+ break;
26096+ }
26097+ /* Find the next extension header */
26098+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
26099+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
26100+ }
26101+
26102+ if(remain) {
26103+ DEBUGGING(
26104+ "pfkey_msg_parse: unexpected remainder of %d.\n",
26105+ remain);
26106+ /* why is there still something remaining? */
26107+ SENDERR(EINVAL);
26108+ }
26109+
26110+ /* check required extensions */
26111+ DEBUGGING(
26112+ "pfkey_msg_parse: extensions "
26113+ "permitted=%08x, seen=%08x, required=%08x.\n",
26114+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
26115+ extensions_seen,
26116+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
26117+
26118+ /* don't check further if it is an error return message since it
26119+ may not have a body */
26120+ if(pfkey_msg->sadb_msg_errno) {
26121+ return error;
26122+ }
26123+
26124+ if((extensions_seen &
26125+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
26126+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
26127+ DEBUGGING(
26128+ "pfkey_msg_parse: required extensions missing:%08x.\n",
26129+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
26130+ (extensions_seen &
26131+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
26132+ SENDERR(EINVAL);
26133+ }
26134+
26135+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
26136+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
26137+ != SADB_X_EXT_ADDRESS_DELFLOW)
26138+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
26139+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
26140+ & SADB_X_SAFLAGS_CLEARFLOW)
26141+ != SADB_X_SAFLAGS_CLEARFLOW))) {
26142+ DEBUGGING(
26143+ "pfkey_msg_parse: "
26144+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
26145+ SADB_X_EXT_ADDRESS_DELFLOW
26146+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
26147+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
26148+ SENDERR(EINVAL);
26149+ }
26150+
26151+ if((pfkey_msg->sadb_msg_type == SADB_ADD) ||
26152+ (pfkey_msg->sadb_msg_type == SADB_UPDATE)) {
26153+
26154+ /* check maturity */
26155+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
26156+ SADB_SASTATE_MATURE) {
26157+ DEBUGGING(
26158+ "pfkey_msg_parse: "
26159+ "state=%d for add or update should be MATURE=%d.\n",
26160+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
26161+ SADB_SASTATE_MATURE);
26162+ SENDERR(EINVAL);
26163+ }
26164+
26165+ /* check AH and ESP */
26166+ if(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype ==
26167+ SADB_SATYPE_AH) {
26168+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
26169+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
26170+ SADB_AALG_NONE)) {
26171+ DEBUGGING(
26172+ "pfkey_msg_parse: "
26173+ "auth alg is zero, must be non-zero for AH SAs.\n");
26174+ SENDERR(EINVAL);
26175+ }
26176+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
26177+ SADB_EALG_NONE) {
26178+ DEBUGGING(
26179+ "pfkey_msg_parse: "
26180+ "AH handed encalg=%d, must be zero.\n",
26181+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
26182+ SENDERR(EINVAL);
26183+ }
26184+ }
26185+
26186+ if(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype ==
26187+ SADB_SATYPE_ESP) {
26188+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
26189+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
26190+ SADB_EALG_NONE)) {
26191+ DEBUGGING(
26192+ "pfkey_msg_parse: "
26193+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
26194+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
26195+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
26196+ SENDERR(EINVAL);
26197+ }
26198+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
26199+ SADB_EALG_NULL) &&
26200+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
26201+ SADB_AALG_NONE) ) {
26202+ DEBUGGING(
26203+ "pfkey_msg_parse: "
26204+ "ESP handed encNULL+authNONE, illegal combination.\n");
26205+ SENDERR(EINVAL);
26206+ }
26207+ }
26208+ }
26209+errlab:
26210+
26211+ return error;
26212+}
26213+
26214+/*
26215+ * $Log$
26216+ * Revision 1.30 2000/11/17 18:10:30 rgb
26217+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
26218+ * network byte order since this is the way PF_KEYv2 stored spis.
26219+ *
26220+ * Revision 1.29 2000/10/12 00:02:39 rgb
26221+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
26222+ *
26223+ * Revision 1.28 2000/09/20 16:23:04 rgb
26224+ * Remove over-paranoid extension check in the presence of sadb_msg_errno.
26225+ *
26226+ * Revision 1.27 2000/09/20 04:04:21 rgb
26227+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
26228+ * oopsen.
26229+ *
26230+ * Revision 1.26 2000/09/15 11:37:02 rgb
26231+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
26232+ * IPCOMP zlib deflate code.
26233+ *
26234+ * Revision 1.25 2000/09/12 22:35:37 rgb
26235+ * Restructured to remove unused extensions from CLEARFLOW messages.
26236+ *
26237+ * Revision 1.24 2000/09/12 18:59:54 rgb
26238+ * Added Gerhard's IPv6 support to pfkey parts of libfreeswan.
26239+ *
26240+ * Revision 1.23 2000/09/12 03:27:00 rgb
26241+ * Moved DEBUGGING definition to compile kernel with debug off.
26242+ *
26243+ * Revision 1.22 2000/09/09 06:39:27 rgb
26244+ * Restrict pfkey errno check to downward messages only.
26245+ *
26246+ * Revision 1.21 2000/09/08 19:22:34 rgb
26247+ * Enabled pfkey_sens_parse().
26248+ * Added check for errno on downward acquire messages only.
26249+ *
26250+ * Revision 1.20 2000/09/01 18:48:23 rgb
26251+ * Fixed reserved check bug and added debug output in
26252+ * pfkey_supported_parse().
26253+ * Fixed debug output label bug in pfkey_ident_parse().
26254+ *
26255+ * Revision 1.19 2000/08/27 01:55:26 rgb
26256+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
26257+ *
26258+ * Revision 1.18 2000/08/24 17:00:36 rgb
26259+ * Ignore unknown extensions instead of failing.
26260+ *
26261+ * Revision 1.17 2000/06/02 22:54:14 rgb
26262+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
26263+ *
26264+ * Revision 1.16 2000/05/10 19:25:11 rgb
26265+ * Fleshed out proposal and supported extensions.
26266+ *
26267+ * Revision 1.15 2000/01/24 21:15:31 rgb
26268+ * Added disabled pluto pfkey lib debug flag.
26269+ * Added algo debugging reporting.
26270+ *
26271+ * Revision 1.14 2000/01/22 23:24:29 rgb
26272+ * Added new functions proto2satype() and satype2proto() and lookup
26273+ * table satype_tbl. Also added proto2name() since it was easy.
26274+ *
26275+ * Revision 1.13 2000/01/21 09:43:59 rgb
26276+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
26277+ *
26278+ * Revision 1.12 2000/01/21 06:28:19 rgb
26279+ * Added address cases for eroute flows.
26280+ * Indented compiler directives for readability.
26281+ * Added klipsdebug switching capability.
26282+ *
26283+ * Revision 1.11 1999/12/29 21:14:59 rgb
26284+ * Fixed debug text cut and paste typo.
26285+ *
26286+ * Revision 1.10 1999/12/10 17:45:24 rgb
26287+ * Added address debugging.
26288+ *
26289+ * Revision 1.9 1999/12/09 23:11:42 rgb
26290+ * Ditched <string.h> include since we no longer use memset().
26291+ * Use new pfkey_extensions_init() instead of memset().
26292+ * Added check for SATYPE in pfkey_msg_build().
26293+ * Tidy up comments and debugging comments.
26294+ *
26295+ * Revision 1.8 1999/12/07 19:55:26 rgb
26296+ * Removed unused first argument from extension parsers.
26297+ * Removed static pluto debug flag.
26298+ * Moved message type and state checking to pfkey_msg_parse().
26299+ * Changed print[fk] type from lx to x to quiet compiler.
26300+ * Removed redundant remain check.
26301+ * Changed __u* types to uint* to avoid use of asm/types.h and
26302+ * sys/types.h in userspace code.
26303+ *
26304+ * Revision 1.7 1999/12/01 22:20:51 rgb
26305+ * Moved pfkey_lib_debug variable into the library.
26306+ * Added pfkey version check into header parsing.
26307+ * Added check for SATYPE only for those extensions that require a
26308+ * non-zero value.
26309+ *
26310+ * Revision 1.6 1999/11/27 11:58:05 rgb
26311+ * Added ipv6 headers.
26312+ * Moved sadb_satype2proto protocol lookup table from
26313+ * klips/net/ipsec/pfkey_v2_parser.c.
26314+ * Enable lifetime_current checking.
26315+ * Debugging error messages added.
26316+ * Add argument to pfkey_msg_parse() for direction.
26317+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
26318+ * Add CVS log entry to bottom of file.
26319+ * Moved auth and enc alg check to pfkey_msg_parse().
26320+ * Enable accidentally disabled spirange parsing.
26321+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
26322+ *
26323+ */
26324diff -druN linux-noipsec/net/ipsec/libfreeswan/pfkeyv2.h linux/net/ipsec/libfreeswan/pfkeyv2.h
26325--- linux-noipsec/net/ipsec/libfreeswan/pfkeyv2.h Thu Jan 1 01:00:00 1970
26326+++ linux/net/ipsec/libfreeswan/pfkeyv2.h Tue Oct 10 22:10:20 2000
26327@@ -0,0 +1,317 @@
26328+/*
26329+ * RCSID $Id$
26330+ */
26331+
26332+/*
26333+This file defines structures and symbols for the PF_KEY Version 2
26334+key management interface. It was written at the U.S. Naval Research
26335+Laboratory. This file is in the public domain. The authors ask that
26336+you leave this credit intact on any copies of this file.
26337+*/
26338+#ifndef __PFKEY_V2_H
26339+#define __PFKEY_V2_H 1
26340+
26341+#define PF_KEY_V2 2
26342+#define PFKEYV2_REVISION 199806L
26343+
26344+#define SADB_RESERVED 0
26345+#define SADB_GETSPI 1
26346+#define SADB_UPDATE 2
26347+#define SADB_ADD 3
26348+#define SADB_DELETE 4
26349+#define SADB_GET 5
26350+#define SADB_ACQUIRE 6
26351+#define SADB_REGISTER 7
26352+#define SADB_EXPIRE 8
26353+#define SADB_FLUSH 9
26354+#define SADB_DUMP 10
26355+#define SADB_X_PROMISC 11
26356+#define SADB_X_PCHANGE 12
26357+#define SADB_X_GRPSA 13
26358+#define SADB_X_ADDFLOW 14
26359+#define SADB_X_DELFLOW 15
26360+#define SADB_X_DEBUG 16
26361+#define SADB_MAX 16
26362+
26363+struct sadb_msg {
26364+ uint8_t sadb_msg_version;
26365+ uint8_t sadb_msg_type;
26366+ uint8_t sadb_msg_errno;
26367+ uint8_t sadb_msg_satype;
26368+ uint16_t sadb_msg_len;
26369+ uint16_t sadb_msg_reserved;
26370+ uint32_t sadb_msg_seq;
26371+ uint32_t sadb_msg_pid;
26372+};
26373+
26374+struct sadb_ext {
26375+ uint16_t sadb_ext_len;
26376+ uint16_t sadb_ext_type;
26377+};
26378+
26379+struct sadb_sa {
26380+ uint16_t sadb_sa_len;
26381+ uint16_t sadb_sa_exttype;
26382+ uint32_t sadb_sa_spi;
26383+ uint8_t sadb_sa_replay;
26384+ uint8_t sadb_sa_state;
26385+ uint8_t sadb_sa_auth;
26386+ uint8_t sadb_sa_encrypt;
26387+ uint32_t sadb_sa_flags;
26388+};
26389+
26390+struct sadb_lifetime {
26391+ uint16_t sadb_lifetime_len;
26392+ uint16_t sadb_lifetime_exttype;
26393+ uint32_t sadb_lifetime_allocations;
26394+ uint64_t sadb_lifetime_bytes;
26395+ uint64_t sadb_lifetime_addtime;
26396+ uint64_t sadb_lifetime_usetime;
26397+};
26398+
26399+struct sadb_address {
26400+ uint16_t sadb_address_len;
26401+ uint16_t sadb_address_exttype;
26402+ uint8_t sadb_address_proto;
26403+ uint8_t sadb_address_prefixlen;
26404+ uint16_t sadb_address_reserved;
26405+};
26406+
26407+struct sadb_key {
26408+ uint16_t sadb_key_len;
26409+ uint16_t sadb_key_exttype;
26410+ uint16_t sadb_key_bits;
26411+ uint16_t sadb_key_reserved;
26412+};
26413+
26414+struct sadb_ident {
26415+ uint16_t sadb_ident_len;
26416+ uint16_t sadb_ident_exttype;
26417+ uint16_t sadb_ident_type;
26418+ uint16_t sadb_ident_reserved;
26419+ uint64_t sadb_ident_id;
26420+};
26421+
26422+struct sadb_sens {
26423+ uint16_t sadb_sens_len;
26424+ uint16_t sadb_sens_exttype;
26425+ uint32_t sadb_sens_dpd;
26426+ uint8_t sadb_sens_sens_level;
26427+ uint8_t sadb_sens_sens_len;
26428+ uint8_t sadb_sens_integ_level;
26429+ uint8_t sadb_sens_integ_len;
26430+ uint32_t sadb_sens_reserved;
26431+};
26432+
26433+struct sadb_prop {
26434+ uint16_t sadb_prop_len;
26435+ uint16_t sadb_prop_exttype;
26436+ uint8_t sadb_prop_replay;
26437+ uint8_t sadb_prop_reserved[3];
26438+};
26439+
26440+struct sadb_comb {
26441+ uint8_t sadb_comb_auth;
26442+ uint8_t sadb_comb_encrypt;
26443+ uint16_t sadb_comb_flags;
26444+ uint16_t sadb_comb_auth_minbits;
26445+ uint16_t sadb_comb_auth_maxbits;
26446+ uint16_t sadb_comb_encrypt_minbits;
26447+ uint16_t sadb_comb_encrypt_maxbits;
26448+ uint32_t sadb_comb_reserved;
26449+ uint32_t sadb_comb_soft_allocations;
26450+ uint32_t sadb_comb_hard_allocations;
26451+ uint64_t sadb_comb_soft_bytes;
26452+ uint64_t sadb_comb_hard_bytes;
26453+ uint64_t sadb_comb_soft_addtime;
26454+ uint64_t sadb_comb_hard_addtime;
26455+ uint64_t sadb_comb_soft_usetime;
26456+ uint64_t sadb_comb_hard_usetime;
26457+};
26458+
26459+struct sadb_supported {
26460+ uint16_t sadb_supported_len;
26461+ uint16_t sadb_supported_exttype;
26462+ uint32_t sadb_supported_reserved;
26463+};
26464+
26465+struct sadb_alg {
26466+ uint8_t sadb_alg_id;
26467+ uint8_t sadb_alg_ivlen;
26468+ uint16_t sadb_alg_minbits;
26469+ uint16_t sadb_alg_maxbits;
26470+ uint16_t sadb_alg_reserved;
26471+};
26472+
26473+struct sadb_spirange {
26474+ uint16_t sadb_spirange_len;
26475+ uint16_t sadb_spirange_exttype;
26476+ uint32_t sadb_spirange_min;
26477+ uint32_t sadb_spirange_max;
26478+ uint32_t sadb_spirange_reserved;
26479+};
26480+
26481+struct sadb_x_kmprivate {
26482+ uint16_t sadb_x_kmprivate_len;
26483+ uint16_t sadb_x_kmprivate_exttype;
26484+ uint32_t sadb_x_kmprivate_reserved;
26485+};
26486+
26487+struct sadb_x_satype {
26488+ uint16_t sadb_x_satype_len;
26489+ uint16_t sadb_x_satype_exttype;
26490+ uint8_t sadb_x_satype_satype;
26491+ uint8_t sadb_x_satype_reserved[3];
26492+};
26493+
26494+struct sadb_x_debug {
26495+ uint16_t sadb_x_debug_len;
26496+ uint16_t sadb_x_debug_exttype;
26497+ uint32_t sadb_x_debug_tunnel;
26498+ uint32_t sadb_x_debug_netlink;
26499+ uint32_t sadb_x_debug_xform;
26500+ uint32_t sadb_x_debug_eroute;
26501+ uint32_t sadb_x_debug_spi;
26502+ uint32_t sadb_x_debug_radij;
26503+ uint32_t sadb_x_debug_esp;
26504+ uint32_t sadb_x_debug_ah;
26505+ uint32_t sadb_x_debug_rcv;
26506+ uint32_t sadb_x_debug_pfkey;
26507+ uint32_t sadb_x_debug_ipcomp;
26508+ uint32_t sadb_x_debug_verbose;
26509+ uint8_t sadb_x_debug_reserved[4];
26510+};
26511+
26512+#define SADB_EXT_RESERVED 0
26513+#define SADB_EXT_SA 1
26514+#define SADB_EXT_LIFETIME_CURRENT 2
26515+#define SADB_EXT_LIFETIME_HARD 3
26516+#define SADB_EXT_LIFETIME_SOFT 4
26517+#define SADB_EXT_ADDRESS_SRC 5
26518+#define SADB_EXT_ADDRESS_DST 6
26519+#define SADB_EXT_ADDRESS_PROXY 7
26520+#define SADB_EXT_KEY_AUTH 8
26521+#define SADB_EXT_KEY_ENCRYPT 9
26522+#define SADB_EXT_IDENTITY_SRC 10
26523+#define SADB_EXT_IDENTITY_DST 11
26524+#define SADB_EXT_SENSITIVITY 12
26525+#define SADB_EXT_PROPOSAL 13
26526+#define SADB_EXT_SUPPORTED_AUTH 14
26527+#define SADB_EXT_SUPPORTED_ENCRYPT 15
26528+#define SADB_EXT_SPIRANGE 16
26529+#define SADB_X_EXT_KMPRIVATE 17
26530+#define SADB_X_EXT_SATYPE2 18
26531+#define SADB_X_EXT_SA2 19
26532+#define SADB_X_EXT_ADDRESS_DST2 20
26533+#define SADB_X_EXT_ADDRESS_SRC_FLOW 21
26534+#define SADB_X_EXT_ADDRESS_DST_FLOW 22
26535+#define SADB_X_EXT_ADDRESS_SRC_MASK 23
26536+#define SADB_X_EXT_ADDRESS_DST_MASK 24
26537+#define SADB_X_EXT_DEBUG 25
26538+#define SADB_EXT_MAX 25
26539+
26540+/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
26541+#define SADB_X_EXT_ADDRESS_DELFLOW \
26542+ ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
26543+ | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
26544+ | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
26545+ | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
26546+
26547+#define SADB_SATYPE_UNSPEC 0
26548+#define SADB_SATYPE_AH 2
26549+#define SADB_SATYPE_ESP 3
26550+#define SADB_SATYPE_RSVP 5
26551+#define SADB_SATYPE_OSPFV2 6
26552+#define SADB_SATYPE_RIPV2 7
26553+#define SADB_SATYPE_MIP 8
26554+#define SADB_X_SATYPE_IPIP 9
26555+#define SADB_X_SATYPE_COMP 10
26556+#define SADB_SATYPE_MAX 10
26557+
26558+#define SADB_SASTATE_LARVAL 0
26559+#define SADB_SASTATE_MATURE 1
26560+#define SADB_SASTATE_DYING 2
26561+#define SADB_SASTATE_DEAD 3
26562+#define SADB_SASTATE_MAX 3
26563+
26564+#define SADB_SAFLAGS_PFS 1
26565+#define SADB_X_SAFLAGS_REPLACEFLOW 2
26566+#define SADB_X_SAFLAGS_CLEARFLOW 4
26567+
26568+#define SADB_AALG_NONE 0
26569+#define SADB_AALG_MD5HMAC 2
26570+#define SADB_AALG_SHA1HMAC 3
26571+#define SADB_AALG_MAX 3
26572+
26573+#define SADB_EALG_NONE 0
26574+#define SADB_EALG_DESCBC 2
26575+#define SADB_EALG_3DESCBC 3
26576+#define SADB_EALG_NULL 11
26577+#define SADB_EALG_MAX 11
26578+
26579+#define SADB_X_CALG_NONE 0
26580+#define SADB_X_CALG_OUI 1
26581+#define SADB_X_CALG_DEFLATE 2
26582+#define SADB_X_CALG_LZS 3
26583+#define SADB_X_CALG_V42BIS 4
26584+#define SADB_X_CALG_MAX 4
26585+
26586+#define SADB_X_TALG_NONE 0
26587+#define SADB_X_TALG_IPv4_in_IPv4 1
26588+#define SADB_X_TALG_IPv6_in_IPv4 2
26589+#define SADB_X_TALG_IPv4_in_IPv6 3
26590+#define SADB_X_TALG_IPv6_in_IPv6 4
26591+#define SADB_X_TALG_MAX 4
26592+
26593+
26594+#define SADB_IDENTTYPE_RESERVED 0
26595+#define SADB_IDENTTYPE_PREFIX 1
26596+#define SADB_IDENTTYPE_FQDN 2
26597+#define SADB_IDENTTYPE_USERFQDN 3
26598+#define SADB_IDENTTYPE_MAX 3
26599+
26600+#define SADB_KEY_FLAGS_MAX 0
26601+#endif /* __PFKEY_V2_H */
26602+
26603+/*
26604+ * $Log$
26605+ * Revision 1.13 2000/10/10 20:10:20 rgb
26606+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
26607+ *
26608+ * Revision 1.12 2000/09/15 06:41:50 rgb
26609+ * Added V42BIS constant.
26610+ *
26611+ * Revision 1.11 2000/09/12 22:35:37 rgb
26612+ * Restructured to remove unused extensions from CLEARFLOW messages.
26613+ *
26614+ * Revision 1.10 2000/09/12 18:50:09 rgb
26615+ * Added IPIP tunnel types as algo support.
26616+ *
26617+ * Revision 1.9 2000/08/21 16:47:19 rgb
26618+ * Added SADB_X_CALG_* macros for IPCOMP.
26619+ *
26620+ * Revision 1.8 2000/08/09 20:43:34 rgb
26621+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
26622+ *
26623+ * Revision 1.7 2000/01/21 06:28:37 rgb
26624+ * Added flow add/delete message type macros.
26625+ * Added flow address extension type macros.
26626+ * Tidied up spacing.
26627+ * Added klipsdebug switching capability.
26628+ *
26629+ * Revision 1.6 1999/11/27 11:56:08 rgb
26630+ * Add SADB_X_SATYPE_COMP for compression, eventually.
26631+ *
26632+ * Revision 1.5 1999/11/23 22:23:16 rgb
26633+ * This file has been moved in the distribution from klips/net/ipsec to
26634+ * lib.
26635+ *
26636+ * Revision 1.4 1999/04/29 15:23:29 rgb
26637+ * Add GRPSA support.
26638+ * Add support for a second SATYPE, SA and DST_ADDRESS.
26639+ * Add IPPROTO_IPIP support.
26640+ *
26641+ * Revision 1.3 1999/04/15 17:58:08 rgb
26642+ * Add RCSID labels.
26643+ *
26644+ */
26645diff -druN linux-noipsec/net/ipsec/libfreeswan/portof.c linux/net/ipsec/libfreeswan/portof.c
26646--- linux-noipsec/net/ipsec/libfreeswan/portof.c Thu Jan 1 01:00:00 1970
26647+++ linux/net/ipsec/libfreeswan/portof.c Fri Sep 8 20:03:45 2000
26648@@ -0,0 +1,96 @@
26649+/*
26650+ * low-level ip_address ugliness
26651+ * Copyright (C) 2000 Henry Spencer.
26652+ *
26653+ * This library is free software; you can redistribute it and/or modify it
26654+ * under the terms of the GNU Library General Public License as published by
26655+ * the Free Software Foundation; either version 2 of the License, or (at your
26656+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
26657+ *
26658+ * This library is distributed in the hope that it will be useful, but
26659+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26660+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
26661+ * License for more details.
26662+ *
26663+ * RCSID $Id$
26664+ */
26665+#include "internal.h"
26666+#include "freeswan.h"
26667+
26668+/*
26669+ - portof - get the port field of an ip_address
26670+ */
26671+int /* network order */
26672+portof(src)
26673+const ip_address *src;
26674+{
26675+ switch (src->u.v4.sin_family) {
26676+ case AF_INET:
26677+ return src->u.v4.sin_port;
26678+ break;
26679+ case AF_INET6:
26680+ return src->u.v6.sin6_port;
26681+ break;
26682+ default:
26683+ return -1; /* "can't happen" */
26684+ break;
26685+ }
26686+}
26687+
26688+/*
26689+ - setportof - set the port field of an ip_address
26690+ */
26691+void
26692+setportof(port, dst)
26693+int port; /* network order */
26694+ip_address *dst;
26695+{
26696+ switch (dst->u.v4.sin_family) {
26697+ case AF_INET:
26698+ dst->u.v4.sin_port = port;
26699+ break;
26700+ case AF_INET6:
26701+ dst->u.v6.sin6_port = port;
26702+ break;
26703+ }
26704+}
26705+
26706+/*
26707+ - sockaddrof - get a pointer to the sockaddr hiding inside an ip_address
26708+ */
26709+struct sockaddr *
26710+sockaddrof(src)
26711+ip_address *src;
26712+{
26713+ switch (src->u.v4.sin_family) {
26714+ case AF_INET:
26715+ return (struct sockaddr *)&src->u.v4;
26716+ break;
26717+ case AF_INET6:
26718+ return (struct sockaddr *)&src->u.v6;
26719+ break;
26720+ default:
26721+ return NULL; /* "can't happen" */
26722+ break;
26723+ }
26724+}
26725+
26726+/*
26727+ - sockaddrlenof - get length of the sockaddr hiding inside an ip_address
26728+ */
26729+size_t /* 0 for error */
26730+sockaddrlenof(src)
26731+const ip_address *src;
26732+{
26733+ switch (src->u.v4.sin_family) {
26734+ case AF_INET:
26735+ return sizeof(src->u.v4);
26736+ break;
26737+ case AF_INET6:
26738+ return sizeof(src->u.v6);
26739+ break;
26740+ default:
26741+ return 0;
26742+ break;
26743+ }
26744+}
26745diff -druN linux-noipsec/net/ipsec/libfreeswan/rangetoa.c linux/net/ipsec/libfreeswan/rangetoa.c
26746--- linux-noipsec/net/ipsec/libfreeswan/rangetoa.c Thu Jan 1 01:00:00 1970
26747+++ linux/net/ipsec/libfreeswan/rangetoa.c Sun Apr 11 01:24:21 1999
26748@@ -0,0 +1,61 @@
26749+/*
26750+ * convert binary form of address range to ASCII
26751+ * Copyright (C) 1998, 1999 Henry Spencer.
26752+ *
26753+ * This library is free software; you can redistribute it and/or modify it
26754+ * under the terms of the GNU Library General Public License as published by
26755+ * the Free Software Foundation; either version 2 of the License, or (at your
26756+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
26757+ *
26758+ * This library is distributed in the hope that it will be useful, but
26759+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26760+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
26761+ * License for more details.
26762+ *
26763+ * RCSID $Id$
26764+ */
26765+#include "internal.h"
26766+#include "freeswan.h"
26767+
26768+/*
26769+ - rangetoa - convert address range to ASCII
26770+ */
26771+size_t /* space needed for full conversion */
26772+rangetoa(addrs, format, dst, dstlen)
26773+struct in_addr addrs[2];
26774+int format; /* character */
26775+char *dst; /* need not be valid if dstlen is 0 */
26776+size_t dstlen;
26777+{
26778+ size_t len;
26779+ size_t rest;
26780+ int n;
26781+ char *p;
26782+
26783+ switch (format) {
26784+ case 0:
26785+ break;
26786+ default:
26787+ return 0;
26788+ break;
26789+ }
26790+
26791+ len = addrtoa(addrs[0], 0, dst, dstlen);
26792+ if (len < dstlen)
26793+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
26794+ p++, len++, n--)
26795+ *p = '.';
26796+ else
26797+ p = NULL;
26798+ if (len < dstlen)
26799+ rest = dstlen - len;
26800+ else {
26801+ if (dstlen > 0)
26802+ *(dst + dstlen - 1) = '\0';
26803+ rest = 0;
26804+ }
26805+
26806+ len += addrtoa(addrs[1], 0, p, rest);
26807+
26808+ return len;
26809+}
26810diff -druN linux-noipsec/net/ipsec/libfreeswan/rangetosubnet.c linux/net/ipsec/libfreeswan/rangetosubnet.c
26811--- linux-noipsec/net/ipsec/libfreeswan/rangetosubnet.c Thu Jan 1 01:00:00 1970
26812+++ linux/net/ipsec/libfreeswan/rangetosubnet.c Fri Sep 8 20:03:45 2000
26813@@ -0,0 +1,228 @@
26814+/*
26815+ * express an address range as a subnet (if possible)
26816+ * Copyright (C) 2000 Henry Spencer.
26817+ *
26818+ * This library is free software; you can redistribute it and/or modify it
26819+ * under the terms of the GNU Library General Public License as published by
26820+ * the Free Software Foundation; either version 2 of the License, or (at your
26821+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
26822+ *
26823+ * This library is distributed in the hope that it will be useful, but
26824+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26825+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
26826+ * License for more details.
26827+ *
26828+ * RCSID $Id$
26829+ */
26830+#include "internal.h"
26831+#include "freeswan.h"
26832+
26833+/*
26834+ - rangetosubnet - turn an address range into a subnet, if possible
26835+ *
26836+ * A range which is a valid subnet will have a network part which is the
26837+ * same in the from value and the to value, followed by a host part which
26838+ * is all 0 in the from value and all 1 in the to value.
26839+ */
26840+err_t
26841+rangetosubnet(from, to, dst)
26842+const ip_address *from;
26843+const ip_address *to;
26844+ip_subnet *dst;
26845+{
26846+ unsigned const char *fp;
26847+ unsigned const char *tp;
26848+ unsigned fb;
26849+ unsigned tb;
26850+ unsigned const char *f;
26851+ unsigned const char *t;
26852+ size_t n;
26853+ size_t n2;
26854+ int i;
26855+ int nnet;
26856+ unsigned m;
26857+
26858+ if (addrtypeof(from) != addrtypeof(to))
26859+ return "mismatched address types";
26860+ n = addrbytesptr(from, &fp);
26861+ if (n == 0)
26862+ return "unknown address type";
26863+ n2 = addrbytesptr(to, &tp);
26864+ if (n != n2)
26865+ return "internal size mismatch in rangetosubnet";
26866+
26867+ f = fp;
26868+ t = tp;
26869+ nnet = 0;
26870+ for (i = n; i > 0 && *f == *t; i--, f++, t++)
26871+ nnet += 8;
26872+ if (i > 0 && !(*f == 0x00 && *t == 0xff)) { /* mid-byte bdry. */
26873+ fb = *f++;
26874+ tb = *t++;
26875+ i--;
26876+ m = 0x80;
26877+ while ((fb&m) == (tb&m)) {
26878+ fb &= ~m;
26879+ tb |= m;
26880+ m >>= 1;
26881+ nnet++;
26882+ }
26883+ if (fb != 0x00 || tb != 0xff)
26884+ return "not a valid subnet";
26885+ }
26886+ for (; i > 0 && *f == 0x00 && *t == 0xff; i--, f++, t++)
26887+ continue;
26888+
26889+ if (i != 0)
26890+ return "invalid subnet";
26891+
26892+ return initsubnet(from, nnet, 'x', dst);
26893+}
26894+
26895+
26896+
26897+#ifdef RANGETOSUBNET_MAIN
26898+
26899+#include <stdio.h>
26900+
26901+void regress();
26902+
26903+int
26904+main(argc, argv)
26905+int argc;
26906+char *argv[];
26907+{
26908+ ip_address start;
26909+ ip_address stop;
26910+ ip_subnet sub;
26911+ char buf[100];
26912+ const char *oops;
26913+ size_t n;
26914+ int af;
26915+ int i;
26916+
26917+ if (argc == 2 && strcmp(argv[1], "-r") == 0) {
26918+ regress();
26919+ fprintf(stderr, "regress() returned?!?\n");
26920+ exit(1);
26921+ }
26922+
26923+ if (argc < 3) {
26924+ fprintf(stderr, "Usage: %s [-6] start stop\n", argv[0]);
26925+ fprintf(stderr, " or: %s -r\n", argv[0]);
26926+ exit(2);
26927+ }
26928+
26929+ af = AF_INET;
26930+ i = 1;
26931+ if (strcmp(argv[i], "-6") == 0) {
26932+ af = AF_INET6;
26933+ i++;
26934+ }
26935+
26936+ oops = ttoaddr(argv[i], 0, af, &start);
26937+ if (oops != NULL) {
26938+ fprintf(stderr, "%s: start conversion failed: %s\n", argv[0], oops);
26939+ exit(1);
26940+ }
26941+ oops = ttoaddr(argv[i+1], 0, af, &stop);
26942+ if (oops != NULL) {
26943+ fprintf(stderr, "%s: stop conversion failed: %s\n", argv[0], oops);
26944+ exit(1);
26945+ }
26946+ oops = rangetosubnet(&start, &stop, &sub);
26947+ if (oops != NULL) {
26948+ fprintf(stderr, "%s: rangetosubnet failed: %s\n", argv[0], oops);
26949+ exit(1);
26950+ }
26951+ n = subnettot(&sub, 0, buf, sizeof(buf));
26952+ if (n > sizeof(buf)) {
26953+ fprintf(stderr, "%s: reverse conversion", argv[0]);
26954+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
26955+ (long)n, (long)sizeof(buf));
26956+ exit(1);
26957+ }
26958+ printf("%s\n", buf);
26959+
26960+ exit(0);
26961+}
26962+
26963+struct rtab {
26964+ int family;
26965+ char *start;
26966+ char *stop;
26967+ char *output; /* NULL means error expected */
26968+} rtab[] = {
26969+ 4, "1.2.3.0", "1.2.3.255", "1.2.3.0/24",
26970+ 4, "1.2.3.0", "1.2.3.7", "1.2.3.0/29",
26971+ 4, "1.2.3.240", "1.2.3.255", "1.2.3.240/28",
26972+ 4, "0.0.0.0", "255.255.255.255", "0.0.0.0/0",
26973+ 4, "1.2.3.4", "1.2.3.4", "1.2.3.4/32",
26974+ 4, "1.2.3.0", "1.2.3.254", NULL,
26975+ 4, "1.2.3.0", "1.2.3.126", NULL,
26976+ 4, "1.2.3.0", "1.2.3.125", NULL,
26977+ 4, "1.2.0.0", "1.2.255.255", "1.2.0.0/16",
26978+ 4, "1.2.0.0", "1.2.0.255", "1.2.0.0/24",
26979+ 4, "1.2.255.0", "1.2.255.255", "1.2.255.0/24",
26980+ 4, "1.2.255.0", "1.2.254.255", NULL,
26981+ 4, "1.2.255.1", "1.2.255.255", NULL,
26982+ 4, "1.2.0.1", "1.2.255.255", NULL,
26983+ 6, "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:ffff", "1:2:3:4:5:6:7:0/112",
26984+ 6, "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:fff", "1:2:3:4:5:6:7:0/116",
26985+ 6, "1:2:3:4:5:6:7:f0", "1:2:3:4:5:6:7:ff", "1:2:3:4:5:6:7:f0/124",
26986+ 4, NULL, NULL, NULL,
26987+};
26988+
26989+void
26990+regress()
26991+{
26992+ struct rtab *r;
26993+ int status = 0;
26994+ ip_address start;
26995+ ip_address stop;
26996+ ip_subnet sub;
26997+ char buf[100];
26998+ const char *oops;
26999+ size_t n;
27000+ int af;
27001+
27002+ for (r = rtab; r->start != NULL; r++) {
27003+ af = (r->family == 4) ? AF_INET : AF_INET6;
27004+ oops = ttoaddr(r->start, 0, af, &start);
27005+ if (oops != NULL) {
27006+ printf("surprise failure converting `%s'\n", r->start);
27007+ exit(1);
27008+ }
27009+ oops = ttoaddr(r->stop, 0, af, &stop);
27010+ if (oops != NULL) {
27011+ printf("surprise failure converting `%s'\n", r->stop);
27012+ exit(1);
27013+ }
27014+ oops = rangetosubnet(&start, &stop, &sub);
27015+ if (oops != NULL && r->output == NULL)
27016+ {} /* okay, error expected */
27017+ else if (oops != NULL) {
27018+ printf("`%s'-`%s' rangetosubnet failed: %s\n",
27019+ r->start, r->stop, oops);
27020+ status = 1;
27021+ } else if (r->output == NULL) {
27022+ printf("`%s'-`%s' rangetosubnet succeeded unexpectedly\n",
27023+ r->start, r->stop);
27024+ status = 1;
27025+ } else {
27026+ n = subnettot(&sub, 0, buf, sizeof(buf));
27027+ if (n > sizeof(buf)) {
27028+ printf("`%s'-`%s' subnettot failed: need %ld\n",
27029+ r->start, r->stop, (long)n);
27030+ status = 1;
27031+ } else if (strcmp(r->output, buf) != 0) {
27032+ printf("`%s'-`%s' gave `%s', expected `%s'\n",
27033+ r->start, r->stop, buf, r->output);
27034+ status = 1;
27035+ }
27036+ }
27037+ }
27038+ exit(status);
27039+}
27040+
27041+#endif /* RANGETOSUBNET_MAIN */
27042diff -druN linux-noipsec/net/ipsec/libfreeswan/sameaddr.c linux/net/ipsec/libfreeswan/sameaddr.c
27043--- linux-noipsec/net/ipsec/libfreeswan/sameaddr.c Thu Jan 1 01:00:00 1970
27044+++ linux/net/ipsec/libfreeswan/sameaddr.c Wed Nov 29 17:34:01 2000
27045@@ -0,0 +1,190 @@
27046+/*
27047+ * comparisons
27048+ * Copyright (C) 2000 Henry Spencer.
27049+ *
27050+ * This library is free software; you can redistribute it and/or modify it
27051+ * under the terms of the GNU Library General Public License as published by
27052+ * the Free Software Foundation; either version 2 of the License, or (at your
27053+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
27054+ *
27055+ * This library is distributed in the hope that it will be useful, but
27056+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27057+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
27058+ * License for more details.
27059+ *
27060+ * RCSID $Id$
27061+ */
27062+#include "internal.h"
27063+#include "freeswan.h"
27064+
27065+static int samenbits(const ip_address *a, const ip_address *b, int n);
27066+
27067+/*
27068+ - addrcmp - compare two addresses
27069+ * Caution, the order of the tests is subtle: doing type test before
27070+ * size test can yield cases where a<b, b<c, but a>c.
27071+ */
27072+int /* like memcmp */
27073+addrcmp(a, b)
27074+const ip_address *a;
27075+const ip_address *b;
27076+{
27077+ int at = addrtypeof(a);
27078+ int bt = addrtypeof(b);
27079+ const unsigned char *ap;
27080+ const unsigned char *bp;
27081+ size_t as = addrbytesptr(a, &ap);
27082+ size_t bs = addrbytesptr(b, &bp);
27083+ size_t n = (as < bs) ? as : bs; /* min(as, bs) */
27084+ int c = memcmp(ap, bp, n);
27085+
27086+ if (c != 0) /* bytes differ */
27087+ return (c < 0) ? -1 : 1;
27088+ if (as != bs) /* comparison incomplete: lexical order */
27089+ return (as < bs) ? -1 : 1;
27090+ if (at != bt) /* bytes same but not same type: break tie */
27091+ return (at < bt) ? -1 : 1;
27092+ return 0;
27093+}
27094+
27095+/*
27096+ - sameaddr - are two addresses the same?
27097+ */
27098+int
27099+sameaddr(a, b)
27100+const ip_address *a;
27101+const ip_address *b;
27102+{
27103+ return (addrcmp(a, b) == 0) ? 1 : 0;
27104+}
27105+
27106+/*
27107+ - samesubnet - are two subnets the same?
27108+ */
27109+int
27110+samesubnet(a, b)
27111+const ip_subnet *a;
27112+const ip_subnet *b;
27113+{
27114+ if (!sameaddr(&a->addr, &b->addr)) /* also does type check */
27115+ return 0;
27116+ if (a->maskbits != b->maskbits)
27117+ return 0;
27118+ return 1;
27119+}
27120+
27121+/*
27122+ - subnetishost - is a subnet in fact a single host?
27123+ */
27124+int
27125+subnetishost(a)
27126+const ip_subnet *a;
27127+{
27128+ return (a->maskbits == addrlenof(&a->addr)*8) ? 1 : 0;
27129+}
27130+
27131+/*
27132+ - samesaid - are two SA IDs the same?
27133+ */
27134+int
27135+samesaid(a, b)
27136+const ip_said *a;
27137+const ip_said *b;
27138+{
27139+ if (a->spi != b->spi) /* test first, most likely to be different */
27140+ return 0;
27141+ if (!sameaddr(&a->dst, &b->dst))
27142+ return 0;
27143+ if (a->proto != b->proto)
27144+ return 0;
27145+ return 1;
27146+}
27147+
27148+/*
27149+ - sameaddrtype - do two addresses have the same type?
27150+ */
27151+int
27152+sameaddrtype(a, b)
27153+const ip_address *a;
27154+const ip_address *b;
27155+{
27156+ return (addrtypeof(a) == addrtypeof(b)) ? 1 : 0;
27157+}
27158+
27159+/*
27160+ - samesubnettype - do two subnets have the same type?
27161+ */
27162+int
27163+samesubnettype(a, b)
27164+const ip_subnet *a;
27165+const ip_subnet *b;
27166+{
27167+ return (subnettypeof(a) == subnettypeof(b)) ? 1 : 0;
27168+}
27169+
27170+/*
27171+ - addrinsubnet - is this address in this subnet?
27172+ */
27173+int
27174+addrinsubnet(a, s)
27175+const ip_address *a;
27176+const ip_subnet *s;
27177+{
27178+ if (addrtypeof(a) != subnettypeof(s))
27179+ return 0;
27180+ if (!samenbits(a, &s->addr, s->maskbits))
27181+ return 0;
27182+ return 1;
27183+}
27184+
27185+/*
27186+ - subnetinsubnet - is one subnet within another?
27187+ */
27188+int
27189+subnetinsubnet(a, b)
27190+const ip_subnet *a;
27191+const ip_subnet *b;
27192+{
27193+ if (subnettypeof(a) != subnettypeof(b))
27194+ return 0;
27195+ if (a->maskbits < b->maskbits) /* a is bigger than b */
27196+ return 0;
27197+ if (!samenbits(&a->addr, &b->addr, b->maskbits))
27198+ return 0;
27199+ return 1;
27200+}
27201+
27202+/*
27203+ - samenbits - do two addresses have the same first n bits?
27204+ */
27205+static int
27206+samenbits(a, b, nbits)
27207+const ip_address *a;
27208+const ip_address *b;
27209+int nbits;
27210+{
27211+ const unsigned char *ap;
27212+ const unsigned char *bp;
27213+ size_t n;
27214+ int m;
27215+
27216+ if (addrtypeof(a) != addrtypeof(b))
27217+ return 0; /* arbitrary */
27218+ n = addrbytesptr(a, &ap);
27219+ if (n == 0)
27220+ return 0; /* arbitrary */
27221+ (void) addrbytesptr(b, &bp);
27222+ if (nbits > n*8)
27223+ return 0; /* "can't happen" */
27224+
27225+ for (; nbits >= 8 && *ap == *bp; nbits -= 8, ap++, bp++)
27226+ continue;
27227+ if (nbits >= 8)
27228+ return 0;
27229+ if (nbits > 0) { /* partial byte */
27230+ m = ~(0xff >> nbits);
27231+ if ((*ap & m) != (*bp & m))
27232+ return 0;
27233+ }
27234+ return 1;
27235+}
27236diff -druN linux-noipsec/net/ipsec/libfreeswan/satoa.c linux/net/ipsec/libfreeswan/satoa.c
27237--- linux-noipsec/net/ipsec/libfreeswan/satoa.c Thu Jan 1 01:00:00 1970
27238+++ linux/net/ipsec/libfreeswan/satoa.c Sat Sep 16 08:43:47 2000
27239@@ -0,0 +1,83 @@
27240+/*
27241+ * convert from binary form of SA ID to ASCII
27242+ * Copyright (C) 1998, 1999 Henry Spencer.
27243+ *
27244+ * This library is free software; you can redistribute it and/or modify it
27245+ * under the terms of the GNU Library General Public License as published by
27246+ * the Free Software Foundation; either version 2 of the License, or (at your
27247+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
27248+ *
27249+ * This library is distributed in the hope that it will be useful, but
27250+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27251+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
27252+ * License for more details.
27253+ *
27254+ * RCSID $Id$
27255+ */
27256+#include "internal.h"
27257+#include "freeswan.h"
27258+
27259+static struct typename {
27260+ char type;
27261+ char *name;
27262+} typenames[] = {
27263+ { SA_AH, "ah" },
27264+ { SA_ESP, "esp" },
27265+ { SA_IPIP, "tun" },
27266+ { SA_COMP, "comp" },
27267+ { 0, NULL }
27268+};
27269+
27270+/*
27271+ - satoa - convert SA to ASCII "ah507@1.2.3.4"
27272+ */
27273+size_t /* space needed for full conversion */
27274+satoa(sa, format, dst, dstlen)
27275+struct sa_id sa;
27276+int format; /* character */
27277+char *dst; /* need not be valid if dstlen is 0 */
27278+size_t dstlen;
27279+{
27280+ size_t len;
27281+ int base;
27282+ struct typename *tn;
27283+ char buf[30+ADDRTOA_BUF];
27284+
27285+ switch (format) {
27286+ case 0:
27287+ base = 16; /* temporarily at least */
27288+ break;
27289+ case 'd':
27290+ base = 10;
27291+ break;
27292+ default:
27293+ return 0;
27294+ break;
27295+ }
27296+
27297+ for (tn = typenames; tn->name != NULL; tn++)
27298+ if (sa.proto == tn->type)
27299+ break;
27300+ if (tn->name == NULL)
27301+ return 0;
27302+
27303+ if (strcmp(tn->name, PASSTHROUGHTYPE) == 0 &&
27304+ sa.spi == PASSTHROUGHSPI &&
27305+ sa.dst.s_addr == PASSTHROUGHDST) {
27306+ strcpy(buf, PASSTHROUGHNAME);
27307+ len = strlen(buf);
27308+ } else {
27309+ strcpy(buf, tn->name);
27310+ len = strlen(buf);
27311+ len += ultoa(ntohl(sa.spi), base, buf+len, sizeof(buf)-len);
27312+ *(buf+len-1) = '@';
27313+ len += addrtoa(sa.dst, 0, buf+len, sizeof(buf)-len);
27314+ }
27315+
27316+ if (dst != NULL) {
27317+ if (len > dstlen)
27318+ *(buf+dstlen-1) = '\0';
27319+ strcpy(dst, buf);
27320+ }
27321+ return len;
27322+}
27323diff -druN linux-noipsec/net/ipsec/libfreeswan/satot.c linux/net/ipsec/libfreeswan/satot.c
27324--- linux-noipsec/net/ipsec/libfreeswan/satot.c Thu Jan 1 01:00:00 1970
27325+++ linux/net/ipsec/libfreeswan/satot.c Fri Sep 15 19:02:52 2000
27326@@ -0,0 +1,102 @@
27327+/*
27328+ * convert from binary form of SA ID to text
27329+ * Copyright (C) 2000 Henry Spencer.
27330+ *
27331+ * This library is free software; you can redistribute it and/or modify it
27332+ * under the terms of the GNU Library General Public License as published by
27333+ * the Free Software Foundation; either version 2 of the License, or (at your
27334+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
27335+ *
27336+ * This library is distributed in the hope that it will be useful, but
27337+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27338+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
27339+ * License for more details.
27340+ *
27341+ * RCSID $Id$
27342+ */
27343+#include "internal.h"
27344+#include "freeswan.h"
27345+
27346+static struct typename {
27347+ char type;
27348+ char *name;
27349+} typenames[] = {
27350+ { SA_AH, "ah" },
27351+ { SA_ESP, "esp" },
27352+ { SA_IPIP, "tun" },
27353+ { SA_COMP, "comp" },
27354+ { 0, NULL }
27355+};
27356+
27357+/*
27358+ - satot - convert SA to text "ah507@1.2.3.4"
27359+ */
27360+size_t /* space needed for full conversion */
27361+satot(sa, format, dst, dstlen)
27362+const ip_said *sa;
27363+int format; /* character */
27364+char *dst; /* need not be valid if dstlen is 0 */
27365+size_t dstlen;
27366+{
27367+ size_t len;
27368+ int base;
27369+ int showversion; /* use delimiter to show IP version? */
27370+ struct typename *tn;
27371+ char buf[3+1+ULTOT_BUF+ADDRTOT_BUF];
27372+
27373+ switch (format) {
27374+ case 0:
27375+ base = 16;
27376+ showversion = 1;
27377+ break;
27378+ case 'f':
27379+ base = 17;
27380+ showversion = 1;
27381+ break;
27382+ case 'x':
27383+ base = 'x';
27384+ showversion = 0;
27385+ break;
27386+ case 'd':
27387+ base = 10;
27388+ showversion = 0;
27389+ break;
27390+ default:
27391+ return 0;
27392+ break;
27393+ }
27394+
27395+ for (tn = typenames; tn->name != NULL; tn++)
27396+ if (sa->proto == tn->type)
27397+ break;
27398+ if (tn->name == NULL)
27399+ return 0;
27400+
27401+ if (strcmp(tn->name, PASSTHROUGHTYPE) == 0 &&
27402+ sa->spi == PASSTHROUGHSPI &&
27403+ isunspecaddr(&sa->dst)) {
27404+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
27405+ PASSTHROUGH4NAME :
27406+ PASSTHROUGH6NAME);
27407+ len = strlen(buf);
27408+ } else {
27409+ strcpy(buf, tn->name);
27410+ len = strlen(buf);
27411+ if (showversion) {
27412+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
27413+ ':';
27414+ len++;
27415+ *(buf+len) = '\0';
27416+ }
27417+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
27418+ *(buf+len-1) = '@';
27419+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
27420+ }
27421+
27422+ if (dst != NULL) {
27423+ if (len > dstlen)
27424+ *(buf+dstlen-1) = '\0';
27425+ strcpy(dst, buf);
27426+ }
27427+ return len;
27428+}
27429diff -druN linux-noipsec/net/ipsec/libfreeswan/subnetof.c linux/net/ipsec/libfreeswan/subnetof.c
27430--- linux-noipsec/net/ipsec/libfreeswan/subnetof.c Thu Jan 1 01:00:00 1970
27431+++ linux/net/ipsec/libfreeswan/subnetof.c Sun Apr 11 01:24:22 1999
27432@@ -0,0 +1,60 @@
27433+/*
27434+ * minor network-address manipulation utilities
27435+ * Copyright (C) 1998, 1999 Henry Spencer.
27436+ *
27437+ * This library is free software; you can redistribute it and/or modify it
27438+ * under the terms of the GNU Library General Public License as published by
27439+ * the Free Software Foundation; either version 2 of the License, or (at your
27440+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
27441+ *
27442+ * This library is distributed in the hope that it will be useful, but
27443+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27444+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
27445+ * License for more details.
27446+ *
27447+ * RCSID $Id$
27448+ */
27449+#include "internal.h"
27450+#include "freeswan.h"
27451+
27452+/*
27453+ - subnetof - given address and mask, return subnet part
27454+ */
27455+struct in_addr
27456+subnetof(addr, mask)
27457+struct in_addr addr;
27458+struct in_addr mask;
27459+{
27460+ struct in_addr result;
27461+
27462+ result.s_addr = addr.s_addr & mask.s_addr;
27463+ return result;
27464+}
27465+
27466+/*
27467+ - hostof - given address and mask, return host part
27468+ */
27469+struct in_addr
27470+hostof(addr, mask)
27471+struct in_addr addr;
27472+struct in_addr mask;
27473+{
27474+ struct in_addr result;
27475+
27476+ result.s_addr = addr.s_addr & ~mask.s_addr;
27477+ return result;
27478+}
27479+
27480+/*
27481+ - broadcastof - given (network) address and mask, return broadcast address
27482+ */
27483+struct in_addr
27484+broadcastof(addr, mask)
27485+struct in_addr addr;
27486+struct in_addr mask;
27487+{
27488+ struct in_addr result;
27489+
27490+ result.s_addr = addr.s_addr | ~mask.s_addr;
27491+ return result;
27492+}
27493diff -druN linux-noipsec/net/ipsec/libfreeswan/subnettoa.c linux/net/ipsec/libfreeswan/subnettoa.c
27494--- linux-noipsec/net/ipsec/libfreeswan/subnettoa.c Thu Jan 1 01:00:00 1970
27495+++ linux/net/ipsec/libfreeswan/subnettoa.c Sun Apr 11 01:24:22 1999
27496@@ -0,0 +1,62 @@
27497+/*
27498+ * convert binary form of subnet description to ASCII
27499+ * Copyright (C) 1998, 1999 Henry Spencer.
27500+ *
27501+ * This library is free software; you can redistribute it and/or modify it
27502+ * under the terms of the GNU Library General Public License as published by
27503+ * the Free Software Foundation; either version 2 of the License, or (at your
27504+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
27505+ *
27506+ * This library is distributed in the hope that it will be useful, but
27507+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27508+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
27509+ * License for more details.
27510+ *
27511+ * RCSID $Id$
27512+ */
27513+#include "internal.h"
27514+#include "freeswan.h"
27515+
27516+/*
27517+ - subnettoa - convert address and mask to ASCII "addr/mask"
27518+ * Output expresses the mask as a bit count if possible, else dotted decimal.
27519+ */
27520+size_t /* space needed for full conversion */
27521+subnettoa(addr, mask, format, dst, dstlen)
27522+struct in_addr addr;
27523+struct in_addr mask;
27524+int format; /* character */
27525+char *dst; /* need not be valid if dstlen is 0 */
27526+size_t dstlen;
27527+{
27528+ size_t len;
27529+ size_t rest;
27530+ int n;
27531+ char *p;
27532+
27533+ switch (format) {
27534+ case 0:
27535+ break;
27536+ default:
27537+ return 0;
27538+ break;
27539+ }
27540+
27541+ len = addrtoa(addr, 0, dst, dstlen);
27542+ if (len < dstlen) {
27543+ dst[len - 1] = '/';
27544+ p = dst + len;
27545+ rest = dstlen - len;
27546+ } else {
27547+ p = NULL;
27548+ rest = 0;
27549+ }
27550+
27551+ n = masktobits(mask);
27552+ if (n >= 0)
27553+ len += ultoa((unsigned long)n, 10, p, rest);
27554+ else
27555+ len += addrtoa(mask, 0, p, rest);
27556+
27557+ return len;
27558+}
27559diff -druN linux-noipsec/net/ipsec/libfreeswan/subnettot.c linux/net/ipsec/libfreeswan/subnettot.c
27560--- linux-noipsec/net/ipsec/libfreeswan/subnettot.c Thu Jan 1 01:00:00 1970
27561+++ linux/net/ipsec/libfreeswan/subnettot.c Fri Sep 8 20:03:45 2000
27562@@ -0,0 +1,56 @@
27563+/*
27564+ * convert binary form of subnet description to text
27565+ * Copyright (C) 2000 Henry Spencer.
27566+ *
27567+ * This library is free software; you can redistribute it and/or modify it
27568+ * under the terms of the GNU Library General Public License as published by
27569+ * the Free Software Foundation; either version 2 of the License, or (at your
27570+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
27571+ *
27572+ * This library is distributed in the hope that it will be useful, but
27573+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27574+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
27575+ * License for more details.
27576+ *
27577+ * RCSID $Id$
27578+ */
27579+#include "internal.h"
27580+#include "freeswan.h"
27581+
27582+/*
27583+ - subnettot - convert subnet to text "addr/bitcount"
27584+ */
27585+size_t /* space needed for full conversion */
27586+subnettot(sub, format, dst, dstlen)
27587+const ip_subnet *sub;
27588+int format; /* character */
27589+char *dst; /* need not be valid if dstlen is 0 */
27590+size_t dstlen;
27591+{
27592+ size_t len;
27593+ size_t rest;
27594+ char *p;
27595+
27596+ switch (format) {
27597+ case 0:
27598+ break;
27599+ default:
27600+ return 0;
27601+ break;
27602+ }
27603+
27604+ len = addrtot(&sub->addr, format, dst, dstlen);
27605+ if (len < dstlen) {
27606+ dst[len - 1] = '/';
27607+ p = dst + len;
27608+ rest = dstlen - len;
27609+ } else {
27610+ p = NULL;
27611+ rest = 0;
27612+ }
27613+
27614+
27615+ len += ultoa((unsigned long)sub->maskbits, 10, p, rest);
27616+
27617+ return len;
27618+}
27619diff -druN linux-noipsec/net/ipsec/libfreeswan/subnettypeof.c linux/net/ipsec/libfreeswan/subnettypeof.c
27620--- linux-noipsec/net/ipsec/libfreeswan/subnettypeof.c Thu Jan 1 01:00:00 1970
27621+++ linux/net/ipsec/libfreeswan/subnettypeof.c Fri Sep 8 20:03:45 2000
27622@@ -0,0 +1,109 @@
27623+/*
27624+ * extract parts of an ip_subnet, and related
27625+ * Copyright (C) 2000 Henry Spencer.
27626+ *
27627+ * This library is free software; you can redistribute it and/or modify it
27628+ * under the terms of the GNU Library General Public License as published by
27629+ * the Free Software Foundation; either version 2 of the License, or (at your
27630+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
27631+ *
27632+ * This library is distributed in the hope that it will be useful, but
27633+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27634+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
27635+ * License for more details.
27636+ *
27637+ * RCSID $Id$
27638+ */
27639+#include "internal.h"
27640+#include "freeswan.h"
27641+
27642+/*
27643+ - subnettypeof - get the address type of an ip_subnet
27644+ */
27645+int
27646+subnettypeof(src)
27647+const ip_subnet *src;
27648+{
27649+ return src->addr.u.v4.sin_family;
27650+}
27651+
27652+/*
27653+ - networkof - get the network address of a subnet
27654+ */
27655+void
27656+networkof(src, dst)
27657+const ip_subnet *src;
27658+ip_address *dst;
27659+{
27660+ *dst = src->addr;
27661+}
27662+
27663+/*
27664+ - maskof - get the mask of a subnet, as an address
27665+ */
27666+void
27667+maskof(src, dst)
27668+const ip_subnet *src;
27669+ip_address *dst;
27670+{
27671+ int b;
27672+ unsigned char buf[16];
27673+ size_t n = addrlenof(&src->addr);
27674+ unsigned char *p;
27675+
27676+ if (src->maskbits > n*8 || n > sizeof(buf))
27677+ return; /* "can't happen" */
27678+
27679+ p = buf;
27680+ for (b = src->maskbits; b >= 8; b -= 8)
27681+ *p++ = 0xff;
27682+ if (b != 0)
27683+ *p++ = (0xff << (8 - b)) & 0xff;
27684+ while (p - buf < n)
27685+ *p++ = 0;
27686+
27687+ (void) initaddr(buf, n, addrtypeof(&src->addr), dst);
27688+}
27689+
27690+/*
27691+ - masktocount - convert a mask, expressed as an address, to a bit count
27692+ */
27693+int /* -1 if not valid mask */
27694+masktocount(src)
27695+const ip_address *src;
27696+{
27697+ int b;
27698+ unsigned const char *bp;
27699+ size_t n;
27700+ unsigned const char *p;
27701+ unsigned const char *stop;
27702+
27703+ n = addrbytesptr(src, &bp);
27704+ if (n == 0)
27705+ return -1;
27706+
27707+ p = bp;
27708+ stop = bp + n;
27709+
27710+ n = 0;
27711+ while (p < stop && *p == 0xff) {
27712+ p++;
27713+ n += 8;
27714+ }
27715+ if (p < stop && *p != 0) { /* boundary in mid-byte */
27716+ b = *p++;
27717+ while (b&0x80) {
27718+ b <<= 1;
27719+ n++;
27720+ }
27721+ if ((b&0xff) != 0)
27722+ return -1; /* bits not contiguous */
27723+ }
27724+ while (p < stop && *p == 0)
27725+ p++;
27726+
27727+ if (p != stop)
27728+ return -1;
27729+
27730+ return n;
27731+}
27732diff -druN linux-noipsec/net/ipsec/libfreeswan/ttoaddr.c linux/net/ipsec/libfreeswan/ttoaddr.c
27733--- linux-noipsec/net/ipsec/libfreeswan/ttoaddr.c Thu Jan 1 01:00:00 1970
27734+++ linux/net/ipsec/libfreeswan/ttoaddr.c Mon Oct 2 23:57:20 2000
27735@@ -0,0 +1,397 @@
27736+/*
27737+ * conversion from text forms of addresses to internal ones
27738+ * Copyright (C) 2000 Henry Spencer.
27739+ *
27740+ * This library is free software; you can redistribute it and/or modify it
27741+ * under the terms of the GNU Library General Public License as published by
27742+ * the Free Software Foundation; either version 2 of the License, or (at your
27743+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
27744+ *
27745+ * This library is distributed in the hope that it will be useful, but
27746+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27747+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
27748+ * License for more details.
27749+ *
27750+ * RCSID $Id$
27751+ */
27752+#include "internal.h"
27753+#include "freeswan.h"
27754+
27755+/*
27756+ * Legal ASCII characters in a domain name. Underscore technically is not,
27757+ * but is a common misunderstanding. Non-ASCII characters are simply
27758+ * exempted from checking at the moment, to allow for UTF-8 encoded stuff;
27759+ * the purpose of this check is merely to catch blatant errors.
27760+ */
27761+static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789"
27762+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
27763+#define ISASCII(c) (((c) & 0x80) == 0)
27764+
27765+static err_t tryname(const char *, size_t, int, int, ip_address *);
27766+static err_t tryhex(const char *, size_t, int, ip_address *);
27767+static err_t trydotted(const char *, size_t, ip_address *);
27768+static err_t getbyte(const char **, const char *, int *);
27769+static err_t colon(const char *, size_t, ip_address *);
27770+static err_t getpiece(const char **, const char *, unsigned *);
27771+
27772+/*
27773+ - ttoaddr - convert text name or dotted-decimal address to binary address
27774+ */
27775+err_t /* NULL for success, else string literal */
27776+ttoaddr(src, srclen, af, dst)
27777+const char *src;
27778+size_t srclen; /* 0 means "apply strlen" */
27779+int af; /* address family */
27780+ip_address *dst;
27781+{
27782+ err_t oops;
27783+# define HEXLEN 10 /* strlen("0x11223344") */
27784+ int nultermd;
27785+
27786+ if (srclen == 0) {
27787+ srclen = strlen(src);
27788+ if (srclen == 0)
27789+ return "empty string";
27790+ nultermd = 1;
27791+ } else
27792+ nultermd = 0; /* at least, not *known* to be terminated */
27793+
27794+ if (af == AF_INET && srclen == HEXLEN && *src == '0') {
27795+ if (*(src+1) == 'x' || *(src+1) == 'X')
27796+ return tryhex(src+2, srclen-2, 'x', dst);
27797+ if (*(src+1) == 'h' || *(src+1) == 'H')
27798+ return tryhex(src+2, srclen-2, 'h', dst);
27799+ }
27800+
27801+ if (memchr(src, ':', srclen) != NULL) {
27802+ if (af != AF_INET6)
27803+ return "non-ipv6 address may not contain `:'";
27804+ return colon(src, srclen, dst);
27805+ }
27806+
27807+ if (af == AF_INET) {
27808+ oops = trydotted(src, srclen, dst);
27809+ if (oops == NULL)
27810+ return NULL; /* it worked */
27811+ if (*oops != '?')
27812+ return oops; /* probably meant as d-d */
27813+ }
27814+
27815+ return tryname(src, srclen, nultermd, af, dst);
27816+}
27817+
27818+/*
27819+ - tnatoaddr - convert text numeric address (only) to binary address
27820+ */
27821+err_t /* NULL for success, else string literal */
27822+tnatoaddr(src, srclen, af, dst)
27823+const char *src;
27824+size_t srclen; /* 0 means "apply strlen" */
27825+int af; /* address family */
27826+ip_address *dst;
27827+{
27828+ err_t oops;
27829+
27830+ if (srclen == 0) {
27831+ srclen = strlen(src);
27832+ if (srclen == 0)
27833+ return "empty string";
27834+ }
27835+
27836+ switch (af) {
27837+ case AF_INET6:
27838+ return colon(src, srclen, dst);
27839+ break;
27840+ case AF_INET:
27841+ oops = trydotted(src, srclen, dst);
27842+ if (oops == NULL)
27843+ return NULL; /* it worked */
27844+ if (*oops != '?')
27845+ return oops; /* probably meant as d-d */
27846+ return "does not appear to be numeric address";
27847+ break;
27848+ default:
27849+ return "unknown address family in tnatoaddr";
27850+ break;
27851+ }
27852+}
27853+
27854+/*
27855+ - tryname - try it as a name
27856+ * Slightly complicated by lack of reliable NUL termination in source.
27857+ */
27858+static err_t
27859+tryname(src, srclen, nultermd, af, dst)
27860+const char *src;
27861+size_t srclen;
27862+int nultermd; /* is it known to be NUL-terminated? */
27863+int af;
27864+ip_address *dst;
27865+{
27866+ struct hostent *h;
27867+ struct netent *ne = NULL;
27868+ char namebuf[100]; /* enough for most DNS names */
27869+ const char *cp;
27870+ char *p = namebuf;
27871+ size_t n;
27872+
27873+ for (cp = src, n = srclen; n > 0; cp++, n--)
27874+ if (ISASCII(*cp) && strchr(namechars, *cp) == NULL)
27875+ return "illegal (non-DNS-name) character in name";
27876+
27877+ if (nultermd)
27878+ cp = src;
27879+ else {
27880+ if (srclen+1 > sizeof(namebuf)) {
27881+ p = (char *) MALLOC(srclen+1);
27882+ if (p == NULL)
27883+ return "unable to get temporary space for name";
27884+ }
27885+ p[0] = '\0'; /* strncpy semantics are wrong */
27886+ strncat(p, src, srclen);
27887+ cp = (const char *)p;
27888+ }
27889+
27890+ h = gethostbyname2(cp, af);
27891+ if (h == NULL && af == AF_INET)
27892+ ne = getnetbyname(cp);
27893+ if (p != namebuf)
27894+ FREE(p);
27895+ if (h == NULL && ne == NULL)
27896+ return "does not look numeric and name lookup failed";
27897+
27898+ if (h != NULL) {
27899+ if (h->h_addrtype != af)
27900+ return "address-type mismatch from gethostbyname2!!!";
27901+ return initaddr((unsigned char *)h->h_addr, h->h_length, af, dst);
27902+ } else {
27903+ if (ne->n_addrtype != af)
27904+ return "address-type mismatch from getnetbyname!!!";
27905+ ne->n_net = htonl(ne->n_net);
27906+ return initaddr((unsigned char *)&ne->n_net, sizeof(ne->n_net),
27907+ af, dst);
27908+ }
27909+}
27910+
27911+/*
27912+ - tryhex - try conversion as an eight-digit hex number (AF_INET only)
27913+ */
27914+static err_t
27915+tryhex(src, srclen, flavor, dst)
27916+const char *src;
27917+size_t srclen; /* should be 8 */
27918+int flavor; /* 'x' for network order, 'h' for host order */
27919+ip_address *dst;
27920+{
27921+ err_t oops;
27922+ unsigned long ul;
27923+ union {
27924+ uint32_t addr;
27925+ unsigned char buf[4];
27926+ } u;
27927+
27928+ if (srclen != 8)
27929+ return "internal error, tryhex called with bad length";
27930+
27931+ oops = ttoul(src, srclen, 16, &ul);
27932+ if (oops != NULL)
27933+ return oops;
27934+
27935+ u.addr = (flavor == 'h') ? ul : htonl(ul);
27936+ return initaddr(u.buf, sizeof(u.buf), AF_INET, dst);
27937+}
27938+
27939+/*
27940+ - trydotted - try conversion as dotted decimal (AF_INET only)
27941+ *
27942+ * If the first char of a complaint is '?', that means "didn't look like
27943+ * dotted decimal at all".
27944+ */
27945+static err_t
27946+trydotted(src, srclen, dst)
27947+const char *src;
27948+size_t srclen;
27949+ip_address *dst;
27950+{
27951+ const char *stop = src + srclen; /* just past end */
27952+ int byte;
27953+ err_t oops;
27954+# define NBYTES 4
27955+ unsigned char buf[NBYTES];
27956+ int i;
27957+
27958+ memset(buf, 0, sizeof(buf));
27959+ for (i = 0; i < NBYTES && src < stop; i++) {
27960+ oops = getbyte(&src, stop, &byte);
27961+ if (oops != NULL) {
27962+ if (*oops != '?')
27963+ return oops; /* bad number */
27964+ if (i > 1)
27965+ return oops+1; /* failed number */
27966+ return oops; /* with leading '?' */
27967+ }
27968+ buf[i] = byte;
27969+ if (i < 3 && src < stop && *src++ != '.') {
27970+ if (i == 0)
27971+ return "?syntax error in dotted-decimal address";
27972+ else
27973+ return "syntax error in dotted-decimal address";
27974+ }
27975+ }
27976+ if (src != stop)
27977+ return "extra garbage on end of dotted-decimal address";
27978+
27979+ return initaddr(buf, sizeof(buf), AF_INET, dst);
27980+}
27981+
27982+/*
27983+ - getbyte - try to scan a byte in dotted decimal
27984+ * A subtlety here is that all this arithmetic on ASCII digits really is
27985+ * highly portable -- ANSI C guarantees that digits 0-9 are contiguous.
27986+ * It's easier to just do it ourselves than set up for a call to ttoul().
27987+ *
27988+ * If the first char of a complaint is '?', that means "didn't look like a
27989+ * number at all".
27990+ */
27991+err_t
27992+getbyte(srcp, stop, retp)
27993+const char **srcp; /* *srcp is updated */
27994+const char *stop; /* first untouchable char */
27995+int *retp; /* return-value pointer */
27996+{
27997+ char c;
27998+ const char *p;
27999+ int no;
28000+
28001+ if (*srcp >= stop)
28002+ return "?empty number in dotted-decimal address";
28003+
28004+ no = 0;
28005+ p = *srcp;
28006+ while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') {
28007+ no = no*10 + (c - '0');
28008+ p++;
28009+ }
28010+ if (p == *srcp)
28011+ return "?non-numeric component in dotted-decimal address";
28012+ *srcp = p;
28013+ if (no > 255)
28014+ return "byte overflow in dotted-decimal address";
28015+ *retp = no;
28016+ return NULL;
28017+}
28018+
28019+/*
28020+ - colon - convert IPv6 "numeric" address
28021+ */
28022+static err_t
28023+colon(src, srclen, dst)
28024+const char *src;
28025+size_t srclen; /* known to be >0 */
28026+ip_address *dst;
28027+{
28028+ const char *stop = src + srclen; /* just past end */
28029+ unsigned piece;
28030+ int gapat; /* where was empty piece seen */
28031+ err_t oops;
28032+# define NPIECES 8
28033+ unsigned char buf[NPIECES*2]; /* short may have wrong byte order */
28034+ int i;
28035+ int j;
28036+# define IT "IPv6 numeric address"
28037+ int naftergap;
28038+
28039+ /* leading or trailing :: becomes single empty field */
28040+ if (*src == ':') { /* legal only if leading :: */
28041+ if (srclen == 1 || *(src+1) != ':')
28042+ return "illegal leading `:' in " IT;
28043+ if (srclen == 2) {
28044+ unspecaddr(AF_INET6, dst);
28045+ return NULL;
28046+ }
28047+ src++; /* past first but not second */
28048+ srclen--;
28049+ }
28050+ if (*(stop-1) == ':') { /* legal only if trailing :: */
28051+ if (srclen == 1 || *(stop-2) != ':')
28052+ return "illegal trailing `:' in " IT;
28053+ srclen--; /* leave one */
28054+ }
28055+
28056+ gapat = -1;
28057+ for (i = 0; i < NPIECES && src < stop; i++) {
28058+ oops = getpiece(&src, stop, &piece);
28059+ if (oops != NULL && *oops == ':') { /* empty field */
28060+ if (gapat >= 0)
28061+ return "more than one :: in " IT;
28062+ gapat = i;
28063+ } else if (oops != NULL)
28064+ return oops;
28065+ buf[2*i] = piece >> 8;
28066+ buf[2*i + 1] = piece & 0xff;
28067+ if (i < NPIECES-1) { /* there should be more input */
28068+ if (src == stop && gapat < 0)
28069+ return IT " ends prematurely";
28070+ if (src != stop && *src++ != ':')
28071+ return "syntax error in " IT;
28072+ }
28073+ }
28074+ if (src != stop)
28075+ return "extra garbage on end of " IT;
28076+
28077+ if (gapat < 0 && i < NPIECES) /* should have been caught earlier */
28078+ return "incomplete " IT " (internal error)";
28079+ if (gapat >= 0 && i == NPIECES)
28080+ return "non-abbreviating empty field in " IT;
28081+ if (gapat >= 0) {
28082+ naftergap = i - (gapat + 1);
28083+ for (i--, j = NPIECES-1; naftergap > 0; i--, j--, naftergap--) {
28084+ buf[2*j] = buf[2*i];
28085+ buf[2*j + 1] = buf[2*i + 1];
28086+ }
28087+ for (; j >= gapat; j--)
28088+ buf[2*j] = buf[2*j + 1] = 0;
28089+ }
28090+
28091+ return initaddr(buf, sizeof(buf), AF_INET6, dst);
28092+}
28093+
28094+/*
28095+ - getpiece - try to scan one 16-bit piece of an IPv6 address
28096+ */
28097+err_t /* ":" means "empty field seen" */
28098+getpiece(srcp, stop, retp)
28099+const char **srcp; /* *srcp is updated */
28100+const char *stop; /* first untouchable char */
28101+unsigned *retp; /* return-value pointer */
28102+{
28103+ const char *p;
28104+# define NDIG 4
28105+ int d;
28106+ unsigned long ret;
28107+ err_t oops;
28108+
28109+ if (*srcp >= stop || **srcp == ':') { /* empty field */
28110+ *retp = 0;
28111+ return ":";
28112+ }
28113+
28114+ p = *srcp;
28115+ d = 0;
28116+ while (p < stop && d < NDIG && isxdigit(*p)) {
28117+ p++;
28118+ d++;
28119+ }
28120+ if (d == 0)
28121+ return "non-hex field in IPv6 numeric address";
28122+ if (p < stop && d == NDIG && isxdigit(*p))
28123+ return "field in IPv6 numeric address longer than 4 hex digits";
28124+
28125+ oops = ttoul(*srcp, d, 16, &ret);
28126+ if (oops != NULL) /* shouldn't happen, really... */
28127+ return oops;
28128+
28129+ *srcp = p;
28130+ *retp = ret;
28131+ return NULL;
28132+}
28133diff -druN linux-noipsec/net/ipsec/libfreeswan/ttodata.c linux/net/ipsec/libfreeswan/ttodata.c
28134--- linux-noipsec/net/ipsec/libfreeswan/ttodata.c Thu Jan 1 01:00:00 1970
28135+++ linux/net/ipsec/libfreeswan/ttodata.c Fri Aug 18 17:09:07 2000
28136@@ -0,0 +1,576 @@
28137+/*
28138+ * convert from text form of arbitrary data (e.g., keys) to binary
28139+ * Copyright (C) 2000 Henry Spencer.
28140+ *
28141+ * This library is free software; you can redistribute it and/or modify it
28142+ * under the terms of the GNU Library General Public License as published by
28143+ * the Free Software Foundation; either version 2 of the License, or (at your
28144+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
28145+ *
28146+ * This library is distributed in the hope that it will be useful, but
28147+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28148+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
28149+ * License for more details.
28150+ *
28151+ * RCSID $Id$
28152+ */
28153+#include "internal.h"
28154+#include "freeswan.h"
28155+
28156+/* converters */
28157+static int unhex(const char *, char *, size_t);
28158+static int unb64(const char *, char *, size_t);
28159+static int untext(const char *, char *, size_t);
28160+
28161+/* internal error codes for converters */
28162+#define BADCHAR (-1) /* invalid character */
28163+#define SHORT (-2) /* string ended prematurely */
28164+#define BADPAD (-3) /* bad base64 padding */
28165+
28166+/*
28167+ - ttodata - convert text to data
28168+ * If some of this looks slightly odd, it's because it has changed
28169+ * repeatedly (from the original atodata()) without a major rewrite.
28170+ */
28171+const char * /* NULL for success, else string literal */
28172+ttodata(src, srclen, base, dst, dstlen, lenp)
28173+const char *src;
28174+size_t srclen; /* 0 means apply strlen() */
28175+int base; /* 0 means figure it out */
28176+char *dst; /* need not be valid if dstlen is 0 */
28177+size_t dstlen;
28178+size_t *lenp; /* where to record length (NULL is nowhere) */
28179+{
28180+ size_t ingroup; /* number of input bytes converted at once */
28181+ char buf[4]; /* output from conversion */
28182+ int nbytes; /* size of output */
28183+ int (*decode)(const char *, char *, size_t);
28184+ char *stop;
28185+ int ndone;
28186+ int i;
28187+ int underscoreok;
28188+
28189+ if (srclen == 0)
28190+ srclen = strlen(src);
28191+ if (dstlen == 0)
28192+ dst = buf; /* point it somewhere valid */
28193+ stop = dst + dstlen;
28194+
28195+ if (base == 0) {
28196+ if (srclen < 2)
28197+ return "input too short to be valid";
28198+ if (*src++ != '0')
28199+ return "input does not begin with format prefix";
28200+ switch (*src++) {
28201+ case 'x':
28202+ case 'X':
28203+ base = 16;
28204+ break;
28205+ case 's':
28206+ case 'S':
28207+ base = 64;
28208+ break;
28209+ case 't':
28210+ case 'T':
28211+ base = 256;
28212+ break;
28213+ default:
28214+ return "unknown format prefix";
28215+ break;
28216+ }
28217+ srclen -= 2;
28218+ }
28219+ switch (base) {
28220+ case 16:
28221+ ingroup = 2;
28222+ decode = unhex;
28223+ underscoreok = 1;
28224+ break;
28225+ case 64:
28226+ ingroup = 4;
28227+ decode = unb64;
28228+ underscoreok = 0;
28229+ break;
28230+ case 256:
28231+ ingroup = 1;
28232+ decode = untext;
28233+ underscoreok = 0;
28234+ break;
28235+ default:
28236+ return "unknown base";
28237+ break;
28238+ }
28239+
28240+ /* proceed */
28241+ ndone = 0;
28242+ while (srclen >= ingroup) {
28243+ nbytes = (*decode)(src, buf, sizeof(buf));
28244+ switch (nbytes) {
28245+ case BADCHAR:
28246+ return "unknown character in input";
28247+ break;
28248+ case SHORT:
28249+ return "input ends prematurely, perhaps truncated";
28250+ break;
28251+ case BADPAD:
28252+ return "non-zero padding in base64 input";
28253+ break;
28254+ }
28255+ if (nbytes <= 0)
28256+ return "unknown internal error";
28257+ for (i = 0; i < nbytes; i++) {
28258+ if (dst < stop)
28259+ *dst++ = buf[i];
28260+ ndone++;
28261+ }
28262+ src += ingroup;
28263+ srclen -= ingroup;
28264+ if (underscoreok && srclen > 1 && *src == '_') {
28265+ /* srclen > 1 means not last character */
28266+ src++;
28267+ srclen--;
28268+ }
28269+ }
28270+ if (srclen != 0)
28271+ return "input ends in mid-byte, perhaps truncated";
28272+ if (ndone == 0)
28273+ return "no data bytes specified by input";
28274+ if (lenp != NULL)
28275+ *lenp = ndone;
28276+ return NULL;
28277+}
28278+
28279+/*
28280+ - atodata - convert ASCII to data
28281+ * backward-compatibility interface
28282+ */
28283+size_t /* 0 for failure, true length for success */
28284+atodata(src, srclen, dst, dstlen)
28285+const char *src;
28286+size_t srclen;
28287+char *dst;
28288+size_t dstlen;
28289+{
28290+ size_t len;
28291+ const char *err;
28292+
28293+ err = ttodata(src, srclen, 0, dst, dstlen, &len);
28294+ if (err != NULL)
28295+ return 0;
28296+ return len;
28297+}
28298+
28299+/*
28300+ - atobytes - convert ASCII to data bytes
28301+ * another backward-compatibility interface
28302+ */
28303+const char *
28304+atobytes(src, srclen, dst, dstlen, lenp)
28305+const char *src;
28306+size_t srclen;
28307+char *dst;
28308+size_t dstlen;
28309+size_t *lenp;
28310+{
28311+ return ttodata(src, srclen, 0, dst, dstlen, lenp);
28312+}
28313+
28314+/*
28315+ - unhex - convert two ASCII hex digits to byte
28316+ */
28317+static int /* number of result bytes, or error code */
28318+unhex(src, dst, dstlen)
28319+const char *src; /* known to be full length */
28320+char *dst;
28321+size_t dstlen; /* not large enough is a failure */
28322+{
28323+ char *p;
28324+ unsigned byte;
28325+ static char hex[] = "0123456789abcdef";
28326+
28327+ if (dstlen < 1)
28328+ return SHORT;
28329+
28330+ p = strchr(hex, *src);
28331+ if (p == NULL)
28332+ p = strchr(hex, tolower(*src));
28333+ if (p == NULL)
28334+ return BADCHAR;
28335+ byte = (p - hex) << 4;
28336+ src++;
28337+
28338+ p = strchr(hex, *src);
28339+ if (p == NULL)
28340+ p = strchr(hex, tolower(*src));
28341+ if (p == NULL)
28342+ return BADCHAR;
28343+ byte |= (p - hex);
28344+
28345+ *dst = byte;
28346+ return 1;
28347+}
28348+
28349+/*
28350+ - unb64 - convert four ASCII base64 digits to three bytes
28351+ * Note that a base64 digit group is padded out with '=' if it represents
28352+ * less than three bytes: one byte is dd==, two is ddd=, three is dddd.
28353+ */
28354+static int /* number of result bytes, or error code */
28355+unb64(src, dst, dstlen)
28356+const char *src; /* known to be full length */
28357+char *dst;
28358+size_t dstlen;
28359+{
28360+ char *p;
28361+ unsigned byte1;
28362+ unsigned byte2;
28363+ static char base64[] =
28364+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
28365+
28366+ if (dstlen < 3)
28367+ return SHORT;
28368+
28369+ p = strchr(base64, *src++);
28370+ if (p == NULL)
28371+ return BADCHAR;
28372+ byte1 = (p - base64) << 2; /* first six bits */
28373+
28374+ p = strchr(base64, *src++);
28375+ if (p == NULL)
28376+ return BADCHAR;
28377+ byte2 = p - base64; /* next six: two plus four */
28378+ *dst++ = byte1 | (byte2 >> 4);
28379+ byte1 = (byte2 & 0xf) << 4;
28380+
28381+ p = strchr(base64, *src++);
28382+ if (p == NULL) {
28383+ if (*(src-1) == '=' && *src == '=') {
28384+ if (byte1 != 0) /* bad padding */
28385+ return BADPAD;
28386+ return 1;
28387+ }
28388+ return BADCHAR;
28389+ }
28390+ byte2 = p - base64; /* next six: four plus two */
28391+ *dst++ = byte1 | (byte2 >> 2);
28392+ byte1 = (byte2 & 0x3) << 6;
28393+
28394+ p = strchr(base64, *src++);
28395+ if (p == NULL) {
28396+ if (*(src-1) == '=') {
28397+ if (byte1 != 0) /* bad padding */
28398+ return BADPAD;
28399+ return 2;
28400+ }
28401+ return BADCHAR;
28402+ }
28403+ byte2 = p - base64; /* last six */
28404+ *dst++ = byte1 | byte2;
28405+ return 3;
28406+}
28407+
28408+/*
28409+ - untext - convert one ASCII character to byte
28410+ */
28411+static int /* number of result bytes, or error code */
28412+untext(src, dst, dstlen)
28413+const char *src; /* known to be full length */
28414+char *dst;
28415+size_t dstlen; /* not large enough is a failure */
28416+{
28417+ if (dstlen < 1)
28418+ return SHORT;
28419+
28420+ *dst = *src;
28421+ return 1;
28422+}
28423+
28424+
28425+
28426+#ifdef TTODATA_MAIN
28427+
28428+#include <stdio.h>
28429+
28430+void regress();
28431+void hexout();
28432+
28433+/*
28434+ - main - convert first argument to hex, or run regression
28435+ */
28436+int
28437+main(argc, argv)
28438+int argc;
28439+char *argv[];
28440+{
28441+ char buf[1024];
28442+ char buf2[1024];
28443+ size_t n;
28444+ size_t i;
28445+ char *p = buf;
28446+ char *p2 = buf2;
28447+ char *pgm = argv[0];
28448+ const char *oops;
28449+
28450+ if (argc < 2) {
28451+ fprintf(stderr, "Usage: %s {0x<hex>|0s<base64>|-r}\n", pgm);
28452+ exit(2);
28453+ }
28454+
28455+ if (strcmp(argv[1], "-r") == 0) {
28456+ regress(pgm); /* should not return */
28457+ fprintf(stderr, "%s: regress() returned?!?\n", pgm);
28458+ exit(1);
28459+ }
28460+
28461+ oops = ttodata(argv[1], 0, 0, buf, sizeof(buf), &n);
28462+ if (oops != NULL) {
28463+ fprintf(stderr, "%s: ttodata error `%s' in `%s'\n", pgm,
28464+ oops, argv[1]);
28465+ exit(1);
28466+ }
28467+
28468+ if (n > sizeof(buf)) {
28469+ p = (char *)malloc((size_t)n);
28470+ if (p == NULL) {
28471+ fprintf(stderr,
28472+ "%s: unable to malloc %d bytes for result\n",
28473+ pgm, n);
28474+ exit(1);
28475+ }
28476+ oops = ttodata(argv[1], 0, 0, p, n, &n);
28477+ if (oops != NULL) {
28478+ fprintf(stderr, "%s: error `%s' in ttodata retry?!?\n",
28479+ pgm, oops);
28480+ exit(1);
28481+ }
28482+ }
28483+
28484+ hexout(p, n, stdout);
28485+ printf("\n");
28486+
28487+ i = datatot(buf, n, 'h', buf2, sizeof(buf2));
28488+ if (i == 0) {
28489+ fprintf(stderr, "%s: datatot reports error in `%s'\n", pgm,
28490+ argv[1]);
28491+ exit(1);
28492+ }
28493+
28494+ if (i > sizeof(buf2)) {
28495+ p2 = (char *)malloc((size_t)i);
28496+ if (p == NULL) {
28497+ fprintf(stderr,
28498+ "%s: unable to malloc %d bytes for result\n",
28499+ pgm, i);
28500+ exit(1);
28501+ }
28502+ i = datatot(buf, n, 'h', p2, i);
28503+ if (i == 0) {
28504+ fprintf(stderr, "%s: error in datatoa retry?!?\n", pgm);
28505+ exit(1);
28506+ }
28507+ }
28508+
28509+ printf("%s\n", p2);
28510+
28511+ exit(0);
28512+}
28513+
28514+/*
28515+ - hexout - output an arbitrary-length string in hex
28516+ */
28517+void
28518+hexout(s, len, f)
28519+const char *s;
28520+size_t len;
28521+FILE *f;
28522+{
28523+ size_t i;
28524+
28525+ fprintf(f, "0x");
28526+ for (i = 0; i < len; i++)
28527+ fprintf(f, "%02x", (unsigned char)s[i]);
28528+}
28529+
28530+struct artab {
28531+ int base;
28532+ char *ascii; /* NULL for end */
28533+ char *data; /* NULL for error expected */
28534+} atodatatab[] = {
28535+ 0, "", NULL,
28536+ 0, "0", NULL,
28537+ 0, "0x", NULL,
28538+ 0, "0xa", NULL,
28539+ 0, "0xab", "\xab",
28540+ 0, "0xabc", NULL,
28541+ 0, "0xabcd", "\xab\xcd",
28542+ 0, "0x0123456789", "\x01\x23\x45\x67\x89",
28543+ 0, "0x01x", NULL,
28544+ 0, "0xabcdef", "\xab\xcd\xef",
28545+ 0, "0xABCDEF", "\xab\xcd\xef",
28546+ 0, "0XaBc0eEd81f", "\xab\xc0\xee\xd8\x1f",
28547+ 0, "0XaBc0_eEd8", "\xab\xc0\xee\xd8",
28548+ 0, "0XaBc0_", NULL,
28549+ 0, "0X_aBc0", NULL,
28550+ 0, "0Xa_Bc0", NULL,
28551+ 16, "aBc0_eEd8", "\xab\xc0\xee\xd8",
28552+ 0, "0s", NULL,
28553+ 0, "0sA", NULL,
28554+ 0, "0sBA", NULL,
28555+ 0, "0sCBA", NULL,
28556+ 0, "0sDCBA", "\x0c\x20\x40",
28557+ 0, "0SDCBA", "\x0c\x20\x40",
28558+ 0, "0sDA==", "\x0c",
28559+ 0, "0sDC==", NULL,
28560+ 0, "0sDCA=", "\x0c\x20",
28561+ 0, "0sDCB=", NULL,
28562+ 0, "0sDCAZ", "\x0c\x20\x19",
28563+ 0, "0sDCAa", "\x0c\x20\x1a",
28564+ 0, "0sDCAz", "\x0c\x20\x33",
28565+ 0, "0sDCA0", "\x0c\x20\x34",
28566+ 0, "0sDCA9", "\x0c\x20\x3d",
28567+ 0, "0sDCA+", "\x0c\x20\x3e",
28568+ 0, "0sDCA/", "\x0c\x20\x3f",
28569+ 0, "0sAbraCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe",
28570+ 64, "AbraCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe",
28571+ 0, "0t", NULL,
28572+ 0, "0tabc_xyz", "abc_xyz",
28573+ 256, "abc_xyz", "abc_xyz",
28574+ 0, NULL, NULL,
28575+};
28576+
28577+struct drtab {
28578+ char *data; /* input; NULL for end */
28579+ char format;
28580+ int buflen; /* -1 means big buffer */
28581+ int outlen; /* -1 means strlen(ascii)+1 */
28582+ char *ascii; /* NULL for error expected */
28583+} datatoatab[] = {
28584+ "", 'x', -1, -1, NULL,
28585+ "", 'X', -1, -1, NULL,
28586+ "", 'n', -1, -1, NULL,
28587+ "0", 'x', -1, -1, "0x30",
28588+ "0", 'x', 0, 5, "---",
28589+ "0", 'x', 1, 5, "",
28590+ "0", 'x', 2, 5, "0",
28591+ "0", 'x', 3, 5, "0x",
28592+ "0", 'x', 4, 5, "0x3",
28593+ "0", 'x', 5, 5, "0x30",
28594+ "0", 'x', 6, 5, "0x30",
28595+ "\xab\xcd", 'x', -1, -1, "0xabcd",
28596+ "\x01\x23\x45\x67\x89", 'x', -1, -1, "0x0123456789",
28597+ "\xab\xcd\xef", 'x', -1, -1, "0xabcdef",
28598+ "\xab\xc0\xee\xd8\x1f", 'x', -1, -1, "0xabc0eed81f",
28599+ "\x01\x02", 'h', -1, -1, "0x0102",
28600+ "\x01\x02\x03\x04\x05\x06", 'h', -1, -1, "0x01020304_0506",
28601+ "\xab\xc0\xee\xd8\x1f", 16, -1, -1, "abc0eed81f",
28602+ "\x0c\x20\x40", 's', -1, -1, "0sDCBA",
28603+ "\x0c\x20\x40", 's', 0, 7, "---",
28604+ "\x0c\x20\x40", 's', 1, 7, "",
28605+ "\x0c\x20\x40", 's', 2, 7, "0",
28606+ "\x0c\x20\x40", 's', 3, 7, "0s",
28607+ "\x0c\x20\x40", 's', 4, 7, "0sD",
28608+ "\x0c\x20\x40", 's', 5, 7, "0sDC",
28609+ "\x0c\x20\x40", 's', 6, 7, "0sDCB",
28610+ "\x0c\x20\x40", 's', 7, 7, "0sDCBA",
28611+ "\x0c\x20\x40", 's', 8, 7, "0sDCBA",
28612+ "\x0c", 's', -1, -1, "0sDA==",
28613+ "\x0c\x20", 's', -1, -1, "0sDCA=",
28614+ "\x0c\x20\x19", 's', -1, -1, "0sDCAZ",
28615+ "\x0c\x20\x1a", 's', -1, -1, "0sDCAa",
28616+ "\x0c\x20\x33", 's', -1, -1, "0sDCAz",
28617+ "\x0c\x20\x34", 's', -1, -1, "0sDCA0",
28618+ "\x0c\x20\x3d", 's', -1, -1, "0sDCA9",
28619+ "\x0c\x20\x3e", 's', -1, -1, "0sDCA+",
28620+ "\x0c\x20\x3f", 's', -1, -1, "0sDCA/",
28621+ "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 's', -1, -1, "0sAbraCadabra+",
28622+ "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 64, -1, -1, "AbraCadabra+",
28623+ NULL, 'x', -1, -1, NULL,
28624+};
28625+
28626+/*
28627+ - regress - regression-test ttodata() and datatot()
28628+ */
28629+void /* should not return at all, in fact */
28630+regress(pgm)
28631+char *pgm;
28632+{
28633+ struct artab *r;
28634+ struct drtab *dr;
28635+ char buf[100];
28636+ size_t n;
28637+ int status = 0;
28638+ size_t should;
28639+ const char *oops;
28640+
28641+ for (r = atodatatab; r->ascii != NULL; r++) {
28642+ oops = ttodata(r->ascii, 0, r->base, buf, sizeof(buf), &n);
28643+ if (oops != NULL && r->data == NULL)
28644+ {} /* error expected */
28645+ else if (oops != NULL) {
28646+ printf("`%s' gave error `%s', expecting %d `", r->ascii,
28647+ oops, strlen(r->data));
28648+ hexout(r->data, strlen(r->data), stdout);
28649+ printf("'\n");
28650+ status = 1;
28651+ } else if (r->data == NULL) {
28652+ printf("`%s' gave %d `", r->ascii, n);
28653+ hexout(buf, n, stdout);
28654+ printf("', expecting error\n");
28655+ status = 1;
28656+ } else if (n != strlen(r->data)) {
28657+ printf("length wrong in `%s': got %d `", r->ascii, n);
28658+ hexout(buf, n, stdout);
28659+ printf("', expecting %d `", strlen(r->data));
28660+ hexout(r->data, strlen(r->data), stdout);
28661+ printf("'\n");
28662+ status = 1;
28663+ } else if (memcmp(buf, r->data, n) != 0) {
28664+ printf("`%s' gave %d `", r->ascii, n);
28665+ hexout(buf, n, stdout);
28666+ printf("', expecting %d `", strlen(r->data));
28667+ hexout(r->data, strlen(r->data), stdout);
28668+ printf("'\n");
28669+ status = 1;
28670+ }
28671+ fflush(stdout);
28672+ }
28673+ for (dr = datatoatab; dr->data != NULL; dr++) {
28674+ strcpy(buf, "---");
28675+ n = datatot(dr->data, strlen(dr->data), dr->format, buf,
28676+ (dr->buflen == -1) ? sizeof(buf) : dr->buflen);
28677+ should = (dr->ascii == NULL) ? 0 : strlen(dr->ascii) + 1;
28678+ if (dr->outlen != -1)
28679+ should = dr->outlen;
28680+ if (n == 0 && dr->ascii == NULL)
28681+ {} /* error expected */
28682+ else if (n == 0) {
28683+ printf("`");
28684+ hexout(dr->data, strlen(dr->data), stdout);
28685+ printf("' %c gave error, expecting %d `%s'\n",
28686+ dr->format, should, dr->ascii);
28687+ status = 1;
28688+ } else if (dr->ascii == NULL) {
28689+ printf("`");
28690+ hexout(dr->data, strlen(dr->data), stdout);
28691+ printf("' %c gave %d `%.*s', expecting error\n",
28692+ dr->format, n, n, buf);
28693+ status = 1;
28694+ } else if (n != should) {
28695+ printf("length wrong in `");
28696+ hexout(dr->data, strlen(dr->data), stdout);
28697+ printf("': got %d `%s'", n, buf);
28698+ printf(", expecting %d `%s'\n", should, dr->ascii);
28699+ status = 1;
28700+ } else if (strcmp(buf, dr->ascii) != 0) {
28701+ printf("`");
28702+ hexout(dr->data, strlen(dr->data), stdout);
28703+ printf("' gave %d `%s'", n, buf);
28704+ printf(", expecting %d `%s'\n", should, dr->ascii);
28705+ status = 1;
28706+ }
28707+ fflush(stdout);
28708+ }
28709+ exit(status);
28710+}
28711+
28712+#endif /* TTODATA_MAIN */
28713diff -druN linux-noipsec/net/ipsec/libfreeswan/ttosa.c linux/net/ipsec/libfreeswan/ttosa.c
28714--- linux-noipsec/net/ipsec/libfreeswan/ttosa.c Thu Jan 1 01:00:00 1970
28715+++ linux/net/ipsec/libfreeswan/ttosa.c Fri Sep 15 21:20:33 2000
28716@@ -0,0 +1,250 @@
28717+/*
28718+ * convert from text form of SA ID to binary
28719+ * Copyright (C) 2000 Henry Spencer.
28720+ *
28721+ * This library is free software; you can redistribute it and/or modify it
28722+ * under the terms of the GNU Library General Public License as published by
28723+ * the Free Software Foundation; either version 2 of the License, or (at your
28724+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
28725+ *
28726+ * This library is distributed in the hope that it will be useful, but
28727+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28728+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
28729+ * License for more details.
28730+ *
28731+ * RCSID $Id$
28732+ */
28733+#include "internal.h"
28734+#include "freeswan.h"
28735+
28736+static struct satype {
28737+ char *prefix;
28738+ size_t prelen; /* strlen(prefix) */
28739+ int proto;
28740+} satypes[] = {
28741+ { "ah", 2, SA_AH },
28742+ { "esp", 3, SA_ESP },
28743+ { "tun", 3, SA_IPIP },
28744+ { "comp", 4, SA_COMP },
28745+ { NULL, 0, 0, }
28746+};
28747+
28748+/*
28749+ - ttosa - convert text "ah507@10.0.0.1" to SA identifier
28750+ */
28751+err_t /* NULL for success, else string literal */
28752+ttosa(src, srclen, sa)
28753+const char *src;
28754+size_t srclen; /* 0 means "apply strlen" */
28755+ip_said *sa;
28756+{
28757+ const char *at;
28758+ const char *addr;
28759+ size_t alen;
28760+ const char *spi = NULL;
28761+ struct satype *sat;
28762+ unsigned long ul;
28763+ const char *oops;
28764+# define MINLEN 5 /* ah0@0 is as short as it can get */
28765+ static char ptname[] = PASSTHROUGHNAME;
28766+# define PTNLEN (sizeof(ptname)-1) /* -1 for NUL */
28767+ static char pt4name[] = PASSTHROUGH4NAME;
28768+# define PT4NLEN (sizeof(pt4name)-1) /* -1 for NUL */
28769+ static char pt6name[] = PASSTHROUGH6NAME;
28770+# define PT6NLEN (sizeof(pt6name)-1) /* -1 for NUL */
28771+ int af;
28772+ int base;
28773+
28774+ if (srclen == 0)
28775+ srclen = strlen(src);
28776+ if (srclen == 0)
28777+ return "empty string";
28778+ if (srclen < MINLEN)
28779+ return "string too short to be SA identifier";
28780+ if (srclen == PTNLEN && memcmp(src, ptname, PTNLEN) == 0) {
28781+ src = PASSTHROUGH4IS;
28782+ srclen = strlen(src);
28783+ } else if (srclen == PT4NLEN && memcmp(src, pt4name, PT4NLEN) == 0) {
28784+ src = PASSTHROUGH4IS;
28785+ srclen = strlen(src);
28786+ } else if (srclen == PT6NLEN && memcmp(src, pt6name, PT6NLEN) == 0) {
28787+ src = PASSTHROUGH6IS;
28788+ srclen = strlen(src);
28789+ }
28790+
28791+ at = memchr(src, '@', srclen);
28792+ if (at == NULL)
28793+ return "no @ in SA specifier";
28794+
28795+ for (sat = satypes; sat->prefix != NULL; sat++)
28796+ if (sat->prelen < srclen &&
28797+ strncmp(src, sat->prefix, sat->prelen) == 0) {
28798+ sa->proto = sat->proto;
28799+ spi = src + sat->prelen;
28800+ break; /* NOTE BREAK OUT */
28801+ }
28802+ if (sat->prefix == NULL)
28803+ return "SA specifier lacks valid protocol prefix";
28804+
28805+ if (spi >= at)
28806+ return "no SPI in SA specifier";
28807+ switch (*spi) {
28808+ case '.':
28809+ af = AF_INET;
28810+ spi++;
28811+ base = 16;
28812+ break;
28813+ case ':':
28814+ af = AF_INET6;
28815+ spi++;
28816+ base = 16;
28817+ break;
28818+ default:
28819+ af = AF_UNSPEC; /* not known yet */
28820+ base = 0;
28821+ break;
28822+ }
28823+ if (spi >= at)
28824+ return "no SPI found in SA specifier";
28825+ oops = ttoul(spi, at - spi, base, &ul);
28826+ if (oops != NULL)
28827+ return oops;
28828+ sa->spi = htonl(ul);
28829+
28830+ addr = at + 1;
28831+ alen = srclen - (addr - src);
28832+ if (af == AF_UNSPEC)
28833+ af = (memchr(addr, ':', alen) != NULL) ? AF_INET6 : AF_INET;
28834+ oops = ttoaddr(addr, alen, af, &sa->dst);
28835+ if (oops != NULL)
28836+ return oops;
28837+
28838+ return NULL;
28839+}
28840+
28841+
28842+
28843+#ifdef TTOSA_MAIN
28844+
28845+#include <stdio.h>
28846+
28847+void regress();
28848+
28849+int
28850+main(argc, argv)
28851+int argc;
28852+char *argv[];
28853+{
28854+ ip_said sa;
28855+ char buf[100];
28856+ char buf2[100];
28857+ const char *oops;
28858+ size_t n;
28859+
28860+ if (argc < 2) {
28861+ fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
28862+ exit(2);
28863+ }
28864+
28865+ if (strcmp(argv[1], "-r") == 0) {
28866+ regress();
28867+ fprintf(stderr, "regress() returned?!?\n");
28868+ exit(1);
28869+ }
28870+
28871+ oops = ttosa(argv[1], 0, &sa);
28872+ if (oops != NULL) {
28873+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
28874+ exit(1);
28875+ }
28876+ n = satot(&sa, 0, buf, sizeof(buf));
28877+ if (n > sizeof(buf)) {
28878+ fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto);
28879+ fprintf(stderr, "%lx@", sa.spi);
28880+ (void) addrtot(&sa.dst, 0, buf2, sizeof(buf2));
28881+ fprintf(stderr, "%s", buf2);
28882+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
28883+ (long)n, (long)sizeof(buf));
28884+ exit(1);
28885+ }
28886+ printf("%s\n", buf);
28887+
28888+ exit(0);
28889+}
28890+
28891+struct rtab {
28892+ int format;
28893+ char *input;
28894+ char *output; /* NULL means error expected */
28895+} rtab[] = {
28896+ 0, "esp257@1.2.3.0", "esp.101@1.2.3.0",
28897+ 0, "ah0x20@1.2.3.4", "ah.20@1.2.3.4",
28898+ 0, "tun20@1.2.3.4", "tun.14@1.2.3.4",
28899+ 0, "comp20@1.2.3.4", "comp.14@1.2.3.4",
28900+ 0, "esp257@::1", "esp:101@::1",
28901+ 0, "esp257@0bc:12de::1", "esp:101@bc:12de::1",
28902+ 0, "esp78@1049:1::8007:2040", "esp:4e@1049:1::8007:2040",
28903+ 0, "esp0x78@1049:1::8007:2040", "esp:78@1049:1::8007:2040",
28904+ 0, "ah78@1049:1::8007:2040", "ah:4e@1049:1::8007:2040",
28905+ 0, "ah0x78@1049:1::8007:2040", "ah:78@1049:1::8007:2040",
28906+ 0, "tun78@1049:1::8007:2040", "tun:4e@1049:1::8007:2040",
28907+ 0, "tun0x78@1049:1::8007:2040", "tun:78@1049:1::8007:2040",
28908+ 0, "duk99@3ffe:370:400:ff::9001:3001", NULL,
28909+ 0, "esp78x@1049:1::8007:2040", NULL,
28910+ 0, "esp0x78@1049:1:0xfff::8007:2040", NULL,
28911+ 0, "es78@1049:1::8007:2040", NULL,
28912+ 0, "", NULL,
28913+ 0, "_", NULL,
28914+ 0, "ah2.2", NULL,
28915+ 0, "goo2@1.2.3.4", NULL,
28916+ 0, "esp9@1.2.3.4", "esp.9@1.2.3.4",
28917+ 'f', "esp0xa9@1.2.3.4", "esp.000000a9@1.2.3.4",
28918+ 0, "espp9@1.2.3.4", NULL,
28919+ 0, "es9@1.2.3.4", NULL,
28920+ 0, "ah@1.2.3.4", NULL,
28921+ 0, "esp7x7@1.2.3.4", NULL,
28922+ 0, "esp77@1.0x2.3.4", NULL,
28923+ 0, PASSTHROUGHNAME, PASSTHROUGH4NAME,
28924+ 0, NULL, NULL
28925+};
28926+
28927+void
28928+regress()
28929+{
28930+ struct rtab *r;
28931+ int status = 0;
28932+ ip_said sa;
28933+ char in[100];
28934+ char buf[100];
28935+ const char *oops;
28936+ size_t n;
28937+
28938+ for (r = rtab; r->input != NULL; r++) {
28939+ strcpy(in, r->input);
28940+ oops = ttosa(in, 0, &sa);
28941+ if (oops != NULL && r->output == NULL)
28942+ {} /* okay, error expected */
28943+ else if (oops != NULL) {
28944+ printf("`%s' ttosa failed: %s\n", r->input, oops);
28945+ status = 1;
28946+ } else if (r->output == NULL) {
28947+ printf("`%s' ttosa succeeded unexpectedly\n",
28948+ r->input);
28949+ status = 1;
28950+ } else {
28951+ n = satot(&sa, r->format, buf, sizeof(buf));
28952+ if (n > sizeof(buf)) {
28953+ printf("`%s' satot failed: need %ld\n",
28954+ r->input, (long)n);
28955+ status = 1;
28956+ } else if (strcmp(r->output, buf) != 0) {
28957+ printf("`%s' gave `%s', expected `%s'\n",
28958+ r->input, buf, r->output);
28959+ status = 1;
28960+ }
28961+ }
28962+ }
28963+ exit(status);
28964+}
28965+
28966+#endif /* TTOSA_MAIN */
28967diff -druN linux-noipsec/net/ipsec/libfreeswan/ttosubnet.c linux/net/ipsec/libfreeswan/ttosubnet.c
28968--- linux-noipsec/net/ipsec/libfreeswan/ttosubnet.c Thu Jan 1 01:00:00 1970
28969+++ linux/net/ipsec/libfreeswan/ttosubnet.c Thu Aug 17 06:14:27 2000
28970@@ -0,0 +1,275 @@
28971+/*
28972+ * convert from text form of subnet specification to binary
28973+ * Copyright (C) 2000 Henry Spencer.
28974+ *
28975+ * This library is free software; you can redistribute it and/or modify it
28976+ * under the terms of the GNU Library General Public License as published by
28977+ * the Free Software Foundation; either version 2 of the License, or (at your
28978+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
28979+ *
28980+ * This library is distributed in the hope that it will be useful, but
28981+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28982+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
28983+ * License for more details.
28984+ *
28985+ * RCSID $Id$
28986+ */
28987+#include "internal.h"
28988+#include "freeswan.h"
28989+
28990+#ifndef DEFAULTSUBNET
28991+#define DEFAULTSUBNET "%default"
28992+#endif
28993+
28994+/*
28995+ - ttosubnet - convert text "addr/mask" to address and mask
28996+ * Mask can be integer bit count.
28997+ */
28998+err_t
28999+ttosubnet(src, srclen, af, dst)
29000+const char *src;
29001+size_t srclen; /* 0 means "apply strlen" */
29002+int af; /* AF_INET or AF_INET6 */
29003+ip_subnet *dst;
29004+{
29005+ const char *slash;
29006+ const char *mask;
29007+ size_t mlen;
29008+ const char *oops;
29009+ unsigned long bc;
29010+ static char def[] = DEFAULTSUBNET;
29011+# define DEFLEN (sizeof(def) - 1) /* -1 for NUL */
29012+ static char defis4[] = "0/0";
29013+# define DEFIS4LEN (sizeof(defis4) - 1)
29014+ static char defis6[] = "::/0";
29015+# define DEFIS6LEN (sizeof(defis6) - 1)
29016+ ip_address addrtmp;
29017+ ip_address masktmp;
29018+ int nbits;
29019+ int i;
29020+
29021+ if (srclen == 0)
29022+ srclen = strlen(src);
29023+ if (srclen == 0)
29024+ return "empty string";
29025+
29026+ switch (af) {
29027+ case AF_INET:
29028+ nbits = 32;
29029+ break;
29030+ case AF_INET6:
29031+ nbits = 128;
29032+ break;
29033+ default:
29034+ return "unknown address family in ttosubnet";
29035+ break;
29036+ }
29037+
29038+ if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) {
29039+ src = (af == AF_INET) ? defis4 : defis6;
29040+ srclen = (af == AF_INET) ? DEFIS4LEN : DEFIS6LEN;
29041+ }
29042+
29043+ slash = memchr(src, '/', srclen);
29044+ if (slash == NULL)
29045+ return "no / in subnet specification";
29046+ mask = slash + 1;
29047+ mlen = srclen - (mask - src);
29048+
29049+ oops = ttoaddr(src, slash-src, af, &addrtmp);
29050+ if (oops != NULL)
29051+ return oops;
29052+
29053+ oops = ttoul(mask, mlen, 10, &bc);
29054+ if (oops == NULL) {
29055+ /* ttoul succeeded, it's a bit-count mask */
29056+ if (bc > nbits)
29057+ return "subnet mask bit count too large";
29058+ i = bc;
29059+ } else {
29060+ oops = ttoaddr(mask, mlen, af, &masktmp);
29061+ if (oops != NULL)
29062+ return oops;
29063+ i = masktocount(&masktmp);
29064+ if (i < 0)
29065+ return "non-contiguous or otherwise erroneous mask";
29066+ }
29067+
29068+ return initsubnet(&addrtmp, i, '0', dst);
29069+}
29070+
29071+
29072+
29073+#ifdef TTOSUBNET_MAIN
29074+
29075+#include <stdio.h>
29076+
29077+void regress();
29078+
29079+int
29080+main(argc, argv)
29081+int argc;
29082+char *argv[];
29083+{
29084+ ip_address a;
29085+ ip_subnet s;
29086+ char buf[100];
29087+ char buf2[100];
29088+ const char *oops;
29089+ size_t n;
29090+ int af;
29091+ char *p;
29092+
29093+ if (argc < 2) {
29094+ fprintf(stderr, "Usage: %s [-6] addr/mask\n", argv[0]);
29095+ fprintf(stderr, " or: %s -r\n", argv[0]);
29096+ exit(2);
29097+ }
29098+
29099+ if (strcmp(argv[1], "-r") == 0) {
29100+ regress();
29101+ fprintf(stderr, "regress() returned?!?\n");
29102+ exit(1);
29103+ }
29104+
29105+ af = AF_INET;
29106+ p = argv[1];
29107+ if (strcmp(argv[1], "-6") == 0) {
29108+ af = AF_INET6;
29109+ p = argv[2];
29110+ } else if (strchr(argv[1], ':') != NULL)
29111+ af = AF_INET6;
29112+
29113+ oops = ttosubnet(p, 0, af, &s);
29114+ if (oops != NULL) {
29115+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
29116+ exit(1);
29117+ }
29118+ n = subnettot(&s, 0, buf, sizeof(buf));
29119+ if (n > sizeof(buf)) {
29120+ fprintf(stderr, "%s: reverse conversion of ", argv[0]);
29121+ (void) addrtot(&s.addr, 0, buf2, sizeof(buf2));
29122+ fprintf(stderr, "%s/", buf2);
29123+ fprintf(stderr, "%d", s.maskbits);
29124+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
29125+ (long)n, (long)sizeof(buf));
29126+ exit(1);
29127+ }
29128+ printf("%s\n", buf);
29129+
29130+ exit(0);
29131+}
29132+
29133+struct rtab {
29134+ int family;
29135+ char *input;
29136+ char *output; /* NULL means error expected */
29137+} rtab[] = {
29138+ 4, "1.2.3.0/255.255.255.0", "1.2.3.0/24",
29139+ 4, "1.2.3.0/24", "1.2.3.0/24",
29140+ 4, "1.2.3.1/255.255.255.240", "1.2.3.0/28",
29141+ 4, "1.2.3.1/32", "1.2.3.1/32",
29142+ 4, "1.2.3.1/0", "0.0.0.0/0",
29143+/* 4, "1.2.3.1/255.255.127.0", "1.2.3.0/255.255.127.0", */
29144+ 4, "1.2.3.1/255.255.127.0", NULL,
29145+ 4, "128.009.000.032/32", "128.9.0.32/32",
29146+ 4, "128.0x9.0.32/32", NULL,
29147+ 4, "0x80090020/32", "128.9.0.32/32",
29148+ 4, "0x800x0020/32", NULL,
29149+ 4, "128.9.0.32/0xffFF0000", "128.9.0.0/16",
29150+ 4, "128.9.0.32/0xff0000FF", NULL,
29151+ 4, "128.9.0.32/0x0000ffFF", NULL,
29152+ 4, "128.9.0.32/0x00ffFF0000", NULL,
29153+ 4, "128.9.0.32/0xffFF", NULL,
29154+ 4, "128.9.0.32.27/32", NULL,
29155+ 4, "128.9.0k32/32", NULL,
29156+ 4, "328.9.0.32/32", NULL,
29157+ 4, "128.9..32/32", NULL,
29158+ 4, "10/8", "10.0.0.0/8",
29159+ 4, "10.0/8", "10.0.0.0/8",
29160+ 4, "10.0.0/8", "10.0.0.0/8",
29161+ 4, "10.0.1/24", "10.0.1.0/24",
29162+ 4, "_", NULL,
29163+ 4, "_/_", NULL,
29164+ 4, "1.2.3.1", NULL,
29165+ 4, "1.2.3.1/_", NULL,
29166+ 4, "1.2.3.1/24._", NULL,
29167+ 4, "1.2.3.1/99", NULL,
29168+ 4, "localhost./32", "127.0.0.1/32",
29169+ 4, "%default", "0.0.0.0/0",
29170+ 6, "3049:1::8007:2040/0", "::/0",
29171+ 6, "3049:1::8007:2040/128", "3049:1::8007:2040/128",
29172+ 6, "3049:1::192.168.0.1/128", NULL, /*"3049:1::c0a8:1/128",*/
29173+ 6, "3049:1::8007::2040/128", NULL,
29174+ 6, "3049:1::8007:2040/ffff::0", "3049::/16",
29175+ 6, "3049:1::8007:2040/64", "3049:1::/64",
29176+ 6, "3049:1::8007:2040/ffff::", "3049::/16",
29177+ 6, "3049:1::8007:2040/0000:ffff::0", NULL,
29178+ 6, "3049:1::8007:2040/ff1f::0", NULL,
29179+ 6, "3049:1::8007:x:2040/128", NULL,
29180+ 6, "3049:1t::8007:2040/128", NULL,
29181+ 6, "3049:1::80071:2040/128", NULL,
29182+ 6, "::/21", "::/21",
29183+ 6, "::1/128", "::1/128",
29184+ 6, "1::/21", "1::/21",
29185+ 6, "1::2/128", "1::2/128",
29186+ 6, "1:0:0:0:0:0:0:2/128", "1::2/128",
29187+ 6, "1:0:0:0:3:0:0:2/128", "1::3:0:0:2/128",
29188+ 6, "1:0:0:3:0:0:0:2/128", "1::3:0:0:0:2/128",
29189+ 6, "1:0:3:0:0:0:0:2/128", "1:0:3::2/128",
29190+ 6, "abcd:ef01:2345:6789:0:00a:000:20/128", "abcd:ef01:2345:6789:0:a:0:20/128",
29191+ 6, "3049:1::8007:2040/ffff:ffff:", NULL,
29192+ 6, "3049:1::8007:2040/ffff:88::", NULL,
29193+ 6, "3049:12::9000:3200/ffff:fff0::", "3049:10::/28",
29194+ 6, "3049:12::9000:3200/28", "3049:10::/28",
29195+ 6, "3049:12::9000:3200/ff00:::", NULL,
29196+ 6, "3049:12::9000:3200/ffff:::", NULL,
29197+ 6, "3049:12::9000:3200/128_", NULL,
29198+ 6, "3049:12::9000:3200/", NULL,
29199+ 6, "%default", "::/0",
29200+ 4, NULL, NULL
29201+};
29202+
29203+void
29204+regress()
29205+{
29206+ struct rtab *r;
29207+ int status = 0;
29208+ ip_address a;
29209+ ip_subnet s;
29210+ char in[100];
29211+ char buf[100];
29212+ const char *oops;
29213+ size_t n;
29214+ int af;
29215+
29216+ for (r = rtab; r->input != NULL; r++) {
29217+ af = (r->family == 4) ? AF_INET : AF_INET6;
29218+ strcpy(in, r->input);
29219+ oops = ttosubnet(in, 0, af, &s);
29220+ if (oops != NULL && r->output == NULL)
29221+ {} /* okay, error expected */
29222+ else if (oops != NULL) {
29223+ printf("`%s' ttosubnet failed: %s\n", r->input, oops);
29224+ status = 1;
29225+ } else if (r->output == NULL) {
29226+ printf("`%s' ttosubnet succeeded unexpectedly\n",
29227+ r->input);
29228+ status = 1;
29229+ } else {
29230+ n = subnettot(&s, 0, buf, sizeof(buf));
29231+ if (n > sizeof(buf)) {
29232+ printf("`%s' subnettot failed: need %ld\n",
29233+ r->input, (long)n);
29234+ status = 1;
29235+ } else if (strcmp(r->output, buf) != 0) {
29236+ printf("`%s' gave `%s', expected `%s'\n",
29237+ r->input, buf, r->output);
29238+ status = 1;
29239+ }
29240+ }
29241+ }
29242+ exit(status);
29243+}
29244+
29245+#endif /* TTOSUBNET_MAIN */
29246diff -druN linux-noipsec/net/ipsec/libfreeswan/ttoul.c linux/net/ipsec/libfreeswan/ttoul.c
29247--- linux-noipsec/net/ipsec/libfreeswan/ttoul.c Thu Jan 1 01:00:00 1970
29248+++ linux/net/ipsec/libfreeswan/ttoul.c Thu Aug 17 01:07:16 2000
29249@@ -0,0 +1,91 @@
29250+/*
29251+ * convert from text form of unsigned long to binary
29252+ * Copyright (C) 2000 Henry Spencer.
29253+ *
29254+ * This library is free software; you can redistribute it and/or modify it
29255+ * under the terms of the GNU Library General Public License as published by
29256+ * the Free Software Foundation; either version 2 of the License, or (at your
29257+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
29258+ *
29259+ * This library is distributed in the hope that it will be useful, but
29260+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29261+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
29262+ * License for more details.
29263+ *
29264+ * RCSID $Id$
29265+ */
29266+#include "internal.h"
29267+#include "freeswan.h"
29268+
29269+/*
29270+ - ttoul - convert text substring to unsigned long number
29271+ */
29272+const char * /* NULL for success, else string literal */
29273+ttoul(src, srclen, base, resultp)
29274+const char *src;
29275+size_t srclen; /* 0 means strlen(src) */
29276+int base; /* 0 means figure it out */
29277+unsigned long *resultp;
29278+{
29279+ const char *stop;
29280+ static char hex[] = "0123456789abcdef";
29281+ static char uchex[] = "0123456789ABCDEF";
29282+ int d;
29283+ char c;
29284+ char *p;
29285+ unsigned long r;
29286+ unsigned long rlimit;
29287+ int dlimit;
29288+
29289+ if (srclen == 0)
29290+ srclen = strlen(src);
29291+ if (srclen == 0)
29292+ return "empty string";
29293+
29294+ if (base == 0) {
29295+ if (srclen > 2 && *src == '0' &&
29296+ (*(src+1) == 'x' || *(src+1) == 'X'))
29297+ return ttoul(src+2, srclen-2, 16, resultp);
29298+ if (srclen > 1 && *src == '0')
29299+ return ttoul(src+1, srclen-1, 8, resultp);
29300+ return ttoul(src, srclen, 10, resultp);
29301+ }
29302+ if (base != 8 && base != 10 && base != 16)
29303+ return "unsupported number base";
29304+
29305+ r = 0;
29306+ stop = src + srclen;
29307+ if (base == 16) {
29308+ while (src < stop) {
29309+ c = *src++;
29310+ p = strchr(hex, c);
29311+ if (p != NULL)
29312+ d = p - hex;
29313+ else {
29314+ p = strchr(uchex, c);
29315+ if (p == NULL)
29316+ return "non-hex digit in hex number";
29317+ d = p - uchex;
29318+ }
29319+ r = (r << 4) | d;
29320+ }
29321+ /* defer length check to catch invalid digits first */
29322+ if (srclen > sizeof(unsigned long) * 2)
29323+ return "hex number too long";
29324+ } else {
29325+ rlimit = ULONG_MAX / base;
29326+ dlimit = (int)(ULONG_MAX - rlimit*base);
29327+ while (src < stop) {
29328+ c = *src++;
29329+ d = c - '0';
29330+ if (d < 0 || d >= base)
29331+ return "non-digit in number";
29332+ if (r > rlimit || (r == rlimit && d > dlimit))
29333+ return "unsigned-long overflow";
29334+ r = r*base + d;
29335+ }
29336+ }
29337+
29338+ *resultp = r;
29339+ return NULL;
29340+}
29341diff -druN linux-noipsec/net/ipsec/libfreeswan/ultoa.c linux/net/ipsec/libfreeswan/ultoa.c
29342--- linux-noipsec/net/ipsec/libfreeswan/ultoa.c Thu Jan 1 01:00:00 1970
29343+++ linux/net/ipsec/libfreeswan/ultoa.c Wed Oct 13 20:09:06 1999
29344@@ -0,0 +1,67 @@
29345+/*
29346+ * convert unsigned long to ASCII
29347+ * Copyright (C) 1998, 1999 Henry Spencer.
29348+ *
29349+ * This library is free software; you can redistribute it and/or modify it
29350+ * under the terms of the GNU Library General Public License as published by
29351+ * the Free Software Foundation; either version 2 of the License, or (at your
29352+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
29353+ *
29354+ * This library is distributed in the hope that it will be useful, but
29355+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29356+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
29357+ * License for more details.
29358+ *
29359+ * RCSID $Id$
29360+ */
29361+#include "internal.h"
29362+#include "freeswan.h"
29363+
29364+/*
29365+ - ultoa - convert unsigned long to decimal ASCII
29366+ */
29367+size_t /* length required for full conversion */
29368+ultoa(n, base, dst, dstlen)
29369+unsigned long n;
29370+int base;
29371+char *dst; /* need not be valid if dstlen is 0 */
29372+size_t dstlen;
29373+{
29374+ char buf[3*sizeof(unsigned long) + 1];
29375+ char *bufend = buf + sizeof(buf);
29376+ size_t len;
29377+ char *p;
29378+ static char hex[] = "0123456789abcdef";
29379+
29380+ p = bufend;
29381+ *--p = '\0';
29382+ if (base == 10) {
29383+ do {
29384+ *--p = n%10 + '0';
29385+ n /= 10;
29386+ } while (n != 0);
29387+ } else if (base == 16) {
29388+ do {
29389+ *--p = hex[n&0xf];
29390+ n >>= 4;
29391+ } while (n != 0);
29392+ *--p = 'x';
29393+ *--p = '0';
29394+ } else if (base == 8) {
29395+ do {
29396+ *--p = (n&07) + '0';
29397+ n >>= 3;
29398+ } while (n != 0);
29399+ *--p = '0';
29400+ } else
29401+ *--p = '?';
29402+
29403+ len = bufend - p;
29404+
29405+ if (dstlen > 0) {
29406+ if (len > dstlen)
29407+ *(p + dstlen - 1) = '\0';
29408+ strcpy(dst, p);
29409+ }
29410+ return len;
29411+}
29412diff -druN linux-noipsec/net/ipsec/libfreeswan/ultot.c linux/net/ipsec/libfreeswan/ultot.c
29413--- linux-noipsec/net/ipsec/libfreeswan/ultot.c Thu Jan 1 01:00:00 1970
29414+++ linux/net/ipsec/libfreeswan/ultot.c Thu Aug 17 01:07:16 2000
29415@@ -0,0 +1,83 @@
29416+/*
29417+ * convert unsigned long to text
29418+ * Copyright (C) 2000 Henry Spencer.
29419+ *
29420+ * This library is free software; you can redistribute it and/or modify it
29421+ * under the terms of the GNU Library General Public License as published by
29422+ * the Free Software Foundation; either version 2 of the License, or (at your
29423+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
29424+ *
29425+ * This library is distributed in the hope that it will be useful, but
29426+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29427+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
29428+ * License for more details.
29429+ *
29430+ * RCSID $Id$
29431+ */
29432+#include "internal.h"
29433+#include "freeswan.h"
29434+
29435+/*
29436+ - ultot - convert unsigned long to text
29437+ */
29438+size_t /* length required for full conversion */
29439+ultot(n, base, dst, dstlen)
29440+unsigned long n;
29441+int base;
29442+char *dst; /* need not be valid if dstlen is 0 */
29443+size_t dstlen;
29444+{
29445+ char buf[3*sizeof(unsigned long) + 1];
29446+ char *bufend = buf + sizeof(buf);
29447+ size_t len;
29448+ char *p;
29449+ static char hex[] = "0123456789abcdef";
29450+# define HEX32 (32/4)
29451+
29452+ p = bufend;
29453+ *--p = '\0';
29454+ switch (base) {
29455+ case 10:
29456+ case 'd':
29457+ do {
29458+ *--p = n%10 + '0';
29459+ n /= 10;
29460+ } while (n != 0);
29461+ break;
29462+ case 16:
29463+ case 17:
29464+ case 'x':
29465+ do {
29466+ *--p = hex[n&0xf];
29467+ n >>= 4;
29468+ } while (n != 0);
29469+ if (base == 17)
29470+ while (bufend - p < HEX32 + 1)
29471+ *--p = '0';
29472+ if (base == 'x') {
29473+ *--p = 'x';
29474+ *--p = '0';
29475+ }
29476+ break;
29477+ case 8:
29478+ case 'o':
29479+ do {
29480+ *--p = (n&07) + '0';
29481+ n >>= 3;
29482+ } while (n != 0);
29483+ if (base == 'o')
29484+ *--p = '0';
29485+ break;
29486+ default:
29487+ return 0;
29488+ break;
29489+ }
29490+
29491+ len = bufend - p;
29492+ if (dstlen > 0) {
29493+ if (len > dstlen)
29494+ *(p + dstlen - 1) = '\0';
29495+ strcpy(dst, p);
29496+ }
29497+ return len;
29498+}
29499diff -druN linux-noipsec/net/ipsec/pfkey_v2.c linux/net/ipsec/pfkey_v2.c
29500--- linux-noipsec/net/ipsec/pfkey_v2.c Thu Jan 1 01:00:00 1970
29501+++ linux/net/ipsec/pfkey_v2.c Mon Nov 6 05:33:47 2000
29502@@ -0,0 +1,1891 @@
29503+/*
29504+ * RFC2367 PF_KEYv2 Key management API domain socket I/F
29505+ * Copyright (C) 1999, 2000 Richard Guy Briggs.
29506+ *
29507+ * This program is free software; you can redistribute it and/or modify it
29508+ * under the terms of the GNU General Public License as published by the
29509+ * Free Software Foundation; either version 2 of the License, or (at your
29510+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29511+ *
29512+ * This program is distributed in the hope that it will be useful, but
29513+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29514+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29515+ * for more details.
29516+ *
29517+ * RCSID $Id$
29518+ */
29519+
29520+/*
29521+ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
29522+ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
29523+ */
29524+
29525+#define __NO_VERSION__
29526+#include <linux/module.h>
29527+#include <linux/version.h>
29528+
29529+#include <linux/config.h>
29530+#include <linux/kernel.h>
29531+#include <linux/major.h>
29532+#include <linux/signal.h>
29533+#include <linux/sched.h>
29534+#include <linux/errno.h>
29535+#include <linux/string.h>
29536+#include <linux/stat.h>
29537+#include <linux/socket.h>
29538+#include <linux/un.h>
29539+#include <linux/fcntl.h>
29540+#include <linux/termios.h>
29541+#include <linux/socket.h>
29542+#include <linux/sockios.h>
29543+#include <linux/net.h> /* struct socket */
29544+#include <linux/in.h>
29545+#include <linux/fs.h>
29546+#include <linux/malloc.h>
29547+#include <asm/segment.h>
29548+#include <linux/skbuff.h>
29549+#include <linux/netdevice.h>
29550+#include <net/sock.h> /* struct sock */
29551+/* #include <net/tcp.h> */
29552+#include <net/af_unix.h>
29553+#ifdef CONFIG_PROC_FS
29554+#include <linux/proc_fs.h>
29555+#endif /* CONFIG_PROC_FS */
29556+
29557+#include <linux/types.h>
29558+
29559+#include <freeswan.h>
29560+#ifdef NET_21
29561+#include <asm/uaccess.h>
29562+#include <linux/in6.h>
29563+#endif /* NET_21 */
29564+#include <pfkeyv2.h>
29565+#include <pfkey.h>
29566+#include "radij.h"
29567+#include "ipsec_encap.h"
29568+#include "ipsec_netlink.h"
29569+
29570+#ifdef CONFIG_IPSEC_DEBUG
29571+int debug_pfkey = 0;
29572+extern int sysctl_ipsec_debug_verbose;
29573+#endif /* CONFIG_IPSEC_DEBUG */
29574+
29575+#define min(a,b) (((a)<(b))?(a):(b))
29576+
29577+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
29578+
29579+#ifndef SOCKOPS_WRAPPED
29580+#define SOCKOPS_WRAPPED(name) name
29581+#endif
29582+
29583+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops);
29584+struct sock *pfkey_sock_list = NULL;
29585+struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
29586+
29587+struct socket_list *pfkey_open_sockets = NULL;
29588+struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
29589+
29590+int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
29591+
29592+int
29593+pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
29594+{
29595+ struct socket_list *socket_listp,*prev;
29596+
29597+ if(!socketp) {
29598+ KLIPS_PRINT(debug_pfkey,
29599+ "klips_debug:pfkey_list_remove_socket: "
29600+ "NULL socketp handed in, failed.\n");
29601+ return -EINVAL;
29602+ }
29603+
29604+ if(!sockets) {
29605+ KLIPS_PRINT(debug_pfkey,
29606+ "klips_debug:pfkey_list_remove_socket: "
29607+ "NULL sockets list handed in, failed.\n");
29608+ return -EINVAL;
29609+ }
29610+
29611+ socket_listp = *sockets;
29612+ prev = NULL;
29613+
29614+ KLIPS_PRINT(debug_pfkey,
29615+ "klips_debug:pfkey_list_remove_socket: "
29616+ "removing sock=%p\n",
29617+ socketp);
29618+
29619+ while(socket_listp != NULL) {
29620+ if(socket_listp->socketp == socketp) {
29621+ if(prev != NULL) {
29622+ prev->next = socket_listp->next;
29623+ } else {
29624+ *sockets = socket_listp->next;
29625+ }
29626+
29627+ kfree((void*)socket_listp);
29628+
29629+ break;
29630+ }
29631+ prev = socket_listp;
29632+ socket_listp = socket_listp->next;
29633+ }
29634+
29635+ return 0;
29636+}
29637+
29638+int
29639+pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
29640+{
29641+ struct socket_list *socket_listp;
29642+
29643+ if(!socketp) {
29644+ KLIPS_PRINT(debug_pfkey,
29645+ "klips_debug:pfkey_list_insert_socket: "
29646+ "NULL socketp handed in, failed.\n");
29647+ return -EINVAL;
29648+ }
29649+
29650+ if(!sockets) {
29651+ KLIPS_PRINT(debug_pfkey,
29652+ "klips_debug:pfkey_list_insert_socket: "
29653+ "NULL sockets list handed in, failed.\n");
29654+ return -EINVAL;
29655+ }
29656+
29657+ KLIPS_PRINT(debug_pfkey,
29658+ "klips_debug:pfkey_list_insert_socket: "
29659+ "socketp=%p\n",socketp);
29660+
29661+ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
29662+ KLIPS_PRINT(debug_pfkey,
29663+ "klips_debug:pfkey_list_insert_socket: "
29664+ "memory allocation error.\n");
29665+ return -ENOMEM;
29666+ }
29667+
29668+ socket_listp->socketp = socketp;
29669+ socket_listp->next = *sockets;
29670+ *sockets = socket_listp;
29671+
29672+ return 0;
29673+}
29674+
29675+int
29676+pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list)
29677+{
29678+ struct supported_list *supported_listp = *supported_list, *prev = NULL;
29679+
29680+ if(!supported) {
29681+ KLIPS_PRINT(debug_pfkey,
29682+ "klips_debug:pfkey_list_remove_supported: "
29683+ "NULL supported handed in, failed.\n");
29684+ return -EINVAL;
29685+ }
29686+
29687+ if(!supported_list) {
29688+ KLIPS_PRINT(debug_pfkey,
29689+ "klips_debug:pfkey_list_remove_supported: "
29690+ "NULL supported_list handed in, failed.\n");
29691+ return -EINVAL;
29692+ }
29693+
29694+ KLIPS_PRINT(debug_pfkey,
29695+ "klips_debug:pfkey_list_remove_supported: "
29696+ "removing supported=%p\n",
29697+ supported);
29698+
29699+ while(supported_listp != NULL) {
29700+ if(supported_listp->supportedp == supported) {
29701+ if(prev != NULL) {
29702+ prev->next = supported_listp->next;
29703+ } else {
29704+ *supported_list = supported_listp->next;
29705+ }
29706+
29707+ kfree((void*)supported_listp);
29708+
29709+ break;
29710+ }
29711+ prev = supported_listp;
29712+ supported_listp = supported_listp->next;
29713+ }
29714+
29715+ return 0;
29716+}
29717+
29718+int
29719+pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list)
29720+{
29721+ struct supported_list *supported_listp;
29722+
29723+ if(!supported) {
29724+ KLIPS_PRINT(debug_pfkey,
29725+ "klips_debug:pfkey_list_insert_supported: "
29726+ "NULL supported handed in, failed.\n");
29727+ return -EINVAL;
29728+ }
29729+
29730+ if(!supported_list) {
29731+ KLIPS_PRINT(debug_pfkey,
29732+ "klips_debug:pfkey_list_insert_supported: "
29733+ "NULL supported_list handed in, failed.\n");
29734+ return -EINVAL;
29735+ }
29736+
29737+ KLIPS_PRINT(debug_pfkey,
29738+ "klips_debug:pfkey_list_insert_supported: "
29739+ "incoming, supported=%p, supported_list=%p\n",
29740+ supported,
29741+ supported_list);
29742+
29743+ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
29744+ if(supported_listp == NULL) {
29745+ KLIPS_PRINT(debug_pfkey,
29746+ "klips_debug:pfkey_list_insert_supported: "
29747+ "memory allocation error.\n");
29748+ return -ENOMEM;
29749+ }
29750+
29751+ supported_listp->supportedp = supported;
29752+ supported_listp->next = *supported_list;
29753+ *supported_list = supported_listp;
29754+ KLIPS_PRINT(debug_pfkey,
29755+ "klips_debug:pfkey_list_insert_supported: "
29756+ "outgoing, supported=%p, supported_list=%p\n",
29757+ supported,
29758+ supported_list);
29759+
29760+ return 0;
29761+}
29762+
29763+#ifndef NET_21
29764+DEBUG_NO_STATIC void
29765+pfkey_state_change(struct sock *sk)
29766+{
29767+ KLIPS_PRINT(debug_pfkey,
29768+ "klips_debug:pfkey_state_change: .\n");
29769+ if(!sk->dead) {
29770+ wake_up_interruptible(sk->sleep);
29771+ }
29772+}
29773+#endif /* !NET_21 */
29774+
29775+#ifndef NET_21
29776+DEBUG_NO_STATIC void
29777+pfkey_data_ready(struct sock *sk, int len)
29778+{
29779+ KLIPS_PRINT(debug_pfkey,
29780+ "klips_debug:pfkey_data_ready: .sk=%p len=%d\n", sk, len);
29781+ if(!sk->dead) {
29782+ wake_up_interruptible(sk->sleep);
29783+ sock_wake_async(sk->socket, 1);
29784+ }
29785+}
29786+
29787+DEBUG_NO_STATIC void
29788+pfkey_write_space(struct sock *sk)
29789+{
29790+ KLIPS_PRINT(debug_pfkey,
29791+ "klips_debug:pfkey_write_space: .\n");
29792+ if(!sk->dead) {
29793+ wake_up_interruptible(sk->sleep);
29794+ sock_wake_async(sk->socket, 2);
29795+ }
29796+}
29797+#endif /* !NET_21 */
29798+
29799+DEBUG_NO_STATIC void
29800+pfkey_insert_socket(struct sock *sk)
29801+{
29802+ KLIPS_PRINT(debug_pfkey,
29803+ "klips_debug:pfkey_insert_socket: sk=%p\n", sk);
29804+ cli();
29805+ sk->next=pfkey_sock_list;
29806+ pfkey_sock_list=sk;
29807+ sti();
29808+}
29809+
29810+DEBUG_NO_STATIC void
29811+pfkey_remove_socket(struct sock *sk)
29812+{
29813+ struct sock **s;
29814+
29815+ KLIPS_PRINT(debug_pfkey,
29816+ "klips_debug:pfkey_remove_socket: .\n");
29817+ cli();
29818+ s=&pfkey_sock_list;
29819+
29820+ while(*s!=NULL) {
29821+ if(*s==sk) {
29822+ *s=sk->next;
29823+ sk->next=NULL;
29824+ sti();
29825+ KLIPS_PRINT(debug_pfkey,
29826+ "klips_debug:pfkey_remove_socket: succeeded.\n");
29827+ return;
29828+ }
29829+ s=&((*s)->next);
29830+ }
29831+ sti();
29832+ KLIPS_PRINT(debug_pfkey,
29833+ "klips_debug:pfkey_remove_socket: not found.\n");
29834+ return;
29835+}
29836+
29837+DEBUG_NO_STATIC void
29838+pfkey_destroy_socket(struct sock *sk)
29839+{
29840+ struct sk_buff *skb;
29841+
29842+ KLIPS_PRINT(debug_pfkey,
29843+ "klips_debug:pfkey_destroy_socket: .\n");
29844+ pfkey_remove_socket(sk);
29845+ KLIPS_PRINT(debug_pfkey,
29846+ "klips_debug:pfkey_destroy_socket: pfkey_remove_socket called.\n");
29847+
29848+ KLIPS_PRINT(debug_pfkey,
29849+ "klips_debug:pfkey_destroy_socket: "
29850+ "sk(%p)->(&%p)receive_queue.{next=%p,prev=%p}.\n",
29851+ sk,
29852+ &(sk->receive_queue),
29853+ sk->receive_queue.next,
29854+ sk->receive_queue.prev);
29855+ while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) {
29856+#ifdef NET_21
29857+#ifdef CONFIG_IPSEC_DEBUG
29858+ if(debug_pfkey && sysctl_ipsec_debug_verbose) {
29859+ KLIPS_PRINT(debug_pfkey,
29860+ "klips_debug:pfkey_destroy_socket: skb=%p dequeued.\n", skb);
29861+ printk(KERN_INFO "klips_debug: pfkey_skb contents:");
29862+ printk(" next:%p", skb->next);
29863+ printk(" prev:%p", skb->prev);
29864+ printk(" list:%p", skb->list);
29865+ printk(" sk:%p", skb->sk);
29866+ printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec);
29867+ printk(" dev:%p", skb->dev);
29868+ if(skb->dev) {
29869+ if(skb->dev->name) {
29870+ printk(" dev->name:%s", skb->dev->name);
29871+ } else {
29872+ printk(" dev->name:NULL?");
29873+ }
29874+ } else {
29875+ printk(" dev:NULL");
29876+ }
29877+ printk(" h:%p", skb->h.raw);
29878+ printk(" nh:%p", skb->nh.raw);
29879+ printk(" mac:%p", skb->mac.raw);
29880+ printk(" dst:%p", skb->dst);
29881+ if(sysctl_ipsec_debug_verbose) {
29882+ int i;
29883+
29884+ printk(" cb");
29885+ for(i=0; i<48; i++) {
29886+ printk(":%2x", skb->cb[i]);
29887+ }
29888+ }
29889+ printk(" len:%d", skb->len);
29890+ printk(" csum:%d", skb->csum);
29891+ printk(" used:%d", skb->used);
29892+ printk(" is_clone:%d", skb->is_clone);
29893+ printk(" cloned:%d", skb->cloned);
29894+ printk(" pkt_type:%d", skb->pkt_type);
29895+ printk(" ip_summed:%d", skb->ip_summed);
29896+ printk(" priority:%d", skb->priority);
29897+ printk(" protocol:%d", skb->protocol);
29898+ printk(" security:%d", skb->security);
29899+ printk(" truesize:%d", skb->truesize);
29900+ printk(" head:%p", skb->head);
29901+ printk(" data:%p", skb->data);
29902+ printk(" tail:%p", skb->tail);
29903+ printk(" end:%p", skb->end);
29904+ if(sysctl_ipsec_debug_verbose) {
29905+ unsigned int i;
29906+ printk(" data");
29907+ for(i=(unsigned int)(skb->head); i<(unsigned int)(skb->end); i++) {
29908+ printk(":%2x", (unsigned char)(*(char*)(i)));
29909+ }
29910+ }
29911+ printk(" destructor:%p", skb->destructor);
29912+ printk("\n");
29913+ }
29914+#endif /* CONFIG_IPSEC_DEBUG */
29915+ KLIPS_PRINT(debug_pfkey,
29916+ "klips_debug:pfkey_destroy_socket: skb=%p freed.\n", skb);
29917+ kfree_skb(skb);
29918+
29919+#else /* NET_21 */
29920+ KLIPS_PRINT(debug_pfkey,
29921+ "klips_debug:pfkey_destroy_socket: skb=%p dequeued and freed.\n", skb);
29922+ kfree_skb(skb, FREE_WRITE);
29923+
29924+#endif /* NET_21 */
29925+ }
29926+
29927+ sk->dead = 1;
29928+ sk_free(sk);
29929+
29930+ KLIPS_PRINT(debug_pfkey,
29931+ "klips_debug:pfkey_destroy_socket: destroyed.\n");
29932+}
29933+
29934+int
29935+pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
29936+{
29937+ int error;
29938+ struct sk_buff * skb = NULL;
29939+ struct sock *sk;
29940+
29941+ if(sock == NULL) {
29942+ KLIPS_PRINT(debug_pfkey,
29943+ "klips_debug:pfkey_upmsg: NULL socket passed in.\n");
29944+ return -EINVAL;
29945+ }
29946+
29947+ if(pfkey_msg == NULL) {
29948+ KLIPS_PRINT(debug_pfkey,
29949+ "klips_debug:pfkey_upmsg: NULL pfkey_msg passed in.\n");
29950+ return -EINVAL;
29951+ }
29952+
29953+#ifdef NET_21
29954+ sk = sock->sk;
29955+#else /* NET_21 */
29956+ sk = sock->data;
29957+#endif /* NET_21 */
29958+
29959+ if(sk == NULL) {
29960+ KLIPS_PRINT(debug_pfkey,
29961+ "klips_debug:pfkey_upmsg: NULL sock passed in.\n");
29962+ return -EINVAL;
29963+ }
29964+
29965+ KLIPS_PRINT(debug_pfkey,
29966+ "klips_debug:pfkey_upmsg: allocating %d bytes...\n",
29967+ pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
29968+ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
29969+ KLIPS_PRINT(debug_pfkey,
29970+ "klips_debug:pfkey_upmsg: no buffers left to send up a message.\n");
29971+ return -ENOBUFS;
29972+ }
29973+ KLIPS_PRINT(debug_pfkey,
29974+ "klips_debug:pfkey_upmsg: ...allocated at %p.\n", skb);
29975+
29976+ skb->dev = NULL;
29977+
29978+ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
29979+ printk(KERN_WARNING "klips_error:pfkey_upmsg: "
29980+ "tried to skb_put %ld, %d available. "
29981+ "This should never happen, please report.\n",
29982+ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
29983+ skb_tailroom(skb));
29984+#ifdef NET_21
29985+ kfree_skb(skb);
29986+#else /* NET_21 */
29987+ kfree_skb(skb, FREE_WRITE);
29988+#endif /* NET_21 */
29989+ return -ENOBUFS;
29990+ }
29991+ skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
29992+ memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
29993+
29994+#ifndef NET_21
29995+ skb->free = 1;
29996+#endif /* !NET_21 */
29997+
29998+ if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
29999+ skb->sk=NULL;
30000+#ifdef NET_21
30001+ kfree_skb(skb);
30002+#else /* NET_21 */
30003+ kfree_skb(skb, FREE_WRITE);
30004+#endif /* NET_21 */
30005+ KLIPS_PRINT(debug_pfkey,
30006+ "klips_debug:pfkey_upmsg: "
30007+ "error=%d calling sock_queue_rcv_skb with skb=%p.\n",
30008+ error, skb);
30009+ return error;
30010+ }
30011+ return 0;
30012+}
30013+
30014+DEBUG_NO_STATIC int
30015+pfkey_create(struct socket *sock, int protocol)
30016+{
30017+ struct sock *sk;
30018+
30019+ if(sock == NULL) {
30020+ KLIPS_PRINT(debug_pfkey,
30021+ "klips_debug:pfkey_create: socket NULL.\n");
30022+ return -EINVAL;
30023+ }
30024+
30025+ KLIPS_PRINT(debug_pfkey,
30026+ "klips_debug:pfkey_create: sock=%p type:%d state:%d flags:%ld protocol:%d\n",
30027+ sock,
30028+ sock->type,
30029+ (unsigned int)(sock->state),
30030+ sock->flags, protocol);
30031+
30032+ if(sock->type != SOCK_RAW) {
30033+ KLIPS_PRINT(debug_pfkey,
30034+ "klips_debug:pfkey_create: only SOCK_RAW supported.\n");
30035+ return -ESOCKTNOSUPPORT;
30036+ }
30037+
30038+ if(protocol != PF_KEY_V2) {
30039+ KLIPS_PRINT(debug_pfkey,
30040+ "klips_debug:pfkey_create: protocol not PF_KEY_V2.\n");
30041+ return -EPROTONOSUPPORT;
30042+ }
30043+
30044+ if((current->uid != 0)) {
30045+ KLIPS_PRINT(debug_pfkey,
30046+ "klips_debug:pfkey_create: must be root to open pfkey sockets.\n");
30047+ return -EACCES;
30048+ }
30049+
30050+#ifdef NET_21
30051+ sock->state = SS_UNCONNECTED;
30052+#endif /* NET_21 */
30053+ MOD_INC_USE_COUNT;
30054+#ifdef NET_21
30055+ if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL)
30056+#else /* NET_21 */
30057+ if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL)
30058+#endif /* NET_21 */
30059+ {
30060+ KLIPS_PRINT(debug_pfkey,
30061+ "klips_debug:pfkey_create: Out of memory trying to allocate.\n");
30062+ MOD_DEC_USE_COUNT;
30063+ return -ENOMEM;
30064+ }
30065+
30066+#ifndef NET_21
30067+ memset(sk, 0, sizeof(*sk));
30068+#endif /* !NET_21 */
30069+
30070+#ifdef NET_21
30071+ sock_init_data(sock, sk);
30072+
30073+ sk->destruct = NULL;
30074+ sk->reuse = 1;
30075+ sock->ops = &SOCKOPS_WRAPPED(pfkey_ops);
30076+
30077+ sk->zapped=0;
30078+ sk->family = PF_KEY;
30079+/* sk->num = protocol; */
30080+ sk->protocol = protocol;
30081+ key_pid(sk) = current->pid;
30082+ KLIPS_PRINT(debug_pfkey,
30083+ "klips_debug:pfkey_create: sock->fasync_list=%p sk->sleep=%p.\n",
30084+ sock->fasync_list,
30085+ sk->sleep);
30086+#else /* NET_21 */
30087+ sk->type=sock->type;
30088+ init_timer(&sk->timer);
30089+ skb_queue_head_init(&sk->write_queue);
30090+ skb_queue_head_init(&sk->receive_queue);
30091+ skb_queue_head_init(&sk->back_log);
30092+ sk->rcvbuf=SK_RMEM_MAX;
30093+ sk->sndbuf=SK_WMEM_MAX;
30094+ sk->allocation=GFP_KERNEL;
30095+ sk->state=TCP_CLOSE;
30096+ sk->priority=SOPRI_NORMAL;
30097+ sk->state_change=pfkey_state_change;
30098+ sk->data_ready=pfkey_data_ready;
30099+ sk->write_space=pfkey_write_space;
30100+ sk->error_report=pfkey_state_change;
30101+ sk->mtu=4096;
30102+ sk->socket=sock;
30103+ sock->data=(void *)sk;
30104+ sk->sleep=sock->wait;
30105+#endif /* NET_21 */
30106+
30107+ pfkey_insert_socket(sk);
30108+ pfkey_list_insert_socket(sock, &pfkey_open_sockets);
30109+
30110+ KLIPS_PRINT(debug_pfkey,
30111+ "klips_debug:pfkey_create: Socket sock=%p sk=%p initialised.\n", sock, sk);
30112+ return 0;
30113+}
30114+
30115+#ifndef NET_21
30116+DEBUG_NO_STATIC int
30117+pfkey_dup(struct socket *newsock, struct socket *oldsock)
30118+{
30119+ struct sock *sk;
30120+
30121+ if(newsock==NULL) {
30122+ KLIPS_PRINT(debug_pfkey,
30123+ "klips_debug:pfkey_dup: No new socket attached.\n");
30124+ return -EINVAL;
30125+ }
30126+
30127+ if(oldsock==NULL) {
30128+ KLIPS_PRINT(debug_pfkey,
30129+ "klips_debug:pfkey_dup: No old socket attached.\n");
30130+ return -EINVAL;
30131+ }
30132+
30133+#ifdef NET_21
30134+ sk=oldsock->sk;
30135+#else /* NET_21 */
30136+ sk=oldsock->data;
30137+#endif /* NET_21 */
30138+
30139+ /* May not have data attached */
30140+ if(sk==NULL) {
30141+ KLIPS_PRINT(debug_pfkey,
30142+ "klips_debug:pfkey_dup: No sock attached to old socket.\n");
30143+ return -EINVAL;
30144+ }
30145+
30146+ KLIPS_PRINT(debug_pfkey,
30147+ "klips_debug:pfkey_dup: .\n");
30148+
30149+ return pfkey_create(newsock, sk->protocol);
30150+}
30151+#endif /* !NET_21 */
30152+
30153+DEBUG_NO_STATIC int
30154+#ifdef NETDEV_23
30155+pfkey_release(struct socket *sock)
30156+#else
30157+pfkey_release(struct socket *sock, struct socket *peersock)
30158+#endif
30159+{
30160+ struct sock *sk;
30161+ int i;
30162+
30163+ if(sock==NULL) {
30164+ KLIPS_PRINT(debug_pfkey,
30165+ "klips_debug:pfkey_release: No socket attached.\n");
30166+ return 0; /* -EINVAL; */
30167+ }
30168+
30169+#ifdef NET_21
30170+ sk=sock->sk;
30171+#else /* NET_21 */
30172+ sk=sock->data;
30173+#endif /* NET_21 */
30174+
30175+ /* May not have data attached */
30176+ if(sk==NULL) {
30177+ KLIPS_PRINT(debug_pfkey,
30178+ "klips_debug:pfkey_release: No sk attached to sock=%p.\n", sock);
30179+ return 0; /* -EINVAL; */
30180+ }
30181+
30182+ KLIPS_PRINT(debug_pfkey,
30183+ "klips_debug:pfkey_release: .sock=%p sk=%p\n", sock, sk);
30184+
30185+#ifdef NET_21
30186+ if(!sk->dead)
30187+#endif /* NET_21 */
30188+ if(sk->state_change) {
30189+ sk->state_change(sk);
30190+ }
30191+
30192+#ifdef NET_21
30193+ sock->sk = NULL;
30194+#else /* NET_21 */
30195+ sock->data = NULL;
30196+#endif /* NET_21 */
30197+
30198+ /* Try to flush out this socket. Throw out buffers at least */
30199+ pfkey_destroy_socket(sk);
30200+ pfkey_list_remove_socket(sock, &pfkey_open_sockets);
30201+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
30202+ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
30203+ }
30204+
30205+ MOD_DEC_USE_COUNT;
30206+ KLIPS_PRINT(debug_pfkey,
30207+ "klips_debug:pfkey_release: succeeded.\n");
30208+
30209+ return 0;
30210+}
30211+
30212+#ifndef NET_21
30213+DEBUG_NO_STATIC int
30214+pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
30215+{
30216+ KLIPS_PRINT(debug_pfkey,
30217+ "klips_debug:pfkey_bind: operation not supported.\n");
30218+ return -EINVAL;
30219+}
30220+
30221+DEBUG_NO_STATIC int
30222+pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
30223+{
30224+ KLIPS_PRINT(debug_pfkey,
30225+ "klips_debug:pfkey_connect: operation not supported.\n");
30226+ return -EINVAL;
30227+}
30228+
30229+DEBUG_NO_STATIC int
30230+pfkey_socketpair(struct socket *a, struct socket *b)
30231+{
30232+ KLIPS_PRINT(debug_pfkey,
30233+ "klips_debug:pfkey_socketpair: operation not supported.\n");
30234+ return -EINVAL;
30235+}
30236+
30237+DEBUG_NO_STATIC int
30238+pfkey_accept(struct socket *sock, struct socket *newsock, int flags)
30239+{
30240+ KLIPS_PRINT(debug_pfkey,
30241+ "klips_debug:pfkey_aaccept: operation not supported.\n");
30242+ return -EINVAL;
30243+}
30244+
30245+DEBUG_NO_STATIC int
30246+pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len,
30247+ int peer)
30248+{
30249+ struct sockaddr *ska = (struct sockaddr*)uaddr;
30250+
30251+ KLIPS_PRINT(debug_pfkey,
30252+ "klips_debug:pfkey_getname: .\n");
30253+ ska->sa_family = PF_KEY;
30254+ *uaddr_len = sizeof(*ska);
30255+ return 0;
30256+}
30257+
30258+DEBUG_NO_STATIC int
30259+pfkey_select(struct socket *sock, int sel_type, select_table *wait)
30260+{
30261+
30262+ KLIPS_PRINT(debug_pfkey,
30263+ "klips_debug:pfkey_select: .sock=%p sk=%p sel_type=%d\n",
30264+ sock,
30265+ sock->data,
30266+ sel_type);
30267+ if(sock == NULL) {
30268+ KLIPS_PRINT(debug_pfkey,
30269+ "klips_debug:pfkey_select: Null socket passed in.\n");
30270+ return -EINVAL;
30271+ }
30272+ return datagram_select(sock->data, sel_type, wait);
30273+}
30274+
30275+DEBUG_NO_STATIC int
30276+pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
30277+{
30278+ KLIPS_PRINT(debug_pfkey,
30279+ "klips_debug:pfkey_ioctl: not supported.\n");
30280+ return -EINVAL;
30281+}
30282+
30283+DEBUG_NO_STATIC int
30284+pfkey_listen(struct socket *sock, int backlog)
30285+{
30286+ KLIPS_PRINT(debug_pfkey,
30287+ "klips_debug:pfkey_listen: not supported.\n");
30288+ return -EINVAL;
30289+}
30290+#endif /* !NET_21 */
30291+
30292+DEBUG_NO_STATIC int
30293+pfkey_shutdown(struct socket *sock, int mode)
30294+{
30295+ struct sock *sk;
30296+
30297+ if(sock == NULL) {
30298+ KLIPS_PRINT(debug_pfkey,
30299+ "klips_debug:pfkey_shutdown: NULL socket passed in.\n");
30300+ return -EINVAL;
30301+ }
30302+
30303+#ifdef NET_21
30304+ sk=sock->sk;
30305+#else /* NET_21 */
30306+ sk=sock->data;
30307+#endif /* NET_21 */
30308+
30309+ if(sk == NULL) {
30310+ KLIPS_PRINT(debug_pfkey,
30311+ "klips_debug:pfkey_shutdown: No sock attached to socket.\n");
30312+ return -EINVAL;
30313+ }
30314+
30315+ KLIPS_PRINT(debug_pfkey,
30316+ "klips_debug:pfkey_shutdown: mode=%x.\n", mode);
30317+ mode++;
30318+
30319+ if(mode&SEND_SHUTDOWN) {
30320+ sk->shutdown|=SEND_SHUTDOWN;
30321+ sk->state_change(sk);
30322+ }
30323+
30324+ if(mode&RCV_SHUTDOWN) {
30325+ sk->shutdown|=RCV_SHUTDOWN;
30326+ sk->state_change(sk);
30327+ }
30328+ return 0;
30329+}
30330+
30331+#ifndef NET_21
30332+DEBUG_NO_STATIC int
30333+pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
30334+{
30335+#ifndef NET_21
30336+ struct sock *sk;
30337+
30338+ if(sock == NULL) {
30339+ KLIPS_PRINT(debug_pfkey,
30340+ "klips_debug:pfkey_setsockopt: Null socket passed in.\n");
30341+ return -EINVAL;
30342+ }
30343+
30344+ sk=sock->data;
30345+
30346+ if(sk == NULL) {
30347+ KLIPS_PRINT(debug_pfkey,
30348+ "klips_debug:pfkey_setsockopt: Null sock passed in.\n");
30349+ return -EINVAL;
30350+ }
30351+#endif /* !NET_21 */
30352+
30353+ KLIPS_PRINT(debug_pfkey,
30354+ "klips_debug:pfkey_setsockopt: .\n");
30355+ if(level!=SOL_SOCKET) {
30356+ return -EOPNOTSUPP;
30357+ }
30358+#ifdef NET_21
30359+ return sock_setsockopt(sock, level, optname, optval, optlen);
30360+#else /* NET_21 */
30361+ return sock_setsockopt(sk, level, optname, optval, optlen);
30362+#endif /* NET_21 */
30363+}
30364+
30365+DEBUG_NO_STATIC int
30366+pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
30367+{
30368+#ifndef NET_21
30369+ struct sock *sk;
30370+
30371+ if(sock == NULL) {
30372+ KLIPS_PRINT(debug_pfkey,
30373+ "klips_debug:pfkey_setsockopt: Null socket passed in.\n");
30374+ return -EINVAL;
30375+ }
30376+
30377+ sk=sock->data;
30378+
30379+ if(sk == NULL) {
30380+ KLIPS_PRINT(debug_pfkey,
30381+ "klips_debug:pfkey_setsockopt: Null sock passed in.\n");
30382+ return -EINVAL;
30383+ }
30384+#endif /* !NET_21 */
30385+
30386+ KLIPS_PRINT(debug_pfkey,
30387+ "klips_debug:pfkey_getsockopt: .\n");
30388+ if(level!=SOL_SOCKET) {
30389+ return -EOPNOTSUPP;
30390+ }
30391+#ifdef NET_21
30392+ return sock_getsockopt(sock, level, optname, optval, optlen);
30393+#else /* NET_21 */
30394+ return sock_getsockopt(sk, level, optname, optval, optlen);
30395+#endif /* NET_21 */
30396+}
30397+
30398+DEBUG_NO_STATIC int
30399+pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
30400+{
30401+ KLIPS_PRINT(debug_pfkey,
30402+ "klips_debug:pfkey_fcntl: "
30403+ "not supported.\n");
30404+ return -EINVAL;
30405+}
30406+#endif /* !NET_21 */
30407+
30408+/*
30409+ * Send PF_KEY data down.
30410+ */
30411+
30412+DEBUG_NO_STATIC int
30413+#ifdef NET_21
30414+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
30415+#else /* NET_21 */
30416+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
30417+#endif /* NET_21 */
30418+{
30419+ struct sock *sk;
30420+ int error = 0;
30421+ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
30422+
30423+ if(sock == NULL) {
30424+ KLIPS_PRINT(debug_pfkey,
30425+ "klips_debug:pfkey_sendmsg: "
30426+ "Null socket passed in.\n");
30427+ SENDERR(EINVAL);
30428+ }
30429+
30430+#ifdef NET_21
30431+ sk = sock->sk;
30432+#else /* NET_21 */
30433+ sk = sock->data;
30434+#endif /* NET_21 */
30435+
30436+ if(sk == NULL) {
30437+ KLIPS_PRINT(debug_pfkey,
30438+ "klips_debug:pfkey_sendmsg: "
30439+ "Null sock passed in.\n");
30440+ SENDERR(EINVAL);
30441+ }
30442+
30443+ if(msg == NULL) {
30444+ KLIPS_PRINT(debug_pfkey,
30445+ "klips_debug:pfkey_sendmsg: "
30446+ "Null msghdr passed in.\n");
30447+ SENDERR(EINVAL);
30448+ }
30449+
30450+ KLIPS_PRINT(debug_pfkey,
30451+ "klips_debug:pfkey_sendmsg: .\n");
30452+ if(sk->err) {
30453+ error = sock_error(sk);
30454+ KLIPS_PRINT(debug_pfkey,
30455+ "klips_debug:pfkey_sendmsg: "
30456+ "sk->err is non-zero, returns %d.\n",
30457+ error);
30458+ SENDERR(-error);
30459+ }
30460+
30461+ if((current->uid != 0)) {
30462+ KLIPS_PRINT(debug_pfkey,
30463+ "klips_debug:pfkey_sendmsg: "
30464+ "must be root to send messages to pfkey sockets.\n");
30465+ SENDERR(EACCES);
30466+ }
30467+
30468+#ifdef NET_21
30469+ if(msg->msg_control)
30470+#else /* NET_21 */
30471+ if(flags || msg->msg_control)
30472+#endif /* NET_21 */
30473+ {
30474+ KLIPS_PRINT(debug_pfkey,
30475+ "klips_debug:pfkey_sendmsg: "
30476+ "can't set flags or set msg_control.\n");
30477+ SENDERR(EINVAL);
30478+ }
30479+
30480+ if(sk->shutdown & SEND_SHUTDOWN) {
30481+ KLIPS_PRINT(debug_pfkey,
30482+ "klips_debug:pfkey_sendmsg: "
30483+ "shutdown.\n");
30484+ send_sig(SIGPIPE, current, 0);
30485+ SENDERR(EPIPE);
30486+ }
30487+
30488+ if(len < sizeof(struct sadb_msg)) {
30489+ KLIPS_PRINT(debug_pfkey,
30490+ "klips_debug:pfkey_sendmsg: "
30491+ "bogus msg len of %d, too small.\n", len);
30492+ SENDERR(EMSGSIZE);
30493+ }
30494+
30495+ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
30496+ KLIPS_PRINT(debug_pfkey,
30497+ "klips_debug:pfkey_sendmsg: "
30498+ "memory allocation error.\n");
30499+ SENDERR(ENOBUFS);
30500+ }
30501+
30502+ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
30503+
30504+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
30505+ KLIPS_PRINT(1 || debug_pfkey,
30506+ "klips_debug:pfkey_sendmsg: "
30507+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
30508+ pfkey_msg->sadb_msg_version,
30509+ PF_KEY_V2);
30510+ kfree((void*)pfkey_msg);
30511+ return -EINVAL;
30512+ }
30513+
30514+ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
30515+ KLIPS_PRINT(debug_pfkey,
30516+ "klips_debug:pfkey_sendmsg: "
30517+ "bogus msg len of %d, not %d byte aligned.\n",
30518+ len, IPSEC_PFKEYv2_ALIGN);
30519+ SENDERR(EMSGSIZE);
30520+ }
30521+
30522+ /* check PID */
30523+ if(pfkey_msg->sadb_msg_pid != current->pid) {
30524+ KLIPS_PRINT(debug_pfkey,
30525+ "klips_debug:pfkey_sendmsg: "
30526+ "pid (%d) does not equal sending process pid (%d).\n",
30527+ pfkey_msg->sadb_msg_pid, current->pid);
30528+ SENDERR(EINVAL);
30529+ }
30530+
30531+ if(pfkey_msg->sadb_msg_reserved) {
30532+ KLIPS_PRINT(debug_pfkey,
30533+ "klips_debug:pfkey_sendmsg: "
30534+ "reserved field must be zero, set to %d.\n",
30535+ pfkey_msg->sadb_msg_reserved);
30536+ SENDERR(EINVAL);
30537+ }
30538+
30539+ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
30540+ KLIPS_PRINT(debug_pfkey,
30541+ "klips_debug:pfkey_sendmsg: "
30542+ "msg type too large or small:%d.\n",
30543+ pfkey_msg->sadb_msg_type);
30544+ SENDERR(EINVAL);
30545+ }
30546+
30547+ KLIPS_PRINT(debug_pfkey,
30548+ "klips_debug:pfkey_sendmsg: "
30549+ "msg sent for parsing.\n");
30550+
30551+ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
30552+ struct socket_list *pfkey_socketsp;
30553+
30554+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
30555+ "pfkey_msg_parse returns %d.\n",
30556+ error);
30557+
30558+ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
30559+ KLIPS_PRINT(debug_pfkey,
30560+ "klips_debug:pfkey_sendmsg: "
30561+ "memory allocation error.\n");
30562+ SENDERR(ENOBUFS);
30563+ }
30564+ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
30565+ pfkey_reply->sadb_msg_errno = -error;
30566+ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
30567+
30568+ for(pfkey_socketsp = pfkey_open_sockets;
30569+ pfkey_socketsp;
30570+ pfkey_socketsp = pfkey_socketsp->next) {
30571+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
30572+ "sending up error=%d message=%p to socket=%p.\n",
30573+ error,
30574+ pfkey_reply,
30575+ pfkey_socketsp->socketp);
30576+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
30577+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
30578+ "sending up error message to socket=%p failed with error=%d.\n",
30579+ pfkey_socketsp->socketp, error);
30580+ pfkey_msg_free(&pfkey_reply);
30581+ goto errlab;
30582+ }
30583+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
30584+ "sending up error message to socket=%p succeeded.\n",
30585+ pfkey_socketsp->socketp);
30586+ }
30587+
30588+ pfkey_msg_free(&pfkey_reply);
30589+
30590+ SENDERR(-error);
30591+ }
30592+
30593+ errlab:
30594+ if (pfkey_msg) {
30595+ kfree((void*)pfkey_msg);
30596+ }
30597+
30598+ if(error) {
30599+ return error;
30600+ } else {
30601+ return len;
30602+ }
30603+}
30604+
30605+/*
30606+ * Receive PF_KEY data up.
30607+ */
30608+
30609+DEBUG_NO_STATIC int
30610+#ifdef NET_21
30611+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm)
30612+#else /* NET_21 */
30613+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)
30614+#endif /* NET_21 */
30615+{
30616+ struct sock *sk;
30617+#ifdef NET_21
30618+ int noblock = flags & MSG_DONTWAIT;
30619+#endif /* NET_21 */
30620+ struct sk_buff *skb;
30621+ int error;
30622+
30623+ if(sock == NULL) {
30624+ KLIPS_PRINT(debug_pfkey,
30625+ "klips_debug:pfkey_recvmsg: Null socket passed in.\n");
30626+ return -EINVAL;
30627+ }
30628+
30629+#ifdef NET_21
30630+ sk = sock->sk;
30631+#else /* NET_21 */
30632+ sk = sock->data;
30633+#endif /* NET_21 */
30634+
30635+ if(sk == NULL) {
30636+ KLIPS_PRINT(debug_pfkey,
30637+ "klips_debug:pfkey_recvmsg: Null sock passed in for sock=%p.\n", sock);
30638+ return -EINVAL;
30639+ }
30640+
30641+ if(msg == NULL) {
30642+ KLIPS_PRINT(debug_pfkey,
30643+ "klips_debug:pfkey_recvmsg: Null msghdr passed in for sock=%p, sk=%p.\n",
30644+ sock, sk);
30645+ return -EINVAL;
30646+ }
30647+
30648+ KLIPS_PRINT(debug_pfkey,
30649+ "klips_debug:pfkey_recvmsg: sock=%p sk=%p msg=%p size=%d.\n",
30650+ sock, sk, msg, size);
30651+ if(flags & ~MSG_PEEK) {
30652+ KLIPS_PRINT(debug_pfkey,
30653+ "klips_debug:pfkey_sendmsg: flags (%d) other than MSG_PEEK not supported.\n",
30654+ flags);
30655+ return -EOPNOTSUPP;
30656+ }
30657+
30658+#ifdef NET_21
30659+ msg->msg_namelen = 0; /* sizeof(*ska); */
30660+#else /* NET_21 */
30661+ if(addr_len) {
30662+ *addr_len = 0; /* sizeof(*ska); */
30663+ }
30664+#endif /* NET_21 */
30665+
30666+ if(sk->err) {
30667+ KLIPS_PRINT(debug_pfkey,
30668+ "klips_debug:pfkey_sendmsg: sk->err=%d.\n", sk->err);
30669+ return sock_error(sk);
30670+ }
30671+
30672+ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
30673+ return error;
30674+ }
30675+
30676+ if(size > skb->len) {
30677+ size = skb->len;
30678+ }
30679+#ifdef NET_21
30680+ else if(size <skb->len) {
30681+ msg->msg_flags |= MSG_TRUNC;
30682+ }
30683+#endif /* NET_21 */
30684+
30685+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
30686+ sk->stamp=skb->stamp;
30687+
30688+ skb_free_datagram(sk, skb);
30689+ return size;
30690+}
30691+
30692+#ifdef NET_21
30693+struct net_proto_family pfkey_family_ops = {
30694+ PF_KEY,
30695+ pfkey_create
30696+};
30697+
30698+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
30699+#ifdef NETDEV_23
30700+ family: PF_KEY,
30701+ release: pfkey_release,
30702+ bind: sock_no_bind,
30703+ connect: sock_no_connect,
30704+ socketpair: sock_no_socketpair,
30705+ accept: sock_no_accept,
30706+ getname: sock_no_getname,
30707+ poll: datagram_poll,
30708+ ioctl: sock_no_ioctl,
30709+ listen: sock_no_listen,
30710+ shutdown: pfkey_shutdown,
30711+ setsockopt: sock_no_setsockopt,
30712+ getsockopt: sock_no_getsockopt,
30713+ sendmsg: pfkey_sendmsg,
30714+ recvmsg: pfkey_recvmsg,
30715+ mmap: sock_no_mmap,
30716+#else
30717+ PF_KEY,
30718+ sock_no_dup,
30719+ pfkey_release,
30720+ sock_no_bind,
30721+ sock_no_connect,
30722+ sock_no_socketpair,
30723+ sock_no_accept,
30724+ sock_no_getname,
30725+ datagram_poll,
30726+ sock_no_ioctl,
30727+ sock_no_listen,
30728+ pfkey_shutdown,
30729+ sock_no_setsockopt,
30730+ sock_no_getsockopt,
30731+ sock_no_fcntl,
30732+ pfkey_sendmsg,
30733+ pfkey_recvmsg
30734+#endif
30735+};
30736+
30737+#ifdef NETDEV_23
30738+#include <linux/smp_lock.h>
30739+SOCKOPS_WRAP(pfkey, PF_KEY);
30740+#endif
30741+
30742+#else /* NET_21 */
30743+struct proto_ops pfkey_proto_ops = {
30744+ PF_KEY,
30745+ pfkey_create,
30746+ pfkey_dup,
30747+ pfkey_release,
30748+ pfkey_bind,
30749+ pfkey_connect,
30750+ pfkey_socketpair,
30751+ pfkey_accept,
30752+ pfkey_getname,
30753+ pfkey_select,
30754+ pfkey_ioctl,
30755+ pfkey_listen,
30756+ pfkey_shutdown,
30757+ pfkey_setsockopt,
30758+ pfkey_getsockopt,
30759+ pfkey_fcntl,
30760+ pfkey_sendmsg,
30761+ pfkey_recvmsg
30762+};
30763+#endif /* NET_21 */
30764+
30765+#ifdef CONFIG_PROC_FS
30766+#ifndef PROC_FS_2325
30767+DEBUG_NO_STATIC
30768+#endif /* PROC_FS_2325 */
30769+int
30770+pfkey_get_info(char *buffer, char **start, off_t offset, int length
30771+#ifndef PROC_NO_DUMMY
30772+, int dummy
30773+#endif /* !PROC_NO_DUMMY */
30774+)
30775+{
30776+ off_t pos=0;
30777+ off_t begin=0;
30778+ int len=0;
30779+ struct sock *sk=pfkey_sock_list;
30780+
30781+#ifdef CONFIG_IPSEC_DEBUG
30782+ if(!sysctl_ipsec_debug_verbose) {
30783+#endif CONFIG_IPSEC_DEBUG
30784+ len+= sprintf(buffer," sock pid socket next prev e n p sndbf Flags Type St\n");
30785+#ifdef CONFIG_IPSEC_DEBUG
30786+ } else {
30787+ len+= sprintf(buffer," sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
30788+ }
30789+#endif CONFIG_IPSEC_DEBUG
30790+
30791+ while(sk!=NULL) {
30792+#ifdef CONFIG_IPSEC_DEBUG
30793+ if(!sysctl_ipsec_debug_verbose) {
30794+#endif CONFIG_IPSEC_DEBUG
30795+ len+=sprintf(buffer+len,"%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n",
30796+ sk,
30797+ key_pid(sk),
30798+ sk->socket,
30799+ sk->next,
30800+ sk->prev,
30801+ sk->err,
30802+ sk->num,
30803+ sk->protocol,
30804+ sk->sndbuf,
30805+ sk->socket->flags,
30806+ sk->socket->type,
30807+ sk->socket->state);
30808+#ifdef CONFIG_IPSEC_DEBUG
30809+ } else {
30810+ len+=sprintf(buffer+len,"%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
30811+ sk,
30812+ key_pid(sk),
30813+ sk->dead,
30814+ sk->sleep,
30815+ sk->socket,
30816+ sk->next,
30817+ sk->prev,
30818+ sk->err,
30819+ sk->reuse,
30820+ sk->zapped,
30821+ sk->num,
30822+ sk->protocol,
30823+ sk->sndbuf,
30824+ (unsigned int)sk->stamp.tv_sec,
30825+ (unsigned int)sk->stamp.tv_usec,
30826+ sk->socket->flags,
30827+ sk->socket->type,
30828+ sk->socket->state);
30829+ }
30830+#endif CONFIG_IPSEC_DEBUG
30831+
30832+ pos=begin+len;
30833+ if(pos<offset)
30834+ {
30835+ len=0;
30836+ begin=pos;
30837+ }
30838+ if(pos>offset+length)
30839+ break;
30840+ sk=sk->next;
30841+ }
30842+ *start=buffer+(offset-begin);
30843+ len-=(offset-begin);
30844+ if(len>length)
30845+ len=length;
30846+ return len;
30847+}
30848+
30849+#ifndef PROC_FS_2325
30850+DEBUG_NO_STATIC
30851+#endif /* PROC_FS_2325 */
30852+int
30853+pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
30854+#ifndef PROC_NO_DUMMY
30855+, int dummy
30856+#endif /* !PROC_NO_DUMMY */
30857+)
30858+{
30859+ off_t pos=0;
30860+ off_t begin=0;
30861+ int len=0;
30862+ int satype;
30863+ struct supported_list *pfkey_supported_p;
30864+
30865+ len+= sprintf(buffer,"satype exttype alg_id ivlen minbits maxbits\n");
30866+
30867+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
30868+ pfkey_supported_p = pfkey_supported_list[satype];
30869+ while(pfkey_supported_p) {
30870+ len+=sprintf(buffer+len," %2d %2d %2d %3d %3d %3d\n",
30871+ satype,
30872+ pfkey_supported_p->supportedp->supported_alg_exttype,
30873+ pfkey_supported_p->supportedp->supported_alg_id,
30874+ pfkey_supported_p->supportedp->supported_alg_ivlen,
30875+ pfkey_supported_p->supportedp->supported_alg_minbits,
30876+ pfkey_supported_p->supportedp->supported_alg_maxbits);
30877+
30878+ pos=begin+len;
30879+ if(pos<offset) {
30880+ len=0;
30881+ begin=pos;
30882+ }
30883+ if(pos>offset+length)
30884+ break;
30885+ pfkey_supported_p = pfkey_supported_p->next;
30886+ }
30887+ }
30888+ *start=buffer+(offset-begin);
30889+ len-=(offset-begin);
30890+ if(len>length)
30891+ len=length;
30892+ return len;
30893+}
30894+
30895+#ifndef PROC_FS_2325
30896+DEBUG_NO_STATIC
30897+#endif /* PROC_FS_2325 */
30898+int
30899+pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
30900+#ifndef PROC_NO_DUMMY
30901+, int dummy
30902+#endif /* !PROC_NO_DUMMY */
30903+)
30904+{
30905+ off_t pos=0;
30906+ off_t begin=0;
30907+ int len=0;
30908+ int satype;
30909+ struct socket_list *pfkey_sockets;
30910+
30911+ len+= sprintf(buffer,"satype socket pid sk\n");
30912+
30913+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
30914+ pfkey_sockets = pfkey_registered_sockets[satype];
30915+ while(pfkey_sockets) {
30916+#ifdef NET_21
30917+ len+=sprintf(buffer+len," %2d %8p %5d %8p\n",
30918+ satype,
30919+ pfkey_sockets->socketp,
30920+ key_pid(pfkey_sockets->socketp->sk),
30921+ pfkey_sockets->socketp->sk);
30922+#else /* NET_21 */
30923+ len+=sprintf(buffer+len," %2d %8p N/A %8p\n",
30924+ satype,
30925+ pfkey_sockets->socketp,
30926+#if 0
30927+ key_pid((pfkey_sockets->socketp)->data),
30928+#endif
30929+ (pfkey_sockets->socketp)->data);
30930+#endif /* NET_21 */
30931+
30932+ pos=begin+len;
30933+ if(pos<offset) {
30934+ len=0;
30935+ begin=pos;
30936+ }
30937+ if(pos>offset+length)
30938+ break;
30939+ pfkey_sockets = pfkey_sockets->next;
30940+ }
30941+ }
30942+ *start=buffer+(offset-begin);
30943+ len-=(offset-begin);
30944+ if(len>length)
30945+ len=length;
30946+ return len;
30947+}
30948+
30949+#ifndef PROC_FS_2325
30950+struct proc_dir_entry proc_net_pfkey =
30951+{
30952+ 0,
30953+ 6, "pf_key",
30954+ S_IFREG | S_IRUGO, 1, 0, 0,
30955+ 0, &proc_net_inode_operations,
30956+ pfkey_get_info
30957+};
30958+struct proc_dir_entry proc_net_pfkey_supported =
30959+{
30960+ 0,
30961+ 16, "pf_key_supported",
30962+ S_IFREG | S_IRUGO, 1, 0, 0,
30963+ 0, &proc_net_inode_operations,
30964+ pfkey_supported_get_info
30965+};
30966+struct proc_dir_entry proc_net_pfkey_registered =
30967+{
30968+ 0,
30969+ 17, "pf_key_registered",
30970+ S_IFREG | S_IRUGO, 1, 0, 0,
30971+ 0, &proc_net_inode_operations,
30972+ pfkey_registered_get_info
30973+};
30974+#endif /* !PROC_FS_2325 */
30975+#endif /* CONFIG_PROC_FS */
30976+
30977+DEBUG_NO_STATIC int
30978+supported_add_all(int satype, struct supported supported[], int size)
30979+{
30980+ int i;
30981+ int error = 0;
30982+
30983+ KLIPS_PRINT(debug_pfkey,
30984+ "klips_debug:init_pfkey: "
30985+ "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct supported)[%d]=%d.\n",
30986+ satype,
30987+ size,
30988+ sizeof(struct supported),
30989+ size/sizeof(struct supported));
30990+
30991+ for(i = 0; i < size / sizeof(struct supported); i++) {
30992+
30993+ KLIPS_PRINT(debug_pfkey,
30994+ "klips_debug:init_pfkey: "
30995+ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
30996+ i,
30997+ satype,
30998+ supported[i].supported_alg_exttype,
30999+ supported[i].supported_alg_id,
31000+ supported[i].supported_alg_ivlen,
31001+ supported[i].supported_alg_minbits,
31002+ supported[i].supported_alg_maxbits);
31003+
31004+ error |= pfkey_list_insert_supported(&(supported[i]),
31005+ &(pfkey_supported_list[satype]));
31006+ }
31007+ return error;
31008+}
31009+
31010+DEBUG_NO_STATIC int
31011+supported_remove_all(int satype)
31012+{
31013+ int error = 0;
31014+ struct supported*supportedp;
31015+
31016+ while(pfkey_supported_list[satype]) {
31017+ supportedp = pfkey_supported_list[satype]->supportedp;
31018+ KLIPS_PRINT(debug_pfkey,
31019+ "klips_debug:init_pfkey: "
31020+ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
31021+ satype,
31022+ supportedp->supported_alg_exttype,
31023+ supportedp->supported_alg_id,
31024+ supportedp->supported_alg_ivlen,
31025+ supportedp->supported_alg_minbits,
31026+ supportedp->supported_alg_maxbits);
31027+
31028+ error |= pfkey_list_remove_supported(supportedp,
31029+ &(pfkey_supported_list[satype]));
31030+ }
31031+ return error;
31032+}
31033+
31034+int
31035+pfkey_init(void)
31036+{
31037+ int error = 0;
31038+ int i;
31039+
31040+ static struct supported supported_init_ah[] = {
31041+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
31042+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
31043+ };
31044+ static struct supported supported_init_esp[] = {
31045+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
31046+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
31047+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 128, 168, 168}
31048+ };
31049+ static struct supported supported_init_ipip[] = {
31050+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
31051+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
31052+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
31053+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
31054+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
31055+#endif
31056+ };
31057+#ifdef CONFIG_IPSEC_IPCOMP
31058+ static struct supported supported_init_ipcomp[] = {
31059+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
31060+ };
31061+#endif /* CONFIG_IPSEC_IPCOMP */
31062+
31063+ printk(KERN_INFO "FreeS/WAN: initialising PF_KEY domain sockets.\n");
31064+
31065+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
31066+ pfkey_registered_sockets[i] = NULL;
31067+ pfkey_supported_list[i] = NULL;
31068+ }
31069+
31070+ supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
31071+ supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
31072+#ifdef CONFIG_IPSEC_IPCOMP
31073+ supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
31074+#endif /* CONFIG_IPSEC_IPCOMP */
31075+ supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
31076+
31077+#ifdef NET_21
31078+ sock_register(&pfkey_family_ops);
31079+#else /* NET_21 */
31080+ sock_register(pfkey_proto_ops.family, &pfkey_proto_ops);
31081+#endif /* NET_21 */
31082+
31083+#ifdef CONFIG_PROC_FS
31084+# ifndef PROC_FS_2325
31085+# ifdef PROC_FS_21
31086+ proc_register(proc_net, &proc_net_pfkey);
31087+ proc_register(proc_net, &proc_net_pfkey_supported);
31088+ proc_register(proc_net, &proc_net_pfkey_registered);
31089+# else /* PROC_FS_21 */
31090+ proc_register_dynamic(&proc_net, &proc_net_pfkey);
31091+ proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
31092+ proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
31093+# endif /* PROC_FS_21 */
31094+# else /* !PROC_FS_2325 */
31095+ proc_net_create ("pf_key", 0, pfkey_get_info);
31096+ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
31097+ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
31098+# endif /* !PROC_FS_2325 */
31099+#endif /* CONFIG_PROC_FS */
31100+
31101+ return error;
31102+}
31103+
31104+int
31105+pfkey_cleanup(void)
31106+{
31107+ int error = 0;
31108+
31109+ printk(KERN_INFO "FreeS/WAN: shutting down PF_KEY domain sockets.\n");
31110+#ifdef NET_21
31111+ sock_unregister(PF_KEY);
31112+#else /* NET_21 */
31113+ sock_unregister(pfkey_proto_ops.family);
31114+#endif /* NET_21 */
31115+
31116+ supported_remove_all(SADB_SATYPE_AH);
31117+ supported_remove_all(SADB_SATYPE_ESP);
31118+#ifdef CONFIG_IPSEC_IPCOMP
31119+ supported_remove_all(SADB_X_SATYPE_COMP);
31120+#endif /* CONFIG_IPSEC_IPCOMP */
31121+ supported_remove_all(SADB_X_SATYPE_IPIP);
31122+
31123+#ifdef CONFIG_PROC_FS
31124+# ifndef PROC_FS_2325
31125+ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
31126+ printk("klips_debug:pfkey_cleanup: cannot unregister /proc/net/pf_key\n");
31127+ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
31128+ printk("klips_debug:pfkey_cleanup: cannot unregister /proc/net/pf_key_supported\n");
31129+ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
31130+ printk("klips_debug:pfkey_cleanup: cannot unregister /proc/net/pf_key_registered\n");
31131+# else /* !PROC_FS_2325 */
31132+ proc_net_remove ("pf_key");
31133+ proc_net_remove ("pf_key_supported");
31134+ proc_net_remove ("pf_key_registered");
31135+# endif /* !PROC_FS_2325 */
31136+#endif /* CONFIG_PROC_FS */
31137+
31138+ /* other module unloading cleanup happens here */
31139+ return error;
31140+}
31141+
31142+#ifdef MODULE
31143+#if 0
31144+int
31145+init_module(void)
31146+{
31147+ pfkey_init();
31148+ return 0;
31149+}
31150+
31151+void
31152+cleanup_module(void)
31153+{
31154+ pfkey_cleanup();
31155+}
31156+#endif /* 0 */
31157+#else /* MODULE */
31158+void
31159+pfkey_proto_init(struct net_proto *pro)
31160+{
31161+ pfkey_init();
31162+}
31163+#endif /* MODULE */
31164+
31165+/*
31166+ * $Log$
31167+ * Revision 1.49 2000/11/06 04:33:47 rgb
31168+ * Changed non-exported functions to DEBUG_NO_STATIC.
31169+ *
31170+ * Revision 1.48 2000/09/29 19:47:41 rgb
31171+ * Update copyright.
31172+ *
31173+ * Revision 1.47 2000/09/22 04:23:04 rgb
31174+ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
31175+ *
31176+ * Revision 1.46 2000/09/21 04:20:44 rgb
31177+ * Fixed array size off-by-one error. (Thanks Svenning!)
31178+ *
31179+ * Revision 1.45 2000/09/20 04:01:26 rgb
31180+ * Changed static functions to DEBUG_NO_STATIC for revealing function names
31181+ * in oopsen.
31182+ *
31183+ * Revision 1.44 2000/09/19 00:33:17 rgb
31184+ * 2.0 fixes.
31185+ *
31186+ * Revision 1.43 2000/09/16 01:28:13 rgb
31187+ * Fixed use of 0 in p format warning.
31188+ *
31189+ * Revision 1.42 2000/09/16 01:09:41 rgb
31190+ * Fixed debug format warning for pointers that was expecting ints.
31191+ *
31192+ * Revision 1.41 2000/09/13 15:54:00 rgb
31193+ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
31194+ * Moved supported algos add and remove to functions.
31195+ *
31196+ * Revision 1.40 2000/09/12 18:49:28 rgb
31197+ * Added IPIP tunnel and IPCOMP register support.
31198+ *
31199+ * Revision 1.39 2000/09/12 03:23:49 rgb
31200+ * Converted #if0 debugs to sysctl.
31201+ * Removed debug_pfkey initialisations that prevented no_debug loading or
31202+ * linking.
31203+ *
31204+ * Revision 1.38 2000/09/09 06:38:02 rgb
31205+ * Return positive errno in pfkey_reply error message.
31206+ *
31207+ * Revision 1.37 2000/09/08 19:19:09 rgb
31208+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
31209+ * Clean-up of long-unused crud...
31210+ * Create pfkey error message on on failure.
31211+ * Give pfkey_list_{insert,remove}_{socket,supported}() some error
31212+ * checking.
31213+ *
31214+ * Revision 1.36 2000/09/01 18:49:38 rgb
31215+ * Reap experimental NET_21_ bits.
31216+ * Turned registered sockets list into an array of one list per satype.
31217+ * Remove references to deprecated sklist_{insert,remove}_socket.
31218+ * Removed leaking socket debugging code.
31219+ * Removed duplicate pfkey_insert_socket in pfkey_create.
31220+ * Removed all references to pfkey msg->msg_name, since it is not used for
31221+ * pfkey.
31222+ * Added a supported algorithms array lists, one per satype and registered
31223+ * existing algorithms.
31224+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
31225+ * list.
31226+ * Only send pfkey_expire() messages to sockets registered for that satype.
31227+ *
31228+ * Revision 1.35 2000/08/24 17:03:00 rgb
31229+ * Corrected message size error return code for PF_KEYv2.
31230+ * Removed downward error prohibition.
31231+ *
31232+ * Revision 1.34 2000/08/21 16:32:26 rgb
31233+ * Re-formatted for cosmetic consistency and readability.
31234+ *
31235+ * Revision 1.33 2000/08/20 21:38:24 rgb
31236+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
31237+ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
31238+ *
31239+ * Revision 1.32 2000/07/28 14:58:31 rgb
31240+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
31241+ *
31242+ * Revision 1.31 2000/05/16 03:04:00 rgb
31243+ * Updates for 2.3.99pre8 from MB.
31244+ *
31245+ * Revision 1.30 2000/05/10 19:22:21 rgb
31246+ * Use sklist private functions for 2.3.xx compatibility.
31247+ *
31248+ * Revision 1.29 2000/03/22 16:17:03 rgb
31249+ * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
31250+ *
31251+ * Revision 1.28 2000/02/21 19:30:45 rgb
31252+ * Removed references to pkt_bridged for 2.3.47 compatibility.
31253+ *
31254+ * Revision 1.27 2000/02/14 21:07:00 rgb
31255+ * Fixed /proc/net/pf-key legend spacing.
31256+ *
31257+ * Revision 1.26 2000/01/22 03:46:59 rgb
31258+ * Fixed pfkey error return mechanism so that we are able to free the
31259+ * local copy of the pfkey_msg, plugging a memory leak and silencing
31260+ * the bad object free complaints.
31261+ *
31262+ * Revision 1.25 2000/01/21 06:19:44 rgb
31263+ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
31264+ * Added debugging to pfkey_upmsg.
31265+ *
31266+ * Revision 1.24 2000/01/10 16:38:23 rgb
31267+ * MB fixups for 2.3.x.
31268+ *
31269+ * Revision 1.23 1999/12/09 23:22:16 rgb
31270+ * Added more instrumentation for debugging 2.0 socket
31271+ * selection/reading.
31272+ * Removed erroneous 2.0 wait==NULL check bug in select.
31273+ *
31274+ * Revision 1.22 1999/12/08 20:32:16 rgb
31275+ * Tidied up 2.0.xx support, after major pfkey work, eliminating
31276+ * msg->msg_name twiddling in the process, since it is not defined
31277+ * for PF_KEYv2.
31278+ *
31279+ * Revision 1.21 1999/12/01 22:17:19 rgb
31280+ * Set skb->dev to zero on new skb in case it is a reused skb.
31281+ * Added check for skb_put overflow and freeing to avoid upmsg on error.
31282+ * Added check for wrong pfkey version and freeing to avoid upmsg on
31283+ * error.
31284+ * Shut off content dumping in pfkey_destroy.
31285+ * Added debugging message for size of buffer allocated for upmsg.
31286+ *
31287+ * Revision 1.20 1999/11/27 12:11:00 rgb
31288+ * Minor clean-up, enabling quiet operation of pfkey if desired.
31289+ *
31290+ * Revision 1.19 1999/11/25 19:04:21 rgb
31291+ * Update proc_fs code for pfkey to use dynamic registration.
31292+ *
31293+ * Revision 1.18 1999/11/25 09:07:17 rgb
31294+ * Implemented SENDERR macro for propagating error codes.
31295+ * Fixed error return code bug.
31296+ *
31297+ * Revision 1.17 1999/11/23 23:07:20 rgb
31298+ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
31299+ * parses. (PJO)
31300+ * Sort out pfkey and freeswan headers, putting them in a library path.
31301+ *
31302+ * Revision 1.16 1999/11/20 22:00:22 rgb
31303+ * Moved socketlist type declarations and prototypes for shared use.
31304+ * Renamed reformatted and generically extended for use by other socket
31305+ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
31306+ *
31307+ * Revision 1.15 1999/11/18 04:15:09 rgb
31308+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
31309+ * Clean up pfkey_destroy_socket() debugging statements.
31310+ * Add Peter Onion's code to send messages up to all listening sockets.
31311+ * Changed all occurrences of #include "../../../lib/freeswan.h"
31312+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
31313+ * klips/net/ipsec/Makefile.
31314+ * Replaced all kernel version macros to shorter, readable form.
31315+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
31316+ *
31317+ * Revision 1.14 1999/11/17 16:01:00 rgb
31318+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
31319+ * Clean up pfkey_destroy_socket() debugging statements.
31320+ * Add Peter Onion's code to send messages up to all listening sockets.
31321+ * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
31322+ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
31323+ *
31324+ * Revision 1.13 1999/10/27 19:59:51 rgb
31325+ * Removed af_unix comments that are no longer relevant.
31326+ * Added debug prink statements.
31327+ * Added to the /proc output in pfkey_get_info.
31328+ * Made most functions non-static to enable oops tracing.
31329+ * Re-enable skb dequeueing and freeing.
31330+ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
31331+ *
31332+ * Revision 1.12 1999/10/26 17:05:42 rgb
31333+ * Complete re-ordering based on proto_ops structure order.
31334+ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
31335+ * Simplification to use built-in socket ops where possible for 2.2.x.
31336+ * Add shorter macros for compiler directives to visually clean-up.
31337+ * Add lots of sk skb dequeueing debugging statements.
31338+ * Added to the /proc output in pfkey_get_info.
31339+ *
31340+ * Revision 1.11 1999/09/30 02:55:10 rgb
31341+ * Bogus skb detection.
31342+ * Fix incorrect /proc/net/ipsec-eroute printk message.
31343+ *
31344+ * Revision 1.10 1999/09/21 15:22:13 rgb
31345+ * Temporary fix while I figure out the right way to destroy sockets.
31346+ *
31347+ * Revision 1.9 1999/07/08 19:19:44 rgb
31348+ * Fix pointer format warning.
31349+ * Fix missing member error under 2.0.xx kernels.
31350+ *
31351+ * Revision 1.8 1999/06/13 07:24:04 rgb
31352+ * Add more debugging.
31353+ *
31354+ * Revision 1.7 1999/06/10 05:24:17 rgb
31355+ * Clarified compiler directives.
31356+ * Renamed variables to reduce confusion.
31357+ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
31358+ * Added lots of sanity checking.
31359+ *
31360+ * Revision 1.6 1999/06/03 18:59:50 rgb
31361+ * More updates to 2.2.x socket support. Almost works, oops at end of call.
31362+ *
31363+ * Revision 1.5 1999/05/25 22:44:05 rgb
31364+ * Start fixing 2.2 sockets.
31365+ *
31366+ * Revision 1.4 1999/04/29 15:21:34 rgb
31367+ * Move log to the end of the file.
31368+ * Eliminate min/max redefinition in #include <net/tcp.h>.
31369+ * Correct path for pfkey #includes
31370+ * Standardise an error return method.
31371+ * Add debugging instrumentation.
31372+ * Move message type checking to pfkey_msg_parse().
31373+ * Add check for errno incorrectly set.
31374+ * Add check for valid PID.
31375+ * Add check for reserved illegally set.
31376+ * Add check for message out of bounds.
31377+ *
31378+ * Revision 1.3 1999/04/15 17:58:07 rgb
31379+ * Add RCSID labels.
31380+ *
31381+ * Revision 1.2 1999/04/15 15:37:26 rgb
31382+ * Forward check changes from POST1_00 branch.
31383+ *
31384+ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
31385+ * Header Title correction.
31386+ *
31387+ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
31388+ * Add pfkeyv2 support to KLIPS.
31389+ *
31390+ *
31391+ * RFC 2367
31392+ * PF_KEY_v2 Key Management API
31393+ */
31394diff -druN linux-noipsec/net/ipsec/pfkey_v2_parser.c linux/net/ipsec/pfkey_v2_parser.c
31395--- linux-noipsec/net/ipsec/pfkey_v2_parser.c Thu Jan 1 01:00:00 1970
31396+++ linux/net/ipsec/pfkey_v2_parser.c Thu Nov 30 22:47:51 2000
31397@@ -0,0 +1,3433 @@
31398+/*
31399+ * RFC2367 PF_KEYv2 Key management API message parser
31400+ * Copyright (C) 1999 Richard Guy Briggs.
31401+ *
31402+ * This program is free software; you can redistribute it and/or modify it
31403+ * under the terms of the GNU General Public License as published by the
31404+ * Free Software Foundation; either version 2 of the License, or (at your
31405+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
31406+ *
31407+ * This program is distributed in the hope that it will be useful, but
31408+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
31409+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31410+ * for more details.
31411+ *
31412+ * RCSID $Id$
31413+ */
31414+
31415+/*
31416+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
31417+ */
31418+
31419+char pfkey_v2_parser_c_version[] = "$Id$";
31420+
31421+#include <linux/config.h>
31422+#include <linux/version.h>
31423+
31424+#include <linux/kernel.h> /* printk() */
31425+#include <linux/malloc.h> /* kmalloc() */
31426+#include <linux/errno.h> /* error codes */
31427+#include <linux/types.h> /* size_t */
31428+#include <linux/interrupt.h> /* mark_bh */
31429+
31430+#include <linux/netdevice.h> /* struct device, and other headers */
31431+#include <linux/etherdevice.h> /* eth_type_trans */
31432+#include <linux/ip.h> /* struct iphdr */
31433+#include <linux/skbuff.h>
31434+#include <freeswan.h>
31435+#ifdef SPINLOCK
31436+#ifdef SPINLOCK_23
31437+#include <linux/spinlock.h> /* *lock* */
31438+#else /* SPINLOCK_23 */
31439+#include <asm/spinlock.h> /* *lock* */
31440+#endif /* SPINLOCK_23 */
31441+#endif /* SPINLOCK */
31442+#ifdef NET_21
31443+#include <asm/uaccess.h>
31444+#include <linux/in6.h>
31445+#define ip_chk_addr inet_addr_type
31446+#define IS_MYADDR RTN_LOCAL
31447+#endif
31448+#include <asm/checksum.h>
31449+#include <net/ip.h>
31450+#ifdef NETLINK_SOCK
31451+#include <linux/netlink.h>
31452+#else
31453+#include <net/netlink.h>
31454+#endif
31455+
31456+#include <linux/random.h> /* get_random_bytes() */
31457+
31458+#include "radij.h"
31459+#include "ipsec_encap.h"
31460+#include "ipsec_radij.h"
31461+#include "ipsec_netlink.h"
31462+#include "ipsec_xform.h"
31463+#include "ipsec_ah.h"
31464+#include "ipsec_esp.h"
31465+#include "ipsec_tunnel.h"
31466+#include "ipsec_rcv.h"
31467+#include "ipcomp.h"
31468+
31469+#include <pfkeyv2.h>
31470+#include <pfkey.h>
31471+
31472+
31473+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
31474+
31475+#ifndef min
31476+#define min(a,b) (((a)<(b))?(a):(b))
31477+#endif
31478+
31479+extern int des_set_key(caddr_t, caddr_t);
31480+
31481+struct sklist_t {
31482+ struct socket *sk;
31483+ struct sklist_t* next;
31484+} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
31485+
31486+__u32 pfkey_msg_seq = 0;
31487+
31488+DEBUG_NO_STATIC int
31489+pfkey_alloc_tdb(struct tdb** tdb)
31490+{
31491+ int error = 0;
31492+ if(*tdb) {
31493+ KLIPS_PRINT(debug_pfkey,
31494+ "klips_debug:pfkey_alloc_tdb: tdb struct already allocated\n");
31495+ SENDERR(EEXIST);
31496+ }
31497+
31498+ if((*tdb = kmalloc(sizeof(**tdb), GFP_ATOMIC) ) == NULL) {
31499+ KLIPS_PRINT(debug_pfkey,
31500+ "klips_debug:pfkey_alloc_tdb: memory allocation error\n");
31501+ SENDERR(ENOMEM);
31502+ }
31503+ KLIPS_PRINT(debug_pfkey,
31504+ "klips_debug:pfkey_alloc_tdb: "
31505+ "allocated tdb struct=%p.\n", tdb);
31506+
31507+ memset((caddr_t)*tdb, 0, sizeof(**tdb));
31508+ errlab:
31509+ return(error);
31510+}
31511+
31512+DEBUG_NO_STATIC int
31513+pfkey_alloc_eroute(struct eroute** eroute)
31514+{
31515+ int error = 0;
31516+ if(*eroute) {
31517+ KLIPS_PRINT(debug_pfkey,
31518+ "klips_debug:pfkey_alloc_eroute: eroute struct already allocated\n");
31519+ SENDERR(EEXIST);
31520+ }
31521+
31522+ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
31523+ KLIPS_PRINT(debug_pfkey,
31524+ "klips_debug:pfkey_alloc_eroute: memory allocation error\n");
31525+ SENDERR(ENOMEM);
31526+ }
31527+ KLIPS_PRINT(debug_pfkey,
31528+ "klips_debug:pfkey_alloc_eroute: "
31529+ "allocated eroute struct=%p.\n", eroute);
31530+ memset((caddr_t)*eroute, 0, sizeof(**eroute));
31531+ (*eroute)->er_eaddr.sen_len =
31532+ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
31533+ (*eroute)->er_eaddr.sen_family =
31534+ (*eroute)->er_emask.sen_family = AF_ENCAP;
31535+ (*eroute)->er_eaddr.sen_type = SENT_IP4;
31536+ (*eroute)->er_emask.sen_type = 255;
31537+
31538+ errlab:
31539+ return(error);
31540+}
31541+
31542+DEBUG_NO_STATIC int
31543+pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
31544+{
31545+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
31546+ int error = 0;
31547+ struct tdb* tdbp;
31548+
31549+ KLIPS_PRINT(debug_pfkey,
31550+ "klips_debug:pfkey_sa_process: .\n");
31551+
31552+ if(!extr || !extr->tdb) {
31553+ KLIPS_PRINT(debug_pfkey,
31554+ "klips_debug:pfkey_sa_process: "
31555+ "extr or extr->tdb is NULL, fatal\n");
31556+ SENDERR(EINVAL);
31557+ }
31558+
31559+ switch(pfkey_ext->sadb_ext_type) {
31560+ case SADB_EXT_SA:
31561+ tdbp = extr->tdb;
31562+ break;
31563+ case SADB_X_EXT_SA2:
31564+ if(pfkey_alloc_tdb(&(extr->tdb2)) == ENOMEM) {
31565+ SENDERR(ENOMEM);
31566+ }
31567+ tdbp = extr->tdb2;
31568+ break;
31569+ default:
31570+ KLIPS_PRINT(debug_pfkey,
31571+ "klips_debug:pfkey_sa_process: invalid exttype=%d.\n",
31572+ pfkey_ext->sadb_ext_type);
31573+ SENDERR(EINVAL);
31574+ }
31575+
31576+ tdbp->tdb_said.spi = pfkey_sa->sadb_sa_spi;
31577+ tdbp->tdb_replaywin = pfkey_sa->sadb_sa_replay;
31578+ tdbp->tdb_state = pfkey_sa->sadb_sa_state;
31579+ tdbp->tdb_flags = pfkey_sa->sadb_sa_flags;
31580+ tdbp->tdb_replaywin_lastseq = tdbp->tdb_replaywin_bitmap = 0;
31581+
31582+ switch(tdbp->tdb_said.proto) {
31583+ case IPPROTO_AH:
31584+ tdbp->tdb_authalg = pfkey_sa->sadb_sa_auth;
31585+ tdbp->tdb_encalg = SADB_EALG_NONE;
31586+ break;
31587+ case IPPROTO_ESP:
31588+ tdbp->tdb_authalg = pfkey_sa->sadb_sa_auth;
31589+ tdbp->tdb_encalg = pfkey_sa->sadb_sa_encrypt;
31590+ break;
31591+ case IPPROTO_IPIP:
31592+ tdbp->tdb_authalg = AH_NONE;
31593+ tdbp->tdb_encalg = ESP_NONE;
31594+ break;
31595+#ifdef CONFIG_IPSEC_IPCOMP
31596+ case IPPROTO_COMP:
31597+ tdbp->tdb_authalg = AH_NONE;
31598+ tdbp->tdb_encalg = pfkey_sa->sadb_sa_encrypt;
31599+ break;
31600+#endif /* CONFIG_IPSEC_IPCOMP */
31601+ case 0:
31602+ break;
31603+ default:
31604+ KLIPS_PRINT(debug_pfkey,
31605+ "klips_debug:pfkey_sa_process: "
31606+ "unknown proto=%d.\n",
31607+ tdbp->tdb_said.proto);
31608+ SENDERR(EINVAL);
31609+ }
31610+
31611+errlab:
31612+ return error;
31613+}
31614+
31615+DEBUG_NO_STATIC int
31616+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
31617+{
31618+ int error = 0;
31619+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
31620+
31621+ KLIPS_PRINT(debug_pfkey,
31622+ "klips_debug:pfkey_lifetime_process: .\n");
31623+
31624+ if(!extr || !extr->tdb) {
31625+ KLIPS_PRINT(debug_pfkey,
31626+ "klips_debug:pfkey_lifetime_process: "
31627+ "extr or extr->tdb is NULL, fatal\n");
31628+ SENDERR(EINVAL);
31629+ }
31630+
31631+ switch(pfkey_lifetime->sadb_lifetime_exttype) {
31632+ case SADB_EXT_LIFETIME_CURRENT:
31633+ KLIPS_PRINT(debug_pfkey,
31634+ "klips_debug:pfkey_lifetime_process: "
31635+ "lifetime_current not supported yet.\n");
31636+ SENDERR(EINVAL);
31637+ break;
31638+ case SADB_EXT_LIFETIME_HARD:
31639+ if(pfkey_lifetime->sadb_lifetime_allocations &&
31640+ (!extr->tdb->tdb_lifetime_allocations_h ||
31641+ (pfkey_lifetime->sadb_lifetime_allocations < extr->tdb->tdb_lifetime_allocations_h))) {
31642+ extr->tdb->tdb_lifetime_allocations_h =
31643+ pfkey_lifetime->sadb_lifetime_allocations;
31644+ if(!extr->tdb->tdb_lifetime_allocations_s &&
31645+ (extr->tdb->tdb_lifetime_allocations_h < extr->tdb->tdb_lifetime_allocations_s)) {
31646+ extr->tdb->tdb_lifetime_allocations_s = extr->tdb->tdb_lifetime_allocations_h;
31647+ }
31648+ }
31649+ if(pfkey_lifetime->sadb_lifetime_bytes &&
31650+ (!extr->tdb->tdb_lifetime_bytes_h ||
31651+ (pfkey_lifetime->sadb_lifetime_bytes < extr->tdb->tdb_lifetime_bytes_h))) {
31652+ extr->tdb->tdb_lifetime_bytes_h =
31653+ pfkey_lifetime->sadb_lifetime_bytes;
31654+ if(!extr->tdb->tdb_lifetime_bytes_s &&
31655+ (extr->tdb->tdb_lifetime_bytes_h < extr->tdb->tdb_lifetime_bytes_s)) {
31656+ extr->tdb->tdb_lifetime_bytes_s = extr->tdb->tdb_lifetime_bytes_h;
31657+ }
31658+ }
31659+ if(pfkey_lifetime->sadb_lifetime_addtime &&
31660+ (!extr->tdb->tdb_lifetime_addtime_h ||
31661+ (pfkey_lifetime->sadb_lifetime_addtime < extr->tdb->tdb_lifetime_addtime_h))) {
31662+ extr->tdb->tdb_lifetime_addtime_h =
31663+ pfkey_lifetime->sadb_lifetime_addtime;
31664+ if(extr->tdb->tdb_lifetime_addtime_s &&
31665+ (extr->tdb->tdb_lifetime_addtime_h < extr->tdb->tdb_lifetime_addtime_s)) {
31666+ extr->tdb->tdb_lifetime_addtime_s = extr->tdb->tdb_lifetime_addtime_h;
31667+ }
31668+ }
31669+ if(pfkey_lifetime->sadb_lifetime_usetime &&
31670+ (!extr->tdb->tdb_lifetime_usetime_h ||
31671+ (pfkey_lifetime->sadb_lifetime_usetime < extr->tdb->tdb_lifetime_usetime_h))) {
31672+ extr->tdb->tdb_lifetime_usetime_h =
31673+ pfkey_lifetime->sadb_lifetime_usetime;
31674+ if(extr->tdb->tdb_lifetime_usetime_s &&
31675+ (extr->tdb->tdb_lifetime_usetime_h < extr->tdb->tdb_lifetime_usetime_s)) {
31676+ extr->tdb->tdb_lifetime_usetime_s = extr->tdb->tdb_lifetime_usetime_h;
31677+ }
31678+ }
31679+ break;
31680+ case SADB_EXT_LIFETIME_SOFT:
31681+ if(pfkey_lifetime->sadb_lifetime_allocations &&
31682+ (!extr->tdb->tdb_lifetime_allocations_s ||
31683+ (pfkey_lifetime->sadb_lifetime_allocations < extr->tdb->tdb_lifetime_allocations_s))) {
31684+ extr->tdb->tdb_lifetime_allocations_s =
31685+ pfkey_lifetime->sadb_lifetime_allocations;
31686+ if(extr->tdb->tdb_lifetime_allocations_h &&
31687+ (extr->tdb->tdb_lifetime_allocations_h < extr->tdb->tdb_lifetime_allocations_s)) {
31688+ extr->tdb->tdb_lifetime_allocations_s = extr->tdb->tdb_lifetime_allocations_h;
31689+ }
31690+ }
31691+ if(pfkey_lifetime->sadb_lifetime_bytes &&
31692+ (!extr->tdb->tdb_lifetime_bytes_s ||
31693+ (pfkey_lifetime->sadb_lifetime_bytes < extr->tdb->tdb_lifetime_bytes_s))) {
31694+ extr->tdb->tdb_lifetime_bytes_s =
31695+ pfkey_lifetime->sadb_lifetime_bytes;
31696+ if(extr->tdb->tdb_lifetime_bytes_h &&
31697+ (extr->tdb->tdb_lifetime_bytes_h < extr->tdb->tdb_lifetime_bytes_s)) {
31698+ extr->tdb->tdb_lifetime_bytes_s = extr->tdb->tdb_lifetime_bytes_h;
31699+ }
31700+ }
31701+ if(pfkey_lifetime->sadb_lifetime_addtime &&
31702+ (!extr->tdb->tdb_lifetime_addtime_s ||
31703+ (pfkey_lifetime->sadb_lifetime_addtime < extr->tdb->tdb_lifetime_addtime_s))) {
31704+ extr->tdb->tdb_lifetime_addtime_s =
31705+ pfkey_lifetime->sadb_lifetime_addtime;
31706+ if(extr->tdb->tdb_lifetime_addtime_h &&
31707+ (extr->tdb->tdb_lifetime_addtime_h < extr->tdb->tdb_lifetime_addtime_s)) {
31708+ extr->tdb->tdb_lifetime_addtime_s = extr->tdb->tdb_lifetime_addtime_h;
31709+ }
31710+ }
31711+ if(pfkey_lifetime->sadb_lifetime_usetime &&
31712+ (!extr->tdb->tdb_lifetime_usetime_s ||
31713+ (pfkey_lifetime->sadb_lifetime_usetime < extr->tdb->tdb_lifetime_usetime_s))) {
31714+ extr->tdb->tdb_lifetime_usetime_s =
31715+ pfkey_lifetime->sadb_lifetime_usetime;
31716+ if(extr->tdb->tdb_lifetime_usetime_h &&
31717+ (extr->tdb->tdb_lifetime_usetime_h < extr->tdb->tdb_lifetime_usetime_s)) {
31718+ extr->tdb->tdb_lifetime_usetime_s = extr->tdb->tdb_lifetime_usetime_h;
31719+ }
31720+ }
31721+ break;
31722+ default:
31723+ KLIPS_PRINT(debug_pfkey,
31724+ "klips_debug: pfkey_lifetime_process: invalid exttype=%d.\n",
31725+ pfkey_ext->sadb_ext_type);
31726+ SENDERR(EINVAL);
31727+ }
31728+
31729+errlab:
31730+ return error;
31731+}
31732+
31733+DEBUG_NO_STATIC int
31734+pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
31735+{
31736+ int error = 0;
31737+ int saddr_len = 0;
31738+ char ipaddr_txt[ADDRTOA_BUF];
31739+ unsigned char **sap;
31740+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
31741+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
31742+ struct tdb* tdbp;
31743+
31744+ KLIPS_PRINT(debug_pfkey,
31745+ "klips_debug:pfkey_address_process:\n");
31746+
31747+ if(!extr || !extr->tdb) {
31748+ KLIPS_PRINT(debug_pfkey,
31749+ "klips_debug:pfkey_address_process:\n"
31750+ "extr or extr->tdb is NULL, fatal\n");
31751+ SENDERR(EINVAL);
31752+ }
31753+
31754+ switch(s->sa_family) {
31755+ case AF_INET:
31756+ saddr_len = sizeof(struct sockaddr_in);
31757+ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
31758+ KLIPS_PRINT(debug_pfkey,
31759+ "klips_debug:pfkey_address_process: found address family=%d, AF_INET, %s.\n",
31760+ s->sa_family, ipaddr_txt);
31761+ break;
31762+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
31763+ case AF_INET6:
31764+ saddr_len = sizeof(struct sockaddr_in6);
31765+ break;
31766+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
31767+ default:
31768+ KLIPS_PRINT(debug_pfkey,
31769+ "klips_debug:pfkey_address_process: s->sa_family=%d not supported.\n",
31770+ s->sa_family);
31771+ SENDERR(EPFNOSUPPORT);
31772+ }
31773+
31774+ switch(pfkey_address->sadb_address_exttype) {
31775+ case SADB_EXT_ADDRESS_SRC:
31776+ KLIPS_PRINT(debug_pfkey,
31777+ "klips_debug:pfkey_address_process: found src address.\n");
31778+ sap = (unsigned char **)&(extr->tdb->tdb_addr_s);
31779+ extr->tdb->tdb_addr_s_size = saddr_len;
31780+ break;
31781+ case SADB_EXT_ADDRESS_DST:
31782+ KLIPS_PRINT(debug_pfkey,
31783+ "klips_debug:pfkey_address_process: found dst address.\n");
31784+ sap = (unsigned char **)&(extr->tdb->tdb_addr_d);
31785+ extr->tdb->tdb_addr_d_size = saddr_len;
31786+ break;
31787+ case SADB_EXT_ADDRESS_PROXY:
31788+ KLIPS_PRINT(debug_pfkey,
31789+ "klips_debug:pfkey_address_process: found proxy address.\n");
31790+ sap = (unsigned char **)&(extr->tdb->tdb_addr_p);
31791+ extr->tdb->tdb_addr_p_size = saddr_len;
31792+ break;
31793+ case SADB_X_EXT_ADDRESS_DST2:
31794+ KLIPS_PRINT(debug_pfkey,
31795+ "klips_debug:pfkey_address_process: found 2nd dst address.\n");
31796+ if(pfkey_alloc_tdb(&(extr->tdb2)) == ENOMEM) {
31797+ SENDERR(ENOMEM);
31798+ }
31799+ sap = (unsigned char **)&(extr->tdb2->tdb_addr_d);
31800+ extr->tdb2->tdb_addr_d_size = saddr_len;
31801+ break;
31802+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
31803+ KLIPS_PRINT(debug_pfkey,
31804+ "klips_debug:pfkey_address_process: found src flow address.\n");
31805+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
31806+ SENDERR(ENOMEM);
31807+ }
31808+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
31809+ break;
31810+ case SADB_X_EXT_ADDRESS_DST_FLOW:
31811+ KLIPS_PRINT(debug_pfkey,
31812+ "klips_debug:pfkey_address_process: found dst flow address.\n");
31813+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
31814+ SENDERR(ENOMEM);
31815+ }
31816+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
31817+ break;
31818+ case SADB_X_EXT_ADDRESS_SRC_MASK:
31819+ KLIPS_PRINT(debug_pfkey,
31820+ "klips_debug:pfkey_address_process: found src mask address.\n");
31821+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
31822+ SENDERR(ENOMEM);
31823+ }
31824+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
31825+ break;
31826+ case SADB_X_EXT_ADDRESS_DST_MASK:
31827+ KLIPS_PRINT(debug_pfkey,
31828+ "klips_debug:pfkey_address_process: found dst mask address.\n");
31829+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
31830+ SENDERR(ENOMEM);
31831+ }
31832+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
31833+ break;
31834+ default:
31835+ KLIPS_PRINT(debug_pfkey,
31836+ "klips_debug:pfkey_address_process: unrecognised ext_type=%d.\n",
31837+ pfkey_address->sadb_address_exttype);
31838+ SENDERR(EINVAL);
31839+ }
31840+
31841+ switch(pfkey_address->sadb_address_exttype) {
31842+ case SADB_EXT_ADDRESS_SRC:
31843+ case SADB_EXT_ADDRESS_DST:
31844+ case SADB_EXT_ADDRESS_PROXY:
31845+ case SADB_X_EXT_ADDRESS_DST2:
31846+ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
31847+ SENDERR(ENOMEM);
31848+ }
31849+ memcpy(*sap, s, saddr_len);
31850+ break;
31851+ default:
31852+ if(s->sa_family != AF_INET) {
31853+ KLIPS_PRINT(debug_pfkey,
31854+ "klips_debug:pfkey_address_process: s->sa_family=%d not supported.\n",
31855+ s->sa_family);
31856+ SENDERR(EPFNOSUPPORT);
31857+ }
31858+ (unsigned int)(*sap) = ((struct sockaddr_in*)s)->sin_addr.s_addr;
31859+#ifdef CONFIG_IPSEC_DEBUG
31860+ if(extr->eroute) {
31861+ char buf1[64], buf2[64];
31862+ if (debug_pfkey) {
31863+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
31864+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
31865+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
31866+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
31867+ KLIPS_PRINT(debug_pfkey,
31868+ "klips_debug:pfkey_address_parse: "
31869+ "extr->eroute set to %s->%s\n",
31870+ buf1, buf2);
31871+ }
31872+ }
31873+#endif /* CONFIG_IPSEC_DEBUG */
31874+ }
31875+
31876+ tdbp = extr->tdb;
31877+ switch(pfkey_address->sadb_address_exttype) {
31878+ case SADB_X_EXT_ADDRESS_DST2:
31879+ tdbp = extr->tdb2;
31880+ case SADB_EXT_ADDRESS_DST:
31881+ if(s->sa_family == AF_INET) {
31882+ tdbp->tdb_said.dst.s_addr = ((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr.s_addr;
31883+ KLIPS_PRINT(debug_pfkey,
31884+ "klips_debug:pfkey_address_process: tdbp->tdb_said.dst.s_addr=%08x,\n"
31885+ "klips_debug: ((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr.s_addr=%08x,\n",
31886+ tdbp->tdb_said.dst.s_addr,
31887+ ((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr.s_addr
31888+ );
31889+ addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr,
31890+ 0,
31891+ ipaddr_txt,
31892+ sizeof(ipaddr_txt));
31893+ KLIPS_PRINT(debug_pfkey,
31894+ "klips_debug:pfkey_address_process: tdb_said.dst set to %s.\n",
31895+ ipaddr_txt);
31896+ } else {
31897+ KLIPS_PRINT(debug_pfkey,
31898+ "klips_debug:pfkey_address_process: "
31899+ "uh, tdb_said.dst doesn't do address family=%d yet, "
31900+ "said will be invalid.\n",
31901+ s->sa_family);
31902+ }
31903+ default:
31904+ }
31905+
31906+ /* XXX check if port!=0 */
31907+
31908+ KLIPS_PRINT(debug_pfkey,
31909+ "klips_debug:pfkey_address_process: successful.\n");
31910+ errlab:
31911+ return error;
31912+}
31913+
31914+DEBUG_NO_STATIC int
31915+pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
31916+{
31917+ int error = 0;
31918+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
31919+
31920+ KLIPS_PRINT(debug_pfkey,
31921+ "klips_debug:pfkey_key_process: .\n");
31922+
31923+ if(!extr || !extr->tdb) {
31924+ KLIPS_PRINT(debug_pfkey,
31925+ "klips_debug:pfkey_key_process: "
31926+ "extr or extr->tdb is NULL, fatal\n");
31927+ SENDERR(EINVAL);
31928+ }
31929+
31930+ switch(pfkey_key->sadb_key_exttype) {
31931+ case SADB_EXT_KEY_AUTH:
31932+ extr->tdb->tdb_key_bits_a = pfkey_key->sadb_key_bits;
31933+ if(!(extr->tdb->tdb_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
31934+ KLIPS_PRINT(debug_pfkey,
31935+ "klips_debug:pfkey_key_process: memory allocation error.\n");
31936+ SENDERR(ENOMEM);
31937+ }
31938+ memcpy(extr->tdb->tdb_key_a,
31939+ (char*)pfkey_key + sizeof(struct sadb_key),
31940+ DIVUP(pfkey_key->sadb_key_bits, 8));
31941+ break;
31942+ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
31943+ extr->tdb->tdb_key_bits_e = pfkey_key->sadb_key_bits;
31944+ if(!(extr->tdb->tdb_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
31945+ KLIPS_PRINT(debug_pfkey,
31946+ "klips_debug:pfkey_key_process: memory allocation error.\n");
31947+ SENDERR(ENOMEM);
31948+ }
31949+ memcpy(extr->tdb->tdb_key_e,
31950+ (char*)pfkey_key + sizeof(struct sadb_key),
31951+ DIVUP(pfkey_key->sadb_key_bits, 8));
31952+ break;
31953+ default:
31954+ SENDERR(EINVAL);
31955+ }
31956+
31957+ KLIPS_PRINT(debug_pfkey,
31958+ "klips_debug:pfkey_key_process: success.\n");
31959+errlab:
31960+ return error;
31961+}
31962+
31963+DEBUG_NO_STATIC int
31964+pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
31965+{
31966+ int error = 0;
31967+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
31968+
31969+ KLIPS_PRINT(debug_pfkey,
31970+ "klips_debug:pfkey_ident_process: .\n");
31971+
31972+ if(!extr || !extr->tdb) {
31973+ KLIPS_PRINT(debug_pfkey,
31974+ "klips_debug:pfkey_ident_process: "
31975+ "extr or extr->tdb is NULL, fatal\n");
31976+ SENDERR(EINVAL);
31977+ }
31978+
31979+ switch(pfkey_ident->sadb_ident_exttype) {
31980+ case SADB_EXT_IDENTITY_SRC:
31981+ extr->tdb->tdb_ident_type_s = pfkey_ident->sadb_ident_type;
31982+ extr->tdb->tdb_ident_id_s = pfkey_ident->sadb_ident_id;
31983+ extr->tdb->tdb_ident_len_s = pfkey_ident->sadb_ident_len -
31984+ (sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN);
31985+ if(extr->tdb->tdb_ident_len_s) {
31986+ if(!(extr->tdb->tdb_ident_data_s
31987+ = kmalloc(pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN,
31988+ GFP_KERNEL))) {
31989+ SENDERR(ENOMEM);
31990+ }
31991+ memcpy(extr->tdb->tdb_ident_data_s,
31992+ (char*)pfkey_ident + sizeof(struct sadb_ident),
31993+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN);
31994+ } else {
31995+ extr->tdb->tdb_ident_data_s = NULL;
31996+ }
31997+ break;
31998+ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
31999+ extr->tdb->tdb_ident_type_d = pfkey_ident->sadb_ident_type;
32000+ extr->tdb->tdb_ident_id_d = pfkey_ident->sadb_ident_id;
32001+ extr->tdb->tdb_ident_len_d = pfkey_ident->sadb_ident_len -
32002+ sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN;
32003+ if(extr->tdb->tdb_ident_len_d) {
32004+ if(!(extr->tdb->tdb_ident_data_d
32005+ = kmalloc(pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN,
32006+ GFP_KERNEL))) {
32007+ SENDERR(ENOMEM);
32008+ }
32009+ memcpy(extr->tdb->tdb_ident_data_d,
32010+ (char*)pfkey_ident + sizeof(struct sadb_ident),
32011+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN);
32012+ } else {
32013+ extr->tdb->tdb_ident_data_d = NULL;
32014+ }
32015+ break;
32016+ default:
32017+ SENDERR(EINVAL);
32018+ }
32019+errlab:
32020+ return error;
32021+}
32022+
32023+DEBUG_NO_STATIC int
32024+pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
32025+{
32026+ int error = 0;
32027+
32028+ KLIPS_PRINT(debug_pfkey,
32029+ "klips_debug: pfkey_sens_process: Sorry, I can't process exttype=%d yet.\n",
32030+ pfkey_ext->sadb_ext_type);
32031+ SENDERR(EINVAL); /* don't process these yet */
32032+ errlab:
32033+ return error;
32034+}
32035+
32036+DEBUG_NO_STATIC int
32037+pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
32038+{
32039+ int error = 0;
32040+
32041+ KLIPS_PRINT(debug_pfkey,
32042+ "klips_debug: pfkey_prop_process: Sorry, I can't process exttype=%d yet.\n",
32043+ pfkey_ext->sadb_ext_type);
32044+ SENDERR(EINVAL); /* don't process these yet */
32045+
32046+ errlab:
32047+ return error;
32048+}
32049+
32050+DEBUG_NO_STATIC int
32051+pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
32052+{
32053+ int error = 0;
32054+
32055+ KLIPS_PRINT(debug_pfkey,
32056+ "klips_debug: pfkey_supported_process: Sorry, I can't process exttype=%d yet.\n",
32057+ pfkey_ext->sadb_ext_type);
32058+ SENDERR(EINVAL); /* don't process these yet */
32059+
32060+errlab:
32061+ return error;
32062+}
32063+
32064+DEBUG_NO_STATIC int
32065+pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
32066+{
32067+ int error = 0;
32068+
32069+ KLIPS_PRINT(debug_pfkey,
32070+ "klips_debug: pfkey_spirange_process: .\n");
32071+/* errlab: */
32072+ return error;
32073+}
32074+
32075+DEBUG_NO_STATIC int
32076+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
32077+{
32078+ int error = 0;
32079+
32080+ KLIPS_PRINT(debug_pfkey,
32081+ "klips_debug: pfkey_x_kmprivate_process: Sorry, I can't process exttype=%d yet.\n",
32082+ pfkey_ext->sadb_ext_type);
32083+ SENDERR(EINVAL); /* don't process these yet */
32084+
32085+errlab:
32086+ return error;
32087+}
32088+
32089+DEBUG_NO_STATIC int
32090+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
32091+{
32092+ int error = 0;
32093+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
32094+
32095+ KLIPS_PRINT(debug_pfkey,
32096+ "klips_debug: pfkey_x_satype_process: .\n");
32097+
32098+ if(!extr || !extr->tdb) {
32099+ KLIPS_PRINT(debug_pfkey,
32100+ "klips_debug: pfkey_x_satype_process: "
32101+ "extr or extr->tdb is NULL, fatal\n");
32102+ SENDERR(EINVAL);
32103+ }
32104+
32105+ if(pfkey_alloc_tdb(&(extr->tdb2)) == ENOMEM) {
32106+ SENDERR(ENOMEM);
32107+ }
32108+ if(!(extr->tdb2->tdb_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
32109+ KLIPS_PRINT(debug_pfkey,
32110+ "klips_debug: pfkey_x_satype_process: proto lookup from satype=%d failed.\n",
32111+ pfkey_x_satype->sadb_x_satype_satype);
32112+ SENDERR(EINVAL);
32113+ }
32114+
32115+errlab:
32116+ return error;
32117+}
32118+
32119+DEBUG_NO_STATIC int
32120+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
32121+{
32122+ int error = 0;
32123+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
32124+
32125+ if(!pfkey_x_debug) {
32126+ printk("klips_debug:pfkey_x_debug_process: null pointer passed in\n");
32127+ SENDERR(EINVAL);
32128+ }
32129+
32130+ KLIPS_PRINT(debug_pfkey,
32131+ "klips_debug:pfkey_x_debug_process: .\n");
32132+
32133+#ifdef CONFIG_IPSEC_DEBUG
32134+ if(pfkey_x_debug->sadb_x_debug_netlink >>
32135+ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
32136+ pfkey_x_debug->sadb_x_debug_netlink &=
32137+ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
32138+ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
32139+ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
32140+ debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
32141+ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
32142+ debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
32143+ debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
32144+ debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
32145+ debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
32146+ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
32147+ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
32148+#ifdef CONFIG_IPSEC_IPCOMP
32149+ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
32150+#endif /* CONFIG_IPSEC_IPCOMP */
32151+ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
32152+ if(debug_netlink)
32153+ printk("klips_debug:pfkey_x_debug_process: set\n");
32154+ } else {
32155+ if(debug_netlink)
32156+ printk("klips_debug:pfkey_x_debug_process: unset\n");
32157+ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
32158+ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
32159+ debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
32160+ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
32161+ debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
32162+ debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
32163+ debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
32164+ debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
32165+ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
32166+ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
32167+#ifdef CONFIG_IPSEC_IPCOMP
32168+ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
32169+#endif /* CONFIG_IPSEC_IPCOMP */
32170+ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
32171+ }
32172+#else /* CONFIG_IPSEC_DEBUG */
32173+ printk("klips_debug:pfkey_x_debug_process: debugging not enabled\n");
32174+ SENDERR(EINVAL);
32175+#endif /* CONFIG_IPSEC_DEBUG */
32176+
32177+errlab:
32178+ return error;
32179+}
32180+
32181+
32182+DEBUG_NO_STATIC int
32183+pfkey_tdb_init(struct tdb *tdbp, struct sadb_ext **extensions)
32184+{
32185+ int i;
32186+ int error = 0;
32187+ char sa[SATOA_BUF];
32188+ char ipaddr_txt[ADDRTOA_BUF];
32189+ char ipaddr2_txt[ADDRTOA_BUF];
32190+ unsigned char kb[AHMD596_BLKLEN];
32191+
32192+ if(!tdbp) {
32193+ KLIPS_PRINT(debug_pfkey,
32194+ "klips_debug:pfkey_tdb_init: "
32195+ "tdbp is NULL, fatal\n");
32196+ SENDERR(EINVAL);
32197+ }
32198+
32199+ satoa(tdbp->tdb_said, 0, sa, SATOA_BUF);
32200+
32201+ KLIPS_PRINT(debug_pfkey,
32202+ "klips_debug:pfkey_tdb_init: (pfkey defined) called for SA:%s\n", sa);
32203+
32204+ KLIPS_PRINT(debug_pfkey,
32205+ "klips_debug:pfkey_tdb_init: calling init routine of %s%s%s\n",
32206+ TDB_XFORM_NAME(tdbp));
32207+
32208+ switch(tdbp->tdb_said.proto) {
32209+
32210+#ifdef CONFIG_IPSEC_IPIP
32211+ case IPPROTO_IPIP: {
32212+ addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr,
32213+ 0,
32214+ ipaddr_txt, sizeof(ipaddr_txt));
32215+ addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr,
32216+ 0,
32217+ ipaddr2_txt, sizeof(ipaddr_txt));
32218+ KLIPS_PRINT(debug_pfkey,
32219+ "klips_debug:pfkey_tdb_init: "
32220+ "(pfkey defined) IPIP tdb set for %s->%s.\n",
32221+ ipaddr_txt,
32222+ ipaddr2_txt);
32223+ }
32224+ break;
32225+#endif /* !CONFIG_IPSEC_IPIP */
32226+#ifdef CONFIG_IPSEC_AH
32227+ case IPPROTO_AH:
32228+ switch(tdbp->tdb_authalg) {
32229+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
32230+ case AH_MD5: {
32231+ unsigned char *akp;
32232+ MD5_CTX *ictx;
32233+ MD5_CTX *octx;
32234+
32235+ if(tdbp->tdb_key_bits_a != (AHMD596_KLEN * 8)) {
32236+ KLIPS_PRINT(debug_pfkey,
32237+ "klips_debug:pfkey_tdb_init: incorrect key size: %d bits"
32238+ "-- must be %d bits\n"/*octets (bytes)\n"*/,
32239+ tdbp->tdb_key_bits_a, AHMD596_KLEN * 8);
32240+ SENDERR(EINVAL);
32241+ }
32242+
32243+# if 0 /* we don't really want to print these unless there are really big problems */
32244+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
32245+ "klips_debug:pfkey_tdb_init: hmac md5-96 key is 0x%08lx %08lx %08lx %08lx\n",
32246+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+0)),
32247+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)),
32248+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)),
32249+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+3)));
32250+# endif
32251+
32252+ tdbp->tdb_auth_bits = AHMD596_ALEN * 8;
32253+
32254+ /* save the pointer to the key material */
32255+ akp = tdbp->tdb_key_a;
32256+
32257+ if((tdbp->tdb_key_a = (caddr_t)
32258+ kmalloc((tdbp->tdb_key_a_size = sizeof(struct md5_ctx)),
32259+ GFP_ATOMIC)) == NULL) {
32260+ SENDERR(ENOMEM);
32261+ }
32262+
32263+ for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) {
32264+ kb[i] = akp[i] ^ HMAC_IPAD;
32265+ }
32266+ for (; i < AHMD596_BLKLEN; i++) {
32267+ kb[i] = HMAC_IPAD;
32268+ }
32269+
32270+ ictx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->ictx);
32271+ MD5Init(ictx);
32272+ MD5Update(ictx, kb, AHMD596_BLKLEN);
32273+
32274+ for (i = 0; i < AHMD596_BLKLEN; i++) {
32275+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
32276+ }
32277+
32278+ octx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->octx);
32279+ MD5Init(octx);
32280+ MD5Update(octx, kb, AHMD596_BLKLEN);
32281+
32282+# if 0 /* we don't really want to print these unless there are really big problems */
32283+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
32284+ "klips_debug:pfkey_tdb_init: MD5 ictx=0x%08x %08x %08x %08x"
32285+ " octx=0x%08x %08x %08x %08x\n",
32286+ ((__u32*)ictx)[0],
32287+ ((__u32*)ictx)[1],
32288+ ((__u32*)ictx)[2],
32289+ ((__u32*)ictx)[3],
32290+ ((__u32*)octx)[0],
32291+ ((__u32*)octx)[1],
32292+ ((__u32*)octx)[2],
32293+ ((__u32*)octx)[3] );
32294+# endif
32295+
32296+ /* zero key buffer -- paranoid */
32297+ memset(akp, 0, DIVUP(tdbp->tdb_key_bits_a, BITS_PER_OCTET));
32298+ }
32299+ break;
32300+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
32301+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
32302+ case AH_SHA: {
32303+
32304+ unsigned char *akp;
32305+ SHA1_CTX *ictx;
32306+ SHA1_CTX *octx;
32307+
32308+ if(tdbp->tdb_key_bits_a != (AHSHA196_KLEN * 8)) {
32309+ KLIPS_PRINT(debug_pfkey,
32310+ "klips_debug:pfkey_tdb_init: incorrect key size: %d bits"
32311+ "-- must be %d bits\n"/*octets (bytes)\n"*/,
32312+ tdbp->tdb_key_bits_a, AHSHA196_KLEN * 8);
32313+ SENDERR(EINVAL);
32314+ }
32315+
32316+# if 0 /* we don't really want to print these unless there are really big problems */
32317+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
32318+ "klips_debug:pfkey_tdb_init: hmac sha1-96 key is 0x%08lx %08lx %08lx %08lx\n",
32319+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+0)),
32320+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)),
32321+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)),
32322+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+3)));
32323+# endif
32324+
32325+ tdbp->tdb_auth_bits = AHSHA196_ALEN * 8;
32326+
32327+ /* save the pointer to the key material */
32328+ akp = tdbp->tdb_key_a;
32329+
32330+ if((tdbp->tdb_key_a = (caddr_t)
32331+ kmalloc((tdbp->tdb_key_a_size = sizeof(struct sha1_ctx)),
32332+ GFP_ATOMIC)) == NULL) {
32333+ SENDERR(ENOMEM);
32334+ }
32335+
32336+ for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) {
32337+ kb[i] = akp[i] ^ HMAC_IPAD;
32338+ }
32339+ for (; i < AHMD596_BLKLEN; i++) {
32340+ kb[i] = HMAC_IPAD;
32341+ }
32342+
32343+ ictx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx);
32344+ SHA1Init(ictx);
32345+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
32346+
32347+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
32348+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
32349+ }
32350+
32351+ octx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->octx);
32352+ SHA1Init(octx);
32353+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
32354+
32355+# if 0 /* we don't really want to print these unless there are really big problems */
32356+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
32357+ "klips_debug:pfkey_tdb_init: SHA1 ictx=0x%08x %08x %08x %08x"
32358+ " octx=0x%08x %08x %08x %08x\n",
32359+ ((__u32*)ictx)[0],
32360+ ((__u32*)ictx)[1],
32361+ ((__u32*)ictx)[2],
32362+ ((__u32*)ictx)[3],
32363+ ((__u32*)octx)[0],
32364+ ((__u32*)octx)[1],
32365+ ((__u32*)octx)[2],
32366+ ((__u32*)octx)[3] );
32367+# endif
32368+ /* zero key buffer -- paranoid */
32369+ memset(akp, 0, DIVUP(tdbp->tdb_key_bits_a, BITS_PER_OCTET));
32370+ }
32371+ break;
32372+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
32373+ default:
32374+ KLIPS_PRINT(debug_pfkey,
32375+ "klips_debug:pfkey_tdb_init: "
32376+ "authalg=%d support not available in the kernel",
32377+ tdbp->tdb_authalg);
32378+ SENDERR(EINVAL);
32379+ }
32380+ break;
32381+#endif /* CONFIG_IPSEC_AH */
32382+#ifdef CONFIG_IPSEC_ESP
32383+ case IPPROTO_ESP: {
32384+ unsigned char *akp, *ekp;
32385+
32386+ switch(tdbp->tdb_encalg) {
32387+# ifdef CONFIG_IPSEC_ENC_3DES
32388+ case ESP_3DES:
32389+# endif /* CONFIG_IPSEC_ENC_3DES */
32390+# if defined(CONFIG_IPSEC_ENC_3DES)
32391+ if((tdbp->tdb_iv = (caddr_t)
32392+ kmalloc((tdbp->tdb_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) {
32393+ SENDERR(ENOMEM);
32394+ }
32395+ get_random_bytes((void *)tdbp->tdb_iv, EMT_ESPDES_IV_SZ);
32396+ tdbp->tdb_iv_bits = tdbp->tdb_iv_size * 8;
32397+ break;
32398+# endif /* defined(CONFIG_IPSEC_ENC_3DES) */
32399+ case ESP_NONE:
32400+# ifdef CONFIG_IPSEC_ENC_NULL
32401+ case ESP_NULL:
32402+# endif /* CONFIG_IPSEC_ENC_NULL */
32403+ break;
32404+ default:
32405+ KLIPS_PRINT(debug_pfkey,
32406+ "klips_debug:pfkey_tdb_init: "
32407+ "encalg=%d support not available in the kernel",
32408+ tdbp->tdb_encalg);
32409+ SENDERR(EINVAL);
32410+ }
32411+
32412+ switch(tdbp->tdb_encalg) {
32413+# ifdef CONFIG_IPSEC_ENC_3DES
32414+ case ESP_3DES:
32415+ if(tdbp->tdb_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) {
32416+ KLIPS_PRINT(debug_pfkey,
32417+ "klips_debug:pfkey_tdb_init: incorrect encryption"
32418+ "key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
32419+ tdbp->tdb_key_bits_e, EMT_ESP3DES_KEY_SZ * 8);
32420+ SENDERR(EINVAL);
32421+ }
32422+
32423+ /* save encryption key pointer */
32424+ ekp = tdbp->tdb_key_e;
32425+
32426+ if((tdbp->tdb_key_e = (caddr_t)
32427+ kmalloc((tdbp->tdb_key_e_size = 3 * sizeof(struct des_eks)),
32428+ GFP_ATOMIC)) == NULL) {
32429+ SENDERR(ENOMEM);
32430+ }
32431+
32432+ for(i = 0; i < 3; i++) {
32433+# if 0 /* we don't really want to print these unless there are really big problems */
32434+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
32435+ "klips_debug:pfkey_tdb_init: 3des key %d/3 is 0x%08lx%08lx\n",
32436+ i + 1,
32437+ ntohl(*((__u32 *)tdbp->tdb_key_e + i * 2)),
32438+ ntohl(*((__u32 *)tdbp->tdb_key_e + i * 2 + 1)));
32439+# endif
32440+ error = des_set_key((caddr_t)ekp + EMT_ESPDES_KEY_SZ * i,
32441+ (caddr_t)&((struct des_eks*)(tdbp->tdb_key_e))[i]);
32442+ if (error == -1)
32443+ printk("klips_debug:pfkey_tdb_init: parity error in des key %d/3\n", i + 1);
32444+ else if (error == -2)
32445+ printk("klips_debug:pfkey_tdb_init: illegal weak des key %d/3\n", i + 1);
32446+ if (error) {
32447+ memset(tdbp->tdb_key_e, 0, 3 * sizeof(struct des_eks));
32448+ kfree(tdbp->tdb_key_e);
32449+ memset(ekp, 0, DIVUP(tdbp->tdb_key_bits_e, BITS_PER_OCTET));
32450+ SENDERR(EINVAL);
32451+ }
32452+ }
32453+
32454+ /* paranoid */
32455+ memset(ekp, 0, DIVUP(tdbp->tdb_key_bits_e, BITS_PER_OCTET));
32456+
32457+ break;
32458+# endif /* CONFIG_IPSEC_ENC_3DES */
32459+# ifdef CONFIG_IPSEC_ENC_NULL
32460+ case ESP_NULL:
32461+# endif /* CONFIG_IPSEC_ENC_NULL */
32462+ case ESP_NONE:
32463+ break;
32464+ default:
32465+ KLIPS_PRINT(debug_pfkey,
32466+ "klips_debug:pfkey_tdb_init: "
32467+ "encalg=%d support not available in the kernel",
32468+ tdbp->tdb_encalg);
32469+ SENDERR(EINVAL);
32470+ }
32471+
32472+ switch(tdbp->tdb_authalg) {
32473+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
32474+ case AH_MD5: {
32475+ MD5_CTX *ictx;
32476+ MD5_CTX *octx;
32477+
32478+ if(tdbp->tdb_key_bits_a != (AHMD596_KLEN * 8)) {
32479+ KLIPS_PRINT(debug_pfkey,
32480+ "klips_debug:pfkey_tdb_init: incorrect authorisation"
32481+ " key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
32482+ tdbp->tdb_key_bits_a, AHMD596_KLEN * 8);
32483+ SENDERR(EINVAL);
32484+ }
32485+
32486+# if 0 /* we don't really want to print these unless there are really big problems */
32487+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
32488+ "klips_debug:pfkey_tdb_init: hmac md5-96 key is 0x%08lx %08lx %08lx %08lx\n",
32489+ ntohl(*(((__u32 *)(tdbp->tdb_key_a))+0)),
32490+ ntohl(*(((__u32 *)(tdbp->tdb_key_a))+1)),
32491+ ntohl(*(((__u32 *)(tdbp->tdb_key_a))+2)),
32492+ ntohl(*(((__u32 *)(tdbp->tdb_key_a))+3)));
32493+# endif
32494+ tdbp->tdb_auth_bits = AHMD596_ALEN * 8;
32495+
32496+ /* save the pointer to the key material */
32497+ akp = tdbp->tdb_key_a;
32498+
32499+ if((tdbp->tdb_key_a = (caddr_t)
32500+ kmalloc((tdbp->tdb_key_a_size = sizeof(struct md5_ctx)),
32501+ GFP_ATOMIC)) == NULL) {
32502+ SENDERR(ENOMEM);
32503+ }
32504+
32505+ for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) {
32506+ kb[i] = akp[i] ^ HMAC_IPAD;
32507+ }
32508+ for (; i < AHMD596_BLKLEN; i++) {
32509+ kb[i] = HMAC_IPAD;
32510+ }
32511+
32512+ ictx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->ictx);
32513+ MD5Init(ictx);
32514+ MD5Update(ictx, kb, AHMD596_BLKLEN);
32515+
32516+ for (i = 0; i < AHMD596_BLKLEN; i++) {
32517+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
32518+ }
32519+
32520+ octx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->octx);
32521+ MD5Init(octx);
32522+ MD5Update(octx, kb, AHMD596_BLKLEN);
32523+
32524+# if 0 /* we don't really want to print these unless there are really big problems */
32525+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
32526+ "klips_debug:pfkey_tdb_init: MD5 ictx=0x%08x %08x %08x %08x"
32527+ " octx=0x%08x %08x %08x %08x\n",
32528+ ((__u32*)ictx)[0],
32529+ ((__u32*)ictx)[1],
32530+ ((__u32*)ictx)[2],
32531+ ((__u32*)ictx)[3],
32532+ ((__u32*)octx)[0],
32533+ ((__u32*)octx)[1],
32534+ ((__u32*)octx)[2],
32535+ ((__u32*)octx)[3] );
32536+# endif
32537+ /* paranoid */
32538+ memset(akp, 0, DIVUP(tdbp->tdb_key_bits_a, BITS_PER_OCTET));
32539+ break;
32540+ }
32541+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
32542+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
32543+ case AH_SHA: {
32544+ SHA1_CTX *ictx;
32545+ SHA1_CTX *octx;
32546+
32547+ if(tdbp->tdb_key_bits_a != (AHSHA196_KLEN * 8)) {
32548+ KLIPS_PRINT(debug_pfkey,
32549+ "klips_debug:pfkey_tdb_init: incorrect authorisation"
32550+ " key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
32551+ tdbp->tdb_key_bits_a, AHSHA196_KLEN * 8);
32552+ SENDERR(EINVAL);
32553+ }
32554+
32555+# if 0 /* we don't really want to print these unless there are really big problems */
32556+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
32557+ "klips_debug:pfkey_tdb_init: hmac sha1-96 key is 0x%08lx %08lx %08lx %08lx\n",
32558+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+0)),
32559+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)),
32560+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)),
32561+ ntohl(*(((__u32 *)tdbp->tdb_key_a)+3)));
32562+# endif
32563+ tdbp->tdb_auth_bits = AHSHA196_ALEN * 8;
32564+
32565+ /* save the pointer to the key material */
32566+ akp = tdbp->tdb_key_a;
32567+
32568+ if((tdbp->tdb_key_a = (caddr_t)
32569+ kmalloc((tdbp->tdb_key_a_size = sizeof(struct sha1_ctx)),
32570+ GFP_ATOMIC)) == NULL) {
32571+ SENDERR(ENOMEM);
32572+ }
32573+
32574+ for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) {
32575+ kb[i] = akp[i] ^ HMAC_IPAD;
32576+ }
32577+ for (; i < AHMD596_BLKLEN; i++) {
32578+ kb[i] = HMAC_IPAD;
32579+ }
32580+
32581+ ictx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx);
32582+ SHA1Init(ictx);
32583+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
32584+
32585+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
32586+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
32587+ }
32588+
32589+ octx = &((struct sha1_ctx*)(tdbp->tdb_key_a))->octx;
32590+ SHA1Init(octx);
32591+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
32592+
32593+# if 0 /* we don't really want to print these unless there are really big problems */
32594+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
32595+ "klips_debug:pfkey_tdb_init: SHA1 ictx=0x%08x %08x %08x %08x"
32596+ " octx=0x%08x %08x %08x %08x\n",
32597+ ((__u32*)ictx)[0],
32598+ ((__u32*)ictx)[1],
32599+ ((__u32*)ictx)[2],
32600+ ((__u32*)ictx)[3],
32601+ ((__u32*)octx)[0],
32602+ ((__u32*)octx)[1],
32603+ ((__u32*)octx)[2],
32604+ ((__u32*)octx)[3] );
32605+# endif
32606+ memset(akp, 0, DIVUP(tdbp->tdb_key_bits_a, BITS_PER_OCTET));
32607+ break;
32608+ }
32609+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
32610+ case AH_NONE:
32611+ break;
32612+ default:
32613+ KLIPS_PRINT(debug_pfkey,
32614+ "klips_debug:pfkey_tdb_init: "
32615+ "authalg=%d support not available in the kernel.\n",
32616+ tdbp->tdb_authalg);
32617+ SENDERR(EINVAL);
32618+ }
32619+ }
32620+ break;
32621+#endif /* !CONFIG_IPSEC_ESP */
32622+#ifdef CONFIG_IPSEC_IPCOMP
32623+ case IPPROTO_COMP:
32624+ tdbp->tdb_comp_adapt_tries = 0;
32625+ tdbp->tdb_comp_adapt_skip = 0;
32626+ tdbp->tdb_comp_ratio_cbytes = 0;
32627+ tdbp->tdb_comp_ratio_dbytes = 0;
32628+ break;
32629+#endif /* CONFIG_IPSEC_IPCOMP */
32630+ default:
32631+ KLIPS_PRINT(debug_pfkey,
32632+ "klips_debug:pfkey_tdb_init: "
32633+ "proto=%d unknown.\n",
32634+ tdbp->tdb_said.proto);
32635+ SENDERR(EINVAL);
32636+ }
32637+
32638+ errlab:
32639+ return(error);
32640+}
32641+
32642+
32643+int
32644+pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
32645+{
32646+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: error=%d\n", error);
32647+ if (!error) {
32648+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
32649+ "success.\n");
32650+ return 1;
32651+ } else {
32652+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
32653+ "caught error %d\n", error);
32654+ pfkey_extensions_free(extensions);
32655+ return 0;
32656+ }
32657+}
32658+
32659+
32660+DEBUG_NO_STATIC int
32661+pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
32662+{
32663+ int error = 0;
32664+ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
32665+ int found_avail = 0;
32666+ struct tdb *tdbq;
32667+ char sa[SATOA_BUF];
32668+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
32669+ struct sadb_msg *pfkey_reply = NULL;
32670+ struct socket_list *pfkey_socketsp;
32671+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
32672+
32673+ KLIPS_PRINT(debug_pfkey,
32674+ "klips_debug:pfkey_getspi_parse: .\n");
32675+
32676+ pfkey_extensions_init(extensions_reply);
32677+
32678+ if(!extr || !extr->tdb) {
32679+ KLIPS_PRINT(debug_pfkey,
32680+ "klips_debug:pfkey_getspi_parse: error, extr or extr->tdb pointer NULL\n");
32681+ SENDERR(EINVAL);
32682+ }
32683+
32684+ if(extensions[SADB_EXT_SPIRANGE]) {
32685+ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
32686+ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
32687+ }
32688+
32689+ if(maxspi == minspi) {
32690+ extr->tdb->tdb_said.spi = maxspi;
32691+ if((tdbq = gettdb(&(extr->tdb->tdb_said)))) {
32692+ satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
32693+ KLIPS_PRINT(debug_pfkey,
32694+ "klips_debug: pfkey_getspi_parse: EMT_GETSPI found an old Tunnel Descriptor Block\n"
32695+ "klips_debug: for SA: %s, delete it first.\n", sa);
32696+ SENDERR(EEXIST);
32697+ } else {
32698+ found_avail = 1;
32699+ }
32700+ } else {
32701+ int i = 0;
32702+ __u32 rand_val;
32703+ __u32 spi_diff;
32704+ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
32705+ get_random_bytes((void*) &(rand_val),
32706+ /* sizeof(extr->tdb->tdb_said.spi) */
32707+ ( (spi_diff < (2^8)) ? 1 :
32708+ ( (spi_diff < (2^16)) ? 2 :
32709+ ( (spi_diff < (2^24)) ? 3 :
32710+ 4 ) ) ) );
32711+ extr->tdb->tdb_said.spi = htonl(ntohl(minspi) +
32712+ (rand_val %
32713+ (spi_diff + 1)));
32714+ i++;
32715+ tdbq = gettdb(&(extr->tdb->tdb_said));
32716+ if(!tdbq) {
32717+ found_avail = 1;
32718+ }
32719+ }
32720+ }
32721+
32722+ satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
32723+
32724+ if (!found_avail) {
32725+ KLIPS_PRINT(debug_pfkey,
32726+ "klips_debug: pfkey_getspi_parse: found an old Tunnel Descriptor Block\n"
32727+ "klips_debug: for SA: %s, delete it first.\n", sa);
32728+ SENDERR(EEXIST);
32729+ }
32730+
32731+ if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) {
32732+ extr->tdb->tdb_flags |= EMT_INBOUND;
32733+ }
32734+
32735+ KLIPS_PRINT(debug_pfkey,
32736+ "klips_debug: pfkey_getspi_parse: existing Tunnel Descriptor Block not found (this\n"
32737+ "klips_debug: is good) for SA: %s, %s-bound, allocating.\n",
32738+ sa, extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out");
32739+
32740+ /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/
32741+ extr->tdb->tdb_rcvif = NULL;
32742+ extr->tdb->tdb_lifetime_addtime_c = jiffies/HZ;
32743+
32744+ extr->tdb->tdb_state = SADB_SASTATE_LARVAL;
32745+
32746+ if(!extr->tdb->tdb_lifetime_allocations_c) {
32747+ extr->tdb->tdb_lifetime_allocations_c += 1;
32748+ }
32749+
32750+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
32751+ SADB_GETSPI,
32752+ satype,
32753+ 0,
32754+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
32755+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
32756+ extensions_reply) &&
32757+ pfkey_safe_build(pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
32758+ SADB_EXT_SA,
32759+ extr->tdb->tdb_said.spi,
32760+ 0,
32761+ SADB_SASTATE_LARVAL,
32762+ 0,
32763+ 0,
32764+ 0),
32765+ extensions_reply) &&
32766+ pfkey_safe_build(pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
32767+ SADB_EXT_ADDRESS_SRC,
32768+ 0, /*extr->tdb->tdb_said.proto,*/
32769+ 0,
32770+ extr->tdb->tdb_addr_s),
32771+ extensions_reply) &&
32772+ pfkey_safe_build(pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
32773+ SADB_EXT_ADDRESS_DST,
32774+ 0, /*extr->tdb->tdb_said.proto,*/
32775+ 0,
32776+ extr->tdb->tdb_addr_d),
32777+ extensions_reply) )) {
32778+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
32779+ "failed to build the getspi reply message extensions\n");
32780+ goto errlab;
32781+ }
32782+
32783+ if((error = puttdb(extr->tdb))) {
32784+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
32785+ "failed to add the larval SA with error=%d.\n",
32786+ error);
32787+ goto errlab;
32788+ }
32789+
32790+ KLIPS_PRINT(debug_pfkey,
32791+ "klips_debug:pfkey_getspi_parse: successful for SA: %s\n", sa);
32792+
32793+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
32794+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
32795+ "failed to build the getspi reply message\n");
32796+ goto errlab;
32797+ }
32798+ for(pfkey_socketsp = pfkey_open_sockets;
32799+ pfkey_socketsp;
32800+ pfkey_socketsp = pfkey_socketsp->next) {
32801+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
32802+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
32803+ "sending up getspi reply message for satype=%d to socket=%p failed with error=%d.\n",
32804+ satype, pfkey_socketsp->socketp, error);
32805+ goto errlab;
32806+ }
32807+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
32808+ "sending up getspi reply message for satype=%d to socket=%p succeeded.\n",
32809+ satype, pfkey_socketsp->socketp);
32810+ }
32811+
32812+ errlab:
32813+ if (pfkey_reply) {
32814+ pfkey_msg_free(&pfkey_reply);
32815+ }
32816+ pfkey_extensions_free(extensions_reply);
32817+ return error;
32818+}
32819+
32820+DEBUG_NO_STATIC int
32821+pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
32822+{
32823+ int error = 0;
32824+ struct tdb* tdbq;
32825+ char sa[SATOA_BUF];
32826+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
32827+ struct sadb_msg *pfkey_reply = NULL;
32828+ struct socket_list *pfkey_socketsp;
32829+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
32830+
32831+ KLIPS_PRINT(debug_pfkey,
32832+ "klips_debug:pfkey_update_parse: .\n");
32833+
32834+ pfkey_extensions_init(extensions_reply);
32835+
32836+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
32837+ KLIPS_PRINT(debug_pfkey,
32838+ "klips_debug:pfkey_update_parse: "
32839+ "error, sa_state=%d must be MATURE=%d\n",
32840+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
32841+ SADB_SASTATE_MATURE);
32842+ SENDERR(EINVAL);
32843+ }
32844+
32845+ if(!extr || !extr->tdb) {
32846+ KLIPS_PRINT(debug_pfkey,
32847+ "klips_debug:pfkey_update_parse: error, extr or extr->tdb pointer NULL\n");
32848+ SENDERR(EINVAL);
32849+ }
32850+
32851+ satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
32852+
32853+ spin_lock_bh(&tdb_lock);
32854+
32855+ tdbq = gettdb(&(extr->tdb->tdb_said));
32856+ if (!tdbq) {
32857+ spin_unlock_bh(&tdb_lock);
32858+ KLIPS_PRINT(debug_pfkey,
32859+ "klips_debug: pfkey_update_parse: reserved Tunnel Descriptor Block\n"
32860+ "klips_debug: for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n", sa);
32861+ SENDERR(EEXIST);
32862+ }
32863+
32864+ if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) {
32865+ extr->tdb->tdb_flags |= EMT_INBOUND;
32866+ }
32867+
32868+ KLIPS_PRINT(debug_pfkey,
32869+ "klips_debug: pfkey_update_parse: existing Tunnel Descriptor Block found (this\n"
32870+ "klips_debug: is good) for SA: %s, %s-bound, updating.\n",
32871+ sa, extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out");
32872+
32873+ /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/
32874+ extr->tdb->tdb_rcvif = NULL;
32875+ if ((error = pfkey_tdb_init(extr->tdb, extensions))) {
32876+ spin_unlock_bh(&tdb_lock);
32877+ KLIPS_PRINT(debug_pfkey,
32878+ "klips_debug:pfkey_update_parse: "
32879+ "not successful for SA: %s, deleting.\n", sa);
32880+ ipsec_tdbwipe(extr->tdb);
32881+ SENDERR(-error);
32882+ }
32883+
32884+ extr->tdb->tdb_lifetime_addtime_c = tdbq->tdb_lifetime_addtime_c;
32885+ if((error = deltdbchain(tdbq))) {
32886+ spin_unlock_bh(&tdb_lock);
32887+ KLIPS_PRINT(debug_pfkey,
32888+ "klips_debug:pfkey_update_parse: "
32889+ "error=%d, trouble deleting intermediate tdb for SA=%s.\n",
32890+ error, sa);
32891+ SENDERR(-error);
32892+ }
32893+
32894+ spin_unlock_bh(&tdb_lock);
32895+
32896+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
32897+ SADB_UPDATE,
32898+ satype,
32899+ 0,
32900+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
32901+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
32902+ extensions_reply)
32903+ && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
32904+ SADB_EXT_SA,
32905+ extr->tdb->tdb_said.spi,
32906+ extr->tdb->tdb_replaywin,
32907+ extr->tdb->tdb_state,
32908+ extr->tdb->tdb_authalg,
32909+ extr->tdb->tdb_encalg,
32910+ extr->tdb->tdb_flags),
32911+ extensions_reply)
32912+ /* FIXME: The 3 lifetime extentions should only be sent if
32913+ non-zero. */
32914+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
32915+ SADB_EXT_LIFETIME_CURRENT,
32916+ extr->tdb->tdb_lifetime_allocations_c,
32917+ extr->tdb->tdb_lifetime_bytes_c,
32918+ extr->tdb->tdb_lifetime_addtime_c,
32919+ extr->tdb->tdb_lifetime_usetime_c),
32920+ extensions)
32921+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
32922+ SADB_EXT_LIFETIME_HARD,
32923+ extr->tdb->tdb_lifetime_allocations_h,
32924+ extr->tdb->tdb_lifetime_bytes_h,
32925+ extr->tdb->tdb_lifetime_addtime_h,
32926+ extr->tdb->tdb_lifetime_usetime_h),
32927+ extensions)
32928+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
32929+ SADB_EXT_ADDRESS_SRC,
32930+ 0, /*extr->tdb->tdb_said.proto,*/
32931+ 0,
32932+ extr->tdb->tdb_addr_s),
32933+ extensions_reply)
32934+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
32935+ SADB_EXT_ADDRESS_DST,
32936+ 0, /*extr->tdb->tdb_said.proto,*/
32937+ 0,
32938+ extr->tdb->tdb_addr_d),
32939+ extensions_reply)
32940+#if 0
32941+ /* FIXME: This won't work yet because I have not finished
32942+ it. */
32943+ && extr->tdb->tdb_ident_data_s ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
32944+ SADB_EXT_IDENTITY_SRC,
32945+ SADB_IDENTTYPE_PREFIX,
32946+ 0,
32947+ extr->tdb->tdb_ident_data_s),
32948+ extensions_reply) : 1
32949+ /* FIXME: This won't work yet because I have not finished
32950+ it. */
32951+ && extr->tdb->tdb_ident_data_d ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
32952+ SADB_EXT_IDENTITY_DST,
32953+ SADB_IDENTTYPE_PREFIX,
32954+ 0,
32955+ extr->tdb->tdb_ident_data_d),
32956+ extensions_reply) : 1
32957+ /* FIXME: This won't work yet because I have not finished
32958+ it. */
32959+ && extr->tdb->tdb_sens_ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
32960+ extr->tdb->tdb_sens_dpd,
32961+ extr->tdb->tdb_sens_sens_level,
32962+ extr->tdb->tdb_sens_sens_len,
32963+ extr->tdb->tdb_sens_sens_bitmap,
32964+ extr->tdb->tdb_sens_integ_level,
32965+ extr->tdb->tdb_sens_integ_len,
32966+ extr->tdb->tdb_sens_integ_bitmap),
32967+ extensions_reply) : 1
32968+#endif
32969+ )) {
32970+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
32971+ "failed to build the update reply message extensions\n");
32972+ goto errlab;
32973+ }
32974+
32975+ if((error = puttdb(extr->tdb))) {
32976+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
32977+ "failed to add the mature SA with error=%d.\n",
32978+ error);
32979+ goto errlab;
32980+ }
32981+
32982+ KLIPS_PRINT(debug_pfkey,
32983+ "klips_debug:pfkey_update_parse: successful for SA: %s\n", sa);
32984+
32985+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
32986+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
32987+ "failed to build the update reply message\n");
32988+ goto errlab;
32989+ }
32990+ for(pfkey_socketsp = pfkey_open_sockets;
32991+ pfkey_socketsp;
32992+ pfkey_socketsp = pfkey_socketsp->next) {
32993+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
32994+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
32995+ "sending up update reply message for satype=%d to socket=%p failed with error=%d.\n",
32996+ satype, pfkey_socketsp->socketp, error);
32997+ goto errlab;
32998+ }
32999+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
33000+ "sending up update reply message for satype=%d to socket=%p succeeded.\n",
33001+ satype, pfkey_socketsp->socketp);
33002+ }
33003+
33004+ errlab:
33005+ if (pfkey_reply) {
33006+ pfkey_msg_free(&pfkey_reply);
33007+ }
33008+ pfkey_extensions_free(extensions_reply);
33009+ return error;
33010+}
33011+
33012+DEBUG_NO_STATIC int
33013+pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33014+{
33015+ int error = 0;
33016+ struct tdb* tdbq;
33017+ char sa[SATOA_BUF];
33018+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
33019+ struct sadb_msg *pfkey_reply = NULL;
33020+ struct socket_list *pfkey_socketsp;
33021+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
33022+
33023+ KLIPS_PRINT(debug_pfkey,
33024+ "klips_debug:pfkey_add_parse: parsing add message\n");
33025+
33026+ pfkey_extensions_init(extensions_reply);
33027+
33028+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
33029+ KLIPS_PRINT(debug_pfkey,
33030+ "klips_debug:pfkey_add_parse: "
33031+ "error, sa_state=%d must be MATURE=%d\n",
33032+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
33033+ SADB_SASTATE_MATURE);
33034+ SENDERR(EINVAL);
33035+ }
33036+
33037+ if(!extr || !extr->tdb) {
33038+ KLIPS_PRINT(debug_pfkey,
33039+ "klips_debug:pfkey_add_parse: extr or extr->tdb pointer NULL\n");
33040+ SENDERR(EINVAL);
33041+ }
33042+
33043+ satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
33044+
33045+ tdbq = gettdb(&(extr->tdb->tdb_said));
33046+ if (tdbq) {
33047+ KLIPS_PRINT(debug_pfkey,
33048+ "klips_debug:pfkey_add_parse: found an old Tunnel Descriptor Block\n"
33049+ "klips_debug: for SA: %s, delete it first.\n", sa);
33050+ SENDERR(EEXIST);
33051+ }
33052+
33053+ if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) {
33054+ extr->tdb->tdb_flags |= EMT_INBOUND;
33055+ }
33056+
33057+ KLIPS_PRINT(debug_pfkey,
33058+ "klips_debug:pfkey_add_parse: existing Tunnel Descriptor Block not found (this\n"
33059+ "klips_debug: is good) for SA: %s, %s-bound, allocating.\n",
33060+ sa, extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out");
33061+
33062+ /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/
33063+ extr->tdb->tdb_rcvif = NULL;
33064+
33065+ if ((error = pfkey_tdb_init(extr->tdb, extensions))) {
33066+ KLIPS_PRINT(debug_pfkey,
33067+ "klips_debug:pfkey_add_parse: not successful for SA: %s, deleting.\n", sa);
33068+ ipsec_tdbwipe(extr->tdb);
33069+ goto errlab;
33070+ }
33071+
33072+ extr->tdb->tdb_lifetime_addtime_c = jiffies / HZ;
33073+ if(!extr->tdb->tdb_lifetime_allocations_c) {
33074+ extr->tdb->tdb_lifetime_allocations_c += 1;
33075+ }
33076+
33077+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
33078+ SADB_ADD,
33079+ satype,
33080+ 0,
33081+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
33082+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
33083+ extensions_reply)
33084+ && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
33085+ SADB_EXT_SA,
33086+ extr->tdb->tdb_said.spi,
33087+ extr->tdb->tdb_replaywin,
33088+ extr->tdb->tdb_state,
33089+ extr->tdb->tdb_authalg,
33090+ extr->tdb->tdb_encalg,
33091+ extr->tdb->tdb_flags),
33092+ extensions_reply)
33093+ /* FIXME: The 3 lifetime extentions should only be sent if
33094+ non-zero. */
33095+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
33096+ SADB_EXT_LIFETIME_CURRENT,
33097+ extr->tdb->tdb_lifetime_allocations_c,
33098+ extr->tdb->tdb_lifetime_bytes_c,
33099+ extr->tdb->tdb_lifetime_addtime_c,
33100+ extr->tdb->tdb_lifetime_usetime_c),
33101+ extensions)
33102+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
33103+ SADB_EXT_LIFETIME_HARD,
33104+ extr->tdb->tdb_lifetime_allocations_h,
33105+ extr->tdb->tdb_lifetime_bytes_h,
33106+ extr->tdb->tdb_lifetime_addtime_h,
33107+ extr->tdb->tdb_lifetime_usetime_h),
33108+ extensions)
33109+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
33110+ SADB_EXT_ADDRESS_SRC,
33111+ 0, /*extr->tdb->tdb_said.proto,*/
33112+ 0,
33113+ extr->tdb->tdb_addr_s),
33114+ extensions_reply)
33115+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
33116+ SADB_EXT_ADDRESS_DST,
33117+ 0, /*extr->tdb->tdb_said.proto,*/
33118+ 0,
33119+ extr->tdb->tdb_addr_d),
33120+ extensions_reply)
33121+#if 0
33122+ /* FIXME: This won't work yet because I have not finished
33123+ it. */
33124+ && extr->tdb->tdb_ident_data_s ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
33125+ SADB_EXT_IDENTITY_SRC,
33126+ SADB_IDENTTYPE_PREFIX,
33127+ 0,
33128+ extr->tdb->tdb_ident_data_s),
33129+ extensions_reply) : 1
33130+ /* FIXME: This won't work yet because I have not finished
33131+ it. */
33132+ && extr->tdb->tdb_ident_data_d ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
33133+ SADB_EXT_IDENTITY_DST,
33134+ SADB_IDENTTYPE_PREFIX,
33135+ 0,
33136+ extr->tdb->tdb_ident_data_d),
33137+ extensions_reply) : 1
33138+ /* FIXME: This won't work yet because I have not finished
33139+ it. */
33140+ && extr->tdb->tdb_sens_ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
33141+ extr->tdb->tdb_sens_dpd,
33142+ extr->tdb->tdb_sens_sens_level,
33143+ extr->tdb->tdb_sens_sens_len,
33144+ extr->tdb->tdb_sens_sens_bitmap,
33145+ extr->tdb->tdb_sens_integ_level,
33146+ extr->tdb->tdb_sens_integ_len,
33147+ extr->tdb->tdb_sens_integ_bitmap),
33148+ extensions_reply) : 1
33149+#endif
33150+ )) {
33151+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
33152+ "failed to build the add reply message extensions\n");
33153+ goto errlab;
33154+ }
33155+
33156+ if((error = puttdb(extr->tdb))) {
33157+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
33158+ "failed to add the mature SA with error=%d.\n",
33159+ error);
33160+ goto errlab;
33161+ }
33162+
33163+ KLIPS_PRINT(debug_pfkey,
33164+ "klips_debug:pfkey_add_parse: successful for SA: %s\n", sa);
33165+
33166+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
33167+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
33168+ "failed to build the add reply message\n");
33169+ goto errlab;
33170+ }
33171+ for(pfkey_socketsp = pfkey_open_sockets;
33172+ pfkey_socketsp;
33173+ pfkey_socketsp = pfkey_socketsp->next) {
33174+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
33175+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
33176+ "sending up add reply message for satype=%d to socket=%p failed with error=%d.\n",
33177+ satype, pfkey_socketsp->socketp, error);
33178+ goto errlab;
33179+ }
33180+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
33181+ "sending up add reply message for satype=%d to socket=%p succeeded.\n",
33182+ satype, pfkey_socketsp->socketp);
33183+ }
33184+
33185+ errlab:
33186+ if (pfkey_reply) {
33187+ pfkey_msg_free(&pfkey_reply);
33188+ }
33189+ pfkey_extensions_free(extensions_reply);
33190+ return error;
33191+}
33192+
33193+DEBUG_NO_STATIC int
33194+pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33195+{
33196+ struct tdb *tdbp;
33197+ char sa[SATOA_BUF];
33198+ int error = 0;
33199+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
33200+ struct sadb_msg *pfkey_reply = NULL;
33201+ struct socket_list *pfkey_socketsp;
33202+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
33203+
33204+ KLIPS_PRINT(debug_pfkey,
33205+ "klips_debug:pfkey_delete_parse: .\n");
33206+
33207+ pfkey_extensions_init(extensions_reply);
33208+
33209+ if(!extr || !extr->tdb) {
33210+ KLIPS_PRINT(debug_pfkey,
33211+ "klips_debug:pfkey_delete_parse: "
33212+ "extr or extr->tdb pointer NULL, fatal\n");
33213+ SENDERR(EINVAL);
33214+ }
33215+
33216+ satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
33217+
33218+ spin_lock_bh(&tdb_lock);
33219+
33220+ tdbp = gettdb(&(extr->tdb->tdb_said));
33221+ if (tdbp == NULL) {
33222+ spin_unlock_bh(&tdb_lock);
33223+ KLIPS_PRINT(debug_pfkey,
33224+ "klips_debug:pfkey_delete_parse: "
33225+ "Tunnel Descriptor Block not found for SA:%s, could not delete.\n",
33226+ sa);
33227+ SENDERR(ESRCH);
33228+ }
33229+
33230+ if((error = deltdbchain(tdbp))) {
33231+ spin_unlock_bh(&tdb_lock);
33232+ KLIPS_PRINT(debug_pfkey,
33233+ "klips_debug:pfkey_delete_parse: "
33234+ "error=%d returned trying to delete Tunnel Descriptor Block for SA:%s.\n",
33235+ error, sa);
33236+ SENDERR(-error);
33237+ }
33238+ spin_unlock_bh(&tdb_lock);
33239+
33240+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
33241+ SADB_DELETE,
33242+ satype,
33243+ 0,
33244+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
33245+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
33246+ extensions_reply)
33247+ && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
33248+ SADB_EXT_SA,
33249+ extr->tdb->tdb_said.spi,
33250+ 0,
33251+ 0,
33252+ 0,
33253+ 0,
33254+ 0),
33255+ extensions_reply)
33256+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
33257+ SADB_EXT_ADDRESS_SRC,
33258+ 0, /*extr->tdb->tdb_said.proto,*/
33259+ 0,
33260+ extr->tdb->tdb_addr_s),
33261+ extensions_reply)
33262+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
33263+ SADB_EXT_ADDRESS_DST,
33264+ 0, /*extr->tdb->tdb_said.proto,*/
33265+ 0,
33266+ extr->tdb->tdb_addr_d),
33267+ extensions_reply)
33268+ )) {
33269+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
33270+ "failed to build the delete reply message extensions\n");
33271+ goto errlab;
33272+ }
33273+
33274+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
33275+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
33276+ "failed to build the delete reply message\n");
33277+ goto errlab;
33278+ }
33279+ for(pfkey_socketsp = pfkey_open_sockets;
33280+ pfkey_socketsp;
33281+ pfkey_socketsp = pfkey_socketsp->next) {
33282+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
33283+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
33284+ "sending up delete reply message for satype=%d to socket=%p failed with error=%d.\n",
33285+ satype, pfkey_socketsp->socketp, error);
33286+ goto errlab;
33287+ }
33288+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
33289+ "sending up delete reply message for satype=%d to socket=%p succeeded.\n",
33290+ satype, pfkey_socketsp->socketp);
33291+ }
33292+
33293+ errlab:
33294+ ipsec_tdbwipe(extr->tdb);
33295+
33296+ if (pfkey_reply) {
33297+ pfkey_msg_free(&pfkey_reply);
33298+ }
33299+ pfkey_extensions_free(extensions_reply);
33300+ return error;
33301+}
33302+
33303+DEBUG_NO_STATIC int
33304+pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33305+{
33306+ int error = 0;
33307+ struct tdb *tdbp;
33308+ char sa[SATOA_BUF];
33309+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
33310+ struct sadb_msg *pfkey_reply = NULL;
33311+
33312+ KLIPS_PRINT(debug_pfkey,
33313+ "klips_debug:pfkey_get_parse: .\n");
33314+
33315+ pfkey_extensions_init(extensions_reply);
33316+
33317+ if(!extr || !extr->tdb) {
33318+ KLIPS_PRINT(debug_pfkey,
33319+ "klips_debug:pfkey_get_parse: "
33320+ "extr or extr->tdb pointer NULL, fatal\n");
33321+ SENDERR(EINVAL);
33322+ }
33323+
33324+ satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF);
33325+
33326+ spin_lock_bh(&tdb_lock);
33327+
33328+ tdbp = gettdb(&(extr->tdb->tdb_said));
33329+ if (tdbp == NULL) {
33330+ spin_unlock_bh(&tdb_lock);
33331+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
33332+ "Tunnel Descriptor Block not found for SA=%s, could not get.\n",
33333+ sa);
33334+ SENDERR(ESRCH);
33335+ }
33336+
33337+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
33338+ SADB_GET,
33339+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
33340+ 0,
33341+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
33342+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
33343+ extensions_reply)
33344+ && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA],
33345+ SADB_EXT_SA,
33346+ extr->tdb->tdb_said.spi,
33347+ extr->tdb->tdb_replaywin,
33348+ extr->tdb->tdb_state,
33349+ extr->tdb->tdb_authalg,
33350+ extr->tdb->tdb_encalg,
33351+ extr->tdb->tdb_flags),
33352+ extensions_reply)
33353+ /* FIXME: The 3 lifetime extentions should only be sent if
33354+ non-zero. */
33355+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
33356+ SADB_EXT_LIFETIME_CURRENT,
33357+ tdbp->tdb_lifetime_allocations_c,
33358+ tdbp->tdb_lifetime_bytes_c,
33359+ tdbp->tdb_lifetime_addtime_c,
33360+ tdbp->tdb_lifetime_usetime_c),
33361+ extensions)
33362+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
33363+ SADB_EXT_LIFETIME_HARD,
33364+ tdbp->tdb_lifetime_allocations_h,
33365+ tdbp->tdb_lifetime_bytes_h,
33366+ tdbp->tdb_lifetime_addtime_h,
33367+ tdbp->tdb_lifetime_usetime_h),
33368+ extensions)
33369+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
33370+ SADB_EXT_LIFETIME_SOFT,
33371+ tdbp->tdb_lifetime_allocations_s,
33372+ tdbp->tdb_lifetime_bytes_s,
33373+ tdbp->tdb_lifetime_addtime_s,
33374+ tdbp->tdb_lifetime_usetime_s),
33375+ extensions)
33376+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
33377+ SADB_EXT_ADDRESS_SRC,
33378+ 0, /*extr->tdb->tdb_said.proto,*/
33379+ 0,
33380+ extr->tdb->tdb_addr_s),
33381+ extensions_reply)
33382+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
33383+ SADB_EXT_ADDRESS_DST,
33384+ 0, /*extr->tdb->tdb_said.proto,*/
33385+ 0,
33386+ extr->tdb->tdb_addr_d),
33387+ extensions_reply)
33388+ && extr->tdb->tdb_addr_d ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
33389+ SADB_EXT_ADDRESS_PROXY,
33390+ 0, /*extr->tdb->tdb_said.proto,*/
33391+ 0,
33392+ extr->tdb->tdb_addr_p),
33393+ extensions_reply) : 1
33394+#if 0
33395+ /* FIXME: This won't work yet because the keys are not
33396+ stored directly in the tdb. They are stored as
33397+ contexts. */
33398+ && extr->tdb->tdb_key_a_size ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
33399+ SADB_EXT_KEY_AUTH,
33400+ extr->tdb->tdb_key_a_size * 8,
33401+ extr->tdb->tdb_key_a),
33402+ extensions_reply)
33403+ /* FIXME: This won't work yet because the keys are not
33404+ stored directly in the tdb. They are stored as
33405+ key schedules. */
33406+ && extr->tdb->tdb_key_e_size ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
33407+ SADB_EXT_KEY_ENCRYPT,
33408+ extr->tdb->tdb_key_e_size * 8,
33409+ extr->tdb->tdb_key_e),
33410+ extensions_reply) : 1
33411+ /* FIXME: This won't work yet because I have not finished
33412+ it. */
33413+ && extr->tdb->tdb_ident_data_s ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
33414+ SADB_EXT_IDENTITY_SRC,
33415+ SADB_IDENTTYPE_PREFIX,
33416+ 0,
33417+ extr->tdb->tdb_ident_data_s),
33418+ extensions_reply) : 1
33419+ /* FIXME: This won't work yet because I have not finished
33420+ it. */
33421+ && extr->tdb->tdb_ident_data_d ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
33422+ SADB_EXT_IDENTITY_DST,
33423+ SADB_IDENTTYPE_PREFIX,
33424+ 0,
33425+ extr->tdb->tdb_ident_data_d),
33426+ extensions_reply) : 1
33427+ /* FIXME: This won't work yet because I have not finished
33428+ it. */
33429+ && extr->tdb->tdb_sens_ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
33430+ extr->tdb->tdb_sens_dpd,
33431+ extr->tdb->tdb_sens_sens_level,
33432+ extr->tdb->tdb_sens_sens_len,
33433+ extr->tdb->tdb_sens_sens_bitmap,
33434+ extr->tdb->tdb_sens_integ_level,
33435+ extr->tdb->tdb_sens_integ_len,
33436+ extr->tdb->tdb_sens_integ_bitmap),
33437+ extensions_reply) : 1
33438+#endif
33439+ )) {
33440+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
33441+ "failed to build the get reply message extensions\n");
33442+ spin_unlock_bh(&tdb_lock);
33443+ goto errlab;
33444+ }
33445+
33446+ spin_unlock_bh(&tdb_lock);
33447+
33448+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
33449+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
33450+ "failed to build the get reply message\n");
33451+ goto errlab;
33452+ }
33453+
33454+ if((error = pfkey_upmsg(sk->socket, pfkey_reply))) {
33455+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
33456+ "failed to send the get reply message\n");
33457+ goto errlab;
33458+ }
33459+
33460+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
33461+ "succeeded in sending get reply message.\n");
33462+
33463+ errlab:
33464+ if (pfkey_reply) {
33465+ pfkey_msg_free(&pfkey_reply);
33466+ }
33467+ pfkey_extensions_free(extensions_reply);
33468+ return error;
33469+}
33470+
33471+DEBUG_NO_STATIC int
33472+pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33473+{
33474+ int error = 0;
33475+ struct socket_list *pfkey_socketsp;
33476+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
33477+
33478+ KLIPS_PRINT(debug_pfkey,
33479+ "klips_debug:pfkey_acquire_parse: .\n");
33480+
33481+ /* I don't know if we want an upper bound, since userspace may
33482+ want to register itself for an satype > SADB_SATYPE_MAX. */
33483+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
33484+ KLIPS_PRINT(debug_pfkey,
33485+ "klips_debug:pfkey_acquire_parse: "
33486+ "SATYPE=%d invalid.\n",
33487+ satype);
33488+ SENDERR(EINVAL);
33489+ }
33490+
33491+ if(!(pfkey_registered_sockets[satype])) {
33492+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
33493+ "no sockets registered for SAtype=%d.\n",
33494+ satype);
33495+ SENDERR(EPROTONOSUPPORT);
33496+ }
33497+
33498+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
33499+ pfkey_socketsp;
33500+ pfkey_socketsp = pfkey_socketsp->next) {
33501+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
33502+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
33503+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
33504+ "sending up acquire reply message for satype=%d to socket=%p failed with error=%d.\n",
33505+ satype, pfkey_socketsp->socketp, error);
33506+ goto errlab;
33507+ }
33508+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
33509+ "sending up acquire reply message for satype=%d to socket=%p succeeded.\n",
33510+ satype, pfkey_socketsp->socketp);
33511+ }
33512+
33513+ errlab:
33514+ return error;
33515+}
33516+
33517+DEBUG_NO_STATIC int
33518+pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33519+{
33520+ unsigned int alg_num_a = 0, alg_num_e = 0;
33521+ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
33522+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
33523+ struct sadb_msg *pfkey_reply = NULL;
33524+ struct supported_list *pfkey_supported_listp;
33525+ struct socket_list *pfkey_socketsp;
33526+ int error = 0;
33527+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
33528+
33529+ KLIPS_PRINT(debug_pfkey,
33530+ "klips_debug:pfkey_register_parse: .\n");
33531+
33532+ pfkey_extensions_init(extensions_reply);
33533+
33534+ /* I don't know if we want an upper bound, since userspace may
33535+ want to register itself for an satype > SADB_SATYPE_MAX. */
33536+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
33537+ KLIPS_PRINT(debug_pfkey,
33538+ "klips_debug:pfkey_register_parse: "
33539+ "SATYPE=%d invalid.\n",
33540+ satype);
33541+ SENDERR(EINVAL);
33542+ }
33543+
33544+ if(!pfkey_list_insert_socket(sk->socket,
33545+ &(pfkey_registered_sockets[satype]))) {
33546+ KLIPS_PRINT(1 || debug_pfkey,
33547+ "klips_debug:pfkey_register_parse: "
33548+ "SATYPE=%02d successfully registered by KMd on pid=%d.\n",
33549+ satype, key_pid(sk));
33550+ };
33551+
33552+ /* send up register msg with supported SATYPE algos */
33553+ pfkey_supported_listp = pfkey_supported_list[satype];
33554+ KLIPS_PRINT(debug_pfkey,
33555+ "klips_debug:pfkey_register_parse: "
33556+ "pfkey_supported_list[%d]=%p\n",
33557+ satype,
33558+ pfkey_supported_list[satype]);
33559+ while(pfkey_supported_listp) {
33560+ KLIPS_PRINT(debug_pfkey,
33561+ "klips_debug:pfkey_register_parse: "
33562+ "checking supported=%p\n",
33563+ pfkey_supported_listp);
33564+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
33565+ KLIPS_PRINT(debug_pfkey,
33566+ "klips_debug:pfkey_register_parse: "
33567+ "adding auth alg.\n");
33568+ alg_num_a++;
33569+ }
33570+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
33571+ KLIPS_PRINT(debug_pfkey,
33572+ "klips_debug:pfkey_register_parse: "
33573+ "adding encrypt alg.\n");
33574+ alg_num_e++;
33575+ }
33576+ pfkey_supported_listp = pfkey_supported_listp->next;
33577+ }
33578+
33579+ if(alg_num_a) {
33580+ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
33581+ KLIPS_PRINT(debug_pfkey,
33582+ "klips_debug:pfkey_register_parse: auth alg memory allocation error\n");
33583+ SENDERR(ENOMEM);
33584+ }
33585+ alg_ap = alg_a;
33586+ }
33587+
33588+ if(alg_num_e) {
33589+ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
33590+ KLIPS_PRINT(debug_pfkey,
33591+ "klips_debug:pfkey_register_parse: enc alg memory allocation error\n");
33592+ SENDERR(ENOMEM);
33593+ }
33594+ alg_ep = alg_e;
33595+ }
33596+
33597+ pfkey_supported_listp = pfkey_supported_list[satype];
33598+ while(pfkey_supported_listp) {
33599+ if(alg_num_a) {
33600+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
33601+ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
33602+ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
33603+ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
33604+ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
33605+ alg_ap->sadb_alg_reserved = 0;
33606+ KLIPS_PRINT(debug_pfkey,
33607+ "klips_debug:pfkey_register_parse: "
33608+ "adding auth=%p\n",
33609+ alg_ap);
33610+ alg_ap++;
33611+ }
33612+ }
33613+ if(alg_num_e) {
33614+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
33615+ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
33616+ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
33617+ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
33618+ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
33619+ alg_ep->sadb_alg_reserved = 0;
33620+ KLIPS_PRINT(debug_pfkey,
33621+ "klips_debug:pfkey_register_parse: "
33622+ "adding encrypt=%p\n",
33623+ alg_ep);
33624+ alg_ep++;
33625+ }
33626+ }
33627+ KLIPS_PRINT(debug_pfkey,
33628+ "klips_debug:pfkey_register_parse: "
33629+ "found satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
33630+ satype,
33631+ pfkey_supported_listp->supportedp->supported_alg_exttype,
33632+ pfkey_supported_listp->supportedp->supported_alg_id,
33633+ pfkey_supported_listp->supportedp->supported_alg_ivlen,
33634+ pfkey_supported_listp->supportedp->supported_alg_minbits,
33635+ pfkey_supported_listp->supportedp->supported_alg_maxbits);
33636+ pfkey_supported_listp = pfkey_supported_listp->next;
33637+ }
33638+
33639+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
33640+ SADB_REGISTER,
33641+ satype,
33642+ 0,
33643+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
33644+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
33645+ extensions_reply) &&
33646+ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
33647+ SADB_EXT_SUPPORTED_AUTH,
33648+ alg_num_a,
33649+ alg_a),
33650+ extensions_reply) : 1) &&
33651+ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
33652+ SADB_EXT_SUPPORTED_ENCRYPT,
33653+ alg_num_e,
33654+ alg_e),
33655+ extensions_reply) : 1))) {
33656+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: "
33657+ "failed to build the register message extensions\n");
33658+ goto errlab;
33659+ }
33660+
33661+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
33662+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: "
33663+ "failed to build the register message\n");
33664+ goto errlab;
33665+ }
33666+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
33667+ pfkey_socketsp;
33668+ pfkey_socketsp = pfkey_socketsp->next) {
33669+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
33670+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: "
33671+ "sending up register reply message for satype=%d to socket=%p failed with error=%d.\n",
33672+ satype, pfkey_socketsp->socketp, error);
33673+ goto errlab;
33674+ }
33675+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_parse: "
33676+ "sending up register reply message for satype=%d to socket=%p succeeded.\n",
33677+ satype, pfkey_socketsp->socketp);
33678+ }
33679+
33680+ errlab:
33681+ if (pfkey_reply) {
33682+ pfkey_msg_free(&pfkey_reply);
33683+ }
33684+ pfkey_extensions_free(extensions_reply);
33685+ return error;
33686+}
33687+
33688+DEBUG_NO_STATIC int
33689+pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33690+{
33691+ int error = 0;
33692+ struct socket_list *pfkey_socketsp;
33693+#ifdef CONFIG_IPSEC_DEBUG
33694+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
33695+#endif /* CONFIG_IPSEC_DEBUG */
33696+
33697+ KLIPS_PRINT(debug_pfkey,
33698+ "klips_debug:pfkey_expire_parse: .\n");
33699+
33700+ if(pfkey_open_sockets) {
33701+ for(pfkey_socketsp = pfkey_open_sockets;
33702+ pfkey_socketsp;
33703+ pfkey_socketsp = pfkey_socketsp->next) {
33704+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
33705+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
33706+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
33707+ "sending up expire reply message for satype=%d to socket=%p failed with error=%d.\n",
33708+ satype, pfkey_socketsp->socketp, error);
33709+ goto errlab;
33710+ }
33711+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
33712+ "sending up expire reply message for satype=%d to socket=%p succeeded.\n",
33713+ satype, pfkey_socketsp->socketp);
33714+ }
33715+ }
33716+
33717+ errlab:
33718+ return error;
33719+}
33720+
33721+DEBUG_NO_STATIC int
33722+pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33723+{
33724+ int error = 0;
33725+ struct socket_list *pfkey_socketsp;
33726+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
33727+
33728+ KLIPS_PRINT(debug_pfkey,
33729+ "klips_debug:pfkey_flush_parse: "
33730+ "flushing type %d SAs\n",
33731+ satype);
33732+
33733+ if ((error = ipsec_tdbcleanup(satype)))
33734+ SENDERR(-error);
33735+
33736+ if(pfkey_open_sockets) {
33737+ for(pfkey_socketsp = pfkey_open_sockets;
33738+ pfkey_socketsp;
33739+ pfkey_socketsp = pfkey_socketsp->next) {
33740+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
33741+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
33742+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
33743+ "sending up flush reply message for satype=%d to socket=%p failed with error=%d.\n",
33744+ satype,
33745+ pfkey_socketsp->socketp,
33746+ error);
33747+ goto errlab;
33748+ }
33749+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
33750+ "sending up flush reply message for satype=%d to socket=%p succeeded.\n",
33751+ satype,
33752+ pfkey_socketsp->socketp);
33753+ }
33754+ }
33755+
33756+ errlab:
33757+ return error;
33758+}
33759+
33760+DEBUG_NO_STATIC int
33761+pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33762+{
33763+ int error = 0;
33764+
33765+ KLIPS_PRINT(debug_pfkey,
33766+ "klips_debug:pfkey_dump_parse: .\n");
33767+
33768+ SENDERR(ENOSYS);
33769+ errlab:
33770+ return error;
33771+}
33772+
33773+DEBUG_NO_STATIC int
33774+pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33775+{
33776+ int error = 0;
33777+
33778+ KLIPS_PRINT(debug_pfkey,
33779+ "klips_debug:pfkey_promisc_parse: .\n");
33780+
33781+ SENDERR(ENOSYS);
33782+ errlab:
33783+ return error;
33784+}
33785+
33786+DEBUG_NO_STATIC int
33787+pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33788+{
33789+ int error = 0;
33790+
33791+ KLIPS_PRINT(debug_pfkey,
33792+ "klips_debug:pfkey_x_pchange_parse: .\n");
33793+
33794+ SENDERR(ENOSYS);
33795+ errlab:
33796+ return error;
33797+}
33798+
33799+DEBUG_NO_STATIC int
33800+pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33801+{
33802+ struct tdb *tdb1p, *tdb2p, *tdbp;
33803+ char sa1[SATOA_BUF], sa2[SATOA_BUF];
33804+ int error = 0;
33805+
33806+ KLIPS_PRINT(debug_pfkey,
33807+ "klips_debug:pfkey_x_grpsa_parse: .\n");
33808+
33809+ spin_lock_bh(&tdb_lock);
33810+
33811+ if(!extr || !extr->tdb) {
33812+ KLIPS_PRINT(debug_pfkey,
33813+ "klips_debug:pfkey_x_grpsa_parse: "
33814+ "extr or extr->tdb is NULL, fatal.\n");
33815+ SENDERR(EINVAL);
33816+ }
33817+
33818+ satoa(extr->tdb->tdb_said, 0, sa1, SATOA_BUF);
33819+ if(extr->tdb2) {
33820+ satoa(extr->tdb2->tdb_said, 0, sa2, SATOA_BUF);
33821+ }
33822+
33823+ if(!(tdb1p = gettdb(&(extr->tdb->tdb_said)))) {
33824+ KLIPS_PRINT(debug_pfkey,
33825+ "klips_debug: pfkey_x_grpsa_parse: reserved Tunnel Descriptor Block\n"
33826+ "klips_debug: for SA: %s not found. Call SADB_ADD/UPDATE first.\n", sa1);
33827+ SENDERR(EEXIST);
33828+ }
33829+ if(extr->tdb2) { /* GRPSA */
33830+ if(!(tdb2p = gettdb(&(extr->tdb2->tdb_said)))) {
33831+ KLIPS_PRINT(debug_pfkey,
33832+ "klips_debug: pfkey_x_grpsa_parse: reserved Tunnel Descriptor Block\n"
33833+ "klips_debug: for SA: %s not found. Call SADB_ADD/UPDATE first.\n", sa2);
33834+ SENDERR(EEXIST);
33835+ }
33836+
33837+ /* Is either one already linked? */
33838+ if(tdb1p->tdb_onext) {
33839+ KLIPS_PRINT(debug_pfkey,
33840+ "klips_debug: pfkey_x_grpsa_parse: Tunnel Descriptor Block\n"
33841+ "klips_debug: for SA: %s is already linked.\n", sa1);
33842+ SENDERR(EEXIST);
33843+ }
33844+ if(tdb2p->tdb_inext) {
33845+ KLIPS_PRINT(debug_pfkey,
33846+ "klips_debug: pfkey_x_grpsa_parse: Tunnel Descriptor Block\n"
33847+ "klips_debug: for SA: %s is already linked.\n", sa2);
33848+ SENDERR(EEXIST);
33849+ }
33850+
33851+ /* Is extr->tdb already linked to extr->tdb2? */
33852+ tdbp = tdb2p;
33853+ while(tdbp) {
33854+ if(tdbp == tdb1p) {
33855+ SENDERR(EEXIST);
33856+ }
33857+ tdbp = tdb2p->tdb_onext;
33858+ }
33859+
33860+ /* link 'em */
33861+ tdb1p->tdb_onext = tdb2p;
33862+ tdb2p->tdb_inext = tdb1p;
33863+ } else { /* UNGRPSA */
33864+ while(tdb1p->tdb_onext) {
33865+ tdb1p = tdb1p->tdb_onext;
33866+ }
33867+ while(tdb1p->tdb_inext) {
33868+ tdbp = tdb1p;
33869+ tdb1p = tdb1p->tdb_inext;
33870+ tdbp->tdb_inext = NULL;
33871+ tdb1p->tdb_onext = NULL;
33872+ }
33873+ }
33874+
33875+ errlab:
33876+ spin_unlock_bh(&tdb_lock);
33877+
33878+ ipsec_tdbwipe(extr->tdb);
33879+ if(extr->tdb2) {
33880+ ipsec_tdbwipe(extr->tdb2);
33881+ }
33882+
33883+ return error;
33884+}
33885+
33886+DEBUG_NO_STATIC int
33887+pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33888+{
33889+ int error = 0;
33890+#ifdef CONFIG_IPSEC_DEBUG
33891+ char buf1[64], buf2[64];
33892+#endif /* CONFIG_IPSEC_DEBUG */
33893+
33894+ KLIPS_PRINT(debug_pfkey,
33895+ "klips_debug:pfkey_x_addflow_parse: .\n");
33896+
33897+ if(!extr || !(extr->tdb) || !(extr->eroute)) {
33898+ KLIPS_PRINT(debug_pfkey,
33899+ "klips_debug:pfkey_x_addflow_parse: "
33900+ "missing extr, tdb or eroute data.\n");
33901+ SENDERR(EINVAL);
33902+ }
33903+
33904+#ifdef CONFIG_IPSEC_DEBUG
33905+ if (debug_pfkey) {
33906+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
33907+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
33908+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
33909+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
33910+ KLIPS_PRINT(debug_pfkey,
33911+ "klips_debug:pfkey_x_addflow_parse: "
33912+ "calling breakeroute and/or makeroute for %s->%s\n",
33913+ buf1, buf2);
33914+ }
33915+#endif /* CONFIG_IPSEC_DEBUG */
33916+ if(extr->tdb->tdb_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
33917+ KLIPS_PRINT(debug_pfkey,
33918+ "klips_debug:pfkey_x_addflow_parse: "
33919+ "REPLACEFLOW flag set, calling breakeroute.\n");
33920+ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
33921+ &(extr->eroute->er_emask))) == EINVAL) {
33922+ KLIPS_PRINT(debug_pfkey,
33923+ "klips_debug:pfkey_x_addflow_parse: "
33924+ "breakeroute returned %d.\n", error);
33925+ SENDERR(-error);
33926+ }
33927+ }
33928+
33929+ KLIPS_PRINT(debug_pfkey,
33930+ "klips_debug:pfkey_x_addflow_parse: "
33931+ "calling makeroute.\n");
33932+
33933+ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
33934+ &(extr->eroute->er_emask),
33935+ extr->tdb->tdb_said))) {
33936+ KLIPS_PRINT(debug_pfkey,
33937+ "klips_debug:pfkey_x_addflow_parse: "
33938+ "makeroute returned %d.\n", error);
33939+ SENDERR(-error);
33940+ }
33941+
33942+ KLIPS_PRINT(debug_pfkey,
33943+ "klips_debug:pfkey_x_addflow_parse: "
33944+ "makeroute call successful.\n");
33945+
33946+ ipsec_tdbwipe(extr->tdb);
33947+
33948+ KLIPS_PRINT(debug_pfkey,
33949+ "klips_debug:pfkey_x_addflow_parse: "
33950+ "extr->tdb cleaned up and freed.\n");
33951+
33952+ errlab:
33953+ return error;
33954+}
33955+
33956+DEBUG_NO_STATIC int
33957+pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
33958+{
33959+ int error = 0;
33960+#ifdef CONFIG_IPSEC_DEBUG
33961+ char buf1[64], buf2[64];
33962+#endif /* CONFIG_IPSEC_DEBUG */
33963+
33964+ KLIPS_PRINT(debug_pfkey,
33965+ "klips_debug:pfkey_x_delflow_parse: .\n");
33966+
33967+ if(!extr || !(extr->tdb)) {
33968+ KLIPS_PRINT(debug_pfkey,
33969+ "klips_debug:pfkey_x_delflow_parse: "
33970+ "extr, or extr->tdb is NULL, fatal\n");
33971+ SENDERR(EINVAL);
33972+ }
33973+
33974+ if(extr->tdb->tdb_flags & SADB_X_SAFLAGS_CLEARFLOW) {
33975+ KLIPS_PRINT(debug_pfkey,
33976+ "klips_debug:pfkey_x_delflow_parse: "
33977+ "CLEARFLOW flag set, calling cleareroutes.\n");
33978+ if ((error = ipsec_cleareroutes()))
33979+ KLIPS_PRINT(debug_pfkey,
33980+ "klips_debug:pfkey_x_delflow_parse: "
33981+ "cleareroutes returned %d.\n", error);
33982+ SENDERR(-error);
33983+ } else {
33984+ if(!(extr->eroute)) {
33985+ KLIPS_PRINT(debug_pfkey,
33986+ "klips_debug:pfkey_x_delflow_parse: "
33987+ "extr->eroute is NULL, fatal.\n");
33988+ SENDERR(EINVAL);
33989+ }
33990+
33991+#ifdef CONFIG_IPSEC_DEBUG
33992+ if (debug_pfkey) {
33993+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
33994+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
33995+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
33996+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
33997+ KLIPS_PRINT(debug_pfkey,
33998+ "klips_debug:pfkey_x_delflow_parse: "
33999+ "calling breakeroute for %s->%s\n",
34000+ buf1, buf2);
34001+ }
34002+#endif /* CONFIG_IPSEC_DEBUG */
34003+ if((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
34004+ &(extr->eroute->er_emask)))) {
34005+ KLIPS_PRINT(debug_pfkey,
34006+ "klips_debug:pfkey_x_delflow_parse: "
34007+ "breakeroute returned %d.\n", error);
34008+ SENDERR(-error);
34009+ }
34010+ }
34011+
34012+ ipsec_tdbwipe(extr->tdb);
34013+
34014+ KLIPS_PRINT(debug_pfkey,
34015+ "klips_debug:pfkey_x_delflow_parse: "
34016+ "extr->tdb cleaned up and freed.\n");
34017+
34018+ errlab:
34019+ return error;
34020+}
34021+
34022+DEBUG_NO_STATIC int
34023+pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
34024+{
34025+ int error = 0;
34026+
34027+ KLIPS_PRINT(debug_pfkey,
34028+ "klips_debug:pfkey_x_msg_debug_parse: .\n");
34029+
34030+/* errlab:*/
34031+ return error;
34032+}
34033+
34034+
34035+int
34036+pfkey_expire(struct tdb *tdbp, int hard)
34037+{
34038+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
34039+ struct sadb_msg *pfkey_msg = NULL;
34040+ struct socket_list *pfkey_socketsp;
34041+ int error = 0;
34042+ uint8_t satype = proto2satype(tdbp->tdb_said.proto);
34043+
34044+ pfkey_extensions_init(extensions);
34045+
34046+ if(!pfkey_open_sockets) {
34047+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
34048+ "no sockets listening.\n");
34049+ SENDERR(EPROTONOSUPPORT);
34050+ }
34051+
34052+ spin_lock(&tdb_lock);
34053+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
34054+ SADB_EXPIRE,
34055+ satype,
34056+ 0,
34057+ ++pfkey_msg_seq,
34058+ 0),
34059+ extensions)
34060+ && pfkey_safe_build(error = pfkey_sa_build(&extensions[SADB_EXT_SA],
34061+ SADB_EXT_SA,
34062+ tdbp->tdb_said.spi,
34063+ tdbp->tdb_replaywin,
34064+ tdbp->tdb_state,
34065+ tdbp->tdb_authalg,
34066+ tdbp->tdb_encalg,
34067+ tdbp->tdb_flags),
34068+ extensions)
34069+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
34070+ SADB_EXT_LIFETIME_CURRENT,
34071+ tdbp->tdb_lifetime_allocations_c,
34072+ tdbp->tdb_lifetime_bytes_c,
34073+ tdbp->tdb_lifetime_addtime_c,
34074+ tdbp->tdb_lifetime_usetime_c),
34075+ extensions)
34076+ && (hard ?
34077+ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
34078+ SADB_EXT_LIFETIME_HARD,
34079+ tdbp->tdb_lifetime_allocations_h,
34080+ tdbp->tdb_lifetime_bytes_h,
34081+ tdbp->tdb_lifetime_addtime_h,
34082+ tdbp->tdb_lifetime_usetime_h),
34083+ extensions)
34084+ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
34085+ SADB_EXT_LIFETIME_SOFT,
34086+ tdbp->tdb_lifetime_allocations_s,
34087+ tdbp->tdb_lifetime_bytes_s,
34088+ tdbp->tdb_lifetime_addtime_s,
34089+ tdbp->tdb_lifetime_usetime_s),
34090+ extensions))
34091+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
34092+ SADB_EXT_ADDRESS_SRC,
34093+ 0, /* tdbp->tdb_said.proto, */
34094+ 0,
34095+ tdbp->tdb_addr_s),
34096+ extensions)
34097+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
34098+ SADB_EXT_ADDRESS_DST,
34099+ 0, /* tdbp->tdb_said.proto, */
34100+ 0,
34101+ tdbp->tdb_addr_d),
34102+ extensions))) {
34103+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: failed to "
34104+ "build the expire message extensions\n");
34105+ spin_unlock(&tdb_lock);
34106+ goto errlab;
34107+ }
34108+
34109+ spin_unlock(&tdb_lock);
34110+
34111+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
34112+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: failed to "
34113+ "build the expire message\n");
34114+ goto errlab;
34115+ }
34116+
34117+ for(pfkey_socketsp = pfkey_open_sockets;
34118+ pfkey_socketsp;
34119+ pfkey_socketsp = pfkey_socketsp->next) {
34120+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
34121+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
34122+ "sending up expire message for satype=%d to socket=%p failed with error=%d.\n",
34123+ satype, pfkey_socketsp->socketp, error);
34124+ goto errlab;
34125+ }
34126+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
34127+ "sending up expire message for satype=%d to socket=%p succeeded.\n",
34128+ satype, pfkey_socketsp->socketp);
34129+ }
34130+
34131+ errlab:
34132+ if (pfkey_msg) {
34133+ pfkey_msg_free(&pfkey_msg);
34134+ }
34135+ pfkey_extensions_free(extensions);
34136+ return error;
34137+}
34138+
34139+int
34140+pfkey_acquire(struct tdb *tdbp)
34141+{
34142+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
34143+ struct sadb_msg *pfkey_msg = NULL;
34144+ struct socket_list *pfkey_socketsp;
34145+ int error = 0;
34146+ struct sadb_comb comb[] = {
34147+ /* auth; encrypt; flags; */
34148+ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
34149+ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
34150+ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
34151+ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
34152+ 128, 128, 168, 168,
34153+ 0, 0, 0, 0, 0,
34154+ 57600, 86400, 57600, 86400 },
34155+ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
34156+ 160, 160, 168, 168,
34157+ 0, 0, 0, 0, 0,
34158+ 57600, 86400, 57600, 86400 }
34159+ };
34160+
34161+ /* This should not be hard-coded. It should be taken from the spdb */
34162+ uint8_t satype = SADB_SATYPE_ESP;
34163+
34164+ pfkey_extensions_init(extensions);
34165+
34166+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
34167+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
34168+ "SAtype=%d unspecified or unknown.\n",
34169+ satype);
34170+ SENDERR(EINVAL);
34171+ }
34172+
34173+ if(!(pfkey_registered_sockets[satype])) {
34174+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
34175+ "no sockets registered for SAtype=%d.\n",
34176+ satype);
34177+ SENDERR(EPROTONOSUPPORT);
34178+ }
34179+
34180+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
34181+ SADB_ACQUIRE,
34182+ satype,
34183+ 0,
34184+ ++pfkey_msg_seq,
34185+ 0),
34186+ extensions)
34187+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
34188+ SADB_EXT_ADDRESS_SRC,
34189+ tdbp->tdb_said.proto,
34190+ 0,
34191+ tdbp->tdb_addr_s),
34192+ extensions)
34193+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
34194+ SADB_EXT_ADDRESS_DST,
34195+ tdbp->tdb_said.proto,
34196+ 0,
34197+ tdbp->tdb_addr_d),
34198+ extensions)
34199+#if 0
34200+ && tdbp->tdb_addr_p ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
34201+ SADB_EXT_ADDRESS_PROXY,
34202+ tdbp->tdb_said.proto,
34203+ 0,
34204+ tdbp->tdb_addr_p),
34205+ extensions) : 1
34206+ /* FIXME: This won't work yet because I have not finished
34207+ it. */
34208+ && tdbp->tdb_ident_data_s ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
34209+ SADB_EXT_IDENTITY_SRC,
34210+ SADB_IDENTTYPE_PREFIX,
34211+ 0,
34212+ tdbp->tdb_ident_data_s),
34213+ extensions) : 1
34214+ /* FIXME: This won't work yet because I have not finished
34215+ it. */
34216+ && tdbp->tdb_ident_data_d ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
34217+ SADB_EXT_IDENTITY_DST,
34218+ SADB_IDENTTYPE_PREFIX,
34219+ 0,
34220+ tdbp->tdb_ident_data_d),
34221+ extensions) : 1
34222+ /* FIXME: This won't work yet because I have not finished
34223+ it. */
34224+ && tdbp->tdb_sens_ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
34225+ tdbp->tdb_sens_dpd,
34226+ tdbp->tdb_sens_sens_level,
34227+ tdbp->tdb_sens_sens_len,
34228+ tdbp->tdb_sens_sens_bitmap,
34229+ tdbp->tdb_sens_integ_level,
34230+ tdbp->tdb_sens_integ_len,
34231+ tdbp->tdb_sens_integ_bitmap),
34232+ extensions) : 1
34233+#endif
34234+ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
34235+ 64, /* replay */
34236+ sizeof(comb)/sizeof(struct sadb_comb),
34237+ &(comb[0])),
34238+ extensions)
34239+ )) {
34240+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: failed to "
34241+ "build the acquire message extensions\n");
34242+ goto errlab;
34243+ }
34244+
34245+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
34246+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: failed to "
34247+ "build the acquire message\n");
34248+ goto errlab;
34249+ }
34250+
34251+ /* this should go to all registered sockets for that satype only */
34252+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
34253+ pfkey_socketsp;
34254+ pfkey_socketsp = pfkey_socketsp->next) {
34255+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
34256+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
34257+ "sending up acquire message for satype=%d to socket=%p failed with error=%d.\n",
34258+ satype, pfkey_socketsp->socketp, error);
34259+ goto errlab;
34260+ }
34261+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
34262+ "sending up acquire message for satype=%d to socket=%p succeeded.\n",
34263+ satype, pfkey_socketsp->socketp);
34264+ }
34265+
34266+ errlab:
34267+ if (pfkey_msg) {
34268+ pfkey_msg_free(&pfkey_msg);
34269+ }
34270+ pfkey_extensions_free(extensions);
34271+ return error;
34272+}
34273+
34274+
34275+DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
34276+{
34277+ NULL, /* pfkey_msg_process, */
34278+ pfkey_sa_process,
34279+ pfkey_lifetime_process,
34280+ pfkey_lifetime_process,
34281+ pfkey_lifetime_process,
34282+ pfkey_address_process,
34283+ pfkey_address_process,
34284+ pfkey_address_process,
34285+ pfkey_key_process,
34286+ pfkey_key_process,
34287+ pfkey_ident_process,
34288+ pfkey_ident_process,
34289+ pfkey_sens_process,
34290+ pfkey_prop_process,
34291+ pfkey_supported_process,
34292+ pfkey_supported_process,
34293+ pfkey_spirange_process,
34294+ pfkey_x_kmprivate_process,
34295+ pfkey_x_satype_process,
34296+ pfkey_sa_process,
34297+ pfkey_address_process,
34298+ pfkey_address_process,
34299+ pfkey_address_process,
34300+ pfkey_address_process,
34301+ pfkey_address_process,
34302+ pfkey_x_debug_process
34303+};
34304+
34305+
34306+DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
34307+ =
34308+{
34309+ NULL, /* RESERVED */
34310+ pfkey_getspi_parse,
34311+ pfkey_update_parse,
34312+ pfkey_add_parse,
34313+ pfkey_delete_parse,
34314+ pfkey_get_parse,
34315+ pfkey_acquire_parse,
34316+ pfkey_register_parse,
34317+ pfkey_expire_parse,
34318+ pfkey_flush_parse,
34319+ pfkey_dump_parse,
34320+ pfkey_x_promisc_parse,
34321+ pfkey_x_pchange_parse,
34322+ pfkey_x_grpsa_parse,
34323+ pfkey_x_addflow_parse,
34324+ pfkey_x_delflow_parse,
34325+ pfkey_x_msg_debug_parse
34326+};
34327+
34328+int
34329+pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr,
34330+ struct sadb_msg **pfkey_reply)
34331+{
34332+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
34333+ int error = 0;
34334+ int msg_type = pfkey_msg->sadb_msg_type;
34335+ int seq = pfkey_msg->sadb_msg_seq;
34336+
34337+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: building reply"
34338+ " with type: %d\n", msg_type);
34339+ pfkey_extensions_init(extensions);
34340+ if (!extr || !extr->tdb) {
34341+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: bad TDB"
34342+ "passed\n");
34343+ return EINVAL;
34344+ }
34345+ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
34346+ msg_type,
34347+ proto2satype(extr->tdb->tdb_said.proto),
34348+ 0,
34349+ seq,
34350+ pfkey_msg->sadb_msg_pid),
34351+ extensions) &&
34352+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
34353+ 1 << SADB_EXT_SA)
34354+ || pfkey_safe_build(pfkey_sa_build(&extensions[SADB_EXT_SA],
34355+ SADB_EXT_SA,
34356+ extr->tdb->tdb_said.spi,
34357+ extr->tdb->tdb_replaywin,
34358+ extr->tdb->tdb_state,
34359+ extr->tdb->tdb_authalg,
34360+ extr->tdb->tdb_encalg,
34361+ extr->tdb->tdb_flags),
34362+ extensions)) &&
34363+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
34364+ 1 << SADB_EXT_LIFETIME_CURRENT)
34365+ || pfkey_safe_build(pfkey_lifetime_build(&extensions
34366+ [SADB_EXT_LIFETIME_CURRENT],
34367+ SADB_EXT_LIFETIME_CURRENT,
34368+ extr->tdb->tdb_lifetime_allocations_c,
34369+ extr->tdb->tdb_lifetime_bytes_c,
34370+ extr->tdb->tdb_lifetime_addtime_c,
34371+ extr->tdb->tdb_lifetime_usetime_c),
34372+ extensions)) &&
34373+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
34374+ 1 << SADB_EXT_ADDRESS_SRC)
34375+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
34376+ SADB_EXT_ADDRESS_SRC,
34377+ extr->tdb->tdb_said.proto,
34378+ 0,
34379+ extr->tdb->tdb_addr_s),
34380+ extensions)) &&
34381+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
34382+ 1 << SADB_EXT_ADDRESS_DST)
34383+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
34384+ SADB_EXT_ADDRESS_DST,
34385+ extr->tdb->tdb_said.proto,
34386+ 0,
34387+ extr->tdb->tdb_addr_d),
34388+ extensions));
34389+
34390+ if (error == 0) {
34391+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
34392+ "building extensions failed\n");
34393+ return EINVAL;
34394+ }
34395+
34396+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: built extensions"
34397+ ", proceed to build the message\n");
34398+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: extensions[1]="
34399+ " %p\n", extensions[1]);
34400+ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
34401+ pfkey_extensions_free(extensions);
34402+
34403+ return error;
34404+}
34405+
34406+int
34407+pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
34408+ struct sadb_msg **pfkey_reply)
34409+{
34410+ int error = 0;
34411+ int i;
34412+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
34413+ struct pfkey_extracted_data extr = {NULL, NULL, NULL};
34414+
34415+ pfkey_extensions_init(extensions);
34416+ KLIPS_PRINT(debug_pfkey,
34417+ "klips_debug:pfkey_msg_interp: parsing message "
34418+ "ver=%d, type=%d, errno=%d, satype=%d, len=%d, res=%d, seq=%d, pid=%d.\n",
34419+ pfkey_msg->sadb_msg_version,
34420+ pfkey_msg->sadb_msg_type,
34421+ pfkey_msg->sadb_msg_errno,
34422+ pfkey_msg->sadb_msg_satype,
34423+ pfkey_msg->sadb_msg_len,
34424+ pfkey_msg->sadb_msg_reserved,
34425+ pfkey_msg->sadb_msg_seq,
34426+ pfkey_msg->sadb_msg_pid);
34427+
34428+ if((error = pfkey_alloc_tdb(&(extr.tdb)))) {
34429+ KLIPS_PRINT(debug_pfkey,
34430+ "klips_debug:pfkey_msg_interp: "
34431+ "something's really wrong, extr.tdb=%p should be NULL.\n", extr.tdb);
34432+ SENDERR(-error);
34433+ }
34434+
34435+ KLIPS_PRINT(debug_pfkey,
34436+ "klips_debug:pfkey_msg_interp: "
34437+ "allocated extr->tdb=%p.\n", extr.tdb);
34438+
34439+ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
34440+ KLIPS_PRINT(debug_pfkey,
34441+ "klips_debug:pfkey_msg_interp: satype %d > max %d\n",
34442+ pfkey_msg->sadb_msg_satype, SADB_SATYPE_MAX);
34443+ SENDERR(EINVAL);
34444+ }
34445+
34446+ switch(pfkey_msg->sadb_msg_type) {
34447+ case SADB_GETSPI:
34448+ case SADB_UPDATE:
34449+ case SADB_ADD:
34450+ case SADB_DELETE:
34451+ case SADB_X_GRPSA:
34452+ if(!(extr.tdb->tdb_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
34453+ KLIPS_PRINT(debug_pfkey,
34454+ "klips_debug:pfkey_msg_interp: satype %d lookup failed.\n",
34455+ pfkey_msg->sadb_msg_satype);
34456+ SENDERR(EINVAL);
34457+ }
34458+ break;
34459+ case SADB_X_ADDFLOW:
34460+ extr.tdb->tdb_said.proto = satype2proto(pfkey_msg->sadb_msg_satype);
34461+ break;
34462+ default:
34463+ }
34464+
34465+ /* The NULL below causes the default extension parsers to be used */
34466+ /* Parse the extensions */
34467+ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
34468+ {
34469+ KLIPS_PRINT(debug_pfkey,
34470+ "klips_debug:pfkey_msg_interp: message parsing failed with error %d.\n",
34471+ error);
34472+ SENDERR(-error);
34473+ }
34474+
34475+ /* Process the extensions */
34476+ for(i=1; i <= SADB_EXT_MAX;i++) {
34477+ if(extensions[i] != NULL) {
34478+ KLIPS_PRINT(debug_pfkey,
34479+ "klips_debug:pfkey_msg_interp: "
34480+ "processing ext %d %p with processor %p.\n",
34481+ i, extensions[i], ext_processors[i]);
34482+ if((error = ext_processors[i](extensions[i], &extr))) {
34483+ KLIPS_PRINT(debug_pfkey,
34484+ "klips_debug:pfkey_msg_interp: extension processing for type %d failed with error %d.\n",
34485+ i,error);
34486+ SENDERR(-error);
34487+ }
34488+
34489+ }
34490+
34491+ }
34492+
34493+ /* Parse the message types */
34494+ KLIPS_PRINT(debug_pfkey,
34495+ "klips_debug:pfkey_msg_interp: "
34496+ "parsing message type %d with msg_parser %p.\n",
34497+ pfkey_msg->sadb_msg_type,
34498+ msg_parsers[pfkey_msg->sadb_msg_type]);
34499+ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
34500+ KLIPS_PRINT(debug_pfkey,
34501+ "klips_debug:pfkey_msg_interp: message parsing failed with error %d.\n",
34502+ error);
34503+ SENDERR(-error);
34504+ }
34505+
34506+#if 0
34507+ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
34508+ if (error) {
34509+ *pfkey_reply = NULL;
34510+ }
34511+#endif
34512+ errlab:
34513+ return(error);
34514+}
34515+
34516+/*
34517+ * $Log$
34518+ * Revision 1.62 2000/11/30 21:47:51 rgb
34519+ * Fix error return bug after returning from pfkey_tdb_init().
34520+ *
34521+ * Revision 1.61 2000/11/17 18:10:29 rgb
34522+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
34523+ * network byte order since this is the way PF_KEYv2 stored spis.
34524+ *
34525+ * Revision 1.60 2000/11/06 04:34:53 rgb
34526+ * Changed non-exported functions to DEBUG_NO_STATIC.
34527+ * Add Svenning's adaptive content compression.
34528+ * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
34529+ * Fixed double unlock bug (Svenning).
34530+ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
34531+ * Fixed incorrect extension type (prop) in pfkey)acquire().
34532+ *
34533+ * Revision 1.59 2000/10/11 15:25:12 rgb
34534+ * Fixed IPCOMP disabled compile bug.
34535+ *
34536+ * Revision 1.58 2000/10/11 14:54:03 rgb
34537+ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
34538+ * protocol violations of setting pfkey_address_build() protocol parameter
34539+ * to non-zero except in the case of pfkey_acquire().
34540+ *
34541+ * Revision 1.57 2000/10/10 20:10:18 rgb
34542+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
34543+ *
34544+ * Revision 1.56 2000/10/06 20:24:36 rgb
34545+ * Fixes to pfkey_acquire to initialize extensions[] and use correct
34546+ * ipproto.
34547+ *
34548+ * Revision 1.55 2000/10/03 03:20:57 rgb
34549+ * Added brackets to get a?b:c scope right for pfkey_register reply.
34550+ *
34551+ * Revision 1.54 2000/09/29 19:49:30 rgb
34552+ * As-yet-unused-bits cleanup.
34553+ *
34554+ * Revision 1.53 2000/09/28 00:35:45 rgb
34555+ * Padded SATYPE printout in pfkey_register for vertical alignment.
34556+ *
34557+ * Revision 1.52 2000/09/20 16:21:58 rgb
34558+ * Cleaned up ident string alloc/free.
34559+ *
34560+ * Revision 1.51 2000/09/20 04:04:20 rgb
34561+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
34562+ * oopsen.
34563+ *
34564+ * Revision 1.50 2000/09/16 01:10:53 rgb
34565+ * Fixed unused var warning with debug off.
34566+ *
34567+ * Revision 1.49 2000/09/15 11:37:02 rgb
34568+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
34569+ * IPCOMP zlib deflate code.
34570+ *
34571+ * Revision 1.48 2000/09/15 04:57:57 rgb
34572+ * Cleaned up existing IPCOMP code before svenning addition.
34573+ * Initialize pfkey_reply and extensions_reply in case of early error in
34574+ * message parsing functions (thanks Kai!).
34575+ *
34576+ * Revision 1.47 2000/09/13 08:02:56 rgb
34577+ * Added KMd registration notification.
34578+ *
34579+ * Revision 1.46 2000/09/12 22:35:36 rgb
34580+ * Restructured to remove unused extensions from CLEARFLOW messages.
34581+ *
34582+ * Revision 1.45 2000/09/12 03:24:23 rgb
34583+ * Converted #if0 debugs to sysctl.
34584+ *
34585+ * Revision 1.44 2000/09/09 06:38:39 rgb
34586+ * Correct SADB message type for update, add and delete.
34587+ *
34588+ * Revision 1.43 2000/09/08 19:19:56 rgb
34589+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
34590+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
34591+ * Put in sanity checks in most msg type parsers to catch invalid satypes
34592+ * and empty socket lists.
34593+ * Moved spin-locks in pfkey_get_parse() to simplify.
34594+ * Added pfkey_acquire().
34595+ * Added upwards messages to update, add, delete, acquire_parse,
34596+ * expire_parse and flush.
34597+ * Fix pfkey_prop_build() parameter to be only single indirection.
34598+ * Changed all replies to use pfkey_reply.
34599+ * Check return code on puttdb() and deltdbchain() in getspi, update,
34600+ * add, delete.
34601+ * Fixed up all pfkey replies to open and registered sockets.
34602+ *
34603+ * Revision 1.42 2000/09/01 18:50:26 rgb
34604+ * Added a supported algorithms array lists, one per satype and registered
34605+ * existing algorithms.
34606+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
34607+ * list.
34608+ * Only send pfkey_expire() messages to sockets registered for that satype.
34609+ * Added reply to pfkey_getspi_parse().
34610+ * Added reply to pfkey_get_parse().
34611+ * Fixed debug output label bug in pfkey_lifetime_process().
34612+ * Cleaned up pfkey_sa_process a little.
34613+ * Moved pfkey_safe_build() above message type parsers to make it available
34614+ * for creating replies.
34615+ * Added comments for future work in pfkey_acquire_parse().
34616+ * Fleshed out guts of pfkey_register_parse().
34617+ *
34618+ * Revision 1.41 2000/08/24 16:58:11 rgb
34619+ * Fixed key debugging variables.
34620+ * Fixed error return code for a failed search.
34621+ * Changed order of pfkey_get operations.
34622+ *
34623+ * Revision 1.40 2000/08/21 16:32:27 rgb
34624+ * Re-formatted for cosmetic consistency and readability.
34625+ *
34626+ * Revision 1.39 2000/08/20 21:38:57 rgb
34627+ * Bugfixes to as-yet-unused pfkey_update_parse() and
34628+ * pfkey_register_parse(). (Momchil)
34629+ * Added functions pfkey_safe_build(), pfkey_expire() and
34630+ * pfkey_build_reply(). (Momchil)
34631+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
34632+ *
34633+ * Revision 1.38 2000/08/18 21:30:41 rgb
34634+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
34635+ *
34636+ * Revision 1.37 2000/08/18 18:18:02 rgb
34637+ * Cosmetic and descriptive changes made to debug test.
34638+ * getspi and update fixes from Momchil.
34639+ *
34640+ * Revision 1.36 2000/08/15 15:41:55 rgb
34641+ * Fixed the (as yet unused and untested) pfkey_getspi() routine.
34642+ *
34643+ * Revision 1.35 2000/08/01 14:51:52 rgb
34644+ * Removed _all_ remaining traces of DES.
34645+ *
34646+ * Revision 1.34 2000/07/28 14:58:32 rgb
34647+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
34648+ *
34649+ * Revision 1.33 2000/06/28 05:50:11 rgb
34650+ * Actually set iv_bits.
34651+ *
34652+ * Revision 1.32 2000/05/30 18:36:56 rgb
34653+ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY
34654+ * FreeS/WAN, but fixes interop with other implementations.
34655+ *
34656+ * Revision 1.31 2000/03/16 14:05:48 rgb
34657+ * Fixed brace scope preventing non-debug compile.
34658+ * Added null parameter check for pfkey_x_debug().
34659+ *
34660+ * Revision 1.30 2000/01/22 23:21:13 rgb
34661+ * Use new function satype2proto().
34662+ *
34663+ * Revision 1.29 2000/01/22 08:40:21 rgb
34664+ * Invert condition to known value to avoid AF_INET6 in 2.0.36.
34665+ *
34666+ * Revision 1.28 2000/01/22 07:58:57 rgb
34667+ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
34668+ *
34669+ * Revision 1.27 2000/01/22 03:48:01 rgb
34670+ * Added extr pointer component debugging.
34671+ *
34672+ * Revision 1.26 2000/01/21 09:41:25 rgb
34673+ * Changed a (void*) to (char*) cast to do proper pointer math.
34674+ * Don't call tdbwipe if tdb2 is NULL.
34675+ *
34676+ * Revision 1.25 2000/01/21 06:21:01 rgb
34677+ * Added address cases for eroute flows.
34678+ * Tidied up compiler directive indentation for readability.
34679+ * Added ictx,octx vars for simplification.
34680+ * Added macros for HMAC padding magic numbers.
34681+ * Converted from double tdb arguments to one structure (extr)
34682+ * containing pointers to all temporary information structures
34683+ * and checking for valid arguments to all ext processors and
34684+ * msg type parsers.
34685+ * Added spiungrp'ing.
34686+ * Added klipsdebug switching capability.
34687+ * Removed sa_process() check for zero protocol.
34688+ * Added address case for DST2 for grouping.
34689+ * Added/changed minor debugging instrumentation.
34690+ * Fixed spigrp for single said, ungrouping case.
34691+ * Added code to parse addflow and delflow messages.
34692+ * Removed redundant statements duplicating tdbwipe() functionality
34693+ * and causing double kfrees.
34694+ * Permit addflow to have a protocol of 0.
34695+ *
34696+ * Revision 1.24 1999/12/09 23:23:00 rgb
34697+ * Added check to pfkey_sa_process() to do eroutes.
34698+ * Converted to DIVUP() macro.
34699+ * Converted if() to switch() in pfkey_register_parse().
34700+ * Use new pfkey_extensions_init() instead of memset().
34701+ *
34702+ * Revision 1.23 1999/12/01 22:18:13 rgb
34703+ * Preset minspi and maxspi values in case and spirange extension is not
34704+ * included and check for the presence of an spirange extension before
34705+ * using it. Initialise tdb_sastate to LARVAL.
34706+ * Fixed debugging output typo.
34707+ * Fixed authentication context initialisation bugs (4 places).
34708+ *
34709+ * Revision 1.22 1999/11/27 11:53:08 rgb
34710+ * Moved pfkey_msg_parse prototype to pfkey.h
34711+ * Moved exts_permitted/required prototype to pfkey.h.
34712+ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
34713+ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
34714+ * be called.
34715+ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
34716+ * Debugging error messages added.
34717+ * Enable lifetime_current checking.
34718+ * Remove illegal requirement for SA extension to be present in an
34719+ * originating GETSPI call.
34720+ * Re-instate requirement for UPDATE or ADD message to be MATURE.
34721+ * Add argument to pfkey_msg_parse() for direction.
34722+ * Fixed IPIP dst address bug and purged redundant, leaky code.
34723+ *
34724+ * Revision 1.21 1999/11/24 05:24:20 rgb
34725+ * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
34726+ * Fixed indention.
34727+ * Ditched redundant replay check.
34728+ * Fixed debug message text from 'parse' to 'process'.
34729+ * Added more debug output.
34730+ * Forgot to zero extensions array causing bug, fixed.
34731+ *
34732+ * Revision 1.20 1999/11/23 23:08:13 rgb
34733+ * Move all common parsing code to lib/pfkey_v2_parse.c and rename
34734+ * remaining bits to *_process. (PJO)
34735+ * Add macros for dealing with alignment and rounding up more opaquely.
34736+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
34737+ * Sort out pfkey and freeswan headers, putting them in a library path.
34738+ * Corrected a couple of bugs in as-yet-inactive code.
34739+ *
34740+ * Revision 1.19 1999/11/20 22:01:10 rgb
34741+ * Add more descriptive error messages for non-zero reserved fields.
34742+ * Add more descriptive error message for spirange parsing.
34743+ * Start on supported extension parsing.
34744+ * Start on register and get message parsing.
34745+ *
34746+ * Revision 1.18 1999/11/18 04:09:20 rgb
34747+ * Replaced all kernel version macros to shorter, readable form.
34748+ *
34749+ * Revision 1.17 1999/11/17 15:53:41 rgb
34750+ * Changed all occurrences of #include "../../../lib/freeswan.h"
34751+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
34752+ * klips/net/ipsec/Makefile.
34753+ *
34754+ * Revision 1.16 1999/10/26 16:57:43 rgb
34755+ * Add shorter macros for compiler directives to visually clean-up.
34756+ * Give ipv6 code meaningful compiler directive.
34757+ * Add comments to other #if 0 debug code.
34758+ * Remove unused *_bh_atomic() calls.
34759+ * Fix mis-placed spinlock.
34760+ *
34761+ * Revision 1.15 1999/10/16 18:27:10 rgb
34762+ * Clean-up unused cruft.
34763+ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
34764+ *
34765+ * Revision 1.14 1999/10/08 18:37:34 rgb
34766+ * Fix end-of-line spacing to sate whining PHMs.
34767+ *
34768+ * Revision 1.13 1999/10/03 18:49:12 rgb
34769+ * Spinlock fixes for 2.0.xx and 2.3.xx.
34770+ *
34771+ * Revision 1.12 1999/10/01 15:44:54 rgb
34772+ * Move spinlock header include to 2.1> scope.
34773+ *
34774+ * Revision 1.11 1999/10/01 00:05:45 rgb
34775+ * Added tdb structure locking.
34776+ * Use 'jiffies' instead of do_get_timeofday().
34777+ * Fix lifetime assignments.
34778+ *
34779+ * Revision 1.10 1999/09/21 15:24:45 rgb
34780+ * Rework spirange code to save entropy and prevent endless loops.
34781+ *
34782+ * Revision 1.9 1999/09/16 12:10:21 rgb
34783+ * Minor fixes to random spi selection for correctness and entropy conservation.
34784+ *
34785+ * Revision 1.8 1999/05/25 22:54:46 rgb
34786+ * Fix comparison that should be an assignment in an if.
34787+ *
34788+ * Revision 1.7 1999/05/09 03:25:37 rgb
34789+ * Fix bug introduced by 2.2 quick-and-dirty patch.
34790+ *
34791+ * Revision 1.6 1999/05/08 21:32:30 rgb
34792+ * Fix error return reporting.
34793+ *
34794+ * Revision 1.5 1999/05/05 22:02:33 rgb
34795+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
34796+ *
34797+ * Revision 1.4 1999/04/29 15:22:40 rgb
34798+ * Standardise an error return method.
34799+ * Add debugging instrumentation.
34800+ * Add check for existence of macros min/max.
34801+ * Add extensions permitted/required in/out filters.
34802+ * Add satype-to-protocol table.
34803+ * Add a second tdb pointer to each parser to accomodate GRPSA.
34804+ * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
34805+ * Add OOO window check.
34806+ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
34807+ * Add timestamp to lifetime parse.
34808+ * Fix address structure length checking bug.
34809+ * Fix address structure allocation bug (forgot to kmalloc!).
34810+ * Add checks for extension lengths.
34811+ * Add checks for extension reserved illegal values.
34812+ * Add check for spirange legal values.
34813+ * Add an extension type for parsing a second satype, SA and
34814+ * DST_ADDRESS.
34815+ * Make changes to tdb_init() template to get pfkey_tdb_init(),
34816+ * eliminating any mention of xformsw.
34817+ * Implement getspi, update and grpsa (not tested).
34818+ * Add stubs for as yet unimplemented message types.
34819+ * Add table of message parsers to substitute for msg_parse switch.
34820+ *
34821+ * Revision 1.3 1999/04/15 17:58:07 rgb
34822+ * Add RCSID labels.
34823+ *
34824+ * Revision 1.2 1999/04/15 15:37:26 rgb
34825+ * Forward check changes from POST1_00 branch.
34826+ *
34827+ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb
34828+ * Add pfkeyv2 support to KLIPS.
34829+ *
34830+ */
34831diff -druN linux-noipsec/net/ipsec/radij.c linux/net/ipsec/radij.c
34832--- linux-noipsec/net/ipsec/radij.c Thu Jan 1 01:00:00 1970
34833+++ linux/net/ipsec/radij.c Mon Nov 6 05:35:21 2000
34834@@ -0,0 +1,1113 @@
34835+char radij_c_version[] = "RCSID $Id$";
34836+
34837+/*
34838+ * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
34839+ *
34840+ * Variable and procedure names have been modified so that they don't
34841+ * conflict with the original BSD code, as a small number of modifications
34842+ * have been introduced and we may want to reuse this code in BSD.
34843+ *
34844+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
34845+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
34846+ * spanish j as in Juan. It is not as far back in the throat like
34847+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
34848+ * It has nothing to do with the Dutch ij sound.
34849+ *
34850+ * Here is the appropriate copyright notice:
34851+ */
34852+
34853+/*
34854+ * Copyright (c) 1988, 1989, 1993
34855+ * The Regents of the University of California. All rights reserved.
34856+ *
34857+ * Redistribution and use in source and binary forms, with or without
34858+ * modification, are permitted provided that the following conditions
34859+ * are met:
34860+ * 1. Redistributions of source code must retain the above copyright
34861+ * notice, this list of conditions and the following disclaimer.
34862+ * 2. Redistributions in binary form must reproduce the above copyright
34863+ * notice, this list of conditions and the following disclaimer in the
34864+ * documentation and/or other materials provided with the distribution.
34865+ * 3. All advertising materials mentioning features or use of this software
34866+ * must display the following acknowledgement:
34867+ * This product includes software developed by the University of
34868+ * California, Berkeley and its contributors.
34869+ * 4. Neither the name of the University nor the names of its contributors
34870+ * may be used to endorse or promote products derived from this software
34871+ * without specific prior written permission.
34872+ *
34873+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34874+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34875+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34876+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34877+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34878+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34879+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34880+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34881+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34882+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34883+ * SUCH DAMAGE.
34884+ *
34885+ * @(#)radix.c 8.2 (Berkeley) 1/4/94
34886+ */
34887+
34888+/*
34889+ * Routines to build and maintain radix trees for routing lookups.
34890+ */
34891+
34892+#include <linux/config.h>
34893+#include <linux/version.h>
34894+
34895+#include <linux/kernel.h> /* printk() */
34896+#include <linux/malloc.h> /* kmalloc() */
34897+#include <linux/errno.h> /* error codes */
34898+#include <linux/types.h> /* size_t */
34899+#include <linux/interrupt.h> /* mark_bh */
34900+
34901+#include <linux/netdevice.h> /* struct device, and other headers */
34902+#include <linux/etherdevice.h> /* eth_type_trans */
34903+#include <linux/ip.h> /* struct iphdr */
34904+#include <linux/skbuff.h>
34905+#include <freeswan.h>
34906+#ifdef NET_21
34907+#include <asm/uaccess.h>
34908+#include <linux/in6.h>
34909+#endif /* NET_21 */
34910+#include <asm/checksum.h>
34911+#include <net/ip.h>
34912+
34913+#include "radij.h"
34914+#include "ipsec_encap.h"
34915+#include "ipsec_radij.h"
34916+#include "ipsec_netlink.h"
34917+
34918+int maj_keylen;
34919+struct radij_mask *rj_mkfreelist;
34920+struct radij_node_head *mask_rjhead;
34921+static int gotOddMasks;
34922+static char *maskedKey;
34923+static char *rj_zeroes, *rj_ones;
34924+
34925+#define rj_masktop (mask_rjhead->rnh_treetop)
34926+#ifdef Bcmp
34927+#undef Bcmp
34928+#endif /* Bcmp */
34929+#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
34930+/*
34931+ * The data structure for the keys is a radix tree with one way
34932+ * branching removed. The index rj_b at an internal node n represents a bit
34933+ * position to be tested. The tree is arranged so that all descendants
34934+ * of a node n have keys whose bits all agree up to position rj_b - 1.
34935+ * (We say the index of n is rj_b.)
34936+ *
34937+ * There is at least one descendant which has a one bit at position rj_b,
34938+ * and at least one with a zero there.
34939+ *
34940+ * A route is determined by a pair of key and mask. We require that the
34941+ * bit-wise logical and of the key and mask to be the key.
34942+ * We define the index of a route to associated with the mask to be
34943+ * the first bit number in the mask where 0 occurs (with bit number 0
34944+ * representing the highest order bit).
34945+ *
34946+ * We say a mask is normal if every bit is 0, past the index of the mask.
34947+ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
34948+ * and m is a normal mask, then the route applies to every descendant of n.
34949+ * If the index(m) < rj_b, this implies the trailing last few bits of k
34950+ * before bit b are all 0, (and hence consequently true of every descendant
34951+ * of n), so the route applies to all descendants of the node as well.
34952+ *
34953+ * The present version of the code makes no use of normal routes,
34954+ * but similar logic shows that a non-normal mask m such that
34955+ * index(m) <= index(n) could potentially apply to many children of n.
34956+ * Thus, for each non-host route, we attach its mask to a list at an internal
34957+ * node as high in the tree as we can go.
34958+ */
34959+
34960+struct radij_node *
34961+rj_search(v_arg, head)
34962+ void *v_arg;
34963+ struct radij_node *head;
34964+{
34965+ register struct radij_node *x;
34966+ register caddr_t v;
34967+
34968+ for (x = head, v = v_arg; x->rj_b >= 0;) {
34969+ if (x->rj_bmask & v[x->rj_off])
34970+ x = x->rj_r;
34971+ else
34972+ x = x->rj_l;
34973+ }
34974+ return (x);
34975+};
34976+
34977+struct radij_node *
34978+rj_search_m(v_arg, head, m_arg)
34979+ struct radij_node *head;
34980+ void *v_arg, *m_arg;
34981+{
34982+ register struct radij_node *x;
34983+ register caddr_t v = v_arg, m = m_arg;
34984+
34985+ for (x = head; x->rj_b >= 0;) {
34986+ if ((x->rj_bmask & m[x->rj_off]) &&
34987+ (x->rj_bmask & v[x->rj_off]))
34988+ x = x->rj_r;
34989+ else
34990+ x = x->rj_l;
34991+ }
34992+ return x;
34993+};
34994+
34995+int
34996+rj_refines(m_arg, n_arg)
34997+ void *m_arg, *n_arg;
34998+{
34999+ register caddr_t m = m_arg, n = n_arg;
35000+ register caddr_t lim, lim2 = lim = n + *(u_char *)n;
35001+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
35002+ int masks_are_equal = 1;
35003+
35004+ if (longer > 0)
35005+ lim -= longer;
35006+ while (n < lim) {
35007+ if (*n & ~(*m))
35008+ return 0;
35009+ if (*n++ != *m++)
35010+ masks_are_equal = 0;
35011+
35012+ }
35013+ while (n < lim2)
35014+ if (*n++)
35015+ return 0;
35016+ if (masks_are_equal && (longer < 0))
35017+ for (lim2 = m - longer; m < lim2; )
35018+ if (*m++)
35019+ return 1;
35020+ return (!masks_are_equal);
35021+}
35022+
35023+
35024+struct radij_node *
35025+rj_match(v_arg, head)
35026+ void *v_arg;
35027+ struct radij_node_head *head;
35028+{
35029+ caddr_t v = v_arg;
35030+ register struct radij_node *t = head->rnh_treetop, *x;
35031+ register caddr_t cp = v, cp2, cp3;
35032+ caddr_t cplim, mstart;
35033+ struct radij_node *saved_t, *top = t;
35034+ int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
35035+
35036+ /*
35037+ * Open code rj_search(v, top) to avoid overhead of extra
35038+ * subroutine call.
35039+ */
35040+ for (; t->rj_b >= 0; ) {
35041+ if (t->rj_bmask & cp[t->rj_off])
35042+ t = t->rj_r;
35043+ else
35044+ t = t->rj_l;
35045+ }
35046+ /*
35047+ * See if we match exactly as a host destination
35048+ */
35049+ KLIPS_PRINT(debug_radij,
35050+ "klips_debug:rj_match: * See if we match exactly as a host destination\n");
35051+
35052+ cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
35053+ for (; cp < cplim; cp++, cp2++)
35054+ if (*cp != *cp2)
35055+ goto on1;
35056+ /*
35057+ * This extra grot is in case we are explicitly asked
35058+ * to look up the default. Ugh!
35059+ */
35060+ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
35061+ t = t->rj_dupedkey;
35062+ return t;
35063+on1:
35064+ matched_off = cp - v;
35065+ saved_t = t;
35066+ KLIPS_PRINT(debug_radij,
35067+ "klips_debug:rj_match: ** try to match a leaf, t=0x%p\n", t);
35068+ do {
35069+ if (t->rj_mask) {
35070+ /*
35071+ * Even if we don't match exactly as a hosts;
35072+ * we may match if the leaf we wound up at is
35073+ * a route to a net.
35074+ */
35075+ cp3 = matched_off + t->rj_mask;
35076+ cp2 = matched_off + t->rj_key;
35077+ for (; cp < cplim; cp++)
35078+ if ((*cp2++ ^ *cp) & *cp3++)
35079+ break;
35080+ if (cp == cplim)
35081+ return t;
35082+ cp = matched_off + v;
35083+ }
35084+ } while ((t = t->rj_dupedkey));
35085+ t = saved_t;
35086+ /* start searching up the tree */
35087+ KLIPS_PRINT(debug_radij,
35088+ "klips_debug:rj_match: *** start searching up the tree, t=0x%p\n", t);
35089+ do {
35090+ register struct radij_mask *m;
35091+
35092+ t = t->rj_p;
35093+ KLIPS_PRINT(debug_radij,
35094+ "klips_debug:rj_match: **** t=0x%p\n", t);
35095+ if ((m = t->rj_mklist)) {
35096+ /*
35097+ * After doing measurements here, it may
35098+ * turn out to be faster to open code
35099+ * rj_search_m here instead of always
35100+ * copying and masking.
35101+ */
35102+ off = min(t->rj_off, matched_off);
35103+ mstart = maskedKey + off;
35104+ do {
35105+ cp2 = mstart;
35106+ cp3 = m->rm_mask + off;
35107+ KLIPS_PRINT(debug_radij,
35108+ "klips_debug:rj_match: ***** cp2=0x%p cp3=0x%p\n", cp2, cp3);
35109+ for (cp = v + off; cp < cplim;)
35110+ *cp2++ = *cp++ & *cp3++;
35111+ x = rj_search(maskedKey, t);
35112+ while (x && x->rj_mask != m->rm_mask)
35113+ x = x->rj_dupedkey;
35114+ if (x &&
35115+ (Bcmp(mstart, x->rj_key + off,
35116+ vlen - off) == 0))
35117+ return x;
35118+ } while ((m = m->rm_mklist));
35119+ }
35120+ } while (t != top);
35121+ KLIPS_PRINT(debug_radij,
35122+ "klips_debug:rj_match: ***** not found.\n");
35123+ return 0;
35124+};
35125+
35126+#ifdef RJ_DEBUG
35127+int rj_nodenum;
35128+struct radij_node *rj_clist;
35129+int rj_saveinfo;
35130+DEBUG_NO_STATIC void traverse(struct radij_node *);
35131+#ifdef RJ_DEBUG2
35132+int rj_debug = 1;
35133+#else
35134+int rj_debug = 0;
35135+#endif /* RJ_DEBUG2 */
35136+#endif /* RJ_DEBUG */
35137+
35138+struct radij_node *
35139+rj_newpair(v, b, nodes)
35140+ void *v;
35141+ int b;
35142+ struct radij_node nodes[2];
35143+{
35144+ register struct radij_node *tt = nodes, *t = tt + 1;
35145+ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
35146+ t->rj_l = tt; t->rj_off = b >> 3;
35147+ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
35148+ tt->rj_flags = t->rj_flags = RJF_ACTIVE;
35149+#ifdef RJ_DEBUG
35150+ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
35151+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
35152+#endif /* RJ_DEBUG */
35153+ return t;
35154+}
35155+
35156+struct radij_node *
35157+rj_insert(v_arg, head, dupentry, nodes)
35158+ void *v_arg;
35159+ struct radij_node_head *head;
35160+ int *dupentry;
35161+ struct radij_node nodes[2];
35162+{
35163+ caddr_t v = v_arg;
35164+ struct radij_node *top = head->rnh_treetop;
35165+ int head_off = top->rj_off, vlen = (int)*((u_char *)v);
35166+ register struct radij_node *t = rj_search(v_arg, top);
35167+ register caddr_t cp = v + head_off;
35168+ register int b;
35169+ struct radij_node *tt;
35170+ /*
35171+ *find first bit at which v and t->rj_key differ
35172+ */
35173+ {
35174+ register caddr_t cp2 = t->rj_key + head_off;
35175+ register int cmp_res;
35176+ caddr_t cplim = v + vlen;
35177+
35178+ while (cp < cplim)
35179+ if (*cp2++ != *cp++)
35180+ goto on1;
35181+ *dupentry = 1;
35182+ return t;
35183+on1:
35184+ *dupentry = 0;
35185+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
35186+ for (b = (cp - v) << 3; cmp_res; b--)
35187+ cmp_res >>= 1;
35188+ }
35189+ {
35190+ register struct radij_node *p, *x = top;
35191+ cp = v;
35192+ do {
35193+ p = x;
35194+ if (cp[x->rj_off] & x->rj_bmask)
35195+ x = x->rj_r;
35196+ else x = x->rj_l;
35197+ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
35198+#ifdef RJ_DEBUG
35199+ if (rj_debug)
35200+ printk("klips_debug:Going In:\n"), traverse(p);
35201+#endif /* RJ_DEBUG */
35202+ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
35203+ if ((cp[p->rj_off] & p->rj_bmask) == 0)
35204+ p->rj_l = t;
35205+ else
35206+ p->rj_r = t;
35207+ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
35208+ if ((cp[t->rj_off] & t->rj_bmask) == 0) {
35209+ t->rj_r = x;
35210+ } else {
35211+ t->rj_r = tt; t->rj_l = x;
35212+ }
35213+#ifdef RJ_DEBUG
35214+ if (rj_debug)
35215+ printk("klips_debug:Coming out:\n"), traverse(p);
35216+#endif /* RJ_DEBUG */
35217+ }
35218+ return (tt);
35219+}
35220+
35221+struct radij_node *
35222+rj_addmask(n_arg, search, skip)
35223+ int search, skip;
35224+ void *n_arg;
35225+{
35226+ caddr_t netmask = (caddr_t)n_arg;
35227+ register struct radij_node *x;
35228+ register caddr_t cp, cplim;
35229+ register int b, mlen, j;
35230+ int maskduplicated;
35231+
35232+ mlen = *(u_char *)netmask;
35233+ if (search) {
35234+ x = rj_search(netmask, rj_masktop);
35235+ mlen = *(u_char *)netmask;
35236+ if (Bcmp(netmask, x->rj_key, mlen) == 0)
35237+ return (x);
35238+ }
35239+ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
35240+ if (x == 0)
35241+ return (0);
35242+ Bzero(x, maj_keylen + 2 * sizeof (*x));
35243+ cp = (caddr_t)(x + 2);
35244+ Bcopy(netmask, cp, mlen);
35245+ netmask = cp;
35246+ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
35247+ /*
35248+ * Calculate index of mask.
35249+ */
35250+ cplim = netmask + mlen;
35251+ for (cp = netmask + skip; cp < cplim; cp++)
35252+ if (*(u_char *)cp != 0xff)
35253+ break;
35254+ b = (cp - netmask) << 3;
35255+ if (cp != cplim) {
35256+ if (*cp != 0) {
35257+ gotOddMasks = 1;
35258+ for (j = 0x80; j; b++, j >>= 1)
35259+ if ((j & *cp) == 0)
35260+ break;
35261+ }
35262+ }
35263+ x->rj_b = -1 - b;
35264+ return (x);
35265+}
35266+
35267+#if 0
35268+struct radij_node *
35269+#endif
35270+int
35271+rj_addroute(v_arg, n_arg, head, treenodes)
35272+ void *v_arg, *n_arg;
35273+ struct radij_node_head *head;
35274+ struct radij_node treenodes[2];
35275+{
35276+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
35277+ register struct radij_node *t, *x=NULL, *tt;
35278+ struct radij_node *saved_tt, *top = head->rnh_treetop;
35279+ short b = 0, b_leaf;
35280+ int mlen, keyduplicated;
35281+ caddr_t cplim;
35282+ struct radij_mask *m, **mp;
35283+
35284+ /*
35285+ * In dealing with non-contiguous masks, there may be
35286+ * many different routes which have the same mask.
35287+ * We will find it useful to have a unique pointer to
35288+ * the mask to speed avoiding duplicate references at
35289+ * nodes and possibly save time in calculating indices.
35290+ */
35291+ if (netmask) {
35292+ x = rj_search(netmask, rj_masktop);
35293+ mlen = *(u_char *)netmask;
35294+ if (Bcmp(netmask, x->rj_key, mlen) != 0) {
35295+ x = rj_addmask(netmask, 0, top->rj_off);
35296+ if (x == 0)
35297+ return /* (0) rgb */ ENOMEM;
35298+ }
35299+ netmask = x->rj_key;
35300+ b = -1 - x->rj_b;
35301+ }
35302+ /*
35303+ * Deal with duplicated keys: attach node to previous instance
35304+ */
35305+ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
35306+ if (keyduplicated) {
35307+ do {
35308+ if (tt->rj_mask == netmask)
35309+ return /* (0) rgb */ ENXIO;
35310+ t = tt;
35311+ if (netmask == 0 ||
35312+ (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
35313+ break;
35314+ } while ((tt = tt->rj_dupedkey));
35315+ /*
35316+ * If the mask is not duplicated, we wouldn't
35317+ * find it among possible duplicate key entries
35318+ * anyway, so the above test doesn't hurt.
35319+ *
35320+ * We sort the masks for a duplicated key the same way as
35321+ * in a masklist -- most specific to least specific.
35322+ * This may require the unfortunate nuisance of relocating
35323+ * the head of the list.
35324+ */
35325+ if (tt && t == saved_tt) {
35326+ struct radij_node *xx = x;
35327+ /* link in at head of list */
35328+ (tt = treenodes)->rj_dupedkey = t;
35329+ tt->rj_flags = t->rj_flags;
35330+ tt->rj_p = x = t->rj_p;
35331+ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
35332+ saved_tt = tt; x = xx;
35333+ } else {
35334+ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
35335+ t->rj_dupedkey = tt;
35336+ }
35337+#ifdef RJ_DEBUG
35338+ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
35339+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
35340+#endif /* RJ_DEBUG */
35341+ t = saved_tt;
35342+ tt->rj_key = (caddr_t) v;
35343+ tt->rj_b = -1;
35344+ tt->rj_flags = t->rj_flags & ~RJF_ROOT;
35345+ }
35346+ /*
35347+ * Put mask in tree.
35348+ */
35349+ if (netmask) {
35350+ tt->rj_mask = netmask;
35351+ tt->rj_b = x->rj_b;
35352+ }
35353+ t = saved_tt->rj_p;
35354+ b_leaf = -1 - t->rj_b;
35355+ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
35356+ /* Promote general routes from below */
35357+ if (x->rj_b < 0) {
35358+ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
35359+ MKGet(m);
35360+ if (m) {
35361+ Bzero(m, sizeof *m);
35362+ m->rm_b = x->rj_b;
35363+ m->rm_mask = x->rj_mask;
35364+ x->rj_mklist = t->rj_mklist = m;
35365+ }
35366+ }
35367+ } else if (x->rj_mklist) {
35368+ /*
35369+ * Skip over masks whose index is > that of new node
35370+ */
35371+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
35372+ if (m->rm_b >= b_leaf)
35373+ break;
35374+ t->rj_mklist = m; *mp = 0;
35375+ }
35376+ /* Add new route to highest possible ancestor's list */
35377+ if ((netmask == 0) || (b > t->rj_b ))
35378+ return /* tt rgb */ 0; /* can't lift at all */
35379+ b_leaf = tt->rj_b;
35380+ do {
35381+ x = t;
35382+ t = t->rj_p;
35383+ } while (b <= t->rj_b && x != top);
35384+ /*
35385+ * Search through routes associated with node to
35386+ * insert new route according to index.
35387+ * For nodes of equal index, place more specific
35388+ * masks first.
35389+ */
35390+ cplim = netmask + mlen;
35391+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
35392+ if (m->rm_b < b_leaf)
35393+ continue;
35394+ if (m->rm_b > b_leaf)
35395+ break;
35396+ if (m->rm_mask == netmask) {
35397+ m->rm_refs++;
35398+ tt->rj_mklist = m;
35399+ return /* tt rgb */ 0;
35400+ }
35401+ if (rj_refines(netmask, m->rm_mask))
35402+ break;
35403+ }
35404+ MKGet(m);
35405+ if (m == 0) {
35406+ printk("klips_debug:Mask for route not entered\n");
35407+ return /* (tt) rgb */ 0;
35408+ }
35409+ Bzero(m, sizeof *m);
35410+ m->rm_b = b_leaf;
35411+ m->rm_mask = netmask;
35412+ m->rm_mklist = *mp;
35413+ *mp = m;
35414+ tt->rj_mklist = m;
35415+ return /* tt rgb */ 0;
35416+}
35417+
35418+int
35419+rj_delete(v_arg, netmask_arg, head, node)
35420+ void *v_arg, *netmask_arg;
35421+ struct radij_node_head *head;
35422+ struct radij_node **node;
35423+{
35424+ register struct radij_node *t, *p, *x, *tt;
35425+ struct radij_mask *m, *saved_m, **mp;
35426+ struct radij_node *dupedkey, *saved_tt, *top;
35427+ caddr_t v, netmask;
35428+ int b, head_off, vlen;
35429+
35430+ v = v_arg;
35431+ netmask = netmask_arg;
35432+ x = head->rnh_treetop;
35433+ tt = rj_search(v, x);
35434+ head_off = x->rj_off;
35435+ vlen = *(u_char *)v;
35436+ saved_tt = tt;
35437+ top = x;
35438+ if (tt == 0 ||
35439+ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
35440+ return /* (0) rgb */ -EFAULT;
35441+ /*
35442+ * Delete our route from mask lists.
35443+ */
35444+ if ((dupedkey = tt->rj_dupedkey)) {
35445+ if (netmask)
35446+ netmask = rj_search(netmask, rj_masktop)->rj_key;
35447+ while (tt->rj_mask != netmask)
35448+ if ((tt = tt->rj_dupedkey) == 0)
35449+ return /* (0) rgb */ -ENXIO;
35450+ }
35451+ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
35452+ goto on1;
35453+ if (m->rm_mask != tt->rj_mask) {
35454+ printk("klips_debug:rj_delete: inconsistent annotation\n");
35455+ goto on1;
35456+ }
35457+ if (--m->rm_refs >= 0)
35458+ goto on1;
35459+ b = -1 - tt->rj_b;
35460+ t = saved_tt->rj_p;
35461+ if (b > t->rj_b)
35462+ goto on1; /* Wasn't lifted at all */
35463+ do {
35464+ x = t;
35465+ t = t->rj_p;
35466+ } while (b <= t->rj_b && x != top);
35467+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
35468+ if (m == saved_m) {
35469+ *mp = m->rm_mklist;
35470+ MKFree(m);
35471+ break;
35472+ }
35473+ if (m == 0)
35474+ printk("klips_debug:rj_delete: couldn't find our annotation\n");
35475+on1:
35476+ /*
35477+ * Eliminate us from tree
35478+ */
35479+ if (tt->rj_flags & RJF_ROOT)
35480+ return /* (0) rgb */ -EFAULT;
35481+#ifdef RJ_DEBUG
35482+ /* Get us out of the creation list */
35483+ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
35484+ if (t) t->rj_ybro = tt->rj_ybro;
35485+#endif /* RJ_DEBUG */
35486+ t = tt->rj_p;
35487+ if (dupedkey) {
35488+ if (tt == saved_tt) {
35489+ x = dupedkey; x->rj_p = t;
35490+ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
35491+ } else {
35492+ for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
35493+ p = p->rj_dupedkey;
35494+ if (p) p->rj_dupedkey = tt->rj_dupedkey;
35495+ else printk("klips_debug:rj_delete: couldn't find us\n");
35496+ }
35497+ t = tt + 1;
35498+ if (t->rj_flags & RJF_ACTIVE) {
35499+#ifndef RJ_DEBUG
35500+ *++x = *t; p = t->rj_p;
35501+#else
35502+ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
35503+#endif /* RJ_DEBUG */
35504+ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
35505+ x->rj_l->rj_p = x; x->rj_r->rj_p = x;
35506+ }
35507+ goto out;
35508+ }
35509+ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
35510+ p = t->rj_p;
35511+ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
35512+ x->rj_p = p;
35513+ /*
35514+ * Demote routes attached to us.
35515+ */
35516+ if (t->rj_mklist) {
35517+ if (x->rj_b >= 0) {
35518+ for (mp = &x->rj_mklist; (m = *mp);)
35519+ mp = &m->rm_mklist;
35520+ *mp = t->rj_mklist;
35521+ } else {
35522+ for (m = t->rj_mklist; m;) {
35523+ struct radij_mask *mm = m->rm_mklist;
35524+ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
35525+ x->rj_mklist = 0;
35526+ MKFree(m);
35527+ } else
35528+ printk("klips_debug:%s %p at %p\n",
35529+ "rj_delete: Orphaned Mask", m, x);
35530+ m = mm;
35531+ }
35532+ }
35533+ }
35534+ /*
35535+ * We may be holding an active internal node in the tree.
35536+ */
35537+ x = tt + 1;
35538+ if (t != x) {
35539+#ifndef RJ_DEBUG
35540+ *t = *x;
35541+#else
35542+ b = t->rj_info; *t = *x; t->rj_info = b;
35543+#endif /* RJ_DEBUG */
35544+ t->rj_l->rj_p = t; t->rj_r->rj_p = t;
35545+ p = x->rj_p;
35546+ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
35547+ }
35548+out:
35549+ tt->rj_flags &= ~RJF_ACTIVE;
35550+ tt[1].rj_flags &= ~RJF_ACTIVE;
35551+ *node = tt;
35552+ return /* (tt) rgb */ 0;
35553+}
35554+
35555+int
35556+rj_walktree(h, f, w)
35557+ struct radij_node_head *h;
35558+ register int (*f)(struct radij_node *,void *);
35559+ void *w;
35560+{
35561+ int error;
35562+ struct radij_node *base, *next;
35563+ register struct radij_node *rn;
35564+
35565+ if(!h || !f /* || !w */) {
35566+ return -1;
35567+ }
35568+
35569+ rn = h->rnh_treetop;
35570+ /*
35571+ * This gets complicated because we may delete the node
35572+ * while applying the function f to it, so we need to calculate
35573+ * the successor node in advance.
35574+ */
35575+ /* First time through node, go left */
35576+ while (rn->rj_b >= 0)
35577+ rn = rn->rj_l;
35578+ for (;;) {
35579+#ifdef CONFIG_IPSEC_DEBUG
35580+ if(debug_radij) {
35581+ printk("klips_debug:RN_WALKTREE: for: rn=%p rj_b=%d rj_flags=%x", rn, rn->rj_b, rn->rj_flags);
35582+ rn->rj_b >= 0 ?
35583+ printk(" node off=%x\n", rn->rj_off) :
35584+ printk(" leaf key = %08x->%08x\n",
35585+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
35586+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
35587+ ;
35588+ }
35589+#endif /* CONFIG_IPSEC_DEBUG */
35590+ base = rn;
35591+ /* If at right child go back up, otherwise, go right */
35592+ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
35593+ rn = rn->rj_p;
35594+ /* Find the next *leaf* since next node might vanish, too */
35595+ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
35596+ rn = rn->rj_l;
35597+ next = rn;
35598+#ifdef CONFIG_IPSEC_DEBUG
35599+ if(debug_radij) {
35600+ printk("klips_debug:RN_WALKTREE: processing leaves, rn=%p rj_b=%d rj_flags=%x", rn, rn->rj_b, rn->rj_flags);
35601+ rn->rj_b >= 0 ?
35602+ printk(" node off=%x\n", rn->rj_off) :
35603+ printk(" leaf key = %08x->%08x\n",
35604+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
35605+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
35606+ ;
35607+ }
35608+#endif /* CONFIG_IPSEC_DEBUG */
35609+ /* Process leaves */
35610+ while ((rn = base)) {
35611+ base = rn->rj_dupedkey;
35612+#ifdef CONFIG_IPSEC_DEBUG
35613+ if(debug_radij) {
35614+ printk("klips_debug:RN_WALKTREE: while: base=%p rn=%p rj_b=%d rj_flags=%x",
35615+ base, rn, rn->rj_b, rn->rj_flags);
35616+ rn->rj_b >= 0 ?
35617+ printk(" node off=%x\n", rn->rj_off) :
35618+ printk(" leaf key = %08x->%08x\n",
35619+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
35620+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
35621+ ;
35622+ }
35623+#endif /* CONFIG_IPSEC_DEBUG */
35624+ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
35625+ return (-error);
35626+ }
35627+ rn = next;
35628+ if (rn->rj_flags & RJF_ROOT)
35629+ return (0);
35630+ }
35631+ /* NOTREACHED */
35632+}
35633+
35634+int
35635+rj_inithead(head, off)
35636+ void **head;
35637+ int off;
35638+{
35639+ register struct radij_node_head *rnh;
35640+ register struct radij_node *t, *tt, *ttt;
35641+ if (*head)
35642+ return (1);
35643+ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
35644+ if (rnh == 0)
35645+ return (0);
35646+ Bzero(rnh, sizeof (*rnh));
35647+ *head = rnh;
35648+ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
35649+ ttt = rnh->rnh_nodes + 2;
35650+ t->rj_r = ttt;
35651+ t->rj_p = t;
35652+ tt = t->rj_l;
35653+ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
35654+ tt->rj_b = -1 - off;
35655+ *ttt = *tt;
35656+ ttt->rj_key = rj_ones;
35657+ rnh->rnh_addaddr = rj_addroute;
35658+ rnh->rnh_deladdr = rj_delete;
35659+ rnh->rnh_matchaddr = rj_match;
35660+ rnh->rnh_walktree = rj_walktree;
35661+ rnh->rnh_treetop = t;
35662+ return (1);
35663+}
35664+
35665+void
35666+rj_init()
35667+{
35668+ char *cp, *cplim;
35669+
35670+ if (maj_keylen == 0) {
35671+ printk("klips_debug:rj_init: radij functions require maj_keylen be set\n");
35672+ return;
35673+ }
35674+ R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
35675+ if (rj_zeroes == NULL)
35676+ panic("rj_init");
35677+ Bzero(rj_zeroes, 3 * maj_keylen);
35678+ rj_ones = cp = rj_zeroes + maj_keylen;
35679+ maskedKey = cplim = rj_ones + maj_keylen;
35680+ while (cp < cplim)
35681+ *cp++ = -1;
35682+ if (rj_inithead((void **)&mask_rjhead, 0) == 0)
35683+ panic("rj_init 2");
35684+}
35685+
35686+void
35687+rj_preorder(struct radij_node *rn, int l)
35688+{
35689+ int i;
35690+
35691+ if (rn == NULL){
35692+ printk("klips_debug:rj_preorder: NULL pointer\n");
35693+ return;
35694+ }
35695+
35696+ if (rn->rj_b >= 0){
35697+ rj_preorder(rn->rj_l, l+1);
35698+ rj_preorder(rn->rj_r, l+1);
35699+ printk("klips_debug:");
35700+ for (i=0; i<l; i++)
35701+ printk("*");
35702+ printk(" off = %d\n", rn->rj_off);
35703+ } else {
35704+ printk("klips_debug:");
35705+ for (i=0; i<l; i++)
35706+ printk("@");
35707+ printk(" flags = %x", (u_int)rn->rj_flags);
35708+ if (rn->rj_flags & RJF_ACTIVE) {
35709+ printk(" @key = %p", rn->rj_key);
35710+
35711+ printk(" key = %08x->%08x",
35712+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
35713+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
35714+
35715+ printk(" @mask = %p", rn->rj_mask);
35716+ if (rn->rj_mask)
35717+ printk(" mask = %08x->%08x",
35718+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
35719+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
35720+
35721+ if (rn->rj_dupedkey)
35722+ printk(" dupedkey = %08x", (u_int)rn->rj_dupedkey);
35723+ }
35724+ printk("\n");
35725+ }
35726+}
35727+
35728+#ifdef RJ_DEBUG
35729+DEBUG_NO_STATIC void traverse(struct radij_node *p)
35730+{
35731+ rj_preorder(p, 0);
35732+}
35733+#endif /* RJ_DEBUG */
35734+
35735+void
35736+rj_dumptrees(void)
35737+{
35738+ rj_preorder(rnh->rnh_treetop, 0);
35739+}
35740+
35741+void
35742+rj_free_mkfreelist(void)
35743+{
35744+ struct radij_mask *mknp, *mknp2;
35745+
35746+ mknp = rj_mkfreelist;
35747+ while(mknp)
35748+ {
35749+ mknp2 = mknp;
35750+ mknp = mknp->rm_mklist;
35751+ kfree(mknp2);
35752+ }
35753+}
35754+
35755+int
35756+radijcleartree(void)
35757+{
35758+ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
35759+}
35760+
35761+int
35762+radijcleanup(void)
35763+{
35764+ int error = 0;
35765+
35766+ error = radijcleartree();
35767+
35768+ rj_free_mkfreelist();
35769+
35770+/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
35771+ if(mask_rjhead) {
35772+ kfree(mask_rjhead);
35773+ }
35774+
35775+ if(rj_zeroes) {
35776+ kfree(rj_zeroes);
35777+ }
35778+
35779+ if(rnh) {
35780+ kfree(rnh);
35781+ }
35782+
35783+ return error;
35784+}
35785+
35786+/*
35787+ * $Log$
35788+ * Revision 1.31 2000/11/06 04:35:21 rgb
35789+ * Clear table *before* releasing other items in radijcleanup.
35790+ *
35791+ * Revision 1.30 2000/09/20 04:07:40 rgb
35792+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
35793+ * oopsen.
35794+ *
35795+ * Revision 1.29 2000/09/12 03:25:02 rgb
35796+ * Moved radij_c_version printing to ipsec_version_get_info().
35797+ *
35798+ * Revision 1.28 2000/09/08 19:12:56 rgb
35799+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
35800+ *
35801+ * Revision 1.27 2000/07/28 14:58:32 rgb
35802+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
35803+ *
35804+ * Revision 1.26 2000/05/10 23:11:37 rgb
35805+ * Comment out most of the startup version information.
35806+ *
35807+ * Revision 1.25 2000/01/21 06:21:47 rgb
35808+ * Change return codes to negative on error.
35809+ *
35810+ * Revision 1.24 1999/11/18 04:09:20 rgb
35811+ * Replaced all kernel version macros to shorter, readable form.
35812+ *
35813+ * Revision 1.23 1999/11/17 15:53:41 rgb
35814+ * Changed all occurrences of #include "../../../lib/freeswan.h"
35815+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
35816+ * klips/net/ipsec/Makefile.
35817+ *
35818+ * Revision 1.22 1999/10/15 22:17:28 rgb
35819+ * Modify radijcleanup() to call radijcleartree().
35820+ *
35821+ * Revision 1.21 1999/10/08 18:37:34 rgb
35822+ * Fix end-of-line spacing to sate whining PHMs.
35823+ *
35824+ * Revision 1.20 1999/10/01 15:44:54 rgb
35825+ * Move spinlock header include to 2.1> scope.
35826+ *
35827+ * Revision 1.19 1999/10/01 08:35:52 rgb
35828+ * Add spinlock include to shut up compiler for 2.0.38.
35829+ *
35830+ * Revision 1.18 1999/09/23 18:02:52 rgb
35831+ * De-alarm the search failure message so it doesn't sound so grave.
35832+ *
35833+ * Revision 1.17 1999/05/25 21:26:01 rgb
35834+ * Fix rj_walktree() sanity checking bug.
35835+ *
35836+ * Revision 1.16 1999/05/09 03:25:38 rgb
35837+ * Fix bug introduced by 2.2 quick-and-dirty patch.
35838+ *
35839+ * Revision 1.15 1999/05/05 22:02:33 rgb
35840+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
35841+ *
35842+ * Revision 1.14 1999/04/29 15:24:15 rgb
35843+ * Add sanity checking for null pointer arguments.
35844+ * Standardise an error return method.
35845+ *
35846+ * Revision 1.13 1999/04/11 00:29:02 henry
35847+ * GPL boilerplate
35848+ *
35849+ * Revision 1.12 1999/04/06 04:54:28 rgb
35850+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
35851+ * patch shell fixes.
35852+ *
35853+ * Revision 1.11 1999/02/17 16:52:53 rgb
35854+ * Convert DEBUG_IPSEC to KLIPS_PRINT
35855+ * Clean out unused cruft.
35856+ *
35857+ * Revision 1.10 1999/01/22 06:30:05 rgb
35858+ * Cruft clean-out.
35859+ * 64-bit clean-up.
35860+ *
35861+ * Revision 1.9 1998/12/01 13:22:04 rgb
35862+ * Added support for debug printing of version info.
35863+ *
35864+ * Revision 1.8 1998/11/30 13:22:55 rgb
35865+ * Rationalised all the klips kernel file headers. They are much shorter
35866+ * now and won't conflict under RH5.2.
35867+ *
35868+ * Revision 1.7 1998/10/25 02:43:26 rgb
35869+ * Change return type on rj_addroute and rj_delete and add and argument
35870+ * to the latter to be able to transmit more infomation about errors.
35871+ *
35872+ * Revision 1.6 1998/10/19 14:30:06 rgb
35873+ * Added inclusion of freeswan.h.
35874+ *
35875+ * Revision 1.5 1998/10/09 04:33:27 rgb
35876+ * Added 'klips_debug' prefix to all klips printk debug statements.
35877+ * Fixed output formatting slightly.
35878+ *
35879+ * Revision 1.4 1998/07/28 00:06:59 rgb
35880+ * Add debug detail to tree traversing.
35881+ *
35882+ * Revision 1.3 1998/07/14 18:07:58 rgb
35883+ * Add a routine to clear the eroute tree.
35884+ *
35885+ * Revision 1.2 1998/06/25 20:03:22 rgb
35886+ * Cleanup #endif comments. Debug output for rj_init.
35887+ *
35888+ * Revision 1.1 1998/06/18 21:30:22 henry
35889+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
35890+ * build scripts happier about symlinks
35891+ *
35892+ * Revision 1.8 1998/05/25 20:34:15 rgb
35893+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
35894+ *
35895+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
35896+ * add ipsec_rj_walker_delete.
35897+ *
35898+ * Recover memory for eroute table on unload of module.
35899+ *
35900+ * Revision 1.7 1998/05/21 12:58:58 rgb
35901+ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
35902+ *
35903+ * Revision 1.6 1998/04/23 20:57:29 rgb
35904+ * Cleaned up compiler warnings for unused debugging functions.
35905+ *
35906+ * Revision 1.5 1998/04/22 16:51:38 rgb
35907+ * Tidy up radij debug code from recent rash of modifications to debug code.
35908+ *
35909+ * Revision 1.4 1998/04/21 21:28:56 rgb
35910+ * Rearrange debug switches to change on the fly debug output from user
35911+ * space. Only kernel changes checked in at this time. radij.c was also
35912+ * changed to temporarily remove buggy debugging code in rj_delete causing
35913+ * an OOPS and hence, netlink device open errors.
35914+ *
35915+ * Revision 1.3 1998/04/14 17:30:37 rgb
35916+ * Fix up compiling errors for radij tree memory reclamation.
35917+ *
35918+ * Revision 1.2 1998/04/12 22:03:25 rgb
35919+ * Updated ESP-3DES-HMAC-MD5-96,
35920+ * ESP-DES-HMAC-MD5-96,
35921+ * AH-HMAC-MD5-96,
35922+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
35923+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
35924+ *
35925+ * Fixed eroute references in /proc/net/ipsec*.
35926+ *
35927+ * Started to patch module unloading memory leaks in ipsec_netlink and
35928+ * radij tree unloading.
35929+ *
35930+ * Revision 1.1 1998/04/09 03:06:15 henry
35931+ * sources moved up from linux/net/ipsec
35932+ *
35933+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
35934+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
35935+ *
35936+ * Revision 0.4 1997/01/15 01:28:15 ji
35937+ * No changes.
35938+ *
35939+ * Revision 0.3 1996/11/20 14:39:04 ji
35940+ * Minor cleanups.
35941+ * Rationalized debugging code.
35942+ *
35943+ * Revision 0.2 1996/11/02 00:18:33 ji
35944+ * First limited release.
35945+ *
35946+ *
35947+ */
35948diff -druN linux-noipsec/net/ipsec/radij.h linux/net/ipsec/radij.h
35949--- linux-noipsec/net/ipsec/radij.h Thu Jan 1 01:00:00 1970
35950+++ linux/net/ipsec/radij.h Thu Nov 18 05:09:20 1999
35951@@ -0,0 +1,291 @@
35952+/*
35953+ * RCSID $Id$
35954+ */
35955+
35956+/*
35957+ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
35958+ *
35959+ * Variable and procedure names have been modified so that they don't
35960+ * conflict with the original BSD code, as a small number of modifications
35961+ * have been introduced and we may want to reuse this code in BSD.
35962+ *
35963+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
35964+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
35965+ * spanish j as in Juan. It is not as far back in the throat like
35966+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
35967+ * It has nothing to do with the Dutch ij sound.
35968+ *
35969+ * Here is the appropriate copyright notice:
35970+ */
35971+
35972+/*
35973+ * Copyright (c) 1988, 1989, 1993
35974+ * The Regents of the University of California. All rights reserved.
35975+ *
35976+ * Redistribution and use in source and binary forms, with or without
35977+ * modification, are permitted provided that the following conditions
35978+ * are met:
35979+ * 1. Redistributions of source code must retain the above copyright
35980+ * notice, this list of conditions and the following disclaimer.
35981+ * 2. Redistributions in binary form must reproduce the above copyright
35982+ * notice, this list of conditions and the following disclaimer in the
35983+ * documentation and/or other materials provided with the distribution.
35984+ * 3. All advertising materials mentioning features or use of this software
35985+ * must display the following acknowledgement:
35986+ * This product includes software developed by the University of
35987+ * California, Berkeley and its contributors.
35988+ * 4. Neither the name of the University nor the names of its contributors
35989+ * may be used to endorse or promote products derived from this software
35990+ * without specific prior written permission.
35991+ *
35992+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35993+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35994+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35995+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
35996+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35997+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35998+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35999+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36000+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36001+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36002+ * SUCH DAMAGE.
36003+ *
36004+ * @(#)radix.h 8.1 (Berkeley) 6/10/93
36005+ */
36006+
36007+#ifndef _RADIJ_H_
36008+#define _RADIJ_H_
36009+
36010+/*
36011+#define RJ_DEBUG
36012+*/
36013+
36014+#ifdef __KERNEL__
36015+
36016+#ifndef __P
36017+#ifdef __STDC__
36018+#define __P(x) x
36019+#else
36020+#define __P(x) ()
36021+#endif
36022+#endif
36023+
36024+#ifndef NET_21
36025+#ifndef min
36026+static __inline__ int min(unsigned int a, unsigned int b)
36027+{
36028+ if (a > b)
36029+ a = b;
36030+ return a;
36031+}
36032+#endif /* !min */
36033+
36034+#ifndef max
36035+static __inline__ int max(unsigned int a, unsigned int b)
36036+{
36037+ if (a < b)
36038+ a = b;
36039+ return a;
36040+}
36041+#endif /* !max */
36042+#endif /* NET_21 */
36043+
36044+/*
36045+ * Radix search tree node layout.
36046+ */
36047+
36048+struct radij_node
36049+{
36050+ struct radij_mask *rj_mklist; /* list of masks contained in subtree */
36051+ struct radij_node *rj_p; /* parent */
36052+ short rj_b; /* bit offset; -1-index(netmask) */
36053+ char rj_bmask; /* node: mask for bit test*/
36054+ u_char rj_flags; /* enumerated next */
36055+#define RJF_NORMAL 1 /* leaf contains normal route */
36056+#define RJF_ROOT 2 /* leaf is root leaf for tree */
36057+#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
36058+ union {
36059+ struct { /* leaf only data: */
36060+ caddr_t rj_Key; /* object of search */
36061+ caddr_t rj_Mask; /* netmask, if present */
36062+ struct radij_node *rj_Dupedkey;
36063+ } rj_leaf;
36064+ struct { /* node only data: */
36065+ int rj_Off; /* where to start compare */
36066+ struct radij_node *rj_L;/* progeny */
36067+ struct radij_node *rj_R;/* progeny */
36068+ }rj_node;
36069+ } rj_u;
36070+#ifdef RJ_DEBUG
36071+ int rj_info;
36072+ struct radij_node *rj_twin;
36073+ struct radij_node *rj_ybro;
36074+#endif
36075+};
36076+
36077+#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
36078+#define rj_key rj_u.rj_leaf.rj_Key
36079+#define rj_mask rj_u.rj_leaf.rj_Mask
36080+#define rj_off rj_u.rj_node.rj_Off
36081+#define rj_l rj_u.rj_node.rj_L
36082+#define rj_r rj_u.rj_node.rj_R
36083+
36084+/*
36085+ * Annotations to tree concerning potential routes applying to subtrees.
36086+ */
36087+
36088+extern struct radij_mask {
36089+ short rm_b; /* bit offset; -1-index(netmask) */
36090+ char rm_unused; /* cf. rj_bmask */
36091+ u_char rm_flags; /* cf. rj_flags */
36092+ struct radij_mask *rm_mklist; /* more masks to try */
36093+ caddr_t rm_mask; /* the mask */
36094+ int rm_refs; /* # of references to this struct */
36095+} *rj_mkfreelist;
36096+
36097+#define MKGet(m) {\
36098+ if (rj_mkfreelist) {\
36099+ m = rj_mkfreelist; \
36100+ rj_mkfreelist = (m)->rm_mklist; \
36101+ } else \
36102+ R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
36103+
36104+#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
36105+
36106+struct radij_node_head {
36107+ struct radij_node *rnh_treetop;
36108+ int rnh_addrsize; /* permit, but not require fixed keys */
36109+ int rnh_pktsize; /* permit, but not require fixed keys */
36110+#if 0
36111+ struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
36112+ __P((void *v, void *mask,
36113+ struct radij_node_head *head, struct radij_node nodes[]));
36114+#endif
36115+ int (*rnh_addaddr) /* add based on sockaddr */
36116+ __P((void *v, void *mask,
36117+ struct radij_node_head *head, struct radij_node nodes[]));
36118+ struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
36119+ __P((void *v, void *mask,
36120+ struct radij_node_head *head, struct radij_node nodes[]));
36121+#if 0
36122+ struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
36123+ __P((void *v, void *mask, struct radij_node_head *head));
36124+#endif
36125+ int (*rnh_deladdr) /* remove based on sockaddr */
36126+ __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
36127+ struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
36128+ __P((void *v, void *mask, struct radij_node_head *head));
36129+ struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
36130+ __P((void *v, struct radij_node_head *head));
36131+ struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
36132+ __P((void *v, struct radij_node_head *head));
36133+ int (*rnh_walktree) /* traverse tree */
36134+ __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
36135+ struct radij_node rnh_nodes[3]; /* empty tree for common case */
36136+};
36137+
36138+
36139+#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
36140+#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
36141+#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
36142+#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
36143+#define Free(p) kfree((caddr_t)p);
36144+
36145+void rj_init __P((void));
36146+int rj_inithead __P((void **, int));
36147+int rj_refines __P((void *, void *));
36148+int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
36149+struct radij_node
36150+ *rj_addmask __P((void *, int, int)) /* , rgb */ ;
36151+int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
36152+ struct radij_node [2])) /* , rgb */ ;
36153+int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
36154+struct radij_node /* rgb */
36155+ *rj_insert __P((void *, struct radij_node_head *, int *,
36156+ struct radij_node [2])),
36157+ *rj_match __P((void *, struct radij_node_head *)),
36158+ *rj_newpair __P((void *, int, struct radij_node[2])),
36159+ *rj_search __P((void *, struct radij_node *)),
36160+ *rj_search_m __P((void *, struct radij_node *, void *));
36161+
36162+void rj_deltree(struct radij_node_head *);
36163+void rj_delnodes(struct radij_node *);
36164+void rj_free_mkfreelist(void);
36165+int radijcleartree(void);
36166+int radijcleanup(void);
36167+
36168+extern struct radij_node_head *mask_rjhead;
36169+extern int maj_keylen;
36170+#endif /* __KERNEL__ */
36171+
36172+#endif /* _RADIJ_H_ */
36173+
36174+
36175+/*
36176+ * $Log$
36177+ * Revision 1.10 1999/11/18 04:09:20 rgb
36178+ * Replaced all kernel version macros to shorter, readable form.
36179+ *
36180+ * Revision 1.9 1999/05/05 22:02:33 rgb
36181+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
36182+ *
36183+ * Revision 1.8 1999/04/29 15:24:58 rgb
36184+ * Add check for existence of macros min/max.
36185+ *
36186+ * Revision 1.7 1999/04/11 00:29:02 henry
36187+ * GPL boilerplate
36188+ *
36189+ * Revision 1.6 1999/04/06 04:54:29 rgb
36190+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
36191+ * patch shell fixes.
36192+ *
36193+ * Revision 1.5 1999/01/22 06:30:32 rgb
36194+ * 64-bit clean-up.
36195+ *
36196+ * Revision 1.4 1998/11/30 13:22:55 rgb
36197+ * Rationalised all the klips kernel file headers. They are much shorter
36198+ * now and won't conflict under RH5.2.
36199+ *
36200+ * Revision 1.3 1998/10/25 02:43:27 rgb
36201+ * Change return type on rj_addroute and rj_delete and add and argument
36202+ * to the latter to be able to transmit more infomation about errors.
36203+ *
36204+ * Revision 1.2 1998/07/14 18:09:51 rgb
36205+ * Add a routine to clear eroute table.
36206+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
36207+ *
36208+ * Revision 1.1 1998/06/18 21:30:22 henry
36209+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
36210+ * build scripts happier about symlinks
36211+ *
36212+ * Revision 1.4 1998/05/25 20:34:16 rgb
36213+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
36214+ *
36215+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
36216+ * add ipsec_rj_walker_delete.
36217+ *
36218+ * Recover memory for eroute table on unload of module.
36219+ *
36220+ * Revision 1.3 1998/04/22 16:51:37 rgb
36221+ * Tidy up radij debug code from recent rash of modifications to debug code.
36222+ *
36223+ * Revision 1.2 1998/04/14 17:30:38 rgb
36224+ * Fix up compiling errors for radij tree memory reclamation.
36225+ *
36226+ * Revision 1.1 1998/04/09 03:06:16 henry
36227+ * sources moved up from linux/net/ipsec
36228+ *
36229+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
36230+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
36231+ *
36232+ * Revision 0.4 1997/01/15 01:28:15 ji
36233+ * No changes.
36234+ *
36235+ * Revision 0.3 1996/11/20 14:44:45 ji
36236+ * Release update only.
36237+ *
36238+ * Revision 0.2 1996/11/02 00:18:33 ji
36239+ * First limited release.
36240+ *
36241+ *
36242+ */
36243diff -druN linux-noipsec/net/ipsec/sysctl_net_ipsec.c linux/net/ipsec/sysctl_net_ipsec.c
36244--- linux-noipsec/net/ipsec/sysctl_net_ipsec.c Thu Jan 1 01:00:00 1970
36245+++ linux/net/ipsec/sysctl_net_ipsec.c Sat Sep 16 03:50:15 2000
36246@@ -0,0 +1,174 @@
36247+/*
36248+ * sysctl interface to net IPSEC subsystem.
36249+ * Copyright (C) 1998, 1999, 2000 Richard Guy Briggs.
36250+ *
36251+ * This program is free software; you can redistribute it and/or modify it
36252+ * under the terms of the GNU General Public License as published by the
36253+ * Free Software Foundation; either version 2 of the License, or (at your
36254+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
36255+ *
36256+ * This program is distributed in the hope that it will be useful, but
36257+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
36258+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36259+ * for more details.
36260+ *
36261+ * RCSID $Id$
36262+ */
36263+
36264+/* -*- linux-c -*-
36265+ *
36266+ * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
36267+ */
36268+
36269+#include <linux/mm.h>
36270+#include <linux/sysctl.h>
36271+
36272+#ifdef CONFIG_SYSCTL
36273+
36274+#define NET_IPSEC 2112 /* Random number */
36275+#ifdef CONFIG_IPSEC_DEBUG
36276+extern int debug_ah;
36277+extern int debug_esp;
36278+extern int debug_tunnel;
36279+extern int debug_eroute;
36280+extern int debug_spi;
36281+extern int debug_radij;
36282+extern int debug_netlink;
36283+extern int debug_xform;
36284+extern int debug_rcv;
36285+extern int debug_pfkey;
36286+extern int sysctl_ipsec_debug_verbose;
36287+#ifdef CONFIG_IPSEC_IPCOMP
36288+extern int sysctl_ipsec_debug_ipcomp;
36289+#endif /* CONFIG_IPSEC_IPCOMP */
36290+#endif /* CONFIG_IPSEC_DEBUG */
36291+
36292+extern int sysctl_ipsec_icmp;
36293+extern int sysctl_ipsec_no_eroute_pass;
36294+extern int sysctl_ipsec_inbound_policy_check;
36295+extern int sysctl_ipsec_opportunistic;
36296+extern int sysctl_ipsec_tos;
36297+
36298+enum {
36299+#ifdef CONFIG_IPSEC_DEBUG
36300+ NET_IPSEC_DEBUG_AH=1,
36301+ NET_IPSEC_DEBUG_ESP=2,
36302+ NET_IPSEC_DEBUG_TUNNEL=3,
36303+ NET_IPSEC_DEBUG_EROUTE=4,
36304+ NET_IPSEC_DEBUG_SPI=5,
36305+ NET_IPSEC_DEBUG_RADIJ=6,
36306+ NET_IPSEC_DEBUG_NETLINK=7,
36307+ NET_IPSEC_DEBUG_XFORM=8,
36308+ NET_IPSEC_DEBUG_RCV=9,
36309+ NET_IPSEC_DEBUG_PFKEY=10,
36310+ NET_IPSEC_DEBUG_VERBOSE=11,
36311+ NET_IPSEC_DEBUG_IPCOMP=12,
36312+#endif /* CONFIG_IPSEC_DEBUG */
36313+ NET_IPSEC_ICMP=13,
36314+ NET_IPSEC_NO_EROUTE_PASS=14,
36315+ NET_IPSEC_INBOUND_POLICY_CHECK=15,
36316+ NET_IPSEC_OPPORTUNISTIC=16,
36317+ NET_IPSEC_TOS=17
36318+};
36319+
36320+static ctl_table ipsec_table[] = {
36321+#ifdef CONFIG_IPSEC_DEBUG
36322+ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
36323+ sizeof(int), 0644, NULL, &proc_dointvec},
36324+ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
36325+ sizeof(int), 0644, NULL, &proc_dointvec},
36326+ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
36327+ sizeof(int), 0644, NULL, &proc_dointvec},
36328+ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
36329+ sizeof(int), 0644, NULL, &proc_dointvec},
36330+ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
36331+ sizeof(int), 0644, NULL, &proc_dointvec},
36332+ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
36333+ sizeof(int), 0644, NULL, &proc_dointvec},
36334+ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
36335+ sizeof(int), 0644, NULL, &proc_dointvec},
36336+ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
36337+ sizeof(int), 0644, NULL, &proc_dointvec},
36338+ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
36339+ sizeof(int), 0644, NULL, &proc_dointvec},
36340+ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
36341+ sizeof(int), 0644, NULL, &proc_dointvec},
36342+ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
36343+ sizeof(int), 0644, NULL, &proc_dointvec},
36344+#ifdef CONFIG_IPSEC_IPCOMP
36345+ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
36346+ sizeof(int), 0644, NULL, &proc_dointvec},
36347+#endif /* CONFIG_IPSEC_IPCOMP */
36348+#endif /* CONFIG_IPSEC_DEBUG */
36349+ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
36350+ sizeof(int), 0644, NULL, &proc_dointvec},
36351+ { NET_IPSEC_NO_EROUTE_PASS, "no_eroute_pass", &sysctl_ipsec_no_eroute_pass,
36352+ sizeof(int), 0644, NULL, &proc_dointvec},
36353+ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
36354+ sizeof(int), 0644, NULL, &proc_dointvec},
36355+ { NET_IPSEC_OPPORTUNISTIC, "opportunistic", &sysctl_ipsec_opportunistic,
36356+ sizeof(int), 0644, NULL, &proc_dointvec},
36357+ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
36358+ sizeof(int), 0644, NULL, &proc_dointvec},
36359+ {0}
36360+};
36361+
36362+static ctl_table ipsec_net_table[] = {
36363+ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
36364+ { 0 }
36365+};
36366+
36367+static ctl_table ipsec_root_table[] = {
36368+ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
36369+ { 0 }
36370+};
36371+
36372+static struct ctl_table_header *ipsec_table_header;
36373+
36374+int ipsec_sysctl_register(void)
36375+{
36376+ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
36377+ if (!ipsec_table_header) {
36378+ return -ENOMEM;
36379+ }
36380+ return 0;
36381+}
36382+
36383+void ipsec_sysctl_unregister(void)
36384+{
36385+ unregister_sysctl_table(ipsec_table_header);
36386+}
36387+
36388+#endif /* CONFIG_SYSCTL */
36389+
36390+/*
36391+ * $Log$
36392+ * Revision 1.10 2000/09/16 01:50:15 rgb
36393+ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
36394+ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
36395+ *
36396+ * Revision 1.9 2000/09/15 23:17:51 rgb
36397+ * Moved stuff around to compile with debug off.
36398+ *
36399+ * Revision 1.8 2000/09/15 11:37:02 rgb
36400+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
36401+ * IPCOMP zlib deflate code.
36402+ *
36403+ * Revision 1.7 2000/09/15 07:37:15 rgb
36404+ * Munged silly log comment that was causing a warning.
36405+ *
36406+ * Revision 1.6 2000/09/15 04:58:23 rgb
36407+ * Added tos runtime switch.
36408+ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
36409+ *
36410+ * Revision 1.5 2000/09/12 03:25:28 rgb
36411+ * Filled in and implemented sysctl.
36412+ *
36413+ * Revision 1.4 1999/04/11 00:29:03 henry
36414+ * GPL boilerplate
36415+ *
36416+ * Revision 1.3 1999/04/06 04:54:29 rgb
36417+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
36418+ * patch shell fixes.
36419+ *
36420+ */
36421diff -druN linux-noipsec/net/ipsec/version.c linux/net/ipsec/version.c
36422--- linux-noipsec/net/ipsec/version.c Thu Jan 1 01:00:00 1970
36423+++ linux/net/ipsec/version.c Thu Nov 30 06:02:51 2000
36424@@ -0,0 +1,2 @@
36425+/* silly pointless RCSID $Id$ */
36426+static const char freeswan_version[] = "1.8";
36427diff -druN linux-noipsec/net/ipsec/zlib/Makefile linux/net/ipsec/zlib/Makefile
36428--- linux-noipsec/net/ipsec/zlib/Makefile Thu Jan 1 01:00:00 1970
36429+++ linux/net/ipsec/zlib/Makefile Fri Sep 29 20:51:33 2000
36430@@ -0,0 +1,74 @@
36431+# Makefile for IPCOMP zlib deflate code
36432+# Copyright (C) 1998, 1999, 2000 Richard Guy Briggs.
36433+# Copyright (C) 2000 Svenning Soerensen
36434+#
36435+# This program is free software; you can redistribute it and/or modify it
36436+# under the terms of the GNU General Public License as published by the
36437+# Free Software Foundation; either version 2 of the License, or (at your
36438+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
36439+#
36440+# This program is distributed in the hope that it will be useful, but
36441+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
36442+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36443+# for more details.
36444+#
36445+# RCSID $Id$
36446+#
36447+
36448+ifndef TOPDIR
36449+TOPDIR := /usr/src/linux
36450+endif
36451+
36452+
36453+L_TARGET := zlib.a
36454+L_OBJS := adler32.o deflate.o infblock.o infcodes.o inffast.o inflate.o inftrees.o infutil.o trees.o zutil.o
36455+
36456+
36457+ifeq ($(CONFIG_IPSEC_DEBUG),y)
36458+override CFLAGS += -g
36459+endif
36460+
36461+override CFLAGS += -Wall
36462+#override CFLAGS += -Wconversion
36463+#override CFLAGS += -Wmissing-prototypes
36464+override CFLAGS += -Wpointer-arith
36465+#override CFLAGS += -Wcast-qual
36466+#override CFLAGS += -Wmissing-declarations
36467+override CFLAGS += -Wstrict-prototypes
36468+#override CFLAGS += -pedantic
36469+#override CFLAGS += -O3
36470+#override CFLAGS += -W
36471+#override CFLAGS += -Wwrite-strings
36472+override CFLAGS += -Wbad-function-cast
36473+override CFLAGS += -DIPCOMP_PREFIX
36474+
36475+.S.o:
36476+ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o
36477+
36478+ifdef CONFIG_M586
36479+ L_OBJS += match586.o
36480+ override CFLAGS += -DASMV
36481+endif
36482+ifdef CONFIG_M586TSC
36483+ L_OBJS += match586.o
36484+ override CFLAGS += -DASMV
36485+endif
36486+ifdef CONFIG_M686
36487+ L_OBJS += match686.o
36488+ override CFLAGS += -DASMV
36489+endif
36490+
36491+
36492+include $(TOPDIR)/Rules.make
36493+
36494+$(L_OBJS): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
36495+
36496+clean:
36497+ -rm -f *.o *.a
36498+
36499+#
36500+# $Log$
36501+# Revision 1.1.1.1 2000/09/29 18:51:33 rgb
36502+# zlib_beginnings
36503+#
36504+#
36505diff -druN linux-noipsec/net/ipsec/zlib/adler32.c linux/net/ipsec/zlib/adler32.c
36506--- linux-noipsec/net/ipsec/zlib/adler32.c Thu Jan 1 01:00:00 1970
36507+++ linux/net/ipsec/zlib/adler32.c Fri Sep 29 20:51:33 2000
36508@@ -0,0 +1,48 @@
36509+/* adler32.c -- compute the Adler-32 checksum of a data stream
36510+ * Copyright (C) 1995-1998 Mark Adler
36511+ * For conditions of distribution and use, see copyright notice in zlib.h
36512+ */
36513+
36514+/* @(#) $Id$ */
36515+
36516+#include "zlib.h"
36517+
36518+#define BASE 65521L /* largest prime smaller than 65536 */
36519+#define NMAX 5552
36520+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
36521+
36522+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
36523+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
36524+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
36525+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
36526+#define DO16(buf) DO8(buf,0); DO8(buf,8);
36527+
36528+/* ========================================================================= */
36529+uLong ZEXPORT adler32(adler, buf, len)
36530+ uLong adler;
36531+ const Bytef *buf;
36532+ uInt len;
36533+{
36534+ unsigned long s1 = adler & 0xffff;
36535+ unsigned long s2 = (adler >> 16) & 0xffff;
36536+ int k;
36537+
36538+ if (buf == Z_NULL) return 1L;
36539+
36540+ while (len > 0) {
36541+ k = len < NMAX ? len : NMAX;
36542+ len -= k;
36543+ while (k >= 16) {
36544+ DO16(buf);
36545+ buf += 16;
36546+ k -= 16;
36547+ }
36548+ if (k != 0) do {
36549+ s1 += *buf++;
36550+ s2 += s1;
36551+ } while (--k);
36552+ s1 %= BASE;
36553+ s2 %= BASE;
36554+ }
36555+ return (s2 << 16) | s1;
36556+}
36557diff -druN linux-noipsec/net/ipsec/zlib/deflate.c linux/net/ipsec/zlib/deflate.c
36558--- linux-noipsec/net/ipsec/zlib/deflate.c Thu Jan 1 01:00:00 1970
36559+++ linux/net/ipsec/zlib/deflate.c Fri Sep 29 20:51:33 2000
36560@@ -0,0 +1,1351 @@
36561+/* deflate.c -- compress data using the deflation algorithm
36562+ * Copyright (C) 1995-1998 Jean-loup Gailly.
36563+ * For conditions of distribution and use, see copyright notice in zlib.h
36564+ */
36565+
36566+/*
36567+ * ALGORITHM
36568+ *
36569+ * The "deflation" process depends on being able to identify portions
36570+ * of the input text which are identical to earlier input (within a
36571+ * sliding window trailing behind the input currently being processed).
36572+ *
36573+ * The most straightforward technique turns out to be the fastest for
36574+ * most input files: try all possible matches and select the longest.
36575+ * The key feature of this algorithm is that insertions into the string
36576+ * dictionary are very simple and thus fast, and deletions are avoided
36577+ * completely. Insertions are performed at each input character, whereas
36578+ * string matches are performed only when the previous match ends. So it
36579+ * is preferable to spend more time in matches to allow very fast string
36580+ * insertions and avoid deletions. The matching algorithm for small
36581+ * strings is inspired from that of Rabin & Karp. A brute force approach
36582+ * is used to find longer strings when a small match has been found.
36583+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
36584+ * (by Leonid Broukhis).
36585+ * A previous version of this file used a more sophisticated algorithm
36586+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
36587+ * time, but has a larger average cost, uses more memory and is patented.
36588+ * However the F&G algorithm may be faster for some highly redundant
36589+ * files if the parameter max_chain_length (described below) is too large.
36590+ *
36591+ * ACKNOWLEDGEMENTS
36592+ *
36593+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
36594+ * I found it in 'freeze' written by Leonid Broukhis.
36595+ * Thanks to many people for bug reports and testing.
36596+ *
36597+ * REFERENCES
36598+ *
36599+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
36600+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt
36601+ *
36602+ * A description of the Rabin and Karp algorithm is given in the book
36603+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
36604+ *
36605+ * Fiala,E.R., and Greene,D.H.
36606+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
36607+ *
36608+ */
36609+
36610+/* @(#) $Id$ */
36611+
36612+#include "deflate.h"
36613+
36614+local const char deflate_copyright[] =
36615+ " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly ";
36616+/*
36617+ If you use the zlib library in a product, an acknowledgment is welcome
36618+ in the documentation of your product. If for some reason you cannot
36619+ include such an acknowledgment, I would appreciate that you keep this
36620+ copyright string in the executable of your product.
36621+ */
36622+
36623+/* ===========================================================================
36624+ * Function prototypes.
36625+ */
36626+typedef enum {
36627+ need_more, /* block not completed, need more input or more output */
36628+ block_done, /* block flush performed */
36629+ finish_started, /* finish started, need only more output at next deflate */
36630+ finish_done /* finish done, accept no more input or output */
36631+} block_state;
36632+
36633+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
36634+/* Compression function. Returns the block state after the call. */
36635+
36636+local void fill_window OF((deflate_state *s));
36637+local block_state deflate_stored OF((deflate_state *s, int flush));
36638+local block_state deflate_fast OF((deflate_state *s, int flush));
36639+local block_state deflate_slow OF((deflate_state *s, int flush));
36640+local void lm_init OF((deflate_state *s));
36641+local void putShortMSB OF((deflate_state *s, uInt b));
36642+local void flush_pending OF((z_streamp strm));
36643+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
36644+#ifdef ASMV
36645+ void match_init OF((void)); /* asm code initialization */
36646+ uInt longest_match OF((deflate_state *s, IPos cur_match));
36647+#else
36648+local uInt longest_match OF((deflate_state *s, IPos cur_match));
36649+#endif
36650+
36651+#ifdef DEBUG
36652+local void check_match OF((deflate_state *s, IPos start, IPos match,
36653+ int length));
36654+#endif
36655+
36656+/* ===========================================================================
36657+ * Local data
36658+ */
36659+
36660+#define NIL 0
36661+/* Tail of hash chains */
36662+
36663+#ifndef TOO_FAR
36664+# define TOO_FAR 4096
36665+#endif
36666+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
36667+
36668+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
36669+/* Minimum amount of lookahead, except at the end of the input file.
36670+ * See deflate.c for comments about the MIN_MATCH+1.
36671+ */
36672+
36673+/* Values for max_lazy_match, good_match and max_chain_length, depending on
36674+ * the desired pack level (0..9). The values given below have been tuned to
36675+ * exclude worst case performance for pathological files. Better values may be
36676+ * found for specific files.
36677+ */
36678+typedef struct config_s {
36679+ ush good_length; /* reduce lazy search above this match length */
36680+ ush max_lazy; /* do not perform lazy search above this match length */
36681+ ush nice_length; /* quit search above this match length */
36682+ ush max_chain;
36683+ compress_func func;
36684+} config;
36685+
36686+local const config configuration_table[10] = {
36687+/* good lazy nice chain */
36688+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
36689+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
36690+/* 2 */ {4, 5, 16, 8, deflate_fast},
36691+/* 3 */ {4, 6, 32, 32, deflate_fast},
36692+
36693+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
36694+/* 5 */ {8, 16, 32, 32, deflate_slow},
36695+/* 6 */ {8, 16, 128, 128, deflate_slow},
36696+/* 7 */ {8, 32, 128, 256, deflate_slow},
36697+/* 8 */ {32, 128, 258, 1024, deflate_slow},
36698+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
36699+
36700+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
36701+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
36702+ * meaning.
36703+ */
36704+
36705+#define EQUAL 0
36706+/* result of memcmp for equal strings */
36707+
36708+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
36709+
36710+/* ===========================================================================
36711+ * Update a hash value with the given input byte
36712+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
36713+ * input characters, so that a running hash key can be computed from the
36714+ * previous key instead of complete recalculation each time.
36715+ */
36716+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
36717+
36718+
36719+/* ===========================================================================
36720+ * Insert string str in the dictionary and set match_head to the previous head
36721+ * of the hash chain (the most recent string with same hash key). Return
36722+ * the previous length of the hash chain.
36723+ * If this file is compiled with -DFASTEST, the compression level is forced
36724+ * to 1, and no hash chains are maintained.
36725+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
36726+ * input characters and the first MIN_MATCH bytes of str are valid
36727+ * (except for the last MIN_MATCH-1 bytes of the input file).
36728+ */
36729+#ifdef FASTEST
36730+#define INSERT_STRING(s, str, match_head) \
36731+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
36732+ match_head = s->head[s->ins_h], \
36733+ s->head[s->ins_h] = (Pos)(str))
36734+#else
36735+#define INSERT_STRING(s, str, match_head) \
36736+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
36737+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
36738+ s->head[s->ins_h] = (Pos)(str))
36739+#endif
36740+
36741+/* ===========================================================================
36742+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
36743+ * prev[] will be initialized on the fly.
36744+ */
36745+#define CLEAR_HASH(s) \
36746+ s->head[s->hash_size-1] = NIL; \
36747+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
36748+
36749+/* ========================================================================= */
36750+int ZEXPORT deflateInit_(strm, level, version, stream_size)
36751+ z_streamp strm;
36752+ int level;
36753+ const char *version;
36754+ int stream_size;
36755+{
36756+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
36757+ Z_DEFAULT_STRATEGY, version, stream_size);
36758+ /* To do: ignore strm->next_in if we use it as window */
36759+}
36760+
36761+/* ========================================================================= */
36762+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
36763+ version, stream_size)
36764+ z_streamp strm;
36765+ int level;
36766+ int method;
36767+ int windowBits;
36768+ int memLevel;
36769+ int strategy;
36770+ const char *version;
36771+ int stream_size;
36772+{
36773+ deflate_state *s;
36774+ int noheader = 0;
36775+ static const char* my_version = ZLIB_VERSION;
36776+
36777+ ushf *overlay;
36778+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
36779+ * output size for (length,distance) codes is <= 24 bits.
36780+ */
36781+
36782+ if (version == Z_NULL || version[0] != my_version[0] ||
36783+ stream_size != sizeof(z_stream)) {
36784+ return Z_VERSION_ERROR;
36785+ }
36786+ if (strm == Z_NULL) return Z_STREAM_ERROR;
36787+
36788+ strm->msg = Z_NULL;
36789+ if (strm->zalloc == Z_NULL) {
36790+ return Z_STREAM_ERROR;
36791+/* strm->zalloc = zcalloc;
36792+ strm->opaque = (voidpf)0;*/
36793+ }
36794+ if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
36795+
36796+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
36797+#ifdef FASTEST
36798+ level = 1;
36799+#endif
36800+
36801+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
36802+ noheader = 1;
36803+ windowBits = -windowBits;
36804+ }
36805+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
36806+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
36807+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
36808+ return Z_STREAM_ERROR;
36809+ }
36810+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
36811+ if (s == Z_NULL) return Z_MEM_ERROR;
36812+ strm->state = (struct internal_state FAR *)s;
36813+ s->strm = strm;
36814+
36815+ s->noheader = noheader;
36816+ s->w_bits = windowBits;
36817+ s->w_size = 1 << s->w_bits;
36818+ s->w_mask = s->w_size - 1;
36819+
36820+ s->hash_bits = memLevel + 7;
36821+ s->hash_size = 1 << s->hash_bits;
36822+ s->hash_mask = s->hash_size - 1;
36823+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
36824+
36825+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
36826+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
36827+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
36828+
36829+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
36830+
36831+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
36832+ s->pending_buf = (uchf *) overlay;
36833+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
36834+
36835+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
36836+ s->pending_buf == Z_NULL) {
36837+ strm->msg = ERR_MSG(Z_MEM_ERROR);
36838+ deflateEnd (strm);
36839+ return Z_MEM_ERROR;
36840+ }
36841+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
36842+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
36843+
36844+ s->level = level;
36845+ s->strategy = strategy;
36846+ s->method = (Byte)method;
36847+
36848+ return deflateReset(strm);
36849+}
36850+
36851+/* ========================================================================= */
36852+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
36853+ z_streamp strm;
36854+ const Bytef *dictionary;
36855+ uInt dictLength;
36856+{
36857+ deflate_state *s;
36858+ uInt length = dictLength;
36859+ uInt n;
36860+ IPos hash_head = 0;
36861+
36862+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
36863+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
36864+
36865+ s = strm->state;
36866+ strm->adler = adler32(strm->adler, dictionary, dictLength);
36867+
36868+ if (length < MIN_MATCH) return Z_OK;
36869+ if (length > MAX_DIST(s)) {
36870+ length = MAX_DIST(s);
36871+#ifndef USE_DICT_HEAD
36872+ dictionary += dictLength - length; /* use the tail of the dictionary */
36873+#endif
36874+ }
36875+ zmemcpy(s->window, dictionary, length);
36876+ s->strstart = length;
36877+ s->block_start = (long)length;
36878+
36879+ /* Insert all strings in the hash table (except for the last two bytes).
36880+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
36881+ * call of fill_window.
36882+ */
36883+ s->ins_h = s->window[0];
36884+ UPDATE_HASH(s, s->ins_h, s->window[1]);
36885+ for (n = 0; n <= length - MIN_MATCH; n++) {
36886+ INSERT_STRING(s, n, hash_head);
36887+ }
36888+ if (hash_head) hash_head = 0; /* to make compiler happy */
36889+ return Z_OK;
36890+}
36891+
36892+/* ========================================================================= */
36893+int ZEXPORT deflateReset (strm)
36894+ z_streamp strm;
36895+{
36896+ deflate_state *s;
36897+
36898+ if (strm == Z_NULL || strm->state == Z_NULL ||
36899+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
36900+
36901+ strm->total_in = strm->total_out = 0;
36902+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
36903+ strm->data_type = Z_UNKNOWN;
36904+
36905+ s = (deflate_state *)strm->state;
36906+ s->pending = 0;
36907+ s->pending_out = s->pending_buf;
36908+
36909+ if (s->noheader < 0) {
36910+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
36911+ }
36912+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
36913+ strm->adler = 1;
36914+ s->last_flush = Z_NO_FLUSH;
36915+
36916+ _tr_init(s);
36917+ lm_init(s);
36918+
36919+ return Z_OK;
36920+}
36921+
36922+/* ========================================================================= */
36923+int ZEXPORT deflateParams(strm, level, strategy)
36924+ z_streamp strm;
36925+ int level;
36926+ int strategy;
36927+{
36928+ deflate_state *s;
36929+ compress_func func;
36930+ int err = Z_OK;
36931+
36932+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
36933+ s = strm->state;
36934+
36935+ if (level == Z_DEFAULT_COMPRESSION) {
36936+ level = 6;
36937+ }
36938+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
36939+ return Z_STREAM_ERROR;
36940+ }
36941+ func = configuration_table[s->level].func;
36942+
36943+ if (func != configuration_table[level].func && strm->total_in != 0) {
36944+ /* Flush the last buffer: */
36945+ err = deflate(strm, Z_PARTIAL_FLUSH);
36946+ }
36947+ if (s->level != level) {
36948+ s->level = level;
36949+ s->max_lazy_match = configuration_table[level].max_lazy;
36950+ s->good_match = configuration_table[level].good_length;
36951+ s->nice_match = configuration_table[level].nice_length;
36952+ s->max_chain_length = configuration_table[level].max_chain;
36953+ }
36954+ s->strategy = strategy;
36955+ return err;
36956+}
36957+
36958+/* =========================================================================
36959+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
36960+ * IN assertion: the stream state is correct and there is enough room in
36961+ * pending_buf.
36962+ */
36963+local void putShortMSB (s, b)
36964+ deflate_state *s;
36965+ uInt b;
36966+{
36967+ put_byte(s, (Byte)(b >> 8));
36968+ put_byte(s, (Byte)(b & 0xff));
36969+}
36970+
36971+/* =========================================================================
36972+ * Flush as much pending output as possible. All deflate() output goes
36973+ * through this function so some applications may wish to modify it
36974+ * to avoid allocating a large strm->next_out buffer and copying into it.
36975+ * (See also read_buf()).
36976+ */
36977+local void flush_pending(strm)
36978+ z_streamp strm;
36979+{
36980+ unsigned len = strm->state->pending;
36981+
36982+ if (len > strm->avail_out) len = strm->avail_out;
36983+ if (len == 0) return;
36984+
36985+ zmemcpy(strm->next_out, strm->state->pending_out, len);
36986+ strm->next_out += len;
36987+ strm->state->pending_out += len;
36988+ strm->total_out += len;
36989+ strm->avail_out -= len;
36990+ strm->state->pending -= len;
36991+ if (strm->state->pending == 0) {
36992+ strm->state->pending_out = strm->state->pending_buf;
36993+ }
36994+}
36995+
36996+/* ========================================================================= */
36997+int ZEXPORT deflate (strm, flush)
36998+ z_streamp strm;
36999+ int flush;
37000+{
37001+ int old_flush; /* value of flush param for previous deflate call */
37002+ deflate_state *s;
37003+
37004+ if (strm == Z_NULL || strm->state == Z_NULL ||
37005+ flush > Z_FINISH || flush < 0) {
37006+ return Z_STREAM_ERROR;
37007+ }
37008+ s = strm->state;
37009+
37010+ if (strm->next_out == Z_NULL ||
37011+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
37012+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
37013+ ERR_RETURN(strm, Z_STREAM_ERROR);
37014+ }
37015+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
37016+
37017+ s->strm = strm; /* just in case */
37018+ old_flush = s->last_flush;
37019+ s->last_flush = flush;
37020+
37021+ /* Write the zlib header */
37022+ if (s->status == INIT_STATE) {
37023+
37024+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
37025+ uInt level_flags = (s->level-1) >> 1;
37026+
37027+ if (level_flags > 3) level_flags = 3;
37028+ header |= (level_flags << 6);
37029+ if (s->strstart != 0) header |= PRESET_DICT;
37030+ header += 31 - (header % 31);
37031+
37032+ s->status = BUSY_STATE;
37033+ putShortMSB(s, header);
37034+
37035+ /* Save the adler32 of the preset dictionary: */
37036+ if (s->strstart != 0) {
37037+ putShortMSB(s, (uInt)(strm->adler >> 16));
37038+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
37039+ }
37040+ strm->adler = 1L;
37041+ }
37042+
37043+ /* Flush as much pending output as possible */
37044+ if (s->pending != 0) {
37045+ flush_pending(strm);
37046+ if (strm->avail_out == 0) {
37047+ /* Since avail_out is 0, deflate will be called again with
37048+ * more output space, but possibly with both pending and
37049+ * avail_in equal to zero. There won't be anything to do,
37050+ * but this is not an error situation so make sure we
37051+ * return OK instead of BUF_ERROR at next call of deflate:
37052+ */
37053+ s->last_flush = -1;
37054+ return Z_OK;
37055+ }
37056+
37057+ /* Make sure there is something to do and avoid duplicate consecutive
37058+ * flushes. For repeated and useless calls with Z_FINISH, we keep
37059+ * returning Z_STREAM_END instead of Z_BUFF_ERROR.
37060+ */
37061+ } else if (strm->avail_in == 0 && flush <= old_flush &&
37062+ flush != Z_FINISH) {
37063+ ERR_RETURN(strm, Z_BUF_ERROR);
37064+ }
37065+
37066+ /* User must not provide more input after the first FINISH: */
37067+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
37068+ ERR_RETURN(strm, Z_BUF_ERROR);
37069+ }
37070+
37071+ /* Start a new block or continue the current one.
37072+ */
37073+ if (strm->avail_in != 0 || s->lookahead != 0 ||
37074+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
37075+ block_state bstate;
37076+
37077+ bstate = (*(configuration_table[s->level].func))(s, flush);
37078+
37079+ if (bstate == finish_started || bstate == finish_done) {
37080+ s->status = FINISH_STATE;
37081+ }
37082+ if (bstate == need_more || bstate == finish_started) {
37083+ if (strm->avail_out == 0) {
37084+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
37085+ }
37086+ return Z_OK;
37087+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
37088+ * of deflate should use the same flush parameter to make sure
37089+ * that the flush is complete. So we don't have to output an
37090+ * empty block here, this will be done at next call. This also
37091+ * ensures that for a very small output buffer, we emit at most
37092+ * one empty block.
37093+ */
37094+ }
37095+ if (bstate == block_done) {
37096+ if (flush == Z_PARTIAL_FLUSH) {
37097+ _tr_align(s);
37098+ } else { /* FULL_FLUSH or SYNC_FLUSH */
37099+ _tr_stored_block(s, (char*)0, 0L, 0);
37100+ /* For a full flush, this empty block will be recognized
37101+ * as a special marker by inflate_sync().
37102+ */
37103+ if (flush == Z_FULL_FLUSH) {
37104+ CLEAR_HASH(s); /* forget history */
37105+ }
37106+ }
37107+ flush_pending(strm);
37108+ if (strm->avail_out == 0) {
37109+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
37110+ return Z_OK;
37111+ }
37112+ }
37113+ }
37114+ Assert(strm->avail_out > 0, "bug2");
37115+
37116+ if (flush != Z_FINISH) return Z_OK;
37117+ if (s->noheader) return Z_STREAM_END;
37118+
37119+ /* Write the zlib trailer (adler32) */
37120+ putShortMSB(s, (uInt)(strm->adler >> 16));
37121+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
37122+ flush_pending(strm);
37123+ /* If avail_out is zero, the application will call deflate again
37124+ * to flush the rest.
37125+ */
37126+ s->noheader = -1; /* write the trailer only once! */
37127+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
37128+}
37129+
37130+/* ========================================================================= */
37131+int ZEXPORT deflateEnd (strm)
37132+ z_streamp strm;
37133+{
37134+ int status;
37135+
37136+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
37137+
37138+ status = strm->state->status;
37139+ if (status != INIT_STATE && status != BUSY_STATE &&
37140+ status != FINISH_STATE) {
37141+ return Z_STREAM_ERROR;
37142+ }
37143+
37144+ /* Deallocate in reverse order of allocations: */
37145+ TRY_FREE(strm, strm->state->pending_buf);
37146+ TRY_FREE(strm, strm->state->head);
37147+ TRY_FREE(strm, strm->state->prev);
37148+ TRY_FREE(strm, strm->state->window);
37149+
37150+ ZFREE(strm, strm->state);
37151+ strm->state = Z_NULL;
37152+
37153+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
37154+}
37155+
37156+/* =========================================================================
37157+ * Copy the source state to the destination state.
37158+ * To simplify the source, this is not supported for 16-bit MSDOS (which
37159+ * doesn't have enough memory anyway to duplicate compression states).
37160+ */
37161+int ZEXPORT deflateCopy (dest, source)
37162+ z_streamp dest;
37163+ z_streamp source;
37164+{
37165+#ifdef MAXSEG_64K
37166+ return Z_STREAM_ERROR;
37167+#else
37168+ deflate_state *ds;
37169+ deflate_state *ss;
37170+ ushf *overlay;
37171+
37172+
37173+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
37174+ return Z_STREAM_ERROR;
37175+ }
37176+
37177+ ss = source->state;
37178+
37179+ *dest = *source;
37180+
37181+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
37182+ if (ds == Z_NULL) return Z_MEM_ERROR;
37183+ dest->state = (struct internal_state FAR *) ds;
37184+ *ds = *ss;
37185+ ds->strm = dest;
37186+
37187+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
37188+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
37189+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
37190+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
37191+ ds->pending_buf = (uchf *) overlay;
37192+
37193+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
37194+ ds->pending_buf == Z_NULL) {
37195+ deflateEnd (dest);
37196+ return Z_MEM_ERROR;
37197+ }
37198+ /* following zmemcpy do not work for 16-bit MSDOS */
37199+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
37200+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
37201+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
37202+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
37203+
37204+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
37205+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
37206+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
37207+
37208+ ds->l_desc.dyn_tree = ds->dyn_ltree;
37209+ ds->d_desc.dyn_tree = ds->dyn_dtree;
37210+ ds->bl_desc.dyn_tree = ds->bl_tree;
37211+
37212+ return Z_OK;
37213+#endif
37214+}
37215+
37216+/* ===========================================================================
37217+ * Read a new buffer from the current input stream, update the adler32
37218+ * and total number of bytes read. All deflate() input goes through
37219+ * this function so some applications may wish to modify it to avoid
37220+ * allocating a large strm->next_in buffer and copying from it.
37221+ * (See also flush_pending()).
37222+ */
37223+local int read_buf(strm, buf, size)
37224+ z_streamp strm;
37225+ Bytef *buf;
37226+ unsigned size;
37227+{
37228+ unsigned len = strm->avail_in;
37229+
37230+ if (len > size) len = size;
37231+ if (len == 0) return 0;
37232+
37233+ strm->avail_in -= len;
37234+
37235+ if (!strm->state->noheader) {
37236+ strm->adler = adler32(strm->adler, strm->next_in, len);
37237+ }
37238+ zmemcpy(buf, strm->next_in, len);
37239+ strm->next_in += len;
37240+ strm->total_in += len;
37241+
37242+ return (int)len;
37243+}
37244+
37245+/* ===========================================================================
37246+ * Initialize the "longest match" routines for a new zlib stream
37247+ */
37248+local void lm_init (s)
37249+ deflate_state *s;
37250+{
37251+ s->window_size = (ulg)2L*s->w_size;
37252+
37253+ CLEAR_HASH(s);
37254+
37255+ /* Set the default configuration parameters:
37256+ */
37257+ s->max_lazy_match = configuration_table[s->level].max_lazy;
37258+ s->good_match = configuration_table[s->level].good_length;
37259+ s->nice_match = configuration_table[s->level].nice_length;
37260+ s->max_chain_length = configuration_table[s->level].max_chain;
37261+
37262+ s->strstart = 0;
37263+ s->block_start = 0L;
37264+ s->lookahead = 0;
37265+ s->match_length = s->prev_length = MIN_MATCH-1;
37266+ s->match_available = 0;
37267+ s->ins_h = 0;
37268+#ifdef ASMV
37269+ match_init(); /* initialize the asm code */
37270+#endif
37271+}
37272+
37273+/* ===========================================================================
37274+ * Set match_start to the longest match starting at the given string and
37275+ * return its length. Matches shorter or equal to prev_length are discarded,
37276+ * in which case the result is equal to prev_length and match_start is
37277+ * garbage.
37278+ * IN assertions: cur_match is the head of the hash chain for the current
37279+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
37280+ * OUT assertion: the match length is not greater than s->lookahead.
37281+ */
37282+#ifndef ASMV
37283+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
37284+ * match.S. The code will be functionally equivalent.
37285+ */
37286+#ifndef FASTEST
37287+local uInt longest_match(s, cur_match)
37288+ deflate_state *s;
37289+ IPos cur_match; /* current match */
37290+{
37291+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
37292+ register Bytef *scan = s->window + s->strstart; /* current string */
37293+ register Bytef *match; /* matched string */
37294+ register int len; /* length of current match */
37295+ int best_len = s->prev_length; /* best match length so far */
37296+ int nice_match = s->nice_match; /* stop if match long enough */
37297+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
37298+ s->strstart - (IPos)MAX_DIST(s) : NIL;
37299+ /* Stop when cur_match becomes <= limit. To simplify the code,
37300+ * we prevent matches with the string of window index 0.
37301+ */
37302+ Posf *prev = s->prev;
37303+ uInt wmask = s->w_mask;
37304+
37305+#ifdef UNALIGNED_OK
37306+ /* Compare two bytes at a time. Note: this is not always beneficial.
37307+ * Try with and without -DUNALIGNED_OK to check.
37308+ */
37309+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
37310+ register ush scan_start = *(ushf*)scan;
37311+ register ush scan_end = *(ushf*)(scan+best_len-1);
37312+#else
37313+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
37314+ register Byte scan_end1 = scan[best_len-1];
37315+ register Byte scan_end = scan[best_len];
37316+#endif
37317+
37318+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
37319+ * It is easy to get rid of this optimization if necessary.
37320+ */
37321+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
37322+
37323+ /* Do not waste too much time if we already have a good match: */
37324+ if (s->prev_length >= s->good_match) {
37325+ chain_length >>= 2;
37326+ }
37327+ /* Do not look for matches beyond the end of the input. This is necessary
37328+ * to make deflate deterministic.
37329+ */
37330+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
37331+
37332+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
37333+
37334+ do {
37335+ Assert(cur_match < s->strstart, "no future");
37336+ match = s->window + cur_match;
37337+
37338+ /* Skip to next match if the match length cannot increase
37339+ * or if the match length is less than 2:
37340+ */
37341+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
37342+ /* This code assumes sizeof(unsigned short) == 2. Do not use
37343+ * UNALIGNED_OK if your compiler uses a different size.
37344+ */
37345+ if (*(ushf*)(match+best_len-1) != scan_end ||
37346+ *(ushf*)match != scan_start) continue;
37347+
37348+ /* It is not necessary to compare scan[2] and match[2] since they are
37349+ * always equal when the other bytes match, given that the hash keys
37350+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
37351+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
37352+ * lookahead only every 4th comparison; the 128th check will be made
37353+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
37354+ * necessary to put more guard bytes at the end of the window, or
37355+ * to check more often for insufficient lookahead.
37356+ */
37357+ Assert(scan[2] == match[2], "scan[2]?");
37358+ scan++, match++;
37359+ do {
37360+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
37361+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
37362+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
37363+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
37364+ scan < strend);
37365+ /* The funny "do {}" generates better code on most compilers */
37366+
37367+ /* Here, scan <= window+strstart+257 */
37368+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
37369+ if (*scan == *match) scan++;
37370+
37371+ len = (MAX_MATCH - 1) - (int)(strend-scan);
37372+ scan = strend - (MAX_MATCH-1);
37373+
37374+#else /* UNALIGNED_OK */
37375+
37376+ if (match[best_len] != scan_end ||
37377+ match[best_len-1] != scan_end1 ||
37378+ *match != *scan ||
37379+ *++match != scan[1]) continue;
37380+
37381+ /* The check at best_len-1 can be removed because it will be made
37382+ * again later. (This heuristic is not always a win.)
37383+ * It is not necessary to compare scan[2] and match[2] since they
37384+ * are always equal when the other bytes match, given that
37385+ * the hash keys are equal and that HASH_BITS >= 8.
37386+ */
37387+ scan += 2, match++;
37388+ Assert(*scan == *match, "match[2]?");
37389+
37390+ /* We check for insufficient lookahead only every 8th comparison;
37391+ * the 256th check will be made at strstart+258.
37392+ */
37393+ do {
37394+ } while (*++scan == *++match && *++scan == *++match &&
37395+ *++scan == *++match && *++scan == *++match &&
37396+ *++scan == *++match && *++scan == *++match &&
37397+ *++scan == *++match && *++scan == *++match &&
37398+ scan < strend);
37399+
37400+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
37401+
37402+ len = MAX_MATCH - (int)(strend - scan);
37403+ scan = strend - MAX_MATCH;
37404+
37405+#endif /* UNALIGNED_OK */
37406+
37407+ if (len > best_len) {
37408+ s->match_start = cur_match;
37409+ best_len = len;
37410+ if (len >= nice_match) break;
37411+#ifdef UNALIGNED_OK
37412+ scan_end = *(ushf*)(scan+best_len-1);
37413+#else
37414+ scan_end1 = scan[best_len-1];
37415+ scan_end = scan[best_len];
37416+#endif
37417+ }
37418+ } while ((cur_match = prev[cur_match & wmask]) > limit
37419+ && --chain_length != 0);
37420+
37421+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
37422+ return s->lookahead;
37423+}
37424+
37425+#else /* FASTEST */
37426+/* ---------------------------------------------------------------------------
37427+ * Optimized version for level == 1 only
37428+ */
37429+local uInt longest_match(s, cur_match)
37430+ deflate_state *s;
37431+ IPos cur_match; /* current match */
37432+{
37433+ register Bytef *scan = s->window + s->strstart; /* current string */
37434+ register Bytef *match; /* matched string */
37435+ register int len; /* length of current match */
37436+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
37437+
37438+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
37439+ * It is easy to get rid of this optimization if necessary.
37440+ */
37441+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
37442+
37443+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
37444+
37445+ Assert(cur_match < s->strstart, "no future");
37446+
37447+ match = s->window + cur_match;
37448+
37449+ /* Return failure if the match length is less than 2:
37450+ */
37451+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
37452+
37453+ /* The check at best_len-1 can be removed because it will be made
37454+ * again later. (This heuristic is not always a win.)
37455+ * It is not necessary to compare scan[2] and match[2] since they
37456+ * are always equal when the other bytes match, given that
37457+ * the hash keys are equal and that HASH_BITS >= 8.
37458+ */
37459+ scan += 2, match += 2;
37460+ Assert(*scan == *match, "match[2]?");
37461+
37462+ /* We check for insufficient lookahead only every 8th comparison;
37463+ * the 256th check will be made at strstart+258.
37464+ */
37465+ do {
37466+ } while (*++scan == *++match && *++scan == *++match &&
37467+ *++scan == *++match && *++scan == *++match &&
37468+ *++scan == *++match && *++scan == *++match &&
37469+ *++scan == *++match && *++scan == *++match &&
37470+ scan < strend);
37471+
37472+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
37473+
37474+ len = MAX_MATCH - (int)(strend - scan);
37475+
37476+ if (len < MIN_MATCH) return MIN_MATCH - 1;
37477+
37478+ s->match_start = cur_match;
37479+ return len <= s->lookahead ? len : s->lookahead;
37480+}
37481+#endif /* FASTEST */
37482+#endif /* ASMV */
37483+
37484+#ifdef DEBUG
37485+/* ===========================================================================
37486+ * Check that the match at match_start is indeed a match.
37487+ */
37488+local void check_match(s, start, match, length)
37489+ deflate_state *s;
37490+ IPos start, match;
37491+ int length;
37492+{
37493+ /* check that the match is indeed a match */
37494+ if (zmemcmp(s->window + match,
37495+ s->window + start, length) != EQUAL) {
37496+ fprintf(stderr, " start %u, match %u, length %d\n",
37497+ start, match, length);
37498+ do {
37499+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
37500+ } while (--length != 0);
37501+ z_error("invalid match");
37502+ }
37503+ if (z_verbose > 1) {
37504+ fprintf(stderr,"\\[%d,%d]", start-match, length);
37505+ do { putc(s->window[start++], stderr); } while (--length != 0);
37506+ }
37507+}
37508+#else
37509+# define check_match(s, start, match, length)
37510+#endif
37511+
37512+/* ===========================================================================
37513+ * Fill the window when the lookahead becomes insufficient.
37514+ * Updates strstart and lookahead.
37515+ *
37516+ * IN assertion: lookahead < MIN_LOOKAHEAD
37517+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
37518+ * At least one byte has been read, or avail_in == 0; reads are
37519+ * performed for at least two bytes (required for the zip translate_eol
37520+ * option -- not supported here).
37521+ */
37522+local void fill_window(s)
37523+ deflate_state *s;
37524+{
37525+ register unsigned n, m;
37526+ register Posf *p;
37527+ unsigned more; /* Amount of free space at the end of the window. */
37528+ uInt wsize = s->w_size;
37529+
37530+ do {
37531+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
37532+
37533+ /* Deal with !@#$% 64K limit: */
37534+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
37535+ more = wsize;
37536+
37537+ } else if (more == (unsigned)(-1)) {
37538+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
37539+ * and lookahead == 1 (input done one byte at time)
37540+ */
37541+ more--;
37542+
37543+ /* If the window is almost full and there is insufficient lookahead,
37544+ * move the upper half to the lower one to make room in the upper half.
37545+ */
37546+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
37547+
37548+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
37549+ s->match_start -= wsize;
37550+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
37551+ s->block_start -= (long) wsize;
37552+
37553+ /* Slide the hash table (could be avoided with 32 bit values
37554+ at the expense of memory usage). We slide even when level == 0
37555+ to keep the hash table consistent if we switch back to level > 0
37556+ later. (Using level 0 permanently is not an optimal usage of
37557+ zlib, so we don't care about this pathological case.)
37558+ */
37559+ n = s->hash_size;
37560+ p = &s->head[n];
37561+ do {
37562+ m = *--p;
37563+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
37564+ } while (--n);
37565+
37566+ n = wsize;
37567+#ifndef FASTEST
37568+ p = &s->prev[n];
37569+ do {
37570+ m = *--p;
37571+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
37572+ /* If n is not on any hash chain, prev[n] is garbage but
37573+ * its value will never be used.
37574+ */
37575+ } while (--n);
37576+#endif
37577+ more += wsize;
37578+ }
37579+ if (s->strm->avail_in == 0) return;
37580+
37581+ /* If there was no sliding:
37582+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
37583+ * more == window_size - lookahead - strstart
37584+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
37585+ * => more >= window_size - 2*WSIZE + 2
37586+ * In the BIG_MEM or MMAP case (not yet supported),
37587+ * window_size == input_size + MIN_LOOKAHEAD &&
37588+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
37589+ * Otherwise, window_size == 2*WSIZE so more >= 2.
37590+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
37591+ */
37592+ Assert(more >= 2, "more < 2");
37593+
37594+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
37595+ s->lookahead += n;
37596+
37597+ /* Initialize the hash value now that we have some input: */
37598+ if (s->lookahead >= MIN_MATCH) {
37599+ s->ins_h = s->window[s->strstart];
37600+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
37601+#if MIN_MATCH != 3
37602+ Call UPDATE_HASH() MIN_MATCH-3 more times
37603+#endif
37604+ }
37605+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
37606+ * but this is not important since only literal bytes will be emitted.
37607+ */
37608+
37609+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
37610+}
37611+
37612+/* ===========================================================================
37613+ * Flush the current block, with given end-of-file flag.
37614+ * IN assertion: strstart is set to the end of the current match.
37615+ */
37616+#define FLUSH_BLOCK_ONLY(s, eof) { \
37617+ _tr_flush_block(s, (s->block_start >= 0L ? \
37618+ (charf *)&s->window[(unsigned)s->block_start] : \
37619+ (charf *)Z_NULL), \
37620+ (ulg)((long)s->strstart - s->block_start), \
37621+ (eof)); \
37622+ s->block_start = s->strstart; \
37623+ flush_pending(s->strm); \
37624+ Tracev((stderr,"[FLUSH]")); \
37625+}
37626+
37627+/* Same but force premature exit if necessary. */
37628+#define FLUSH_BLOCK(s, eof) { \
37629+ FLUSH_BLOCK_ONLY(s, eof); \
37630+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
37631+}
37632+
37633+/* ===========================================================================
37634+ * Copy without compression as much as possible from the input stream, return
37635+ * the current block state.
37636+ * This function does not insert new strings in the dictionary since
37637+ * uncompressible data is probably not useful. This function is used
37638+ * only for the level=0 compression option.
37639+ * NOTE: this function should be optimized to avoid extra copying from
37640+ * window to pending_buf.
37641+ */
37642+local block_state deflate_stored(s, flush)
37643+ deflate_state *s;
37644+ int flush;
37645+{
37646+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
37647+ * to pending_buf_size, and each stored block has a 5 byte header:
37648+ */
37649+ ulg max_block_size = 0xffff;
37650+ ulg max_start;
37651+
37652+ if (max_block_size > s->pending_buf_size - 5) {
37653+ max_block_size = s->pending_buf_size - 5;
37654+ }
37655+
37656+ /* Copy as much as possible from input to output: */
37657+ for (;;) {
37658+ /* Fill the window as much as possible: */
37659+ if (s->lookahead <= 1) {
37660+
37661+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
37662+ s->block_start >= (long)s->w_size, "slide too late");
37663+
37664+ fill_window(s);
37665+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
37666+
37667+ if (s->lookahead == 0) break; /* flush the current block */
37668+ }
37669+ Assert(s->block_start >= 0L, "block gone");
37670+
37671+ s->strstart += s->lookahead;
37672+ s->lookahead = 0;
37673+
37674+ /* Emit a stored block if pending_buf will be full: */
37675+ max_start = s->block_start + max_block_size;
37676+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
37677+ /* strstart == 0 is possible when wraparound on 16-bit machine */
37678+ s->lookahead = (uInt)(s->strstart - max_start);
37679+ s->strstart = (uInt)max_start;
37680+ FLUSH_BLOCK(s, 0);
37681+ }
37682+ /* Flush if we may have to slide, otherwise block_start may become
37683+ * negative and the data will be gone:
37684+ */
37685+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
37686+ FLUSH_BLOCK(s, 0);
37687+ }
37688+ }
37689+ FLUSH_BLOCK(s, flush == Z_FINISH);
37690+ return flush == Z_FINISH ? finish_done : block_done;
37691+}
37692+
37693+/* ===========================================================================
37694+ * Compress as much as possible from the input stream, return the current
37695+ * block state.
37696+ * This function does not perform lazy evaluation of matches and inserts
37697+ * new strings in the dictionary only for unmatched strings or for short
37698+ * matches. It is used only for the fast compression options.
37699+ */
37700+local block_state deflate_fast(s, flush)
37701+ deflate_state *s;
37702+ int flush;
37703+{
37704+ IPos hash_head = NIL; /* head of the hash chain */
37705+ int bflush; /* set if current block must be flushed */
37706+
37707+ for (;;) {
37708+ /* Make sure that we always have enough lookahead, except
37709+ * at the end of the input file. We need MAX_MATCH bytes
37710+ * for the next match, plus MIN_MATCH bytes to insert the
37711+ * string following the next match.
37712+ */
37713+ if (s->lookahead < MIN_LOOKAHEAD) {
37714+ fill_window(s);
37715+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
37716+ return need_more;
37717+ }
37718+ if (s->lookahead == 0) break; /* flush the current block */
37719+ }
37720+
37721+ /* Insert the string window[strstart .. strstart+2] in the
37722+ * dictionary, and set hash_head to the head of the hash chain:
37723+ */
37724+ if (s->lookahead >= MIN_MATCH) {
37725+ INSERT_STRING(s, s->strstart, hash_head);
37726+ }
37727+
37728+ /* Find the longest match, discarding those <= prev_length.
37729+ * At this point we have always match_length < MIN_MATCH
37730+ */
37731+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
37732+ /* To simplify the code, we prevent matches with the string
37733+ * of window index 0 (in particular we have to avoid a match
37734+ * of the string with itself at the start of the input file).
37735+ */
37736+ if (s->strategy != Z_HUFFMAN_ONLY) {
37737+ s->match_length = longest_match (s, hash_head);
37738+ }
37739+ /* longest_match() sets match_start */
37740+ }
37741+ if (s->match_length >= MIN_MATCH) {
37742+ check_match(s, s->strstart, s->match_start, s->match_length);
37743+
37744+ _tr_tally_dist(s, s->strstart - s->match_start,
37745+ s->match_length - MIN_MATCH, bflush);
37746+
37747+ s->lookahead -= s->match_length;
37748+
37749+ /* Insert new strings in the hash table only if the match length
37750+ * is not too large. This saves time but degrades compression.
37751+ */
37752+#ifndef FASTEST
37753+ if (s->match_length <= s->max_insert_length &&
37754+ s->lookahead >= MIN_MATCH) {
37755+ s->match_length--; /* string at strstart already in hash table */
37756+ do {
37757+ s->strstart++;
37758+ INSERT_STRING(s, s->strstart, hash_head);
37759+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
37760+ * always MIN_MATCH bytes ahead.
37761+ */
37762+ } while (--s->match_length != 0);
37763+ s->strstart++;
37764+ } else
37765+#endif
37766+ {
37767+ s->strstart += s->match_length;
37768+ s->match_length = 0;
37769+ s->ins_h = s->window[s->strstart];
37770+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
37771+#if MIN_MATCH != 3
37772+ Call UPDATE_HASH() MIN_MATCH-3 more times
37773+#endif
37774+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
37775+ * matter since it will be recomputed at next deflate call.
37776+ */
37777+ }
37778+ } else {
37779+ /* No match, output a literal byte */
37780+ Tracevv((stderr,"%c", s->window[s->strstart]));
37781+ _tr_tally_lit (s, s->window[s->strstart], bflush);
37782+ s->lookahead--;
37783+ s->strstart++;
37784+ }
37785+ if (bflush) FLUSH_BLOCK(s, 0);
37786+ }
37787+ FLUSH_BLOCK(s, flush == Z_FINISH);
37788+ return flush == Z_FINISH ? finish_done : block_done;
37789+}
37790+
37791+/* ===========================================================================
37792+ * Same as above, but achieves better compression. We use a lazy
37793+ * evaluation for matches: a match is finally adopted only if there is
37794+ * no better match at the next window position.
37795+ */
37796+local block_state deflate_slow(s, flush)
37797+ deflate_state *s;
37798+ int flush;
37799+{
37800+ IPos hash_head = NIL; /* head of hash chain */
37801+ int bflush; /* set if current block must be flushed */
37802+
37803+ /* Process the input block. */
37804+ for (;;) {
37805+ /* Make sure that we always have enough lookahead, except
37806+ * at the end of the input file. We need MAX_MATCH bytes
37807+ * for the next match, plus MIN_MATCH bytes to insert the
37808+ * string following the next match.
37809+ */
37810+ if (s->lookahead < MIN_LOOKAHEAD) {
37811+ fill_window(s);
37812+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
37813+ return need_more;
37814+ }
37815+ if (s->lookahead == 0) break; /* flush the current block */
37816+ }
37817+
37818+ /* Insert the string window[strstart .. strstart+2] in the
37819+ * dictionary, and set hash_head to the head of the hash chain:
37820+ */
37821+ if (s->lookahead >= MIN_MATCH) {
37822+ INSERT_STRING(s, s->strstart, hash_head);
37823+ }
37824+
37825+ /* Find the longest match, discarding those <= prev_length.
37826+ */
37827+ s->prev_length = s->match_length, s->prev_match = s->match_start;
37828+ s->match_length = MIN_MATCH-1;
37829+
37830+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
37831+ s->strstart - hash_head <= MAX_DIST(s)) {
37832+ /* To simplify the code, we prevent matches with the string
37833+ * of window index 0 (in particular we have to avoid a match
37834+ * of the string with itself at the start of the input file).
37835+ */
37836+ if (s->strategy != Z_HUFFMAN_ONLY) {
37837+ s->match_length = longest_match (s, hash_head);
37838+ }
37839+ /* longest_match() sets match_start */
37840+
37841+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
37842+ (s->match_length == MIN_MATCH &&
37843+ s->strstart - s->match_start > TOO_FAR))) {
37844+
37845+ /* If prev_match is also MIN_MATCH, match_start is garbage
37846+ * but we will ignore the current match anyway.
37847+ */
37848+ s->match_length = MIN_MATCH-1;
37849+ }
37850+ }
37851+ /* If there was a match at the previous step and the current
37852+ * match is not better, output the previous match:
37853+ */
37854+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
37855+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
37856+ /* Do not insert strings in hash table beyond this. */
37857+
37858+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
37859+
37860+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
37861+ s->prev_length - MIN_MATCH, bflush);
37862+
37863+ /* Insert in hash table all strings up to the end of the match.
37864+ * strstart-1 and strstart are already inserted. If there is not
37865+ * enough lookahead, the last two strings are not inserted in
37866+ * the hash table.
37867+ */
37868+ s->lookahead -= s->prev_length-1;
37869+ s->prev_length -= 2;
37870+ do {
37871+ if (++s->strstart <= max_insert) {
37872+ INSERT_STRING(s, s->strstart, hash_head);
37873+ }
37874+ } while (--s->prev_length != 0);
37875+ s->match_available = 0;
37876+ s->match_length = MIN_MATCH-1;
37877+ s->strstart++;
37878+
37879+ if (bflush) FLUSH_BLOCK(s, 0);
37880+
37881+ } else if (s->match_available) {
37882+ /* If there was no match at the previous position, output a
37883+ * single literal. If there was a match but the current match
37884+ * is longer, truncate the previous match to a single literal.
37885+ */
37886+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
37887+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
37888+ if (bflush) {
37889+ FLUSH_BLOCK_ONLY(s, 0);
37890+ }
37891+ s->strstart++;
37892+ s->lookahead--;
37893+ if (s->strm->avail_out == 0) return need_more;
37894+ } else {
37895+ /* There is no previous match to compare with, wait for
37896+ * the next step to decide.
37897+ */
37898+ s->match_available = 1;
37899+ s->strstart++;
37900+ s->lookahead--;
37901+ }
37902+ }
37903+ Assert (flush != Z_NO_FLUSH, "no flush?");
37904+ if (s->match_available) {
37905+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
37906+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
37907+ s->match_available = 0;
37908+ }
37909+ FLUSH_BLOCK(s, flush == Z_FINISH);
37910+ return flush == Z_FINISH ? finish_done : block_done;
37911+}
37912diff -druN linux-noipsec/net/ipsec/zlib/deflate.h linux/net/ipsec/zlib/deflate.h
37913--- linux-noipsec/net/ipsec/zlib/deflate.h Thu Jan 1 01:00:00 1970
37914+++ linux/net/ipsec/zlib/deflate.h Fri Sep 29 20:51:34 2000
37915@@ -0,0 +1,318 @@
37916+/* deflate.h -- internal compression state
37917+ * Copyright (C) 1995-1998 Jean-loup Gailly
37918+ * For conditions of distribution and use, see copyright notice in zlib.h
37919+ */
37920+
37921+/* WARNING: this file should *not* be used by applications. It is
37922+ part of the implementation of the compression library and is
37923+ subject to change. Applications should only use zlib.h.
37924+ */
37925+
37926+/* @(#) $Id$ */
37927+
37928+#ifndef _DEFLATE_H
37929+#define _DEFLATE_H
37930+
37931+#include "zutil.h"
37932+
37933+/* ===========================================================================
37934+ * Internal compression state.
37935+ */
37936+
37937+#define LENGTH_CODES 29
37938+/* number of length codes, not counting the special END_BLOCK code */
37939+
37940+#define LITERALS 256
37941+/* number of literal bytes 0..255 */
37942+
37943+#define L_CODES (LITERALS+1+LENGTH_CODES)
37944+/* number of Literal or Length codes, including the END_BLOCK code */
37945+
37946+#define D_CODES 30
37947+/* number of distance codes */
37948+
37949+#define BL_CODES 19
37950+/* number of codes used to transfer the bit lengths */
37951+
37952+#define HEAP_SIZE (2*L_CODES+1)
37953+/* maximum heap size */
37954+
37955+#define MAX_BITS 15
37956+/* All codes must not exceed MAX_BITS bits */
37957+
37958+#define INIT_STATE 42
37959+#define BUSY_STATE 113
37960+#define FINISH_STATE 666
37961+/* Stream status */
37962+
37963+
37964+/* Data structure describing a single value and its code string. */
37965+typedef struct ct_data_s {
37966+ union {
37967+ ush freq; /* frequency count */
37968+ ush code; /* bit string */
37969+ } fc;
37970+ union {
37971+ ush dad; /* father node in Huffman tree */
37972+ ush len; /* length of bit string */
37973+ } dl;
37974+} FAR ct_data;
37975+
37976+#define Freq fc.freq
37977+#define Code fc.code
37978+#define Dad dl.dad
37979+#define Len dl.len
37980+
37981+typedef struct static_tree_desc_s static_tree_desc;
37982+
37983+typedef struct tree_desc_s {
37984+ ct_data *dyn_tree; /* the dynamic tree */
37985+ int max_code; /* largest code with non zero frequency */
37986+ static_tree_desc *stat_desc; /* the corresponding static tree */
37987+} FAR tree_desc;
37988+
37989+typedef ush Pos;
37990+typedef Pos FAR Posf;
37991+typedef unsigned IPos;
37992+
37993+/* A Pos is an index in the character window. We use short instead of int to
37994+ * save space in the various tables. IPos is used only for parameter passing.
37995+ */
37996+
37997+typedef struct internal_state {
37998+ z_streamp strm; /* pointer back to this zlib stream */
37999+ int status; /* as the name implies */
38000+ Bytef *pending_buf; /* output still pending */
38001+ ulg pending_buf_size; /* size of pending_buf */
38002+ Bytef *pending_out; /* next pending byte to output to the stream */
38003+ int pending; /* nb of bytes in the pending buffer */
38004+ int noheader; /* suppress zlib header and adler32 */
38005+ Byte data_type; /* UNKNOWN, BINARY or ASCII */
38006+ Byte method; /* STORED (for zip only) or DEFLATED */
38007+ int last_flush; /* value of flush param for previous deflate call */
38008+
38009+ /* used by deflate.c: */
38010+
38011+ uInt w_size; /* LZ77 window size (32K by default) */
38012+ uInt w_bits; /* log2(w_size) (8..16) */
38013+ uInt w_mask; /* w_size - 1 */
38014+
38015+ Bytef *window;
38016+ /* Sliding window. Input bytes are read into the second half of the window,
38017+ * and move to the first half later to keep a dictionary of at least wSize
38018+ * bytes. With this organization, matches are limited to a distance of
38019+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
38020+ * performed with a length multiple of the block size. Also, it limits
38021+ * the window size to 64K, which is quite useful on MSDOS.
38022+ * To do: use the user input buffer as sliding window.
38023+ */
38024+
38025+ ulg window_size;
38026+ /* Actual size of window: 2*wSize, except when the user input buffer
38027+ * is directly used as sliding window.
38028+ */
38029+
38030+ Posf *prev;
38031+ /* Link to older string with same hash index. To limit the size of this
38032+ * array to 64K, this link is maintained only for the last 32K strings.
38033+ * An index in this array is thus a window index modulo 32K.
38034+ */
38035+
38036+ Posf *head; /* Heads of the hash chains or NIL. */
38037+
38038+ uInt ins_h; /* hash index of string to be inserted */
38039+ uInt hash_size; /* number of elements in hash table */
38040+ uInt hash_bits; /* log2(hash_size) */
38041+ uInt hash_mask; /* hash_size-1 */
38042+
38043+ uInt hash_shift;
38044+ /* Number of bits by which ins_h must be shifted at each input
38045+ * step. It must be such that after MIN_MATCH steps, the oldest
38046+ * byte no longer takes part in the hash key, that is:
38047+ * hash_shift * MIN_MATCH >= hash_bits
38048+ */
38049+
38050+ long block_start;
38051+ /* Window position at the beginning of the current output block. Gets
38052+ * negative when the window is moved backwards.
38053+ */
38054+
38055+ uInt match_length; /* length of best match */
38056+ IPos prev_match; /* previous match */
38057+ int match_available; /* set if previous match exists */
38058+ uInt strstart; /* start of string to insert */
38059+ uInt match_start; /* start of matching string */
38060+ uInt lookahead; /* number of valid bytes ahead in window */
38061+
38062+ uInt prev_length;
38063+ /* Length of the best match at previous step. Matches not greater than this
38064+ * are discarded. This is used in the lazy match evaluation.
38065+ */
38066+
38067+ uInt max_chain_length;
38068+ /* To speed up deflation, hash chains are never searched beyond this
38069+ * length. A higher limit improves compression ratio but degrades the
38070+ * speed.
38071+ */
38072+
38073+ uInt max_lazy_match;
38074+ /* Attempt to find a better match only when the current match is strictly
38075+ * smaller than this value. This mechanism is used only for compression
38076+ * levels >= 4.
38077+ */
38078+# define max_insert_length max_lazy_match
38079+ /* Insert new strings in the hash table only if the match length is not
38080+ * greater than this length. This saves time but degrades compression.
38081+ * max_insert_length is used only for compression levels <= 3.
38082+ */
38083+
38084+ int level; /* compression level (1..9) */
38085+ int strategy; /* favor or force Huffman coding*/
38086+
38087+ uInt good_match;
38088+ /* Use a faster search when the previous match is longer than this */
38089+
38090+ int nice_match; /* Stop searching when current match exceeds this */
38091+
38092+ /* used by trees.c: */
38093+ /* Didn't use ct_data typedef below to supress compiler warning */
38094+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
38095+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
38096+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
38097+
38098+ struct tree_desc_s l_desc; /* desc. for literal tree */
38099+ struct tree_desc_s d_desc; /* desc. for distance tree */
38100+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
38101+
38102+ ush bl_count[MAX_BITS+1];
38103+ /* number of codes at each bit length for an optimal tree */
38104+
38105+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
38106+ int heap_len; /* number of elements in the heap */
38107+ int heap_max; /* element of largest frequency */
38108+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
38109+ * The same heap array is used to build all trees.
38110+ */
38111+
38112+ uch depth[2*L_CODES+1];
38113+ /* Depth of each subtree used as tie breaker for trees of equal frequency
38114+ */
38115+
38116+ uchf *l_buf; /* buffer for literals or lengths */
38117+
38118+ uInt lit_bufsize;
38119+ /* Size of match buffer for literals/lengths. There are 4 reasons for
38120+ * limiting lit_bufsize to 64K:
38121+ * - frequencies can be kept in 16 bit counters
38122+ * - if compression is not successful for the first block, all input
38123+ * data is still in the window so we can still emit a stored block even
38124+ * when input comes from standard input. (This can also be done for
38125+ * all blocks if lit_bufsize is not greater than 32K.)
38126+ * - if compression is not successful for a file smaller than 64K, we can
38127+ * even emit a stored file instead of a stored block (saving 5 bytes).
38128+ * This is applicable only for zip (not gzip or zlib).
38129+ * - creating new Huffman trees less frequently may not provide fast
38130+ * adaptation to changes in the input data statistics. (Take for
38131+ * example a binary file with poorly compressible code followed by
38132+ * a highly compressible string table.) Smaller buffer sizes give
38133+ * fast adaptation but have of course the overhead of transmitting
38134+ * trees more frequently.
38135+ * - I can't count above 4
38136+ */
38137+
38138+ uInt last_lit; /* running index in l_buf */
38139+
38140+ ushf *d_buf;
38141+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
38142+ * the same number of elements. To use different lengths, an extra flag
38143+ * array would be necessary.
38144+ */
38145+
38146+ ulg opt_len; /* bit length of current block with optimal trees */
38147+ ulg static_len; /* bit length of current block with static trees */
38148+ uInt matches; /* number of string matches in current block */
38149+ int last_eob_len; /* bit length of EOB code for last block */
38150+
38151+#ifdef DEBUG
38152+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
38153+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
38154+#endif
38155+
38156+ ush bi_buf;
38157+ /* Output buffer. bits are inserted starting at the bottom (least
38158+ * significant bits).
38159+ */
38160+ int bi_valid;
38161+ /* Number of valid bits in bi_buf. All bits above the last valid bit
38162+ * are always zero.
38163+ */
38164+
38165+} FAR deflate_state;
38166+
38167+/* Output a byte on the stream.
38168+ * IN assertion: there is enough room in pending_buf.
38169+ */
38170+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
38171+
38172+
38173+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
38174+/* Minimum amount of lookahead, except at the end of the input file.
38175+ * See deflate.c for comments about the MIN_MATCH+1.
38176+ */
38177+
38178+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
38179+/* In order to simplify the code, particularly on 16 bit machines, match
38180+ * distances are limited to MAX_DIST instead of WSIZE.
38181+ */
38182+
38183+ /* in trees.c */
38184+void _tr_init OF((deflate_state *s));
38185+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
38186+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
38187+ int eof));
38188+void _tr_align OF((deflate_state *s));
38189+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
38190+ int eof));
38191+
38192+#define d_code(dist) \
38193+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
38194+/* Mapping from a distance to a distance code. dist is the distance - 1 and
38195+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
38196+ * used.
38197+ */
38198+
38199+#ifndef DEBUG
38200+/* Inline versions of _tr_tally for speed: */
38201+
38202+#if defined(GEN_TREES_H) || !defined(STDC)
38203+ extern uch _length_code[];
38204+ extern uch _dist_code[];
38205+#else
38206+ extern const uch _length_code[];
38207+ extern const uch _dist_code[];
38208+#endif
38209+
38210+# define _tr_tally_lit(s, c, flush) \
38211+ { uch cc = (c); \
38212+ s->d_buf[s->last_lit] = 0; \
38213+ s->l_buf[s->last_lit++] = cc; \
38214+ s->dyn_ltree[cc].Freq++; \
38215+ flush = (s->last_lit == s->lit_bufsize-1); \
38216+ }
38217+# define _tr_tally_dist(s, distance, length, flush) \
38218+ { uch len = (length); \
38219+ ush dist = (distance); \
38220+ s->d_buf[s->last_lit] = dist; \
38221+ s->l_buf[s->last_lit++] = len; \
38222+ dist--; \
38223+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
38224+ s->dyn_dtree[d_code(dist)].Freq++; \
38225+ flush = (s->last_lit == s->lit_bufsize-1); \
38226+ }
38227+#else
38228+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
38229+# define _tr_tally_dist(s, distance, length, flush) \
38230+ flush = _tr_tally(s, distance, length)
38231+#endif
38232+
38233+#endif /* _DEFLATE_H */
38234diff -druN linux-noipsec/net/ipsec/zlib/infblock.c linux/net/ipsec/zlib/infblock.c
38235--- linux-noipsec/net/ipsec/zlib/infblock.c Thu Jan 1 01:00:00 1970
38236+++ linux/net/ipsec/zlib/infblock.c Fri Sep 29 20:51:34 2000
38237@@ -0,0 +1,398 @@
38238+/* infblock.c -- interpret and process block types to last block
38239+ * Copyright (C) 1995-1998 Mark Adler
38240+ * For conditions of distribution and use, see copyright notice in zlib.h
38241+ */
38242+
38243+#include "zutil.h"
38244+#include "infblock.h"
38245+#include "inftrees.h"
38246+#include "infcodes.h"
38247+#include "infutil.h"
38248+
38249+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
38250+
38251+/* simplify the use of the inflate_huft type with some defines */
38252+#define exop word.what.Exop
38253+#define bits word.what.Bits
38254+
38255+/* Table for deflate from PKZIP's appnote.txt. */
38256+local const uInt border[] = { /* Order of the bit length code lengths */
38257+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
38258+
38259+/*
38260+ Notes beyond the 1.93a appnote.txt:
38261+
38262+ 1. Distance pointers never point before the beginning of the output
38263+ stream.
38264+ 2. Distance pointers can point back across blocks, up to 32k away.
38265+ 3. There is an implied maximum of 7 bits for the bit length table and
38266+ 15 bits for the actual data.
38267+ 4. If only one code exists, then it is encoded using one bit. (Zero
38268+ would be more efficient, but perhaps a little confusing.) If two
38269+ codes exist, they are coded using one bit each (0 and 1).
38270+ 5. There is no way of sending zero distance codes--a dummy must be
38271+ sent if there are none. (History: a pre 2.0 version of PKZIP would
38272+ store blocks with no distance codes, but this was discovered to be
38273+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
38274+ zero distance codes, which is sent as one code of zero bits in
38275+ length.
38276+ 6. There are up to 286 literal/length codes. Code 256 represents the
38277+ end-of-block. Note however that the static length tree defines
38278+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
38279+ cannot be used though, since there is no length base or extra bits
38280+ defined for them. Similarily, there are up to 30 distance codes.
38281+ However, static trees define 32 codes (all 5 bits) to fill out the
38282+ Huffman codes, but the last two had better not show up in the data.
38283+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
38284+ The exception is that a single code would not be complete (see #4).
38285+ 8. The five bits following the block type is really the number of
38286+ literal codes sent minus 257.
38287+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
38288+ (1+6+6). Therefore, to output three times the length, you output
38289+ three codes (1+1+1), whereas to output four times the same length,
38290+ you only need two codes (1+3). Hmm.
38291+ 10. In the tree reconstruction algorithm, Code = Code + Increment
38292+ only if BitLength(i) is not zero. (Pretty obvious.)
38293+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
38294+ 12. Note: length code 284 can represent 227-258, but length code 285
38295+ really is 258. The last length deserves its own, short code
38296+ since it gets used a lot in very redundant files. The length
38297+ 258 is special since 258 - 3 (the min match length) is 255.
38298+ 13. The literal/length and distance code bit lengths are read as a
38299+ single stream of lengths. It is possible (and advantageous) for
38300+ a repeat code (16, 17, or 18) to go across the boundary between
38301+ the two sets of lengths.
38302+ */
38303+
38304+
38305+void inflate_blocks_reset(s, z, c)
38306+inflate_blocks_statef *s;
38307+z_streamp z;
38308+uLongf *c;
38309+{
38310+ if (c != Z_NULL)
38311+ *c = s->check;
38312+ if (s->mode == BTREE || s->mode == DTREE)
38313+ ZFREE(z, s->sub.trees.blens);
38314+ if (s->mode == CODES)
38315+ inflate_codes_free(s->sub.decode.codes, z);
38316+ s->mode = TYPE;
38317+ s->bitk = 0;
38318+ s->bitb = 0;
38319+ s->read = s->write = s->window;
38320+ if (s->checkfn != Z_NULL)
38321+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
38322+ Tracev((stderr, "inflate: blocks reset\n"));
38323+}
38324+
38325+
38326+inflate_blocks_statef *inflate_blocks_new(z, c, w)
38327+z_streamp z;
38328+check_func c;
38329+uInt w;
38330+{
38331+ inflate_blocks_statef *s;
38332+
38333+ if ((s = (inflate_blocks_statef *)ZALLOC
38334+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
38335+ return s;
38336+ if ((s->hufts =
38337+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
38338+ {
38339+ ZFREE(z, s);
38340+ return Z_NULL;
38341+ }
38342+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
38343+ {
38344+ ZFREE(z, s->hufts);
38345+ ZFREE(z, s);
38346+ return Z_NULL;
38347+ }
38348+ s->end = s->window + w;
38349+ s->checkfn = c;
38350+ s->mode = TYPE;
38351+ Tracev((stderr, "inflate: blocks allocated\n"));
38352+ inflate_blocks_reset(s, z, Z_NULL);
38353+ return s;
38354+}
38355+
38356+
38357+int inflate_blocks(s, z, r)
38358+inflate_blocks_statef *s;
38359+z_streamp z;
38360+int r;
38361+{
38362+ uInt t; /* temporary storage */
38363+ uLong b; /* bit buffer */
38364+ uInt k; /* bits in bit buffer */
38365+ Bytef *p; /* input data pointer */
38366+ uInt n; /* bytes available there */
38367+ Bytef *q; /* output window write pointer */
38368+ uInt m; /* bytes to end of window or read pointer */
38369+
38370+ /* copy input/output information to locals (UPDATE macro restores) */
38371+ LOAD
38372+
38373+ /* process input based on current state */
38374+ while (1) switch (s->mode)
38375+ {
38376+ case TYPE:
38377+ NEEDBITS(3)
38378+ t = (uInt)b & 7;
38379+ s->last = t & 1;
38380+ switch (t >> 1)
38381+ {
38382+ case 0: /* stored */
38383+ Tracev((stderr, "inflate: stored block%s\n",
38384+ s->last ? " (last)" : ""));
38385+ DUMPBITS(3)
38386+ t = k & 7; /* go to byte boundary */
38387+ DUMPBITS(t)
38388+ s->mode = LENS; /* get length of stored block */
38389+ break;
38390+ case 1: /* fixed */
38391+ Tracev((stderr, "inflate: fixed codes block%s\n",
38392+ s->last ? " (last)" : ""));
38393+ {
38394+ uInt bl, bd;
38395+ inflate_huft *tl, *td;
38396+
38397+ inflate_trees_fixed(&bl, &bd, &tl, &td, z);
38398+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
38399+ if (s->sub.decode.codes == Z_NULL)
38400+ {
38401+ r = Z_MEM_ERROR;
38402+ LEAVE
38403+ }
38404+ }
38405+ DUMPBITS(3)
38406+ s->mode = CODES;
38407+ break;
38408+ case 2: /* dynamic */
38409+ Tracev((stderr, "inflate: dynamic codes block%s\n",
38410+ s->last ? " (last)" : ""));
38411+ DUMPBITS(3)
38412+ s->mode = TABLE;
38413+ break;
38414+ case 3: /* illegal */
38415+ DUMPBITS(3)
38416+ s->mode = BAD;
38417+ z->msg = (char*)"invalid block type";
38418+ r = Z_DATA_ERROR;
38419+ LEAVE
38420+ }
38421+ break;
38422+ case LENS:
38423+ NEEDBITS(32)
38424+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
38425+ {
38426+ s->mode = BAD;
38427+ z->msg = (char*)"invalid stored block lengths";
38428+ r = Z_DATA_ERROR;
38429+ LEAVE
38430+ }
38431+ s->sub.left = (uInt)b & 0xffff;
38432+ b = k = 0; /* dump bits */
38433+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
38434+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
38435+ break;
38436+ case STORED:
38437+ if (n == 0)
38438+ LEAVE
38439+ NEEDOUT
38440+ t = s->sub.left;
38441+ if (t > n) t = n;
38442+ if (t > m) t = m;
38443+ zmemcpy(q, p, t);
38444+ p += t; n -= t;
38445+ q += t; m -= t;
38446+ if ((s->sub.left -= t) != 0)
38447+ break;
38448+ Tracev((stderr, "inflate: stored end, %lu total out\n",
38449+ z->total_out + (q >= s->read ? q - s->read :
38450+ (s->end - s->read) + (q - s->window))));
38451+ s->mode = s->last ? DRY : TYPE;
38452+ break;
38453+ case TABLE:
38454+ NEEDBITS(14)
38455+ s->sub.trees.table = t = (uInt)b & 0x3fff;
38456+#ifndef PKZIP_BUG_WORKAROUND
38457+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
38458+ {
38459+ s->mode = BAD;
38460+ z->msg = (char*)"too many length or distance symbols";
38461+ r = Z_DATA_ERROR;
38462+ LEAVE
38463+ }
38464+#endif
38465+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
38466+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
38467+ {
38468+ r = Z_MEM_ERROR;
38469+ LEAVE
38470+ }
38471+ DUMPBITS(14)
38472+ s->sub.trees.index = 0;
38473+ Tracev((stderr, "inflate: table sizes ok\n"));
38474+ s->mode = BTREE;
38475+ case BTREE:
38476+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
38477+ {
38478+ NEEDBITS(3)
38479+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
38480+ DUMPBITS(3)
38481+ }
38482+ while (s->sub.trees.index < 19)
38483+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
38484+ s->sub.trees.bb = 7;
38485+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
38486+ &s->sub.trees.tb, s->hufts, z);
38487+ if (t != Z_OK)
38488+ {
38489+ ZFREE(z, s->sub.trees.blens);
38490+ r = t;
38491+ if (r == Z_DATA_ERROR)
38492+ s->mode = BAD;
38493+ LEAVE
38494+ }
38495+ s->sub.trees.index = 0;
38496+ Tracev((stderr, "inflate: bits tree ok\n"));
38497+ s->mode = DTREE;
38498+ case DTREE:
38499+ while (t = s->sub.trees.table,
38500+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
38501+ {
38502+ inflate_huft *h;
38503+ uInt i, j, c;
38504+
38505+ t = s->sub.trees.bb;
38506+ NEEDBITS(t)
38507+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
38508+ t = h->bits;
38509+ c = h->base;
38510+ if (c < 16)
38511+ {
38512+ DUMPBITS(t)
38513+ s->sub.trees.blens[s->sub.trees.index++] = c;
38514+ }
38515+ else /* c == 16..18 */
38516+ {
38517+ i = c == 18 ? 7 : c - 14;
38518+ j = c == 18 ? 11 : 3;
38519+ NEEDBITS(t + i)
38520+ DUMPBITS(t)
38521+ j += (uInt)b & inflate_mask[i];
38522+ DUMPBITS(i)
38523+ i = s->sub.trees.index;
38524+ t = s->sub.trees.table;
38525+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
38526+ (c == 16 && i < 1))
38527+ {
38528+ ZFREE(z, s->sub.trees.blens);
38529+ s->mode = BAD;
38530+ z->msg = (char*)"invalid bit length repeat";
38531+ r = Z_DATA_ERROR;
38532+ LEAVE
38533+ }
38534+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
38535+ do {
38536+ s->sub.trees.blens[i++] = c;
38537+ } while (--j);
38538+ s->sub.trees.index = i;
38539+ }
38540+ }
38541+ s->sub.trees.tb = Z_NULL;
38542+ {
38543+ uInt bl, bd;
38544+ inflate_huft *tl, *td;
38545+ inflate_codes_statef *c;
38546+
38547+ bl = 9; /* must be <= 9 for lookahead assumptions */
38548+ bd = 6; /* must be <= 9 for lookahead assumptions */
38549+ t = s->sub.trees.table;
38550+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
38551+ s->sub.trees.blens, &bl, &bd, &tl, &td,
38552+ s->hufts, z);
38553+ ZFREE(z, s->sub.trees.blens);
38554+ if (t != Z_OK)
38555+ {
38556+ if (t == (uInt)Z_DATA_ERROR)
38557+ s->mode = BAD;
38558+ r = t;
38559+ LEAVE
38560+ }
38561+ Tracev((stderr, "inflate: trees ok\n"));
38562+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
38563+ {
38564+ r = Z_MEM_ERROR;
38565+ LEAVE
38566+ }
38567+ s->sub.decode.codes = c;
38568+ }
38569+ s->mode = CODES;
38570+ case CODES:
38571+ UPDATE
38572+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
38573+ return inflate_flush(s, z, r);
38574+ r = Z_OK;
38575+ inflate_codes_free(s->sub.decode.codes, z);
38576+ LOAD
38577+ Tracev((stderr, "inflate: codes end, %lu total out\n",
38578+ z->total_out + (q >= s->read ? q - s->read :
38579+ (s->end - s->read) + (q - s->window))));
38580+ if (!s->last)
38581+ {
38582+ s->mode = TYPE;
38583+ break;
38584+ }
38585+ s->mode = DRY;
38586+ case DRY:
38587+ FLUSH
38588+ if (s->read != s->write)
38589+ LEAVE
38590+ s->mode = DONE;
38591+ case DONE:
38592+ r = Z_STREAM_END;
38593+ LEAVE
38594+ case BAD:
38595+ r = Z_DATA_ERROR;
38596+ LEAVE
38597+ default:
38598+ r = Z_STREAM_ERROR;
38599+ LEAVE
38600+ }
38601+}
38602+
38603+
38604+int inflate_blocks_free(s, z)
38605+inflate_blocks_statef *s;
38606+z_streamp z;
38607+{
38608+ inflate_blocks_reset(s, z, Z_NULL);
38609+ ZFREE(z, s->window);
38610+ ZFREE(z, s->hufts);
38611+ ZFREE(z, s);
38612+ Tracev((stderr, "inflate: blocks freed\n"));
38613+ return Z_OK;
38614+}
38615+
38616+
38617+void inflate_set_dictionary(s, d, n)
38618+inflate_blocks_statef *s;
38619+const Bytef *d;
38620+uInt n;
38621+{
38622+ zmemcpy(s->window, d, n);
38623+ s->read = s->write = s->window + n;
38624+}
38625+
38626+
38627+/* Returns true if inflate is currently at the end of a block generated
38628+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
38629+ * IN assertion: s != Z_NULL
38630+ */
38631+int inflate_blocks_sync_point(s)
38632+inflate_blocks_statef *s;
38633+{
38634+ return s->mode == LENS;
38635+}
38636diff -druN linux-noipsec/net/ipsec/zlib/infblock.h linux/net/ipsec/zlib/infblock.h
38637--- linux-noipsec/net/ipsec/zlib/infblock.h Thu Jan 1 01:00:00 1970
38638+++ linux/net/ipsec/zlib/infblock.h Fri Sep 29 20:51:34 2000
38639@@ -0,0 +1,39 @@
38640+/* infblock.h -- header to use infblock.c
38641+ * Copyright (C) 1995-1998 Mark Adler
38642+ * For conditions of distribution and use, see copyright notice in zlib.h
38643+ */
38644+
38645+/* WARNING: this file should *not* be used by applications. It is
38646+ part of the implementation of the compression library and is
38647+ subject to change. Applications should only use zlib.h.
38648+ */
38649+
38650+struct inflate_blocks_state;
38651+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
38652+
38653+extern inflate_blocks_statef * inflate_blocks_new OF((
38654+ z_streamp z,
38655+ check_func c, /* check function */
38656+ uInt w)); /* window size */
38657+
38658+extern int inflate_blocks OF((
38659+ inflate_blocks_statef *,
38660+ z_streamp ,
38661+ int)); /* initial return code */
38662+
38663+extern void inflate_blocks_reset OF((
38664+ inflate_blocks_statef *,
38665+ z_streamp ,
38666+ uLongf *)); /* check value on output */
38667+
38668+extern int inflate_blocks_free OF((
38669+ inflate_blocks_statef *,
38670+ z_streamp));
38671+
38672+extern void inflate_set_dictionary OF((
38673+ inflate_blocks_statef *s,
38674+ const Bytef *d, /* dictionary */
38675+ uInt n)); /* dictionary length */
38676+
38677+extern int inflate_blocks_sync_point OF((
38678+ inflate_blocks_statef *s));
38679diff -druN linux-noipsec/net/ipsec/zlib/infcodes.c linux/net/ipsec/zlib/infcodes.c
38680--- linux-noipsec/net/ipsec/zlib/infcodes.c Thu Jan 1 01:00:00 1970
38681+++ linux/net/ipsec/zlib/infcodes.c Fri Sep 29 20:51:34 2000
38682@@ -0,0 +1,257 @@
38683+/* infcodes.c -- process literals and length/distance pairs
38684+ * Copyright (C) 1995-1998 Mark Adler
38685+ * For conditions of distribution and use, see copyright notice in zlib.h
38686+ */
38687+
38688+#include "zutil.h"
38689+#include "inftrees.h"
38690+#include "infblock.h"
38691+#include "infcodes.h"
38692+#include "infutil.h"
38693+#include "inffast.h"
38694+
38695+/* simplify the use of the inflate_huft type with some defines */
38696+#define exop word.what.Exop
38697+#define bits word.what.Bits
38698+
38699+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
38700+ START, /* x: set up for LEN */
38701+ LEN, /* i: get length/literal/eob next */
38702+ LENEXT, /* i: getting length extra (have base) */
38703+ DIST, /* i: get distance next */
38704+ DISTEXT, /* i: getting distance extra */
38705+ COPY, /* o: copying bytes in window, waiting for space */
38706+ LIT, /* o: got literal, waiting for output space */
38707+ WASH, /* o: got eob, possibly still output waiting */
38708+ END, /* x: got eob and all data flushed */
38709+ BADCODE} /* x: got error */
38710+inflate_codes_mode;
38711+
38712+/* inflate codes private state */
38713+struct inflate_codes_state {
38714+
38715+ /* mode */
38716+ inflate_codes_mode mode; /* current inflate_codes mode */
38717+
38718+ /* mode dependent information */
38719+ uInt len;
38720+ union {
38721+ struct {
38722+ inflate_huft *tree; /* pointer into tree */
38723+ uInt need; /* bits needed */
38724+ } code; /* if LEN or DIST, where in tree */
38725+ uInt lit; /* if LIT, literal */
38726+ struct {
38727+ uInt get; /* bits to get for extra */
38728+ uInt dist; /* distance back to copy from */
38729+ } copy; /* if EXT or COPY, where and how much */
38730+ } sub; /* submode */
38731+
38732+ /* mode independent information */
38733+ Byte lbits; /* ltree bits decoded per branch */
38734+ Byte dbits; /* dtree bits decoder per branch */
38735+ inflate_huft *ltree; /* literal/length/eob tree */
38736+ inflate_huft *dtree; /* distance tree */
38737+
38738+};
38739+
38740+
38741+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
38742+uInt bl, bd;
38743+inflate_huft *tl;
38744+inflate_huft *td; /* need separate declaration for Borland C++ */
38745+z_streamp z;
38746+{
38747+ inflate_codes_statef *c;
38748+
38749+ if ((c = (inflate_codes_statef *)
38750+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
38751+ {
38752+ c->mode = START;
38753+ c->lbits = (Byte)bl;
38754+ c->dbits = (Byte)bd;
38755+ c->ltree = tl;
38756+ c->dtree = td;
38757+ Tracev((stderr, "inflate: codes new\n"));
38758+ }
38759+ return c;
38760+}
38761+
38762+
38763+int inflate_codes(s, z, r)
38764+inflate_blocks_statef *s;
38765+z_streamp z;
38766+int r;
38767+{
38768+ uInt j; /* temporary storage */
38769+ inflate_huft *t; /* temporary pointer */
38770+ uInt e; /* extra bits or operation */
38771+ uLong b; /* bit buffer */
38772+ uInt k; /* bits in bit buffer */
38773+ Bytef *p; /* input data pointer */
38774+ uInt n; /* bytes available there */
38775+ Bytef *q; /* output window write pointer */
38776+ uInt m; /* bytes to end of window or read pointer */
38777+ Bytef *f; /* pointer to copy strings from */
38778+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
38779+
38780+ /* copy input/output information to locals (UPDATE macro restores) */
38781+ LOAD
38782+
38783+ /* process input and output based on current state */
38784+ while (1) switch (c->mode)
38785+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
38786+ case START: /* x: set up for LEN */
38787+#ifndef SLOW
38788+ if (m >= 258 && n >= 10)
38789+ {
38790+ UPDATE
38791+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
38792+ LOAD
38793+ if (r != Z_OK)
38794+ {
38795+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
38796+ break;
38797+ }
38798+ }
38799+#endif /* !SLOW */
38800+ c->sub.code.need = c->lbits;
38801+ c->sub.code.tree = c->ltree;
38802+ c->mode = LEN;
38803+ case LEN: /* i: get length/literal/eob next */
38804+ j = c->sub.code.need;
38805+ NEEDBITS(j)
38806+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
38807+ DUMPBITS(t->bits)
38808+ e = (uInt)(t->exop);
38809+ if (e == 0) /* literal */
38810+ {
38811+ c->sub.lit = t->base;
38812+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
38813+ "inflate: literal '%c'\n" :
38814+ "inflate: literal 0x%02x\n", t->base));
38815+ c->mode = LIT;
38816+ break;
38817+ }
38818+ if (e & 16) /* length */
38819+ {
38820+ c->sub.copy.get = e & 15;
38821+ c->len = t->base;
38822+ c->mode = LENEXT;
38823+ break;
38824+ }
38825+ if ((e & 64) == 0) /* next table */
38826+ {
38827+ c->sub.code.need = e;
38828+ c->sub.code.tree = t + t->base;
38829+ break;
38830+ }
38831+ if (e & 32) /* end of block */
38832+ {
38833+ Tracevv((stderr, "inflate: end of block\n"));
38834+ c->mode = WASH;
38835+ break;
38836+ }
38837+ c->mode = BADCODE; /* invalid code */
38838+ z->msg = (char*)"invalid literal/length code";
38839+ r = Z_DATA_ERROR;
38840+ LEAVE
38841+ case LENEXT: /* i: getting length extra (have base) */
38842+ j = c->sub.copy.get;
38843+ NEEDBITS(j)
38844+ c->len += (uInt)b & inflate_mask[j];
38845+ DUMPBITS(j)
38846+ c->sub.code.need = c->dbits;
38847+ c->sub.code.tree = c->dtree;
38848+ Tracevv((stderr, "inflate: length %u\n", c->len));
38849+ c->mode = DIST;
38850+ case DIST: /* i: get distance next */
38851+ j = c->sub.code.need;
38852+ NEEDBITS(j)
38853+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
38854+ DUMPBITS(t->bits)
38855+ e = (uInt)(t->exop);
38856+ if (e & 16) /* distance */
38857+ {
38858+ c->sub.copy.get = e & 15;
38859+ c->sub.copy.dist = t->base;
38860+ c->mode = DISTEXT;
38861+ break;
38862+ }
38863+ if ((e & 64) == 0) /* next table */
38864+ {
38865+ c->sub.code.need = e;
38866+ c->sub.code.tree = t + t->base;
38867+ break;
38868+ }
38869+ c->mode = BADCODE; /* invalid code */
38870+ z->msg = (char*)"invalid distance code";
38871+ r = Z_DATA_ERROR;
38872+ LEAVE
38873+ case DISTEXT: /* i: getting distance extra */
38874+ j = c->sub.copy.get;
38875+ NEEDBITS(j)
38876+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
38877+ DUMPBITS(j)
38878+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
38879+ c->mode = COPY;
38880+ case COPY: /* o: copying bytes in window, waiting for space */
38881+#ifndef __TURBOC__ /* Turbo C bug for following expression */
38882+ f = (uInt)(q - s->window) < c->sub.copy.dist ?
38883+ s->end - (c->sub.copy.dist - (q - s->window)) :
38884+ q - c->sub.copy.dist;
38885+#else
38886+ f = q - c->sub.copy.dist;
38887+ if ((uInt)(q - s->window) < c->sub.copy.dist)
38888+ f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
38889+#endif
38890+ while (c->len)
38891+ {
38892+ NEEDOUT
38893+ OUTBYTE(*f++)
38894+ if (f == s->end)
38895+ f = s->window;
38896+ c->len--;
38897+ }
38898+ c->mode = START;
38899+ break;
38900+ case LIT: /* o: got literal, waiting for output space */
38901+ NEEDOUT
38902+ OUTBYTE(c->sub.lit)
38903+ c->mode = START;
38904+ break;
38905+ case WASH: /* o: got eob, possibly more output */
38906+ if (k > 7) /* return unused byte, if any */
38907+ {
38908+ Assert(k < 16, "inflate_codes grabbed too many bytes")
38909+ k -= 8;
38910+ n++;
38911+ p--; /* can always return one */
38912+ }
38913+ FLUSH
38914+ if (s->read != s->write)
38915+ LEAVE
38916+ c->mode = END;
38917+ case END:
38918+ r = Z_STREAM_END;
38919+ LEAVE
38920+ case BADCODE: /* x: got error */
38921+ r = Z_DATA_ERROR;
38922+ LEAVE
38923+ default:
38924+ r = Z_STREAM_ERROR;
38925+ LEAVE
38926+ }
38927+#ifdef NEED_DUMMY_RETURN
38928+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
38929+#endif
38930+}
38931+
38932+
38933+void inflate_codes_free(c, z)
38934+inflate_codes_statef *c;
38935+z_streamp z;
38936+{
38937+ ZFREE(z, c);
38938+ Tracev((stderr, "inflate: codes free\n"));
38939+}
38940diff -druN linux-noipsec/net/ipsec/zlib/infcodes.h linux/net/ipsec/zlib/infcodes.h
38941--- linux-noipsec/net/ipsec/zlib/infcodes.h Thu Jan 1 01:00:00 1970
38942+++ linux/net/ipsec/zlib/infcodes.h Fri Sep 29 20:51:34 2000
38943@@ -0,0 +1,31 @@
38944+/* infcodes.h -- header to use infcodes.c
38945+ * Copyright (C) 1995-1998 Mark Adler
38946+ * For conditions of distribution and use, see copyright notice in zlib.h
38947+ */
38948+
38949+/* WARNING: this file should *not* be used by applications. It is
38950+ part of the implementation of the compression library and is
38951+ subject to change. Applications should only use zlib.h.
38952+ */
38953+
38954+#ifndef _INFCODES_H
38955+#define _INFCODES_H
38956+
38957+struct inflate_codes_state;
38958+typedef struct inflate_codes_state FAR inflate_codes_statef;
38959+
38960+extern inflate_codes_statef *inflate_codes_new OF((
38961+ uInt, uInt,
38962+ inflate_huft *, inflate_huft *,
38963+ z_streamp ));
38964+
38965+extern int inflate_codes OF((
38966+ inflate_blocks_statef *,
38967+ z_streamp ,
38968+ int));
38969+
38970+extern void inflate_codes_free OF((
38971+ inflate_codes_statef *,
38972+ z_streamp ));
38973+
38974+#endif /* _INFCODES_H */
38975diff -druN linux-noipsec/net/ipsec/zlib/inffast.c linux/net/ipsec/zlib/inffast.c
38976--- linux-noipsec/net/ipsec/zlib/inffast.c Thu Jan 1 01:00:00 1970
38977+++ linux/net/ipsec/zlib/inffast.c Fri Sep 29 20:51:34 2000
38978@@ -0,0 +1,170 @@
38979+/* inffast.c -- process literals and length/distance pairs fast
38980+ * Copyright (C) 1995-1998 Mark Adler
38981+ * For conditions of distribution and use, see copyright notice in zlib.h
38982+ */
38983+
38984+#include "zutil.h"
38985+#include "inftrees.h"
38986+#include "infblock.h"
38987+#include "infcodes.h"
38988+#include "infutil.h"
38989+#include "inffast.h"
38990+
38991+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
38992+
38993+/* simplify the use of the inflate_huft type with some defines */
38994+#define exop word.what.Exop
38995+#define bits word.what.Bits
38996+
38997+/* macros for bit input with no checking and for returning unused bytes */
38998+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
38999+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
39000+
39001+/* Called with number of bytes left to write in window at least 258
39002+ (the maximum string length) and number of input bytes available
39003+ at least ten. The ten bytes are six bytes for the longest length/
39004+ distance pair plus four bytes for overloading the bit buffer. */
39005+
39006+int inflate_fast(bl, bd, tl, td, s, z)
39007+uInt bl, bd;
39008+inflate_huft *tl;
39009+inflate_huft *td; /* need separate declaration for Borland C++ */
39010+inflate_blocks_statef *s;
39011+z_streamp z;
39012+{
39013+ inflate_huft *t; /* temporary pointer */
39014+ uInt e; /* extra bits or operation */
39015+ uLong b; /* bit buffer */
39016+ uInt k; /* bits in bit buffer */
39017+ Bytef *p; /* input data pointer */
39018+ uInt n; /* bytes available there */
39019+ Bytef *q; /* output window write pointer */
39020+ uInt m; /* bytes to end of window or read pointer */
39021+ uInt ml; /* mask for literal/length tree */
39022+ uInt md; /* mask for distance tree */
39023+ uInt c; /* bytes to copy */
39024+ uInt d; /* distance back to copy from */
39025+ Bytef *r; /* copy source pointer */
39026+
39027+ /* load input, output, bit values */
39028+ LOAD
39029+
39030+ /* initialize masks */
39031+ ml = inflate_mask[bl];
39032+ md = inflate_mask[bd];
39033+
39034+ /* do until not enough input or output space for fast loop */
39035+ do { /* assume called with m >= 258 && n >= 10 */
39036+ /* get literal/length code */
39037+ GRABBITS(20) /* max bits for literal/length code */
39038+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
39039+ {
39040+ DUMPBITS(t->bits)
39041+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
39042+ "inflate: * literal '%c'\n" :
39043+ "inflate: * literal 0x%02x\n", t->base));
39044+ *q++ = (Byte)t->base;
39045+ m--;
39046+ continue;
39047+ }
39048+ do {
39049+ DUMPBITS(t->bits)
39050+ if (e & 16)
39051+ {
39052+ /* get extra bits for length */
39053+ e &= 15;
39054+ c = t->base + ((uInt)b & inflate_mask[e]);
39055+ DUMPBITS(e)
39056+ Tracevv((stderr, "inflate: * length %u\n", c));
39057+
39058+ /* decode distance base of block to copy */
39059+ GRABBITS(15); /* max bits for distance code */
39060+ e = (t = td + ((uInt)b & md))->exop;
39061+ do {
39062+ DUMPBITS(t->bits)
39063+ if (e & 16)
39064+ {
39065+ /* get extra bits to add to distance base */
39066+ e &= 15;
39067+ GRABBITS(e) /* get extra bits (up to 13) */
39068+ d = t->base + ((uInt)b & inflate_mask[e]);
39069+ DUMPBITS(e)
39070+ Tracevv((stderr, "inflate: * distance %u\n", d));
39071+
39072+ /* do the copy */
39073+ m -= c;
39074+ if ((uInt)(q - s->window) >= d) /* offset before dest */
39075+ { /* just copy */
39076+ r = q - d;
39077+ *q++ = *r++; c--; /* minimum count is three, */
39078+ *q++ = *r++; c--; /* so unroll loop a little */
39079+ }
39080+ else /* else offset after destination */
39081+ {
39082+ e = d - (uInt)(q - s->window); /* bytes from offset to end */
39083+ r = s->end - e; /* pointer to offset */
39084+ if (c > e) /* if source crosses, */
39085+ {
39086+ c -= e; /* copy to end of window */
39087+ do {
39088+ *q++ = *r++;
39089+ } while (--e);
39090+ r = s->window; /* copy rest from start of window */
39091+ }
39092+ }
39093+ do { /* copy all or what's left */
39094+ *q++ = *r++;
39095+ } while (--c);
39096+ break;
39097+ }
39098+ else if ((e & 64) == 0)
39099+ {
39100+ t += t->base;
39101+ e = (t += ((uInt)b & inflate_mask[e]))->exop;
39102+ }
39103+ else
39104+ {
39105+ z->msg = (char*)"invalid distance code";
39106+ UNGRAB
39107+ UPDATE
39108+ return Z_DATA_ERROR;
39109+ }
39110+ } while (1);
39111+ break;
39112+ }
39113+ if ((e & 64) == 0)
39114+ {
39115+ t += t->base;
39116+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
39117+ {
39118+ DUMPBITS(t->bits)
39119+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
39120+ "inflate: * literal '%c'\n" :
39121+ "inflate: * literal 0x%02x\n", t->base));
39122+ *q++ = (Byte)t->base;
39123+ m--;
39124+ break;
39125+ }
39126+ }
39127+ else if (e & 32)
39128+ {
39129+ Tracevv((stderr, "inflate: * end of block\n"));
39130+ UNGRAB
39131+ UPDATE
39132+ return Z_STREAM_END;
39133+ }
39134+ else
39135+ {
39136+ z->msg = (char*)"invalid literal/length code";
39137+ UNGRAB
39138+ UPDATE
39139+ return Z_DATA_ERROR;
39140+ }
39141+ } while (1);
39142+ } while (m >= 258 && n >= 10);
39143+
39144+ /* not enough input or output--restore pointers and return */
39145+ UNGRAB
39146+ UPDATE
39147+ return Z_OK;
39148+}
39149diff -druN linux-noipsec/net/ipsec/zlib/inffast.h linux/net/ipsec/zlib/inffast.h
39150--- linux-noipsec/net/ipsec/zlib/inffast.h Thu Jan 1 01:00:00 1970
39151+++ linux/net/ipsec/zlib/inffast.h Fri Sep 29 20:51:34 2000
39152@@ -0,0 +1,22 @@
39153+/* inffast.h -- header to use inffast.c
39154+ * Copyright (C) 1995-1998 Mark Adler
39155+ * For conditions of distribution and use, see copyright notice in zlib.h
39156+ */
39157+
39158+/* WARNING: this file should *not* be used by applications. It is
39159+ part of the implementation of the compression library and is
39160+ subject to change. Applications should only use zlib.h.
39161+ */
39162+
39163+#ifndef _INFFAST_H
39164+#define _INFFAST_H
39165+
39166+extern int inflate_fast OF((
39167+ uInt,
39168+ uInt,
39169+ inflate_huft *,
39170+ inflate_huft *,
39171+ inflate_blocks_statef *,
39172+ z_streamp ));
39173+
39174+#endif /* _INFFAST_H */
39175diff -druN linux-noipsec/net/ipsec/zlib/inffixed.h linux/net/ipsec/zlib/inffixed.h
39176--- linux-noipsec/net/ipsec/zlib/inffixed.h Thu Jan 1 01:00:00 1970
39177+++ linux/net/ipsec/zlib/inffixed.h Fri Sep 29 20:51:34 2000
39178@@ -0,0 +1,151 @@
39179+/* inffixed.h -- table for decoding fixed codes
39180+ * Generated automatically by the maketree.c program
39181+ */
39182+
39183+/* WARNING: this file should *not* be used by applications. It is
39184+ part of the implementation of the compression library and is
39185+ subject to change. Applications should only use zlib.h.
39186+ */
39187+
39188+local uInt fixed_bl = 9;
39189+local uInt fixed_bd = 5;
39190+local inflate_huft fixed_tl[] = {
39191+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
39192+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
39193+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
39194+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
39195+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
39196+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
39197+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
39198+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
39199+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
39200+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
39201+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
39202+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
39203+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
39204+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
39205+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
39206+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
39207+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
39208+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
39209+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
39210+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
39211+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
39212+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
39213+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
39214+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
39215+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
39216+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
39217+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
39218+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
39219+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
39220+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
39221+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
39222+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
39223+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
39224+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
39225+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
39226+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
39227+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
39228+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
39229+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
39230+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
39231+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
39232+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
39233+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
39234+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
39235+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
39236+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
39237+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
39238+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
39239+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
39240+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
39241+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
39242+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
39243+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
39244+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
39245+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
39246+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
39247+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
39248+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
39249+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
39250+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
39251+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
39252+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
39253+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
39254+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
39255+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
39256+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
39257+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
39258+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
39259+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
39260+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
39261+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
39262+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
39263+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
39264+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
39265+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
39266+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
39267+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
39268+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
39269+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
39270+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
39271+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
39272+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
39273+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
39274+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
39275+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
39276+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
39277+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
39278+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
39279+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
39280+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
39281+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
39282+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
39283+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
39284+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
39285+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
39286+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
39287+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
39288+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
39289+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
39290+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
39291+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
39292+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
39293+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
39294+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
39295+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
39296+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
39297+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
39298+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
39299+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
39300+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
39301+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
39302+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
39303+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
39304+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
39305+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
39306+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
39307+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
39308+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
39309+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
39310+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
39311+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
39312+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
39313+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
39314+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
39315+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
39316+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
39317+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
39318+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
39319+ };
39320+local inflate_huft fixed_td[] = {
39321+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
39322+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
39323+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
39324+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
39325+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
39326+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
39327+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
39328+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
39329+ };
39330diff -druN linux-noipsec/net/ipsec/zlib/inflate.c linux/net/ipsec/zlib/inflate.c
39331--- linux-noipsec/net/ipsec/zlib/inflate.c Thu Jan 1 01:00:00 1970
39332+++ linux/net/ipsec/zlib/inflate.c Fri Sep 29 20:51:34 2000
39333@@ -0,0 +1,368 @@
39334+/* inflate.c -- zlib interface to inflate modules
39335+ * Copyright (C) 1995-1998 Mark Adler
39336+ * For conditions of distribution and use, see copyright notice in zlib.h
39337+ */
39338+
39339+#include "zutil.h"
39340+#include "infblock.h"
39341+
39342+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
39343+
39344+typedef enum {
39345+ METHOD, /* waiting for method byte */
39346+ FLAG, /* waiting for flag byte */
39347+ DICT4, /* four dictionary check bytes to go */
39348+ DICT3, /* three dictionary check bytes to go */
39349+ DICT2, /* two dictionary check bytes to go */
39350+ DICT1, /* one dictionary check byte to go */
39351+ DICT0, /* waiting for inflateSetDictionary */
39352+ BLOCKS, /* decompressing blocks */
39353+ CHECK4, /* four check bytes to go */
39354+ CHECK3, /* three check bytes to go */
39355+ CHECK2, /* two check bytes to go */
39356+ CHECK1, /* one check byte to go */
39357+ DONE, /* finished check, done */
39358+ BAD} /* got an error--stay here */
39359+inflate_mode;
39360+
39361+/* inflate private state */
39362+struct internal_state {
39363+
39364+ /* mode */
39365+ inflate_mode mode; /* current inflate mode */
39366+
39367+ /* mode dependent information */
39368+ union {
39369+ uInt method; /* if FLAGS, method byte */
39370+ struct {
39371+ uLong was; /* computed check value */
39372+ uLong need; /* stream check value */
39373+ } check; /* if CHECK, check values to compare */
39374+ uInt marker; /* if BAD, inflateSync's marker bytes count */
39375+ } sub; /* submode */
39376+
39377+ /* mode independent information */
39378+ int nowrap; /* flag for no wrapper */
39379+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
39380+ inflate_blocks_statef
39381+ *blocks; /* current inflate_blocks state */
39382+
39383+};
39384+
39385+
39386+int ZEXPORT inflateReset(z)
39387+z_streamp z;
39388+{
39389+ if (z == Z_NULL || z->state == Z_NULL)
39390+ return Z_STREAM_ERROR;
39391+ z->total_in = z->total_out = 0;
39392+ z->msg = Z_NULL;
39393+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
39394+ inflate_blocks_reset(z->state->blocks, z, Z_NULL);
39395+ Tracev((stderr, "inflate: reset\n"));
39396+ return Z_OK;
39397+}
39398+
39399+
39400+int ZEXPORT inflateEnd(z)
39401+z_streamp z;
39402+{
39403+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
39404+ return Z_STREAM_ERROR;
39405+ if (z->state->blocks != Z_NULL)
39406+ inflate_blocks_free(z->state->blocks, z);
39407+ ZFREE(z, z->state);
39408+ z->state = Z_NULL;
39409+ Tracev((stderr, "inflate: end\n"));
39410+ return Z_OK;
39411+}
39412+
39413+
39414+int ZEXPORT inflateInit2_(z, w, version, stream_size)
39415+z_streamp z;
39416+int w;
39417+const char *version;
39418+int stream_size;
39419+{
39420+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
39421+ stream_size != sizeof(z_stream))
39422+ return Z_VERSION_ERROR;
39423+
39424+ /* initialize state */
39425+ if (z == Z_NULL)
39426+ return Z_STREAM_ERROR;
39427+ z->msg = Z_NULL;
39428+ if (z->zalloc == Z_NULL)
39429+ {
39430+ return Z_STREAM_ERROR;
39431+/* z->zalloc = zcalloc;
39432+ z->opaque = (voidpf)0;
39433+*/
39434+ }
39435+ if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
39436+ if ((z->state = (struct internal_state FAR *)
39437+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
39438+ return Z_MEM_ERROR;
39439+ z->state->blocks = Z_NULL;
39440+
39441+ /* handle undocumented nowrap option (no zlib header or check) */
39442+ z->state->nowrap = 0;
39443+ if (w < 0)
39444+ {
39445+ w = - w;
39446+ z->state->nowrap = 1;
39447+ }
39448+
39449+ /* set window size */
39450+ if (w < 8 || w > 15)
39451+ {
39452+ inflateEnd(z);
39453+ return Z_STREAM_ERROR;
39454+ }
39455+ z->state->wbits = (uInt)w;
39456+
39457+ /* create inflate_blocks state */
39458+ if ((z->state->blocks =
39459+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
39460+ == Z_NULL)
39461+ {
39462+ inflateEnd(z);
39463+ return Z_MEM_ERROR;
39464+ }
39465+ Tracev((stderr, "inflate: allocated\n"));
39466+
39467+ /* reset state */
39468+ inflateReset(z);
39469+ return Z_OK;
39470+}
39471+
39472+
39473+int ZEXPORT inflateInit_(z, version, stream_size)
39474+z_streamp z;
39475+const char *version;
39476+int stream_size;
39477+{
39478+ return inflateInit2_(z, DEF_WBITS, version, stream_size);
39479+}
39480+
39481+
39482+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
39483+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
39484+
39485+int ZEXPORT inflate(z, f)
39486+z_streamp z;
39487+int f;
39488+{
39489+ int r;
39490+ uInt b;
39491+
39492+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
39493+ return Z_STREAM_ERROR;
39494+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
39495+ r = Z_BUF_ERROR;
39496+ while (1) switch (z->state->mode)
39497+ {
39498+ case METHOD:
39499+ NEEDBYTE
39500+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
39501+ {
39502+ z->state->mode = BAD;
39503+ z->msg = (char*)"unknown compression method";
39504+ z->state->sub.marker = 5; /* can't try inflateSync */
39505+ break;
39506+ }
39507+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
39508+ {
39509+ z->state->mode = BAD;
39510+ z->msg = (char*)"invalid window size";
39511+ z->state->sub.marker = 5; /* can't try inflateSync */
39512+ break;
39513+ }
39514+ z->state->mode = FLAG;
39515+ case FLAG:
39516+ NEEDBYTE
39517+ b = NEXTBYTE;
39518+ if (((z->state->sub.method << 8) + b) % 31)
39519+ {
39520+ z->state->mode = BAD;
39521+ z->msg = (char*)"incorrect header check";
39522+ z->state->sub.marker = 5; /* can't try inflateSync */
39523+ break;
39524+ }
39525+ Tracev((stderr, "inflate: zlib header ok\n"));
39526+ if (!(b & PRESET_DICT))
39527+ {
39528+ z->state->mode = BLOCKS;
39529+ break;
39530+ }
39531+ z->state->mode = DICT4;
39532+ case DICT4:
39533+ NEEDBYTE
39534+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
39535+ z->state->mode = DICT3;
39536+ case DICT3:
39537+ NEEDBYTE
39538+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
39539+ z->state->mode = DICT2;
39540+ case DICT2:
39541+ NEEDBYTE
39542+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
39543+ z->state->mode = DICT1;
39544+ case DICT1:
39545+ NEEDBYTE
39546+ z->state->sub.check.need += (uLong)NEXTBYTE;
39547+ z->adler = z->state->sub.check.need;
39548+ z->state->mode = DICT0;
39549+ return Z_NEED_DICT;
39550+ case DICT0:
39551+ z->state->mode = BAD;
39552+ z->msg = (char*)"need dictionary";
39553+ z->state->sub.marker = 0; /* can try inflateSync */
39554+ return Z_STREAM_ERROR;
39555+ case BLOCKS:
39556+ r = inflate_blocks(z->state->blocks, z, r);
39557+ if (r == Z_DATA_ERROR)
39558+ {
39559+ z->state->mode = BAD;
39560+ z->state->sub.marker = 0; /* can try inflateSync */
39561+ break;
39562+ }
39563+ if (r == Z_OK)
39564+ r = f;
39565+ if (r != Z_STREAM_END)
39566+ return r;
39567+ r = f;
39568+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
39569+ if (z->state->nowrap)
39570+ {
39571+ z->state->mode = DONE;
39572+ break;
39573+ }
39574+ z->state->mode = CHECK4;
39575+ case CHECK4:
39576+ NEEDBYTE
39577+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
39578+ z->state->mode = CHECK3;
39579+ case CHECK3:
39580+ NEEDBYTE
39581+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
39582+ z->state->mode = CHECK2;
39583+ case CHECK2:
39584+ NEEDBYTE
39585+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
39586+ z->state->mode = CHECK1;
39587+ case CHECK1:
39588+ NEEDBYTE
39589+ z->state->sub.check.need += (uLong)NEXTBYTE;
39590+
39591+ if (z->state->sub.check.was != z->state->sub.check.need)
39592+ {
39593+ z->state->mode = BAD;
39594+ z->msg = (char*)"incorrect data check";
39595+ z->state->sub.marker = 5; /* can't try inflateSync */
39596+ break;
39597+ }
39598+ Tracev((stderr, "inflate: zlib check ok\n"));
39599+ z->state->mode = DONE;
39600+ case DONE:
39601+ return Z_STREAM_END;
39602+ case BAD:
39603+ return Z_DATA_ERROR;
39604+ default:
39605+ return Z_STREAM_ERROR;
39606+ }
39607+#ifdef NEED_DUMMY_RETURN
39608+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
39609+#endif
39610+}
39611+
39612+
39613+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
39614+z_streamp z;
39615+const Bytef *dictionary;
39616+uInt dictLength;
39617+{
39618+ uInt length = dictLength;
39619+
39620+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
39621+ return Z_STREAM_ERROR;
39622+
39623+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
39624+ z->adler = 1L;
39625+
39626+ if (length >= ((uInt)1<<z->state->wbits))
39627+ {
39628+ length = (1<<z->state->wbits)-1;
39629+ dictionary += dictLength - length;
39630+ }
39631+ inflate_set_dictionary(z->state->blocks, dictionary, length);
39632+ z->state->mode = BLOCKS;
39633+ return Z_OK;
39634+}
39635+
39636+
39637+int ZEXPORT inflateSync(z)
39638+z_streamp z;
39639+{
39640+ uInt n; /* number of bytes to look at */
39641+ Bytef *p; /* pointer to bytes */
39642+ uInt m; /* number of marker bytes found in a row */
39643+ uLong r, w; /* temporaries to save total_in and total_out */
39644+
39645+ /* set up */
39646+ if (z == Z_NULL || z->state == Z_NULL)
39647+ return Z_STREAM_ERROR;
39648+ if (z->state->mode != BAD)
39649+ {
39650+ z->state->mode = BAD;
39651+ z->state->sub.marker = 0;
39652+ }
39653+ if ((n = z->avail_in) == 0)
39654+ return Z_BUF_ERROR;
39655+ p = z->next_in;
39656+ m = z->state->sub.marker;
39657+
39658+ /* search */
39659+ while (n && m < 4)
39660+ {
39661+ static const Byte mark[4] = {0, 0, 0xff, 0xff};
39662+ if (*p == mark[m])
39663+ m++;
39664+ else if (*p)
39665+ m = 0;
39666+ else
39667+ m = 4 - m;
39668+ p++, n--;
39669+ }
39670+
39671+ /* restore */
39672+ z->total_in += p - z->next_in;
39673+ z->next_in = p;
39674+ z->avail_in = n;
39675+ z->state->sub.marker = m;
39676+
39677+ /* return no joy or set up to restart on a new block */
39678+ if (m != 4)
39679+ return Z_DATA_ERROR;
39680+ r = z->total_in; w = z->total_out;
39681+ inflateReset(z);
39682+ z->total_in = r; z->total_out = w;
39683+ z->state->mode = BLOCKS;
39684+ return Z_OK;
39685+}
39686+
39687+
39688+/* Returns true if inflate is currently at the end of a block generated
39689+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
39690+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
39691+ * but removes the length bytes of the resulting empty stored block. When
39692+ * decompressing, PPP checks that at the end of input packet, inflate is
39693+ * waiting for these length bytes.
39694+ */
39695+int ZEXPORT inflateSyncPoint(z)
39696+z_streamp z;
39697+{
39698+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
39699+ return Z_STREAM_ERROR;
39700+ return inflate_blocks_sync_point(z->state->blocks);
39701+}
39702diff -druN linux-noipsec/net/ipsec/zlib/inftrees.c linux/net/ipsec/zlib/inftrees.c
39703--- linux-noipsec/net/ipsec/zlib/inftrees.c Thu Jan 1 01:00:00 1970
39704+++ linux/net/ipsec/zlib/inftrees.c Fri Sep 29 20:51:34 2000
39705@@ -0,0 +1,455 @@
39706+/* inftrees.c -- generate Huffman trees for efficient decoding
39707+ * Copyright (C) 1995-1998 Mark Adler
39708+ * For conditions of distribution and use, see copyright notice in zlib.h
39709+ */
39710+
39711+#include "zutil.h"
39712+#include "inftrees.h"
39713+
39714+#if !defined(BUILDFIXED) && !defined(STDC)
39715+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
39716+#endif
39717+
39718+local const char inflate_copyright[] =
39719+ " inflate 1.1.3 Copyright 1995-1998 Mark Adler ";
39720+/*
39721+ If you use the zlib library in a product, an acknowledgment is welcome
39722+ in the documentation of your product. If for some reason you cannot
39723+ include such an acknowledgment, I would appreciate that you keep this
39724+ copyright string in the executable of your product.
39725+ */
39726+struct internal_state {int dummy;}; /* for buggy compilers */
39727+
39728+/* simplify the use of the inflate_huft type with some defines */
39729+#define exop word.what.Exop
39730+#define bits word.what.Bits
39731+
39732+
39733+local int huft_build OF((
39734+ uIntf *, /* code lengths in bits */
39735+ uInt, /* number of codes */
39736+ uInt, /* number of "simple" codes */
39737+ const uIntf *, /* list of base values for non-simple codes */
39738+ const uIntf *, /* list of extra bits for non-simple codes */
39739+ inflate_huft * FAR*,/* result: starting table */
39740+ uIntf *, /* maximum lookup bits (returns actual) */
39741+ inflate_huft *, /* space for trees */
39742+ uInt *, /* hufts used in space */
39743+ uIntf * )); /* space for values */
39744+
39745+/* Tables for deflate from PKZIP's appnote.txt. */
39746+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
39747+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
39748+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
39749+ /* see note #13 above about 258 */
39750+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
39751+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
39752+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
39753+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
39754+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
39755+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
39756+ 8193, 12289, 16385, 24577};
39757+local const uInt cpdext[30] = { /* Extra bits for distance codes */
39758+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
39759+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
39760+ 12, 12, 13, 13};
39761+
39762+/*
39763+ Huffman code decoding is performed using a multi-level table lookup.
39764+ The fastest way to decode is to simply build a lookup table whose
39765+ size is determined by the longest code. However, the time it takes
39766+ to build this table can also be a factor if the data being decoded
39767+ is not very long. The most common codes are necessarily the
39768+ shortest codes, so those codes dominate the decoding time, and hence
39769+ the speed. The idea is you can have a shorter table that decodes the
39770+ shorter, more probable codes, and then point to subsidiary tables for
39771+ the longer codes. The time it costs to decode the longer codes is
39772+ then traded against the time it takes to make longer tables.
39773+
39774+ This results of this trade are in the variables lbits and dbits
39775+ below. lbits is the number of bits the first level table for literal/
39776+ length codes can decode in one step, and dbits is the same thing for
39777+ the distance codes. Subsequent tables are also less than or equal to
39778+ those sizes. These values may be adjusted either when all of the
39779+ codes are shorter than that, in which case the longest code length in
39780+ bits is used, or when the shortest code is *longer* than the requested
39781+ table size, in which case the length of the shortest code in bits is
39782+ used.
39783+
39784+ There are two different values for the two tables, since they code a
39785+ different number of possibilities each. The literal/length table
39786+ codes 286 possible values, or in a flat code, a little over eight
39787+ bits. The distance table codes 30 possible values, or a little less
39788+ than five bits, flat. The optimum values for speed end up being
39789+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
39790+ The optimum values may differ though from machine to machine, and
39791+ possibly even between compilers. Your mileage may vary.
39792+ */
39793+
39794+
39795+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
39796+#define BMAX 15 /* maximum bit length of any code */
39797+
39798+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
39799+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
39800+uInt n; /* number of codes (assumed <= 288) */
39801+uInt s; /* number of simple-valued codes (0..s-1) */
39802+const uIntf *d; /* list of base values for non-simple codes */
39803+const uIntf *e; /* list of extra bits for non-simple codes */
39804+inflate_huft * FAR *t; /* result: starting table */
39805+uIntf *m; /* maximum lookup bits, returns actual */
39806+inflate_huft *hp; /* space for trees */
39807+uInt *hn; /* hufts used in space */
39808+uIntf *v; /* working area: values in order of bit length */
39809+/* Given a list of code lengths and a maximum table size, make a set of
39810+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
39811+ if the given code set is incomplete (the tables are still built in this
39812+ case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
39813+ lengths), or Z_MEM_ERROR if not enough memory. */
39814+{
39815+
39816+ uInt a; /* counter for codes of length k */
39817+ uInt c[BMAX+1]; /* bit length count table */
39818+ uInt f; /* i repeats in table every f entries */
39819+ int g; /* maximum code length */
39820+ int h; /* table level */
39821+ register uInt i; /* counter, current code */
39822+ register uInt j; /* counter */
39823+ register int k; /* number of bits in current code */
39824+ int l; /* bits per table (returned in m) */
39825+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
39826+ register uIntf *p; /* pointer into c[], b[], or v[] */
39827+ inflate_huft *q; /* points to current table */
39828+ struct inflate_huft_s r; /* table entry for structure assignment */
39829+ inflate_huft *u[BMAX]; /* table stack */
39830+ register int w; /* bits before this table == (l * h) */
39831+ uInt x[BMAX+1]; /* bit offsets, then code stack */
39832+ uIntf *xp; /* pointer into x */
39833+ int y; /* number of dummy codes added */
39834+ uInt z; /* number of entries in current table */
39835+
39836+
39837+ /* Generate counts for each bit length */
39838+ p = c;
39839+#define C0 *p++ = 0;
39840+#define C2 C0 C0 C0 C0
39841+#define C4 C2 C2 C2 C2
39842+ C4 /* clear c[]--assume BMAX+1 is 16 */
39843+ p = b; i = n;
39844+ do {
39845+ c[*p++]++; /* assume all entries <= BMAX */
39846+ } while (--i);
39847+ if (c[0] == n) /* null input--all zero length codes */
39848+ {
39849+ *t = (inflate_huft *)Z_NULL;
39850+ *m = 0;
39851+ return Z_OK;
39852+ }
39853+
39854+
39855+ /* Find minimum and maximum length, bound *m by those */
39856+ l = *m;
39857+ for (j = 1; j <= BMAX; j++)
39858+ if (c[j])
39859+ break;
39860+ k = j; /* minimum code length */
39861+ if ((uInt)l < j)
39862+ l = j;
39863+ for (i = BMAX; i; i--)
39864+ if (c[i])
39865+ break;
39866+ g = i; /* maximum code length */
39867+ if ((uInt)l > i)
39868+ l = i;
39869+ *m = l;
39870+
39871+
39872+ /* Adjust last length count to fill out codes, if needed */
39873+ for (y = 1 << j; j < i; j++, y <<= 1)
39874+ if ((y -= c[j]) < 0)
39875+ return Z_DATA_ERROR;
39876+ if ((y -= c[i]) < 0)
39877+ return Z_DATA_ERROR;
39878+ c[i] += y;
39879+
39880+
39881+ /* Generate starting offsets into the value table for each length */
39882+ x[1] = j = 0;
39883+ p = c + 1; xp = x + 2;
39884+ while (--i) { /* note that i == g from above */
39885+ *xp++ = (j += *p++);
39886+ }
39887+
39888+
39889+ /* Make a table of values in order of bit lengths */
39890+ p = b; i = 0;
39891+ do {
39892+ if ((j = *p++) != 0)
39893+ v[x[j]++] = i;
39894+ } while (++i < n);
39895+ n = x[g]; /* set n to length of v */
39896+
39897+
39898+ /* Generate the Huffman codes and for each, make the table entries */
39899+ x[0] = i = 0; /* first Huffman code is zero */
39900+ p = v; /* grab values in bit order */
39901+ h = -1; /* no tables yet--level -1 */
39902+ w = -l; /* bits decoded == (l * h) */
39903+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
39904+ q = (inflate_huft *)Z_NULL; /* ditto */
39905+ z = 0; /* ditto */
39906+
39907+ /* go through the bit lengths (k already is bits in shortest code) */
39908+ for (; k <= g; k++)
39909+ {
39910+ a = c[k];
39911+ while (a--)
39912+ {
39913+ /* here i is the Huffman code of length k bits for value *p */
39914+ /* make tables up to required level */
39915+ while (k > w + l)
39916+ {
39917+ h++;
39918+ w += l; /* previous table always l bits */
39919+
39920+ /* compute minimum size table less than or equal to l bits */
39921+ z = g - w;
39922+ z = z > (uInt)l ? l : z; /* table size upper limit */
39923+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
39924+ { /* too few codes for k-w bit table */
39925+ f -= a + 1; /* deduct codes from patterns left */
39926+ xp = c + k;
39927+ if (j < z)
39928+ while (++j < z) /* try smaller tables up to z bits */
39929+ {
39930+ if ((f <<= 1) <= *++xp)
39931+ break; /* enough codes to use up j bits */
39932+ f -= *xp; /* else deduct codes from patterns */
39933+ }
39934+ }
39935+ z = 1 << j; /* table entries for j-bit table */
39936+
39937+ /* allocate new table */
39938+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
39939+ return Z_MEM_ERROR; /* not enough memory */
39940+ u[h] = q = hp + *hn;
39941+ *hn += z;
39942+
39943+ /* connect to last table, if there is one */
39944+ if (h)
39945+ {
39946+ x[h] = i; /* save pattern for backing up */
39947+ r.bits = (Byte)l; /* bits to dump before this table */
39948+ r.exop = (Byte)j; /* bits in this table */
39949+ j = i >> (w - l);
39950+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
39951+ u[h-1][j] = r; /* connect to last table */
39952+ }
39953+ else
39954+ *t = q; /* first table is returned result */
39955+ }
39956+
39957+ /* set up table entry in r */
39958+ r.bits = (Byte)(k - w);
39959+ if (p >= v + n)
39960+ r.exop = 128 + 64; /* out of values--invalid code */
39961+ else if (*p < s)
39962+ {
39963+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
39964+ r.base = *p++; /* simple code is just the value */
39965+ }
39966+ else
39967+ {
39968+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
39969+ r.base = d[*p++ - s];
39970+ }
39971+
39972+ /* fill code-like entries with r */
39973+ f = 1 << (k - w);
39974+ for (j = i >> w; j < z; j += f)
39975+ q[j] = r;
39976+
39977+ /* backwards increment the k-bit code i */
39978+ for (j = 1 << (k - 1); i & j; j >>= 1)
39979+ i ^= j;
39980+ i ^= j;
39981+
39982+ /* backup over finished tables */
39983+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */
39984+ while ((i & mask) != x[h])
39985+ {
39986+ h--; /* don't need to update q */
39987+ w -= l;
39988+ mask = (1 << w) - 1;
39989+ }
39990+ }
39991+ }
39992+
39993+
39994+ /* Return Z_BUF_ERROR if we were given an incomplete table */
39995+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
39996+}
39997+
39998+
39999+int inflate_trees_bits(c, bb, tb, hp, z)
40000+uIntf *c; /* 19 code lengths */
40001+uIntf *bb; /* bits tree desired/actual depth */
40002+inflate_huft * FAR *tb; /* bits tree result */
40003+inflate_huft *hp; /* space for trees */
40004+z_streamp z; /* for messages */
40005+{
40006+ int r;
40007+ uInt hn = 0; /* hufts used in space */
40008+ uIntf *v; /* work area for huft_build */
40009+
40010+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
40011+ return Z_MEM_ERROR;
40012+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
40013+ tb, bb, hp, &hn, v);
40014+ if (r == Z_DATA_ERROR)
40015+ z->msg = (char*)"oversubscribed dynamic bit lengths tree";
40016+ else if (r == Z_BUF_ERROR || *bb == 0)
40017+ {
40018+ z->msg = (char*)"incomplete dynamic bit lengths tree";
40019+ r = Z_DATA_ERROR;
40020+ }
40021+ ZFREE(z, v);
40022+ return r;
40023+}
40024+
40025+
40026+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
40027+uInt nl; /* number of literal/length codes */
40028+uInt nd; /* number of distance codes */
40029+uIntf *c; /* that many (total) code lengths */
40030+uIntf *bl; /* literal desired/actual bit depth */
40031+uIntf *bd; /* distance desired/actual bit depth */
40032+inflate_huft * FAR *tl; /* literal/length tree result */
40033+inflate_huft * FAR *td; /* distance tree result */
40034+inflate_huft *hp; /* space for trees */
40035+z_streamp z; /* for messages */
40036+{
40037+ int r;
40038+ uInt hn = 0; /* hufts used in space */
40039+ uIntf *v; /* work area for huft_build */
40040+
40041+ /* allocate work area */
40042+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
40043+ return Z_MEM_ERROR;
40044+
40045+ /* build literal/length tree */
40046+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
40047+ if (r != Z_OK || *bl == 0)
40048+ {
40049+ if (r == Z_DATA_ERROR)
40050+ z->msg = (char*)"oversubscribed literal/length tree";
40051+ else if (r != Z_MEM_ERROR)
40052+ {
40053+ z->msg = (char*)"incomplete literal/length tree";
40054+ r = Z_DATA_ERROR;
40055+ }
40056+ ZFREE(z, v);
40057+ return r;
40058+ }
40059+
40060+ /* build distance tree */
40061+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
40062+ if (r != Z_OK || (*bd == 0 && nl > 257))
40063+ {
40064+ if (r == Z_DATA_ERROR)
40065+ z->msg = (char*)"oversubscribed distance tree";
40066+ else if (r == Z_BUF_ERROR) {
40067+#ifdef PKZIP_BUG_WORKAROUND
40068+ r = Z_OK;
40069+ }
40070+#else
40071+ z->msg = (char*)"incomplete distance tree";
40072+ r = Z_DATA_ERROR;
40073+ }
40074+ else if (r != Z_MEM_ERROR)
40075+ {
40076+ z->msg = (char*)"empty distance tree with lengths";
40077+ r = Z_DATA_ERROR;
40078+ }
40079+ ZFREE(z, v);
40080+ return r;
40081+#endif
40082+ }
40083+
40084+ /* done */
40085+ ZFREE(z, v);
40086+ return Z_OK;
40087+}
40088+
40089+
40090+/* build fixed tables only once--keep them here */
40091+#ifdef BUILDFIXED
40092+local int fixed_built = 0;
40093+#define FIXEDH 544 /* number of hufts used by fixed tables */
40094+local inflate_huft fixed_mem[FIXEDH];
40095+local uInt fixed_bl;
40096+local uInt fixed_bd;
40097+local inflate_huft *fixed_tl;
40098+local inflate_huft *fixed_td;
40099+#else
40100+#include "inffixed.h"
40101+#endif
40102+
40103+
40104+int inflate_trees_fixed(bl, bd, tl, td, z)
40105+uIntf *bl; /* literal desired/actual bit depth */
40106+uIntf *bd; /* distance desired/actual bit depth */
40107+inflate_huft * FAR *tl; /* literal/length tree result */
40108+inflate_huft * FAR *td; /* distance tree result */
40109+z_streamp z; /* for memory allocation */
40110+{
40111+#ifdef BUILDFIXED
40112+ /* build fixed tables if not already */
40113+ if (!fixed_built)
40114+ {
40115+ int k; /* temporary variable */
40116+ uInt f = 0; /* number of hufts used in fixed_mem */
40117+ uIntf *c; /* length list for huft_build */
40118+ uIntf *v; /* work area for huft_build */
40119+
40120+ /* allocate memory */
40121+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
40122+ return Z_MEM_ERROR;
40123+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
40124+ {
40125+ ZFREE(z, c);
40126+ return Z_MEM_ERROR;
40127+ }
40128+
40129+ /* literal table */
40130+ for (k = 0; k < 144; k++)
40131+ c[k] = 8;
40132+ for (; k < 256; k++)
40133+ c[k] = 9;
40134+ for (; k < 280; k++)
40135+ c[k] = 7;
40136+ for (; k < 288; k++)
40137+ c[k] = 8;
40138+ fixed_bl = 9;
40139+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
40140+ fixed_mem, &f, v);
40141+
40142+ /* distance table */
40143+ for (k = 0; k < 30; k++)
40144+ c[k] = 5;
40145+ fixed_bd = 5;
40146+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
40147+ fixed_mem, &f, v);
40148+
40149+ /* done */
40150+ ZFREE(z, v);
40151+ ZFREE(z, c);
40152+ fixed_built = 1;
40153+ }
40154+#endif
40155+ *bl = fixed_bl;
40156+ *bd = fixed_bd;
40157+ *tl = fixed_tl;
40158+ *td = fixed_td;
40159+ return Z_OK;
40160+}
40161diff -druN linux-noipsec/net/ipsec/zlib/inftrees.h linux/net/ipsec/zlib/inftrees.h
40162--- linux-noipsec/net/ipsec/zlib/inftrees.h Thu Jan 1 01:00:00 1970
40163+++ linux/net/ipsec/zlib/inftrees.h Fri Sep 29 20:51:34 2000
40164@@ -0,0 +1,63 @@
40165+/* inftrees.h -- header to use inftrees.c
40166+ * Copyright (C) 1995-1998 Mark Adler
40167+ * For conditions of distribution and use, see copyright notice in zlib.h
40168+ */
40169+
40170+/* WARNING: this file should *not* be used by applications. It is
40171+ part of the implementation of the compression library and is
40172+ subject to change. Applications should only use zlib.h.
40173+ */
40174+
40175+/* Huffman code lookup table entry--this entry is four bytes for machines
40176+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
40177+
40178+#ifndef _INFTREES_H
40179+#define _INFTREES_H
40180+
40181+typedef struct inflate_huft_s FAR inflate_huft;
40182+
40183+struct inflate_huft_s {
40184+ union {
40185+ struct {
40186+ Byte Exop; /* number of extra bits or operation */
40187+ Byte Bits; /* number of bits in this code or subcode */
40188+ } what;
40189+ uInt pad; /* pad structure to a power of 2 (4 bytes for */
40190+ } word; /* 16-bit, 8 bytes for 32-bit int's) */
40191+ uInt base; /* literal, length base, distance base,
40192+ or table offset */
40193+};
40194+
40195+/* Maximum size of dynamic tree. The maximum found in a long but non-
40196+ exhaustive search was 1004 huft structures (850 for length/literals
40197+ and 154 for distances, the latter actually the result of an
40198+ exhaustive search). The actual maximum is not known, but the
40199+ value below is more than safe. */
40200+#define MANY 1440
40201+
40202+extern int inflate_trees_bits OF((
40203+ uIntf *, /* 19 code lengths */
40204+ uIntf *, /* bits tree desired/actual depth */
40205+ inflate_huft * FAR *, /* bits tree result */
40206+ inflate_huft *, /* space for trees */
40207+ z_streamp)); /* for messages */
40208+
40209+extern int inflate_trees_dynamic OF((
40210+ uInt, /* number of literal/length codes */
40211+ uInt, /* number of distance codes */
40212+ uIntf *, /* that many (total) code lengths */
40213+ uIntf *, /* literal desired/actual bit depth */
40214+ uIntf *, /* distance desired/actual bit depth */
40215+ inflate_huft * FAR *, /* literal/length tree result */
40216+ inflate_huft * FAR *, /* distance tree result */
40217+ inflate_huft *, /* space for trees */
40218+ z_streamp)); /* for messages */
40219+
40220+extern int inflate_trees_fixed OF((
40221+ uIntf *, /* literal desired/actual bit depth */
40222+ uIntf *, /* distance desired/actual bit depth */
40223+ inflate_huft * FAR *, /* literal/length tree result */
40224+ inflate_huft * FAR *, /* distance tree result */
40225+ z_streamp)); /* for memory allocation */
40226+
40227+#endif /* _INFTREES_H */
40228diff -druN linux-noipsec/net/ipsec/zlib/infutil.c linux/net/ipsec/zlib/infutil.c
40229--- linux-noipsec/net/ipsec/zlib/infutil.c Thu Jan 1 01:00:00 1970
40230+++ linux/net/ipsec/zlib/infutil.c Fri Sep 29 20:51:34 2000
40231@@ -0,0 +1,87 @@
40232+/* inflate_util.c -- data and routines common to blocks and codes
40233+ * Copyright (C) 1995-1998 Mark Adler
40234+ * For conditions of distribution and use, see copyright notice in zlib.h
40235+ */
40236+
40237+#include "zutil.h"
40238+#include "infblock.h"
40239+#include "inftrees.h"
40240+#include "infcodes.h"
40241+#include "infutil.h"
40242+
40243+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
40244+
40245+/* And'ing with mask[n] masks the lower n bits */
40246+uInt inflate_mask[17] = {
40247+ 0x0000,
40248+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
40249+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
40250+};
40251+
40252+
40253+/* copy as much as possible from the sliding window to the output area */
40254+int inflate_flush(s, z, r)
40255+inflate_blocks_statef *s;
40256+z_streamp z;
40257+int r;
40258+{
40259+ uInt n;
40260+ Bytef *p;
40261+ Bytef *q;
40262+
40263+ /* local copies of source and destination pointers */
40264+ p = z->next_out;
40265+ q = s->read;
40266+
40267+ /* compute number of bytes to copy as far as end of window */
40268+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
40269+ if (n > z->avail_out) n = z->avail_out;
40270+ if (n && r == Z_BUF_ERROR) r = Z_OK;
40271+
40272+ /* update counters */
40273+ z->avail_out -= n;
40274+ z->total_out += n;
40275+
40276+ /* update check information */
40277+ if (s->checkfn != Z_NULL)
40278+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
40279+
40280+ /* copy as far as end of window */
40281+ zmemcpy(p, q, n);
40282+ p += n;
40283+ q += n;
40284+
40285+ /* see if more to copy at beginning of window */
40286+ if (q == s->end)
40287+ {
40288+ /* wrap pointers */
40289+ q = s->window;
40290+ if (s->write == s->end)
40291+ s->write = s->window;
40292+
40293+ /* compute bytes to copy */
40294+ n = (uInt)(s->write - q);
40295+ if (n > z->avail_out) n = z->avail_out;
40296+ if (n && r == Z_BUF_ERROR) r = Z_OK;
40297+
40298+ /* update counters */
40299+ z->avail_out -= n;
40300+ z->total_out += n;
40301+
40302+ /* update check information */
40303+ if (s->checkfn != Z_NULL)
40304+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
40305+
40306+ /* copy */
40307+ zmemcpy(p, q, n);
40308+ p += n;
40309+ q += n;
40310+ }
40311+
40312+ /* update pointers */
40313+ z->next_out = p;
40314+ s->read = q;
40315+
40316+ /* done */
40317+ return r;
40318+}
40319diff -druN linux-noipsec/net/ipsec/zlib/infutil.h linux/net/ipsec/zlib/infutil.h
40320--- linux-noipsec/net/ipsec/zlib/infutil.h Thu Jan 1 01:00:00 1970
40321+++ linux/net/ipsec/zlib/infutil.h Fri Sep 29 20:51:34 2000
40322@@ -0,0 +1,98 @@
40323+/* infutil.h -- types and macros common to blocks and codes
40324+ * Copyright (C) 1995-1998 Mark Adler
40325+ * For conditions of distribution and use, see copyright notice in zlib.h
40326+ */
40327+
40328+/* WARNING: this file should *not* be used by applications. It is
40329+ part of the implementation of the compression library and is
40330+ subject to change. Applications should only use zlib.h.
40331+ */
40332+
40333+#ifndef _INFUTIL_H
40334+#define _INFUTIL_H
40335+
40336+typedef enum {
40337+ TYPE, /* get type bits (3, including end bit) */
40338+ LENS, /* get lengths for stored */
40339+ STORED, /* processing stored block */
40340+ TABLE, /* get table lengths */
40341+ BTREE, /* get bit lengths tree for a dynamic block */
40342+ DTREE, /* get length, distance trees for a dynamic block */
40343+ CODES, /* processing fixed or dynamic block */
40344+ DRY, /* output remaining window bytes */
40345+ DONE, /* finished last block, done */
40346+ BAD} /* got a data error--stuck here */
40347+inflate_block_mode;
40348+
40349+/* inflate blocks semi-private state */
40350+struct inflate_blocks_state {
40351+
40352+ /* mode */
40353+ inflate_block_mode mode; /* current inflate_block mode */
40354+
40355+ /* mode dependent information */
40356+ union {
40357+ uInt left; /* if STORED, bytes left to copy */
40358+ struct {
40359+ uInt table; /* table lengths (14 bits) */
40360+ uInt index; /* index into blens (or border) */
40361+ uIntf *blens; /* bit lengths of codes */
40362+ uInt bb; /* bit length tree depth */
40363+ inflate_huft *tb; /* bit length decoding tree */
40364+ } trees; /* if DTREE, decoding info for trees */
40365+ struct {
40366+ inflate_codes_statef
40367+ *codes;
40368+ } decode; /* if CODES, current state */
40369+ } sub; /* submode */
40370+ uInt last; /* true if this block is the last block */
40371+
40372+ /* mode independent information */
40373+ uInt bitk; /* bits in bit buffer */
40374+ uLong bitb; /* bit buffer */
40375+ inflate_huft *hufts; /* single malloc for tree space */
40376+ Bytef *window; /* sliding window */
40377+ Bytef *end; /* one byte after sliding window */
40378+ Bytef *read; /* window read pointer */
40379+ Bytef *write; /* window write pointer */
40380+ check_func checkfn; /* check function */
40381+ uLong check; /* check on output */
40382+
40383+};
40384+
40385+
40386+/* defines for inflate input/output */
40387+/* update pointers and return */
40388+#define UPDBITS {s->bitb=b;s->bitk=k;}
40389+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
40390+#define UPDOUT {s->write=q;}
40391+#define UPDATE {UPDBITS UPDIN UPDOUT}
40392+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
40393+/* get bytes and bits */
40394+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
40395+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
40396+#define NEXTBYTE (n--,*p++)
40397+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
40398+#define DUMPBITS(j) {b>>=(j);k-=(j);}
40399+/* output bytes */
40400+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
40401+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
40402+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
40403+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
40404+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
40405+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
40406+/* load local pointers */
40407+#define LOAD {LOADIN LOADOUT}
40408+
40409+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
40410+extern uInt inflate_mask[17];
40411+
40412+/* copy as much as possible from the sliding window to the output area */
40413+extern int inflate_flush OF((
40414+ inflate_blocks_statef *,
40415+ z_streamp ,
40416+ int));
40417+
40418+struct internal_state {int dummy;}; /* for buggy compilers */
40419+
40420+#endif /* _INFUTIL_H */
40421diff -druN linux-noipsec/net/ipsec/zlib/match586.S linux/net/ipsec/zlib/match586.S
40422--- linux-noipsec/net/ipsec/zlib/match586.S Thu Jan 1 01:00:00 1970
40423+++ linux/net/ipsec/zlib/match586.S Fri Sep 29 20:51:34 2000
40424@@ -0,0 +1,357 @@
40425+/* match.s -- Pentium-optimized version of longest_match()
40426+ * Written for zlib 1.1.2
40427+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
40428+ *
40429+ * This is free software; you can redistribute it and/or modify it
40430+ * under the terms of the GNU General Public License.
40431+ */
40432+
40433+#ifndef NO_UNDERLINE
40434+#define match_init _ipcomp_match_init
40435+#define longest_match _ipcomp_longest_match
40436+#else
40437+#define match_init ipcomp_match_init
40438+#define longest_match ipcomp_longest_match
40439+#endif
40440+
40441+#define MAX_MATCH (258)
40442+#define MIN_MATCH (3)
40443+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
40444+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
40445+
40446+/* stack frame offsets */
40447+
40448+#define wmask 0 /* local copy of s->wmask */
40449+#define window 4 /* local copy of s->window */
40450+#define windowbestlen 8 /* s->window + bestlen */
40451+#define chainlenscanend 12 /* high word: current chain len */
40452+ /* low word: last bytes sought */
40453+#define scanstart 16 /* first two bytes of string */
40454+#define scanalign 20 /* dword-misalignment of string */
40455+#define nicematch 24 /* a good enough match size */
40456+#define bestlen 28 /* size of best match so far */
40457+#define scan 32 /* ptr to string wanting match */
40458+
40459+#define LocalVarsSize (36)
40460+/* saved ebx 36 */
40461+/* saved edi 40 */
40462+/* saved esi 44 */
40463+/* saved ebp 48 */
40464+/* return address 52 */
40465+#define deflatestate 56 /* the function arguments */
40466+#define curmatch 60
40467+
40468+/* Offsets for fields in the deflate_state structure. These numbers
40469+ * are calculated from the definition of deflate_state, with the
40470+ * assumption that the compiler will dword-align the fields. (Thus,
40471+ * changing the definition of deflate_state could easily cause this
40472+ * program to crash horribly, without so much as a warning at
40473+ * compile time. Sigh.)
40474+ */
40475+#define dsWSize 36
40476+#define dsWMask 44
40477+#define dsWindow 48
40478+#define dsPrev 56
40479+#define dsMatchLen 88
40480+#define dsPrevMatch 92
40481+#define dsStrStart 100
40482+#define dsMatchStart 104
40483+#define dsLookahead 108
40484+#define dsPrevLen 112
40485+#define dsMaxChainLen 116
40486+#define dsGoodMatch 132
40487+#define dsNiceMatch 136
40488+
40489+
40490+.file "match.S"
40491+
40492+.globl match_init, longest_match
40493+
40494+.text
40495+
40496+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
40497+
40498+longest_match:
40499+
40500+/* Save registers that the compiler may be using, and adjust %esp to */
40501+/* make room for our stack frame. */
40502+
40503+ pushl %ebp
40504+ pushl %edi
40505+ pushl %esi
40506+ pushl %ebx
40507+ subl $LocalVarsSize, %esp
40508+
40509+/* Retrieve the function arguments. %ecx will hold cur_match */
40510+/* throughout the entire function. %edx will hold the pointer to the */
40511+/* deflate_state structure during the function's setup (before */
40512+/* entering the main loop). */
40513+
40514+ movl deflatestate(%esp), %edx
40515+ movl curmatch(%esp), %ecx
40516+
40517+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
40518+
40519+ movl dsNiceMatch(%edx), %eax
40520+ movl dsLookahead(%edx), %ebx
40521+ cmpl %eax, %ebx
40522+ jl LookaheadLess
40523+ movl %eax, %ebx
40524+LookaheadLess: movl %ebx, nicematch(%esp)
40525+
40526+/* register Bytef *scan = s->window + s->strstart; */
40527+
40528+ movl dsWindow(%edx), %esi
40529+ movl %esi, window(%esp)
40530+ movl dsStrStart(%edx), %ebp
40531+ lea (%esi,%ebp), %edi
40532+ movl %edi, scan(%esp)
40533+
40534+/* Determine how many bytes the scan ptr is off from being */
40535+/* dword-aligned. */
40536+
40537+ movl %edi, %eax
40538+ negl %eax
40539+ andl $3, %eax
40540+ movl %eax, scanalign(%esp)
40541+
40542+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
40543+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
40544+
40545+ movl dsWSize(%edx), %eax
40546+ subl $MIN_LOOKAHEAD, %eax
40547+ subl %eax, %ebp
40548+ jg LimitPositive
40549+ xorl %ebp, %ebp
40550+LimitPositive:
40551+
40552+/* unsigned chain_length = s->max_chain_length; */
40553+/* if (s->prev_length >= s->good_match) { */
40554+/* chain_length >>= 2; */
40555+/* } */
40556+
40557+ movl dsPrevLen(%edx), %eax
40558+ movl dsGoodMatch(%edx), %ebx
40559+ cmpl %ebx, %eax
40560+ movl dsMaxChainLen(%edx), %ebx
40561+ jl LastMatchGood
40562+ shrl $2, %ebx
40563+LastMatchGood:
40564+
40565+/* chainlen is decremented once beforehand so that the function can */
40566+/* use the sign flag instead of the zero flag for the exit test. */
40567+/* It is then shifted into the high word, to make room for the scanend */
40568+/* scanend value, which it will always accompany. */
40569+
40570+ decl %ebx
40571+ shll $16, %ebx
40572+
40573+/* int best_len = s->prev_length; */
40574+
40575+ movl dsPrevLen(%edx), %eax
40576+ movl %eax, bestlen(%esp)
40577+
40578+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
40579+
40580+ addl %eax, %esi
40581+ movl %esi, windowbestlen(%esp)
40582+
40583+/* register ush scan_start = *(ushf*)scan; */
40584+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
40585+
40586+ movw (%edi), %bx
40587+ movw %bx, scanstart(%esp)
40588+ movw -1(%edi,%eax), %bx
40589+ movl %ebx, chainlenscanend(%esp)
40590+
40591+/* Posf *prev = s->prev; */
40592+/* uInt wmask = s->w_mask; */
40593+
40594+ movl dsPrev(%edx), %edi
40595+ movl dsWMask(%edx), %edx
40596+ mov %edx, wmask(%esp)
40597+
40598+/* Jump into the main loop. */
40599+
40600+ jmp LoopEntry
40601+
40602+.balign 16
40603+
40604+/* do {
40605+ * match = s->window + cur_match;
40606+ * if (*(ushf*)(match+best_len-1) != scan_end ||
40607+ * *(ushf*)match != scan_start) continue;
40608+ * [...]
40609+ * } while ((cur_match = prev[cur_match & wmask]) > limit
40610+ * && --chain_length != 0);
40611+ *
40612+ * Here is the inner loop of the function. The function will spend the
40613+ * majority of its time in this loop, and majority of that time will
40614+ * be spent in the first ten instructions.
40615+ *
40616+ * Within this loop:
40617+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
40618+ * %ecx = curmatch
40619+ * %edx = curmatch & wmask
40620+ * %esi = windowbestlen - i.e., (window + bestlen)
40621+ * %edi = prev
40622+ * %ebp = limit
40623+ *
40624+ * Two optimization notes on the choice of instructions:
40625+ *
40626+ * The first instruction uses a 16-bit address, which costs an extra,
40627+ * unpairable cycle. This is cheaper than doing a 32-bit access and
40628+ * zeroing the high word, due to the 3-cycle misalignment penalty which
40629+ * would occur half the time. This also turns out to be cheaper than
40630+ * doing two separate 8-bit accesses, as the memory is so rarely in the
40631+ * L1 cache.
40632+ *
40633+ * The window buffer, however, apparently spends a lot of time in the
40634+ * cache, and so it is faster to retrieve the word at the end of the
40635+ * match string with two 8-bit loads. The instructions that test the
40636+ * word at the beginning of the match string, however, are executed
40637+ * much less frequently, and there it was cheaper to use 16-bit
40638+ * instructions, which avoided the necessity of saving off and
40639+ * subsequently reloading one of the other registers.
40640+ */
40641+LookupLoop:
40642+ /* 1 U & V */
40643+ movw (%edi,%edx,2), %cx /* 2 U pipe */
40644+ movl wmask(%esp), %edx /* 2 V pipe */
40645+ cmpl %ebp, %ecx /* 3 U pipe */
40646+ jbe LeaveNow /* 3 V pipe */
40647+ subl $0x00010000, %ebx /* 4 U pipe */
40648+ js LeaveNow /* 4 V pipe */
40649+LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
40650+ andl %ecx, %edx /* 5 V pipe */
40651+ cmpb %bl, %al /* 6 U pipe */
40652+ jnz LookupLoop /* 6 V pipe */
40653+ movb (%esi,%ecx), %ah
40654+ cmpb %bh, %ah
40655+ jnz LookupLoop
40656+ movl window(%esp), %eax
40657+ movw (%eax,%ecx), %ax
40658+ cmpw scanstart(%esp), %ax
40659+ jnz LookupLoop
40660+
40661+/* Store the current value of chainlen. */
40662+
40663+ movl %ebx, chainlenscanend(%esp)
40664+
40665+/* Point %edi to the string under scrutiny, and %esi to the string we */
40666+/* are hoping to match it up with. In actuality, %esi and %edi are */
40667+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
40668+/* initialized to -(MAX_MATCH_8 - scanalign). */
40669+
40670+ movl window(%esp), %esi
40671+ movl scan(%esp), %edi
40672+ addl %ecx, %esi
40673+ movl scanalign(%esp), %eax
40674+ movl $(-MAX_MATCH_8), %edx
40675+ lea MAX_MATCH_8(%edi,%eax), %edi
40676+ lea MAX_MATCH_8(%esi,%eax), %esi
40677+
40678+/* Test the strings for equality, 8 bytes at a time. At the end,
40679+ * adjust %edx so that it is offset to the exact byte that mismatched.
40680+ *
40681+ * We already know at this point that the first three bytes of the
40682+ * strings match each other, and they can be safely passed over before
40683+ * starting the compare loop. So what this code does is skip over 0-3
40684+ * bytes, as much as necessary in order to dword-align the %edi
40685+ * pointer. (%esi will still be misaligned three times out of four.)
40686+ *
40687+ * It should be confessed that this loop usually does not represent
40688+ * much of the total running time. Replacing it with a more
40689+ * straightforward "rep cmpsb" would not drastically degrade
40690+ * performance.
40691+ */
40692+LoopCmps:
40693+ movl (%esi,%edx), %eax
40694+ movl (%edi,%edx), %ebx
40695+ xorl %ebx, %eax
40696+ jnz LeaveLoopCmps
40697+ movl 4(%esi,%edx), %eax
40698+ movl 4(%edi,%edx), %ebx
40699+ xorl %ebx, %eax
40700+ jnz LeaveLoopCmps4
40701+ addl $8, %edx
40702+ jnz LoopCmps
40703+ jmp LenMaximum
40704+LeaveLoopCmps4: addl $4, %edx
40705+LeaveLoopCmps: testl $0x0000FFFF, %eax
40706+ jnz LenLower
40707+ addl $2, %edx
40708+ shrl $16, %eax
40709+LenLower: subb $1, %al
40710+ adcl $0, %edx
40711+
40712+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
40713+/* then automatically accept it as the best possible match and leave. */
40714+
40715+ lea (%edi,%edx), %eax
40716+ movl scan(%esp), %edi
40717+ subl %edi, %eax
40718+ cmpl $MAX_MATCH, %eax
40719+ jge LenMaximum
40720+
40721+/* If the length of the match is not longer than the best match we */
40722+/* have so far, then forget it and return to the lookup loop. */
40723+
40724+ movl deflatestate(%esp), %edx
40725+ movl bestlen(%esp), %ebx
40726+ cmpl %ebx, %eax
40727+ jg LongerMatch
40728+ movl chainlenscanend(%esp), %ebx
40729+ movl windowbestlen(%esp), %esi
40730+ movl dsPrev(%edx), %edi
40731+ movl wmask(%esp), %edx
40732+ andl %ecx, %edx
40733+ jmp LookupLoop
40734+
40735+/* s->match_start = cur_match; */
40736+/* best_len = len; */
40737+/* if (len >= nice_match) break; */
40738+/* scan_end = *(ushf*)(scan+best_len-1); */
40739+
40740+LongerMatch: movl nicematch(%esp), %ebx
40741+ movl %eax, bestlen(%esp)
40742+ movl %ecx, dsMatchStart(%edx)
40743+ cmpl %ebx, %eax
40744+ jge LeaveNow
40745+ movl window(%esp), %esi
40746+ addl %eax, %esi
40747+ movl %esi, windowbestlen(%esp)
40748+ movl chainlenscanend(%esp), %ebx
40749+ movw -1(%edi,%eax), %bx
40750+ movl dsPrev(%edx), %edi
40751+ movl %ebx, chainlenscanend(%esp)
40752+ movl wmask(%esp), %edx
40753+ andl %ecx, %edx
40754+ jmp LookupLoop
40755+
40756+/* Accept the current string, with the maximum possible length. */
40757+
40758+LenMaximum: movl deflatestate(%esp), %edx
40759+ movl $MAX_MATCH, bestlen(%esp)
40760+ movl %ecx, dsMatchStart(%edx)
40761+
40762+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
40763+/* return s->lookahead; */
40764+
40765+LeaveNow:
40766+ movl deflatestate(%esp), %edx
40767+ movl bestlen(%esp), %ebx
40768+ movl dsLookahead(%edx), %eax
40769+ cmpl %eax, %ebx
40770+ jg LookaheadRet
40771+ movl %ebx, %eax
40772+LookaheadRet:
40773+
40774+/* Restore the stack and return from whence we came. */
40775+
40776+ addl $LocalVarsSize, %esp
40777+ popl %ebx
40778+ popl %esi
40779+ popl %edi
40780+ popl %ebp
40781+match_init: ret
40782diff -druN linux-noipsec/net/ipsec/zlib/match686.S linux/net/ipsec/zlib/match686.S
40783--- linux-noipsec/net/ipsec/zlib/match686.S Thu Jan 1 01:00:00 1970
40784+++ linux/net/ipsec/zlib/match686.S Fri Oct 27 05:35:16 2000
40785@@ -0,0 +1,330 @@
40786+/* match.s -- Pentium-Pro-optimized version of longest_match()
40787+ * Written for zlib 1.1.2
40788+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
40789+ *
40790+ * This is free software; you can redistribute it and/or modify it
40791+ * under the terms of the GNU General Public License.
40792+ */
40793+
40794+#ifndef NO_UNDERLINE
40795+#define match_init _ipcomp_match_init
40796+#define longest_match _ipcomp_longest_match
40797+#else
40798+#define match_init ipcomp_match_init
40799+#define longest_match ipcomp_longest_match
40800+#endif
40801+
40802+#define MAX_MATCH (258)
40803+#define MIN_MATCH (3)
40804+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
40805+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
40806+
40807+/* stack frame offsets */
40808+
40809+#define chainlenwmask 0 /* high word: current chain len */
40810+ /* low word: s->wmask */
40811+#define window 4 /* local copy of s->window */
40812+#define windowbestlen 8 /* s->window + bestlen */
40813+#define scanstart 16 /* first two bytes of string */
40814+#define scanend 12 /* last two bytes of string */
40815+#define scanalign 20 /* dword-misalignment of string */
40816+#define nicematch 24 /* a good enough match size */
40817+#define bestlen 28 /* size of best match so far */
40818+#define scan 32 /* ptr to string wanting match */
40819+
40820+#define LocalVarsSize (36)
40821+/* saved ebx 36 */
40822+/* saved edi 40 */
40823+/* saved esi 44 */
40824+/* saved ebp 48 */
40825+/* return address 52 */
40826+#define deflatestate 56 /* the function arguments */
40827+#define curmatch 60
40828+
40829+/* Offsets for fields in the deflate_state structure. These numbers
40830+ * are calculated from the definition of deflate_state, with the
40831+ * assumption that the compiler will dword-align the fields. (Thus,
40832+ * changing the definition of deflate_state could easily cause this
40833+ * program to crash horribly, without so much as a warning at
40834+ * compile time. Sigh.)
40835+ */
40836+#define dsWSize 36
40837+#define dsWMask 44
40838+#define dsWindow 48
40839+#define dsPrev 56
40840+#define dsMatchLen 88
40841+#define dsPrevMatch 92
40842+#define dsStrStart 100
40843+#define dsMatchStart 104
40844+#define dsLookahead 108
40845+#define dsPrevLen 112
40846+#define dsMaxChainLen 116
40847+#define dsGoodMatch 132
40848+#define dsNiceMatch 136
40849+
40850+
40851+.file "match.S"
40852+
40853+.globl match_init, longest_match
40854+
40855+.text
40856+
40857+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
40858+
40859+longest_match:
40860+
40861+/* Save registers that the compiler may be using, and adjust %esp to */
40862+/* make room for our stack frame. */
40863+
40864+ pushl %ebp
40865+ pushl %edi
40866+ pushl %esi
40867+ pushl %ebx
40868+ subl $LocalVarsSize, %esp
40869+
40870+/* Retrieve the function arguments. %ecx will hold cur_match */
40871+/* throughout the entire function. %edx will hold the pointer to the */
40872+/* deflate_state structure during the function's setup (before */
40873+/* entering the main loop). */
40874+
40875+ movl deflatestate(%esp), %edx
40876+ movl curmatch(%esp), %ecx
40877+
40878+/* uInt wmask = s->w_mask; */
40879+/* unsigned chain_length = s->max_chain_length; */
40880+/* if (s->prev_length >= s->good_match) { */
40881+/* chain_length >>= 2; */
40882+/* } */
40883+
40884+ movl dsPrevLen(%edx), %eax
40885+ movl dsGoodMatch(%edx), %ebx
40886+ cmpl %ebx, %eax
40887+ movl dsWMask(%edx), %eax
40888+ movl dsMaxChainLen(%edx), %ebx
40889+ jl LastMatchGood
40890+ shrl $2, %ebx
40891+LastMatchGood:
40892+
40893+/* chainlen is decremented once beforehand so that the function can */
40894+/* use the sign flag instead of the zero flag for the exit test. */
40895+/* It is then shifted into the high word, to make room for the wmask */
40896+/* value, which it will always accompany. */
40897+
40898+ decl %ebx
40899+ shll $16, %ebx
40900+ orl %eax, %ebx
40901+ movl %ebx, chainlenwmask(%esp)
40902+
40903+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
40904+
40905+ movl dsNiceMatch(%edx), %eax
40906+ movl dsLookahead(%edx), %ebx
40907+ cmpl %eax, %ebx
40908+ jl LookaheadLess
40909+ movl %eax, %ebx
40910+LookaheadLess: movl %ebx, nicematch(%esp)
40911+
40912+/* register Bytef *scan = s->window + s->strstart; */
40913+
40914+ movl dsWindow(%edx), %esi
40915+ movl %esi, window(%esp)
40916+ movl dsStrStart(%edx), %ebp
40917+ lea (%esi,%ebp), %edi
40918+ movl %edi, scan(%esp)
40919+
40920+/* Determine how many bytes the scan ptr is off from being */
40921+/* dword-aligned. */
40922+
40923+ movl %edi, %eax
40924+ negl %eax
40925+ andl $3, %eax
40926+ movl %eax, scanalign(%esp)
40927+
40928+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
40929+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
40930+
40931+ movl dsWSize(%edx), %eax
40932+ subl $MIN_LOOKAHEAD, %eax
40933+ subl %eax, %ebp
40934+ jg LimitPositive
40935+ xorl %ebp, %ebp
40936+LimitPositive:
40937+
40938+/* int best_len = s->prev_length; */
40939+
40940+ movl dsPrevLen(%edx), %eax
40941+ movl %eax, bestlen(%esp)
40942+
40943+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
40944+
40945+ addl %eax, %esi
40946+ movl %esi, windowbestlen(%esp)
40947+
40948+/* register ush scan_start = *(ushf*)scan; */
40949+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
40950+/* Posf *prev = s->prev; */
40951+
40952+ movzwl (%edi), %ebx
40953+ movl %ebx, scanstart(%esp)
40954+ movzwl -1(%edi,%eax), %ebx
40955+ movl %ebx, scanend(%esp)
40956+ movl dsPrev(%edx), %edi
40957+
40958+/* Jump into the main loop. */
40959+
40960+ movl chainlenwmask(%esp), %edx
40961+ jmp LoopEntry
40962+
40963+.balign 16
40964+
40965+/* do {
40966+ * match = s->window + cur_match;
40967+ * if (*(ushf*)(match+best_len-1) != scan_end ||
40968+ * *(ushf*)match != scan_start) continue;
40969+ * [...]
40970+ * } while ((cur_match = prev[cur_match & wmask]) > limit
40971+ * && --chain_length != 0);
40972+ *
40973+ * Here is the inner loop of the function. The function will spend the
40974+ * majority of its time in this loop, and majority of that time will
40975+ * be spent in the first ten instructions.
40976+ *
40977+ * Within this loop:
40978+ * %ebx = scanend
40979+ * %ecx = curmatch
40980+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
40981+ * %esi = windowbestlen - i.e., (window + bestlen)
40982+ * %edi = prev
40983+ * %ebp = limit
40984+ */
40985+LookupLoop:
40986+ andl %edx, %ecx
40987+ movzwl (%edi,%ecx,2), %ecx
40988+ cmpl %ebp, %ecx
40989+ jbe LeaveNow
40990+ subl $0x00010000, %edx
40991+ js LeaveNow
40992+LoopEntry: movzwl -1(%esi,%ecx), %eax
40993+ cmpl %ebx, %eax
40994+ jnz LookupLoop
40995+ movl window(%esp), %eax
40996+ movzwl (%eax,%ecx), %eax
40997+ cmpl scanstart(%esp), %eax
40998+ jnz LookupLoop
40999+
41000+/* Store the current value of chainlen. */
41001+
41002+ movl %edx, chainlenwmask(%esp)
41003+
41004+/* Point %edi to the string under scrutiny, and %esi to the string we */
41005+/* are hoping to match it up with. In actuality, %esi and %edi are */
41006+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
41007+/* initialized to -(MAX_MATCH_8 - scanalign). */
41008+
41009+ movl window(%esp), %esi
41010+ movl scan(%esp), %edi
41011+ addl %ecx, %esi
41012+ movl scanalign(%esp), %eax
41013+ movl $(-MAX_MATCH_8), %edx
41014+ lea MAX_MATCH_8(%edi,%eax), %edi
41015+ lea MAX_MATCH_8(%esi,%eax), %esi
41016+
41017+/* Test the strings for equality, 8 bytes at a time. At the end,
41018+ * adjust %edx so that it is offset to the exact byte that mismatched.
41019+ *
41020+ * We already know at this point that the first three bytes of the
41021+ * strings match each other, and they can be safely passed over before
41022+ * starting the compare loop. So what this code does is skip over 0-3
41023+ * bytes, as much as necessary in order to dword-align the %edi
41024+ * pointer. (%esi will still be misaligned three times out of four.)
41025+ *
41026+ * It should be confessed that this loop usually does not represent
41027+ * much of the total running time. Replacing it with a more
41028+ * straightforward "rep cmpsb" would not drastically degrade
41029+ * performance.
41030+ */
41031+LoopCmps:
41032+ movl (%esi,%edx), %eax
41033+ xorl (%edi,%edx), %eax
41034+ jnz LeaveLoopCmps
41035+ movl 4(%esi,%edx), %eax
41036+ xorl 4(%edi,%edx), %eax
41037+ jnz LeaveLoopCmps4
41038+ addl $8, %edx
41039+ jnz LoopCmps
41040+ jmp LenMaximum
41041+LeaveLoopCmps4: addl $4, %edx
41042+LeaveLoopCmps: testl $0x0000FFFF, %eax
41043+ jnz LenLower
41044+ addl $2, %edx
41045+ shrl $16, %eax
41046+LenLower: subb $1, %al
41047+ adcl $0, %edx
41048+
41049+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
41050+/* then automatically accept it as the best possible match and leave. */
41051+
41052+ lea (%edi,%edx), %eax
41053+ movl scan(%esp), %edi
41054+ subl %edi, %eax
41055+ cmpl $MAX_MATCH, %eax
41056+ jge LenMaximum
41057+
41058+/* If the length of the match is not longer than the best match we */
41059+/* have so far, then forget it and return to the lookup loop. */
41060+
41061+ movl deflatestate(%esp), %edx
41062+ movl bestlen(%esp), %ebx
41063+ cmpl %ebx, %eax
41064+ jg LongerMatch
41065+ movl windowbestlen(%esp), %esi
41066+ movl dsPrev(%edx), %edi
41067+ movl scanend(%esp), %ebx
41068+ movl chainlenwmask(%esp), %edx
41069+ jmp LookupLoop
41070+
41071+/* s->match_start = cur_match; */
41072+/* best_len = len; */
41073+/* if (len >= nice_match) break; */
41074+/* scan_end = *(ushf*)(scan+best_len-1); */
41075+
41076+LongerMatch: movl nicematch(%esp), %ebx
41077+ movl %eax, bestlen(%esp)
41078+ movl %ecx, dsMatchStart(%edx)
41079+ cmpl %ebx, %eax
41080+ jge LeaveNow
41081+ movl window(%esp), %esi
41082+ addl %eax, %esi
41083+ movl %esi, windowbestlen(%esp)
41084+ movzwl -1(%edi,%eax), %ebx
41085+ movl dsPrev(%edx), %edi
41086+ movl %ebx, scanend(%esp)
41087+ movl chainlenwmask(%esp), %edx
41088+ jmp LookupLoop
41089+
41090+/* Accept the current string, with the maximum possible length. */
41091+
41092+LenMaximum: movl deflatestate(%esp), %edx
41093+ movl $MAX_MATCH, bestlen(%esp)
41094+ movl %ecx, dsMatchStart(%edx)
41095+
41096+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
41097+/* return s->lookahead; */
41098+
41099+LeaveNow:
41100+ movl deflatestate(%esp), %edx
41101+ movl bestlen(%esp), %ebx
41102+ movl dsLookahead(%edx), %eax
41103+ cmpl %eax, %ebx
41104+ jg LookaheadRet
41105+ movl %ebx, %eax
41106+LookaheadRet:
41107+
41108+/* Restore the stack and return from whence we came. */
41109+
41110+ addl $LocalVarsSize, %esp
41111+ popl %ebx
41112+ popl %esi
41113+ popl %edi
41114+ popl %ebp
41115+match_init: ret
41116diff -druN linux-noipsec/net/ipsec/zlib/trees.c linux/net/ipsec/zlib/trees.c
41117--- linux-noipsec/net/ipsec/zlib/trees.c Thu Jan 1 01:00:00 1970
41118+++ linux/net/ipsec/zlib/trees.c Fri Sep 29 20:51:34 2000
41119@@ -0,0 +1,1214 @@
41120+/* trees.c -- output deflated data using Huffman coding
41121+ * Copyright (C) 1995-1998 Jean-loup Gailly
41122+ * For conditions of distribution and use, see copyright notice in zlib.h
41123+ */
41124+
41125+/*
41126+ * ALGORITHM
41127+ *
41128+ * The "deflation" process uses several Huffman trees. The more
41129+ * common source values are represented by shorter bit sequences.
41130+ *
41131+ * Each code tree is stored in a compressed form which is itself
41132+ * a Huffman encoding of the lengths of all the code strings (in
41133+ * ascending order by source values). The actual code strings are
41134+ * reconstructed from the lengths in the inflate process, as described
41135+ * in the deflate specification.
41136+ *
41137+ * REFERENCES
41138+ *
41139+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
41140+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
41141+ *
41142+ * Storer, James A.
41143+ * Data Compression: Methods and Theory, pp. 49-50.
41144+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
41145+ *
41146+ * Sedgewick, R.
41147+ * Algorithms, p290.
41148+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
41149+ */
41150+
41151+/* @(#) $Id$ */
41152+
41153+/* #define GEN_TREES_H */
41154+
41155+#include "deflate.h"
41156+
41157+#ifdef DEBUG
41158+# include <ctype.h>
41159+#endif
41160+
41161+/* ===========================================================================
41162+ * Constants
41163+ */
41164+
41165+#define MAX_BL_BITS 7
41166+/* Bit length codes must not exceed MAX_BL_BITS bits */
41167+
41168+#define END_BLOCK 256
41169+/* end of block literal code */
41170+
41171+#define REP_3_6 16
41172+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
41173+
41174+#define REPZ_3_10 17
41175+/* repeat a zero length 3-10 times (3 bits of repeat count) */
41176+
41177+#define REPZ_11_138 18
41178+/* repeat a zero length 11-138 times (7 bits of repeat count) */
41179+
41180+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
41181+ = {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};
41182+
41183+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
41184+ = {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};
41185+
41186+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
41187+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
41188+
41189+local const uch bl_order[BL_CODES]
41190+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
41191+/* The lengths of the bit length codes are sent in order of decreasing
41192+ * probability, to avoid transmitting the lengths for unused bit length codes.
41193+ */
41194+
41195+#define Buf_size (8 * 2*sizeof(char))
41196+/* Number of bits used within bi_buf. (bi_buf might be implemented on
41197+ * more than 16 bits on some systems.)
41198+ */
41199+
41200+/* ===========================================================================
41201+ * Local data. These are initialized only once.
41202+ */
41203+
41204+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
41205+
41206+#if defined(GEN_TREES_H) || !defined(STDC)
41207+/* non ANSI compilers may not accept trees.h */
41208+
41209+local ct_data static_ltree[L_CODES+2];
41210+/* The static literal tree. Since the bit lengths are imposed, there is no
41211+ * need for the L_CODES extra codes used during heap construction. However
41212+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
41213+ * below).
41214+ */
41215+
41216+local ct_data static_dtree[D_CODES];
41217+/* The static distance tree. (Actually a trivial tree since all codes use
41218+ * 5 bits.)
41219+ */
41220+
41221+uch _dist_code[DIST_CODE_LEN];
41222+/* Distance codes. The first 256 values correspond to the distances
41223+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
41224+ * the 15 bit distances.
41225+ */
41226+
41227+uch _length_code[MAX_MATCH-MIN_MATCH+1];
41228+/* length code for each normalized match length (0 == MIN_MATCH) */
41229+
41230+local int base_length[LENGTH_CODES];
41231+/* First normalized length for each code (0 = MIN_MATCH) */
41232+
41233+local int base_dist[D_CODES];
41234+/* First normalized distance for each code (0 = distance of 1) */
41235+
41236+#else
41237+# include "trees.h"
41238+#endif /* GEN_TREES_H */
41239+
41240+struct static_tree_desc_s {
41241+ const ct_data *static_tree; /* static tree or NULL */
41242+ const intf *extra_bits; /* extra bits for each code or NULL */
41243+ int extra_base; /* base index for extra_bits */
41244+ int elems; /* max number of elements in the tree */
41245+ int max_length; /* max bit length for the codes */
41246+};
41247+
41248+local static_tree_desc static_l_desc =
41249+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
41250+
41251+local static_tree_desc static_d_desc =
41252+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
41253+
41254+local static_tree_desc static_bl_desc =
41255+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
41256+
41257+/* ===========================================================================
41258+ * Local (static) routines in this file.
41259+ */
41260+
41261+local void tr_static_init OF((void));
41262+local void init_block OF((deflate_state *s));
41263+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
41264+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
41265+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
41266+local void build_tree OF((deflate_state *s, tree_desc *desc));
41267+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
41268+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
41269+local int build_bl_tree OF((deflate_state *s));
41270+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
41271+ int blcodes));
41272+local void compress_block OF((deflate_state *s, const ct_data *ltree,
41273+ const ct_data *dtree));
41274+local void set_data_type OF((deflate_state *s));
41275+local unsigned bi_reverse OF((unsigned value, int length));
41276+local void bi_windup OF((deflate_state *s));
41277+local void bi_flush OF((deflate_state *s));
41278+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
41279+ int header));
41280+
41281+#ifdef GEN_TREES_H
41282+local void gen_trees_header OF((void));
41283+#endif
41284+
41285+#ifndef DEBUG
41286+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
41287+ /* Send a code of the given tree. c and tree must not have side effects */
41288+
41289+#else /* DEBUG */
41290+# define send_code(s, c, tree) \
41291+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
41292+ send_bits(s, tree[c].Code, tree[c].Len); }
41293+#endif
41294+
41295+/* ===========================================================================
41296+ * Output a short LSB first on the stream.
41297+ * IN assertion: there is enough room in pendingBuf.
41298+ */
41299+#define put_short(s, w) { \
41300+ put_byte(s, (uch)((w) & 0xff)); \
41301+ put_byte(s, (uch)((ush)(w) >> 8)); \
41302+}
41303+
41304+/* ===========================================================================
41305+ * Send a value on a given number of bits.
41306+ * IN assertion: length <= 16 and value fits in length bits.
41307+ */
41308+#ifdef DEBUG
41309+local void send_bits OF((deflate_state *s, int value, int length));
41310+
41311+local void send_bits(s, value, length)
41312+ deflate_state *s;
41313+ int value; /* value to send */
41314+ int length; /* number of bits */
41315+{
41316+ Tracevv((stderr," l %2d v %4x ", length, value));
41317+ Assert(length > 0 && length <= 15, "invalid length");
41318+ s->bits_sent += (ulg)length;
41319+
41320+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
41321+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
41322+ * unused bits in value.
41323+ */
41324+ if (s->bi_valid > (int)Buf_size - length) {
41325+ s->bi_buf |= (value << s->bi_valid);
41326+ put_short(s, s->bi_buf);
41327+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
41328+ s->bi_valid += length - Buf_size;
41329+ } else {
41330+ s->bi_buf |= value << s->bi_valid;
41331+ s->bi_valid += length;
41332+ }
41333+}
41334+#else /* !DEBUG */
41335+
41336+#define send_bits(s, value, length) \
41337+{ int len = length;\
41338+ if (s->bi_valid > (int)Buf_size - len) {\
41339+ int val = value;\
41340+ s->bi_buf |= (val << s->bi_valid);\
41341+ put_short(s, s->bi_buf);\
41342+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
41343+ s->bi_valid += len - Buf_size;\
41344+ } else {\
41345+ s->bi_buf |= (value) << s->bi_valid;\
41346+ s->bi_valid += len;\
41347+ }\
41348+}
41349+#endif /* DEBUG */
41350+
41351+
41352+#define MAX(a,b) (a >= b ? a : b)
41353+/* the arguments must not have side effects */
41354+
41355+/* ===========================================================================
41356+ * Initialize the various 'constant' tables.
41357+ */
41358+local void tr_static_init()
41359+{
41360+#if defined(GEN_TREES_H) || !defined(STDC)
41361+ static int static_init_done = 0;
41362+ int n; /* iterates over tree elements */
41363+ int bits; /* bit counter */
41364+ int length; /* length value */
41365+ int code; /* code value */
41366+ int dist; /* distance index */
41367+ ush bl_count[MAX_BITS+1];
41368+ /* number of codes at each bit length for an optimal tree */
41369+
41370+ if (static_init_done) return;
41371+
41372+ /* For some embedded targets, global variables are not initialized: */
41373+ static_l_desc.static_tree = static_ltree;
41374+ static_l_desc.extra_bits = extra_lbits;
41375+ static_d_desc.static_tree = static_dtree;
41376+ static_d_desc.extra_bits = extra_dbits;
41377+ static_bl_desc.extra_bits = extra_blbits;
41378+
41379+ /* Initialize the mapping length (0..255) -> length code (0..28) */
41380+ length = 0;
41381+ for (code = 0; code < LENGTH_CODES-1; code++) {
41382+ base_length[code] = length;
41383+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
41384+ _length_code[length++] = (uch)code;
41385+ }
41386+ }
41387+ Assert (length == 256, "tr_static_init: length != 256");
41388+ /* Note that the length 255 (match length 258) can be represented
41389+ * in two different ways: code 284 + 5 bits or code 285, so we
41390+ * overwrite length_code[255] to use the best encoding:
41391+ */
41392+ _length_code[length-1] = (uch)code;
41393+
41394+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
41395+ dist = 0;
41396+ for (code = 0 ; code < 16; code++) {
41397+ base_dist[code] = dist;
41398+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
41399+ _dist_code[dist++] = (uch)code;
41400+ }
41401+ }
41402+ Assert (dist == 256, "tr_static_init: dist != 256");
41403+ dist >>= 7; /* from now on, all distances are divided by 128 */
41404+ for ( ; code < D_CODES; code++) {
41405+ base_dist[code] = dist << 7;
41406+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
41407+ _dist_code[256 + dist++] = (uch)code;
41408+ }
41409+ }
41410+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
41411+
41412+ /* Construct the codes of the static literal tree */
41413+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
41414+ n = 0;
41415+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
41416+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
41417+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
41418+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
41419+ /* Codes 286 and 287 do not exist, but we must include them in the
41420+ * tree construction to get a canonical Huffman tree (longest code
41421+ * all ones)
41422+ */
41423+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
41424+
41425+ /* The static distance tree is trivial: */
41426+ for (n = 0; n < D_CODES; n++) {
41427+ static_dtree[n].Len = 5;
41428+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
41429+ }
41430+ static_init_done = 1;
41431+
41432+# ifdef GEN_TREES_H
41433+ gen_trees_header();
41434+# endif
41435+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
41436+}
41437+
41438+/* ===========================================================================
41439+ * Genererate the file trees.h describing the static trees.
41440+ */
41441+#ifdef GEN_TREES_H
41442+# ifndef DEBUG
41443+# include <stdio.h>
41444+# endif
41445+
41446+# define SEPARATOR(i, last, width) \
41447+ ((i) == (last)? "\n};\n\n" : \
41448+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
41449+
41450+void gen_trees_header()
41451+{
41452+ FILE *header = fopen("trees.h", "w");
41453+ int i;
41454+
41455+ Assert (header != NULL, "Can't open trees.h");
41456+ fprintf(header,
41457+ "/* header created automatically with -DGEN_TREES_H */\n\n");
41458+
41459+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
41460+ for (i = 0; i < L_CODES+2; i++) {
41461+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
41462+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
41463+ }
41464+
41465+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
41466+ for (i = 0; i < D_CODES; i++) {
41467+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
41468+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
41469+ }
41470+
41471+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
41472+ for (i = 0; i < DIST_CODE_LEN; i++) {
41473+ fprintf(header, "%2u%s", _dist_code[i],
41474+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
41475+ }
41476+
41477+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
41478+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
41479+ fprintf(header, "%2u%s", _length_code[i],
41480+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
41481+ }
41482+
41483+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
41484+ for (i = 0; i < LENGTH_CODES; i++) {
41485+ fprintf(header, "%1u%s", base_length[i],
41486+ SEPARATOR(i, LENGTH_CODES-1, 20));
41487+ }
41488+
41489+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
41490+ for (i = 0; i < D_CODES; i++) {
41491+ fprintf(header, "%5u%s", base_dist[i],
41492+ SEPARATOR(i, D_CODES-1, 10));
41493+ }
41494+
41495+ fclose(header);
41496+}
41497+#endif /* GEN_TREES_H */
41498+
41499+/* ===========================================================================
41500+ * Initialize the tree data structures for a new zlib stream.
41501+ */
41502+void _tr_init(s)
41503+ deflate_state *s;
41504+{
41505+ tr_static_init();
41506+
41507+ s->l_desc.dyn_tree = s->dyn_ltree;
41508+ s->l_desc.stat_desc = &static_l_desc;
41509+
41510+ s->d_desc.dyn_tree = s->dyn_dtree;
41511+ s->d_desc.stat_desc = &static_d_desc;
41512+
41513+ s->bl_desc.dyn_tree = s->bl_tree;
41514+ s->bl_desc.stat_desc = &static_bl_desc;
41515+
41516+ s->bi_buf = 0;
41517+ s->bi_valid = 0;
41518+ s->last_eob_len = 8; /* enough lookahead for inflate */
41519+#ifdef DEBUG
41520+ s->compressed_len = 0L;
41521+ s->bits_sent = 0L;
41522+#endif
41523+
41524+ /* Initialize the first block of the first file: */
41525+ init_block(s);
41526+}
41527+
41528+/* ===========================================================================
41529+ * Initialize a new block.
41530+ */
41531+local void init_block(s)
41532+ deflate_state *s;
41533+{
41534+ int n; /* iterates over tree elements */
41535+
41536+ /* Initialize the trees. */
41537+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
41538+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
41539+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
41540+
41541+ s->dyn_ltree[END_BLOCK].Freq = 1;
41542+ s->opt_len = s->static_len = 0L;
41543+ s->last_lit = s->matches = 0;
41544+}
41545+
41546+#define SMALLEST 1
41547+/* Index within the heap array of least frequent node in the Huffman tree */
41548+
41549+
41550+/* ===========================================================================
41551+ * Remove the smallest element from the heap and recreate the heap with
41552+ * one less element. Updates heap and heap_len.
41553+ */
41554+#define pqremove(s, tree, top) \
41555+{\
41556+ top = s->heap[SMALLEST]; \
41557+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
41558+ pqdownheap(s, tree, SMALLEST); \
41559+}
41560+
41561+/* ===========================================================================
41562+ * Compares to subtrees, using the tree depth as tie breaker when
41563+ * the subtrees have equal frequency. This minimizes the worst case length.
41564+ */
41565+#define smaller(tree, n, m, depth) \
41566+ (tree[n].Freq < tree[m].Freq || \
41567+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
41568+
41569+/* ===========================================================================
41570+ * Restore the heap property by moving down the tree starting at node k,
41571+ * exchanging a node with the smallest of its two sons if necessary, stopping
41572+ * when the heap property is re-established (each father smaller than its
41573+ * two sons).
41574+ */
41575+local void pqdownheap(s, tree, k)
41576+ deflate_state *s;
41577+ ct_data *tree; /* the tree to restore */
41578+ int k; /* node to move down */
41579+{
41580+ int v = s->heap[k];
41581+ int j = k << 1; /* left son of k */
41582+ while (j <= s->heap_len) {
41583+ /* Set j to the smallest of the two sons: */
41584+ if (j < s->heap_len &&
41585+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
41586+ j++;
41587+ }
41588+ /* Exit if v is smaller than both sons */
41589+ if (smaller(tree, v, s->heap[j], s->depth)) break;
41590+
41591+ /* Exchange v with the smallest son */
41592+ s->heap[k] = s->heap[j]; k = j;
41593+
41594+ /* And continue down the tree, setting j to the left son of k */
41595+ j <<= 1;
41596+ }
41597+ s->heap[k] = v;
41598+}
41599+
41600+/* ===========================================================================
41601+ * Compute the optimal bit lengths for a tree and update the total bit length
41602+ * for the current block.
41603+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
41604+ * above are the tree nodes sorted by increasing frequency.
41605+ * OUT assertions: the field len is set to the optimal bit length, the
41606+ * array bl_count contains the frequencies for each bit length.
41607+ * The length opt_len is updated; static_len is also updated if stree is
41608+ * not null.
41609+ */
41610+local void gen_bitlen(s, desc)
41611+ deflate_state *s;
41612+ tree_desc *desc; /* the tree descriptor */
41613+{
41614+ ct_data *tree = desc->dyn_tree;
41615+ int max_code = desc->max_code;
41616+ const ct_data *stree = desc->stat_desc->static_tree;
41617+ const intf *extra = desc->stat_desc->extra_bits;
41618+ int base = desc->stat_desc->extra_base;
41619+ int max_length = desc->stat_desc->max_length;
41620+ int h; /* heap index */
41621+ int n, m; /* iterate over the tree elements */
41622+ int bits; /* bit length */
41623+ int xbits; /* extra bits */
41624+ ush f; /* frequency */
41625+ int overflow = 0; /* number of elements with bit length too large */
41626+
41627+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
41628+
41629+ /* In a first pass, compute the optimal bit lengths (which may
41630+ * overflow in the case of the bit length tree).
41631+ */
41632+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
41633+
41634+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
41635+ n = s->heap[h];
41636+ bits = tree[tree[n].Dad].Len + 1;
41637+ if (bits > max_length) bits = max_length, overflow++;
41638+ tree[n].Len = (ush)bits;
41639+ /* We overwrite tree[n].Dad which is no longer needed */
41640+
41641+ if (n > max_code) continue; /* not a leaf node */
41642+
41643+ s->bl_count[bits]++;
41644+ xbits = 0;
41645+ if (n >= base) xbits = extra[n-base];
41646+ f = tree[n].Freq;
41647+ s->opt_len += (ulg)f * (bits + xbits);
41648+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
41649+ }
41650+ if (overflow == 0) return;
41651+
41652+ Trace((stderr,"\nbit length overflow\n"));
41653+ /* This happens for example on obj2 and pic of the Calgary corpus */
41654+
41655+ /* Find the first bit length which could increase: */
41656+ do {
41657+ bits = max_length-1;
41658+ while (s->bl_count[bits] == 0) bits--;
41659+ s->bl_count[bits]--; /* move one leaf down the tree */
41660+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
41661+ s->bl_count[max_length]--;
41662+ /* The brother of the overflow item also moves one step up,
41663+ * but this does not affect bl_count[max_length]
41664+ */
41665+ overflow -= 2;
41666+ } while (overflow > 0);
41667+
41668+ /* Now recompute all bit lengths, scanning in increasing frequency.
41669+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
41670+ * lengths instead of fixing only the wrong ones. This idea is taken
41671+ * from 'ar' written by Haruhiko Okumura.)
41672+ */
41673+ for (bits = max_length; bits != 0; bits--) {
41674+ n = s->bl_count[bits];
41675+ while (n != 0) {
41676+ m = s->heap[--h];
41677+ if (m > max_code) continue;
41678+ if (tree[m].Len != (unsigned) bits) {
41679+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
41680+ s->opt_len += ((long)bits - (long)tree[m].Len)
41681+ *(long)tree[m].Freq;
41682+ tree[m].Len = (ush)bits;
41683+ }
41684+ n--;
41685+ }
41686+ }
41687+}
41688+
41689+/* ===========================================================================
41690+ * Generate the codes for a given tree and bit counts (which need not be
41691+ * optimal).
41692+ * IN assertion: the array bl_count contains the bit length statistics for
41693+ * the given tree and the field len is set for all tree elements.
41694+ * OUT assertion: the field code is set for all tree elements of non
41695+ * zero code length.
41696+ */
41697+local void gen_codes (tree, max_code, bl_count)
41698+ ct_data *tree; /* the tree to decorate */
41699+ int max_code; /* largest code with non zero frequency */
41700+ ushf *bl_count; /* number of codes at each bit length */
41701+{
41702+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
41703+ ush code = 0; /* running code value */
41704+ int bits; /* bit index */
41705+ int n; /* code index */
41706+
41707+ /* The distribution counts are first used to generate the code values
41708+ * without bit reversal.
41709+ */
41710+ for (bits = 1; bits <= MAX_BITS; bits++) {
41711+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
41712+ }
41713+ /* Check that the bit counts in bl_count are consistent. The last code
41714+ * must be all ones.
41715+ */
41716+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
41717+ "inconsistent bit counts");
41718+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
41719+
41720+ for (n = 0; n <= max_code; n++) {
41721+ int len = tree[n].Len;
41722+ if (len == 0) continue;
41723+ /* Now reverse the bits */
41724+ tree[n].Code = bi_reverse(next_code[len]++, len);
41725+
41726+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
41727+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
41728+ }
41729+}
41730+
41731+/* ===========================================================================
41732+ * Construct one Huffman tree and assigns the code bit strings and lengths.
41733+ * Update the total bit length for the current block.
41734+ * IN assertion: the field freq is set for all tree elements.
41735+ * OUT assertions: the fields len and code are set to the optimal bit length
41736+ * and corresponding code. The length opt_len is updated; static_len is
41737+ * also updated if stree is not null. The field max_code is set.
41738+ */
41739+local void build_tree(s, desc)
41740+ deflate_state *s;
41741+ tree_desc *desc; /* the tree descriptor */
41742+{
41743+ ct_data *tree = desc->dyn_tree;
41744+ const ct_data *stree = desc->stat_desc->static_tree;
41745+ int elems = desc->stat_desc->elems;
41746+ int n, m; /* iterate over heap elements */
41747+ int max_code = -1; /* largest code with non zero frequency */
41748+ int node; /* new node being created */
41749+
41750+ /* Construct the initial heap, with least frequent element in
41751+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
41752+ * heap[0] is not used.
41753+ */
41754+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
41755+
41756+ for (n = 0; n < elems; n++) {
41757+ if (tree[n].Freq != 0) {
41758+ s->heap[++(s->heap_len)] = max_code = n;
41759+ s->depth[n] = 0;
41760+ } else {
41761+ tree[n].Len = 0;
41762+ }
41763+ }
41764+
41765+ /* The pkzip format requires that at least one distance code exists,
41766+ * and that at least one bit should be sent even if there is only one
41767+ * possible code. So to avoid special checks later on we force at least
41768+ * two codes of non zero frequency.
41769+ */
41770+ while (s->heap_len < 2) {
41771+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
41772+ tree[node].Freq = 1;
41773+ s->depth[node] = 0;
41774+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
41775+ /* node is 0 or 1 so it does not have extra bits */
41776+ }
41777+ desc->max_code = max_code;
41778+
41779+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
41780+ * establish sub-heaps of increasing lengths:
41781+ */
41782+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
41783+
41784+ /* Construct the Huffman tree by repeatedly combining the least two
41785+ * frequent nodes.
41786+ */
41787+ node = elems; /* next internal node of the tree */
41788+ do {
41789+ pqremove(s, tree, n); /* n = node of least frequency */
41790+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
41791+
41792+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
41793+ s->heap[--(s->heap_max)] = m;
41794+
41795+ /* Create a new node father of n and m */
41796+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
41797+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
41798+ tree[n].Dad = tree[m].Dad = (ush)node;
41799+#ifdef DUMP_BL_TREE
41800+ if (tree == s->bl_tree) {
41801+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
41802+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
41803+ }
41804+#endif
41805+ /* and insert the new node in the heap */
41806+ s->heap[SMALLEST] = node++;
41807+ pqdownheap(s, tree, SMALLEST);
41808+
41809+ } while (s->heap_len >= 2);
41810+
41811+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
41812+
41813+ /* At this point, the fields freq and dad are set. We can now
41814+ * generate the bit lengths.
41815+ */
41816+ gen_bitlen(s, (tree_desc *)desc);
41817+
41818+ /* The field len is now set, we can generate the bit codes */
41819+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
41820+}
41821+
41822+/* ===========================================================================
41823+ * Scan a literal or distance tree to determine the frequencies of the codes
41824+ * in the bit length tree.
41825+ */
41826+local void scan_tree (s, tree, max_code)
41827+ deflate_state *s;
41828+ ct_data *tree; /* the tree to be scanned */
41829+ int max_code; /* and its largest code of non zero frequency */
41830+{
41831+ int n; /* iterates over all tree elements */
41832+ int prevlen = -1; /* last emitted length */
41833+ int curlen; /* length of current code */
41834+ int nextlen = tree[0].Len; /* length of next code */
41835+ int count = 0; /* repeat count of the current code */
41836+ int max_count = 7; /* max repeat count */
41837+ int min_count = 4; /* min repeat count */
41838+
41839+ if (nextlen == 0) max_count = 138, min_count = 3;
41840+ tree[max_code+1].Len = (ush)0xffff; /* guard */
41841+
41842+ for (n = 0; n <= max_code; n++) {
41843+ curlen = nextlen; nextlen = tree[n+1].Len;
41844+ if (++count < max_count && curlen == nextlen) {
41845+ continue;
41846+ } else if (count < min_count) {
41847+ s->bl_tree[curlen].Freq += count;
41848+ } else if (curlen != 0) {
41849+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
41850+ s->bl_tree[REP_3_6].Freq++;
41851+ } else if (count <= 10) {
41852+ s->bl_tree[REPZ_3_10].Freq++;
41853+ } else {
41854+ s->bl_tree[REPZ_11_138].Freq++;
41855+ }
41856+ count = 0; prevlen = curlen;
41857+ if (nextlen == 0) {
41858+ max_count = 138, min_count = 3;
41859+ } else if (curlen == nextlen) {
41860+ max_count = 6, min_count = 3;
41861+ } else {
41862+ max_count = 7, min_count = 4;
41863+ }
41864+ }
41865+}
41866+
41867+/* ===========================================================================
41868+ * Send a literal or distance tree in compressed form, using the codes in
41869+ * bl_tree.
41870+ */
41871+local void send_tree (s, tree, max_code)
41872+ deflate_state *s;
41873+ ct_data *tree; /* the tree to be scanned */
41874+ int max_code; /* and its largest code of non zero frequency */
41875+{
41876+ int n; /* iterates over all tree elements */
41877+ int prevlen = -1; /* last emitted length */
41878+ int curlen; /* length of current code */
41879+ int nextlen = tree[0].Len; /* length of next code */
41880+ int count = 0; /* repeat count of the current code */
41881+ int max_count = 7; /* max repeat count */
41882+ int min_count = 4; /* min repeat count */
41883+
41884+ /* tree[max_code+1].Len = -1; */ /* guard already set */
41885+ if (nextlen == 0) max_count = 138, min_count = 3;
41886+
41887+ for (n = 0; n <= max_code; n++) {
41888+ curlen = nextlen; nextlen = tree[n+1].Len;
41889+ if (++count < max_count && curlen == nextlen) {
41890+ continue;
41891+ } else if (count < min_count) {
41892+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
41893+
41894+ } else if (curlen != 0) {
41895+ if (curlen != prevlen) {
41896+ send_code(s, curlen, s->bl_tree); count--;
41897+ }
41898+ Assert(count >= 3 && count <= 6, " 3_6?");
41899+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
41900+
41901+ } else if (count <= 10) {
41902+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
41903+
41904+ } else {
41905+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
41906+ }
41907+ count = 0; prevlen = curlen;
41908+ if (nextlen == 0) {
41909+ max_count = 138, min_count = 3;
41910+ } else if (curlen == nextlen) {
41911+ max_count = 6, min_count = 3;
41912+ } else {
41913+ max_count = 7, min_count = 4;
41914+ }
41915+ }
41916+}
41917+
41918+/* ===========================================================================
41919+ * Construct the Huffman tree for the bit lengths and return the index in
41920+ * bl_order of the last bit length code to send.
41921+ */
41922+local int build_bl_tree(s)
41923+ deflate_state *s;
41924+{
41925+ int max_blindex; /* index of last bit length code of non zero freq */
41926+
41927+ /* Determine the bit length frequencies for literal and distance trees */
41928+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
41929+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
41930+
41931+ /* Build the bit length tree: */
41932+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
41933+ /* opt_len now includes the length of the tree representations, except
41934+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
41935+ */
41936+
41937+ /* Determine the number of bit length codes to send. The pkzip format
41938+ * requires that at least 4 bit length codes be sent. (appnote.txt says
41939+ * 3 but the actual value used is 4.)
41940+ */
41941+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
41942+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
41943+ }
41944+ /* Update opt_len to include the bit length tree and counts */
41945+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
41946+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
41947+ s->opt_len, s->static_len));
41948+
41949+ return max_blindex;
41950+}
41951+
41952+/* ===========================================================================
41953+ * Send the header for a block using dynamic Huffman trees: the counts, the
41954+ * lengths of the bit length codes, the literal tree and the distance tree.
41955+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
41956+ */
41957+local void send_all_trees(s, lcodes, dcodes, blcodes)
41958+ deflate_state *s;
41959+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
41960+{
41961+ int rank; /* index in bl_order */
41962+
41963+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
41964+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
41965+ "too many codes");
41966+ Tracev((stderr, "\nbl counts: "));
41967+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
41968+ send_bits(s, dcodes-1, 5);
41969+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
41970+ for (rank = 0; rank < blcodes; rank++) {
41971+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
41972+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
41973+ }
41974+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
41975+
41976+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
41977+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
41978+
41979+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
41980+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
41981+}
41982+
41983+/* ===========================================================================
41984+ * Send a stored block
41985+ */
41986+void _tr_stored_block(s, buf, stored_len, eof)
41987+ deflate_state *s;
41988+ charf *buf; /* input block */
41989+ ulg stored_len; /* length of input block */
41990+ int eof; /* true if this is the last block for a file */
41991+{
41992+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
41993+#ifdef DEBUG
41994+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
41995+ s->compressed_len += (stored_len + 4) << 3;
41996+#endif
41997+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
41998+}
41999+
42000+/* ===========================================================================
42001+ * Send one empty static block to give enough lookahead for inflate.
42002+ * This takes 10 bits, of which 7 may remain in the bit buffer.
42003+ * The current inflate code requires 9 bits of lookahead. If the
42004+ * last two codes for the previous block (real code plus EOB) were coded
42005+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
42006+ * the last real code. In this case we send two empty static blocks instead
42007+ * of one. (There are no problems if the previous block is stored or fixed.)
42008+ * To simplify the code, we assume the worst case of last real code encoded
42009+ * on one bit only.
42010+ */
42011+void _tr_align(s)
42012+ deflate_state *s;
42013+{
42014+ send_bits(s, STATIC_TREES<<1, 3);
42015+ send_code(s, END_BLOCK, static_ltree);
42016+#ifdef DEBUG
42017+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
42018+#endif
42019+ bi_flush(s);
42020+ /* Of the 10 bits for the empty block, we have already sent
42021+ * (10 - bi_valid) bits. The lookahead for the last real code (before
42022+ * the EOB of the previous block) was thus at least one plus the length
42023+ * of the EOB plus what we have just sent of the empty static block.
42024+ */
42025+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
42026+ send_bits(s, STATIC_TREES<<1, 3);
42027+ send_code(s, END_BLOCK, static_ltree);
42028+#ifdef DEBUG
42029+ s->compressed_len += 10L;
42030+#endif
42031+ bi_flush(s);
42032+ }
42033+ s->last_eob_len = 7;
42034+}
42035+
42036+/* ===========================================================================
42037+ * Determine the best encoding for the current block: dynamic trees, static
42038+ * trees or store, and output the encoded block to the zip file.
42039+ */
42040+void _tr_flush_block(s, buf, stored_len, eof)
42041+ deflate_state *s;
42042+ charf *buf; /* input block, or NULL if too old */
42043+ ulg stored_len; /* length of input block */
42044+ int eof; /* true if this is the last block for a file */
42045+{
42046+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
42047+ int max_blindex = 0; /* index of last bit length code of non zero freq */
42048+
42049+ /* Build the Huffman trees unless a stored block is forced */
42050+ if (s->level > 0) {
42051+
42052+ /* Check if the file is ascii or binary */
42053+ if (s->data_type == Z_UNKNOWN) set_data_type(s);
42054+
42055+ /* Construct the literal and distance trees */
42056+ build_tree(s, (tree_desc *)(&(s->l_desc)));
42057+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
42058+ s->static_len));
42059+
42060+ build_tree(s, (tree_desc *)(&(s->d_desc)));
42061+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
42062+ s->static_len));
42063+ /* At this point, opt_len and static_len are the total bit lengths of
42064+ * the compressed block data, excluding the tree representations.
42065+ */
42066+
42067+ /* Build the bit length tree for the above two trees, and get the index
42068+ * in bl_order of the last bit length code to send.
42069+ */
42070+ max_blindex = build_bl_tree(s);
42071+
42072+ /* Determine the best encoding. Compute first the block length in bytes*/
42073+ opt_lenb = (s->opt_len+3+7)>>3;
42074+ static_lenb = (s->static_len+3+7)>>3;
42075+
42076+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
42077+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
42078+ s->last_lit));
42079+
42080+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
42081+
42082+ } else {
42083+ Assert(buf != (char*)0, "lost buf");
42084+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
42085+ }
42086+
42087+#ifdef FORCE_STORED
42088+ if (buf != (char*)0) { /* force stored block */
42089+#else
42090+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
42091+ /* 4: two words for the lengths */
42092+#endif
42093+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
42094+ * Otherwise we can't have processed more than WSIZE input bytes since
42095+ * the last block flush, because compression would have been
42096+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
42097+ * transform a block into a stored block.
42098+ */
42099+ _tr_stored_block(s, buf, stored_len, eof);
42100+
42101+#ifdef FORCE_STATIC
42102+ } else if (static_lenb >= 0) { /* force static trees */
42103+#else
42104+ } else if (static_lenb == opt_lenb) {
42105+#endif
42106+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
42107+ compress_block(s, static_ltree, static_dtree);
42108+#ifdef DEBUG
42109+ s->compressed_len += 3 + s->static_len;
42110+#endif
42111+ } else {
42112+ send_bits(s, (DYN_TREES<<1)+eof, 3);
42113+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
42114+ max_blindex+1);
42115+ compress_block(s, s->dyn_ltree, s->dyn_dtree);
42116+#ifdef DEBUG
42117+ s->compressed_len += 3 + s->opt_len;
42118+#endif
42119+ }
42120+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
42121+ /* The above check is made mod 2^32, for files larger than 512 MB
42122+ * and uLong implemented on 32 bits.
42123+ */
42124+ init_block(s);
42125+
42126+ if (eof) {
42127+ bi_windup(s);
42128+#ifdef DEBUG
42129+ s->compressed_len += 7; /* align on byte boundary */
42130+#endif
42131+ }
42132+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
42133+ s->compressed_len-7*eof));
42134+}
42135+
42136+/* ===========================================================================
42137+ * Save the match info and tally the frequency counts. Return true if
42138+ * the current block must be flushed.
42139+ */
42140+int _tr_tally (s, dist, lc)
42141+ deflate_state *s;
42142+ unsigned dist; /* distance of matched string */
42143+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
42144+{
42145+ s->d_buf[s->last_lit] = (ush)dist;
42146+ s->l_buf[s->last_lit++] = (uch)lc;
42147+ if (dist == 0) {
42148+ /* lc is the unmatched char */
42149+ s->dyn_ltree[lc].Freq++;
42150+ } else {
42151+ s->matches++;
42152+ /* Here, lc is the match length - MIN_MATCH */
42153+ dist--; /* dist = match distance - 1 */
42154+ Assert((ush)dist < (ush)MAX_DIST(s) &&
42155+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
42156+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
42157+
42158+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
42159+ s->dyn_dtree[d_code(dist)].Freq++;
42160+ }
42161+
42162+#ifdef TRUNCATE_BLOCK
42163+ /* Try to guess if it is profitable to stop the current block here */
42164+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
42165+ /* Compute an upper bound for the compressed length */
42166+ ulg out_length = (ulg)s->last_lit*8L;
42167+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
42168+ int dcode;
42169+ for (dcode = 0; dcode < D_CODES; dcode++) {
42170+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
42171+ (5L+extra_dbits[dcode]);
42172+ }
42173+ out_length >>= 3;
42174+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
42175+ s->last_lit, in_length, out_length,
42176+ 100L - out_length*100L/in_length));
42177+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
42178+ }
42179+#endif
42180+ return (s->last_lit == s->lit_bufsize-1);
42181+ /* We avoid equality with lit_bufsize because of wraparound at 64K
42182+ * on 16 bit machines and because stored blocks are restricted to
42183+ * 64K-1 bytes.
42184+ */
42185+}
42186+
42187+/* ===========================================================================
42188+ * Send the block data compressed using the given Huffman trees
42189+ */
42190+local void compress_block(s, ltree, dtree)
42191+ deflate_state *s;
42192+ const ct_data *ltree; /* literal tree */
42193+ const ct_data *dtree; /* distance tree */
42194+{
42195+ unsigned dist; /* distance of matched string */
42196+ int lc; /* match length or unmatched char (if dist == 0) */
42197+ unsigned lx = 0; /* running index in l_buf */
42198+ unsigned code; /* the code to send */
42199+ int extra; /* number of extra bits to send */
42200+
42201+ if (s->last_lit != 0) do {
42202+ dist = s->d_buf[lx];
42203+ lc = s->l_buf[lx++];
42204+ if (dist == 0) {
42205+ send_code(s, lc, ltree); /* send a literal byte */
42206+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
42207+ } else {
42208+ /* Here, lc is the match length - MIN_MATCH */
42209+ code = _length_code[lc];
42210+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
42211+ extra = extra_lbits[code];
42212+ if (extra != 0) {
42213+ lc -= base_length[code];
42214+ send_bits(s, lc, extra); /* send the extra length bits */
42215+ }
42216+ dist--; /* dist is now the match distance - 1 */
42217+ code = d_code(dist);
42218+ Assert (code < D_CODES, "bad d_code");
42219+
42220+ send_code(s, code, dtree); /* send the distance code */
42221+ extra = extra_dbits[code];
42222+ if (extra != 0) {
42223+ dist -= base_dist[code];
42224+ send_bits(s, dist, extra); /* send the extra distance bits */
42225+ }
42226+ } /* literal or match pair ? */
42227+
42228+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
42229+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
42230+
42231+ } while (lx < s->last_lit);
42232+
42233+ send_code(s, END_BLOCK, ltree);
42234+ s->last_eob_len = ltree[END_BLOCK].Len;
42235+}
42236+
42237+/* ===========================================================================
42238+ * Set the data type to ASCII or BINARY, using a crude approximation:
42239+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
42240+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
42241+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
42242+ */
42243+local void set_data_type(s)
42244+ deflate_state *s;
42245+{
42246+ int n = 0;
42247+ unsigned ascii_freq = 0;
42248+ unsigned bin_freq = 0;
42249+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
42250+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
42251+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
42252+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
42253+}
42254+
42255+/* ===========================================================================
42256+ * Reverse the first len bits of a code, using straightforward code (a faster
42257+ * method would use a table)
42258+ * IN assertion: 1 <= len <= 15
42259+ */
42260+local unsigned bi_reverse(code, len)
42261+ unsigned code; /* the value to invert */
42262+ int len; /* its bit length */
42263+{
42264+ register unsigned res = 0;
42265+ do {
42266+ res |= code & 1;
42267+ code >>= 1, res <<= 1;
42268+ } while (--len > 0);
42269+ return res >> 1;
42270+}
42271+
42272+/* ===========================================================================
42273+ * Flush the bit buffer, keeping at most 7 bits in it.
42274+ */
42275+local void bi_flush(s)
42276+ deflate_state *s;
42277+{
42278+ if (s->bi_valid == 16) {
42279+ put_short(s, s->bi_buf);
42280+ s->bi_buf = 0;
42281+ s->bi_valid = 0;
42282+ } else if (s->bi_valid >= 8) {
42283+ put_byte(s, (Byte)s->bi_buf);
42284+ s->bi_buf >>= 8;
42285+ s->bi_valid -= 8;
42286+ }
42287+}
42288+
42289+/* ===========================================================================
42290+ * Flush the bit buffer and align the output on a byte boundary
42291+ */
42292+local void bi_windup(s)
42293+ deflate_state *s;
42294+{
42295+ if (s->bi_valid > 8) {
42296+ put_short(s, s->bi_buf);
42297+ } else if (s->bi_valid > 0) {
42298+ put_byte(s, (Byte)s->bi_buf);
42299+ }
42300+ s->bi_buf = 0;
42301+ s->bi_valid = 0;
42302+#ifdef DEBUG
42303+ s->bits_sent = (s->bits_sent+7) & ~7;
42304+#endif
42305+}
42306+
42307+/* ===========================================================================
42308+ * Copy a stored block, storing first the length and its
42309+ * one's complement if requested.
42310+ */
42311+local void copy_block(s, buf, len, header)
42312+ deflate_state *s;
42313+ charf *buf; /* the input data */
42314+ unsigned len; /* its length */
42315+ int header; /* true if block header must be written */
42316+{
42317+ bi_windup(s); /* align on byte boundary */
42318+ s->last_eob_len = 8; /* enough lookahead for inflate */
42319+
42320+ if (header) {
42321+ put_short(s, (ush)len);
42322+ put_short(s, (ush)~len);
42323+#ifdef DEBUG
42324+ s->bits_sent += 2*16;
42325+#endif
42326+ }
42327+#ifdef DEBUG
42328+ s->bits_sent += (ulg)len<<3;
42329+#endif
42330+ while (len--) {
42331+ put_byte(s, *buf++);
42332+ }
42333+}
42334diff -druN linux-noipsec/net/ipsec/zlib/trees.h linux/net/ipsec/zlib/trees.h
42335--- linux-noipsec/net/ipsec/zlib/trees.h Thu Jan 1 01:00:00 1970
42336+++ linux/net/ipsec/zlib/trees.h Fri Sep 29 20:51:34 2000
42337@@ -0,0 +1,128 @@
42338+/* header created automatically with -DGEN_TREES_H */
42339+
42340+local const ct_data static_ltree[L_CODES+2] = {
42341+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
42342+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
42343+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
42344+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
42345+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
42346+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
42347+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
42348+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
42349+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
42350+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
42351+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
42352+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
42353+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
42354+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
42355+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
42356+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
42357+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
42358+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
42359+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
42360+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
42361+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
42362+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
42363+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
42364+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
42365+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
42366+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
42367+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
42368+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
42369+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
42370+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
42371+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
42372+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
42373+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
42374+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
42375+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
42376+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
42377+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
42378+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
42379+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
42380+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
42381+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
42382+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
42383+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
42384+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
42385+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
42386+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
42387+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
42388+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
42389+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
42390+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
42391+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
42392+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
42393+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
42394+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
42395+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
42396+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
42397+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
42398+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
42399+};
42400+
42401+local const ct_data static_dtree[D_CODES] = {
42402+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
42403+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
42404+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
42405+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
42406+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
42407+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
42408+};
42409+
42410+const uch _dist_code[DIST_CODE_LEN] = {
42411+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
42412+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
42413+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
42414+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
42415+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
42416+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
42417+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
42418+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
42419+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
42420+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
42421+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
42422+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
42423+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
42424+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
42425+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
42426+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
42427+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
42428+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
42429+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
42430+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
42431+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
42432+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
42433+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
42434+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
42435+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
42436+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
42437+};
42438+
42439+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
42440+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
42441+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
42442+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
42443+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
42444+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
42445+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
42446+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
42447+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
42448+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
42449+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
42450+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
42451+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
42452+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
42453+};
42454+
42455+local const int base_length[LENGTH_CODES] = {
42456+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
42457+64, 80, 96, 112, 128, 160, 192, 224, 0
42458+};
42459+
42460+local const int base_dist[D_CODES] = {
42461+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
42462+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
42463+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
42464+};
42465+
42466diff -druN linux-noipsec/net/ipsec/zlib/zconf.h linux/net/ipsec/zlib/zconf.h
42467--- linux-noipsec/net/ipsec/zlib/zconf.h Thu Jan 1 01:00:00 1970
42468+++ linux/net/ipsec/zlib/zconf.h Fri Sep 29 20:51:34 2000
42469@@ -0,0 +1,309 @@
42470+/* zconf.h -- configuration of the zlib compression library
42471+ * Copyright (C) 1995-1998 Jean-loup Gailly.
42472+ * For conditions of distribution and use, see copyright notice in zlib.h
42473+ */
42474+
42475+/* @(#) $Id$ */
42476+
42477+#ifndef _ZCONF_H
42478+#define _ZCONF_H
42479+
42480+/*
42481+ * If you *really* need a unique prefix for all types and library functions,
42482+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
42483+ */
42484+#ifdef IPCOMP_PREFIX
42485+# define deflateInit_ ipcomp_deflateInit_
42486+# define deflate ipcomp_deflate
42487+# define deflateEnd ipcomp_deflateEnd
42488+# define inflateInit_ ipcomp_inflateInit_
42489+# define inflate ipcomp_inflate
42490+# define inflateEnd ipcomp_inflateEnd
42491+# define deflateInit2_ ipcomp_deflateInit2_
42492+# define deflateSetDictionary ipcomp_deflateSetDictionary
42493+# define deflateCopy ipcomp_deflateCopy
42494+# define deflateReset ipcomp_deflateReset
42495+# define deflateParams ipcomp_deflateParams
42496+# define inflateInit2_ ipcomp_inflateInit2_
42497+# define inflateSetDictionary ipcomp_inflateSetDictionary
42498+# define inflateSync ipcomp_inflateSync
42499+# define inflateSyncPoint ipcomp_inflateSyncPoint
42500+# define inflateReset ipcomp_inflateReset
42501+# define compress ipcomp_compress
42502+# define compress2 ipcomp_compress2
42503+# define uncompress ipcomp_uncompress
42504+# define adler32 ipcomp_adler32
42505+# define crc32 ipcomp_crc32
42506+# define get_crc_table ipcomp_get_crc_table
42507+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
42508+# define inflate_blocks ipcomp_deflate_blocks
42509+# define inflate_blocks_free ipcomp_deflate_blocks_free
42510+# define inflate_blocks_new ipcomp_inflate_blocks_new
42511+# define inflate_blocks_reset ipcomp_inflate_blocks_reset
42512+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
42513+# define inflate_set_dictionary ipcomp_inflate_set_dictionary
42514+# define inflate_codes ipcomp_inflate_codes
42515+# define inflate_codes_free ipcomp_inflate_codes_free
42516+# define inflate_codes_new ipcomp_inflate_codes_new
42517+# define inflate_fast ipcomp_inflate_fast
42518+# define inflate_trees_bits ipcomp_inflate_trees_bits
42519+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
42520+# define inflate_trees_fixed ipcomp_inflate_trees_fixed
42521+# define inflate_flush ipcomp_inflate_flush
42522+# define inflate_mask ipcomp_inflate_mask
42523+# define _dist_code _ipcomp_dist_code
42524+# define _length_code _ipcomp_length_code
42525+# define _tr_align _ipcomp_tr_align
42526+# define _tr_flush_block _ipcomp_tr_flush_block
42527+# define _tr_init _ipcomp_tr_init
42528+# define _tr_stored_block _ipcomp_tr_stored_block
42529+# define _tr_tally _ipcomp_tr_tally
42530+# define zError ipcomp_zError
42531+# define z_errmsg ipcomp_z_errmsg
42532+# define zlibVersion ipcomp_zlibVersion
42533+# define match_init ipcomp_match_init
42534+# define longest_match ipcomp_longest_match
42535+#endif
42536+
42537+#ifdef Z_PREFIX
42538+# define Byte z_Byte
42539+# define uInt z_uInt
42540+# define uLong z_uLong
42541+# define Bytef z_Bytef
42542+# define charf z_charf
42543+# define intf z_intf
42544+# define uIntf z_uIntf
42545+# define uLongf z_uLongf
42546+# define voidpf z_voidpf
42547+# define voidp z_voidp
42548+#endif
42549+
42550+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
42551+# define WIN32
42552+#endif
42553+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
42554+# ifndef __32BIT__
42555+# define __32BIT__
42556+# endif
42557+#endif
42558+#if defined(__MSDOS__) && !defined(MSDOS)
42559+# define MSDOS
42560+#endif
42561+
42562+/*
42563+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
42564+ * than 64k bytes at a time (needed on systems with 16-bit int).
42565+ */
42566+#if defined(MSDOS) && !defined(__32BIT__)
42567+# define MAXSEG_64K
42568+#endif
42569+#ifdef MSDOS
42570+# define UNALIGNED_OK
42571+#endif
42572+
42573+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
42574+# define STDC
42575+#endif
42576+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
42577+# ifndef STDC
42578+# define STDC
42579+# endif
42580+#endif
42581+
42582+#ifndef STDC
42583+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
42584+# define const
42585+# endif
42586+#endif
42587+
42588+/* Some Mac compilers merge all .h files incorrectly: */
42589+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
42590+# define NO_DUMMY_DECL
42591+#endif
42592+
42593+/* Old Borland C incorrectly complains about missing returns: */
42594+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
42595+# define NEED_DUMMY_RETURN
42596+#endif
42597+
42598+
42599+/* Maximum value for memLevel in deflateInit2 */
42600+#ifndef MAX_MEM_LEVEL
42601+# ifdef MAXSEG_64K
42602+# define MAX_MEM_LEVEL 8
42603+# else
42604+# define MAX_MEM_LEVEL 9
42605+# endif
42606+#endif
42607+
42608+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
42609+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
42610+ * created by gzip. (Files created by minigzip can still be extracted by
42611+ * gzip.)
42612+ */
42613+#ifndef MAX_WBITS
42614+# define MAX_WBITS 15 /* 32K LZ77 window */
42615+#endif
42616+
42617+/* The memory requirements for deflate are (in bytes):
42618+ (1 << (windowBits+2)) + (1 << (memLevel+9))
42619+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
42620+ plus a few kilobytes for small objects. For example, if you want to reduce
42621+ the default memory requirements from 256K to 128K, compile with
42622+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
42623+ Of course this will generally degrade compression (there's no free lunch).
42624+
42625+ The memory requirements for inflate are (in bytes) 1 << windowBits
42626+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
42627+ for small objects.
42628+*/
42629+
42630+ /* Type declarations */
42631+
42632+#ifndef OF /* function prototypes */
42633+# ifdef STDC
42634+# define OF(args) args
42635+# else
42636+# define OF(args) ()
42637+# endif
42638+#endif
42639+
42640+/* The following definitions for FAR are needed only for MSDOS mixed
42641+ * model programming (small or medium model with some far allocations).
42642+ * This was tested only with MSC; for other MSDOS compilers you may have
42643+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
42644+ * just define FAR to be empty.
42645+ */
42646+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
42647+ /* MSC small or medium model */
42648+# define SMALL_MEDIUM
42649+# ifdef _MSC_VER
42650+# define FAR _far
42651+# else
42652+# define FAR far
42653+# endif
42654+#endif
42655+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
42656+# ifndef __32BIT__
42657+# define SMALL_MEDIUM
42658+# define FAR _far
42659+# endif
42660+#endif
42661+
42662+/* Compile with -DZLIB_DLL for Windows DLL support */
42663+#if defined(ZLIB_DLL)
42664+# if defined(_WINDOWS) || defined(WINDOWS)
42665+# ifdef FAR
42666+# undef FAR
42667+# endif
42668+# include <windows.h>
42669+# define ZEXPORT WINAPI
42670+# ifdef WIN32
42671+# define ZEXPORTVA WINAPIV
42672+# else
42673+# define ZEXPORTVA FAR _cdecl _export
42674+# endif
42675+# endif
42676+# if defined (__BORLANDC__)
42677+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
42678+# include <windows.h>
42679+# define ZEXPORT __declspec(dllexport) WINAPI
42680+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
42681+# else
42682+# if defined (_Windows) && defined (__DLL__)
42683+# define ZEXPORT _export
42684+# define ZEXPORTVA _export
42685+# endif
42686+# endif
42687+# endif
42688+#endif
42689+
42690+#if defined (__BEOS__)
42691+# if defined (ZLIB_DLL)
42692+# define ZEXTERN extern __declspec(dllexport)
42693+# else
42694+# define ZEXTERN extern __declspec(dllimport)
42695+# endif
42696+#endif
42697+
42698+#ifndef ZEXPORT
42699+# define ZEXPORT
42700+#endif
42701+#ifndef ZEXPORTVA
42702+# define ZEXPORTVA
42703+#endif
42704+#ifndef ZEXTERN
42705+# define ZEXTERN extern
42706+#endif
42707+
42708+#ifndef FAR
42709+# define FAR
42710+#endif
42711+
42712+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
42713+typedef unsigned char Byte; /* 8 bits */
42714+#endif
42715+typedef unsigned int uInt; /* 16 bits or more */
42716+typedef unsigned long uLong; /* 32 bits or more */
42717+
42718+#ifdef SMALL_MEDIUM
42719+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
42720+# define Bytef Byte FAR
42721+#else
42722+ typedef Byte FAR Bytef;
42723+#endif
42724+typedef char FAR charf;
42725+typedef int FAR intf;
42726+typedef uInt FAR uIntf;
42727+typedef uLong FAR uLongf;
42728+
42729+#ifdef STDC
42730+ typedef void FAR *voidpf;
42731+ typedef void *voidp;
42732+#else
42733+ typedef Byte FAR *voidpf;
42734+ typedef Byte *voidp;
42735+#endif
42736+
42737+#ifdef HAVE_UNISTD_H
42738+# include <sys/types.h> /* for off_t */
42739+# include <unistd.h> /* for SEEK_* and off_t */
42740+# define z_off_t off_t
42741+#endif
42742+#ifndef SEEK_SET
42743+# define SEEK_SET 0 /* Seek from beginning of file. */
42744+# define SEEK_CUR 1 /* Seek from current position. */
42745+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
42746+#endif
42747+#ifndef z_off_t
42748+# define z_off_t long
42749+#endif
42750+
42751+/* MVS linker does not support external names larger than 8 bytes */
42752+#if defined(__MVS__)
42753+# pragma map(deflateInit_,"DEIN")
42754+# pragma map(deflateInit2_,"DEIN2")
42755+# pragma map(deflateEnd,"DEEND")
42756+# pragma map(inflateInit_,"ININ")
42757+# pragma map(inflateInit2_,"ININ2")
42758+# pragma map(inflateEnd,"INEND")
42759+# pragma map(inflateSync,"INSY")
42760+# pragma map(inflateSetDictionary,"INSEDI")
42761+# pragma map(inflate_blocks,"INBL")
42762+# pragma map(inflate_blocks_new,"INBLNE")
42763+# pragma map(inflate_blocks_free,"INBLFR")
42764+# pragma map(inflate_blocks_reset,"INBLRE")
42765+# pragma map(inflate_codes_free,"INCOFR")
42766+# pragma map(inflate_codes,"INCO")
42767+# pragma map(inflate_fast,"INFA")
42768+# pragma map(inflate_flush,"INFLU")
42769+# pragma map(inflate_mask,"INMA")
42770+# pragma map(inflate_set_dictionary,"INSEDI2")
42771+# pragma map(ipcomp_inflate_copyright,"INCOPY")
42772+# pragma map(inflate_trees_bits,"INTRBI")
42773+# pragma map(inflate_trees_dynamic,"INTRDY")
42774+# pragma map(inflate_trees_fixed,"INTRFI")
42775+# pragma map(inflate_trees_free,"INTRFR")
42776+#endif
42777+
42778+#endif /* _ZCONF_H */
42779diff -druN linux-noipsec/net/ipsec/zlib/zlib.h linux/net/ipsec/zlib/zlib.h
42780--- linux-noipsec/net/ipsec/zlib/zlib.h Thu Jan 1 01:00:00 1970
42781+++ linux/net/ipsec/zlib/zlib.h Fri Sep 29 20:51:34 2000
42782@@ -0,0 +1,893 @@
42783+/* zlib.h -- interface of the 'zlib' general purpose compression library
42784+ version 1.1.3, July 9th, 1998
42785+
42786+ Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
42787+
42788+ This software is provided 'as-is', without any express or implied
42789+ warranty. In no event will the authors be held liable for any damages
42790+ arising from the use of this software.
42791+
42792+ Permission is granted to anyone to use this software for any purpose,
42793+ including commercial applications, and to alter it and redistribute it
42794+ freely, subject to the following restrictions:
42795+
42796+ 1. The origin of this software must not be misrepresented; you must not
42797+ claim that you wrote the original software. If you use this software
42798+ in a product, an acknowledgment in the product documentation would be
42799+ appreciated but is not required.
42800+ 2. Altered source versions must be plainly marked as such, and must not be
42801+ misrepresented as being the original software.
42802+ 3. This notice may not be removed or altered from any source distribution.
42803+
42804+ Jean-loup Gailly Mark Adler
42805+ jloup@gzip.org madler@alumni.caltech.edu
42806+
42807+
42808+ The data format used by the zlib library is described by RFCs (Request for
42809+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
42810+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
42811+*/
42812+
42813+#ifndef _ZLIB_H
42814+#define _ZLIB_H
42815+
42816+#include "zconf.h"
42817+
42818+#ifdef __cplusplus
42819+extern "C" {
42820+#endif
42821+
42822+#define ZLIB_VERSION "1.1.3"
42823+
42824+/*
42825+ The 'zlib' compression library provides in-memory compression and
42826+ decompression functions, including integrity checks of the uncompressed
42827+ data. This version of the library supports only one compression method
42828+ (deflation) but other algorithms will be added later and will have the same
42829+ stream interface.
42830+
42831+ Compression can be done in a single step if the buffers are large
42832+ enough (for example if an input file is mmap'ed), or can be done by
42833+ repeated calls of the compression function. In the latter case, the
42834+ application must provide more input and/or consume the output
42835+ (providing more output space) before each call.
42836+
42837+ The library also supports reading and writing files in gzip (.gz) format
42838+ with an interface similar to that of stdio.
42839+
42840+ The library does not install any signal handler. The decoder checks
42841+ the consistency of the compressed data, so the library should never
42842+ crash even in case of corrupted input.
42843+*/
42844+
42845+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
42846+typedef void (*free_func) OF((voidpf opaque, voidpf address));
42847+
42848+struct internal_state;
42849+
42850+typedef struct z_stream_s {
42851+ Bytef *next_in; /* next input byte */
42852+ uInt avail_in; /* number of bytes available at next_in */
42853+ uLong total_in; /* total nb of input bytes read so far */
42854+
42855+ Bytef *next_out; /* next output byte should be put there */
42856+ uInt avail_out; /* remaining free space at next_out */
42857+ uLong total_out; /* total nb of bytes output so far */
42858+
42859+ const char *msg; /* last error message, NULL if no error */
42860+ struct internal_state FAR *state; /* not visible by applications */
42861+
42862+ alloc_func zalloc; /* used to allocate the internal state */
42863+ free_func zfree; /* used to free the internal state */
42864+ voidpf opaque; /* private data object passed to zalloc and zfree */
42865+
42866+ int data_type; /* best guess about the data type: ascii or binary */
42867+ uLong adler; /* adler32 value of the uncompressed data */
42868+ uLong reserved; /* reserved for future use */
42869+} z_stream;
42870+
42871+typedef z_stream FAR *z_streamp;
42872+
42873+/*
42874+ The application must update next_in and avail_in when avail_in has
42875+ dropped to zero. It must update next_out and avail_out when avail_out
42876+ has dropped to zero. The application must initialize zalloc, zfree and
42877+ opaque before calling the init function. All other fields are set by the
42878+ compression library and must not be updated by the application.
42879+
42880+ The opaque value provided by the application will be passed as the first
42881+ parameter for calls of zalloc and zfree. This can be useful for custom
42882+ memory management. The compression library attaches no meaning to the
42883+ opaque value.
42884+
42885+ zalloc must return Z_NULL if there is not enough memory for the object.
42886+ If zlib is used in a multi-threaded application, zalloc and zfree must be
42887+ thread safe.
42888+
42889+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
42890+ exactly 65536 bytes, but will not be required to allocate more than this
42891+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
42892+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
42893+ have their offset normalized to zero. The default allocation function
42894+ provided by this library ensures this (see zutil.c). To reduce memory
42895+ requirements and avoid any allocation of 64K objects, at the expense of
42896+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
42897+
42898+ The fields total_in and total_out can be used for statistics or
42899+ progress reports. After compression, total_in holds the total size of
42900+ the uncompressed data and may be saved for use in the decompressor
42901+ (particularly if the decompressor wants to decompress everything in
42902+ a single step).
42903+*/
42904+
42905+ /* constants */
42906+
42907+#define Z_NO_FLUSH 0
42908+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
42909+#define Z_SYNC_FLUSH 2
42910+#define Z_FULL_FLUSH 3
42911+#define Z_FINISH 4
42912+/* Allowed flush values; see deflate() below for details */
42913+
42914+#define Z_OK 0
42915+#define Z_STREAM_END 1
42916+#define Z_NEED_DICT 2
42917+#define Z_ERRNO (-1)
42918+#define Z_STREAM_ERROR (-2)
42919+#define Z_DATA_ERROR (-3)
42920+#define Z_MEM_ERROR (-4)
42921+#define Z_BUF_ERROR (-5)
42922+#define Z_VERSION_ERROR (-6)
42923+/* Return codes for the compression/decompression functions. Negative
42924+ * values are errors, positive values are used for special but normal events.
42925+ */
42926+
42927+#define Z_NO_COMPRESSION 0
42928+#define Z_BEST_SPEED 1
42929+#define Z_BEST_COMPRESSION 9
42930+#define Z_DEFAULT_COMPRESSION (-1)
42931+/* compression levels */
42932+
42933+#define Z_FILTERED 1
42934+#define Z_HUFFMAN_ONLY 2
42935+#define Z_DEFAULT_STRATEGY 0
42936+/* compression strategy; see deflateInit2() below for details */
42937+
42938+#define Z_BINARY 0
42939+#define Z_ASCII 1
42940+#define Z_UNKNOWN 2
42941+/* Possible values of the data_type field */
42942+
42943+#define Z_DEFLATED 8
42944+/* The deflate compression method (the only one supported in this version) */
42945+
42946+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
42947+
42948+#define zlib_version zlibVersion()
42949+/* for compatibility with versions < 1.0.2 */
42950+
42951+ /* basic functions */
42952+
42953+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
42954+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
42955+ If the first character differs, the library code actually used is
42956+ not compatible with the zlib.h header file used by the application.
42957+ This check is automatically made by deflateInit and inflateInit.
42958+ */
42959+
42960+/*
42961+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
42962+
42963+ Initializes the internal stream state for compression. The fields
42964+ zalloc, zfree and opaque must be initialized before by the caller.
42965+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
42966+ use default allocation functions.
42967+
42968+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
42969+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
42970+ all (the input data is simply copied a block at a time).
42971+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
42972+ compression (currently equivalent to level 6).
42973+
42974+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
42975+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
42976+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
42977+ with the version assumed by the caller (ZLIB_VERSION).
42978+ msg is set to null if there is no error message. deflateInit does not
42979+ perform any compression: this will be done by deflate().
42980+*/
42981+
42982+
42983+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
42984+/*
42985+ deflate compresses as much data as possible, and stops when the input
42986+ buffer becomes empty or the output buffer becomes full. It may introduce some
42987+ output latency (reading input without producing any output) except when
42988+ forced to flush.
42989+
42990+ The detailed semantics are as follows. deflate performs one or both of the
42991+ following actions:
42992+
42993+ - Compress more input starting at next_in and update next_in and avail_in
42994+ accordingly. If not all input can be processed (because there is not
42995+ enough room in the output buffer), next_in and avail_in are updated and
42996+ processing will resume at this point for the next call of deflate().
42997+
42998+ - Provide more output starting at next_out and update next_out and avail_out
42999+ accordingly. This action is forced if the parameter flush is non zero.
43000+ Forcing flush frequently degrades the compression ratio, so this parameter
43001+ should be set only when necessary (in interactive applications).
43002+ Some output may be provided even if flush is not set.
43003+
43004+ Before the call of deflate(), the application should ensure that at least
43005+ one of the actions is possible, by providing more input and/or consuming
43006+ more output, and updating avail_in or avail_out accordingly; avail_out
43007+ should never be zero before the call. The application can consume the
43008+ compressed output when it wants, for example when the output buffer is full
43009+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
43010+ and with zero avail_out, it must be called again after making room in the
43011+ output buffer because there might be more output pending.
43012+
43013+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
43014+ flushed to the output buffer and the output is aligned on a byte boundary, so
43015+ that the decompressor can get all input data available so far. (In particular
43016+ avail_in is zero after the call if enough output space has been provided
43017+ before the call.) Flushing may degrade compression for some compression
43018+ algorithms and so it should be used only when necessary.
43019+
43020+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
43021+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
43022+ restart from this point if previous compressed data has been damaged or if
43023+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
43024+ the compression.
43025+
43026+ If deflate returns with avail_out == 0, this function must be called again
43027+ with the same value of the flush parameter and more output space (updated
43028+ avail_out), until the flush is complete (deflate returns with non-zero
43029+ avail_out).
43030+
43031+ If the parameter flush is set to Z_FINISH, pending input is processed,
43032+ pending output is flushed and deflate returns with Z_STREAM_END if there
43033+ was enough output space; if deflate returns with Z_OK, this function must be
43034+ called again with Z_FINISH and more output space (updated avail_out) but no
43035+ more input data, until it returns with Z_STREAM_END or an error. After
43036+ deflate has returned Z_STREAM_END, the only possible operations on the
43037+ stream are deflateReset or deflateEnd.
43038+
43039+ Z_FINISH can be used immediately after deflateInit if all the compression
43040+ is to be done in a single step. In this case, avail_out must be at least
43041+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
43042+ Z_STREAM_END, then it must be called again as described above.
43043+
43044+ deflate() sets strm->adler to the adler32 checksum of all input read
43045+ so far (that is, total_in bytes).
43046+
43047+ deflate() may update data_type if it can make a good guess about
43048+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
43049+ binary. This field is only for information purposes and does not affect
43050+ the compression algorithm in any manner.
43051+
43052+ deflate() returns Z_OK if some progress has been made (more input
43053+ processed or more output produced), Z_STREAM_END if all input has been
43054+ consumed and all output has been produced (only when flush is set to
43055+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
43056+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
43057+ (for example avail_in or avail_out was zero).
43058+*/
43059+
43060+
43061+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
43062+/*
43063+ All dynamically allocated data structures for this stream are freed.
43064+ This function discards any unprocessed input and does not flush any
43065+ pending output.
43066+
43067+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
43068+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
43069+ prematurely (some input or output was discarded). In the error case,
43070+ msg may be set but then points to a static string (which must not be
43071+ deallocated).
43072+*/
43073+
43074+
43075+/*
43076+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
43077+
43078+ Initializes the internal stream state for decompression. The fields
43079+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
43080+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
43081+ value depends on the compression method), inflateInit determines the
43082+ compression method from the zlib header and allocates all data structures
43083+ accordingly; otherwise the allocation will be deferred to the first call of
43084+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
43085+ use default allocation functions.
43086+
43087+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
43088+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
43089+ version assumed by the caller. msg is set to null if there is no error
43090+ message. inflateInit does not perform any decompression apart from reading
43091+ the zlib header if present: this will be done by inflate(). (So next_in and
43092+ avail_in may be modified, but next_out and avail_out are unchanged.)
43093+*/
43094+
43095+
43096+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
43097+/*
43098+ inflate decompresses as much data as possible, and stops when the input
43099+ buffer becomes empty or the output buffer becomes full. It may some
43100+ introduce some output latency (reading input without producing any output)
43101+ except when forced to flush.
43102+
43103+ The detailed semantics are as follows. inflate performs one or both of the
43104+ following actions:
43105+
43106+ - Decompress more input starting at next_in and update next_in and avail_in
43107+ accordingly. If not all input can be processed (because there is not
43108+ enough room in the output buffer), next_in is updated and processing
43109+ will resume at this point for the next call of inflate().
43110+
43111+ - Provide more output starting at next_out and update next_out and avail_out
43112+ accordingly. inflate() provides as much output as possible, until there
43113+ is no more input data or no more space in the output buffer (see below
43114+ about the flush parameter).
43115+
43116+ Before the call of inflate(), the application should ensure that at least
43117+ one of the actions is possible, by providing more input and/or consuming
43118+ more output, and updating the next_* and avail_* values accordingly.
43119+ The application can consume the uncompressed output when it wants, for
43120+ example when the output buffer is full (avail_out == 0), or after each
43121+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
43122+ must be called again after making room in the output buffer because there
43123+ might be more output pending.
43124+
43125+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
43126+ output as possible to the output buffer. The flushing behavior of inflate is
43127+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
43128+ and Z_FINISH, but the current implementation actually flushes as much output
43129+ as possible anyway.
43130+
43131+ inflate() should normally be called until it returns Z_STREAM_END or an
43132+ error. However if all decompression is to be performed in a single step
43133+ (a single call of inflate), the parameter flush should be set to
43134+ Z_FINISH. In this case all pending input is processed and all pending
43135+ output is flushed; avail_out must be large enough to hold all the
43136+ uncompressed data. (The size of the uncompressed data may have been saved
43137+ by the compressor for this purpose.) The next operation on this stream must
43138+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
43139+ is never required, but can be used to inform inflate that a faster routine
43140+ may be used for the single inflate() call.
43141+
43142+ If a preset dictionary is needed at this point (see inflateSetDictionary
43143+ below), inflate sets strm-adler to the adler32 checksum of the
43144+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
43145+ it sets strm->adler to the adler32 checksum of all output produced
43146+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
43147+ an error code as described below. At the end of the stream, inflate()
43148+ checks that its computed adler32 checksum is equal to that saved by the
43149+ compressor and returns Z_STREAM_END only if the checksum is correct.
43150+
43151+ inflate() returns Z_OK if some progress has been made (more input processed
43152+ or more output produced), Z_STREAM_END if the end of the compressed data has
43153+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
43154+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
43155+ corrupted (input stream not conforming to the zlib format or incorrect
43156+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
43157+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
43158+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
43159+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
43160+ case, the application may then call inflateSync to look for a good
43161+ compression block.
43162+*/
43163+
43164+
43165+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
43166+/*
43167+ All dynamically allocated data structures for this stream are freed.
43168+ This function discards any unprocessed input and does not flush any
43169+ pending output.
43170+
43171+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
43172+ was inconsistent. In the error case, msg may be set but then points to a
43173+ static string (which must not be deallocated).
43174+*/
43175+
43176+ /* Advanced functions */
43177+
43178+/*
43179+ The following functions are needed only in some special applications.
43180+*/
43181+
43182+/*
43183+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
43184+ int level,
43185+ int method,
43186+ int windowBits,
43187+ int memLevel,
43188+ int strategy));
43189+
43190+ This is another version of deflateInit with more compression options. The
43191+ fields next_in, zalloc, zfree and opaque must be initialized before by
43192+ the caller.
43193+
43194+ The method parameter is the compression method. It must be Z_DEFLATED in
43195+ this version of the library.
43196+
43197+ The windowBits parameter is the base two logarithm of the window size
43198+ (the size of the history buffer). It should be in the range 8..15 for this
43199+ version of the library. Larger values of this parameter result in better
43200+ compression at the expense of memory usage. The default value is 15 if
43201+ deflateInit is used instead.
43202+
43203+ The memLevel parameter specifies how much memory should be allocated
43204+ for the internal compression state. memLevel=1 uses minimum memory but
43205+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
43206+ for optimal speed. The default value is 8. See zconf.h for total memory
43207+ usage as a function of windowBits and memLevel.
43208+
43209+ The strategy parameter is used to tune the compression algorithm. Use the
43210+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
43211+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
43212+ string match). Filtered data consists mostly of small values with a
43213+ somewhat random distribution. In this case, the compression algorithm is
43214+ tuned to compress them better. The effect of Z_FILTERED is to force more
43215+ Huffman coding and less string matching; it is somewhat intermediate
43216+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
43217+ the compression ratio but not the correctness of the compressed output even
43218+ if it is not set appropriately.
43219+
43220+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
43221+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
43222+ method). msg is set to null if there is no error message. deflateInit2 does
43223+ not perform any compression: this will be done by deflate().
43224+*/
43225+
43226+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
43227+ const Bytef *dictionary,
43228+ uInt dictLength));
43229+/*
43230+ Initializes the compression dictionary from the given byte sequence
43231+ without producing any compressed output. This function must be called
43232+ immediately after deflateInit, deflateInit2 or deflateReset, before any
43233+ call of deflate. The compressor and decompressor must use exactly the same
43234+ dictionary (see inflateSetDictionary).
43235+
43236+ The dictionary should consist of strings (byte sequences) that are likely
43237+ to be encountered later in the data to be compressed, with the most commonly
43238+ used strings preferably put towards the end of the dictionary. Using a
43239+ dictionary is most useful when the data to be compressed is short and can be
43240+ predicted with good accuracy; the data can then be compressed better than
43241+ with the default empty dictionary.
43242+
43243+ Depending on the size of the compression data structures selected by
43244+ deflateInit or deflateInit2, a part of the dictionary may in effect be
43245+ discarded, for example if the dictionary is larger than the window size in
43246+ deflate or deflate2. Thus the strings most likely to be useful should be
43247+ put at the end of the dictionary, not at the front.
43248+
43249+ Upon return of this function, strm->adler is set to the Adler32 value
43250+ of the dictionary; the decompressor may later use this value to determine
43251+ which dictionary has been used by the compressor. (The Adler32 value
43252+ applies to the whole dictionary even if only a subset of the dictionary is
43253+ actually used by the compressor.)
43254+
43255+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
43256+ parameter is invalid (such as NULL dictionary) or the stream state is
43257+ inconsistent (for example if deflate has already been called for this stream
43258+ or if the compression method is bsort). deflateSetDictionary does not
43259+ perform any compression: this will be done by deflate().
43260+*/
43261+
43262+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
43263+ z_streamp source));
43264+/*
43265+ Sets the destination stream as a complete copy of the source stream.
43266+
43267+ This function can be useful when several compression strategies will be
43268+ tried, for example when there are several ways of pre-processing the input
43269+ data with a filter. The streams that will be discarded should then be freed
43270+ by calling deflateEnd. Note that deflateCopy duplicates the internal
43271+ compression state which can be quite large, so this strategy is slow and
43272+ can consume lots of memory.
43273+
43274+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
43275+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
43276+ (such as zalloc being NULL). msg is left unchanged in both source and
43277+ destination.
43278+*/
43279+
43280+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
43281+/*
43282+ This function is equivalent to deflateEnd followed by deflateInit,
43283+ but does not free and reallocate all the internal compression state.
43284+ The stream will keep the same compression level and any other attributes
43285+ that may have been set by deflateInit2.
43286+
43287+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
43288+ stream state was inconsistent (such as zalloc or state being NULL).
43289+*/
43290+
43291+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
43292+ int level,
43293+ int strategy));
43294+/*
43295+ Dynamically update the compression level and compression strategy. The
43296+ interpretation of level and strategy is as in deflateInit2. This can be
43297+ used to switch between compression and straight copy of the input data, or
43298+ to switch to a different kind of input data requiring a different
43299+ strategy. If the compression level is changed, the input available so far
43300+ is compressed with the old level (and may be flushed); the new level will
43301+ take effect only at the next call of deflate().
43302+
43303+ Before the call of deflateParams, the stream state must be set as for
43304+ a call of deflate(), since the currently available input may have to
43305+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
43306+
43307+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
43308+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
43309+ if strm->avail_out was zero.
43310+*/
43311+
43312+/*
43313+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
43314+ int windowBits));
43315+
43316+ This is another version of inflateInit with an extra parameter. The
43317+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
43318+ before by the caller.
43319+
43320+ The windowBits parameter is the base two logarithm of the maximum window
43321+ size (the size of the history buffer). It should be in the range 8..15 for
43322+ this version of the library. The default value is 15 if inflateInit is used
43323+ instead. If a compressed stream with a larger window size is given as
43324+ input, inflate() will return with the error code Z_DATA_ERROR instead of
43325+ trying to allocate a larger window.
43326+
43327+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
43328+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
43329+ memLevel). msg is set to null if there is no error message. inflateInit2
43330+ does not perform any decompression apart from reading the zlib header if
43331+ present: this will be done by inflate(). (So next_in and avail_in may be
43332+ modified, but next_out and avail_out are unchanged.)
43333+*/
43334+
43335+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
43336+ const Bytef *dictionary,
43337+ uInt dictLength));
43338+/*
43339+ Initializes the decompression dictionary from the given uncompressed byte
43340+ sequence. This function must be called immediately after a call of inflate
43341+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
43342+ can be determined from the Adler32 value returned by this call of
43343+ inflate. The compressor and decompressor must use exactly the same
43344+ dictionary (see deflateSetDictionary).
43345+
43346+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
43347+ parameter is invalid (such as NULL dictionary) or the stream state is
43348+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
43349+ expected one (incorrect Adler32 value). inflateSetDictionary does not
43350+ perform any decompression: this will be done by subsequent calls of
43351+ inflate().
43352+*/
43353+
43354+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
43355+/*
43356+ Skips invalid compressed data until a full flush point (see above the
43357+ description of deflate with Z_FULL_FLUSH) can be found, or until all
43358+ available input is skipped. No output is provided.
43359+
43360+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
43361+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
43362+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
43363+ case, the application may save the current current value of total_in which
43364+ indicates where valid compressed data was found. In the error case, the
43365+ application may repeatedly call inflateSync, providing more input each time,
43366+ until success or end of the input data.
43367+*/
43368+
43369+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
43370+/*
43371+ This function is equivalent to inflateEnd followed by inflateInit,
43372+ but does not free and reallocate all the internal decompression state.
43373+ The stream will keep attributes that may have been set by inflateInit2.
43374+
43375+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
43376+ stream state was inconsistent (such as zalloc or state being NULL).
43377+*/
43378+
43379+
43380+ /* utility functions */
43381+
43382+/*
43383+ The following utility functions are implemented on top of the
43384+ basic stream-oriented functions. To simplify the interface, some
43385+ default options are assumed (compression level and memory usage,
43386+ standard memory allocation functions). The source code of these
43387+ utility functions can easily be modified if you need special options.
43388+*/
43389+
43390+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
43391+ const Bytef *source, uLong sourceLen));
43392+/*
43393+ Compresses the source buffer into the destination buffer. sourceLen is
43394+ the byte length of the source buffer. Upon entry, destLen is the total
43395+ size of the destination buffer, which must be at least 0.1% larger than
43396+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
43397+ compressed buffer.
43398+ This function can be used to compress a whole file at once if the
43399+ input file is mmap'ed.
43400+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
43401+ enough memory, Z_BUF_ERROR if there was not enough room in the output
43402+ buffer.
43403+*/
43404+
43405+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
43406+ const Bytef *source, uLong sourceLen,
43407+ int level));
43408+/*
43409+ Compresses the source buffer into the destination buffer. The level
43410+ parameter has the same meaning as in deflateInit. sourceLen is the byte
43411+ length of the source buffer. Upon entry, destLen is the total size of the
43412+ destination buffer, which must be at least 0.1% larger than sourceLen plus
43413+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
43414+
43415+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
43416+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
43417+ Z_STREAM_ERROR if the level parameter is invalid.
43418+*/
43419+
43420+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
43421+ const Bytef *source, uLong sourceLen));
43422+/*
43423+ Decompresses the source buffer into the destination buffer. sourceLen is
43424+ the byte length of the source buffer. Upon entry, destLen is the total
43425+ size of the destination buffer, which must be large enough to hold the
43426+ entire uncompressed data. (The size of the uncompressed data must have
43427+ been saved previously by the compressor and transmitted to the decompressor
43428+ by some mechanism outside the scope of this compression library.)
43429+ Upon exit, destLen is the actual size of the compressed buffer.
43430+ This function can be used to decompress a whole file at once if the
43431+ input file is mmap'ed.
43432+
43433+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
43434+ enough memory, Z_BUF_ERROR if there was not enough room in the output
43435+ buffer, or Z_DATA_ERROR if the input data was corrupted.
43436+*/
43437+
43438+
43439+typedef voidp gzFile;
43440+
43441+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
43442+/*
43443+ Opens a gzip (.gz) file for reading or writing. The mode parameter
43444+ is as in fopen ("rb" or "wb") but can also include a compression level
43445+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
43446+ Huffman only compression as in "wb1h". (See the description
43447+ of deflateInit2 for more information about the strategy parameter.)
43448+
43449+ gzopen can be used to read a file which is not in gzip format; in this
43450+ case gzread will directly read from the file without decompression.
43451+
43452+ gzopen returns NULL if the file could not be opened or if there was
43453+ insufficient memory to allocate the (de)compression state; errno
43454+ can be checked to distinguish the two cases (if errno is zero, the
43455+ zlib error is Z_MEM_ERROR). */
43456+
43457+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
43458+/*
43459+ gzdopen() associates a gzFile with the file descriptor fd. File
43460+ descriptors are obtained from calls like open, dup, creat, pipe or
43461+ fileno (in the file has been previously opened with fopen).
43462+ The mode parameter is as in gzopen.
43463+ The next call of gzclose on the returned gzFile will also close the
43464+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
43465+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
43466+ gzdopen returns NULL if there was insufficient memory to allocate
43467+ the (de)compression state.
43468+*/
43469+
43470+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
43471+/*
43472+ Dynamically update the compression level or strategy. See the description
43473+ of deflateInit2 for the meaning of these parameters.
43474+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
43475+ opened for writing.
43476+*/
43477+
43478+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
43479+/*
43480+ Reads the given number of uncompressed bytes from the compressed file.
43481+ If the input file was not in gzip format, gzread copies the given number
43482+ of bytes into the buffer.
43483+ gzread returns the number of uncompressed bytes actually read (0 for
43484+ end of file, -1 for error). */
43485+
43486+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
43487+ const voidp buf, unsigned len));
43488+/*
43489+ Writes the given number of uncompressed bytes into the compressed file.
43490+ gzwrite returns the number of uncompressed bytes actually written
43491+ (0 in case of error).
43492+*/
43493+
43494+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
43495+/*
43496+ Converts, formats, and writes the args to the compressed file under
43497+ control of the format string, as in fprintf. gzprintf returns the number of
43498+ uncompressed bytes actually written (0 in case of error).
43499+*/
43500+
43501+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
43502+/*
43503+ Writes the given null-terminated string to the compressed file, excluding
43504+ the terminating null character.
43505+ gzputs returns the number of characters written, or -1 in case of error.
43506+*/
43507+
43508+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
43509+/*
43510+ Reads bytes from the compressed file until len-1 characters are read, or
43511+ a newline character is read and transferred to buf, or an end-of-file
43512+ condition is encountered. The string is then terminated with a null
43513+ character.
43514+ gzgets returns buf, or Z_NULL in case of error.
43515+*/
43516+
43517+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
43518+/*
43519+ Writes c, converted to an unsigned char, into the compressed file.
43520+ gzputc returns the value that was written, or -1 in case of error.
43521+*/
43522+
43523+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
43524+/*
43525+ Reads one byte from the compressed file. gzgetc returns this byte
43526+ or -1 in case of end of file or error.
43527+*/
43528+
43529+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
43530+/*
43531+ Flushes all pending output into the compressed file. The parameter
43532+ flush is as in the deflate() function. The return value is the zlib
43533+ error number (see function gzerror below). gzflush returns Z_OK if
43534+ the flush parameter is Z_FINISH and all output could be flushed.
43535+ gzflush should be called only when strictly necessary because it can
43536+ degrade compression.
43537+*/
43538+
43539+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
43540+ z_off_t offset, int whence));
43541+/*
43542+ Sets the starting position for the next gzread or gzwrite on the
43543+ given compressed file. The offset represents a number of bytes in the
43544+ uncompressed data stream. The whence parameter is defined as in lseek(2);
43545+ the value SEEK_END is not supported.
43546+ If the file is opened for reading, this function is emulated but can be
43547+ extremely slow. If the file is opened for writing, only forward seeks are
43548+ supported; gzseek then compresses a sequence of zeroes up to the new
43549+ starting position.
43550+
43551+ gzseek returns the resulting offset location as measured in bytes from
43552+ the beginning of the uncompressed stream, or -1 in case of error, in
43553+ particular if the file is opened for writing and the new starting position
43554+ would be before the current position.
43555+*/
43556+
43557+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
43558+/*
43559+ Rewinds the given file. This function is supported only for reading.
43560+
43561+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
43562+*/
43563+
43564+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
43565+/*
43566+ Returns the starting position for the next gzread or gzwrite on the
43567+ given compressed file. This position represents a number of bytes in the
43568+ uncompressed data stream.
43569+
43570+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
43571+*/
43572+
43573+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
43574+/*
43575+ Returns 1 when EOF has previously been detected reading the given
43576+ input stream, otherwise zero.
43577+*/
43578+
43579+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
43580+/*
43581+ Flushes all pending output if necessary, closes the compressed file
43582+ and deallocates all the (de)compression state. The return value is the zlib
43583+ error number (see function gzerror below).
43584+*/
43585+
43586+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
43587+/*
43588+ Returns the error message for the last error which occurred on the
43589+ given compressed file. errnum is set to zlib error number. If an
43590+ error occurred in the file system and not in the compression library,
43591+ errnum is set to Z_ERRNO and the application may consult errno
43592+ to get the exact error code.
43593+*/
43594+
43595+ /* checksum functions */
43596+
43597+/*
43598+ These functions are not related to compression but are exported
43599+ anyway because they might be useful in applications using the
43600+ compression library.
43601+*/
43602+
43603+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
43604+
43605+/*
43606+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
43607+ return the updated checksum. If buf is NULL, this function returns
43608+ the required initial value for the checksum.
43609+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
43610+ much faster. Usage example:
43611+
43612+ uLong adler = adler32(0L, Z_NULL, 0);
43613+
43614+ while (read_buffer(buffer, length) != EOF) {
43615+ adler = adler32(adler, buffer, length);
43616+ }
43617+ if (adler != original_adler) error();
43618+*/
43619+
43620+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
43621+/*
43622+ Update a running crc with the bytes buf[0..len-1] and return the updated
43623+ crc. If buf is NULL, this function returns the required initial value
43624+ for the crc. Pre- and post-conditioning (one's complement) is performed
43625+ within this function so it shouldn't be done by the application.
43626+ Usage example:
43627+
43628+ uLong crc = crc32(0L, Z_NULL, 0);
43629+
43630+ while (read_buffer(buffer, length) != EOF) {
43631+ crc = crc32(crc, buffer, length);
43632+ }
43633+ if (crc != original_crc) error();
43634+*/
43635+
43636+
43637+ /* various hacks, don't look :) */
43638+
43639+/* deflateInit and inflateInit are macros to allow checking the zlib version
43640+ * and the compiler's view of z_stream:
43641+ */
43642+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
43643+ const char *version, int stream_size));
43644+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
43645+ const char *version, int stream_size));
43646+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
43647+ int windowBits, int memLevel,
43648+ int strategy, const char *version,
43649+ int stream_size));
43650+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
43651+ const char *version, int stream_size));
43652+#define deflateInit(strm, level) \
43653+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
43654+#define inflateInit(strm) \
43655+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
43656+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
43657+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
43658+ (strategy), ZLIB_VERSION, sizeof(z_stream))
43659+#define inflateInit2(strm, windowBits) \
43660+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
43661+
43662+
43663+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
43664+ struct internal_state {int dummy;}; /* hack for buggy compilers */
43665+#endif
43666+
43667+ZEXTERN const char * ZEXPORT zError OF((int err));
43668+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
43669+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
43670+
43671+#ifdef __cplusplus
43672+}
43673+#endif
43674+
43675+#endif /* _ZLIB_H */
43676diff -druN linux-noipsec/net/ipsec/zlib/zutil.c linux/net/ipsec/zlib/zutil.c
43677--- linux-noipsec/net/ipsec/zlib/zutil.c Thu Jan 1 01:00:00 1970
43678+++ linux/net/ipsec/zlib/zutil.c Fri Sep 29 20:51:34 2000
43679@@ -0,0 +1,227 @@
43680+/* zutil.c -- target dependent utility functions for the compression library
43681+ * Copyright (C) 1995-1998 Jean-loup Gailly.
43682+ * For conditions of distribution and use, see copyright notice in zlib.h
43683+ */
43684+
43685+/* @(#) $Id$ */
43686+
43687+#include "zutil.h"
43688+
43689+#define MY_ZCALLOC
43690+
43691+struct internal_state {int dummy;}; /* for buggy compilers */
43692+
43693+#ifndef STDC
43694+extern void exit OF((int));
43695+#endif
43696+
43697+const char *z_errmsg[10] = {
43698+"need dictionary", /* Z_NEED_DICT 2 */
43699+"stream end", /* Z_STREAM_END 1 */
43700+"", /* Z_OK 0 */
43701+"file error", /* Z_ERRNO (-1) */
43702+"stream error", /* Z_STREAM_ERROR (-2) */
43703+"data error", /* Z_DATA_ERROR (-3) */
43704+"insufficient memory", /* Z_MEM_ERROR (-4) */
43705+"buffer error", /* Z_BUF_ERROR (-5) */
43706+"incompatible version",/* Z_VERSION_ERROR (-6) */
43707+""};
43708+
43709+
43710+const char * ZEXPORT zlibVersion()
43711+{
43712+ return ZLIB_VERSION;
43713+}
43714+
43715+#ifdef DEBUG
43716+
43717+# ifndef verbose
43718+# define verbose 0
43719+# endif
43720+int z_verbose = verbose;
43721+
43722+void z_error (m)
43723+ char *m;
43724+{
43725+ fprintf(stderr, "%s\n", m);
43726+ exit(1);
43727+}
43728+#endif
43729+
43730+/* exported to allow conversion of error code to string for compress() and
43731+ * uncompress()
43732+ */
43733+const char * ZEXPORT zError(err)
43734+ int err;
43735+{
43736+ return ERR_MSG(err);
43737+}
43738+
43739+
43740+#ifndef HAVE_MEMCPY
43741+
43742+void zmemcpy(dest, source, len)
43743+ Bytef* dest;
43744+ const Bytef* source;
43745+ uInt len;
43746+{
43747+ if (len == 0) return;
43748+ do {
43749+ *dest++ = *source++; /* ??? to be unrolled */
43750+ } while (--len != 0);
43751+}
43752+
43753+int zmemcmp(s1, s2, len)
43754+ const Bytef* s1;
43755+ const Bytef* s2;
43756+ uInt len;
43757+{
43758+ uInt j;
43759+
43760+ for (j = 0; j < len; j++) {
43761+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
43762+ }
43763+ return 0;
43764+}
43765+
43766+void zmemzero(dest, len)
43767+ Bytef* dest;
43768+ uInt len;
43769+{
43770+ if (len == 0) return;
43771+ do {
43772+ *dest++ = 0; /* ??? to be unrolled */
43773+ } while (--len != 0);
43774+}
43775+#endif
43776+
43777+#ifdef __TURBOC__
43778+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
43779+/* Small and medium model in Turbo C are for now limited to near allocation
43780+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
43781+ */
43782+# define MY_ZCALLOC
43783+
43784+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
43785+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
43786+ * must fix the pointer. Warning: the pointer must be put back to its
43787+ * original form in order to free it, use zcfree().
43788+ */
43789+
43790+#define MAX_PTR 10
43791+/* 10*64K = 640K */
43792+
43793+local int next_ptr = 0;
43794+
43795+typedef struct ptr_table_s {
43796+ voidpf org_ptr;
43797+ voidpf new_ptr;
43798+} ptr_table;
43799+
43800+local ptr_table table[MAX_PTR];
43801+/* This table is used to remember the original form of pointers
43802+ * to large buffers (64K). Such pointers are normalized with a zero offset.
43803+ * Since MSDOS is not a preemptive multitasking OS, this table is not
43804+ * protected from concurrent access. This hack doesn't work anyway on
43805+ * a protected system like OS/2. Use Microsoft C instead.
43806+ */
43807+
43808+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
43809+{
43810+ voidpf buf = opaque; /* just to make some compilers happy */
43811+ ulg bsize = (ulg)items*size;
43812+
43813+ /* If we allocate less than 65520 bytes, we assume that farmalloc
43814+ * will return a usable pointer which doesn't have to be normalized.
43815+ */
43816+ if (bsize < 65520L) {
43817+ buf = farmalloc(bsize);
43818+ if (*(ush*)&buf != 0) return buf;
43819+ } else {
43820+ buf = farmalloc(bsize + 16L);
43821+ }
43822+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
43823+ table[next_ptr].org_ptr = buf;
43824+
43825+ /* Normalize the pointer to seg:0 */
43826+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
43827+ *(ush*)&buf = 0;
43828+ table[next_ptr++].new_ptr = buf;
43829+ return buf;
43830+}
43831+
43832+void zcfree (voidpf opaque, voidpf ptr)
43833+{
43834+ int n;
43835+ if (*(ush*)&ptr != 0) { /* object < 64K */
43836+ farfree(ptr);
43837+ return;
43838+ }
43839+ /* Find the original pointer */
43840+ for (n = 0; n < next_ptr; n++) {
43841+ if (ptr != table[n].new_ptr) continue;
43842+
43843+ farfree(table[n].org_ptr);
43844+ while (++n < next_ptr) {
43845+ table[n-1] = table[n];
43846+ }
43847+ next_ptr--;
43848+ return;
43849+ }
43850+ ptr = opaque; /* just to make some compilers happy */
43851+ Assert(0, "zcfree: ptr not found");
43852+}
43853+#endif
43854+#endif /* __TURBOC__ */
43855+
43856+
43857+#if defined(M_I86) && !defined(__32BIT__)
43858+/* Microsoft C in 16-bit mode */
43859+
43860+# define MY_ZCALLOC
43861+
43862+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
43863+# define _halloc halloc
43864+# define _hfree hfree
43865+#endif
43866+
43867+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
43868+{
43869+ if (opaque) opaque = 0; /* to make compiler happy */
43870+ return _halloc((long)items, size);
43871+}
43872+
43873+void zcfree (voidpf opaque, voidpf ptr)
43874+{
43875+ if (opaque) opaque = 0; /* to make compiler happy */
43876+ _hfree(ptr);
43877+}
43878+
43879+#endif /* MSC */
43880+
43881+
43882+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
43883+
43884+#ifndef STDC
43885+extern voidp calloc OF((uInt items, uInt size));
43886+extern void free OF((voidpf ptr));
43887+#endif
43888+
43889+voidpf zcalloc (opaque, items, size)
43890+ voidpf opaque;
43891+ unsigned items;
43892+ unsigned size;
43893+{
43894+ if (opaque) items += size - size; /* make compiler happy */
43895+ return (voidpf)calloc(items, size);
43896+}
43897+
43898+void zcfree (opaque, ptr)
43899+ voidpf opaque;
43900+ voidpf ptr;
43901+{
43902+ free(ptr);
43903+ if (opaque) return; /* make compiler happy */
43904+}
43905+
43906+#endif /* MY_ZCALLOC */
43907diff -druN linux-noipsec/net/ipsec/zlib/zutil.h linux/net/ipsec/zlib/zutil.h
43908--- linux-noipsec/net/ipsec/zlib/zutil.h Thu Jan 1 01:00:00 1970
43909+++ linux/net/ipsec/zlib/zutil.h Fri Sep 29 20:51:34 2000
43910@@ -0,0 +1,223 @@
43911+/* zutil.h -- internal interface and configuration of the compression library
43912+ * Copyright (C) 1995-1998 Jean-loup Gailly.
43913+ * For conditions of distribution and use, see copyright notice in zlib.h
43914+ */
43915+
43916+/* WARNING: this file should *not* be used by applications. It is
43917+ part of the implementation of the compression library and is
43918+ subject to change. Applications should only use zlib.h.
43919+ */
43920+
43921+/* @(#) $Id$ */
43922+
43923+#ifndef _Z_UTIL_H
43924+#define _Z_UTIL_H
43925+
43926+#include "zlib.h"
43927+
43928+#include <linux/string.h>
43929+#define HAVE_MEMCPY
43930+
43931+#if 0 // #ifdef STDC
43932+# include <stddef.h>
43933+# include <string.h>
43934+# include <stdlib.h>
43935+#endif
43936+#ifdef NO_ERRNO_H
43937+ extern int errno;
43938+#else
43939+# include <errno.h>
43940+#endif
43941+
43942+#ifndef local
43943+# define local static
43944+#endif
43945+/* compile with -Dlocal if your debugger can't find static symbols */
43946+
43947+typedef unsigned char uch;
43948+typedef uch FAR uchf;
43949+typedef unsigned short ush;
43950+typedef ush FAR ushf;
43951+typedef unsigned long ulg;
43952+
43953+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
43954+/* (size given to avoid silly warnings with Visual C++) */
43955+
43956+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
43957+
43958+#define ERR_RETURN(strm,err) \
43959+ return (strm->msg = ERR_MSG(err), (err))
43960+/* To be used only when the state is known to be valid */
43961+
43962+ /* common constants */
43963+
43964+#ifndef DEF_WBITS
43965+# define DEF_WBITS MAX_WBITS
43966+#endif
43967+/* default windowBits for decompression. MAX_WBITS is for compression only */
43968+
43969+#if MAX_MEM_LEVEL >= 8
43970+# define DEF_MEM_LEVEL 8
43971+#else
43972+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
43973+#endif
43974+/* default memLevel */
43975+
43976+#define STORED_BLOCK 0
43977+#define STATIC_TREES 1
43978+#define DYN_TREES 2
43979+/* The three kinds of block type */
43980+
43981+#define MIN_MATCH 3
43982+#define MAX_MATCH 258
43983+/* The minimum and maximum match lengths */
43984+
43985+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
43986+
43987+ /* target dependencies */
43988+
43989+#ifdef MSDOS
43990+# define OS_CODE 0x00
43991+# if defined(__TURBOC__) || defined(__BORLANDC__)
43992+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
43993+ /* Allow compilation with ANSI keywords only enabled */
43994+ void _Cdecl farfree( void *block );
43995+ void *_Cdecl farmalloc( unsigned long nbytes );
43996+# else
43997+# include <alloc.h>
43998+# endif
43999+# else /* MSC or DJGPP */
44000+# include <malloc.h>
44001+# endif
44002+#endif
44003+
44004+#ifdef OS2
44005+# define OS_CODE 0x06
44006+#endif
44007+
44008+#ifdef WIN32 /* Window 95 & Windows NT */
44009+# define OS_CODE 0x0b
44010+#endif
44011+
44012+#if defined(VAXC) || defined(VMS)
44013+# define OS_CODE 0x02
44014+# define F_OPEN(name, mode) \
44015+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
44016+#endif
44017+
44018+#ifdef AMIGA
44019+# define OS_CODE 0x01
44020+#endif
44021+
44022+#if defined(ATARI) || defined(atarist)
44023+# define OS_CODE 0x05
44024+#endif
44025+
44026+#if defined(MACOS) || defined(TARGET_OS_MAC)
44027+# define OS_CODE 0x07
44028+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
44029+# include <unix.h> /* for fdopen */
44030+# else
44031+# ifndef fdopen
44032+# define fdopen(fd,mode) NULL /* No fdopen() */
44033+# endif
44034+# endif
44035+#endif
44036+
44037+#ifdef __50SERIES /* Prime/PRIMOS */
44038+# define OS_CODE 0x0F
44039+#endif
44040+
44041+#ifdef TOPS20
44042+# define OS_CODE 0x0a
44043+#endif
44044+
44045+#if defined(_BEOS_) || defined(RISCOS)
44046+# define fdopen(fd,mode) NULL /* No fdopen() */
44047+#endif
44048+
44049+#if (defined(_MSC_VER) && (_MSC_VER > 600))
44050+# define fdopen(fd,type) _fdopen(fd,type)
44051+#endif
44052+
44053+
44054+ /* Common defaults */
44055+
44056+#ifndef OS_CODE
44057+# define OS_CODE 0x03 /* assume Unix */
44058+#endif
44059+
44060+#ifndef F_OPEN
44061+# define F_OPEN(name, mode) fopen((name), (mode))
44062+#endif
44063+
44064+ /* functions */
44065+
44066+#ifdef HAVE_STRERROR
44067+ extern char *strerror OF((int));
44068+# define zstrerror(errnum) strerror(errnum)
44069+#else
44070+# define zstrerror(errnum) ""
44071+#endif
44072+
44073+#if defined(pyr)
44074+# define NO_MEMCPY
44075+#endif
44076+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
44077+ /* Use our own functions for small and medium model with MSC <= 5.0.
44078+ * You may have to use the same strategy for Borland C (untested).
44079+ * The __SC__ check is for Symantec.
44080+ */
44081+# define NO_MEMCPY
44082+#endif
44083+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
44084+# define HAVE_MEMCPY
44085+#endif
44086+#ifdef HAVE_MEMCPY
44087+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
44088+# define zmemcpy _fmemcpy
44089+# define zmemcmp _fmemcmp
44090+# define zmemzero(dest, len) _fmemset(dest, 0, len)
44091+# else
44092+# define zmemcpy memcpy
44093+# define zmemcmp memcmp
44094+# define zmemzero(dest, len) memset(dest, 0, len)
44095+# endif
44096+#else
44097+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
44098+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
44099+ extern void zmemzero OF((Bytef* dest, uInt len));
44100+#endif
44101+
44102+/* Diagnostic functions */
44103+#ifdef DEBUG
44104+# include <stdio.h>
44105+ extern int z_verbose;
44106+ extern void z_error OF((char *m));
44107+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
44108+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
44109+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
44110+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
44111+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
44112+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
44113+#else
44114+# define Assert(cond,msg)
44115+# define Trace(x)
44116+# define Tracev(x)
44117+# define Tracevv(x)
44118+# define Tracec(c,x)
44119+# define Tracecv(c,x)
44120+#endif
44121+
44122+
44123+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
44124+ uInt len));
44125+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
44126+void zcfree OF((voidpf opaque, voidpf ptr));
44127+
44128+#define ZALLOC(strm, items, size) \
44129+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
44130+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
44131+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
44132+
44133+#endif /* _Z_UTIL_H */
44134diff -druN linux-noipsec/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
44135--- linux-noipsec/net/ipv4/af_inet.c Fri Dec 15 15:15:47 2000
44136+++ linux/net/ipv4/af_inet.c Fri Dec 15 15:18:21 2000
44137@@ -1149,6 +1149,17 @@
44138 ip_mr_init();
44139 #endif
44140
44141+#if defined(CONFIG_IPSEC)
44142+ {
44143+ extern /* void */ int ipsec_init(void);
44144+ /*
44145+ * Initialise AF_INET ESP and AH protocol support including
44146+ * e-routing and SA tables
44147+ */
44148+ ipsec_init();
44149+ }
44150+#endif /* CONFIG_IPSEC */
44151+
44152 #ifdef CONFIG_INET_RARP
44153 rarp_ioctl_hook = rarp_ioctl;
44154 #endif
This page took 4.86491 seconds and 4 git commands to generate.