]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.2.18-freeswan-1.8.patch
9cdd694a797623b3d0f76ee69304dd85 linux-loop-hvr-2.4.16.0.patch
[packages/kernel.git] / linux-2.2.18-freeswan-1.8.patch
1 diff -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
64 diff -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
175 diff -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  
195 diff -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 @@
199 +#
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.
212 +#
213 +# RCSID $Id$
214 +
215 +comment 'IPSec options (FreeS/WAN)'
216 +
217 +bool '   IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP
218 +
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
224 +
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
229 +
230 +bool '   IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP
231 +
232 +bool '   IPSEC Debugging Option' CONFIG_IPSEC_DEBUG
233 diff -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...
257 +
258 +ifndef TOPDIR
259 +TOPDIR  := /usr/src/linux
260 +endif
261 +
262 +SUB_DIRS := 
263 +ALL_SUB_DIRS := libfreeswan zlib
264 +MOD_SUB_DIRS := 
265 +
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
268 +
269 +OX_OBJS := radij.o
270 +M_OBJS := $(O_TARGET)
271 +
272 +override CFLAGS += -Ilibfreeswan
273 +
274 +ifeq ($(CONFIG_IPSEC_DEBUG),y)
275 +override CFLAGS += -g
276 +endif
277 +
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 
290 +
291 +
292 +ifeq ($(CONFIG_IPSEC_ENC_DES),y)
293 +INCLUDE_DES = y
294 +endif
295 +
296 +ifeq ($(CONFIG_IPSEC_ENC_3DES),y)
297 +INCLUDE_DES = y
298 +endif
299 +
300 +ifeq ($(CONFIG_IPSEC_AUTH_HMAC_MD5),y)
301 +O_OBJS += ipsec_md5c.o
302 +endif
303 +
304 +ifeq ($(CONFIG_IPSEC_AUTH_HMAC_SHA1),y)
305 +O_OBJS += ipsec_sha1.o
306 +endif
307 +
308 +ifeq ($(CONFIG_IPSEC_IPCOMP),y)
309 +  O_OBJS += ipcomp.o zlib/zlib.a
310 +  SUB_DIRS += zlib
311 +  MOD_SUB_DIRS += zlib
312 +endif
313 +
314 +ifeq ($(INCLUDE_DES),y)
315 +O_OBJS += libdes/libdes.a
316 +endif
317 +
318 +O_OBJS += libfreeswan/libkernel.a
319 +
320 +ifeq ($(CONFIG_IPSEC),y)
321 +SUB_DIRS += libfreeswan
322 +else
323 +  ifeq ($(CONFIG_IPSEC),m)
324 +  override MOD_SUB_DIRS += libfreeswan
325 +  endif
326 +endif
327 +
328 +include $(TOPDIR)/Rules.make
329 +
330 +$(O_OBJS) $(OX_OBJS):  $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
331 +
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 )
338 +
339 +libfreeswan/libkernel.a:
340 +       $(MAKE) -C libfreeswan
341 +
342 +zlib/zlib.a:
343 +       $(MAKE) -C zlib
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 +#
479 diff -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 +#
576 diff -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 +}
1305 diff -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 */
1368 diff -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 + */
1604 diff -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 + */
1776 diff -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 + */
2037 diff -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 + */
3190 diff -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 + */
3253 diff -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 + */
3687 diff -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 + */
3820 diff -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 + */
4459 diff -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 + */
4793 diff -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 + */
5307 diff -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 + */
5457 diff -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 + */
7434 diff -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 +
7599 diff -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 + */
7804 diff -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 + */
7876 diff -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 + */
10945 diff -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 + */
11155 diff -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 + */
12337 diff -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 + */
12700 diff -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.
12950 diff -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 +
13158 diff -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 +
13413 diff -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 +       }
13647 diff -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 +
13730 diff -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;
14076 diff -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 +
14204 diff -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;
14319 diff -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 +       }
14668 diff -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 +       }
15075 diff -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 +
15214 diff -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
15521 diff -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 */
16027 diff -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
16542 diff -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 +       }
17166 diff -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 */
17230 diff -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 +
18105 diff -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 +
18237 diff -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 +
18393 diff -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 +
18545 diff -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};
18624 diff -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 +       }
18874 diff -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 +}};
19082 diff -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 +       }
19415 diff -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 +}};
19623 diff -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 +
19680 diff -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 +}
19752 diff -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 +}
19986 diff -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 +}
20084 diff -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 +}
20234 diff -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 +}
20476 diff -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 */
20692 diff -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 */
20895 diff -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 */
21114 diff -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 +}
21208 diff -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 +}
21437 diff -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 */
21915 diff -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 +}
22016 diff -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 +}
22071 diff -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 +}
22108 diff -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 +}
22189 diff -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 +
22274 diff -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 */
22579 diff -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 + */
22923 diff -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 + */
24192 diff -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 + */
24892 diff -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 + */
26324 diff -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 + */
26645 diff -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 +}
26745 diff -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 +}
26810 diff -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 */
27042 diff -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 +}
27236 diff -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 +}
27323 diff -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 +}
27429 diff -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 +}
27493 diff -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 +}
27559 diff -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 +}
27619 diff -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 +}
27732 diff -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 +}
28133 diff -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 */
28713 diff -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 */
28967 diff -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 */
29246 diff -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 +}
29341 diff -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 +}
29412 diff -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 +}
29499 diff -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 + */
31394 diff -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 + */
34831 diff -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 + */
35948 diff -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 + */
36243 diff -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 + */
36421 diff -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";
36427 diff -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 +#
36505 diff -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 +}
36557 diff -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 +}
37912 diff -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 */
38234 diff -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 +}
38636 diff -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));
38679 diff -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 +}
38940 diff -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 */
38975 diff -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 +}
39149 diff -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 */
39175 diff -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 +  };
39330 diff -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 +}
39702 diff -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 +}
40161 diff -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 */
40228 diff -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 +}
40319 diff -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 */
40421 diff -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
40782 diff -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
41116 diff -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 +}
42334 diff -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 +
42466 diff -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 */
42779 diff -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 */
43676 diff -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 */
43907 diff -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 */
44134 diff -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 3.545657 seconds and 3 git commands to generate.